Commit 735a2a247ec4aeb7655e683a35e8465062e9d16b
1 parent
c5da6290
started testing out template casting support for stim::envi, added a stim::table…
… class for reading csv files
Showing
7 changed files
with
308 additions
and
14 deletions
Show diff stats
stim/envi/bil.h
@@ -200,6 +200,11 @@ public: | @@ -200,6 +200,11 @@ public: | ||
200 | /// @param p is a pointer to pre-allocated memory at least B * sizeof(T) in size. | 200 | /// @param p is a pointer to pre-allocated memory at least B * sizeof(T) in size. |
201 | /// @param x is the x-coordinate (dimension 1) of the spectrum. | 201 | /// @param x is the x-coordinate (dimension 1) of the spectrum. |
202 | /// @param y is the y-coordinate (dimension 2) of the spectrum. | 202 | /// @param y is the y-coordinate (dimension 2) of the spectrum. |
203 | + bool spectrum(T* p, size_t n, bool PROGRESS = false){ | ||
204 | + size_t y = n / X(); | ||
205 | + size_t x = n - y * X(); | ||
206 | + return binary<T>::read_line_1(p, x, y, PROGRESS); | ||
207 | + } | ||
203 | bool spectrum(T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){ | 208 | bool spectrum(T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){ |
204 | return binary<T>::read_line_1(p, x, y, PROGRESS); | 209 | return binary<T>::read_line_1(p, x, y, PROGRESS); |
205 | } | 210 | } |
stim/envi/binary.h
@@ -200,11 +200,30 @@ public: | @@ -200,11 +200,30 @@ public: | ||
200 | /// @param p is a pointer to pre-allocated memory equal to the line size R[2] | 200 | /// @param p is a pointer to pre-allocated memory equal to the line size R[2] |
201 | /// @param x is the x coordinate | 201 | /// @param x is the x coordinate |
202 | /// @param y is the y coordinate | 202 | /// @param y is the y coordinate |
203 | - bool read_line_2( T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){ | 203 | + void read_line_2( T* p, size_t n, bool PROGRESS = false){ |
204 | unsigned long long i; | 204 | unsigned long long i; |
205 | 205 | ||
206 | if(PROGRESS) progress = 0; | 206 | if(PROGRESS) progress = 0; |
207 | 207 | ||
208 | + if ( n > R[0] * R[1]){ //make sure the sample and line number is right | ||
209 | + std::cout<<"ERROR: sample or line out of range in "<<__FILE__<<" (line "<<__LINE__<<")"<<std::endl; | ||
210 | + exit(1); | ||
211 | + } | ||
212 | + | ||
213 | + file.seekg(n * sizeof(T), std::ios::beg); //point to the certain sample and line | ||
214 | + for (i = 0; i < R[2]; i++){ //for each band | ||
215 | + file.read((char *)(p + i), sizeof(T)); | ||
216 | + file.seekg((R[1] * R[0] - 1) * sizeof(T), std::ios::cur); //go to the next band | ||
217 | + if(PROGRESS) progress = (double)i / (double)R[2] * 100; | ||
218 | + } | ||
219 | + if(PROGRESS) progress = 100; | ||
220 | + } | ||
221 | + void read_line_2( T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){ | ||
222 | + read_line_2(p, y * R[0] + x, PROGRESS); | ||
223 | + /*unsigned long long i; | ||
224 | + | ||
225 | + if(PROGRESS) progress = 0; | ||
226 | + | ||
208 | if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right | 227 | if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right |
209 | std::cout<<"ERROR: sample or line out of range"<<std::endl; | 228 | std::cout<<"ERROR: sample or line out of range"<<std::endl; |
210 | return false; | 229 | return false; |
@@ -219,7 +238,7 @@ public: | @@ -219,7 +238,7 @@ public: | ||
219 | } | 238 | } |
220 | if(PROGRESS) progress = 100; | 239 | if(PROGRESS) progress = 100; |
221 | 240 | ||
222 | - return true; | 241 | + return true;*/ |
223 | } | 242 | } |
224 | 243 | ||
225 | ///Reads a line X (fastest dimension) for a given YZ value | 244 | ///Reads a line X (fastest dimension) for a given YZ value |
@@ -230,7 +249,7 @@ public: | @@ -230,7 +249,7 @@ public: | ||
230 | bool read_line_0(T * p, unsigned long long y, unsigned long long z, bool PROGRESS = false){ | 249 | bool read_line_0(T * p, unsigned long long y, unsigned long long z, bool PROGRESS = false){ |
231 | //test to make sure the specified value is within range | 250 | //test to make sure the specified value is within range |
232 | if( y >= R[1] || z >= R[2] ){ | 251 | if( y >= R[1] || z >= R[2] ){ |
233 | - std::cout<<"ERROR: sample or line out of range"<<std::endl; | 252 | + std::cout<<"ERROR: sample ("<<y<<", "<<z<<") out of range in "<<__FILE__<<" (line "<<__LINE__<<")"<<std::endl; |
234 | return false; | 253 | return false; |
235 | } | 254 | } |
236 | 255 | ||
@@ -249,7 +268,7 @@ public: | @@ -249,7 +268,7 @@ public: | ||
249 | if(PROGRESS) progress = 0; | 268 | if(PROGRESS) progress = 0; |
250 | //test to make sure the specified value is within range | 269 | //test to make sure the specified value is within range |
251 | if( x >= R[0] || z >= R[2] ){ | 270 | if( x >= R[0] || z >= R[2] ){ |
252 | - std::cout<<"ERROR: sample or line out of range"<<std::endl; | 271 | + std::cout<<"ERROR: sample or line out of range in "<<__FILE__<<" (line "<<__LINE__<<")"<<std::endl; |
253 | return false; | 272 | return false; |
254 | } | 273 | } |
255 | 274 | ||
@@ -270,7 +289,7 @@ public: | @@ -270,7 +289,7 @@ public: | ||
270 | bool read_plane_0(T* p, unsigned long long n, bool PROGRESS = false){ | 289 | bool read_plane_0(T* p, unsigned long long n, bool PROGRESS = false){ |
271 | if(PROGRESS) progress = 0; | 290 | if(PROGRESS) progress = 0; |
272 | if (n >= R[0]){ //make sure the number is within the possible range | 291 | if (n >= R[0]){ //make sure the number is within the possible range |
273 | - std::cout<<"ERROR read_plane_0: page out of range"<<std::endl; | 292 | + std::cout<<"ERROR: sample or line out of range in "<<__FILE__<<" (line "<<__LINE__<<")"<<std::endl; |
274 | return false; | 293 | return false; |
275 | } | 294 | } |
276 | unsigned long long jump = (R[0] - 1) * sizeof(T); //number of bytes to skip between samples | 295 | unsigned long long jump = (R[0] - 1) * sizeof(T); //number of bytes to skip between samples |
stim/envi/bip.h
@@ -143,6 +143,11 @@ public: | @@ -143,6 +143,11 @@ public: | ||
143 | bool spectrum(T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){ | 143 | bool spectrum(T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){ |
144 | return read_line_0(p, x, y, PROGRESS); //read a line in the binary YZ plane (dimension order for BIP is ZXY) | 144 | return read_line_0(p, x, y, PROGRESS); //read a line in the binary YZ plane (dimension order for BIP is ZXY) |
145 | } | 145 | } |
146 | + bool spectrum(T* p, size_t n, bool PROGRESS = false){ | ||
147 | + size_t y = n / X(); | ||
148 | + size_t x = n - y * X(); | ||
149 | + return read_line_0(p, x, y, PROGRESS); //read a line in the binary YZ plane (dimension order for BIP is ZXY) | ||
150 | + } | ||
146 | 151 | ||
147 | /// Retrieves a band of x values from a given xz plane. | 152 | /// Retrieves a band of x values from a given xz plane. |
148 | 153 |
stim/envi/bsq.h
@@ -146,9 +146,13 @@ public: | @@ -146,9 +146,13 @@ public: | ||
146 | /// @param p is a pointer to pre-allocated memory at least B * sizeof(T) in size. | 146 | /// @param p is a pointer to pre-allocated memory at least B * sizeof(T) in size. |
147 | /// @param x is the x-coordinate (dimension 1) of the spectrum. | 147 | /// @param x is the x-coordinate (dimension 1) of the spectrum. |
148 | /// @param y is the y-coordinate (dimension 2) of the spectrum. | 148 | /// @param y is the y-coordinate (dimension 2) of the spectrum. |
149 | - bool spectrum(T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){ | ||
150 | - return read_line_2(p, x, y, PROGRESS); | 149 | + void spectrum(T* p, size_t n, bool PROGRESS){ |
150 | + read_line_2(p, n, PROGRESS); | ||
151 | } | 151 | } |
152 | + void spectrum(T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){ | ||
153 | + read_line_2(p, x, y, PROGRESS); | ||
154 | + } | ||
155 | + | ||
152 | 156 | ||
153 | /// Retrieve a single pixel and stores it in pre-allocated memory. | 157 | /// Retrieve a single pixel and stores it in pre-allocated memory. |
154 | 158 |
stim/envi/envi.h
@@ -21,10 +21,56 @@ class envi{ | @@ -21,10 +21,56 @@ class envi{ | ||
21 | void* file; //void pointer to the relevant file reader (bip, bsq, or bil - with appropriate data type) | 21 | void* file; //void pointer to the relevant file reader (bip, bsq, or bil - with appropriate data type) |
22 | std::string fname; //file name used for repeated opening and closing | 22 | std::string fname; //file name used for repeated opening and closing |
23 | 23 | ||
24 | + //allocate sufficient space for a spectrum based on the data type and number of bands | ||
25 | + void* alloc_array(size_t len){ | ||
26 | + switch(header.data_type){ | ||
27 | + case envi_header::int8: | ||
28 | + return malloc(len); | ||
29 | + case envi_header::int16: | ||
30 | + case envi_header::uint16: | ||
31 | + return malloc(2 * len); | ||
32 | + case envi_header::int32: | ||
33 | + case envi_header::uint32: | ||
34 | + case envi_header::float32: | ||
35 | + return malloc(4 * len); | ||
36 | + case envi_header::int64: | ||
37 | + case envi_header::uint64: | ||
38 | + case envi_header::float64: | ||
39 | + case envi_header::complex32: | ||
40 | + return malloc(8 * len); | ||
41 | + case envi_header::complex64: | ||
42 | + return malloc(16 * len); | ||
43 | + default: | ||
44 | + std::cout<<"ERROR stim::envi data type not recognized for spectral allocation"<<std::endl; | ||
45 | + exit(1); | ||
46 | + } | ||
47 | + } | ||
48 | + | ||
49 | + //cast a value to DEST type from SRC type | ||
50 | + template<typename DST, typename SRC> | ||
51 | + inline void cast(DST* dst, SRC* src){ | ||
52 | + (*dst) = (DST)(*src); | ||
53 | + } | ||
54 | + | ||
55 | + //cast an array from type SRC to type DEST | ||
56 | + template<typename DST, typename SRC> | ||
57 | + inline void cast(DST* dst, SRC* src, size_t len){ | ||
58 | + for(size_t i = 0; i < len; i++) | ||
59 | + cast(&dst[i], &src[i]); | ||
60 | + } | ||
61 | + | ||
24 | public: | 62 | public: |
25 | 63 | ||
26 | envi_header header; | 64 | envi_header header; |
27 | 65 | ||
66 | + void* malloc_spectrum(){ | ||
67 | + return alloc_array(header.bands); | ||
68 | + } | ||
69 | + | ||
70 | + void* malloc_band(){ | ||
71 | + return alloc_array(header.samples * header.lines); | ||
72 | + } | ||
73 | + | ||
28 | /// Returns the size of the data type in bytes | 74 | /// Returns the size of the data type in bytes |
29 | unsigned int type_size(){ | 75 | unsigned int type_size(){ |
30 | if(header.data_type == envi_header::float32) return 4; | 76 | if(header.data_type == envi_header::float32) return 4; |
@@ -1060,7 +1106,7 @@ public: | @@ -1060,7 +1106,7 @@ public: | ||
1060 | /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T) | 1106 | /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T) |
1061 | /// @param x is the x-coordinate of the spectrum | 1107 | /// @param x is the x-coordinate of the spectrum |
1062 | /// @param y is the y-coordinate of the spectrum | 1108 | /// @param y is the y-coordinate of the spectrum |
1063 | - bool spectrum(void* ptr, unsigned long long x, unsigned long long y, bool PROGRESS = false){ | 1109 | + /*bool spectrum(void* ptr, unsigned long long x, unsigned long long y, bool PROGRESS = false){ |
1064 | 1110 | ||
1065 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 1111 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
1066 | if(header.data_type ==envi_header::float32) | 1112 | if(header.data_type ==envi_header::float32) |
@@ -1093,6 +1139,114 @@ public: | @@ -1093,6 +1139,114 @@ public: | ||
1093 | } | 1139 | } |
1094 | } | 1140 | } |
1095 | return false; | 1141 | return false; |
1142 | + }*/ | ||
1143 | + | ||
1144 | + // Retrieve a spectrum at the specified 1D location | ||
1145 | + | ||
1146 | + /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T) | ||
1147 | + /// @param x is the 1D coordinate of the spectrum | ||
1148 | + template<typename T> | ||
1149 | + void spectrum(T* ptr, size_t n, bool PROGRESS = false){ | ||
1150 | + | ||
1151 | + void* temp = alloc_array(header.bands); //allocate space for the output array | ||
1152 | + | ||
1153 | + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | ||
1154 | + if(header.data_type ==envi_header::float32){ | ||
1155 | + ((bsq<float>*)file)->spectrum((float*)temp, n, PROGRESS); | ||
1156 | + cast<T, float>(ptr, (float*)temp, header.bands); | ||
1157 | + } | ||
1158 | + else if (header.data_type == envi_header::float64){ | ||
1159 | + ((bsq<double>*)file)->spectrum((double*)temp, n, PROGRESS); | ||
1160 | + cast<T, double>(ptr, (double*)temp, header.bands); | ||
1161 | + } | ||
1162 | + else{ | ||
1163 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
1164 | + exit(1); | ||
1165 | + } | ||
1166 | + } | ||
1167 | + else if (header.interleave == envi_header::BIL){ | ||
1168 | + if (header.data_type == envi_header::float32){ | ||
1169 | + ((bil<float>*)file)->spectrum((float*)temp, n, PROGRESS); | ||
1170 | + cast<T, float>(ptr, (float*)temp, header.bands); | ||
1171 | + } | ||
1172 | + else if (header.data_type == envi_header::float64){ | ||
1173 | + ((bil<double>*)file)->spectrum((double*)temp, n, PROGRESS); | ||
1174 | + cast<T, double>(ptr, (double*)temp, header.bands); | ||
1175 | + } | ||
1176 | + else{ | ||
1177 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
1178 | + exit(1); | ||
1179 | + } | ||
1180 | + } | ||
1181 | + else if (header.interleave == envi_header::BIP){ | ||
1182 | + if (header.data_type == envi_header::float32){ | ||
1183 | + ((bip<float>*)file)->spectrum((float*)temp, n, PROGRESS); | ||
1184 | + cast<T, float>(ptr, (float*)temp, header.bands); | ||
1185 | + } | ||
1186 | + else if (header.data_type == envi_header::float64){ | ||
1187 | + ((bip<double>*)file)->spectrum((double*)temp, n, PROGRESS); | ||
1188 | + cast<T, double>(ptr, (double*)temp, header.bands); | ||
1189 | + } | ||
1190 | + else{ | ||
1191 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
1192 | + exit(1); | ||
1193 | + } | ||
1194 | + } | ||
1195 | + } | ||
1196 | + | ||
1197 | + /// Retrieve a spectrum from the specified (x, y) location | ||
1198 | + | ||
1199 | + /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T) | ||
1200 | + /// @param x is the x-coordinate of the spectrum | ||
1201 | + /// @param y is the y-coordinate of the spectrum | ||
1202 | + template<typename T> | ||
1203 | + void spectrum(T* ptr, unsigned long long x, unsigned long long y, bool PROGRESS = false){ | ||
1204 | + | ||
1205 | + spectrum<T>(ptr, y * header.samples + x, PROGRESS = false); | ||
1206 | + /*void* temp = alloc_array<T>(header.bands); //allocate space for the output array | ||
1207 | + | ||
1208 | + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | ||
1209 | + if(header.data_type ==envi_header::float32){ | ||
1210 | + ((bsq<float>*)file)->spectrum((float*)temp, x, y, PROGRESS); | ||
1211 | + cast<T, float>(ptr, temp, header.bands); | ||
1212 | + } | ||
1213 | + else if (header.data_type == envi_header::float64){ | ||
1214 | + ((bsq<double>*)file)->spectrum((double*)temp, x, y, PROGRESS); | ||
1215 | + cast<T, double>(ptr, temp, header.bands); | ||
1216 | + } | ||
1217 | + else{ | ||
1218 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
1219 | + exit(1); | ||
1220 | + } | ||
1221 | + } | ||
1222 | + else if (header.interleave == envi_header::BIL){ | ||
1223 | + if (header.data_type == envi_header::float32){ | ||
1224 | + ((bil<float>*)file)->spectrum((float*)temp, x, y, PROGRESS); | ||
1225 | + cast<T, float>(ptr, temp, header.bands); | ||
1226 | + } | ||
1227 | + else if (header.data_type == envi_header::float64){ | ||
1228 | + ((bil<double>*)file)->spectrum((double*)temp, x, y, PROGRESS); | ||
1229 | + cast<T, double>(ptr, temp, header.bands); | ||
1230 | + } | ||
1231 | + else{ | ||
1232 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
1233 | + exit(1); | ||
1234 | + } | ||
1235 | + } | ||
1236 | + else if (header.interleave == envi_header::BIP){ | ||
1237 | + if (header.data_type == envi_header::float32){ | ||
1238 | + ((bip<float>*)file)->spectrum((float*)temp, x, y, PROGRESS); | ||
1239 | + cast<T, float>(ptr, temp, header.bands); | ||
1240 | + } | ||
1241 | + else if (header.data_type == envi_header::float64){ | ||
1242 | + ((bip<double>*)file)->spectrum((double*)temp, x, y, PROGRESS); | ||
1243 | + cast<T, double>(ptr, temp, header.bands); | ||
1244 | + } | ||
1245 | + else{ | ||
1246 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
1247 | + exit(1); | ||
1248 | + } | ||
1249 | + }*/ | ||
1096 | } | 1250 | } |
1097 | 1251 | ||
1098 | /// Retrieve a single band (based on index) and stores it in pre-allocated memory. | 1252 | /// Retrieve a single band (based on index) and stores it in pre-allocated memory. |
stim/image/image.h
@@ -33,8 +33,7 @@ class image{ | @@ -33,8 +33,7 @@ class image{ | ||
33 | 33 | ||
34 | void unalloc(){ //frees any resources associated with the image | 34 | void unalloc(){ //frees any resources associated with the image |
35 | if(img) free(img); //if memory has been allocated, free it | 35 | if(img) free(img); //if memory has been allocated, free it |
36 | - img=NULL; | ||
37 | - | 36 | + img=NULL; |
38 | } | 37 | } |
39 | 38 | ||
40 | 39 | ||
@@ -92,7 +91,9 @@ class image{ | @@ -92,7 +91,9 @@ class image{ | ||
92 | public: | 91 | public: |
93 | 92 | ||
94 | /// Default constructor - creates an empty image object | 93 | /// Default constructor - creates an empty image object |
95 | - image(){ init(); } //initialize all variables to zero, don't allocate any memory | 94 | + image(){ |
95 | + init(); //initialize all variables to zero, don't allocate any memory | ||
96 | + } | ||
96 | 97 | ||
97 | /// Constructor with a filename - loads the specified file | 98 | /// Constructor with a filename - loads the specified file |
98 | image(std::string filename){ //constructor initialize the image with an image file | 99 | image(std::string filename){ //constructor initialize the image with an image file |
@@ -114,7 +115,7 @@ public: | @@ -114,7 +115,7 @@ public: | ||
114 | } | 115 | } |
115 | 116 | ||
116 | /// Copy constructor - duplicates an image object | 117 | /// Copy constructor - duplicates an image object |
117 | - image(const stim::image<T>& I){ | 118 | + image(const stim::image<T> &I){ |
118 | init(); | 119 | init(); |
119 | allocate(I.X(), I.Y(), I.C()); | 120 | allocate(I.X(), I.Y(), I.C()); |
120 | memcpy(img, I.img, bytes()); | 121 | memcpy(img, I.img, bytes()); |
@@ -125,7 +126,7 @@ public: | @@ -125,7 +126,7 @@ public: | ||
125 | free(img); | 126 | free(img); |
126 | } | 127 | } |
127 | 128 | ||
128 | - stim::image<T> operator=(const stim::image<T>& I){ | 129 | + stim::image<T>& operator=(const stim::image<T>& I){ |
129 | if(&I == this) //handle self-assignment | 130 | if(&I == this) //handle self-assignment |
130 | return *this; | 131 | return *this; |
131 | allocate(I.X(), I.Y(), I.C()); | 132 | allocate(I.X(), I.Y(), I.C()); |
@@ -138,7 +139,7 @@ public: | @@ -138,7 +139,7 @@ public: | ||
138 | 139 | ||
139 | cv::Mat cvImage = cv::imread(filename, CV_LOAD_IMAGE_UNCHANGED); //use OpenCV to open the image file | 140 | cv::Mat cvImage = cv::imread(filename, CV_LOAD_IMAGE_UNCHANGED); //use OpenCV to open the image file |
140 | if(!cvImage.data){ | 141 | if(!cvImage.data){ |
141 | - std::cout<<"ERROR stim::image::load() - unable to find image "<<filename<<std::endl; | 142 | + std::cout<<"ERROR stim::image::load() - unable to find image "<<filename<<" ["<<__FILE__<<" (line "<<__LINE__<<")]"<<std::endl; |
142 | exit(1); | 143 | exit(1); |
143 | } | 144 | } |
144 | allocate(cvImage.cols, cvImage.rows, cvImage.channels()); //allocate space for the image | 145 | allocate(cvImage.cols, cvImage.rows, cvImage.channels()); //allocate space for the image |
1 | +#ifndef STIM_CSV_H | ||
2 | +#define STIM_CSV_H | ||
3 | + | ||
4 | +#include <vector> | ||
5 | +#include <sstream> | ||
6 | +#include <fstream> | ||
7 | + | ||
8 | +namespace stim{ | ||
9 | + | ||
10 | + class table{ | ||
11 | + | ||
12 | + std::vector< std::vector< std::string > > TABLE; | ||
13 | + | ||
14 | + size_t x; //current x and y positions for adding elements to the table | ||
15 | + size_t y; | ||
16 | + | ||
17 | + void init(){ | ||
18 | + x = y = 0; | ||
19 | + TABLE.resize(1); //create a single row | ||
20 | + TABLE[0].clear(); //make sure that the row is empty | ||
21 | + } | ||
22 | + public: | ||
23 | + | ||
24 | + table(){ | ||
25 | + init(); | ||
26 | + } | ||
27 | + | ||
28 | + void new_column(){ | ||
29 | + x = 0; //reset to the first position of the column | ||
30 | + y++; //increment the current row position | ||
31 | + TABLE.push_back( std::vector<std::string>() ); //push an empty row | ||
32 | + } | ||
33 | + | ||
34 | + template<typename T> | ||
35 | + T operator<<(T i){ | ||
36 | + std::stringstream ss; | ||
37 | + ss<<i; | ||
38 | + TABLE[y].push_back(ss.str()); | ||
39 | + x++; | ||
40 | + return i; | ||
41 | + } | ||
42 | + | ||
43 | + std::string str(){ | ||
44 | + std::stringstream ss; | ||
45 | + for(size_t yi = 0; yi < TABLE.size(); yi++){ | ||
46 | + for(size_t xi = 0; xi < TABLE[yi].size(); xi++){ | ||
47 | + if(xi != 0) ss<<", "; | ||
48 | + ss<<TABLE[yi][xi]; | ||
49 | + } | ||
50 | + ss<<std::endl; | ||
51 | + } | ||
52 | + return ss.str(); | ||
53 | + } | ||
54 | + | ||
55 | + void save_ascii(std::string filename, char col_delim = ',', char row_delim = '\n'){ | ||
56 | + ofstream outfile(filename); | ||
57 | + for(size_t yi = 0; yi < TABLE.size(); yi++){ | ||
58 | + if(yi != 0 && TABLE[yi].size() > 0) outfile<<row_delim; | ||
59 | + for(size_t xi = 0; xi < TABLE[yi].size(); xi++){ | ||
60 | + if(xi != 0) outfile<<col_delim; | ||
61 | + outfile<<TABLE[yi][xi]; | ||
62 | + } | ||
63 | + } | ||
64 | + } | ||
65 | + | ||
66 | + void read_ascii(std::string filename, char col_delim = ',', char row_delim = '\n'){ | ||
67 | + ifstream infile(filename); //open an ascii file for reading | ||
68 | + TABLE.clear(); //empty out the table | ||
69 | + | ||
70 | + std::string line; | ||
71 | + while(!infile.eof()){ | ||
72 | + std::getline(infile, line, row_delim); //read a line from the file using the row delimiter | ||
73 | + size_t pos = 0; | ||
74 | + std::string token; | ||
75 | + std::vector< std::string > row; | ||
76 | + while ((pos = line.find(col_delim)) != std::string::npos) { | ||
77 | + token = line.substr(0, pos); | ||
78 | + row.push_back(token); | ||
79 | + line.erase(0, pos + 1); | ||
80 | + } | ||
81 | + token = line.substr(0, std::string::npos); //read the last column | ||
82 | + row.push_back(token); //push it into the table | ||
83 | + TABLE.push_back(row); //add an empty vector to the table | ||
84 | + } | ||
85 | + } | ||
86 | + | ||
87 | + /// Returns a vector representation of the table by casting to the specified template | ||
88 | + template<typename T> | ||
89 | + std::vector< std::vector<T> > get_vector(){ | ||
90 | + std::vector< std::vector<T> > result; | ||
91 | + result.resize(TABLE.size()); //initialize the first dimension of the returned table | ||
92 | + for(size_t i = 0; i < TABLE.size(); i++){ //for each row | ||
93 | + result[i].resize(TABLE[i].size()); //initialize the number of columns in this row | ||
94 | + for(size_t j = 0; j < TABLE[i].size(); j++){ //for each column | ||
95 | + std::stringstream ss(TABLE[i][j]); | ||
96 | + ss >> result[i][j]; | ||
97 | + } | ||
98 | + } | ||
99 | + return result; //return the casted table | ||
100 | + } | ||
101 | + | ||
102 | + }; | ||
103 | +}; | ||
104 | + | ||
105 | + | ||
106 | +#endif | ||
0 | \ No newline at end of file | 107 | \ No newline at end of file |