1 | /*! \brief This class read a Grid raw data format |
2 | * |
3 | * A grid row data format is very simple. The first n numbers indicate the |
4 | * size in every dimension of the grid. The other is the data contained by the grid. |
5 | * In particular if we are in 3D and we are saving a 45x50x30 grid after the 3 numbers |
6 | * I am expecting 45x50x30 = 67500 objects of type T. There is no check the dimensionality |
7 | * is correct, neither the type is correct |
8 | * |
9 | * \tparam dim dimensionality of the grid |
10 | * \tparam T type of the grid |
11 | * |
12 | */ |
13 | #include <iostream> |
14 | #include <Grid/map_grid.hpp> |
15 | #include <fstream> |
16 | |
17 | #define FORTRAN_STYLE 1 |
18 | #define STRUCT_OF_ARRAY 2 |
19 | |
20 | /*! \brief This is the scalar case |
21 | * |
22 | * \tparam T scalar type |
23 | * |
24 | */ |
25 | template<unsigned int dim, typename Tg, typename Tr, unsigned int i> |
26 | struct meta_raw_read |
27 | { |
28 | static inline void read(grid_cpu<dim,Tg> & gr,std::ifstream & raw) |
29 | { |
30 | auto it = gr.getIterator(); |
31 | |
32 | while (it.isNext()) |
33 | { |
34 | auto key = it.get(); |
35 | |
36 | raw.read((char *)&gr.template get<i>(key),sizeof(Tr)); |
37 | |
38 | ++it; |
39 | } |
40 | } |
41 | }; |
42 | |
43 | /*! \brief This is the vector case |
44 | * |
45 | * \tparam T vector type |
46 | * |
47 | */ |
48 | template<unsigned int dim, typename Tg, typename Tr ,unsigned int i, unsigned int nv> |
49 | struct meta_raw_read<dim,Tg,Tr[nv],i> |
50 | { |
51 | static inline void read(grid_cpu<dim,Tg> & gr,std::ifstream & raw) |
52 | { |
53 | for (size_t k = 0 ; k < nv ; k++) |
54 | { |
55 | auto it = gr.getIterator(); |
56 | |
57 | while (it.isNext()) |
58 | { |
59 | auto key = it.get(); |
60 | |
61 | raw.read((char *)&gr.template get<i>(key)[k],sizeof(Tr)); |
62 | |
63 | ++it; |
64 | } |
65 | } |
66 | } |
67 | }; |
68 | |
69 | /*! \brief this class is a functor for "for_each" algorithm |
70 | * |
71 | * This class is a functor for "for_each" algorithm. For each |
72 | * element of the boost::vector the operator() is called. |
73 | * Is mainly used to read each property |
74 | * |
75 | * \tparam ele_g element that store the grid and its attributes |
76 | * \param St type of space where the grid live |
77 | * |
78 | */ |
79 | template<unsigned int dim, typename Tg> |
80 | struct raw_read |
81 | { |
82 | //! Grid out |
83 | grid_cpu<dim,Tg> & gr; |
84 | |
85 | //! File stream |
86 | std::ifstream & fl; |
87 | |
88 | /*! \brief constructor |
89 | * |
90 | * \param gr grid to fill |
91 | * \param fl file from where to read |
92 | * |
93 | */ |
94 | raw_read(grid_cpu<dim,Tg> & gr,std::ifstream & fl) |
95 | :gr(gr),fl(fl) |
96 | {}; |
97 | |
98 | //! It read for each property |
99 | template<typename T> |
100 | void operator()(T& t) const |
101 | { |
102 | typedef typename boost::mpl::at<typename Tg::type,boost::mpl::int_<T::value>>::type Tr; |
103 | |
104 | meta_raw_read<dim,Tg,Tr,T::value>::read(gr,fl); |
105 | } |
106 | }; |
107 | |
108 | template <unsigned int dim, typename T, typename idx_type> |
109 | class GridRawReader |
110 | { |
111 | public: |
112 | |
113 | //! Constructor |
114 | GridRawReader() {}; |
115 | |
116 | |
117 | /*! \brief Read a raw grid |
118 | * |
119 | * \param file raw file to read |
120 | * \param gr grid to fill |
121 | * \param opt option (FORTRAN_STYLE) |
122 | * \param skip skip N byte |
123 | * |
124 | */ |
125 | bool read(std::string file, grid_cpu<dim,T> & gr, size_t opt = 0, size_t skip = 0) |
126 | { |
127 | idx_type tmp; |
128 | std::ifstream raw; |
129 | raw.open (file, std::ios::binary ); |
130 | |
131 | if (raw.is_open() == false) |
132 | { |
133 | std::cerr << __FILE__ << ":" << __LINE__ << " error in opening the file: " << file << std::endl; |
134 | return false; |
135 | } |
136 | |
137 | // get length of file: |
138 | raw.seekg (0, std::ios::end); |
139 | size_t length = raw.tellg(); |
140 | raw.seekg (skip, std::ios::beg); |
141 | |
142 | if (opt & FORTRAN_STYLE) |
143 | raw.read((char *)&tmp,sizeof(idx_type)); |
144 | |
145 | size_t sz[dim]; |
146 | |
147 | for (size_t i = 0 ; i < dim ; i++) |
148 | { |
149 | sz[i] = 0; |
150 | raw.read((char *)&sz[i],sizeof(idx_type)); |
151 | } |
152 | |
153 | if (opt & FORTRAN_STYLE) |
154 | raw.read((char *)&tmp,sizeof(idx_type)); |
155 | |
156 | if (opt & FORTRAN_STYLE) |
157 | raw.read((char *)&tmp,sizeof(idx_type)); |
158 | |
159 | grid_sm<dim,void> gs(sz); |
160 | |
161 | size_t offset = 0; |
162 | if (opt & FORTRAN_STYLE) |
163 | offset += 2*sizeof(idx_type)*2; |
164 | |
165 | // Check the the file size make sense |
166 | if (length - dim*sizeof(idx_type) - offset - skip != gs.size()*sizeof(T) ) |
167 | { |
168 | std::cout << __FILE__ << ":" << __LINE__ << " Error the size of the raw file does not match with the calculated one" << std::endl; |
169 | return false; |
170 | } |
171 | |
172 | gr.setMemory(); |
173 | |
174 | // resize the grid |
175 | gr.resize(sz); |
176 | |
177 | if (!(opt & STRUCT_OF_ARRAY)) |
178 | { |
179 | // read the data |
180 | raw.read((char *)gr.getPointer(),gr.size()*sizeof(T)); |
181 | raw.close(); |
182 | } |
183 | else |
184 | { |
185 | // for each property |
186 | raw_read<dim,T> rr(gr,raw); |
187 | |
188 | boost::mpl::for_each< boost::mpl::range_c<int,0, T::max_prop> >(rr); |
189 | } |
190 | |
191 | return true; |
192 | } |
193 | }; |
194 | |