kspaceFirstOrder3D-CUDA  1.1
The CUDA/C++ implementation of the k-wave toolbox for the time-domain simulation of acoustic wave fields in 3D
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
HDF5_File.cpp
Go to the documentation of this file.
1 /**
2  * @file HDF5_File.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 3.4
12  *
13  * @date 27 July 2012, 14:14 (created) \n
14  * 10 August 2016, 10:49 (revised)
15  *
16  * @section License
17  * This file is part of the C++ extension of the k-Wave Toolbox
18  * (http://www.k-wave.org).\n Copyright (C) 2016 Jiri Jaros and Bradley Treeby.
19  *
20  * This file is part of the k-Wave. k-Wave is free software: you can redistribute it and/or modify
21  * it under the terms of the GNU Lesser General Public License as published by the Free Software
22  * Foundation, either version 3 of the 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
25  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
26  * General Public License for 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/.
30  */
31 
32 
33 #include <iostream>
34 #include <stdexcept>
35 #include <ctime>
36 
37 // Linux build
38 #ifdef __linux__
39  #include <unistd.h>
40 #endif
41 
42 //Windows 64 build
43 #ifdef _WIN64
44  #include<stdio.h>
45  #include<Winsock2.h>
46  #pragma comment(lib, "Ws2_32.lib")
47 #endif
48 
49 #include <HDF5/HDF5_File.h>
50 #include <Parameters/Parameters.h>
51 #include <Logger/ErrorMessages.h>
52 
53 #include <Logger/Logger.h>
54 
55 using std::ios;
56 using std::string;
57 
58 //------------------------------------------------------------------------------------------------//
59 //------------------------------------------ Constants -------------------------------------------//
60 //------------------------------------------------------------------------------------------------//
61 
62 
63 const string THDF5_File::matrixDomainTypeName = "domain_type";
64 const string THDF5_File::matrixDataTypeName = "data_type";
65 
66 const string THDF5_File::matrixDomainTypeNames[] = {"real","complex"};
67 const string THDF5_File::matrixDataTypeNames[] = {"float","long"};
68 
69 const string THDF5_FileHeader::hdf5_FileTypesNames[] = {"input", "output", "checkpoint", "unknown"};
70 
72 const string THDF5_FileHeader::hdf5_MinorFileVersionsNames[] = {"0","1"};
73 
74 //------------------------------------------------------------------------------------------------//
75 //-------------------------------------- THDF5_File ----------------------------------------//
76 //--------------------------------------- Public methods -----------------------------------------//
77 //------------------------------------------------------------------------------------------------//
78 
79 /**
80  * Constructor.
81  */
83  file(H5I_BADID), fileName("")
84 {
85 
86 }// end of constructor
87 //--------------------------------------------------------------------------------------------------
88 
89 
90 /**
91  * Create the HDF5 file.
92  *
93  * @param [in] fileName - File name
94  * @param [in] flags - Flags for the HDF5 runtime
95  * @throw ios:failure if error happened.
96  */
97 void THDF5_File::Create(const string& fileName,
98  unsigned int flags)
99 {
100  // file is opened
101  if (IsOpen())
102  {
103  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_RECREATE_FILE, fileName.c_str()));
104  }
105 
106  // Create a new file using default properties.
107  this->fileName = fileName;
108 
109  file = H5Fcreate(fileName.c_str(), flags, H5P_DEFAULT, H5P_DEFAULT);
110 
111  if (file < 0)
112  {
113  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_CREATE_FILE, fileName.c_str()));
114  }
115 }// end of Create
116 //--------------------------------------------------------------------------------------------------
117 
118 
119 /**
120  * Open the HDF5 file.
121  *
122  * @param [in] fileName - File name
123  * @param [in] flags - Flags for the HDF5 runtime
124  * @throw ios:failure if error happened.
125  *
126  */
127 void THDF5_File::Open(const string& fileName,
128  unsigned int flags)
129 {
130  const char* cFileName = fileName.c_str();
131 
132  if (IsOpen())
133  {
134  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_REOPEN_FILE, cFileName));
135  };
136 
137  this->fileName = fileName;
138 
139  if (H5Fis_hdf5(cFileName) == 0)
140  {
141  throw ios::failure(TLogger::FormatMessage(ERR_FMT_NOT_HDF5_FILE, cFileName));
142  }
143 
144  file = H5Fopen(cFileName, flags, H5P_DEFAULT);
145 
146  if (file < 0)
147  {
148  throw ios::failure(TLogger::FormatMessage(ERR_FMT_FILE_NOT_OPEN, cFileName));
149  }
150 }// end of Open
151 //--------------------------------------------------------------------------------------------------
152 
153 /**
154  * Is a HDF5 file (can I access it)
155  * @param [in] fileName - Filename
156  * @return true if I can access the file
157  */
158 bool THDF5_File::IsHDF5(const string& fileName)
159 {
160  #ifdef __linux__
161  return (access(fileName.c_str(), F_OK) == 0);
162  #endif
163 
164  #ifdef _WIN64
165  return (_access_s(fileName.c_str(), 0) == 0 );
166  #endif
167 }// end of IsHDF5
168 //--------------------------------------------------------------------------------------------------
169 
170 /**
171  * Close the HDF5 file.
172  *
173  * @throw ios::failure
174  */
176 {
177  // Terminate access to the file.
178  herr_t status = H5Fclose(file);
179 
180  if (status < 0)
181  {
182  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_CLOSE_FILE, fileName.c_str()));
183  }
184 
185  fileName = "";
186  file = H5I_BADID;
187 }// end of Close
188 //--------------------------------------------------------------------------------------------------
189 
190 /**
191  * Destructor.
192  */
194 {
195  if (IsOpen()) Close();
196 }//end of ~THDF5_File
197 //--------------------------------------------------------------------------------------------------
198 
199 
200 /**
201  * Create a HDF5 group at a specified place in the file tree.
202  *
203  * @param [in] parentGroup - Where to link the group at
204  * @param [in] groupName - Group name
205  * @return A handle to the new group
206  * @throw ios::failure
207  */
208 hid_t THDF5_File::CreateGroup(const hid_t parentGroup,
209  TMatrixName& groupName)
210 {
211  hid_t group = H5Gcreate(parentGroup, groupName.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
212 
213  if (group == H5I_INVALID_HID)
214  {
216  groupName.c_str(),
217  fileName.c_str()));
218  }
219 
220  return group;
221 }// end of CreateGroup
222 //--------------------------------------------------------------------------------------------------
223 
224 /**
225  * Open a HDF5 group at a specified place in the file tree.
226  *
227  * @param [in] parentGroup - Parent group
228  * @param [in] groupName - Group name
229  * @return A handle to the group
230  * @throw ios::failure
231  */
232 hid_t THDF5_File::OpenGroup(const hid_t parentGroup,
233  TMatrixName& groupName)
234 {
235  hid_t group = H5Gopen(parentGroup, groupName.c_str(), H5P_DEFAULT);
236 
237  if (group == H5I_INVALID_HID)
238  {
240  groupName.c_str(),
241  fileName.c_str()));
242  }
243 
244  return group;
245 }// end of OpenGroup
246 //--------------------------------------------------------------------------------------------------
247 
248 
249 /**
250  * Close a group.
251  *
252  * @param[in] group - Group to close
253  */
254 void THDF5_File::CloseGroup(const hid_t group)
255 {
256  H5Gclose(group);
257 }// end of CloseGroup
258 //--------------------------------------------------------------------------------------------------
259 
260 /**
261  * Open a dataset at a specified place in the file tree.
262  *
263  * @param [in] parentGroup - Parent group Id (can be the file Id for root).
264  * @param [in] datasetName - Dataset name
265  * @return A handle to open dataset
266  * @throw ios::failure
267  */
268 hid_t THDF5_File::OpenDataset(const hid_t parentGroup,
269  TMatrixName& datasetName)
270 {
271  // Open dataset
272  hid_t dataset = H5Dopen(parentGroup, datasetName.c_str(), H5P_DEFAULT);
273 
274  if (dataset == H5I_INVALID_HID)
275  {
277  fileName.c_str(),
278  datasetName.c_str()));
279  }
280 
281  return dataset;
282 }// end of OpenDataset
283 //--------------------------------------------------------------------------------------------------
284 
285 /**
286  * Create a float HDF5 dataset at a specified place in the file tree.
287  *
288  * @param [in] parentGroup - Parent group Id
289  * @param [in] datasetName - Dataset name
290  * @param [in] dimensionSizes - Dimension sizes
291  * @param [in] chunkSizes - Chunk sizes
292  * @param [in] compressionLevel - Compression level
293  * @return A handle to the new dataset
294  * @throw ios::failure
295  */
296 hid_t THDF5_File::CreateFloatDataset(const hid_t parentGroup,
297  TMatrixName& datasetName,
298  const TDimensionSizes& dimensionSizes,
299  const TDimensionSizes& chunkSizes,
300  const size_t compressionLevel)
301 {
302  const int rank = (dimensionSizes.Is3D()) ? 3 : 4;
303 
304 // a windows hack
305  hsize_t dims [4];
306  hsize_t chunk[4];
307 
308  // 3D dataset
309  if (dimensionSizes.Is3D())
310  {
311  dims[0] = dimensionSizes.nz;
312  dims[1] = dimensionSizes.ny;
313  dims[2] = dimensionSizes.nx;
314 
315  chunk[0] = chunkSizes.nz;
316  chunk[1] = chunkSizes.ny;
317  chunk[2] = chunkSizes.nx;
318  }
319  else // 4D dataset
320  {
321  dims[0] = dimensionSizes.nt;
322  dims[1] = dimensionSizes.nz;
323  dims[2] = dimensionSizes.ny;
324  dims[3] = dimensionSizes.nx;
325 
326  chunk[0] = chunkSizes.nt;
327  chunk[1] = chunkSizes.nz;
328  chunk[2] = chunkSizes.ny;
329  chunk[3] = chunkSizes.nx;
330  }
331 
332  hid_t propertyList;
333  herr_t status;
334 
335  hid_t dataspace = H5Screate_simple(rank, dims, NULL);
336 
337  // set chunk size
338  propertyList = H5Pcreate(H5P_DATASET_CREATE);
339 
340  status = H5Pset_chunk(propertyList, rank, chunk);
341  if (status < 0)
342  {
344  fileName.c_str(),
345  datasetName.c_str()));
346  }
347 
348  // set compression level
349  status = H5Pset_deflate(propertyList, compressionLevel);
350  if (status < 0)
351  {
353  fileName.c_str(),
354  datasetName.c_str(),
355  compressionLevel));
356  }
357 
358  // create dataset
359  hid_t dataset = H5Dcreate(parentGroup,
360  datasetName.c_str(),
361  H5T_NATIVE_FLOAT,
362  dataspace,
363  H5P_DEFAULT,
364  propertyList,
365  H5P_DEFAULT);
366 
367  if (dataset == H5I_INVALID_HID)
368  {
370  fileName.c_str(),
371  datasetName.c_str()));
372  }
373 
374  H5Pclose(propertyList);
375 
376  return dataset;
377 }// end of CreateFloatDataset
378 //--------------------------------------------------------------------------------------------------
379 
380 
381 /**
382  * Create an index HDF5 dataset at a specified place in the file tree (always 3D).
383  *
384  * @param [in] parentGroup - Parent group
385  * @param [in] datasetName - Dataset name
386  * @param [in] dimensionSizes - Dimension sizes
387  * @param [in] chunkSizes - Chunk sizes
388  * @param [in] compressionLevel - Compression level
389  * @return A handle to the new dataset
390  * @throw ios::failure
391  */
392 hid_t THDF5_File::CreateIndexDataset(const hid_t parentGroup,
393  TMatrixName& datasetName,
394  const TDimensionSizes& dimensionSizes,
395  const TDimensionSizes& chunkSizes,
396  const size_t compressionLevel)
397 {
398  const int rank = 3;
399 
400  hsize_t dims [rank] = {dimensionSizes.nz, dimensionSizes.ny, dimensionSizes.nx};
401  hsize_t chunk[rank] = {chunkSizes.nz, chunkSizes.ny, chunkSizes.nx};
402 
403  hid_t propertyList;
404  herr_t status;
405 
406  hid_t dataspace = H5Screate_simple(rank, dims, NULL);
407 
408  // set chunk size
409  propertyList = H5Pcreate(H5P_DATASET_CREATE);
410 
411  status = H5Pset_chunk(propertyList, rank, chunk);
412  if (status < 0)
413  {
415  fileName.c_str(),
416  datasetName.c_str()));
417  }
418 
419  // set compression level
420  status = H5Pset_deflate(propertyList, compressionLevel);
421  if (status < 0)
422  {
424  fileName.c_str(),
425  datasetName.c_str(),
426  compressionLevel));
427  }
428 
429  // create dataset
430  hid_t dataset = H5Dcreate(parentGroup,
431  datasetName.c_str(),
432  H5T_STD_U64LE,
433  dataspace,
434  H5P_DEFAULT,
435  propertyList,
436  H5P_DEFAULT);
437 
438  if (dataset == H5I_INVALID_HID)
439  {
441  fileName.c_str(),
442  datasetName.c_str()));
443  }
444 
445  H5Pclose(propertyList);
446 
447  return dataset;
448 }// end of CreateIndexDataset
449 //--------------------------------------------------------------------------------------------------
450 
451 
452 /**
453  * Close dataset.
454  *
455  * @param [in] dataset - Dataset to close
456  */
457 void THDF5_File::CloseDataset(const hid_t dataset)
458 {
459  H5Dclose (dataset);
460 }// end of CloseDataset
461 //--------------------------------------------------------------------------------------------------
462 
463 
464 /**
465  * Write a hyperslab into the dataset, float version.
466  *
467  * @param [in] dataset - Dataset id
468  * @param [in] position - Position in the dataset
469  * @param [in] size - Size of the hyperslab
470  * @param [in] data - Data to be written
471  * @throw ios::failure
472  */
473 void THDF5_File::WriteHyperSlab(const hid_t dataset,
474  const TDimensionSizes& position,
475  const TDimensionSizes& size,
476  const float* data)
477 {
478  herr_t status;
479  hid_t filespace, memspace;
480 
481  // Get file space to find out number of dimensions
482  filespace = H5Dget_space(dataset);
483  const int rank = H5Sget_simple_extent_ndims(filespace);
484 
485  // Select sizes and positions, windows hack
486  hsize_t nElement[4];
487  hsize_t offset[4];
488 
489  // 3D dataset
490  if (rank == 3)
491  {
492  nElement[0] = size.nz;
493  nElement[1] = size.ny;
494  nElement[2] = size.nx;
495 
496  offset[0] = position.nz;
497  offset[1] = position.ny;
498  offset[2] = position.nx;
499  }
500  else // 4D dataset
501  {
502  nElement[0] = size.nt;
503  nElement[1] = size.nz;
504  nElement[2] = size.ny;
505  nElement[3] = size.nx;
506 
507  offset[0] = position.nt;
508  offset[1] = position.nz;
509  offset[2] = position.ny;
510  offset[3] = position.nx;
511  }
512 
513  // select hyperslab
514  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, nElement, NULL);
515  if (status < 0)
516  {
517  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, ""));
518  }
519 
520  // assign memspace
521  memspace = H5Screate_simple(rank, nElement, NULL);
522 
523  status = H5Dwrite(dataset, H5T_NATIVE_FLOAT, memspace, filespace, H5P_DEFAULT, data);
524  if (status < 0)
525  {
526  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, ""));
527  }
528 
529  H5Sclose(memspace);
530  H5Sclose(filespace);
531 }// end of WriteHyperSlab
532 //--------------------------------------------------------------------------------------------------
533 
534 
535 /**
536  * Write a hyperslab into the dataset, index version.
537  *
538  * @param [in] dataset - Dataset id
539  * @param [in] position - Position in the dataset
540  * @param [in] size - Size of the hyperslab
541  * @param [in] data - Data to be written
542  * @throw ios::failure
543  */
544 void THDF5_File::WriteHyperSlab(const hid_t dataset,
545  const TDimensionSizes& position,
546  const TDimensionSizes& size,
547  const size_t* data)
548 {
549  herr_t status;
550  hid_t filespace, memspace;
551 
552  // Get File Space, to find out number of dimensions
553  filespace = H5Dget_space(dataset);
554  const int rank = H5Sget_simple_extent_ndims(filespace);
555 
556  // Set sizes and offsets, windows hack
557  hsize_t nElement[4];
558  hsize_t offset[4];
559 
560  // 3D dataset
561  if (rank == 3)
562  {
563  nElement[0] = size.nz;
564  nElement[1] = size.ny;
565  nElement[2] = size.nx;
566 
567  offset[0] = position.nz;
568  offset[1] = position.ny;
569  offset[2] = position.nx;
570  }
571  else // 4D dataset
572  {
573  nElement[0] = size.nt;
574  nElement[1] = size.nz;
575  nElement[2] = size.ny;
576  nElement[3] = size.nx;
577 
578  offset[0] = position.nt;
579  offset[1] = position.nz;
580  offset[2] = position.ny;
581  offset[3] = position.nx;
582  }
583 
584  // select hyperslab
585  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, nElement, NULL);
586  if (status < 0)
587  {
588  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, ""));
589  }
590 
591  // assign memspace
592  memspace = H5Screate_simple(rank, nElement, NULL);
593 
594  status = H5Dwrite(dataset, H5T_STD_U64LE, memspace, filespace, H5P_DEFAULT, data);
595  if (status < 0)
596  {
597  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, ""));
598  }
599 
600  H5Sclose(memspace);
601  H5Sclose(filespace);
602 }// end of WriteHyperSlab
603 //--------------------------------------------------------------------------------------------------
604 
605 
606 /**
607  * Write a cuboid selected within the matrixData into a hyperslab.
608  * The routine writes 3D cuboid into a 4D dataset (only intended for raw time series).
609  *
610  * @param [in] dataset - Dataset to write MatrixData into
611  * @param [in] hyperslabPosition - Position in the dataset (hyperslab) - may be 3D/4D
612  * @param [in] cuboidPosition - Position of the cuboid in MatrixData (what to sample) - must be 3D
613  * @param [in] cuboidSize - Cuboid size (size of data being sampled) - must by 3D
614  * @param [in] matrixDimensions - Size of the original matrix (the sampled one)
615  * @param [in] matrixData - C array of MatrixData
616  * @throw ios::failure
617  */
618 void THDF5_File::WriteCuboidToHyperSlab(const hid_t dataset,
619  const TDimensionSizes& hyperslabPosition,
620  const TDimensionSizes& cuboidPosition,
621  const TDimensionSizes& cuboidSize,
622  const TDimensionSizes& matrixDimensions,
623  const float* matrixData)
624 {
625  herr_t status;
626  hid_t filespace, memspace;
627 
628  const int rank = 4;
629 
630  // Select sizes and positions
631  // The T here is always 1 (only one timestep)
632  hsize_t slabSize[rank] = {1, cuboidSize.nz, cuboidSize.ny, cuboidSize.nx};
633  hsize_t offsetInDataset[rank] = {hyperslabPosition.nt, hyperslabPosition.nz, hyperslabPosition.ny, hyperslabPosition.nx};
634  hsize_t offsetInMatrixData[] = {cuboidPosition.nz, cuboidPosition.ny, cuboidPosition.nx};
635  hsize_t matrixSize [] = {matrixDimensions.nz, matrixDimensions.ny, matrixDimensions.nx};
636 
637 
638  // select hyperslab in the HDF5 dataset
639  filespace = H5Dget_space(dataset);
640  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offsetInDataset, NULL, slabSize, NULL);
641  if (status < 0)
642  {
643  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, ""));
644  }
645 
646  // assign memspace and select the cuboid in the sampled matrix
647  memspace = H5Screate_simple(3, matrixSize, NULL);
648  status = H5Sselect_hyperslab(memspace,
649  H5S_SELECT_SET,
650  offsetInMatrixData,
651  NULL,
652  slabSize + 1, // Slab size has to be 3D in this case (done by skipping the T dimension)
653  NULL);
654  if (status < 0)
655  {
656  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, ""));
657  }
658 
659  // Write the data
660  status = H5Dwrite(dataset, H5T_NATIVE_FLOAT, memspace, filespace, H5P_DEFAULT, matrixData);
661  if (status < 0)
662  {
663  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, ""));
664  }
665 
666  // close memspace and filespace
667  H5Sclose(memspace);
668  H5Sclose(filespace);
669 }// end of WriteCuboidToHyperSlab
670 //--------------------------------------------------------------------------------------------------
671 
672 /**
673  * Write sensor data selected by the sensor mask.
674  * A routine pick elements from the MatixData based on the sensor data and store.
675  * them into a single hyperslab of size [Nsens, 1, 1].
676  *
677  * @param [in] dataset - Dataset to write MaatrixData into
678  * @param [in] hyperslabPosition - 3D position in the dataset (hyperslab)
679  * @param [in] indexSensorSize - Size of the index based sensor mask
680  * @param [in] indexSensorData - Index based sensor mask
681  * @param [in] matrixDimensions - Size of the sampled matrix
682  * @param [in] matrixData - Matrix data
683  * @warning - Very slow at this version of HDF5 for orthogonal planes-> DO NOT USE
684  * @throw ios::failure
685  */
686 void THDF5_File::WriteDataByMaskToHyperSlab(const hid_t dataset,
687  const TDimensionSizes& hyperslabPosition,
688  const size_t indexSensorSize,
689  const size_t* indexSensorData,
690  const TDimensionSizes& matrixDimensions,
691  const float* matrixData)
692 {
693  herr_t status;
694  hid_t filespace, memspace;
695 
696  const int Rank = 3;
697 
698  // Select sizes and positions
699  // Only one timestep
700  hsize_t slabSize[Rank] = {1, 1, indexSensorSize};
701  hsize_t offsetInDataset[Rank] = {hyperslabPosition.nz, hyperslabPosition.ny, hyperslabPosition.nx};
702 
703  // treat as a 1D array
704  hsize_t matrixSize = matrixDimensions.nz * matrixDimensions.ny * matrixDimensions.nx;
705 
706 
707  // select hyperslab in the HDF5 dataset
708  filespace = H5Dget_space(dataset);
709  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offsetInDataset, NULL, slabSize, NULL);
710  if (status < 0)
711  {
712  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, ""));
713  }
714 
715  // assign 1D memspace and select the elements within the array
716  memspace = H5Screate_simple(1, &matrixSize, NULL);
717  status = H5Sselect_elements(memspace,
718  H5S_SELECT_SET,
719  indexSensorSize,
720  (hsize_t*) (indexSensorData));
721  if (status < 0)
722  {
723  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, ""));
724  }
725 
726  // Write the data
727  status = H5Dwrite(dataset, H5T_NATIVE_FLOAT, memspace, filespace, H5P_DEFAULT, matrixData);
728  if (status < 0)
729  {
730  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, ""));
731  }
732 
733  // close memspace and filespace
734  H5Sclose(memspace);
735  H5Sclose(filespace);
736 }// end of WriteSensorbyMaskToHyperSlab
737 //--------------------------------------------------------------------------------------------------
738 
739 /**
740  * Write a scalar value at a specified place in the file tree
741  * (no chunks, no compression). Float value.
742  *
743  * @param [in] parentGroup - Where to link the scalar dataset
744  * @param [in] datasetName - HDF5 dataset name
745  * @param [in] value - data to be written
746  * @throw ios::failure
747  */
748 void THDF5_File::WriteScalarValue(const hid_t parentGroup,
749  TMatrixName& datasetName,
750  const float value)
751 {
752 
753  const int rank = 3;
754  const hsize_t dims[] = {1, 1, 1};
755 
756  hid_t dataset = H5I_INVALID_HID;
757  hid_t dataspace = H5I_INVALID_HID;
758  herr_t status;
759 
760  const char* cDatasetName = datasetName.c_str();
761  if (H5LTfind_dataset(parentGroup, cDatasetName) == 1)
762  { // dataset already exists (from previous simulation leg) open it
763  dataset = OpenDataset(parentGroup,cDatasetName);
764  }
765  else
766  { // dataset does not exist yet -> create it
767  dataspace = H5Screate_simple(rank, dims, NULL);
768  dataset = H5Dcreate(parentGroup,
769  cDatasetName,
770  H5T_NATIVE_FLOAT,
771  dataspace,
772  H5P_DEFAULT,
773  H5P_DEFAULT,
774  H5P_DEFAULT);
775  }
776 
777  // was created correctly?
778  if (dataset == H5I_INVALID_HID)
779  {
780  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, cDatasetName));
781  }
782 
783  status = H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value);
784  if (status < 0)
785  {
786  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, cDatasetName));
787  }
788 
789  WriteMatrixDataType(parentGroup, datasetName, FLOAT);
790  WriteMatrixDomainType(parentGroup, datasetName, REAL);
791 } // end of WriteScalarValue (float)
792 //--------------------------------------------------------------------------------------------------
793 
794 /**
795  * Write a scalar value at a specified place in the file tree
796  * (no chunks, no compression). Index value.
797  *
798  * @param [in] parentGroup - Where to link the scalar dataset
799  * @param [in] datasetName - HDF5 dataset name
800  * @param [in] value - Data to be written
801  * @throw ios::failure
802  */
803 void THDF5_File::WriteScalarValue(const hid_t parentGroup,
804  TMatrixName& datasetName,
805  const size_t value)
806 {
807  const int rank = 3;
808  const hsize_t dims[] = {1, 1, 1};
809 
810  hid_t dataset = H5I_INVALID_HID;
811  hid_t dataspace = H5I_INVALID_HID;
812  herr_t status;
813 
814  const char* cDatasetName = datasetName.c_str();
815  if (H5LTfind_dataset(parentGroup, cDatasetName) == 1)
816  { // dataset already exists (from previous leg) open it
817  dataset = OpenDataset(parentGroup, cDatasetName);
818  }
819  else
820  { // dataset does not exist yet -> create it
821  dataspace = H5Screate_simple(rank, dims, NULL);
822  dataset = H5Dcreate(parentGroup,
823  cDatasetName,
824  H5T_STD_U64LE,
825  dataspace,
826  H5P_DEFAULT,
827  H5P_DEFAULT,
828  H5P_DEFAULT);
829  }
830 
831  // was created correctly?
832  if (dataset == H5I_INVALID_HID)
833  {
834  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, cDatasetName));
835  }
836 
837  status = H5Dwrite(dataset, H5T_STD_U64LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value);
838  if (status < 0)
839  {
840  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_WRITE_DATASET, cDatasetName));
841  }
842 
843  WriteMatrixDataType(parentGroup, datasetName, LONG);
844  WriteMatrixDomainType(parentGroup, datasetName, REAL);
845 }// end of WriteScalarValue
846 //--------------------------------------------------------------------------------------------------
847 
848 /**
849  * Read the scalar value under a specified group, float value.
850  *
851  * @param [in] parentGroup - Where to link the scalar dataset
852  * @param [in] datasetName - HDF5 dataset name
853  * @param [out] value - Data to be read
854  */
855 void THDF5_File::ReadScalarValue(const hid_t parentGroup,
856  TMatrixName& datasetName,
857  float& value)
858 {
859  ReadCompleteDataset(parentGroup, datasetName, TDimensionSizes(1,1,1), &value);
860 } // end of ReadScalarValue
861 //--------------------------------------------------------------------------------------------------
862 
863 /**
864  * Read the scalar value under a specified group, index value.
865  *
866  * @param [in] parentGroup - Where to link the scalar dataset
867  * @param [in] datasetName - HDF5 dataset name
868  * @param [out] value - Data to be read
869  */
870 void THDF5_File::ReadScalarValue(const hid_t parentGroup,
871  TMatrixName& datasetName,
872  size_t& value)
873 {
874  ReadCompleteDataset(parentGroup, datasetName, TDimensionSizes(1,1,1), &value);
875 }// end of ReadScalarValue
876 //--------------------------------------------------------------------------------------------------
877 
878 /**
879  * Read data from the dataset at a specified place in the file tree, float version.
880  *
881  * @param [in] parentGroup - Where is the dataset situated
882  * @param [in] datasetName - Dataset name
883  * @param [in] dimensionSizes - Dimension sizes
884  * @param [out] data - Pointer to data
885  * @throw ios::failure
886  */
887 void THDF5_File::ReadCompleteDataset (const hid_t parentGroup,
888  TMatrixName& datasetName,
889  const TDimensionSizes& dimensionSizes,
890  float* data)
891 {
892  const char* cDatasetName = datasetName.c_str();
893  // Check Dimensions sizes
894  if (GetDatasetDimensionSizes(parentGroup, datasetName).GetElementCount() !=
895  dimensionSizes.GetElementCount())
896  {
897  throw ios::failure(TLogger::FormatMessage(ERR_FMT_BAD_DIMENSION_SIZES, cDatasetName));
898  }
899 
900  // read dataset
901  herr_t status = H5LTread_dataset_float(parentGroup, cDatasetName, data);
902  if (status < 0)
903  {
904  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_READ_DATASET, cDatasetName));
905  }
906 }// end of ReadDataset (float)
907 //-------------------------------------------------------------------------------------------------
908 
909 
910 /**
911  * Read data from the dataset at a specified place in the file tree, index version.
912  *
913  * @param [in] parentGroup - Where is the dataset situated
914  * @param [in] datasetName - Dataset name
915  * @param [in] dimensionSizes - Dimension sizes
916  * @param [out] data - Pointer to data
917  * @throw ios::failure
918  */
919 void THDF5_File::ReadCompleteDataset(const hid_t parentGroup,
920  TMatrixName& datasetName,
921  const TDimensionSizes& dimensionSizes,
922  size_t* data)
923 {
924  const char* cDatasetName = datasetName.c_str();
925  if (GetDatasetDimensionSizes(parentGroup, datasetName).GetElementCount() !=
926  dimensionSizes.GetElementCount())
927  {
928  throw ios::failure(TLogger::FormatMessage(ERR_FMT_BAD_DIMENSION_SIZES, cDatasetName));
929  }
930 
931  // read dataset
932  herr_t status = H5LTread_dataset(parentGroup, cDatasetName, H5T_STD_U64LE, data);
933  if (status < 0)
934  {
935  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_READ_DATASET, cDatasetName));
936  }
937 }// end of ReadCompleteDataset
938 //--------------------------------------------------------------------------------------------------
939 
940 
941 /**
942  * Get dimension sizes of the dataset at a specified place in the file tree.
943  *
944  * @param [in] parentGroup - Where the dataset is
945  * @param [in] datasetName - Dataset name
946  * @return Dimension sizes of the dataset
947  * @throw ios::failure
948  */
950  TMatrixName& datasetName)
951 {
952  const size_t ndims = GetDatasetNumberOfDimensions(parentGroup, datasetName);
953 
954  hsize_t dims[4] = {0, 0, 0, 0};
955 
956  herr_t status = H5LTget_dataset_info(parentGroup, datasetName.c_str(), dims, NULL, NULL);
957  if (status < 0)
958  {
959 
960  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_READ_DATASET, datasetName.c_str()));
961  }
962 
963  if (ndims == 3)
964  {
965  return TDimensionSizes(dims[2], dims[1], dims[0]);
966  }
967  else
968  {
969  return TDimensionSizes(dims[3], dims[2], dims[1], dims[0]);
970  }
971 }// end of GetDatasetDimensionSizes
972 //--------------------------------------------------------------------------------------------------
973 
974 /**
975  * Get number of dimensions of the dataset under a specified group.
976  *
977  * @param [in] parentGroup - Where the dataset is
978  * @param [in] datasetName - Dataset name
979  * @return Number of dimensions
980  * @throw ios::failure
981  */
982 size_t THDF5_File::GetDatasetNumberOfDimensions(const hid_t parentGroup,
983  TMatrixName& datasetName)
984 {
985  int dims = 0;
986 
987  herr_t status = H5LTget_dataset_ndims(parentGroup, datasetName.c_str(), &dims);
988  if (status < 0)
989  {
990  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_READ_DATASET, datasetName.c_str()));
991  }
992 
993  return dims;
994 }// end of GetDatasetNumberOfDimensions
995 //--------------------------------------------------------------------------------------------------
996 
997 
998 /**
999  * Get dataset element count at a specified place in the file tree.
1000  *
1001  * @param [in] parentGroup - Where the dataset is
1002  * @param [in] datasetName - Dataset name
1003  * @return Number of elements
1004  * @throw ios::failure
1005  */
1006 size_t THDF5_File::GetDatasetElementCount(const hid_t parentGroup,
1007  TMatrixName& datasetName)
1008 {
1009  hsize_t dims[3] = {0, 0, 0};
1010 
1011  herr_t status = H5LTget_dataset_info(parentGroup, datasetName.c_str(), dims, NULL, NULL);
1012  if (status < 0)
1013  {
1014  throw ios::failure(TLogger::FormatMessage(ERR_FMT_CANNOT_READ_DATASET, datasetName.c_str()));
1015  }
1016 
1017  return dims[0] * dims[1] * dims[2];
1018 }// end of GetDatasetElementCount
1019 //--------------------------------------------------------------------------------------------------
1020 
1021 
1022 /**
1023  * Write matrix data type into the dataset at a specified place in the file tree.
1024  *
1025  * @param [in] parentGroup - Where the dataset is
1026  * @param [in] datasetName - Dataset name
1027  * @param [in] matrixDataType - Matrix data type in the file
1028  */
1029 void THDF5_File::WriteMatrixDataType(const hid_t parentGroup,
1030  TMatrixName& datasetName,
1031  const TMatrixDataType& matrixDataType)
1032 {
1033  WriteStringAttribute(parentGroup,
1034  datasetName,
1036  matrixDataTypeNames[matrixDataType]);
1037 }// end of WriteMatrixDataType
1038 //--------------------------------------------------------------------------------------------------
1039 
1040 
1041 /**
1042  * Write matrix data type into the dataset at a specified place in the file tree.
1043  *
1044  * @param [in] parentGroup - Where the dataset is
1045  * @param [in] datasetName - Dataset name
1046  * @param [in] matrixDomainType - Matrix domain type
1047  */
1048 void THDF5_File::WriteMatrixDomainType(const hid_t parentGroup,
1049  TMatrixName& datasetName,
1050  const TMatrixDomainType& matrixDomainType)
1051 {
1052  WriteStringAttribute(parentGroup,
1053  datasetName,
1055  matrixDomainTypeNames[matrixDomainType]);
1056 }// end of WriteMatrixDomainType
1057 //--------------------------------------------------------------------------------------------------
1058 
1059 
1060 /**
1061  * Read matrix data type from the dataset at a specified place in the file tree.
1062  *
1063  * @param [in] parentGroup - Where the dataset is
1064  * @param [in] datasetName - Dataset name
1065  * @return Matrix data type
1066  * @throw ios::failure
1067  */
1069  TMatrixName& datasetName)
1070 {
1071  string paramValue = ReadStringAttribute(parentGroup, datasetName, matrixDataTypeName);
1072 
1073  if (paramValue == matrixDataTypeNames[0])
1074  {
1075  return static_cast<TMatrixDataType>(0);
1076  }
1077  if (paramValue == matrixDataTypeNames[1])
1078  {
1079  return static_cast<TMatrixDataType>(1);
1080  }
1081 
1083  datasetName.c_str(),
1084  matrixDataTypeName.c_str(),
1085  paramValue.c_str()));
1086 
1087  // this will never be executed (just to prevent warning)
1088  return static_cast<TMatrixDataType> (0);
1089 }// end of ReadMatrixDataType
1090 //--------------------------------------------------------------------------------------------------
1091 
1092 
1093 /**
1094  * Read matrix dataset domain type at a specified place in the file tree.
1095  *
1096  * @param [in] parentGroup - Where the dataset is
1097  * @param [in] datasetName - Dataset name
1098  * @return Matrix domain type
1099  * @throw ios::failure
1100  */
1102  TMatrixName& datasetName)
1103 {
1104  string paramValue = ReadStringAttribute(parentGroup, datasetName, matrixDomainTypeName);
1105 
1106  if (paramValue == matrixDomainTypeNames[0])
1107  {
1108  return static_cast<TMatrixDomainType> (0);
1109  }
1110  if (paramValue == matrixDomainTypeNames[1])
1111  {
1112  return static_cast<TMatrixDomainType> (1);
1113  }
1114 
1116  datasetName.c_str(),
1117  matrixDomainTypeName.c_str(),
1118  paramValue.c_str()));
1119 
1120  // This line will never be executed (just to prevent warning)
1121  return static_cast<TMatrixDomainType> (0);
1122 }// end of ReadMatrixDomainType
1123 //--------------------------------------------------------------------------------------------------
1124 
1125 
1126 /**
1127  * Write integer attribute at a specified place in the file tree.
1128  *
1129  * @param [in] parentGroup - Where the dataset is
1130  * @param [in] datasetName - Dataset name
1131  * @param [in] attributeName - Attribute name
1132  * @param [in] value - Data to write
1133  * @throw ios::failure
1134  */
1135 inline void THDF5_File::WriteStringAttribute(const hid_t parentGroup,
1136  TMatrixName& datasetName,
1137  TMatrixName& attributeName,
1138  const string& value)
1139 {
1140  herr_t status = H5LTset_attribute_string(parentGroup,
1141  datasetName.c_str(),
1142  attributeName.c_str(),
1143  value.c_str());
1144  if (status < 0)
1145  {
1147  attributeName.c_str(),
1148  datasetName.c_str()));
1149  }
1150 }// end of WriteIntAttribute
1151 //--------------------------------------------------------------------------------------------------
1152 
1153 
1154 /**
1155  * Read integer attribute at a specified place in the file tree.
1156  *
1157  * @param [in] parentGroup - Where the dataset is
1158  * @param [in] datasetName - Dataset name
1159  * @param [in] attributeName - Attribute name
1160  * @return Attribute value
1161  * @throw ios::failure
1162  */
1163 inline string THDF5_File::ReadStringAttribute(const hid_t parentGroup,
1164  TMatrixName& datasetName,
1165  TMatrixName& attributeName)
1166 {
1167  char value[256] = "";
1168  herr_t status = H5LTget_attribute_string(parentGroup,
1169  datasetName.c_str(),
1170  attributeName.c_str(),
1171  value);
1172 
1173  if (status < 0)
1174  {
1176  attributeName.c_str(),
1177  datasetName.c_str()));
1178  }
1179 
1180  return string(value);
1181 }// end of ReadIntAttribute
1182 //--------------------------------------------------------------------------------------------------
1183 
1184 
1185 //------------------------------------------------------------------------------------------------//
1186 //------------------------------------------ THDF5_File ------------------------------------------//
1187 //-------------------------------------- Protected methods ---------------------------------------//
1188 //------------------------------------------------------------------------------------------------//
1189 
1190 
1191 //------------------------------------------------------------------------------------------------//
1192 //------------------------------------------ THDF5_File ------------------------------------------//
1193 //--------------------------------------- Private methods ----------------------------------------//
1194 //------------------------------------------------------------------------------------------------//
1195 
1196 
1197 //------------------------------------------------------------------------------------------------//
1198 //-------------------------------------- THDF5_File_Header ---------------------------------------//
1199 //--------------------------------------- Public methods -----------------------------------------//
1200 //------------------------------------------------------------------------------------------------//
1201 
1202 /**
1203  * Constructor.
1204  */
1206 {
1207  headerValues.clear();
1209 }// end of constructor
1210 //--------------------------------------------------------------------------------------------------
1211 
1212 /**
1213  * Copy constructor.
1214  * @param [in] src - Source object
1215  */
1217 {
1218  headerValues = src.headerValues;
1219  headerNames = src.headerNames;
1220 }// end of copy constructor
1221 //--------------------------------------------------------------------------------------------------
1222 
1223 /**
1224  * Destructor.
1225  *
1226  */
1228 {
1229  headerValues.clear();
1230  headerNames.clear();
1231 }// end of destructor
1232 //--------------------------------------------------------------------------------------------------
1233 
1234 
1235 /**
1236  * Read header from the input file.
1237  *
1238  * @param [in, out] inputFile - Input file handle
1239  * @throw ios:failure when en error happens
1240  */
1242 {
1243  // Get file root handle
1244  hid_t rootGroup = inputFile.GetRootGroup();
1245  // read file type
1246  headerValues[FILE_TYPE] =
1247  inputFile.ReadStringAttribute(rootGroup,
1248  "/",
1249  headerNames[FILE_TYPE].c_str());
1250 
1251  if (GetFileType() == INPUT)
1252  {
1253  headerValues[CREATED_BY]
1254  = inputFile.ReadStringAttribute(rootGroup,
1255  "/",
1256  headerNames[CREATED_BY].c_str());
1257  headerValues[CREATION_DATA]
1258  = inputFile.ReadStringAttribute(rootGroup,
1259  "/",
1260  headerNames[CREATION_DATA].c_str());
1261  headerValues[FILE_DESCRIPTION]
1262  = inputFile.ReadStringAttribute(rootGroup,
1263  "/",
1264  headerNames[FILE_DESCRIPTION].c_str());
1265  headerValues[MAJOR_VERSION]
1266  = inputFile.ReadStringAttribute(rootGroup,
1267  "/",
1268  headerNames[MAJOR_VERSION].c_str());
1269  headerValues[MINOR_VERSION]
1270  = inputFile.ReadStringAttribute(rootGroup,
1271  "/",
1272  headerNames[MINOR_VERSION].c_str());
1273  }
1274  else
1275  {
1276  throw ios::failure(ERR_FMT_BAD_INPUT_FILE_TYPE);
1277  }
1278 }// end of ReadHeaderFromInputFile
1279 //--------------------------------------------------------------------------------------------------
1280 
1281 
1282 /**
1283  * Read header from output file (necessary for checkpoint-restart). Read only execution times
1284  * (the others are read from the input file, or calculated based on the very last leg of the
1285  * simulation).
1286  * This function is called only if checkpoint-restart is enabled.
1287  *
1288  * @param [in, out] outputFile - Output file handle
1289  */
1291 {
1292  // Get file root handle
1293  hid_t rootGroup = outputFile.GetRootGroup();
1294 
1295  headerValues[FILE_TYPE]
1296  = outputFile.ReadStringAttribute(rootGroup,
1297  "/",
1298  headerNames[FILE_TYPE].c_str());
1299 
1300  if (GetFileType() == OUTPUT)
1301  {
1302  headerValues[TOTAL_EXECUTION_TIME]
1303  = outputFile.ReadStringAttribute(rootGroup,
1304  "/",
1305  headerNames[TOTAL_EXECUTION_TIME].c_str());
1306  headerValues[DATA_LOAD_TIME]
1307  = outputFile.ReadStringAttribute(rootGroup,
1308  "/",
1309  headerNames[DATA_LOAD_TIME].c_str());
1310  headerValues[PREPROCESSING_TIME]
1311  = outputFile.ReadStringAttribute(rootGroup,
1312  "/",
1313  headerNames[PREPROCESSING_TIME].c_str());
1314  headerValues[SIMULATION_TIME]
1315  = outputFile.ReadStringAttribute(rootGroup,
1316  "/",
1317  headerNames[SIMULATION_TIME].c_str());
1318  headerValues[POST_PROCESSING_TIME]
1319  = outputFile.ReadStringAttribute(rootGroup,
1320  "/",
1321  headerNames[POST_PROCESSING_TIME].c_str());
1322  }
1323  else
1324  {
1325  throw ios::failure(ERR_FMT_BAD_OUTPUT_FILE_TYPE);
1326  }
1327 }// end of ReadHeaderFromOutputFile
1328 //--------------------------------------------------------------------------------------------------
1329 
1330 
1331 /**
1332  * Read the file header form the checkpoint file. We need the header to verify the file version
1333  * and type.
1334  * @param [in, out] checkpointFile - Checkpoint file handle
1335  */
1337 {
1338  // Get file root handle
1339  hid_t rootGroup = checkpointFile.GetRootGroup();
1340  // read file type
1341  headerValues[FILE_TYPE] =
1342  checkpointFile.ReadStringAttribute(rootGroup, "/", headerNames[FILE_TYPE]);
1343 
1344  if (GetFileType() == CHECKPOINT)
1345  {
1346  headerValues[CREATED_BY]
1347  = checkpointFile.ReadStringAttribute(rootGroup, "/", headerNames[CREATED_BY]);
1348  headerValues[CREATION_DATA]
1349  = checkpointFile.ReadStringAttribute(rootGroup, "/", headerNames[CREATION_DATA]);
1350  headerValues[FILE_DESCRIPTION]
1351  = checkpointFile.ReadStringAttribute(rootGroup, "/", headerNames[FILE_DESCRIPTION]);
1352  headerValues[MAJOR_VERSION]
1353  = checkpointFile.ReadStringAttribute(rootGroup, "/", headerNames[MAJOR_VERSION]);
1354  headerValues[MINOR_VERSION]
1355  = checkpointFile.ReadStringAttribute(rootGroup, "/", headerNames[MINOR_VERSION]);
1356  }
1357  else
1358  {
1359  throw ios::failure(ERR_FMT_BAD_CHECKPOINT_FILE_TYPE);
1360  }
1361 }// end of ReadHeaderFromCheckpointFile
1362 //--------------------------------------------------------------------------------------------------
1363 
1364 /**
1365  * Write header into the output file.
1366  *
1367  * @param [in,out] outputFile - Output file handle
1368  */
1370 {
1371  // Get file root handle
1372  hid_t rootGroup = outputFile.GetRootGroup();
1373 
1374  for (const auto& it : headerNames)
1375  {
1376  outputFile.WriteStringAttribute(rootGroup, "/", it.second, headerValues[it.first]);
1377  }
1378 }// end of WriteHeaderToOutputFile
1379 //--------------------------------------------------------------------------------------------------
1380 
1381 /**
1382  * Write header to the output file (only a subset of all possible fields are written).
1383  *
1384  * @param [in, out] checkpointFile - Checkpoint file handle
1385  */
1387 {
1388  // Get file root handle
1389  hid_t rootGroup = checkpointFile.GetRootGroup();
1390 
1391  // Write header
1392  checkpointFile.WriteStringAttribute(rootGroup,
1393  "/",
1394  headerNames [FILE_TYPE].c_str(),
1395  headerValues[FILE_TYPE].c_str());
1396 
1397  checkpointFile.WriteStringAttribute(rootGroup,
1398  "/",
1399  headerNames [CREATED_BY].c_str(),
1400  headerValues[CREATED_BY].c_str());
1401 
1402  checkpointFile.WriteStringAttribute(rootGroup,
1403  "/",
1404  headerNames [CREATION_DATA].c_str(),
1405  headerValues[CREATION_DATA].c_str());
1406 
1407  checkpointFile.WriteStringAttribute(rootGroup,
1408  "/",
1409  headerNames [FILE_DESCRIPTION].c_str(),
1410  headerValues[FILE_DESCRIPTION].c_str());
1411 
1412  checkpointFile.WriteStringAttribute(rootGroup,
1413  "/",
1414  headerNames [MAJOR_VERSION].c_str(),
1415  headerValues[MAJOR_VERSION].c_str());
1416 
1417  checkpointFile.WriteStringAttribute(rootGroup,
1418  "/",
1419  headerNames [MINOR_VERSION].c_str(),
1420  headerValues[MINOR_VERSION].c_str());
1421 }// end of WriteHeaderToCheckpointFile
1422 //--------------------------------------------------------------------------------------------------
1423 
1424 
1425 /**
1426  * Set actual date and time.
1427  *
1428  */
1430 {
1431  struct tm *current;
1432  time_t now;
1433  time(&now);
1434  current = localtime(&now);
1435 
1436  headerValues[CREATION_DATA] = TLogger::FormatMessage("%02i/%02i/%02i, %02i:%02i:%02i",
1437  current->tm_mday, current->tm_mon + 1, current->tm_year - 100,
1438  current->tm_hour, current->tm_min, current->tm_sec);
1439 
1440 }// end of SetCreationTime
1441 //--------------------------------------------------------------------------------------------------
1442 
1443 /**
1444  * Get file version as an enum.
1445  * @return File version as an enum
1446  */
1448 {
1449  if ((headerValues[MAJOR_VERSION] == hdf5_MajorFileVersionsNames[0]) &&
1450  (headerValues[MINOR_VERSION] == hdf5_MinorFileVersionsNames[0]))
1451  {
1452  return VERSION_10;
1453  }
1454 
1455  if ((headerValues[MAJOR_VERSION] == hdf5_MajorFileVersionsNames[0]) &&
1456  (headerValues[MINOR_VERSION] == hdf5_MinorFileVersionsNames[1]))
1457  {
1458  return VERSION_11;
1459  }
1460 
1461  return VERSION_UNKNOWN;
1462 }// end of GetFileVersion
1463 //--------------------------------------------------------------------------------------------------
1464 
1465 
1466 
1467 /**
1468  * Get File type.
1469  *
1470  * @return File type
1471  */
1473 {
1474  for (int i = INPUT; i < UNKNOWN ; i++)
1475  {
1476  if (headerValues[FILE_TYPE] == hdf5_FileTypesNames[static_cast<TFileType >(i)])
1477  {
1478  return static_cast<TFileType >(i);
1479  }
1480  }
1481 
1482  return THDF5_FileHeader::UNKNOWN;
1483 }// end of GetFileType
1484 //--------------------------------------------------------------------------------------------------
1485 
1486 /**
1487  * Set File type.
1488  *
1489  * @param [in] fileType - File type
1490  */
1492 {
1493  headerValues[FILE_TYPE] = hdf5_FileTypesNames[fileType];
1494 }// end of SetFileType
1495 //--------------------------------------------------------------------------------------------------
1496 
1497 
1498 
1499 /**
1500  * Set Host name.
1501  *
1502  */
1504 {
1505  char hostName[256];
1506 
1507  //Linux build
1508  #ifdef __linux__
1509  gethostname(hostName, 256);
1510  #endif
1511 
1512  //Windows build
1513  #ifdef _WIN64
1514  WSADATA wsaData;
1515  WSAStartup(MAKEWORD(2, 2), &wsaData);
1516  gethostname(hostName, 256);
1517 
1518  WSACleanup();
1519  #endif
1520 
1521  headerValues[HOST_NAME] = hostName;
1522 }// end of SetHostName
1523 //--------------------------------------------------------------------------------------------------
1524 
1525 
1526 /**
1527  * Set memory consumption.
1528  *
1529  * @param [in] totalMemory - Total memory consumption
1530  */
1531 void THDF5_FileHeader::SetMemoryConsumption(const size_t totalMemory)
1532 {
1533  headerValues[TOTAL_MEMORY_CONSUMPTION] = TLogger::FormatMessage("%ld MB", totalMemory);
1534 
1535  headerValues[PEAK_CORE_MEMORY_CONSUMPTION]
1536  = TLogger::FormatMessage("%ld MB",
1537  totalMemory / TParameters::GetInstance().GetNumberOfThreads());
1538 
1539 }// end of SetMemoryConsumption
1540 //--------------------------------------------------------------------------------------------------
1541 
1542 
1543 /**
1544  * Set execution times in file header.
1545  *
1546  * @param [in] totalTime - Total time
1547  * @param [in] loadTime - Time to load data
1548  * @param [in] preProcessingTime - Preprocessing time
1549  * @param [in] simulationTime - Simulation time
1550  * @param [in] postprocessingTime - Post processing time
1551  */
1552 void THDF5_FileHeader::SetExecutionTimes(const double totalTime,
1553  const double loadTime,
1554  const double preProcessingTime,
1555  const double simulationTime,
1556  const double postprocessingTime)
1557 {
1558  headerValues[TOTAL_EXECUTION_TIME] = TLogger::FormatMessage("%8.2fs", totalTime);
1559  headerValues[DATA_LOAD_TIME] = TLogger::FormatMessage("%8.2fs", loadTime);
1560  headerValues[PREPROCESSING_TIME] = TLogger::FormatMessage("%8.2fs", preProcessingTime);
1561  headerValues[SIMULATION_TIME] = TLogger::FormatMessage("%8.2fs", simulationTime);
1562  headerValues[POST_PROCESSING_TIME] = TLogger::FormatMessage("%8.2fs", postprocessingTime);
1563 }// end of SetExecutionTimes
1564 //--------------------------------------------------------------------------------------------------
1565 
1566 /**
1567  * Get execution times stored in the output file header.
1568  *
1569  * @param [out] totalTime - Total time
1570  * @param [out] loadTime - Time to load data
1571  * @param [out] preProcessingTime - Preprocessing time
1572  * @param [out] simulationTime - Simulation time
1573  * @param [out] postprocessingTime - Post processing time
1574  */
1576  double& loadTime,
1577  double& preProcessingTime,
1578  double& simulationTime,
1579  double& postprocessingTime)
1580 {
1581  totalTime = std::stof(headerValues[TOTAL_EXECUTION_TIME]);
1582  loadTime = std::stof(headerValues[DATA_LOAD_TIME]);
1583  preProcessingTime = std::stof(headerValues[PREPROCESSING_TIME]);
1584  simulationTime = std::stof(headerValues[SIMULATION_TIME]);
1585  postprocessingTime = std::stof(headerValues[POST_PROCESSING_TIME]);
1586 }// end of GetExecutionTimes
1587 //--------------------------------------------------------------------------------------------------
1588 
1589 /**
1590  * Set Number of cores.
1591  *
1592  */
1594 {
1595  headerValues[NUMBER_OF_CORES]
1596  = TLogger::FormatMessage("%ld", TParameters::GetInstance().GetNumberOfThreads());
1597 }// end of SetNumberOfCores
1598 //--------------------------------------------------------------------------------------------------
1599 
1600 //------------------------------------------------------------------------------------------------//
1601 //-------------------------------------- THDF5_File_Header ---------------------------------------//
1602 //-------------------------------------- Protected methods ---------------------------------------//
1603 //------------------------------------------------------------------------------------------------//
1604 
1605 /**
1606  * Create map with names for the header.
1607  *
1608  */
1610 {
1611  headerNames.clear();
1612 
1613  headerNames[CREATED_BY] = "created_by";
1614  headerNames[CREATION_DATA] = "creation_date";
1615  headerNames[FILE_DESCRIPTION] = "file_description";
1616  headerNames[MAJOR_VERSION] = "major_version";
1617  headerNames[MINOR_VERSION] = "minor_version";
1618  headerNames[FILE_TYPE] = "file_type";
1619 
1620  headerNames[HOST_NAME] = "host_names";
1621  headerNames[NUMBER_OF_CORES] = "number_of_cpu_cores";
1622  headerNames[TOTAL_MEMORY_CONSUMPTION] = "total_memory_in_use";
1623  headerNames[PEAK_CORE_MEMORY_CONSUMPTION] = "peak_core_memory_in_use";
1624 
1625  headerNames[TOTAL_EXECUTION_TIME] = "total_execution_time";
1626  headerNames[DATA_LOAD_TIME] = "data_loading_phase_execution_time";
1627  headerNames[PREPROCESSING_TIME] = "pre-processing_phase_execution_time";
1628  headerNames[SIMULATION_TIME] = "simulation_phase_execution_time";
1629  headerNames[POST_PROCESSING_TIME] = "post-processing_phase_execution_time";
1630 }// end of PopulateHeaderFileMap
1631 //--------------------------------------------------------------------------------------------------
Class for HDF5 header.
Definition: HDF5_File.h:730
TErrorMessage ERR_FMT_CANNOT_CREATE_GROUP
HDF5 error message.
size_t nx
number of elements in the x direction
size_t GetDatasetNumberOfDimensions(const hid_t parentGroup, TMatrixName &datasetName)
Get number of dimensions of the dataset under a specified group.
Definition: HDF5_File.cpp:982
hid_t CreateFloatDataset(const hid_t parentGroup, TMatrixName &datasetName, const TDimensionSizes &dimensionSizes, const TDimensionSizes &chunkSizes, const size_t compressionLevel)
Create a float HDF5 dataset at a specified place in the file tree (3D/4D).
Definition: HDF5_File.cpp:296
void WriteMatrixDomainType(const hid_t parentGroup, TMatrixName &datasetName, const TMatrixDomainType &matrixDomainType)
Write matrix domain type into the dataset under the root group.
Definition: HDF5_File.cpp:1048
std::string ReadStringAttribute(const hid_t parentGroup, TMatrixName &datasetName, TMatrixName &attributeName)
Read string attribute from the dataset under the root group.
Definition: HDF5_File.cpp:1163
TMatrixDataType
HDF5 matrix data type (float or uint64).
Definition: HDF5_File.h:509
void SetFileType(const THDF5_FileHeader::TFileType fileType)
Set file type.
Definition: HDF5_File.cpp:1491
TErrorMessage ERR_FMT_CANNOT_RECREATE_FILE
HDF5 error message.
Definition: ErrorMessages.h:68
size_t nt
Number of time steps (for time series datasets).
TErrorMessage ERR_FMT_CANNOT_OPEN_GROUP
HDF5 error message.
THDF5_FileHeader()
Constructor.
Definition: HDF5_File.cpp:1205
static const std::string hdf5_MajorFileVersionsNames[]
String representations of Major file versions.
Definition: HDF5_File.h:915
static const std::string matrixDomainTypeName
String representation of the Domain type in the HDF5 file.
Definition: HDF5_File.h:707
void Open(const std::string &fileName, unsigned int flags=H5F_ACC_RDONLY)
Open a file.
Definition: HDF5_File.cpp:127
TErrorMessage ERR_FMT_CANNOT_CREATE_FILE
HDF5 error message.
Definition: ErrorMessages.h:65
void GetExecutionTimes(double &totalTime, double &loadTime, double &preProcessingTime, double &simulationTime, double &postprocessingTime)
Get execution times stored in the output file header.
Definition: HDF5_File.cpp:1575
TMatrixDomainType
HDF5 Matrix domain type (real or complex).
Definition: HDF5_File.h:520
TErrorMessage ERR_FMT_CANNOT_OPEN_DATASET
HDF5 error message.
Definition: ErrorMessages.h:92
TErrorMessage ERR_FMT_BAD_ATTRIBUTE_VALUE
HDF5 error message.
Definition: ErrorMessages.h:98
static TParameters & GetInstance()
Get instance of the singleton class.
Definition: Parameters.cpp:70
TErrorMessage ERR_FMT_FILE_NOT_OPEN
HDF5 error message.
Definition: ErrorMessages.h:86
TErrorMessage ERR_FMT_CANNOT_WRITE_DATASET
HDF5 error message.
Definition: ErrorMessages.h:77
std::map< TFileHeaderItems, std::string > headerNames
map for the header names.
Definition: HDF5_File.h:910
static const std::string hdf5_FileTypesNames[]
String representation of different file types.
Definition: HDF5_File.h:913
void SetExecutionTimes(const double totalTime, const double loadTime, const double preProcessingTime, const double simulationTime, const double postprocessingTime)
Set execution times.
Definition: HDF5_File.cpp:1552
hid_t CreateGroup(const hid_t parentGroup, TMatrixName &groupName)
Create a HDF5 group at a specified place in the file tree.
Definition: HDF5_File.cpp:208
THDF5_File::TMatrixDataType ReadMatrixDataType(const hid_t parentGroup, TMatrixName &datasetName)
Read matrix data type from the dataset.
Definition: HDF5_File.cpp:1068
void WriteScalarValue(const hid_t parentGroup, TMatrixName &datasetName, const float value)
Write the scalar value under a specified group, float value.
Definition: HDF5_File.cpp:748
TErrorMessage ERR_FMT_BAD_CHECKPOINT_FILE_TYPE
HDF5 error message.
void Close()
Close file.
Definition: HDF5_File.cpp:175
void WriteCuboidToHyperSlab(const hid_t dataset, const TDimensionSizes &hyperslabPosition, const TDimensionSizes &cuboidPosition, const TDimensionSizes &cuboidSize, const TDimensionSizes &matrixDimensions, const float *mMatrixData)
Write a cuboid selected within the matrixData into a hyperslab.
Definition: HDF5_File.cpp:618
TErrorMessage ERR_FMT_NOT_HDF5_FILE
HDF5 error message.
Definition: ErrorMessages.h:89
The header file containing the HDF5 related classes.
The header file containing the parameters of the simulation.
bool IsOpen() const
Is the file opened?
Definition: HDF5_File.h:545
void PopulateHeaderFileMap()
Populate the map with the header items.
Definition: HDF5_File.cpp:1609
hid_t file
HDF file handle.
Definition: HDF5_File.h:717
const std::string TMatrixName
Datatype for matrix names.
Definition: MatrixNames.h:45
void ReadHeaderFromCheckpointFile(THDF5_File &checkpointFile)
Read Header from checkpoint file (necessary for checkpoint-restart).
Definition: HDF5_File.cpp:1336
void WriteHeaderToCheckpointFile(THDF5_File &checkpointFile)
Write header to the output file.
Definition: HDF5_File.cpp:1386
TDimensionSizes GetDatasetDimensionSizes(const hid_t parentGroup, TMatrixName &datasetName)
Get dimension sizes of the dataset under a specified group.
Definition: HDF5_File.cpp:949
void WriteHeaderToOutputFile(THDF5_File &outputFile)
Write header to the output file.
Definition: HDF5_File.cpp:1369
void WriteMatrixDataType(const hid_t parentGroup, TMatrixName &datasetName, const TMatrixDataType &matrixDataType)
Write matrix data type into the dataset under a specified group.
Definition: HDF5_File.cpp:1029
void ReadHeaderFromOutputFile(THDF5_File &outputFile)
Read Header from output file (necessary for checkpoint-restart).
Definition: HDF5_File.cpp:1290
THDF5_File()
Constructor of the class.
Definition: HDF5_File.cpp:82
void SetHostName()
Set host name.
Definition: HDF5_File.cpp:1503
The header file containing a class responsible for printing out info and error messages (stdout...
TErrorMessage ERR_FMT_CANNOT_SET_COMPRESSION
HDF5 error message.
Definition: ErrorMessages.h:95
void ReadScalarValue(const hid_t parentGroup, TMatrixName &datasetName, float &value)
Read the scalar value under a specified group, float value.
Definition: HDF5_File.cpp:855
static const std::string matrixDataTypeNames[]
String representation of different data types.
Definition: HDF5_File.h:714
void ReadHeaderFromInputFile(THDF5_File &inputFile)
Read header from the input file.
Definition: HDF5_File.cpp:1241
TErrorMessage ERR_FMT_CANNOT_CLOSE_FILE
HDF5 error message.
Definition: ErrorMessages.h:74
void WriteStringAttribute(const hid_t parentGroup, TMatrixName &datasetName, TMatrixName &attributeName, const std::string &value)
Write string attribute into the dataset under the root group.
Definition: HDF5_File.cpp:1135
static const std::string hdf5_MinorFileVersionsNames[]
String representations of Major file versions.
Definition: HDF5_File.h:917
static bool IsHDF5(const std::string &fileName)
Does the file exist?
Definition: HDF5_File.cpp:158
hid_t GetRootGroup() const
Get handle to the root group.
Definition: HDF5_File.h:573
TFileVersion
HDF5 file version.
Definition: HDF5_File.h:777
The header file containing routines for error messages and error messages common for both linux and w...
~THDF5_FileHeader()
Destructor.
Definition: HDF5_File.cpp:1227
size_t GetElementCount() const
Get element count, in 3D only spatial domain, in 4D with time.
size_t ny
number of elements in the y direction
TFileType
HDF5 file type.
Definition: HDF5_File.h:764
static const std::string matrixDomainTypeNames[]
String representation of different domain types.
Definition: HDF5_File.h:712
void Create(const std::string &fileName, unsigned int flags=H5F_ACC_TRUNC)
Create a file.
Definition: HDF5_File.cpp:97
TErrorMessage ERR_FMT_CANNOT_REOPEN_FILE
HDF5 error message.
Definition: ErrorMessages.h:71
void WriteDataByMaskToHyperSlab(const hid_t dataset, const TDimensionSizes &hyperslabPosition, const size_t indexSensorSize, const size_t *indexSensorData, const TDimensionSizes &matrixDimensions, const float *matrixData)
Write sensor data selected by the sensor mask - Occasionally very slow, do not use! ...
Definition: HDF5_File.cpp:686
void SetActualCreationTime()
Set creation time.
Definition: HDF5_File.cpp:1429
THDF5_FileHeader::TFileType GetFileType()
Get File type.
Definition: HDF5_File.cpp:1472
TFileVersion GetFileVersion()
Set major file version in a string.
Definition: HDF5_File.cpp:1447
hid_t CreateIndexDataset(const hid_t parentGroup, TMatrixName &datasetName, const TDimensionSizes &dimensionSizes, const TDimensionSizes &chunkSizes, const size_t compressionLevel)
Create an index HDF5 dataset at a specified place in the file tree (3D only).
Definition: HDF5_File.cpp:392
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:126
TErrorMessage ERR_FMT_BAD_OUTPUT_FILE_TYPE
HDF5 error message.
void SetNumberOfCores()
Set number of cores.
Definition: HDF5_File.cpp:1593
THDF5_File::TMatrixDomainType ReadMatrixDomainType(const hid_t parentGroup, TMatrixName &datasetName)
Read matrix domain type from the dataset under a specified group.
Definition: HDF5_File.cpp:1101
void WriteHyperSlab(const hid_t dataset, const TDimensionSizes &position, const TDimensionSizes &size, const float *data)
Write a hyper-slab into the dataset - float dataset.
Definition: HDF5_File.cpp:473
static const std::string matrixDataTypeName
String representation of the Data type in the HDF5 file.
Definition: HDF5_File.h:709
TErrorMessage ERR_FMT_CANNOT_READ_DATASET
HDF5 error message.
Definition: ErrorMessages.h:80
TErrorMessage ERR_FMT_CANNOT_READ_ATTRIBUTE
HDF5 error message.
TErrorMessage ERR_FMT_BAD_DIMENSION_SIZES
HDF5 error message.
Definition: ErrorMessages.h:83
hid_t OpenGroup(const hid_t parentGroup, TMatrixName &groupName)
Open a HDF5 group at a specified place in the file tree.
Definition: HDF5_File.cpp:232
size_t nz
number of elements in the z direction
void CloseGroup(const hid_t group)
Close group.
Definition: HDF5_File.cpp:254
virtual ~THDF5_File()
Destructor.
Definition: HDF5_File.cpp:193
size_t GetDatasetElementCount(const hid_t parentGroup, TMatrixName &datasetName)
Get dataset element count under a specified group.
Definition: HDF5_File.cpp:1006
void ReadCompleteDataset(const hid_t parentGroup, TMatrixName &datasetName, const TDimensionSizes &dimensionSizes, float *data)
Read data from the dataset under a specified group, float dataset.
Definition: HDF5_File.cpp:887
TErrorMessage ERR_FMT_CANNOT_WRITE_ATTRIBUTE
HDF5 error message.
std::string fileName
File name.
Definition: HDF5_File.h:719
void CloseDataset(const hid_t dataset)
Close the HDF5 dataset.
Definition: HDF5_File.cpp:457
TErrorMessage ERR_FMT_BAD_INPUT_FILE_TYPE
HDF5 error message.
Class wrapping the HDF5 routines.
Definition: HDF5_File.h:500
std::map< TFileHeaderItems, std::string > headerValues
map for the header values.
Definition: HDF5_File.h:908
Structure with 4D dimension sizes (3 in space and 1 in time).
bool Is3D() const
Does the object include spatial dimensions only?
void SetMemoryConsumption(const size_t totalMemory)
Set memory consumption.
Definition: HDF5_File.cpp:1531
hid_t OpenDataset(const hid_t parentGroup, TMatrixName &datasetName)
Open the HDF5 dataset at a specified place in the file tree.
Definition: HDF5_File.cpp:268