Commit 735a2a247ec4aeb7655e683a35e8465062e9d16b

Authored by David Mayerich
1 parent c5da6290

started testing out template casting support for stim::envi, added a stim::table…

… class for reading csv files
@@ -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
@@ -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
@@ -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
@@ -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
stim/parser/table.h 0 → 100644
  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