Commit f4069d3f54b21a7ee54160b0f839fd3a4b767dfe
1 parent
95f1e985
fixed the crop function to work with wavelength
Showing
3 changed files
with
158 additions
and
53 deletions
Show diff stats
stim/envi/envi.h
@@ -1368,6 +1368,39 @@ public: | @@ -1368,6 +1368,39 @@ public: | ||
1368 | return false; | 1368 | return false; |
1369 | } | 1369 | } |
1370 | 1370 | ||
1371 | + void band_bounds(double wavelength, size_t& low, size_t& high) { | ||
1372 | + if (header.interleave == envi_header::BSQ) { //if the infile is bsq file | ||
1373 | + if (header.data_type == envi_header::float32) | ||
1374 | + ((bsq<float>*)file)->band_bounds(wavelength, low, high); | ||
1375 | + else if (header.data_type == envi_header::float64) | ||
1376 | + ((bsq<double>*)file)->band_bounds(wavelength, low, high); | ||
1377 | + else { | ||
1378 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
1379 | + exit(1); | ||
1380 | + } | ||
1381 | + } | ||
1382 | + else if (header.interleave == envi_header::BIL) { | ||
1383 | + if (header.data_type == envi_header::float32) | ||
1384 | + ((bil<float>*)file)->band_bounds(wavelength, low, high); | ||
1385 | + else if (header.data_type == envi_header::float64) | ||
1386 | + ((bil<double>*)file)->band_bounds(wavelength, low, high); | ||
1387 | + else { | ||
1388 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
1389 | + exit(1); | ||
1390 | + } | ||
1391 | + } | ||
1392 | + else if (header.interleave == envi_header::BIP) { | ||
1393 | + if (header.data_type == envi_header::float32) | ||
1394 | + ((bip<float>*)file)->band_bounds(wavelength, low, high); | ||
1395 | + else if (header.data_type == envi_header::float64) | ||
1396 | + ((bip<double>*)file)->band_bounds(wavelength, low, high); | ||
1397 | + else { | ||
1398 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
1399 | + exit(1); | ||
1400 | + } | ||
1401 | + } | ||
1402 | + } | ||
1403 | + | ||
1371 | // Retrieve a spectrum at the specified 1D location | 1404 | // Retrieve a spectrum at the specified 1D location |
1372 | 1405 | ||
1373 | /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T) | 1406 | /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T) |
stim/envi/hsi.h
@@ -62,31 +62,6 @@ protected: | @@ -62,31 +62,6 @@ protected: | ||
62 | return (T)((1.0 - alpha) * low_v + alpha * high_v); //interpolate | 62 | return (T)((1.0 - alpha) * low_v + alpha * high_v); //interpolate |
63 | } | 63 | } |
64 | 64 | ||
65 | - /// Gets the two band indices surrounding a given wavelength | ||
66 | - void band_bounds(double wavelength, size_t& low, size_t& high){ | ||
67 | - size_t B = Z(); | ||
68 | - for(high = 0; high < B; high++){ | ||
69 | - if(w[high] > wavelength) break; | ||
70 | - } | ||
71 | - low = 0; | ||
72 | - if(high > 0) | ||
73 | - low = high-1; | ||
74 | - } | ||
75 | - | ||
76 | - /// Get the list of band numbers that bound a list of wavelengths | ||
77 | - void band_bounds(std::vector<double> wavelengths, | ||
78 | - std::vector<unsigned long long>& low_bands, | ||
79 | - std::vector<unsigned long long>& high_bands){ | ||
80 | - | ||
81 | - unsigned long long W = w.size(); //get the number of wavelengths in the list | ||
82 | - low_bands.resize(W); //pre-allocate space for the band lists | ||
83 | - high_bands.resize(W); | ||
84 | - | ||
85 | - for(unsigned long long wl = 0; wl < W; wl++){ //for each wavelength | ||
86 | - band_bounds(wavelengths[wl], low_bands[wl], high_bands[wl]); //find the low and high bands | ||
87 | - } | ||
88 | - } | ||
89 | - | ||
90 | /// Returns the interpolated in the given spectrum based on the given wavelength | 65 | /// Returns the interpolated in the given spectrum based on the given wavelength |
91 | 66 | ||
92 | /// @param s is the spectrum in main memory of length Z() | 67 | /// @param s is the spectrum in main memory of length Z() |
@@ -139,6 +114,31 @@ protected: | @@ -139,6 +114,31 @@ protected: | ||
139 | } | 114 | } |
140 | 115 | ||
141 | public: | 116 | public: |
117 | + | ||
118 | + /// Gets the two band indices surrounding a given wavelength | ||
119 | + void band_bounds(double wavelength, size_t& low, size_t& high) { | ||
120 | + size_t B = Z(); | ||
121 | + for (high = 0; high < B; high++) { | ||
122 | + if (w[high] > wavelength) break; | ||
123 | + } | ||
124 | + low = 0; | ||
125 | + if (high > 0) | ||
126 | + low = high - 1; | ||
127 | + } | ||
128 | + | ||
129 | + /// Get the list of band numbers that bound a list of wavelengths | ||
130 | + void band_bounds(std::vector<double> wavelengths, | ||
131 | + std::vector<unsigned long long>& low_bands, | ||
132 | + std::vector<unsigned long long>& high_bands) { | ||
133 | + | ||
134 | + unsigned long long W = w.size(); //get the number of wavelengths in the list | ||
135 | + low_bands.resize(W); //pre-allocate space for the band lists | ||
136 | + high_bands.resize(W); | ||
137 | + | ||
138 | + for (unsigned long long wl = 0; wl < W; wl++) { //for each wavelength | ||
139 | + band_bounds(wavelengths[wl], low_bands[wl], high_bands[wl]); //find the low and high bands | ||
140 | + } | ||
141 | + } | ||
142 | /// Get a mask that has all pixels with inf or NaN values masked out (false) | 142 | /// Get a mask that has all pixels with inf or NaN values masked out (false) |
143 | void mask_finite(unsigned char* out_mask, unsigned char* mask, bool PROGRESS = false){ | 143 | void mask_finite(unsigned char* out_mask, unsigned char* mask, bool PROGRESS = false){ |
144 | size_t XY = X() * Y(); | 144 | size_t XY = X() * Y(); |
stim/math/matrix.h
@@ -33,32 +33,58 @@ namespace stim{ | @@ -33,32 +33,58 @@ namespace stim{ | ||
33 | } | 33 | } |
34 | } | 34 | } |
35 | 35 | ||
36 | + //class encapsulates a mat4 file, and can be used to write multiple matrices to a single mat4 file | ||
37 | + class mat4file { | ||
38 | + std::ofstream matfile; | ||
39 | + | ||
40 | + public: | ||
41 | + /// Constructor opens a mat4 file for writing | ||
42 | + mat4file(std::string filename) { | ||
43 | + matfile.open(filename, std::ios::binary); | ||
44 | + } | ||
45 | + | ||
46 | + bool is_open() { | ||
47 | + return matfile.is_open(); | ||
48 | + } | ||
49 | + | ||
50 | + void close() { | ||
51 | + matfile.close(); | ||
52 | + } | ||
53 | + | ||
54 | + bool writemat(char* data, std::string varname, size_t sx, size_t sy, mat4Format format) { | ||
55 | + //save the matrix file here (use the mat4 function above) | ||
56 | + //data format: https://maxwell.ict.griffith.edu.au/spl/matlab-page/matfile_format.pdf (page 32) | ||
57 | + | ||
58 | + int MOPT = 0; //initialize the MOPT type value to zero | ||
59 | + int m = 0; //little endian | ||
60 | + int o = 0; //reserved, always 0 | ||
61 | + int p = format; | ||
62 | + int t = 0; | ||
63 | + MOPT = m * 1000 + o * 100 + p * 10 + t; //calculate the type value | ||
64 | + int mrows = (int)sx; | ||
65 | + int ncols = (int)sy; | ||
66 | + int imagf = 0; //assume real (for now) | ||
67 | + varname.push_back('\0'); //add a null to the string | ||
68 | + int namlen = (int)varname.size(); //calculate the name size | ||
69 | + | ||
70 | + size_t bytes = sx * sy * mat4Format_size(format); | ||
71 | + matfile.write((char*)&MOPT, 4); | ||
72 | + matfile.write((char*)&mrows, 4); | ||
73 | + matfile.write((char*)&ncols, 4); | ||
74 | + matfile.write((char*)&imagf, 4); | ||
75 | + matfile.write((char*)&namlen, 4); | ||
76 | + matfile.write((char*)&varname[0], namlen); | ||
77 | + matfile.write((char*)data, bytes); //write the matrix data | ||
78 | + return is_open(); | ||
79 | + } | ||
80 | + }; | ||
81 | + | ||
36 | static void save_mat4(char* data, std::string filename, std::string varname, size_t sx, size_t sy, mat4Format format){ | 82 | static void save_mat4(char* data, std::string filename, std::string varname, size_t sx, size_t sy, mat4Format format){ |
37 | - //save the matrix file here (use the mat4 function above) | ||
38 | - //data format: https://maxwell.ict.griffith.edu.au/spl/matlab-page/matfile_format.pdf (page 32) | ||
39 | - | ||
40 | - int MOPT = 0; //initialize the MOPT type value to zero | ||
41 | - int m = 0; //little endian | ||
42 | - int o = 0; //reserved, always 0 | ||
43 | - int p = format; | ||
44 | - int t = 0; | ||
45 | - MOPT = m * 1000 + o * 100 + p * 10 + t; //calculate the type value | ||
46 | - int mrows = (int)sx; | ||
47 | - int ncols = (int)sy; | ||
48 | - int imagf = 0; //assume real (for now) | ||
49 | - varname.push_back('\0'); //add a null to the string | ||
50 | - int namlen = (int)varname.size(); //calculate the name size | ||
51 | - | ||
52 | - size_t bytes = sx * sy * mat4Format_size(format); | ||
53 | - std::ofstream outfile(filename, std::ios::binary); | ||
54 | - outfile.write((char*)&MOPT, 4); | ||
55 | - outfile.write((char*)&mrows, 4); | ||
56 | - outfile.write((char*)&ncols, 4); | ||
57 | - outfile.write((char*)&imagf, 4); | ||
58 | - outfile.write((char*)&namlen, 4); | ||
59 | - outfile.write((char*)&varname[0], namlen); | ||
60 | - outfile.write((char*)data, bytes); //write the matrix data | ||
61 | - outfile.close(); | 83 | + mat4file outfile(filename); //create a mat4 file object |
84 | + if (outfile.is_open()) { //if the file is open | ||
85 | + outfile.writemat(data, varname, sx, sy, format); //write the matrix | ||
86 | + outfile.close(); //close the file | ||
87 | + } | ||
62 | } | 88 | } |
63 | 89 | ||
64 | template <class T> | 90 | template <class T> |
@@ -409,8 +435,21 @@ public: | @@ -409,8 +435,21 @@ public: | ||
409 | } | 435 | } |
410 | } | 436 | } |
411 | 437 | ||
412 | - // saves the matrix as a Level-4 MATLAB file | ||
413 | - void mat4(std::string filename, std::string name = std::string("unknown"), mat4Format format = mat4_float) { | 438 | + void mat4(stim::mat4file& file, std::string name = std::string("unknown"), mat4Format format = mat4_float) { |
439 | + //make sure the matrix name is valid (only numbers and letters, with a letter at the beginning | ||
440 | + for (size_t c = 0; c < name.size(); c++) { | ||
441 | + if (name[c] < 48 || //if the character isn't a number or letter, replace it with '_' | ||
442 | + (name[c] > 57 && name[c] < 65) || | ||
443 | + (name[c] > 90 && name[c] < 97) || | ||
444 | + (name[c] > 122)) { | ||
445 | + name[c] = '_'; | ||
446 | + } | ||
447 | + } | ||
448 | + if (name[0] < 65 || | ||
449 | + (name[0] > 91 && name[0] < 97) || | ||
450 | + name[0] > 122) { | ||
451 | + name = std::string("m") + name; | ||
452 | + } | ||
414 | if (format == mat4_float) { | 453 | if (format == mat4_float) { |
415 | if (sizeof(T) == 4) format = mat4_float32; | 454 | if (sizeof(T) == 4) format = mat4_float32; |
416 | else if (sizeof(T) == 8) format = mat4_float64; | 455 | else if (sizeof(T) == 8) format = mat4_float64; |
@@ -419,7 +458,40 @@ public: | @@ -419,7 +458,40 @@ public: | ||
419 | exit(1); | 458 | exit(1); |
420 | } | 459 | } |
421 | } | 460 | } |
422 | - stim::save_mat4((char*)M, filename, name, rows(), cols(), format); | 461 | + //the name is now valid |
462 | + | ||
463 | + //if the size of the array is more than 100,000,000 elements, the matrix isn't supported | ||
464 | + if (rows() * cols() > 100000000) { //break the matrix up into multiple parts | ||
465 | + //mat4file out(filename); //create a mat4 object to write the matrix | ||
466 | + if (file.is_open()) { | ||
467 | + if (rows() < 100000000) { //if the size of the row is less than 100,000,000, split the matrix up by columns | ||
468 | + size_t ncols = 100000000 / rows(); //calculate the number of columns that can fit in one matrix | ||
469 | + size_t nmat = (size_t)std::ceil((double)cols() / (double)ncols); //calculate the number of matrices required | ||
470 | + for (size_t m = 0; m < nmat; m++) { //for each matrix | ||
471 | + std::stringstream ss; | ||
472 | + ss << name << "_part_" << m + 1; | ||
473 | + if (m == nmat - 1) | ||
474 | + file.writemat((char*)(data() + m * ncols * rows()), ss.str(), rows(), cols() - m * ncols, format); | ||
475 | + else | ||
476 | + file.writemat((char*)(data() + m * ncols * rows()), ss.str(), rows(), ncols, format); | ||
477 | + } | ||
478 | + } | ||
479 | + } | ||
480 | + } | ||
481 | + //call the mat4 subroutine | ||
482 | + else | ||
483 | + //stim::save_mat4((char*)M, filename, name, rows(), cols(), format); | ||
484 | + file.writemat((char*)data(), name, rows(), cols(), format); | ||
485 | + } | ||
486 | + | ||
487 | + // saves the matrix as a Level-4 MATLAB file | ||
488 | + void mat4(std::string filename, std::string name = std::string("unknown"), mat4Format format = mat4_float) { | ||
489 | + stim::mat4file matfile(filename); | ||
490 | + | ||
491 | + if (matfile.is_open()) { | ||
492 | + mat4(matfile, name, format); | ||
493 | + matfile.close(); | ||
494 | + } | ||
423 | } | 495 | } |
424 | }; | 496 | }; |
425 | 497 |