1 /*
2  MDAL - Mesh Data Abstraction Library (MIT License)
3  Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
4 */
5 
6 #ifndef MDAL_XMDF_HPP
7 #define MDAL_XMDF_HPP
8 
9 #include <string>
10 #include <vector>
11 #include <memory>
12 #include <iosfwd>
13 #include <iostream>
14 #include <fstream>
15 
16 #include "mdal_data_model.hpp"
17 #include "mdal.h"
18 #include "mdal_hdf5.hpp"
19 #include "mdal_driver.hpp"
20 
21 namespace MDAL
22 {
23 
24   /**
25    * The XmdfDataset reads the data directly from HDF5 file
26    * by usage of hyperslabs retrieval. This format is used by TUFLOW and HYDRO_AS-2D
27    * basically all (timesteps) data for one particular dataset groups
28    * are stored in single
29    *   3D arrays (time, x, y) for vector datasets
30    *   2D arrays (time, x) for scalar datasets
31    *   2D arrays (time, active) for active flags (optional, supported by default)
32    *
33    * For TUFLOW, the dataset groups are structured with a tree starting from a unique group and datasets support active flag value.
34    *
35    * For HYDRO_AS-2D, all the groups are on the root of the file and the datasets don't support active flag value.
36    *
37    */
38   class XmdfDataset: public Dataset2D
39   {
40     public:
41       XmdfDataset( DatasetGroup *grp,
42                    const HdfDataset &valuesDs,
43                    const HdfDataset &activeDs,
44                    hsize_t timeIndex );
45       ~XmdfDataset() override;
46 
47       size_t scalarData( size_t indexStart, size_t count, double *buffer ) override;
48       size_t vectorData( size_t indexStart, size_t count, double *buffer ) override;
49       size_t activeData( size_t indexStart, size_t count, int *buffer ) override;
50 
51       const HdfDataset &dsValues() const;
52       const HdfDataset &dsActive() const;
53       hsize_t timeIndex() const;
54 
55     private:
56       HdfDataset mHdf5DatasetValues;
57       HdfDataset mHdf5DatasetActive;
58       // index or row where the data for this timestep begins
59       hsize_t mTimeIndex;
60   };
61 
62   class DriverXmdf: public Driver
63   {
64     public:
65       /**
66        * Driver for XMDF Files
67        *
68        * Structure of the TUFLOW file. Groups are optional since it depends
69        * on tools which groups are created.
70        * - root
71        *   - Temporal
72        *     - Depth
73        *     - Velocity
74        *     - ..
75        *   - Maximums
76        *     - Depth
77        *     - Velocity
78        *     - ..
79        *   - Difference (res_to_res.exe TUFLOW utility tool)
80        *     - ..
81        *   - Times (e.g. time of peak velocity)
82        *     - ..
83        *   - ...
84        */
85       DriverXmdf();
86       ~DriverXmdf( ) override = default;
87       DriverXmdf *create() override;
88 
89       bool canReadDatasets( const std::string &uri ) override;
90       void load( const std::string &datFile, Mesh *mesh ) override;
91 
92     private:
93       MDAL::Mesh *mMesh = nullptr;
94       std::string mDatFile;
95       std::shared_ptr<MDAL::DatasetGroup> readXmdfGroupAsDatasetGroup(
96         const HdfGroup &rootGroup,
97         const std::string &groupName,
98         size_t vertexCount,
99         size_t faceCount ) const;
100 
101       void addDatasetGroupsFromXmdfGroup(
102         DatasetGroups &groups,
103         const HdfGroup &rootGroup,
104         const std::string &nameSuffix,
105         size_t vertexCount,
106         size_t faceCount ) const;
107 
108       void readGroupsTree( HdfFile &file,
109                            const std::string &name,
110                            MDAL::DatasetGroups &groups,
111                            size_t vertexCount,
112                            size_t faceCount ) const;
113 
114   };
115 
116 } // namespace MDAL
117 #endif //MDAL_ASCII_DAT_HPP
118