Commit f4069d3f54b21a7ee54160b0f839fd3a4b767dfe

Authored by David Mayerich
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 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 1404 // Retrieve a spectrum at the specified 1D location
1372 1405  
1373 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 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 65 /// Returns the interpolated in the given spectrum based on the given wavelength
91 66  
92 67 /// @param s is the spectrum in main memory of length Z()
... ... @@ -139,6 +114,31 @@ protected:
139 114 }
140 115  
141 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 142 /// Get a mask that has all pixels with inf or NaN values masked out (false)
143 143 void mask_finite(unsigned char* out_mask, unsigned char* mask, bool PROGRESS = false){
144 144 size_t XY = X() * Y();
... ...
stim/math/matrix.h
... ... @@ -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 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 90 template <class T>
... ... @@ -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 453 if (format == mat4_float) {
415 454 if (sizeof(T) == 4) format = mat4_float32;
416 455 else if (sizeof(T) == 8) format = mat4_float64;
... ... @@ -419,7 +458,40 @@ public:
419 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  
... ...