| 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 |  |