Commit 63fc1df8ebee680b2a16a6709d79f05e2dffe90b
1 parent
371bf339
added an inverse PCA transform to the stim::envi classes
Showing
5 changed files
with
491 additions
and
385 deletions
Show diff stats
stim/envi/bil.h
@@ -35,7 +35,12 @@ protected: | @@ -35,7 +35,12 @@ protected: | ||
35 | return R[1]; | 35 | return R[1]; |
36 | } | 36 | } |
37 | 37 | ||
38 | - using binary<T>::thread_data; | 38 | + using binary<T>::progress; |
39 | + | ||
40 | + /// Call the binary nnz() function for the BIL orientation | ||
41 | + unsigned long long nnz(unsigned char* mask){ | ||
42 | + return binary<T>::nnz(mask, X()*Y()); | ||
43 | + } | ||
39 | 44 | ||
40 | public: | 45 | public: |
41 | 46 | ||
@@ -63,9 +68,10 @@ public: | @@ -63,9 +68,10 @@ public: | ||
63 | 68 | ||
64 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. | 69 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. |
65 | /// @param page <= B is the integer number of the band to be copied. | 70 | /// @param page <= B is the integer number of the band to be copied. |
66 | - bool band_index( T * p, unsigned int page){ | 71 | + bool band_index( T * p, unsigned int page, bool PROGRESS = false){ |
67 | //return binary<T>::read_plane_1(p, page); | 72 | //return binary<T>::read_plane_1(p, page); |
68 | 73 | ||
74 | + if(PROGRESS) progress = 0; | ||
69 | unsigned int L = X() * sizeof(T); //caculate the number of bytes in a sample line | 75 | unsigned int L = X() * sizeof(T); //caculate the number of bytes in a sample line |
70 | unsigned int jump = X() * (Z() - 1) * sizeof(T); | 76 | unsigned int jump = X() * (Z() - 1) * sizeof(T); |
71 | 77 | ||
@@ -79,6 +85,7 @@ public: | @@ -79,6 +85,7 @@ public: | ||
79 | { | 85 | { |
80 | file.read((char *)(p + i * X()), L); | 86 | file.read((char *)(p + i * X()), L); |
81 | file.seekg( jump, std::ios::cur); | 87 | file.seekg( jump, std::ios::cur); |
88 | + if(PROGRESS) progress = (double)(i+1) / Y() * 100; | ||
82 | } | 89 | } |
83 | 90 | ||
84 | return true; | 91 | return true; |
@@ -88,7 +95,7 @@ public: | @@ -88,7 +95,7 @@ public: | ||
88 | 95 | ||
89 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. | 96 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. |
90 | /// @param wavelength is a floating point value (usually a wavelength in spectral data) used as a label for the band to be copied. | 97 | /// @param wavelength is a floating point value (usually a wavelength in spectral data) used as a label for the band to be copied. |
91 | - bool band( T * p, double wavelength){ | 98 | + bool band( T * p, double wavelength, bool PROGRESS = false){ |
92 | 99 | ||
93 | //if there are no wavelengths in the BSQ file | 100 | //if there are no wavelengths in the BSQ file |
94 | if(w.size() == 0) | 101 | if(w.size() == 0) |
@@ -104,7 +111,7 @@ public: | @@ -104,7 +111,7 @@ public: | ||
104 | 111 | ||
105 | //if wavelength is smaller than the first one in header file | 112 | //if wavelength is smaller than the first one in header file |
106 | if ( w[page] > wavelength ){ | 113 | if ( w[page] > wavelength ){ |
107 | - band_index(p, page); | 114 | + band_index(p, page, PROGRESS); |
108 | return true; | 115 | return true; |
109 | } | 116 | } |
110 | 117 | ||
@@ -124,7 +131,7 @@ public: | @@ -124,7 +131,7 @@ public: | ||
124 | p1=(T*)malloc(S); //memory allocation | 131 | p1=(T*)malloc(S); //memory allocation |
125 | p2=(T*)malloc(S); | 132 | p2=(T*)malloc(S); |
126 | band_index(p1, page - 1); | 133 | band_index(p1, page - 1); |
127 | - band_index(p2, page ); | 134 | + band_index(p2, page, PROGRESS); |
128 | for(unsigned i=0; i < XY; i++){ | 135 | for(unsigned i=0; i < XY; i++){ |
129 | double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]); | 136 | double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]); |
130 | p[i] = (p2[i] - p1[i]) * r + p1[i]; | 137 | p[i] = (p2[i] - p1[i]) * r + p1[i]; |
@@ -134,7 +141,7 @@ public: | @@ -134,7 +141,7 @@ public: | ||
134 | } | 141 | } |
135 | else //if the wavelength is equal to a wavelength in header file | 142 | else //if the wavelength is equal to a wavelength in header file |
136 | { | 143 | { |
137 | - band_index(p, page); | 144 | + band_index(p, page, PROGRESS); |
138 | } | 145 | } |
139 | 146 | ||
140 | return true; | 147 | return true; |
@@ -195,8 +202,8 @@ public: | @@ -195,8 +202,8 @@ public: | ||
195 | /// @param p is a pointer to pre-allocated memory at least B * sizeof(T) in size. | 202 | /// @param p is a pointer to pre-allocated memory at least B * sizeof(T) in size. |
196 | /// @param x is the x-coordinate (dimension 1) of the spectrum. | 203 | /// @param x is the x-coordinate (dimension 1) of the spectrum. |
197 | /// @param y is the y-coordinate (dimension 2) of the spectrum. | 204 | /// @param y is the y-coordinate (dimension 2) of the spectrum. |
198 | - bool spectrum(T * p, unsigned x, unsigned y){ | ||
199 | - return binary<T>::read_line_02(p, x, y); | 205 | + bool spectrum(T * p, unsigned x, unsigned y, bool PROGRESS = false){ |
206 | + return binary<T>::read_line_1(p, x, y, PROGRESS); | ||
200 | } | 207 | } |
201 | 208 | ||
202 | /// Retrieve a single pixel and stores it in pre-allocated memory. | 209 | /// Retrieve a single pixel and stores it in pre-allocated memory. |
@@ -223,7 +230,7 @@ public: | @@ -223,7 +230,7 @@ public: | ||
223 | 230 | ||
224 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. | 231 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. |
225 | /// @param wls is the list of baseline points based on band labels. | 232 | /// @param wls is the list of baseline points based on band labels. |
226 | - bool baseline(std::string outname, std::vector<double> wls){ | 233 | + bool baseline(std::string outname, std::vector<double> wls, bool PROGRESS = false){ |
227 | 234 | ||
228 | unsigned N = wls.size(); //get the number of baseline points | 235 | unsigned N = wls.size(); //get the number of baseline points |
229 | 236 | ||
@@ -321,7 +328,7 @@ public: | @@ -321,7 +328,7 @@ public: | ||
321 | }//loop for YZ line end | 328 | }//loop for YZ line end |
322 | target.write(reinterpret_cast<const char*>(c), L); //write the corrected data into destination | 329 | target.write(reinterpret_cast<const char*>(c), L); //write the corrected data into destination |
323 | 330 | ||
324 | - thread_data = (double)k / Y() * 100; | 331 | + if(PROGRESS) progress = (double)(k+1) / Y() * 100; |
325 | }//loop for Y slice end | 332 | }//loop for Y slice end |
326 | 333 | ||
327 | free(a); | 334 | free(a); |
@@ -329,8 +336,6 @@ public: | @@ -329,8 +336,6 @@ public: | ||
329 | free(c); | 336 | free(c); |
330 | target.close(); | 337 | target.close(); |
331 | 338 | ||
332 | - thread_data = 100; | ||
333 | - | ||
334 | return true; | 339 | return true; |
335 | 340 | ||
336 | } | 341 | } |
@@ -340,7 +345,7 @@ public: | @@ -340,7 +345,7 @@ public: | ||
340 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. | 345 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. |
341 | /// @param w is the label specifying the band that the hyperspectral image will be normalized to. | 346 | /// @param w is the label specifying the band that the hyperspectral image will be normalized to. |
342 | /// @param t is a threshold specified such that a spectrum with a value at w less than t is set to zero. Setting this threshold allows the user to limit division by extremely small numbers. | 347 | /// @param t is a threshold specified such that a spectrum with a value at w less than t is set to zero. Setting this threshold allows the user to limit division by extremely small numbers. |
343 | - bool normalize(std::string outname, double w, double t = 0.0) | 348 | + bool normalize(std::string outname, double w, double t = 0.0, bool PROGRESS = false) |
344 | { | 349 | { |
345 | unsigned int B = Z(); //calculate the number of bands | 350 | unsigned int B = Z(); //calculate the number of bands |
346 | unsigned int ZX = Z() * X(); | 351 | unsigned int ZX = Z() * X(); |
@@ -374,20 +379,19 @@ public: | @@ -374,20 +379,19 @@ public: | ||
374 | } | 379 | } |
375 | target.write(reinterpret_cast<const char*>(c), L); //write normalized data into destination | 380 | target.write(reinterpret_cast<const char*>(c), L); //write normalized data into destination |
376 | 381 | ||
377 | - thread_data = (double)j / Y() * 100; | 382 | + if(PROGRESS) progress = (double)(j+1) / Y() * 100; |
378 | } | 383 | } |
379 | 384 | ||
380 | free(b); | 385 | free(b); |
381 | free(c); | 386 | free(c); |
382 | target.close(); | 387 | target.close(); |
383 | - thread_data = 100; | ||
384 | return true; | 388 | return true; |
385 | } | 389 | } |
386 | 390 | ||
387 | /// Convert the current BIL file to a BSQ file with the specified file name. | 391 | /// Convert the current BIL file to a BSQ file with the specified file name. |
388 | 392 | ||
389 | /// @param outname is the name of the output BSQ file to be saved to disk. | 393 | /// @param outname is the name of the output BSQ file to be saved to disk. |
390 | - bool bsq(std::string outname) | 394 | + bool bsq(std::string outname, bool PROGRESS = false) |
391 | { | 395 | { |
392 | unsigned int S = X() * Y() * sizeof(T); //calculate the number of bytes in a band | 396 | unsigned int S = X() * Y() * sizeof(T); //calculate the number of bytes in a band |
393 | 397 | ||
@@ -402,11 +406,9 @@ public: | @@ -402,11 +406,9 @@ public: | ||
402 | band_index(p, i); | 406 | band_index(p, i); |
403 | target.write(reinterpret_cast<const char*>(p), S); //write a band data into target file | 407 | target.write(reinterpret_cast<const char*>(p), S); //write a band data into target file |
404 | 408 | ||
405 | - thread_data = (double)i / Z() * 100; //store the progress for the current operation | 409 | + if(PROGRESS) progress = (double)(i+1) / Z() * 100; //store the progress for the current operation |
406 | } | 410 | } |
407 | 411 | ||
408 | - thread_data = 100; //set the current progress to 100% | ||
409 | - | ||
410 | free(p); | 412 | free(p); |
411 | target.close(); | 413 | target.close(); |
412 | return true; | 414 | return true; |
@@ -415,7 +417,7 @@ public: | @@ -415,7 +417,7 @@ public: | ||
415 | /// Convert the current BIL file to a BIP file with the specified file name. | 417 | /// Convert the current BIL file to a BIP file with the specified file name. |
416 | 418 | ||
417 | /// @param outname is the name of the output BIP file to be saved to disk. | 419 | /// @param outname is the name of the output BIP file to be saved to disk. |
418 | - bool bip(std::string outname) | 420 | + bool bip(std::string outname, bool PROGRESS = false) |
419 | { | 421 | { |
420 | unsigned int S = X() * Z() * sizeof(T); //calculate the number of bytes in a ZX slice | 422 | unsigned int S = X() * Z() * sizeof(T); //calculate the number of bytes in a ZX slice |
421 | 423 | ||
@@ -436,15 +438,12 @@ public: | @@ -436,15 +438,12 @@ public: | ||
436 | for ( unsigned j = 0; j < X(); j++) | 438 | for ( unsigned j = 0; j < X(); j++) |
437 | q[k + j * Z()] = p[ks + j]; | 439 | q[k + j * Z()] = p[ks + j]; |
438 | 440 | ||
439 | - thread_data = (double)(i * Z() + k) / (Z() * Y()) * 100; //store the progress for the current operation | 441 | + if(PROGRESS) progress = (double)((i+1) * Z() + k+1) / (Z() * Y()) * 100; //store the progress for the current operation |
440 | } | 442 | } |
441 | 443 | ||
442 | target.write(reinterpret_cast<const char*>(q), S); //write a band data into target file | 444 | target.write(reinterpret_cast<const char*>(q), S); //write a band data into target file |
443 | } | 445 | } |
444 | 446 | ||
445 | - thread_data = 100; | ||
446 | - | ||
447 | - | ||
448 | free(p); | 447 | free(p); |
449 | free(q); | 448 | free(q); |
450 | target.close(); | 449 | target.close(); |
@@ -879,14 +878,14 @@ public: | @@ -879,14 +878,14 @@ public: | ||
879 | target.write((char*)spec, B * sizeof(T)); //write that spectrum to disk. Size is L2. | 878 | target.write((char*)spec, B * sizeof(T)); //write that spectrum to disk. Size is L2. |
880 | } | 879 | } |
881 | 880 | ||
882 | - thread_data = (double) (y * X() + x) / (Y() * X()) * 100; | 881 | + progress = (double) (y * X() + x) / (Y() * X()) * 100; |
883 | } | 882 | } |
884 | } | 883 | } |
885 | target.close(); | 884 | target.close(); |
886 | free(slice); | 885 | free(slice); |
887 | free(spec); | 886 | free(spec); |
888 | 887 | ||
889 | - thread_data = 100; | 888 | + progress = 100; |
890 | return true; | 889 | return true; |
891 | } | 890 | } |
892 | 891 | ||
@@ -923,7 +922,7 @@ public: | @@ -923,7 +922,7 @@ public: | ||
923 | 922 | ||
924 | /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum | 923 | /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum |
925 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location | 924 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location |
926 | - bool avg_band(double* p, unsigned char* mask = NULL){ | 925 | + bool avg_band(double* p, unsigned char* mask = NULL, bool PROGRESS = false){ |
927 | unsigned long long XZ = X() * Z(); | 926 | unsigned long long XZ = X() * Z(); |
928 | unsigned long long XY = X() * Y(); | 927 | unsigned long long XY = X() * Y(); |
929 | T* temp = (T*)malloc(sizeof(T) * XZ); | 928 | T* temp = (T*)malloc(sizeof(T) * XZ); |
@@ -947,6 +946,7 @@ public: | @@ -947,6 +946,7 @@ public: | ||
947 | } | 946 | } |
948 | } | 947 | } |
949 | } | 948 | } |
949 | + if(PROGRESS) progress = (double)(k+1) / Y() * 100; | ||
950 | } | 950 | } |
951 | free(temp); | 951 | free(temp); |
952 | return true; | 952 | return true; |
@@ -957,8 +957,8 @@ public: | @@ -957,8 +957,8 @@ public: | ||
957 | /// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix | 957 | /// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix |
958 | /// @param avg is a pointer to memory of size B that stores the average spectrum | 958 | /// @param avg is a pointer to memory of size B that stores the average spectrum |
959 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location | 959 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location |
960 | - bool co_matrix(double* co, double* avg, unsigned char *mask){ | ||
961 | - thread_data = 0; | 960 | + bool co_matrix(double* co, double* avg, unsigned char *mask, bool PROGRESS = false){ |
961 | + progress = 0; | ||
962 | //memory allocation | 962 | //memory allocation |
963 | unsigned long long xy = X() * Y(); | 963 | unsigned long long xy = X() * Y(); |
964 | unsigned long long B = Z(); | 964 | unsigned long long B = Z(); |
@@ -986,7 +986,7 @@ public: | @@ -986,7 +986,7 @@ public: | ||
986 | } | 986 | } |
987 | } | 987 | } |
988 | } | 988 | } |
989 | - thread_data = (double)j / xy * 100; | 989 | + if(PROGRESS) progress = (double)(j+1) / xy * 100; |
990 | } | 990 | } |
991 | //because correlation matrix is symmetric | 991 | //because correlation matrix is symmetric |
992 | for (unsigned long long i = 0; i < B; i++){ | 992 | for (unsigned long long i = 0; i < B; i++){ |
@@ -996,9 +996,6 @@ public: | @@ -996,9 +996,6 @@ public: | ||
996 | } | 996 | } |
997 | 997 | ||
998 | free(temp); | 998 | free(temp); |
999 | - | ||
1000 | - thread_data = 100; //processing complete | ||
1001 | - | ||
1002 | return true; | 999 | return true; |
1003 | } | 1000 | } |
1004 | 1001 | ||
@@ -1015,7 +1012,8 @@ public: | @@ -1015,7 +1012,8 @@ public: | ||
1015 | unsigned long long x1, | 1012 | unsigned long long x1, |
1016 | unsigned long long y1, | 1013 | unsigned long long y1, |
1017 | unsigned long long b0, | 1014 | unsigned long long b0, |
1018 | - unsigned long long b1){ | 1015 | + unsigned long long b1, |
1016 | + bool PROGRESS = false){ | ||
1019 | 1017 | ||
1020 | //calculate the new image parameters | 1018 | //calculate the new image parameters |
1021 | unsigned long long samples = x1 - x0; | 1019 | unsigned long long samples = x1 - x0; |
@@ -1048,7 +1046,7 @@ public: | @@ -1048,7 +1046,7 @@ public: | ||
1048 | file.read((char *)(temp + z * samples), sizeof(T) * samples); | 1046 | file.read((char *)(temp + z * samples), sizeof(T) * samples); |
1049 | file.seekg(jumpb, std::ios::cur); //go to the next band | 1047 | file.seekg(jumpb, std::ios::cur); //go to the next band |
1050 | 1048 | ||
1051 | - thread_data = (double)(x * Z() + z) / (lines * Z()) * 100; | 1049 | + if(PROGRESS) progress = (double)(x * Z() + z+1) / (lines * Z()) * 100; |
1052 | } | 1050 | } |
1053 | 1051 | ||
1054 | //write slice data into target file | 1052 | //write slice data into target file |
@@ -1061,8 +1059,6 @@ public: | @@ -1061,8 +1059,6 @@ public: | ||
1061 | //free the temporary frame | 1059 | //free the temporary frame |
1062 | free(temp); | 1060 | free(temp); |
1063 | 1061 | ||
1064 | - thread_data = 100; | ||
1065 | - | ||
1066 | return true; | 1062 | return true; |
1067 | } | 1063 | } |
1068 | 1064 |
stim/envi/binary.h
@@ -24,11 +24,11 @@ protected: | @@ -24,11 +24,11 @@ protected: | ||
24 | std::fstream file; //file stream used for reading and writing | 24 | std::fstream file; //file stream used for reading and writing |
25 | std::string name; //file name | 25 | std::string name; //file name |
26 | 26 | ||
27 | - unsigned long long int R[D]; //resolution | 27 | + unsigned long long R[D]; //resolution |
28 | unsigned int header; //header size (in bytes) | 28 | unsigned int header; //header size (in bytes) |
29 | unsigned char* mask; //pointer to a character array: 0 = background, 1 = foreground (or valid data) | 29 | unsigned char* mask; //pointer to a character array: 0 = background, 1 = foreground (or valid data) |
30 | 30 | ||
31 | - unsigned int thread_data; //unsigned integer used to pass data to threads during processing | 31 | + double progress; //stores the progress on the current operation (accessible using a thread) |
32 | 32 | ||
33 | 33 | ||
34 | /// Private initialization function used to set default parameters in the data structure. | 34 | /// Private initialization function used to set default parameters in the data structure. |
@@ -37,7 +37,24 @@ protected: | @@ -37,7 +37,24 @@ protected: | ||
37 | header = 0; //initialize the header size to zero | 37 | header = 0; //initialize the header size to zero |
38 | mask = NULL; | 38 | mask = NULL; |
39 | 39 | ||
40 | - thread_data = 0; | 40 | + progress = 0; |
41 | + } | ||
42 | + | ||
43 | + //calculate the number of non-zero pixels in a mask | ||
44 | + unsigned long long nnz(unsigned char* mask, unsigned long long N){ | ||
45 | + | ||
46 | + unsigned long long n = 0; //initialize the counter to 0 (zero) | ||
47 | + if(mask == NULL) return N; //if the mask is NULL, assume all pixels are masked | ||
48 | + | ||
49 | + for(unsigned long long i = 0; i < N; i++){ //for each pixel | ||
50 | + if(mask[i] != 0) n++; //increment the counter for every non-zero pixel in the mask | ||
51 | + } | ||
52 | + return n; //return the number of nonzero pixels | ||
53 | + } | ||
54 | + | ||
55 | + /// Calculate the number of nonzero pixels in a mask over X-Y | ||
56 | + unsigned long long nnz(unsigned char* mask){ | ||
57 | + return nnz(mask, R[0] * R[1]); | ||
41 | } | 58 | } |
42 | 59 | ||
43 | /// Private helper function that returns the size of the file on disk using system functions. | 60 | /// Private helper function that returns the size of the file on disk using system functions. |
@@ -105,12 +122,12 @@ protected: | @@ -105,12 +122,12 @@ protected: | ||
105 | 122 | ||
106 | public: | 123 | public: |
107 | 124 | ||
108 | - unsigned int get_thread_data(){ | ||
109 | - return thread_data; | 125 | + unsigned int get_progress(){ |
126 | + return progress; | ||
110 | } | 127 | } |
111 | 128 | ||
112 | - void reset_thread_data(){ | ||
113 | - thread_data = 0; | 129 | + void reset_progress(){ |
130 | + progress = 0; | ||
114 | } | 131 | } |
115 | 132 | ||
116 | /// Open a binary file for streaming. | 133 | /// Open a binary file for streaming. |
@@ -178,7 +195,9 @@ public: | @@ -178,7 +195,9 @@ public: | ||
178 | 195 | ||
179 | /// @param p is a pointer to pre-allocated memory equal to the page size | 196 | /// @param p is a pointer to pre-allocated memory equal to the page size |
180 | /// @param page is the index of the page | 197 | /// @param page is the index of the page |
181 | - bool read_page( T * p, unsigned int page){ | 198 | + bool read_page( T * p, unsigned int page, bool PROGRESS = false){ |
199 | + | ||
200 | + if(PROGRESS) progress = 0; | ||
182 | 201 | ||
183 | if (page >= R[2]){ //make sure the bank number is right | 202 | if (page >= R[2]){ //make sure the bank number is right |
184 | std::cout<<"ERROR: page out of range"<<std::endl; | 203 | std::cout<<"ERROR: page out of range"<<std::endl; |
@@ -187,7 +206,7 @@ public: | @@ -187,7 +206,7 @@ public: | ||
187 | 206 | ||
188 | file.seekg(R[1] * R[0] * page * sizeof(T) + header, std::ios::beg); //write into memory from the binary file | 207 | file.seekg(R[1] * R[0] * page * sizeof(T) + header, std::ios::beg); //write into memory from the binary file |
189 | file.read((char *)p, R[0] * R[1] * sizeof(T)); | 208 | file.read((char *)p, R[0] * R[1] * sizeof(T)); |
190 | - | 209 | + if(PROGRESS) progress = 100; |
191 | return true; | 210 | return true; |
192 | } | 211 | } |
193 | 212 | ||
@@ -198,9 +217,11 @@ public: | @@ -198,9 +217,11 @@ public: | ||
198 | /// @param p is a pointer to pre-allocated memory equal to the line size R[2] | 217 | /// @param p is a pointer to pre-allocated memory equal to the line size R[2] |
199 | /// @param x is the x coordinate | 218 | /// @param x is the x coordinate |
200 | /// @param y is the y coordinate | 219 | /// @param y is the y coordinate |
201 | - bool read_line_01( T * p, unsigned int x, unsigned int y){ | 220 | + bool read_line_2( T * p, unsigned int x, unsigned int y, bool PROGRESS = false){ |
202 | unsigned int i; | 221 | unsigned int i; |
203 | 222 | ||
223 | + if(PROGRESS) progress = 0; | ||
224 | + | ||
204 | if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right | 225 | if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right |
205 | std::cout<<"ERROR: sample or line out of range"<<std::endl; | 226 | std::cout<<"ERROR: sample or line out of range"<<std::endl; |
206 | return false; | 227 | return false; |
@@ -211,7 +232,9 @@ public: | @@ -211,7 +232,9 @@ public: | ||
211 | { | 232 | { |
212 | file.read((char *)(p + i), sizeof(T)); | 233 | file.read((char *)(p + i), sizeof(T)); |
213 | file.seekg((R[1] * R[0] - 1) * sizeof(T), std::ios::cur); //go to the next band | 234 | file.seekg((R[1] * R[0] - 1) * sizeof(T), std::ios::cur); //go to the next band |
235 | + if(PROGRESS) progress = (double)i / (double)R[2] * 100; | ||
214 | } | 236 | } |
237 | + if(PROGRESS) progress = 100; | ||
215 | 238 | ||
216 | return true; | 239 | return true; |
217 | } | 240 | } |
@@ -221,7 +244,7 @@ public: | @@ -221,7 +244,7 @@ public: | ||
221 | /// @param p is a pointer to pre-allocated memory equal to the line size R[2] | 244 | /// @param p is a pointer to pre-allocated memory equal to the line size R[2] |
222 | /// @param x is the y coordinate | 245 | /// @param x is the y coordinate |
223 | /// @param y is the z coordinate | 246 | /// @param y is the z coordinate |
224 | - bool read_line_12(T * p, unsigned int y, unsigned int z){ | 247 | + bool read_line_0(T * p, unsigned int y, unsigned int z, bool PROGRESS = false){ |
225 | //test to make sure the specified value is within range | 248 | //test to make sure the specified value is within range |
226 | if( y >= R[1] || z >= R[2] ){ | 249 | if( y >= R[1] || z >= R[2] ){ |
227 | std::cout<<"ERROR: sample or line out of range"<<std::endl; | 250 | std::cout<<"ERROR: sample or line out of range"<<std::endl; |
@@ -230,7 +253,7 @@ public: | @@ -230,7 +253,7 @@ public: | ||
230 | 253 | ||
231 | file.seekg((z * R[0] * R[1] + y * R[0]) * sizeof(T), std::ios::beg); //seek to the start of the line | 254 | file.seekg((z * R[0] * R[1] + y * R[0]) * sizeof(T), std::ios::beg); //seek to the start of the line |
232 | file.read((char *)p, sizeof(T) * R[0]); //read the line | 255 | file.read((char *)p, sizeof(T) * R[0]); //read the line |
233 | - | 256 | + if(PROGRESS) progress = 100; |
234 | return true; | 257 | return true; |
235 | } | 258 | } |
236 | 259 | ||
@@ -239,7 +262,8 @@ public: | @@ -239,7 +262,8 @@ public: | ||
239 | /// @param p is a pointer to pre-allocated memory equal to the line size R[2] | 262 | /// @param p is a pointer to pre-allocated memory equal to the line size R[2] |
240 | /// @param x is the y coordinate | 263 | /// @param x is the y coordinate |
241 | /// @param z is the z coordinate | 264 | /// @param z is the z coordinate |
242 | - bool read_line_02(T * p, unsigned int x, unsigned int z){ | 265 | + bool read_line_1(T * p, unsigned int x, unsigned int z, bool PROGRESS = false){ |
266 | + if(PROGRESS) progress = 0; | ||
243 | //test to make sure the specified value is within range | 267 | //test to make sure the specified value is within range |
244 | if( x >= R[0] || z >= R[2] ){ | 268 | if( x >= R[0] || z >= R[2] ){ |
245 | std::cout<<"ERROR: sample or line out of range"<<std::endl; | 269 | std::cout<<"ERROR: sample or line out of range"<<std::endl; |
@@ -250,8 +274,9 @@ public: | @@ -250,8 +274,9 @@ public: | ||
250 | for (unsigned int i = 0; i < R[1]; i++){ //for each pixel in the line | 274 | for (unsigned int i = 0; i < R[1]; i++){ //for each pixel in the line |
251 | file.read((char *)(p + i), sizeof(T)); //read the pixel | 275 | file.read((char *)(p + i), sizeof(T)); //read the pixel |
252 | file.seekg((R[0] - 1) * sizeof(T), std::ios::cur); //seek to the next pixel in the line | 276 | file.seekg((R[0] - 1) * sizeof(T), std::ios::cur); //seek to the next pixel in the line |
277 | + if(PROGRESS) progress = (double)i / (double)R[1] * 100; | ||
253 | } | 278 | } |
254 | - | 279 | + if(PROGRESS) progress = 100; |
255 | return true; | 280 | return true; |
256 | } | 281 | } |
257 | 282 | ||
@@ -259,8 +284,8 @@ public: | @@ -259,8 +284,8 @@ public: | ||
259 | 284 | ||
260 | /// @param p is a pointer to pre-allocated memory of size R[1] * R[2] * sizeof(T) | 285 | /// @param p is a pointer to pre-allocated memory of size R[1] * R[2] * sizeof(T) |
261 | /// @param n is the 0-axis coordinate used to retrieve the plane | 286 | /// @param n is the 0-axis coordinate used to retrieve the plane |
262 | - bool read_plane_0(T* p, unsigned int n){ | ||
263 | - | 287 | + bool read_plane_0(T* p, unsigned int n, bool PROGRESS = false){ |
288 | + if(PROGRESS) progress = 0; | ||
264 | if (n >= R[0]){ //make sure the number is within the possible range | 289 | if (n >= R[0]){ //make sure the number is within the possible range |
265 | std::cout<<"ERROR read_plane_0: page out of range"<<std::endl; | 290 | std::cout<<"ERROR read_plane_0: page out of range"<<std::endl; |
266 | return false; | 291 | return false; |
@@ -274,10 +299,10 @@ public: | @@ -274,10 +299,10 @@ public: | ||
274 | for(unsigned int i = 0; i<N; i++){ | 299 | for(unsigned int i = 0; i<N; i++){ |
275 | file.read((char*)(p+i), sizeof(T)); | 300 | file.read((char*)(p+i), sizeof(T)); |
276 | file.seekg(jump, std::ios::cur); | 301 | file.seekg(jump, std::ios::cur); |
277 | - thread_data = (double)i / N * 100; | 302 | + if(PROGRESS) progress = (double)i / N * 100; |
278 | } | 303 | } |
279 | 304 | ||
280 | - thread_data = 100; | 305 | + if(PROGRESS) progress = 100; |
281 | return true; | 306 | return true; |
282 | 307 | ||
283 | 308 | ||
@@ -287,8 +312,8 @@ public: | @@ -287,8 +312,8 @@ public: | ||
287 | 312 | ||
288 | /// @param p is a pointer to pre-allocated memory of size R[0] * R[2] * sizeof(T) | 313 | /// @param p is a pointer to pre-allocated memory of size R[0] * R[2] * sizeof(T) |
289 | /// @param n is the 1-axis coordinate used to retrieve the plane | 314 | /// @param n is the 1-axis coordinate used to retrieve the plane |
290 | - bool read_plane_1(T* p, unsigned int n){ | ||
291 | - | 315 | + bool read_plane_1(T* p, unsigned int n, bool PROGRESS = false){ |
316 | + if(PROGRESS) progress = 0; | ||
292 | unsigned int L = R[0] * sizeof(T); //caculate the number of bytes in a sample line | 317 | unsigned int L = R[0] * sizeof(T); //caculate the number of bytes in a sample line |
293 | unsigned int jump = R[0] * (R[1] - 1) * sizeof(T); | 318 | unsigned int jump = R[0] * (R[1] - 1) * sizeof(T); |
294 | 319 | ||
@@ -299,13 +324,13 @@ public: | @@ -299,13 +324,13 @@ public: | ||
299 | 324 | ||
300 | file.seekg(R[0] * n * sizeof(T), std::ios::beg); | 325 | file.seekg(R[0] * n * sizeof(T), std::ios::beg); |
301 | for (unsigned i = 0; i < R[2]; i++){ | 326 | for (unsigned i = 0; i < R[2]; i++){ |
302 | - thread_data = (double)i / R[2] * 100; | 327 | + if(PROGRESS) progress = (double)i / R[2] * 100; |
303 | file.read((char *)(p + i * R[0]), L); | 328 | file.read((char *)(p + i * R[0]), L); |
304 | file.seekg( jump, std::ios::cur); | 329 | file.seekg( jump, std::ios::cur); |
305 | std::cout<<i<<" "; | 330 | std::cout<<i<<" "; |
306 | } | 331 | } |
307 | 332 | ||
308 | - thread_data = 100; | 333 | + if(PROGRESS) progress = 100; |
309 | return true; | 334 | return true; |
310 | } | 335 | } |
311 | 336 | ||
@@ -313,8 +338,8 @@ public: | @@ -313,8 +338,8 @@ public: | ||
313 | 338 | ||
314 | /// @param p is a pointer to pre-allocated memory of size R[0] * R[1] * sizeof(T) | 339 | /// @param p is a pointer to pre-allocated memory of size R[0] * R[1] * sizeof(T) |
315 | /// @param n is the 2-axis coordinate used to retrieve the plane | 340 | /// @param n is the 2-axis coordinate used to retrieve the plane |
316 | - bool read_plane_2(T* p, unsigned int n){ | ||
317 | - return read_page(p, n); | 341 | + bool read_plane_2(T* p, unsigned int n, bool PROGRESS = false){ |
342 | + return read_page(p, n, PROGRESS); | ||
318 | } | 343 | } |
319 | 344 | ||
320 | /// Reads a single pixel, treating the entire data set as a linear array | 345 | /// Reads a single pixel, treating the entire data set as a linear array |
stim/envi/bip.h
@@ -41,14 +41,77 @@ protected: | @@ -41,14 +41,77 @@ protected: | ||
41 | return R[0]; | 41 | return R[0]; |
42 | } | 42 | } |
43 | 43 | ||
44 | - using binary<T>::thread_data; | 44 | + using binary<T>::progress; |
45 | + | ||
46 | + /// Call the binary nnz() function for the BIP orientation | ||
47 | + unsigned long long nnz(unsigned char* mask){ | ||
48 | + return binary<T>::nnz(mask, X()*Y()); | ||
49 | + } | ||
50 | + | ||
51 | + /// Linear interpolation of a spectral value given the bounding spectral samples | ||
52 | + T lerp(double w, T low_v, double low_w, T high_v, double high_w){ | ||
53 | + if(low_w == high_w) return low_v; //if the interval is of zero length, just return one of the bounds | ||
54 | + double alpha = (w - low_w) / (high_w - low_w); //calculate the interpolation factor | ||
55 | + return (1.0 - alpha) * low_v + alpha * high_v; //interpolate | ||
56 | + } | ||
57 | + | ||
58 | + /// Gets the two band indices surrounding a given wavelength | ||
59 | + void band_bounds(double wavelength, unsigned long long& low, unsigned long long& high){ | ||
60 | + unsigned long long B = Z(); | ||
61 | + for(high = 0; high < B; high++){ | ||
62 | + if(w[high] > wavelength) break; | ||
63 | + } | ||
64 | + low = 0; | ||
65 | + if(high > 0) | ||
66 | + low = high-1; | ||
67 | + } | ||
68 | + | ||
69 | + /// Get the list of band numbers that bound a list of wavelengths | ||
70 | + void band_bounds(std::vector<double> wavelengths, | ||
71 | + std::vector<unsigned long long>& low_bands, | ||
72 | + std::vector<unsigned long long>& high_bands){ | ||
73 | + | ||
74 | + unsigned long long W = w.size(); //get the number of wavelengths in the list | ||
75 | + low_bands.resize(W); //pre-allocate space for the band lists | ||
76 | + high_bands.resize(W); | ||
77 | + | ||
78 | + for(unsigned long long wl = 0; wl < W; wl++){ //for each wavelength | ||
79 | + band_bounds(wavelengths[wl], low_bands[wl], high_bands[wl]); //find the low and high bands | ||
80 | + } | ||
81 | + } | ||
82 | + | ||
83 | + /// Returns the interpolated in the given spectrum based on the given wavelength | ||
84 | + | ||
85 | + /// @param s is the spectrum in main memory of length Z() | ||
86 | + /// @param wavelength is the wavelength value to interpolate out | ||
87 | + T interp_spectrum(T* s, double wavelength){ | ||
88 | + unsigned long long low, high; //indices for the bands surrounding wavelength | ||
89 | + band_bounds(wavelength, low, high); //get the surrounding band indices | ||
90 | + | ||
91 | + if(high == w.size()) return s[w.size()-1]; //if the high band is above the wavelength range, return the highest wavelength value | ||
92 | + | ||
93 | + return lerp(wavelength, s[low], w[low], s[high], w[high]); | ||
94 | + } | ||
95 | + | ||
96 | + /// Returns the interpolated value corresponding to the given list of wavelengths | ||
97 | + std::vector<T> interp_spectrum(T* s, std::vector<double> wavelengths){ | ||
98 | + | ||
99 | + unsigned long long N = wavelengths.size(); //get the number of wavelength measurements | ||
100 | + | ||
101 | + std::vector<T> v; //allocate space for the resulting values | ||
102 | + v.resize(wavelengths.size()); | ||
103 | + for(unsigned long long n = 0; n < N; n++){ //for each measurement | ||
104 | + v[n] = interp_spectrum(s, wavelengths[n]); //interpolate the measurement | ||
105 | + } | ||
106 | + return v; | ||
107 | + } | ||
45 | 108 | ||
46 | public: | 109 | public: |
47 | 110 | ||
48 | using binary<T>::open; | 111 | using binary<T>::open; |
49 | using binary<T>::file; | 112 | using binary<T>::file; |
50 | using binary<T>::R; | 113 | using binary<T>::R; |
51 | - using binary<T>::read_line_12; | 114 | + using binary<T>::read_line_0; |
52 | 115 | ||
53 | /// Open a data file for reading using the class interface. | 116 | /// Open a data file for reading using the class interface. |
54 | 117 | ||
@@ -73,19 +136,19 @@ public: | @@ -73,19 +136,19 @@ public: | ||
73 | 136 | ||
74 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. | 137 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. |
75 | /// @param page <= B is the integer number of the band to be copied. | 138 | /// @param page <= B is the integer number of the band to be copied. |
76 | - bool band_index( T * p, unsigned int page){ | ||
77 | - return binary<T>::read_plane_0(p, page); | 139 | + bool band_index( T * p, unsigned int page, bool PROGRESS = false){ |
140 | + return binary<T>::read_plane_0(p, page, PROGRESS); | ||
78 | } | 141 | } |
79 | 142 | ||
80 | /// Retrieve a single band (by numerical label) and stores it in pre-allocated memory. | 143 | /// Retrieve a single band (by numerical label) and stores it in pre-allocated memory. |
81 | 144 | ||
82 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. | 145 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. |
83 | /// @param wavelength is a floating point value (usually a wavelength in spectral data) used as a label for the band to be copied. | 146 | /// @param wavelength is a floating point value (usually a wavelength in spectral data) used as a label for the band to be copied. |
84 | - bool band( T * p, double wavelength){ | 147 | + bool band( T * p, double wavelength, bool PROGRESS = false){ |
85 | 148 | ||
86 | //if there are no wavelengths in the BSQ file | 149 | //if there are no wavelengths in the BSQ file |
87 | if(w.size() == 0) | 150 | if(w.size() == 0) |
88 | - return band_index(p, (unsigned int)wavelength); | 151 | + return band_index(p, (unsigned int)wavelength, PROGRESS); |
89 | 152 | ||
90 | unsigned int XY = X() * Y(); //calculate the number of pixels in a band | 153 | unsigned int XY = X() * Y(); //calculate the number of pixels in a band |
91 | 154 | ||
@@ -96,7 +159,7 @@ public: | @@ -96,7 +159,7 @@ public: | ||
96 | 159 | ||
97 | //if wavelength is smaller than the first one in header file | 160 | //if wavelength is smaller than the first one in header file |
98 | if ( w[page] > wavelength ){ | 161 | if ( w[page] > wavelength ){ |
99 | - band_index(p, page); | 162 | + band_index(p, page, PROGRESS); |
100 | return true; | 163 | return true; |
101 | } | 164 | } |
102 | 165 | ||
@@ -105,7 +168,7 @@ public: | @@ -105,7 +168,7 @@ public: | ||
105 | page++; | 168 | page++; |
106 | //if wavelength is larger than the last wavelength in header file | 169 | //if wavelength is larger than the last wavelength in header file |
107 | if (page == Z()) { | 170 | if (page == Z()) { |
108 | - band_index(p, Z()-1); | 171 | + band_index(p, Z()-1, PROGRESS); |
109 | return true; | 172 | return true; |
110 | } | 173 | } |
111 | } | 174 | } |
@@ -116,7 +179,7 @@ public: | @@ -116,7 +179,7 @@ public: | ||
116 | p1=(T*)malloc( XY * sizeof(T)); //memory allocation | 179 | p1=(T*)malloc( XY * sizeof(T)); //memory allocation |
117 | p2=(T*)malloc( XY * sizeof(T)); | 180 | p2=(T*)malloc( XY * sizeof(T)); |
118 | band_index(p1, page - 1); | 181 | band_index(p1, page - 1); |
119 | - band_index(p2, page ); | 182 | + band_index(p2, page, PROGRESS); |
120 | for(unsigned i=0; i < XY; i++){ | 183 | for(unsigned i=0; i < XY; i++){ |
121 | double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]); | 184 | double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]); |
122 | p[i] = (p2[i] - p1[i]) * r + p1[i]; | 185 | p[i] = (p2[i] - p1[i]) * r + p1[i]; |
@@ -126,7 +189,7 @@ public: | @@ -126,7 +189,7 @@ public: | ||
126 | } | 189 | } |
127 | else //if the wavelength is equal to a wavelength in header file | 190 | else //if the wavelength is equal to a wavelength in header file |
128 | { | 191 | { |
129 | - band_index(p, page); | 192 | + band_index(p, page, PROGRESS); |
130 | } | 193 | } |
131 | 194 | ||
132 | return true; | 195 | return true; |
@@ -137,8 +200,8 @@ public: | @@ -137,8 +200,8 @@ public: | ||
137 | /// @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. |
138 | /// @param x is the x-coordinate (dimension 1) of the spectrum. | 201 | /// @param x is the x-coordinate (dimension 1) of the spectrum. |
139 | /// @param y is the y-coordinate (dimension 2) of the spectrum. | 202 | /// @param y is the y-coordinate (dimension 2) of the spectrum. |
140 | - bool spectrum(T * p, unsigned x, unsigned y){ | ||
141 | - return read_line_12(p, x, y); //read a line in the binary YZ plane (dimension order for BIP is ZXY) | 203 | + bool spectrum(T * p, unsigned x, unsigned y, bool PROGRESS = false){ |
204 | + return read_line_0(p, x, y, PROGRESS); //read a line in the binary YZ plane (dimension order for BIP is ZXY) | ||
142 | } | 205 | } |
143 | 206 | ||
144 | /// Retrieves a band of x values from a given xz plane. | 207 | /// Retrieves a band of x values from a given xz plane. |
@@ -235,8 +298,8 @@ public: | @@ -235,8 +298,8 @@ public: | ||
235 | /// @param n is an integer index to the pixel using linear array indexing. | 298 | /// @param n is an integer index to the pixel using linear array indexing. |
236 | bool pixel(T * p, unsigned n){ | 299 | bool pixel(T * p, unsigned n){ |
237 | 300 | ||
238 | - unsigned bandnum = X() * Y(); //calculate numbers in one band | ||
239 | - if ( n >= bandnum){ //make sure the pixel number is right | 301 | + unsigned N = X() * Y(); //calculate numbers in one band |
302 | + if ( n >= N){ //make sure the pixel number is right | ||
240 | std::cout<<"ERROR: sample or line out of range"<<std::endl; | 303 | std::cout<<"ERROR: sample or line out of range"<<std::endl; |
241 | return false; | 304 | return false; |
242 | } | 305 | } |
@@ -255,113 +318,57 @@ public: | @@ -255,113 +318,57 @@ public: | ||
255 | 318 | ||
256 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. | 319 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. |
257 | /// @param wls is the list of baseline points based on band labels. | 320 | /// @param wls is the list of baseline points based on band labels. |
258 | - bool baseline(std::string outname, std::vector<double> wls){ | ||
259 | - | ||
260 | - unsigned N = wls.size(); //get the number of baseline points | 321 | + bool baseline(std::string outname, std::vector<double> base_pts, bool PROGRESS = false){ |
261 | 322 | ||
262 | std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file | 323 | std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file |
263 | std::string headername = outname + ".hdr"; //the header file name | 324 | std::string headername = outname + ".hdr"; //the header file name |
264 | 325 | ||
265 | - //simplify image resolution | ||
266 | - unsigned int ZX = Z() * X(); //calculate the number of points in a Y slice | ||
267 | - unsigned int L = ZX * sizeof(T); //calculate the number of bytes of a Y slice | ||
268 | - unsigned int B = Z(); | ||
269 | - | ||
270 | - T* c; //pointer to the current Y slice | ||
271 | - c = (T*)malloc(L); //memory allocation | ||
272 | - | ||
273 | - T* a; //pointer to the two YZ lines surrounding the current YZ line | ||
274 | - T* b; | ||
275 | - | ||
276 | - a = (T*)malloc(X() * sizeof(T)); | ||
277 | - b = (T*)malloc(X() * sizeof(T)); | ||
278 | - | ||
279 | - | ||
280 | - double ai, bi; //stores the two baseline points wavelength surrounding the current band | ||
281 | - double ci; //stores the current band's wavelength | ||
282 | - unsigned control; | ||
283 | - | ||
284 | - if (a == NULL || b == NULL || c == NULL){ | ||
285 | - std::cout<<"ERROR: error allocating memory"; | ||
286 | - exit(1); | ||
287 | - } | ||
288 | - // loop start correct every y slice | ||
289 | - | ||
290 | - for (unsigned k =0; k < Y(); k++) | ||
291 | - { | ||
292 | - //get the current y slice | ||
293 | - read_plane_y(c, k); | ||
294 | - | ||
295 | - //initialize lownum, highnum, low, high | ||
296 | - control=0; | ||
297 | - ai = w[0]; | ||
298 | - //if no baseline point is specified at band 0, | ||
299 | - //set the baseline point at band 0 to 0 | ||
300 | - if(wls[0] != w[0]){ | ||
301 | - bi = wls[control]; | ||
302 | - memset(a, (char)0, X() * sizeof(T) ); | ||
303 | - } | ||
304 | - //else get the low band | ||
305 | - else{ | ||
306 | - control++; | ||
307 | - read_x_from_xz(a, c, ai); | ||
308 | - bi = wls[control]; | ||
309 | - } | ||
310 | - //get the high band | ||
311 | - read_x_from_xz(b, c, bi); | ||
312 | - | ||
313 | - //correct every YZ line | ||
314 | - | ||
315 | - for(unsigned cii = 0; cii < B; cii++){ | ||
316 | - //update baseline points, if necessary | ||
317 | - if( w[cii] >= bi && cii != B - 1) { | ||
318 | - //if the high band is now on the last BL point? | ||
319 | - if (control != N-1) { | ||
320 | - | ||
321 | - control++; //increment the index | ||
322 | - | ||
323 | - std::swap(a, b); //swap the baseline band pointers | ||
324 | - | ||
325 | - ai = bi; | ||
326 | - bi = wls[control]; | ||
327 | - read_x_from_xz(b, c, bi); | ||
328 | - | ||
329 | - } | ||
330 | - //if the last BL point on the last band of the file? | ||
331 | - else if ( wls[control] < w[B - 1]) { | ||
332 | - | ||
333 | - std::swap(a, b); //swap the baseline band pointers | ||
334 | - | ||
335 | - memset(b, (char)0, X() * sizeof(T) ); //clear the high band | ||
336 | - | ||
337 | - ai = bi; | ||
338 | - bi = w[B - 1]; | ||
339 | - } | 326 | + unsigned long long N = X() * Y(); //calculate the total number of pixels to be processed |
327 | + unsigned long long B = Z(); //get the number of bands | ||
328 | + T* s = (T*)malloc(sizeof(T) * B); //allocate memory to store a pixel | ||
329 | + T* sbc = (T*)malloc(sizeof(T) * B); //allocate memory to store the baseline corrected spectrum | ||
330 | + | ||
331 | + std::vector<T> base_vals; //allocate space for the values at each baseline point | ||
332 | + double aw, bw; //surrounding baseline point wavelengths | ||
333 | + T av, bv; //surrounding baseline point values | ||
334 | + double alpha; | ||
335 | + unsigned long long ai, bi; //surrounding baseline point band indices | ||
336 | + for(unsigned long long n = 0; n < N; n++){ //for each pixel in the image | ||
337 | + pixel(s, n); //retrieve the spectrum s | ||
338 | + base_vals = interp_spectrum(s, base_pts); //get the values at each baseline point | ||
339 | + | ||
340 | + ai = bi = 0; | ||
341 | + aw = w[0]; //initialize the current baseline points (assume the spectrum starts at 0) | ||
342 | + av = s[0]; | ||
343 | + bw = base_pts[0]; | ||
344 | + for(unsigned long long b = 0; b < B; b++){ //for each band in the spectrum | ||
345 | + while(bi < base_pts.size() && base_pts[bi] < w[b]) //while the current wavelength is higher than the second baseline point | ||
346 | + bi++; //move to the next baseline point | ||
347 | + if(bi < base_pts.size()){ | ||
348 | + bw = base_pts[bi]; //set the wavelength for the upper bound baseline point | ||
349 | + bv = base_vals[bi]; //set the value for the upper bound baseline point | ||
340 | } | 350 | } |
341 | - | ||
342 | - ci = w[cii]; | ||
343 | - | ||
344 | - //perform the baseline correction | ||
345 | - for(unsigned i=0; i < X(); i++) | ||
346 | - { | ||
347 | - double r = (double) (ci - ai) / (double) (bi - ai); | ||
348 | - c[i * B + cii] =(T) ( c[i * B + cii] - (b[i] - a[i]) * r - a[i] ); | 351 | + if(bi == base_pts.size()){ //if we have passed the last baseline point |
352 | + bw = w[B-1]; //set the outer bound to the last spectral band | ||
353 | + bv = s[B-1]; | ||
349 | } | 354 | } |
350 | - | ||
351 | - }//loop for YZ line end | ||
352 | - target.write(reinterpret_cast<const char*>(c), L); //write the corrected data into destination | ||
353 | - | ||
354 | - thread_data = (double)k / Y() * 100; | ||
355 | - }//loop for Y slice end | 355 | + if(bi != 0){ |
356 | + ai = bi - 1; //set the lower bound baseline point index | ||
357 | + aw = base_pts[ai]; //set the wavelength for the lower bound baseline point | ||
358 | + av = base_vals[ai]; //set the value for the lower bound baseline point | ||
359 | + } | ||
360 | + sbc[b] = s[b] - lerp(w[b], av, aw, bv, bw); //perform the baseline correction and save the new value | ||
361 | + } | ||
356 | 362 | ||
363 | + if(PROGRESS) progress = (double)(n+1) / N * 100; //set the current progress | ||
357 | 364 | ||
365 | + target.write((char*)sbc, sizeof(T) * B); //write the corrected data into destination | ||
366 | + } //end for each pixel | ||
358 | 367 | ||
359 | - free(a); | ||
360 | - free(b); | ||
361 | - free(c); | 368 | + free(s); |
369 | + free(sbc); | ||
362 | target.close(); | 370 | target.close(); |
363 | - | ||
364 | - thread_data = 100; | 371 | + |
365 | return true; | 372 | return true; |
366 | 373 | ||
367 | } | 374 | } |
@@ -371,80 +378,41 @@ public: | @@ -371,80 +378,41 @@ public: | ||
371 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. | 378 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. |
372 | /// @param w is the label specifying the band that the hyperspectral image will be normalized to. | 379 | /// @param w is the label specifying the band that the hyperspectral image will be normalized to. |
373 | /// @param t is a threshold specified such that a spectrum with a value at w less than t is set to zero. Setting this threshold allows the user to limit division by extremely small numbers. | 380 | /// @param t is a threshold specified such that a spectrum with a value at w less than t is set to zero. Setting this threshold allows the user to limit division by extremely small numbers. |
374 | - bool normalize(std::string outname, double w, double t = 0.0) | 381 | + bool normalize(std::string outname, double w, double t = 0.0, bool PROGRESS = false) |
375 | { | 382 | { |
376 | - unsigned int B = Z(); //calculate the number of bands | ||
377 | - unsigned int ZX = Z() * X(); | ||
378 | - unsigned int XY = X() * Y(); //calculate the number of pixels in a band | ||
379 | - unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band | ||
380 | - unsigned int L = ZX * sizeof(T); | ||
381 | - | ||
382 | std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file | 383 | std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file |
383 | - std::string headername = outname + ".hdr"; //the header file name | ||
384 | - | ||
385 | - T * c; //pointer to the current ZX slice | ||
386 | - T * b; //pointer to the standard band | ||
387 | - | ||
388 | - b = (T*)malloc( S ); //memory allocation | ||
389 | - c = (T*)malloc( L ); | ||
390 | - | ||
391 | - band(b, w); //get the certain band into memory | ||
392 | - | ||
393 | - for(unsigned j = 0; j < Y(); j++) | ||
394 | - { | ||
395 | - read_plane_y(c, j); | ||
396 | - unsigned jX = j * X(); //to avoid calculating it many times | ||
397 | - for(unsigned i = 0; i < X(); i++) | ||
398 | - { | ||
399 | - unsigned iB = i * B; | ||
400 | - for(unsigned m = 0; m < B; m++) | ||
401 | - { | ||
402 | - if( b[i+jX] < t ) | ||
403 | - c[m + iB] = (T)0.0; | ||
404 | - else | ||
405 | - c[m + iB] = c[m + iB] / b[i + jX]; //perform normalization | ||
406 | - } | 384 | + std::string headername = outname + ".hdr"; //the header file name |
385 | + | ||
386 | + unsigned long long N = X() * Y(); //calculate the total number of pixels to be processed | ||
387 | + unsigned long long B = Z(); //get the number of bands | ||
388 | + T* s = (T*)malloc(sizeof(T) * B); //allocate memory to store a pixel | ||
389 | + T nv; //stores the value of the normalized band | ||
390 | + for(unsigned long long n = 0; n < N; n++){ //for each pixel in the image | ||
391 | + pixel(s, n); //retrieve the spectrum s | ||
392 | + nv = interp_spectrum(s, w); //find the value of the normalization band | ||
393 | + if(abs(nv) <= t) //if the normalization band is below threshold | ||
394 | + memset(s, 0, sizeof(T) * B); //set the output to zero | ||
395 | + else{ | ||
396 | + for(unsigned long long b = 0; b < B; b++){ //for each band in the spectrum | ||
397 | + s[b] /= nv; //divide by the normalization value | ||
398 | + } | ||
407 | } | 399 | } |
408 | - target.write(reinterpret_cast<const char*>(c), L); //write normalized data into destination | ||
409 | - | ||
410 | - thread_data = (double) j / Y() * 100; | ||
411 | - } | 400 | + |
401 | + if(PROGRESS) progress = (double)(n+1) / N * 100; //set the current progress | ||
412 | 402 | ||
403 | + target.write((char*)s, sizeof(T) * B); //write the corrected data into destination | ||
404 | + } //end for each pixel | ||
413 | 405 | ||
414 | - free(b); | ||
415 | - free(c); | 406 | + free(s); |
416 | target.close(); | 407 | target.close(); |
417 | - thread_data = 100; | ||
418 | return true; | 408 | return true; |
419 | } | 409 | } |
420 | 410 | ||
421 | - /// Convert the current BIP file to a BSQ file with the specified file name. | ||
422 | - | ||
423 | - /// @param outname is the name of the output BSQ file to be saved to disk. | ||
424 | - bool bsq(std::string outname) | ||
425 | - { | ||
426 | - std::string temp = outname + "_temp"; | ||
427 | - std::string headtemp = temp + ".hdr"; | ||
428 | - //first creat a temporary bil file and convert bip file to bil file | ||
429 | - bil(temp); | ||
430 | - | ||
431 | - stim::bil<T> n; | ||
432 | - if(n.open(temp, X(), Y(), Z(), offset, w)==false){ //open infile | ||
433 | - std::cout<<"ERROR: unable to open input file"<<std::endl; | ||
434 | - exit(1); | ||
435 | - } | ||
436 | - //then convert bil file to bsq file | ||
437 | - n.bsq(outname); | ||
438 | - n.close(); | ||
439 | - remove(temp.c_str()); | ||
440 | - remove(headtemp.c_str()); | ||
441 | - return true; | ||
442 | - } | ||
443 | 411 | ||
444 | /// Convert the current BIP file to a BIL file with the specified file name. | 412 | /// Convert the current BIP file to a BIL file with the specified file name. |
445 | 413 | ||
446 | /// @param outname is the name of the output BIL file to be saved to disk. | 414 | /// @param outname is the name of the output BIL file to be saved to disk. |
447 | - bool bil(std::string outname) | 415 | + bool bil(std::string outname, bool PROGRESS = false) |
448 | { | 416 | { |
449 | unsigned int S = X() * Z() * sizeof(T); //calculate the number of bytes in a ZX slice | 417 | unsigned int S = X() * Z() * sizeof(T); //calculate the number of bytes in a ZX slice |
450 | 418 | ||
@@ -465,13 +433,11 @@ public: | @@ -465,13 +433,11 @@ public: | ||
465 | for ( unsigned j = 0; j < X(); j++) | 433 | for ( unsigned j = 0; j < X(); j++) |
466 | q[ks + j] = p[k + j * Z()]; | 434 | q[ks + j] = p[k + j * Z()]; |
467 | 435 | ||
468 | - thread_data = (double)(i * Z() + k) / (Y() * Z()) * 100; | 436 | + if(PROGRESS) progress = (double)(i * Z() + k+1) / (Y() * Z()) * 100; |
469 | } | 437 | } |
470 | target.write(reinterpret_cast<const char*>(q), S); //write a band data into target file | 438 | target.write(reinterpret_cast<const char*>(q), S); //write a band data into target file |
471 | } | 439 | } |
472 | 440 | ||
473 | - thread_data = 100; | ||
474 | - | ||
475 | free(p); | 441 | free(p); |
476 | free(q); | 442 | free(q); |
477 | target.close(); | 443 | target.close(); |
@@ -909,7 +875,7 @@ public: | @@ -909,7 +875,7 @@ public: | ||
909 | //write this pixel out | 875 | //write this pixel out |
910 | target.write((char *)spectrum, B * sizeof(T)); | 876 | target.write((char *)spectrum, B * sizeof(T)); |
911 | 877 | ||
912 | - thread_data = (double) x / XY * 100; | 878 | + progress = (double) x / XY * 100; |
913 | } | 879 | } |
914 | 880 | ||
915 | } | 881 | } |
@@ -918,7 +884,7 @@ public: | @@ -918,7 +884,7 @@ public: | ||
918 | target.close(); | 884 | target.close(); |
919 | free(spectrum); | 885 | free(spectrum); |
920 | 886 | ||
921 | - thread_data = 100; | 887 | + progress = 100; |
922 | 888 | ||
923 | return true; | 889 | return true; |
924 | } | 890 | } |
@@ -962,7 +928,7 @@ public: | @@ -962,7 +928,7 @@ public: | ||
962 | target.write((char *)spectrum, B * sizeof(T)); | 928 | target.write((char *)spectrum, B * sizeof(T)); |
963 | } | 929 | } |
964 | 930 | ||
965 | - thread_data = (double)x / XY * 100; | 931 | + progress = (double)x / XY * 100; |
966 | 932 | ||
967 | } | 933 | } |
968 | 934 | ||
@@ -970,7 +936,7 @@ public: | @@ -970,7 +936,7 @@ public: | ||
970 | target.close(); | 936 | target.close(); |
971 | free(spectrum); | 937 | free(spectrum); |
972 | 938 | ||
973 | - thread_data = 100; | 939 | + progress = 100; |
974 | 940 | ||
975 | return true; | 941 | return true; |
976 | 942 | ||
@@ -981,7 +947,7 @@ public: | @@ -981,7 +947,7 @@ public: | ||
981 | 947 | ||
982 | /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum | 948 | /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum |
983 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location | 949 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location |
984 | - bool avg_band(double* p, unsigned char* mask = NULL){ | 950 | + bool avg_band(double* p, unsigned char* mask = NULL, bool PROGRESS = false){ |
985 | unsigned long long XY = X() * Y(); | 951 | unsigned long long XY = X() * Y(); |
986 | T* temp = (T*)malloc(sizeof(T) * Z()); | 952 | T* temp = (T*)malloc(sizeof(T) * Z()); |
987 | //Iinitialize | 953 | //Iinitialize |
@@ -989,12 +955,8 @@ public: | @@ -989,12 +955,8 @@ public: | ||
989 | p[j] = 0; | 955 | p[j] = 0; |
990 | } | 956 | } |
991 | //calculate vaild number in a band | 957 | //calculate vaild number in a band |
992 | - unsigned count = 0; | ||
993 | - for (unsigned j = 0; j < XY; j++){ | ||
994 | - if (mask == NULL || mask[j] != 0){ | ||
995 | - count++; | ||
996 | - } | ||
997 | - } | 958 | + unsigned count = nnz(mask); |
959 | + | ||
998 | //calculate average number of a band | 960 | //calculate average number of a band |
999 | for (unsigned i = 0; i < XY; i++){ | 961 | for (unsigned i = 0; i < XY; i++){ |
1000 | if (mask == NULL || mask[i] != 0){ | 962 | if (mask == NULL || mask[i] != 0){ |
@@ -1003,22 +965,21 @@ public: | @@ -1003,22 +965,21 @@ public: | ||
1003 | p[j] += (double)temp[j] / (double)count; | 965 | p[j] += (double)temp[j] / (double)count; |
1004 | } | 966 | } |
1005 | } | 967 | } |
1006 | - thread_data = (double)i / XY * 100; | 968 | + if(PROGRESS) progress = (double)(i+1) / XY * 100; |
1007 | } | 969 | } |
1008 | 970 | ||
1009 | free(temp); | 971 | free(temp); |
1010 | - thread_data = 100; | ||
1011 | return true; | 972 | return true; |
1012 | } | 973 | } |
1013 | #ifdef CUDA_FOUND | 974 | #ifdef CUDA_FOUND |
1014 | /// Calculate the covariance matrix for masked pixels using cuBLAS | 975 | /// Calculate the covariance matrix for masked pixels using cuBLAS |
1015 | - bool cu_co_matrix(double* co, double* avg, unsigned char *mask){ | 976 | + bool co_matrix_cublas(double* co, double* avg, unsigned char *mask, bool PROGRESS = false){ |
1016 | 977 | ||
1017 | cudaError_t cudaStat; | 978 | cudaError_t cudaStat; |
1018 | cublasStatus_t stat; | 979 | cublasStatus_t stat; |
1019 | cublasHandle_t handle; | 980 | cublasHandle_t handle; |
1020 | 981 | ||
1021 | - thread_data = 0; //initialize the progress to zero (0) | 982 | + progress = 0; //initialize the progress to zero (0) |
1022 | unsigned long long XY = X() * Y(); //calculate the number of elements in a band image | 983 | unsigned long long XY = X() * Y(); //calculate the number of elements in a band image |
1023 | unsigned long long B = Z(); //calculate the number of spectral elements | 984 | unsigned long long B = Z(); //calculate the number of spectral elements |
1024 | 985 | ||
@@ -1047,7 +1008,7 @@ public: | @@ -1047,7 +1008,7 @@ public: | ||
1047 | stat = cublasDaxpy(handle, B, &axpy_alpha, avg_dev, 1, s_dev, 1); //subtract the average spectrum | 1008 | stat = cublasDaxpy(handle, B, &axpy_alpha, avg_dev, 1, s_dev, 1); //subtract the average spectrum |
1048 | stat = cublasDsyr(handle, CUBLAS_FILL_MODE_UPPER, B, &ger_alpha, s_dev, 1, A_dev, B); //calculate the covariance matrix (symmetric outer product) | 1009 | stat = cublasDsyr(handle, CUBLAS_FILL_MODE_UPPER, B, &ger_alpha, s_dev, 1, A_dev, B); //calculate the covariance matrix (symmetric outer product) |
1049 | } | 1010 | } |
1050 | - thread_data = (double)xy / XY * 100; //record the current progress | 1011 | + if(PROGRESS) progress = (double)(xy+1) / XY * 100; //record the current progress |
1051 | 1012 | ||
1052 | } | 1013 | } |
1053 | 1014 | ||
@@ -1063,7 +1024,6 @@ public: | @@ -1063,7 +1024,6 @@ public: | ||
1063 | } | 1024 | } |
1064 | } | 1025 | } |
1065 | 1026 | ||
1066 | - thread_data = 100; //processing complete | ||
1067 | return true; | 1027 | return true; |
1068 | } | 1028 | } |
1069 | #endif | 1029 | #endif |
@@ -1073,23 +1033,19 @@ public: | @@ -1073,23 +1033,19 @@ public: | ||
1073 | /// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix | 1033 | /// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix |
1074 | /// @param avg is a pointer to memory of size B that stores the average spectrum | 1034 | /// @param avg is a pointer to memory of size B that stores the average spectrum |
1075 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location | 1035 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location |
1076 | - bool co_matrix(double* co, double* avg, unsigned char *mask){ | 1036 | + bool co_matrix(double* co, double* avg, unsigned char *mask, bool PROGRESS = false){ |
1077 | 1037 | ||
1078 | #ifdef CUDA_FOUND | 1038 | #ifdef CUDA_FOUND |
1079 | - return cu_co_matrix(co, avg, mask); //if CUDA is available, use cuBLAS to calculate the covariance matrix | 1039 | + return co_matrix_cublas(co, avg, mask, PROGRESS); //if CUDA is available, use cuBLAS to calculate the covariance matrix |
1080 | #endif | 1040 | #endif |
1081 | - thread_data = 0; | 1041 | + progress = 0; |
1082 | //memory allocation | 1042 | //memory allocation |
1083 | unsigned long long XY = X() * Y(); | 1043 | unsigned long long XY = X() * Y(); |
1084 | unsigned long long B = Z(); | 1044 | unsigned long long B = Z(); |
1085 | T* temp = (T*)malloc(sizeof(T) * B); | 1045 | T* temp = (T*)malloc(sizeof(T) * B); |
1086 | //count vaild pixels in a band | 1046 | //count vaild pixels in a band |
1087 | - unsigned long long count = 0; | ||
1088 | - for (unsigned long long j = 0; j < XY; j++){ | ||
1089 | - if (mask == NULL || mask[j] != 0){ | ||
1090 | - count++; | ||
1091 | - } | ||
1092 | - } | 1047 | + unsigned long long count = nnz(mask); |
1048 | + | ||
1093 | //initialize covariance matrix | 1049 | //initialize covariance matrix |
1094 | memset(co, 0, B * B * sizeof(double)); | 1050 | memset(co, 0, B * B * sizeof(double)); |
1095 | 1051 | ||
@@ -1110,7 +1066,7 @@ public: | @@ -1110,7 +1066,7 @@ public: | ||
1110 | co_half[idx++] += temp_precise[b0] * temp_precise[b1]; | 1066 | co_half[idx++] += temp_precise[b0] * temp_precise[b1]; |
1111 | } | 1067 | } |
1112 | } | 1068 | } |
1113 | - thread_data = (double)xy / XY * 100; | 1069 | + if(PROGRESS) progress = (double)(xy+1) / XY * 100; |
1114 | } | 1070 | } |
1115 | idx = 0; | 1071 | idx = 0; |
1116 | for (unsigned long long i = 0; i < B; i++){ //copy the precision matrix to both halves of the output matrix | 1072 | for (unsigned long long i = 0; i < B; i++){ //copy the precision matrix to both halves of the output matrix |
@@ -1119,12 +1075,78 @@ public: | @@ -1119,12 +1075,78 @@ public: | ||
1119 | } | 1075 | } |
1120 | } | 1076 | } |
1121 | 1077 | ||
1122 | - thread_data = 100; //processing complete | ||
1123 | free(temp); | 1078 | free(temp); |
1124 | free(temp_precise); | 1079 | free(temp_precise); |
1125 | return true; | 1080 | return true; |
1126 | } | 1081 | } |
1127 | 1082 | ||
1083 | + bool project(std::string outfile, double* center, double* basis, unsigned long long M, bool PROGRESS = false){ | ||
1084 | + | ||
1085 | + std::ofstream target(outfile.c_str(), std::ios::binary); //open the target binary file | ||
1086 | + std::string headername = outfile + ".hdr"; //the header file name | ||
1087 | + | ||
1088 | + //memory allocation | ||
1089 | + unsigned long long XY = X() * Y(); | ||
1090 | + unsigned long long B = Z(); | ||
1091 | + | ||
1092 | + T* s = (T*)malloc(sizeof(T) * B); //allocate space for the spectrum | ||
1093 | + T* rs = (T*)malloc(sizeof(T) * M); //allocate space for the projected spectrum | ||
1094 | + double* bv; //pointer to the current projection vector | ||
1095 | + for(unsigned long long xy = 0; xy < XY; xy++){ //for each spectrum in the image | ||
1096 | + pixel(s, xy); //load the spectrum | ||
1097 | + memset(rs, 0, sizeof(T) * M); //initialize the rotated spectrum to zero (0) | ||
1098 | + for(unsigned long long m = 0; m < M; m++){ //for each basis vector | ||
1099 | + bv = &basis[m * B]; //assign 'bv' to the beginning of the basis vector | ||
1100 | + for(unsigned long long b = 0; b < B; b++){ //for each band | ||
1101 | + rs[m] += (s[b] - center[b]) * bv[b]; //center the spectrum and perform the projection | ||
1102 | + } | ||
1103 | + } | ||
1104 | + | ||
1105 | + target.write(reinterpret_cast<const char*>(rs), sizeof(T) * M); //write the projected vector | ||
1106 | + if(PROGRESS) progress = (double)(xy+1) / XY * 100; | ||
1107 | + } | ||
1108 | + | ||
1109 | + free(s); //free temporary storage arrays | ||
1110 | + free(rs); | ||
1111 | + target.close(); //close the output file | ||
1112 | + | ||
1113 | + return true; | ||
1114 | + } | ||
1115 | + | ||
1116 | + bool inverse(std::string outfile, double* center, double* basis, unsigned long long B, unsigned long long C = 0, bool PROGRESS = false){ | ||
1117 | + | ||
1118 | + std::ofstream target(outfile.c_str(), std::ios::binary); //open the target binary file | ||
1119 | + std::string headername = outfile + ".hdr"; //the header file name | ||
1120 | + | ||
1121 | + //memory allocation | ||
1122 | + unsigned long long XY = X() * Y(); | ||
1123 | + if(C == 0) C = Z(); //if no coefficient number is given, assume all are used | ||
1124 | + C = std::min<unsigned long long>(C, Z()); //set the number of coefficients (the user can specify fewer) | ||
1125 | + | ||
1126 | + T* coeff = (T*)malloc(sizeof(T) * Z()); //allocate space for the coefficients | ||
1127 | + T* s = (T*)malloc(sizeof(T) * B); //allocate space for the spectrum | ||
1128 | + double* bv; //pointer to the current projection vector | ||
1129 | + for(unsigned long long xy = 0; xy < XY; xy++){ //for each pixel in the image (expressed as a set of coefficients) | ||
1130 | + pixel(coeff, xy); //load the coefficients | ||
1131 | + memset(s, 0, sizeof(T) * B); //initialize the spectrum to zero (0) | ||
1132 | + for(unsigned long long c = 0; c < C; c++){ //for each basis vector coefficient | ||
1133 | + bv = &basis[c * B]; //assign 'bv' to the beginning of the basis vector | ||
1134 | + for(unsigned long long b = 0; b < B; b++){ //for each component of the basis vector | ||
1135 | + s[b] += coeff[c] * bv[b] + center[b]; //calculate the contribution of each element of the basis vector in the final spectrum | ||
1136 | + } | ||
1137 | + } | ||
1138 | + | ||
1139 | + target.write(reinterpret_cast<const char*>(s), sizeof(T) * B); //write the projected vector | ||
1140 | + if(PROGRESS) progress = (double)(xy+1) / XY * 100; | ||
1141 | + } | ||
1142 | + | ||
1143 | + free(coeff); //free temporary storage arrays | ||
1144 | + free(s); | ||
1145 | + target.close(); //close the output file | ||
1146 | + | ||
1147 | + return true; | ||
1148 | + } | ||
1149 | + | ||
1128 | 1150 | ||
1129 | /// Crop a region of the image and save it to a new file. | 1151 | /// Crop a region of the image and save it to a new file. |
1130 | 1152 | ||
@@ -1138,7 +1160,8 @@ public: | @@ -1138,7 +1160,8 @@ public: | ||
1138 | unsigned long long x1, | 1160 | unsigned long long x1, |
1139 | unsigned long long y1, | 1161 | unsigned long long y1, |
1140 | unsigned long long b0, | 1162 | unsigned long long b0, |
1141 | - unsigned long long b1){ | 1163 | + unsigned long long b1, |
1164 | + bool PROGRESS = false){ | ||
1142 | 1165 | ||
1143 | //calculate the new number of samples, lines, and bands | 1166 | //calculate the new number of samples, lines, and bands |
1144 | unsigned long long samples = x1 - x0; | 1167 | unsigned long long samples = x1 - x0; |
@@ -1180,14 +1203,13 @@ public: | @@ -1180,14 +1203,13 @@ public: | ||
1180 | 1203 | ||
1181 | file.seekg(jump_sample, std::ios::cur); | 1204 | file.seekg(jump_sample, std::ios::cur); |
1182 | 1205 | ||
1183 | - thread_data = (double)(y * samples + x) / (lines * samples) * 100; | 1206 | + if(PROGRESS) progress = (double)((y+1) * samples + x + 1) / (lines * samples) * 100; |
1184 | } | 1207 | } |
1185 | 1208 | ||
1186 | file.seekg(jump_line, std::ios::cur); | 1209 | file.seekg(jump_line, std::ios::cur); |
1187 | } | 1210 | } |
1188 | free(temp); | 1211 | free(temp); |
1189 | 1212 | ||
1190 | - thread_data = 100; | ||
1191 | return true; | 1213 | return true; |
1192 | } | 1214 | } |
1193 | 1215 |
stim/envi/bsq.h
@@ -42,13 +42,14 @@ protected: | @@ -42,13 +42,14 @@ protected: | ||
42 | return R[2]; | 42 | return R[2]; |
43 | } | 43 | } |
44 | 44 | ||
45 | - using binary<T>::thread_data; | 45 | + using binary<T>::nnz; |
46 | + using binary<T>::progress; | ||
46 | 47 | ||
47 | public: | 48 | public: |
48 | 49 | ||
49 | using binary<T>::open; | 50 | using binary<T>::open; |
50 | using binary<T>::file; | 51 | using binary<T>::file; |
51 | - using binary<T>::read_line_01; | 52 | + using binary<T>::read_line_2; |
52 | using binary<T>::read_plane_2; | 53 | using binary<T>::read_plane_2; |
53 | //using binary<T>::getSlice; | 54 | //using binary<T>::getSlice; |
54 | 55 | ||
@@ -76,15 +77,15 @@ public: | @@ -76,15 +77,15 @@ public: | ||
76 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. | 77 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. |
77 | /// @param page <= B is the integer number of the band to be copied. | 78 | /// @param page <= B is the integer number of the band to be copied. |
78 | bool band_index( T * p, unsigned int page){ | 79 | bool band_index( T * p, unsigned int page){ |
79 | - return read_plane_2(p, page); | 80 | + return read_plane_2(p, page); //call the binary read_plane function (don't let it update the progress) |
80 | } | 81 | } |
81 | 82 | ||
82 | /// Retrieve a single band (by numerical label) and stores it in pre-allocated memory. | 83 | /// Retrieve a single band (by numerical label) and stores it in pre-allocated memory. |
83 | 84 | ||
84 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. | 85 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. |
85 | /// @param wavelength is a floating point value (usually a wavelength in spectral data) used as a label for the band to be copied. | 86 | /// @param wavelength is a floating point value (usually a wavelength in spectral data) used as a label for the band to be copied. |
86 | - bool band( T * p, double wavelength){ | ||
87 | - | 87 | + bool band( T * p, double wavelength, bool PROGRESS = false){ |
88 | + if(PROGRESS) progress = 0; | ||
88 | //if there are no wavelengths in the BSQ file | 89 | //if there are no wavelengths in the BSQ file |
89 | if(w.size() == 0) | 90 | if(w.size() == 0) |
90 | return band_index(p, (unsigned int)wavelength); | 91 | return band_index(p, (unsigned int)wavelength); |
@@ -132,7 +133,7 @@ public: | @@ -132,7 +133,7 @@ public: | ||
132 | else{ | 133 | else{ |
133 | band_index(p, page); //return the band | 134 | band_index(p, page); //return the band |
134 | } | 135 | } |
135 | - | 136 | + if(PROGRESS) progress = 100; |
136 | return true; | 137 | return true; |
137 | } | 138 | } |
138 | 139 | ||
@@ -141,8 +142,8 @@ public: | @@ -141,8 +142,8 @@ public: | ||
141 | /// @param p is a pointer to pre-allocated memory at least B * sizeof(T) in size. | 142 | /// @param p is a pointer to pre-allocated memory at least B * sizeof(T) in size. |
142 | /// @param x is the x-coordinate (dimension 1) of the spectrum. | 143 | /// @param x is the x-coordinate (dimension 1) of the spectrum. |
143 | /// @param y is the y-coordinate (dimension 2) of the spectrum. | 144 | /// @param y is the y-coordinate (dimension 2) of the spectrum. |
144 | - bool spectrum(T * p, unsigned x, unsigned y){ | ||
145 | - return read_line_01(p, x, y); | 145 | + bool spectrum(T * p, unsigned x, unsigned y, bool PROGRESS = false){ |
146 | + return read_line_2(p, x, y, PROGRESS); | ||
146 | } | 147 | } |
147 | 148 | ||
148 | /// Retrieve a single pixel and stores it in pre-allocated memory. | 149 | /// Retrieve a single pixel and stores it in pre-allocated memory. |
@@ -171,8 +172,9 @@ public: | @@ -171,8 +172,9 @@ public: | ||
171 | 172 | ||
172 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. | 173 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. |
173 | /// @param wls is the list of baseline points based on band labels. | 174 | /// @param wls is the list of baseline points based on band labels. |
174 | - bool baseline(std::string outname, std::vector<double> wls ) | 175 | + bool baseline(std::string outname, std::vector<double> wls, bool PROGRESS = false ) |
175 | { | 176 | { |
177 | + if(PROGRESS) progress = 0; | ||
176 | unsigned N = wls.size(); //get the number of baseline points | 178 | unsigned N = wls.size(); //get the number of baseline points |
177 | 179 | ||
178 | std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file | 180 | std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file |
@@ -261,7 +263,7 @@ public: | @@ -261,7 +263,7 @@ public: | ||
261 | 263 | ||
262 | target.write(reinterpret_cast<const char*>(c), S); //write the corrected data into destination | 264 | target.write(reinterpret_cast<const char*>(c), S); //write the corrected data into destination |
263 | 265 | ||
264 | - thread_data = (double)cii / B * 100; | 266 | + if(PROGRESS)progress = (double)(cii+1) / B * 100; |
265 | 267 | ||
266 | } | 268 | } |
267 | 269 | ||
@@ -272,7 +274,6 @@ public: | @@ -272,7 +274,6 @@ public: | ||
272 | free(c); | 274 | free(c); |
273 | target.close(); | 275 | target.close(); |
274 | 276 | ||
275 | - thread_data = 100; | ||
276 | return true; | 277 | return true; |
277 | } | 278 | } |
278 | 279 | ||
@@ -281,7 +282,7 @@ public: | @@ -281,7 +282,7 @@ public: | ||
281 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. | 282 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. |
282 | /// @param w is the label specifying the band that the hyperspectral image will be normalized to. | 283 | /// @param w is the label specifying the band that the hyperspectral image will be normalized to. |
283 | /// @param t is a threshold specified such that a spectrum with a value at w less than t is set to zero. Setting this threshold allows the user to limit division by extremely small numbers. | 284 | /// @param t is a threshold specified such that a spectrum with a value at w less than t is set to zero. Setting this threshold allows the user to limit division by extremely small numbers. |
284 | - bool normalize(std::string outname, double w, double t = 0.0) | 285 | + bool normalize(std::string outname, double w, double t = 0.0, bool PROGRESS = false) |
285 | { | 286 | { |
286 | unsigned int B = Z(); //calculate the number of bands | 287 | unsigned int B = Z(); //calculate the number of bands |
287 | unsigned int XY = X() * Y(); //calculate the number of pixels in a band | 288 | unsigned int XY = X() * Y(); //calculate the number of pixels in a band |
@@ -310,7 +311,7 @@ public: | @@ -310,7 +311,7 @@ public: | ||
310 | } | 311 | } |
311 | target.write(reinterpret_cast<const char*>(c), S); //write normalized data into destination | 312 | target.write(reinterpret_cast<const char*>(c), S); //write normalized data into destination |
312 | 313 | ||
313 | - thread_data = (double)j / B * 100; | 314 | + if(PROGRESS) progress = (double)(j+1) / B * 100; |
314 | } | 315 | } |
315 | 316 | ||
316 | 317 | ||
@@ -320,14 +321,13 @@ public: | @@ -320,14 +321,13 @@ public: | ||
320 | free(b); | 321 | free(b); |
321 | free(c); | 322 | free(c); |
322 | target.close(); | 323 | target.close(); |
323 | - thread_data = 100; //make sure that the progress bar is full | ||
324 | return true; | 324 | return true; |
325 | } | 325 | } |
326 | 326 | ||
327 | /// Convert the current BSQ file to a BIP file with the specified file name. | 327 | /// Convert the current BSQ file to a BIP file with the specified file name. |
328 | 328 | ||
329 | /// @param outname is the name of the output BIP file to be saved to disk. | 329 | /// @param outname is the name of the output BIP file to be saved to disk. |
330 | - bool bip(std::string outname) | 330 | + /*bool bip(std::string outname) |
331 | { | 331 | { |
332 | std::string temp = outname + "_temp"; | 332 | std::string temp = outname + "_temp"; |
333 | std::string headtemp = temp + ".hdr"; | 333 | std::string headtemp = temp + ".hdr"; |
@@ -340,17 +340,18 @@ public: | @@ -340,17 +340,18 @@ public: | ||
340 | exit(1); | 340 | exit(1); |
341 | } | 341 | } |
342 | //then convert bil file to bip file | 342 | //then convert bil file to bip file |
343 | + progress = 0; | ||
343 | n.bip(outname); | 344 | n.bip(outname); |
344 | n.close(); | 345 | n.close(); |
345 | remove(temp.c_str()); | 346 | remove(temp.c_str()); |
346 | remove(headtemp.c_str()); | 347 | remove(headtemp.c_str()); |
347 | return true; | 348 | return true; |
348 | - } | 349 | + }*/ |
349 | 350 | ||
350 | /// Convert the current BSQ file to a BIL file with the specified file name. | 351 | /// Convert the current BSQ file to a BIL file with the specified file name. |
351 | 352 | ||
352 | /// @param outname is the name of the output BIL file to be saved to disk. | 353 | /// @param outname is the name of the output BIL file to be saved to disk. |
353 | - bool bil(std::string outname) | 354 | + bool bil(std::string outname, bool PROGRESS = false) |
354 | { | 355 | { |
355 | //simplify image resolution | 356 | //simplify image resolution |
356 | unsigned int L = X() * Z() * sizeof(T); //calculate the number of bytes of a ZX slice | 357 | unsigned int L = X() * Z() * sizeof(T); //calculate the number of bytes of a ZX slice |
@@ -370,17 +371,11 @@ public: | @@ -370,17 +371,11 @@ public: | ||
370 | { | 371 | { |
371 | file.read((char *)(xz_slice + z * X()), sizeof(T) * X()); //read a line | 372 | file.read((char *)(xz_slice + z * X()), sizeof(T) * X()); //read a line |
372 | file.seekg(jump, std::ios::cur); //seek to the next band | 373 | file.seekg(jump, std::ios::cur); //seek to the next band |
373 | - | ||
374 | - | ||
375 | - thread_data = (double)(y * Z() + z) / (Z() * Y()) * 100; //update the progress counter | 374 | + if(PROGRESS) progress = (double)(y * Z() + z + 1) / (Z() * Y()) * 100; //update the progress counter |
376 | } | 375 | } |
377 | target.write(reinterpret_cast<const char*>(xz_slice), xz_bytes); //write the generated XZ slice to the target file | 376 | target.write(reinterpret_cast<const char*>(xz_slice), xz_bytes); //write the generated XZ slice to the target file |
378 | } | 377 | } |
379 | 378 | ||
380 | - | ||
381 | - | ||
382 | - thread_data = 100; | ||
383 | - | ||
384 | free(xz_slice); | 379 | free(xz_slice); |
385 | target.close(); | 380 | target.close(); |
386 | 381 | ||
@@ -869,13 +864,13 @@ public: | @@ -869,13 +864,13 @@ public: | ||
869 | continue; | 864 | continue; |
870 | } | 865 | } |
871 | 866 | ||
872 | - thread_data = (double)(i * XY + j) / (XY * Z()) * 100; | 867 | + progress = (double)(i * XY + j) / (XY * Z()) * 100; |
873 | } | 868 | } |
874 | } | 869 | } |
875 | target.close(); | 870 | target.close(); |
876 | free(temp); | 871 | free(temp); |
877 | 872 | ||
878 | - thread_data = 100; | 873 | + progress = 100; |
879 | 874 | ||
880 | return true; | 875 | return true; |
881 | } | 876 | } |
@@ -923,7 +918,7 @@ public: | @@ -923,7 +918,7 @@ public: | ||
923 | i++; | 918 | i++; |
924 | } | 919 | } |
925 | //std::cout<<xi<<"/"<<XY<<", "<<b<<"/"<<B<<std::endl; | 920 | //std::cout<<xi<<"/"<<XY<<", "<<b<<"/"<<B<<std::endl; |
926 | - thread_data = (double)(b * XY + xi) / (B * XY) * 100; | 921 | + progress = (double)(b * XY + xi) / (B * XY) * 100; |
927 | } | 922 | } |
928 | //std::cout<<b*XY<<"/"<<B*XY<<" "<<B<<"-"<<XY<<std::endl; | 923 | //std::cout<<b*XY<<"/"<<B*XY<<" "<<B<<"-"<<XY<<std::endl; |
929 | //write the band image to disk | 924 | //write the band image to disk |
@@ -931,7 +926,7 @@ public: | @@ -931,7 +926,7 @@ public: | ||
931 | } | 926 | } |
932 | 927 | ||
933 | //std::cout<<"unsifted"<<std::endl; | 928 | //std::cout<<"unsifted"<<std::endl; |
934 | - thread_data = 100; | 929 | + progress = 100; |
935 | 930 | ||
936 | return true; | 931 | return true; |
937 | } | 932 | } |
@@ -963,7 +958,7 @@ public: | @@ -963,7 +958,7 @@ public: | ||
963 | 958 | ||
964 | /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum | 959 | /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum |
965 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location | 960 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location |
966 | - bool avg_band(double* p, unsigned char* mask = NULL){ | 961 | + bool avg_band(double* p, unsigned char* mask = NULL, bool PROGRESS = false){ |
967 | unsigned long long XY = X() * Y(); | 962 | unsigned long long XY = X() * Y(); |
968 | unsigned long long count = 0; //count will store the number of masked pixels | 963 | unsigned long long count = 0; //count will store the number of masked pixels |
969 | T* temp = (T*)malloc(sizeof(T) * XY); | 964 | T* temp = (T*)malloc(sizeof(T) * XY); |
@@ -983,6 +978,7 @@ public: | @@ -983,6 +978,7 @@ public: | ||
983 | p[i] += (double)temp[j] / (double)count; | 978 | p[i] += (double)temp[j] / (double)count; |
984 | } | 979 | } |
985 | } | 980 | } |
981 | + if(PROGRESS) progress = (double)(i+1) / Z() * 100; | ||
986 | } | 982 | } |
987 | free(temp); | 983 | free(temp); |
988 | return true; | 984 | return true; |
@@ -993,8 +989,8 @@ public: | @@ -993,8 +989,8 @@ public: | ||
993 | /// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix | 989 | /// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix |
994 | /// @param avg is a pointer to memory of size B that stores the average spectrum | 990 | /// @param avg is a pointer to memory of size B that stores the average spectrum |
995 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location | 991 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location |
996 | - bool co_matrix(double* co, double* avg, unsigned char *mask){ | ||
997 | - thread_data = 0; //initialize thread data for timers and progress bars | 992 | + /*bool co_matrix(double* co, double* avg, unsigned char *mask){ |
993 | + progress = 0; //initialize thread data for timers and progress bars | ||
998 | //memory allocation | 994 | //memory allocation |
999 | unsigned long long xy = X() * Y(); | 995 | unsigned long long xy = X() * Y(); |
1000 | unsigned long long B = Z(); | 996 | unsigned long long B = Z(); |
@@ -1024,15 +1020,15 @@ public: | @@ -1024,15 +1020,15 @@ public: | ||
1024 | co[i*B + j] = numerator; | 1020 | co[i*B + j] = numerator; |
1025 | co[j*B + i] = numerator; //because correlated matrix is a symmetric matrix | 1021 | co[j*B + i] = numerator; //because correlated matrix is a symmetric matrix |
1026 | } | 1022 | } |
1027 | - thread_data = (double)i / B * 100; | 1023 | + progress = (double)i / B * 100; |
1028 | } | 1024 | } |
1029 | free(bandi); | 1025 | free(bandi); |
1030 | free(bandj); | 1026 | free(bandj); |
1031 | 1027 | ||
1032 | - thread_data = 100; //processing complete | 1028 | + progress = 100; //processing complete |
1033 | 1029 | ||
1034 | return true; | 1030 | return true; |
1035 | - } | 1031 | + }*/ |
1036 | 1032 | ||
1037 | 1033 | ||
1038 | /// Crop a region of the image and save it to a new file. | 1034 | /// Crop a region of the image and save it to a new file. |
@@ -1047,7 +1043,8 @@ public: | @@ -1047,7 +1043,8 @@ public: | ||
1047 | unsigned long long x1, | 1043 | unsigned long long x1, |
1048 | unsigned long long y1, | 1044 | unsigned long long y1, |
1049 | unsigned long long b0, | 1045 | unsigned long long b0, |
1050 | - unsigned long long b1){ | 1046 | + unsigned long long b1, |
1047 | + bool PROGRESS = false){ | ||
1051 | 1048 | ||
1052 | //calculate the new number of samples, lines, and bands | 1049 | //calculate the new number of samples, lines, and bands |
1053 | unsigned long long samples = x1 - x0; | 1050 | unsigned long long samples = x1 - x0; |
@@ -1080,15 +1077,13 @@ public: | @@ -1080,15 +1077,13 @@ public: | ||
1080 | file.read((char *)(temp + y * samples), sizeof(T) * samples); | 1077 | file.read((char *)(temp + y * samples), sizeof(T) * samples); |
1081 | file.seekg(jumpl, std::ios::cur); //go to the next band | 1078 | file.seekg(jumpl, std::ios::cur); //go to the next band |
1082 | 1079 | ||
1083 | - thread_data = (double)(z * lines + y) / (Z() * lines) * 100; | 1080 | + if(PROGRESS) progress = (double)((z+1) * lines + y + 1) / ((b1 - b0) * lines) * 100; |
1084 | } | 1081 | } |
1085 | out.write(reinterpret_cast<const char*>(temp), L); //write slice data into target file | 1082 | out.write(reinterpret_cast<const char*>(temp), L); //write slice data into target file |
1086 | file.seekg(jumpb, std::ios::cur); | 1083 | file.seekg(jumpb, std::ios::cur); |
1087 | } | 1084 | } |
1088 | free(temp); | 1085 | free(temp); |
1089 | 1086 | ||
1090 | - thread_data = 100; | ||
1091 | - | ||
1092 | return true; | 1087 | return true; |
1093 | } | 1088 | } |
1094 | 1089 |
stim/envi/envi.h
@@ -37,27 +37,27 @@ public: | @@ -37,27 +37,27 @@ public: | ||
37 | 37 | ||
38 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 38 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
39 | if(header.data_type ==envi_header::float32) | 39 | if(header.data_type ==envi_header::float32) |
40 | - ((bsq<float>*)file)->reset_thread_data(); | 40 | + ((bsq<float>*)file)->reset_progress(); |
41 | else if(header.data_type == envi_header::float64) | 41 | else if(header.data_type == envi_header::float64) |
42 | - ((bsq<double>*)file)->reset_thread_data(); | 42 | + ((bsq<double>*)file)->reset_progress(); |
43 | else | 43 | else |
44 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 44 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
45 | } | 45 | } |
46 | 46 | ||
47 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file | 47 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
48 | if(header.data_type ==envi_header::float32) | 48 | if(header.data_type ==envi_header::float32) |
49 | - ((bil<float>*)file)->reset_thread_data(); | 49 | + ((bil<float>*)file)->reset_progress(); |
50 | else if(header.data_type == envi_header::float64) | 50 | else if(header.data_type == envi_header::float64) |
51 | - ((bil<double>*)file)->reset_thread_data(); | 51 | + ((bil<double>*)file)->reset_progress(); |
52 | else | 52 | else |
53 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 53 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
54 | } | 54 | } |
55 | 55 | ||
56 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file | 56 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
57 | if(header.data_type ==envi_header::float32) | 57 | if(header.data_type ==envi_header::float32) |
58 | - ((bip<float>*)file)->reset_thread_data(); | 58 | + ((bip<float>*)file)->reset_progress(); |
59 | else if(header.data_type == envi_header::float64) | 59 | else if(header.data_type == envi_header::float64) |
60 | - ((bip<double>*)file)->reset_thread_data(); | 60 | + ((bip<double>*)file)->reset_progress(); |
61 | else | 61 | else |
62 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 62 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
63 | } | 63 | } |
@@ -73,27 +73,27 @@ public: | @@ -73,27 +73,27 @@ public: | ||
73 | 73 | ||
74 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 74 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
75 | if(header.data_type ==envi_header::float32) | 75 | if(header.data_type ==envi_header::float32) |
76 | - return ((bsq<float>*)file)->get_thread_data(); | 76 | + return ((bsq<float>*)file)->get_progress(); |
77 | else if(header.data_type == envi_header::float64) | 77 | else if(header.data_type == envi_header::float64) |
78 | - return ((bsq<double>*)file)->get_thread_data(); | 78 | + return ((bsq<double>*)file)->get_progress(); |
79 | else | 79 | else |
80 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 80 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
81 | } | 81 | } |
82 | 82 | ||
83 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file | 83 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
84 | if(header.data_type ==envi_header::float32) | 84 | if(header.data_type ==envi_header::float32) |
85 | - return ((bil<float>*)file)->get_thread_data(); | 85 | + return ((bil<float>*)file)->get_progress(); |
86 | else if(header.data_type == envi_header::float64) | 86 | else if(header.data_type == envi_header::float64) |
87 | - return ((bil<double>*)file)->get_thread_data(); | 87 | + return ((bil<double>*)file)->get_progress(); |
88 | else | 88 | else |
89 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 89 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
90 | } | 90 | } |
91 | 91 | ||
92 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file | 92 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
93 | if(header.data_type ==envi_header::float32) | 93 | if(header.data_type ==envi_header::float32) |
94 | - return ((bip<float>*)file)->get_thread_data(); | 94 | + return ((bip<float>*)file)->get_progress(); |
95 | else if(header.data_type == envi_header::float64) | 95 | else if(header.data_type == envi_header::float64) |
96 | - return ((bip<double>*)file)->get_thread_data(); | 96 | + return ((bip<double>*)file)->get_progress(); |
97 | else | 97 | else |
98 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 98 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
99 | } | 99 | } |
@@ -213,31 +213,31 @@ public: | @@ -213,31 +213,31 @@ public: | ||
213 | /// @param outfile is the name of the normalized file to be output | 213 | /// @param outfile is the name of the normalized file to be output |
214 | /// @param band is the band label to be output | 214 | /// @param band is the band label to be output |
215 | /// @param threshold is a threshold value specified such that normalization will only be done to values in the band > threshold (preventing division by small numbers) | 215 | /// @param threshold is a threshold value specified such that normalization will only be done to values in the band > threshold (preventing division by small numbers) |
216 | - bool normalize(std::string outfile, double band, double threshold = 0.0){ | 216 | + bool normalize(std::string outfile, double band, double threshold = 0.0, bool PROGRESS = false){ |
217 | 217 | ||
218 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 218 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
219 | if(header.data_type ==envi_header::float32) | 219 | if(header.data_type ==envi_header::float32) |
220 | - return ((bsq<float>*)file)->normalize(outfile, band, threshold); | 220 | + return ((bsq<float>*)file)->normalize(outfile, band, threshold, PROGRESS); |
221 | else if(header.data_type == envi_header::float64) | 221 | else if(header.data_type == envi_header::float64) |
222 | - return ((bsq<double>*)file)->normalize(outfile,band, threshold); | 222 | + return ((bsq<double>*)file)->normalize(outfile,band, threshold, PROGRESS); |
223 | else | 223 | else |
224 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 224 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
225 | } | 225 | } |
226 | 226 | ||
227 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file | 227 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
228 | if(header.data_type ==envi_header::float32) | 228 | if(header.data_type ==envi_header::float32) |
229 | - return ((bil<float>*)file)->normalize(outfile, band); | 229 | + return ((bil<float>*)file)->normalize(outfile, band, threshold, PROGRESS); |
230 | else if(header.data_type == envi_header::float64) | 230 | else if(header.data_type == envi_header::float64) |
231 | - return ((bil<double>*)file)->normalize(outfile,band); | 231 | + return ((bil<double>*)file)->normalize(outfile,band, threshold, PROGRESS); |
232 | else | 232 | else |
233 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 233 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
234 | } | 234 | } |
235 | 235 | ||
236 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file | 236 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
237 | if(header.data_type ==envi_header::float32) | 237 | if(header.data_type ==envi_header::float32) |
238 | - return ((bip<float>*)file)->normalize(outfile, band); | 238 | + return ((bip<float>*)file)->normalize(outfile, band, threshold, PROGRESS); |
239 | else if(header.data_type == envi_header::float64) | 239 | else if(header.data_type == envi_header::float64) |
240 | - return ((bip<double>*)file)->normalize(outfile,band); | 240 | + return ((bip<double>*)file)->normalize(outfile,band, threshold, PROGRESS); |
241 | else | 241 | else |
242 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 242 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
243 | } | 243 | } |
@@ -253,13 +253,13 @@ public: | @@ -253,13 +253,13 @@ public: | ||
253 | 253 | ||
254 | /// @param outfile is the file name for the baseline corrected output | 254 | /// @param outfile is the file name for the baseline corrected output |
255 | /// @param w is a list of band labels to serve as baseline points (zero values) | 255 | /// @param w is a list of band labels to serve as baseline points (zero values) |
256 | - bool baseline(std::string outfile, std::vector<double> w){ | 256 | + bool baseline(std::string outfile, std::vector<double> w, bool PROGRESS){ |
257 | 257 | ||
258 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 258 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
259 | if(header.data_type ==envi_header::float32) | 259 | if(header.data_type ==envi_header::float32) |
260 | - return ((bsq<float>*)file)->baseline(outfile, w); | 260 | + return ((bsq<float>*)file)->baseline(outfile, w, PROGRESS); |
261 | else if(header.data_type == envi_header::float64) | 261 | else if(header.data_type == envi_header::float64) |
262 | - return ((bsq<double>*)file)->baseline(outfile,w); | 262 | + return ((bsq<double>*)file)->baseline(outfile,w, PROGRESS); |
263 | else{ | 263 | else{ |
264 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 264 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
265 | exit(1); | 265 | exit(1); |
@@ -268,9 +268,9 @@ public: | @@ -268,9 +268,9 @@ public: | ||
268 | 268 | ||
269 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file | 269 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
270 | if(header.data_type ==envi_header::float32) | 270 | if(header.data_type ==envi_header::float32) |
271 | - return ((bil<float>*)file)->baseline(outfile, w); | 271 | + return ((bil<float>*)file)->baseline(outfile, w, PROGRESS); |
272 | else if(header.data_type == envi_header::float64) | 272 | else if(header.data_type == envi_header::float64) |
273 | - return ((bil<double>*)file)->baseline(outfile, w); | 273 | + return ((bil<double>*)file)->baseline(outfile, w, PROGRESS); |
274 | else{ | 274 | else{ |
275 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 275 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
276 | exit(1); | 276 | exit(1); |
@@ -279,9 +279,9 @@ public: | @@ -279,9 +279,9 @@ public: | ||
279 | 279 | ||
280 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file | 280 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
281 | if(header.data_type ==envi_header::float32) | 281 | if(header.data_type ==envi_header::float32) |
282 | - return ((bip<float>*)file)->baseline(outfile, w); | 282 | + return ((bip<float>*)file)->baseline(outfile, w, PROGRESS); |
283 | else if(header.data_type == envi_header::float64) | 283 | else if(header.data_type == envi_header::float64) |
284 | - return ((bip<double>*)file)->baseline(outfile, w); | 284 | + return ((bip<double>*)file)->baseline(outfile, w, PROGRESS); |
285 | else{ | 285 | else{ |
286 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 286 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
287 | exit(1); | 287 | exit(1); |
@@ -294,11 +294,65 @@ public: | @@ -294,11 +294,65 @@ public: | ||
294 | } | 294 | } |
295 | } | 295 | } |
296 | 296 | ||
297 | + void project(std::string outfile, double* center, double* basis, unsigned long long M, bool PROGRESS = false){ | ||
298 | + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | ||
299 | + std::cout<<"ERROR: BSQ projection not supported"<<std::endl; | ||
300 | + exit(1); | ||
301 | + } | ||
302 | + | ||
303 | + else if(header.interleave == envi_header::BIL){ //if the infile is bil file | ||
304 | + std::cout<<"ERROR: BIL projection not supported"<<std::endl; | ||
305 | + exit(1); | ||
306 | + } | ||
307 | + | ||
308 | + else if(header.interleave == envi_header::BIP){ //if the infile is bip file | ||
309 | + if(header.data_type ==envi_header::float32) | ||
310 | + ((bip<float>*)file)->project(outfile, center, basis, M, PROGRESS); | ||
311 | + else if(header.data_type == envi_header::float64) | ||
312 | + ((bip<double>*)file)->project(outfile, center, basis, M, PROGRESS); | ||
313 | + else{ | ||
314 | + std::cout<<"ERROR: unidentified data type"<<std::endl; | ||
315 | + exit(1); | ||
316 | + } | ||
317 | + } | ||
318 | + | ||
319 | + stim::envi_header out_hdr = header; | ||
320 | + out_hdr.bands = M; //set the number of bands in the output header | ||
321 | + out_hdr.save(outfile + ".hdr"); //save the output header | ||
322 | + } | ||
323 | + | ||
324 | + void inverse(std::string outfile, double* center, double* basis, unsigned long long B, unsigned long long C = 0, bool PROGRESS = false){ | ||
325 | + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | ||
326 | + std::cout<<"ERROR: BSQ projection not supported"<<std::endl; | ||
327 | + exit(1); | ||
328 | + } | ||
329 | + | ||
330 | + else if(header.interleave == envi_header::BIL){ //if the infile is bil file | ||
331 | + std::cout<<"ERROR: BIL projection not supported"<<std::endl; | ||
332 | + exit(1); | ||
333 | + } | ||
334 | + | ||
335 | + else if(header.interleave == envi_header::BIP){ //if the infile is bip file | ||
336 | + if(header.data_type ==envi_header::float32) | ||
337 | + ((bip<float>*)file)->inverse(outfile, center, basis, B, C, PROGRESS); | ||
338 | + else if(header.data_type == envi_header::float64) | ||
339 | + ((bip<double>*)file)->inverse(outfile, center, basis, B, C, PROGRESS); | ||
340 | + else{ | ||
341 | + std::cout<<"ERROR: unidentified data type"<<std::endl; | ||
342 | + exit(1); | ||
343 | + } | ||
344 | + } | ||
345 | + | ||
346 | + stim::envi_header out_hdr = header; | ||
347 | + out_hdr.bands = B; //set the number of bands in the output header | ||
348 | + out_hdr.save(outfile + ".hdr"); //save the output header | ||
349 | + } | ||
350 | + | ||
297 | /// Converts ENVI files between interleave types (BSQ, BIL, and BIP) | 351 | /// Converts ENVI files between interleave types (BSQ, BIL, and BIP) |
298 | 352 | ||
299 | /// @param outfile is the file name for the converted output | 353 | /// @param outfile is the file name for the converted output |
300 | /// @param interleave is the interleave format for the destination file | 354 | /// @param interleave is the interleave format for the destination file |
301 | - bool convert(std::string outfile, stim::envi_header::interleaveType interleave){ | 355 | + bool convert(std::string outfile, stim::envi_header::interleaveType interleave, bool PROGRESS = false){ |
302 | 356 | ||
303 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 357 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
304 | 358 | ||
@@ -308,9 +362,12 @@ public: | @@ -308,9 +362,12 @@ public: | ||
308 | exit(1); | 362 | exit(1); |
309 | } | 363 | } |
310 | else if(interleave == envi_header::BIL) //if the target file is bil file | 364 | else if(interleave == envi_header::BIL) //if the target file is bil file |
311 | - return ((bsq<float>*)file)->bil(outfile); | ||
312 | - else if(interleave == envi_header::BIP) //if the target file is bip file | ||
313 | - return ((bsq<float>*)file)->bip(outfile); | 365 | + return ((bsq<float>*)file)->bil(outfile, PROGRESS); |
366 | + else if(interleave == envi_header::BIP){ //if the target file is bip file | ||
367 | + std::cout<<"ERROR: conversion from BSQ to BIP isn't practical; use BSQ->BIL->BIP instead"<<std::endl; | ||
368 | + //return ((bsq<float>*)file)->bip(outfile, PROGRESS); | ||
369 | + exit(1); | ||
370 | + } | ||
314 | } | 371 | } |
315 | 372 | ||
316 | else if(header.data_type == envi_header::float64){ //if the data type is float | 373 | else if(header.data_type == envi_header::float64){ //if the data type is float |
@@ -319,9 +376,12 @@ public: | @@ -319,9 +376,12 @@ public: | ||
319 | exit(1); | 376 | exit(1); |
320 | } | 377 | } |
321 | else if(interleave == envi_header::BIL) | 378 | else if(interleave == envi_header::BIL) |
322 | - return ((bsq<double>*)file)->bil(outfile); | ||
323 | - else if(interleave == envi_header::BIP) | ||
324 | - return ((bsq<double>*)file)->bip(outfile); | 379 | + return ((bsq<double>*)file)->bil(outfile, PROGRESS); |
380 | + else if(interleave == envi_header::BIP){ //if the target file is bip file | ||
381 | + std::cout<<"ERROR: conversion from BSQ to BIP isn't practical; use BSQ->BIL->BIP instead"<<std::endl; | ||
382 | + //return ((bsq<float>*)file)->bip(outfile, PROGRESS); | ||
383 | + exit(1); | ||
384 | + } | ||
325 | } | 385 | } |
326 | 386 | ||
327 | else{ | 387 | else{ |
@@ -338,9 +398,9 @@ public: | @@ -338,9 +398,9 @@ public: | ||
338 | exit(1); | 398 | exit(1); |
339 | } | 399 | } |
340 | else if(interleave == envi_header::BSQ) //if the target file is bsq file | 400 | else if(interleave == envi_header::BSQ) //if the target file is bsq file |
341 | - return ((bil<float>*)file)->bsq(outfile); | 401 | + return ((bil<float>*)file)->bsq(outfile, PROGRESS); |
342 | else if(interleave == envi_header::BIP) //if the target file is bip file | 402 | else if(interleave == envi_header::BIP) //if the target file is bip file |
343 | - return ((bil<float>*)file)->bip(outfile); | 403 | + return ((bil<float>*)file)->bip(outfile, PROGRESS); |
344 | } | 404 | } |
345 | 405 | ||
346 | else if(header.data_type == envi_header::float64){ //if the data type is float | 406 | else if(header.data_type == envi_header::float64){ //if the data type is float |
@@ -349,9 +409,9 @@ public: | @@ -349,9 +409,9 @@ public: | ||
349 | exit(1); | 409 | exit(1); |
350 | } | 410 | } |
351 | else if(interleave == envi_header::BSQ) | 411 | else if(interleave == envi_header::BSQ) |
352 | - return ((bil<double>*)file)->bsq(outfile); | 412 | + return ((bil<double>*)file)->bsq(outfile, PROGRESS); |
353 | else if(interleave == envi_header::BIP) | 413 | else if(interleave == envi_header::BIP) |
354 | - return ((bil<double>*)file)->bip(outfile); | 414 | + return ((bil<double>*)file)->bip(outfile, PROGRESS); |
355 | } | 415 | } |
356 | 416 | ||
357 | else{ | 417 | else{ |
@@ -368,9 +428,12 @@ public: | @@ -368,9 +428,12 @@ public: | ||
368 | exit(1); | 428 | exit(1); |
369 | } | 429 | } |
370 | else if(interleave == envi_header::BIL) //if the target file is bil file | 430 | else if(interleave == envi_header::BIL) //if the target file is bil file |
371 | - return ((bip<float>*)file)->bil(outfile); | ||
372 | - else if(interleave == envi_header::BSQ) //if the target file is bsq file | ||
373 | - return ((bip<float>*)file)->bsq(outfile); | 431 | + return ((bip<float>*)file)->bil(outfile, PROGRESS); |
432 | + else if(interleave == envi_header::BSQ){ //if the target file is bip file | ||
433 | + std::cout<<"ERROR: conversion from BIP to BSQ isn't practical; use BIP->BIL->BSQ instead"<<std::endl; | ||
434 | + //return ((bsq<float>*)file)->bip(outfile, PROGRESS); | ||
435 | + exit(1); | ||
436 | + } | ||
374 | } | 437 | } |
375 | 438 | ||
376 | else if(header.data_type == envi_header::float64){ //if the data type is float | 439 | else if(header.data_type == envi_header::float64){ //if the data type is float |
@@ -379,9 +442,12 @@ public: | @@ -379,9 +442,12 @@ public: | ||
379 | exit(1); | 442 | exit(1); |
380 | } | 443 | } |
381 | else if(interleave == envi_header::BIL) //if the target file is bil file | 444 | else if(interleave == envi_header::BIL) //if the target file is bil file |
382 | - return ((bip<double>*)file)->bil(outfile); | ||
383 | - else if(interleave == envi_header::BSQ) //if the target file is bsq file | ||
384 | - return ((bip<double>*)file)->bsq(outfile); | 445 | + return ((bip<double>*)file)->bil(outfile, PROGRESS); |
446 | + else if(interleave == envi_header::BSQ){ //if the target file is bip file | ||
447 | + std::cout<<"ERROR: conversion from BIP to BSQ isn't practical; use BIP->BIL->BSQ instead"<<std::endl; | ||
448 | + //return ((bsq<float>*)file)->bip(outfile, PROGRESS); | ||
449 | + exit(1); | ||
450 | + } | ||
385 | } | 451 | } |
386 | 452 | ||
387 | else{ | 453 | else{ |
@@ -872,13 +938,13 @@ public: | @@ -872,13 +938,13 @@ public: | ||
872 | 938 | ||
873 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. | 939 | /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. |
874 | /// @param wavelength is a floating point value (usually a wavelength in spectral data) used as a label for the band to be copied. | 940 | /// @param wavelength is a floating point value (usually a wavelength in spectral data) used as a label for the band to be copied. |
875 | - bool band(void* ptr, double wavelength){ | 941 | + bool band(void* ptr, double wavelength, bool PROGRESS = false){ |
876 | 942 | ||
877 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 943 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
878 | if(header.data_type ==envi_header::float32) | 944 | if(header.data_type ==envi_header::float32) |
879 | - return ((bsq<float>*)file)->band((float*)ptr, wavelength); | 945 | + return ((bsq<float>*)file)->band((float*)ptr, wavelength, PROGRESS); |
880 | else if (header.data_type == envi_header::float64) | 946 | else if (header.data_type == envi_header::float64) |
881 | - return ((bsq<double>*)file)->band((double*)ptr, wavelength); | 947 | + return ((bsq<double>*)file)->band((double*)ptr, wavelength, PROGRESS); |
882 | else{ | 948 | else{ |
883 | std::cout << "ERROR: unidentified data type" << std::endl; | 949 | std::cout << "ERROR: unidentified data type" << std::endl; |
884 | exit(1); | 950 | exit(1); |
@@ -886,9 +952,9 @@ public: | @@ -886,9 +952,9 @@ public: | ||
886 | } | 952 | } |
887 | else if (header.interleave == envi_header::BIL){ | 953 | else if (header.interleave == envi_header::BIL){ |
888 | if (header.data_type == envi_header::float32) | 954 | if (header.data_type == envi_header::float32) |
889 | - return ((bil<float>*)file)->band((float*)ptr, wavelength); | 955 | + return ((bil<float>*)file)->band((float*)ptr, wavelength, PROGRESS); |
890 | else if (header.data_type == envi_header::float64) | 956 | else if (header.data_type == envi_header::float64) |
891 | - return ((bil<double>*)file)->band((double*)ptr, wavelength); | 957 | + return ((bil<double>*)file)->band((double*)ptr, wavelength, PROGRESS); |
892 | else{ | 958 | else{ |
893 | std::cout << "ERROR: unidentified data type" << std::endl; | 959 | std::cout << "ERROR: unidentified data type" << std::endl; |
894 | exit(1); | 960 | exit(1); |
@@ -896,9 +962,9 @@ public: | @@ -896,9 +962,9 @@ public: | ||
896 | } | 962 | } |
897 | else if (header.interleave == envi_header::BIP){ | 963 | else if (header.interleave == envi_header::BIP){ |
898 | if (header.data_type == envi_header::float32) | 964 | if (header.data_type == envi_header::float32) |
899 | - return ((bip<float>*)file)->band((float*)ptr, wavelength); | 965 | + return ((bip<float>*)file)->band((float*)ptr, wavelength, PROGRESS); |
900 | else if (header.data_type == envi_header::float64) | 966 | else if (header.data_type == envi_header::float64) |
901 | - return ((bip<double>*)file)->band((double*)ptr, wavelength); | 967 | + return ((bip<double>*)file)->band((double*)ptr, wavelength, PROGRESS); |
902 | else{ | 968 | else{ |
903 | std::cout << "ERROR: unidentified data type" << std::endl; | 969 | std::cout << "ERROR: unidentified data type" << std::endl; |
904 | exit(1); | 970 | exit(1); |
@@ -912,13 +978,13 @@ public: | @@ -912,13 +978,13 @@ public: | ||
912 | /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T) | 978 | /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T) |
913 | /// @param x is the x-coordinate of the spectrum | 979 | /// @param x is the x-coordinate of the spectrum |
914 | /// @param y is the y-coordinate of the spectrum | 980 | /// @param y is the y-coordinate of the spectrum |
915 | - bool spectrum(void* ptr, unsigned int x, unsigned int y){ | 981 | + bool spectrum(void* ptr, unsigned int x, unsigned int y, bool PROGRESS = false){ |
916 | 982 | ||
917 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 983 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
918 | if(header.data_type ==envi_header::float32) | 984 | if(header.data_type ==envi_header::float32) |
919 | - return ((bsq<float>*)file)->spectrum((float*)ptr, x, y); | 985 | + return ((bsq<float>*)file)->spectrum((float*)ptr, x, y, PROGRESS); |
920 | else if (header.data_type == envi_header::float64) | 986 | else if (header.data_type == envi_header::float64) |
921 | - return ((bsq<double>*)file)->spectrum((double*)ptr, x, y); | 987 | + return ((bsq<double>*)file)->spectrum((double*)ptr, x, y, PROGRESS); |
922 | else{ | 988 | else{ |
923 | std::cout << "ERROR: unidentified data type" << std::endl; | 989 | std::cout << "ERROR: unidentified data type" << std::endl; |
924 | exit(1); | 990 | exit(1); |
@@ -926,9 +992,9 @@ public: | @@ -926,9 +992,9 @@ public: | ||
926 | } | 992 | } |
927 | else if (header.interleave == envi_header::BIL){ | 993 | else if (header.interleave == envi_header::BIL){ |
928 | if (header.data_type == envi_header::float32) | 994 | if (header.data_type == envi_header::float32) |
929 | - return ((bil<float>*)file)->spectrum((float*)ptr, x, y); | 995 | + return ((bil<float>*)file)->spectrum((float*)ptr, x, y, PROGRESS); |
930 | else if (header.data_type == envi_header::float64) | 996 | else if (header.data_type == envi_header::float64) |
931 | - return ((bil<double>*)file)->spectrum((double*)ptr, x, y); | 997 | + return ((bil<double>*)file)->spectrum((double*)ptr, x, y, PROGRESS); |
932 | else{ | 998 | else{ |
933 | std::cout << "ERROR: unidentified data type" << std::endl; | 999 | std::cout << "ERROR: unidentified data type" << std::endl; |
934 | exit(1); | 1000 | exit(1); |
@@ -936,9 +1002,9 @@ public: | @@ -936,9 +1002,9 @@ public: | ||
936 | } | 1002 | } |
937 | else if (header.interleave == envi_header::BIP){ | 1003 | else if (header.interleave == envi_header::BIP){ |
938 | if (header.data_type == envi_header::float32) | 1004 | if (header.data_type == envi_header::float32) |
939 | - return ((bip<float>*)file)->spectrum((float*)ptr, x, y); | 1005 | + return ((bip<float>*)file)->spectrum((float*)ptr, x, y, PROGRESS); |
940 | else if (header.data_type == envi_header::float64) | 1006 | else if (header.data_type == envi_header::float64) |
941 | - return ((bip<double>*)file)->spectrum((double*)ptr, x, y); | 1007 | + return ((bip<double>*)file)->spectrum((double*)ptr, x, y, PROGRESS); |
942 | else{ | 1008 | else{ |
943 | std::cout << "ERROR: unidentified data type" << std::endl; | 1009 | std::cout << "ERROR: unidentified data type" << std::endl; |
944 | exit(1); | 1010 | exit(1); |
@@ -989,12 +1055,12 @@ public: | @@ -989,12 +1055,12 @@ public: | ||
989 | 1055 | ||
990 | /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum | 1056 | /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum |
991 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location | 1057 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location |
992 | - bool avg_band(double * p, unsigned char* mask){ | 1058 | + bool avg_band(double * p, unsigned char* mask, bool PROGRESS = false){ |
993 | if (header.interleave == envi_header::BSQ){ | 1059 | if (header.interleave == envi_header::BSQ){ |
994 | if (header.data_type == envi_header::float32) | 1060 | if (header.data_type == envi_header::float32) |
995 | - return ((bsq<float>*)file)->avg_band(p, mask); | 1061 | + return ((bsq<float>*)file)->avg_band(p, mask, PROGRESS); |
996 | else if (header.data_type == envi_header::float64) | 1062 | else if (header.data_type == envi_header::float64) |
997 | - return ((bsq<double>*)file)->avg_band(p, mask); | 1063 | + return ((bsq<double>*)file)->avg_band(p, mask, PROGRESS); |
998 | else{ | 1064 | else{ |
999 | std::cout << "ERROR: unidentified data type" << std::endl; | 1065 | std::cout << "ERROR: unidentified data type" << std::endl; |
1000 | exit(1); | 1066 | exit(1); |
@@ -1002,9 +1068,9 @@ public: | @@ -1002,9 +1068,9 @@ public: | ||
1002 | } | 1068 | } |
1003 | else if (header.interleave == envi_header::BIL){ | 1069 | else if (header.interleave == envi_header::BIL){ |
1004 | if (header.data_type == envi_header::float32) | 1070 | if (header.data_type == envi_header::float32) |
1005 | - return ((bil<float>*)file)->avg_band(p, mask); | 1071 | + return ((bil<float>*)file)->avg_band(p, mask, PROGRESS); |
1006 | else if (header.data_type == envi_header::float64) | 1072 | else if (header.data_type == envi_header::float64) |
1007 | - return ((bil<double>*)file)->avg_band(p, mask); | 1073 | + return ((bil<double>*)file)->avg_band(p, mask, PROGRESS); |
1008 | else{ | 1074 | else{ |
1009 | std::cout << "ERROR: unidentified data type" << std::endl; | 1075 | std::cout << "ERROR: unidentified data type" << std::endl; |
1010 | exit(1); | 1076 | exit(1); |
@@ -1012,9 +1078,9 @@ public: | @@ -1012,9 +1078,9 @@ public: | ||
1012 | } | 1078 | } |
1013 | else if (header.interleave == envi_header::BIP){ | 1079 | else if (header.interleave == envi_header::BIP){ |
1014 | if (header.data_type == envi_header::float32) | 1080 | if (header.data_type == envi_header::float32) |
1015 | - return ((bip<float>*)file)->avg_band(p, mask); | 1081 | + return ((bip<float>*)file)->avg_band(p, mask, PROGRESS); |
1016 | else if (header.data_type == envi_header::float64) | 1082 | else if (header.data_type == envi_header::float64) |
1017 | - return ((bip<double>*)file)->avg_band(p, mask); | 1083 | + return ((bip<double>*)file)->avg_band(p, mask, PROGRESS); |
1018 | else{ | 1084 | else{ |
1019 | std::cout << "ERROR: unidentified data type" << std::endl; | 1085 | std::cout << "ERROR: unidentified data type" << std::endl; |
1020 | exit(1); | 1086 | exit(1); |
@@ -1028,22 +1094,24 @@ public: | @@ -1028,22 +1094,24 @@ public: | ||
1028 | /// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix | 1094 | /// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix |
1029 | /// @param avg is a pointer to memory of size B that stores the average spectrum | 1095 | /// @param avg is a pointer to memory of size B that stores the average spectrum |
1030 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location | 1096 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location |
1031 | - bool co_matrix(double* co, double* avg, unsigned char* mask){ | 1097 | + bool co_matrix(double* co, double* avg, unsigned char* mask, bool PROGRESS = false){ |
1032 | if (header.interleave == envi_header::BSQ){ | 1098 | if (header.interleave == envi_header::BSQ){ |
1033 | - if (header.data_type == envi_header::float32) | ||
1034 | - return ((bsq<float>*)file)->co_matrix(co, avg, mask); | 1099 | + std::cout<<"ERROR: calculating the covariance matrix for a BSQ file is impractical; convert to BIL or BIP first"<<std::endl; |
1100 | + exit(1); | ||
1101 | + /*if (header.data_type == envi_header::float32) | ||
1102 | + return ((bsq<float>*)file)->co_matrix(co, avg, mask, PROGRESS); | ||
1035 | else if (header.data_type == envi_header::float64) | 1103 | else if (header.data_type == envi_header::float64) |
1036 | - return ((bsq<double>*)file)->co_matrix(co, avg, mask); | 1104 | + return ((bsq<double>*)file)->co_matrix(co, avg, mask, PROGRESS); |
1037 | else{ | 1105 | else{ |
1038 | std::cout << "ERROR: unidentified data type" << std::endl; | 1106 | std::cout << "ERROR: unidentified data type" << std::endl; |
1039 | exit(1); | 1107 | exit(1); |
1040 | - } | 1108 | + }*/ |
1041 | } | 1109 | } |
1042 | else if (header.interleave == envi_header::BIL){ | 1110 | else if (header.interleave == envi_header::BIL){ |
1043 | if (header.data_type == envi_header::float32) | 1111 | if (header.data_type == envi_header::float32) |
1044 | - return ((bil<float>*)file)->co_matrix(co, avg, mask); | 1112 | + return ((bil<float>*)file)->co_matrix(co, avg, mask, PROGRESS); |
1045 | else if (header.data_type == envi_header::float64) | 1113 | else if (header.data_type == envi_header::float64) |
1046 | - return ((bil<double>*)file)->co_matrix(co, avg, mask); | 1114 | + return ((bil<double>*)file)->co_matrix(co, avg, mask, PROGRESS); |
1047 | else{ | 1115 | else{ |
1048 | std::cout << "ERROR: unidentified data type" << std::endl; | 1116 | std::cout << "ERROR: unidentified data type" << std::endl; |
1049 | exit(1); | 1117 | exit(1); |
@@ -1051,9 +1119,9 @@ public: | @@ -1051,9 +1119,9 @@ public: | ||
1051 | } | 1119 | } |
1052 | else if (header.interleave == envi_header::BIP){ | 1120 | else if (header.interleave == envi_header::BIP){ |
1053 | if (header.data_type == envi_header::float32) | 1121 | if (header.data_type == envi_header::float32) |
1054 | - return ((bip<float>*)file)->co_matrix(co, avg, mask); | 1122 | + return ((bip<float>*)file)->co_matrix(co, avg, mask, PROGRESS); |
1055 | else if (header.data_type == envi_header::float64) | 1123 | else if (header.data_type == envi_header::float64) |
1056 | - return ((bip<double>*)file)->co_matrix(co, avg, mask); | 1124 | + return ((bip<double>*)file)->co_matrix(co, avg, mask, PROGRESS); |
1057 | else{ | 1125 | else{ |
1058 | std::cout << "ERROR: unidentified data type" << std::endl; | 1126 | std::cout << "ERROR: unidentified data type" << std::endl; |
1059 | exit(1); | 1127 | exit(1); |
@@ -1070,7 +1138,7 @@ public: | @@ -1070,7 +1138,7 @@ public: | ||
1070 | /// @param y0 is the lower-left y pixel coordinate to be included in the cropped image | 1138 | /// @param y0 is the lower-left y pixel coordinate to be included in the cropped image |
1071 | /// @param x1 is the upper-right x pixel coordinate to be included in the cropped image | 1139 | /// @param x1 is the upper-right x pixel coordinate to be included in the cropped image |
1072 | /// @param y1 is the upper-right y pixel coordinate to be included in the cropped image | 1140 | /// @param y1 is the upper-right y pixel coordinate to be included in the cropped image |
1073 | - bool crop(std::string outfile,unsigned x0, unsigned y0, unsigned x1, unsigned y1, unsigned b0, unsigned b1){ | 1141 | + bool crop(std::string outfile,unsigned x0, unsigned y0, unsigned x1, unsigned y1, unsigned b0, unsigned b1, bool PROGRESS = false){ |
1074 | 1142 | ||
1075 | //save the header for the cropped file | 1143 | //save the header for the cropped file |
1076 | stim::envi_header new_header = header; | 1144 | stim::envi_header new_header = header; |
@@ -1084,9 +1152,9 @@ public: | @@ -1084,9 +1152,9 @@ public: | ||
1084 | 1152 | ||
1085 | if (header.interleave == envi_header::BSQ){ | 1153 | if (header.interleave == envi_header::BSQ){ |
1086 | if (header.data_type == envi_header::float32) | 1154 | if (header.data_type == envi_header::float32) |
1087 | - return ((bsq<float>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1); | 1155 | + return ((bsq<float>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1, PROGRESS); |
1088 | else if (header.data_type == envi_header::float64) | 1156 | else if (header.data_type == envi_header::float64) |
1089 | - return ((bsq<double>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1); | 1157 | + return ((bsq<double>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1, PROGRESS); |
1090 | else{ | 1158 | else{ |
1091 | std::cout << "ERROR: unidentified data type" << std::endl; | 1159 | std::cout << "ERROR: unidentified data type" << std::endl; |
1092 | exit(1); | 1160 | exit(1); |
@@ -1094,9 +1162,9 @@ public: | @@ -1094,9 +1162,9 @@ public: | ||
1094 | } | 1162 | } |
1095 | else if (header.interleave == envi_header::BIL){ | 1163 | else if (header.interleave == envi_header::BIL){ |
1096 | if (header.data_type == envi_header::float32) | 1164 | if (header.data_type == envi_header::float32) |
1097 | - return ((bil<float>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1); | 1165 | + return ((bil<float>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1, PROGRESS); |
1098 | else if (header.data_type == envi_header::float64) | 1166 | else if (header.data_type == envi_header::float64) |
1099 | - return ((bil<double>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1); | 1167 | + return ((bil<double>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1, PROGRESS); |
1100 | else{ | 1168 | else{ |
1101 | std::cout << "ERROR: unidentified data type" << std::endl; | 1169 | std::cout << "ERROR: unidentified data type" << std::endl; |
1102 | exit(1); | 1170 | exit(1); |
@@ -1104,9 +1172,9 @@ public: | @@ -1104,9 +1172,9 @@ public: | ||
1104 | } | 1172 | } |
1105 | else if (header.interleave == envi_header::BIP){ | 1173 | else if (header.interleave == envi_header::BIP){ |
1106 | if (header.data_type == envi_header::float32) | 1174 | if (header.data_type == envi_header::float32) |
1107 | - return ((bip<float>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1); | 1175 | + return ((bip<float>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1, PROGRESS); |
1108 | else if (header.data_type == envi_header::float64) | 1176 | else if (header.data_type == envi_header::float64) |
1109 | - return ((bip<double>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1); | 1177 | + return ((bip<double>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1, PROGRESS); |
1110 | else{ | 1178 | else{ |
1111 | std::cout << "ERROR: unidentified data type" << std::endl; | 1179 | std::cout << "ERROR: unidentified data type" << std::endl; |
1112 | exit(1); | 1180 | exit(1); |