Commit ba51ae6a3d666879ecea0dd9fe40a56b7ca47092
1 parent
44f44bb5
fixed metric calculations, added a finite-value mask, as_float() in stim::arglist returns a double
Showing
6 changed files
with
265 additions
and
118 deletions
Show diff stats
stim/envi/bil.h
@@ -600,7 +600,7 @@ public: | @@ -600,7 +600,7 @@ public: | ||
600 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) | 600 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
601 | /// @param pos2 is the label value for the second peak (denominator) position | 601 | /// @param pos2 is the label value for the second peak (denominator) position |
602 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 602 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
603 | - bool ph_to_ph(double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, T * result){ | 603 | + bool ph_to_ph(T* result, double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, unsigned char* mask = NULL){ |
604 | 604 | ||
605 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | 605 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
606 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | 606 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
@@ -630,8 +630,8 @@ public: | @@ -630,8 +630,8 @@ public: | ||
630 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) | 630 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
631 | /// @param pos2 is the label value for the second peak (denominator) position | 631 | /// @param pos2 is the label value for the second peak (denominator) position |
632 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 632 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
633 | - bool pa_to_ph(double lb1, double rb1, double lab1, double rab1, | ||
634 | - double lb2, double rb2, double pos, T* result){ | 633 | + bool pa_to_ph(T* result, double lb1, double rb1, double lab1, double rab1, |
634 | + double lb2, double rb2, double pos, unsigned char* mask = NULL){ | ||
635 | 635 | ||
636 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | 636 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
637 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | 637 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
@@ -663,8 +663,8 @@ public: | @@ -663,8 +663,8 @@ public: | ||
663 | /// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator) | 663 | /// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator) |
664 | /// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator) | 664 | /// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator) |
665 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 665 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
666 | - bool pa_to_pa(double lb1, double rb1, double lab1, double rab1, | ||
667 | - double lb2, double rb2, double lab2, double rab2, T* result){ | 666 | + bool pa_to_pa(T* result, double lb1, double rb1, double lab1, double rab1, |
667 | + double lb2, double rb2, double lab2, double rab2, unsigned char* mask = NULL){ | ||
668 | 668 | ||
669 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | 669 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
670 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | 670 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
@@ -773,7 +773,7 @@ public: | @@ -773,7 +773,7 @@ public: | ||
773 | /// @param lab is the label for the start of the peak | 773 | /// @param lab is the label for the start of the peak |
774 | /// @param rab is the label for the end of the peak | 774 | /// @param rab is the label for the end of the peak |
775 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 775 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
776 | - bool cpoint(double lb, double rb, double lab, double rab, T* result){ | 776 | + bool centroid(T* result, double lb, double rb, double lab, double rab, unsigned char* mask = NULL){ |
777 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | 777 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
778 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | 778 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
779 | 779 | ||
@@ -782,9 +782,7 @@ public: | @@ -782,9 +782,7 @@ public: | ||
782 | area(lb, rb, lab, rab, p2); | 782 | area(lb, rb, lab, rab, p2); |
783 | //calculate the ratio in result | 783 | //calculate the ratio in result |
784 | for(unsigned long long i = 0; i < X() * Y(); i++){ | 784 | for(unsigned long long i = 0; i < X() * Y(); i++){ |
785 | - if(p1[i] == 0 && p2[i] ==0) | ||
786 | - result[i] = 1; | ||
787 | - else | 785 | + if(mask == NULL || mask[i]) |
788 | result[i] = p1[i] / p2[i]; | 786 | result[i] = p1[i] / p2[i]; |
789 | } | 787 | } |
790 | 788 | ||
@@ -800,16 +798,16 @@ public: | @@ -800,16 +798,16 @@ public: | ||
800 | /// @param mask_band is the band used to specify the mask | 798 | /// @param mask_band is the band used to specify the mask |
801 | /// @param threshold is the threshold used to determine if the mask value is true or false | 799 | /// @param threshold is the threshold used to determine if the mask value is true or false |
802 | /// @param p is a pointer to a pre-allocated array at least X * Y in size | 800 | /// @param p is a pointer to a pre-allocated array at least X * Y in size |
803 | - bool build_mask(double mask_band, double threshold, unsigned char* p, bool PROGRESS = false){ | 801 | + bool build_mask(unsigned char* mask, double mask_band, double threshold, bool PROGRESS = false){ |
804 | 802 | ||
805 | T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band | 803 | T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band |
806 | band(temp, mask_band, PROGRESS); | 804 | band(temp, mask_band, PROGRESS); |
807 | 805 | ||
808 | for (unsigned long long i = 0; i < X() * Y(); i++) { | 806 | for (unsigned long long i = 0; i < X() * Y(); i++) { |
809 | if (temp[i] < threshold) | 807 | if (temp[i] < threshold) |
810 | - p[i] = 0; | 808 | + mask[i] = 0; |
811 | else | 809 | else |
812 | - p[i] = 255; | 810 | + mask[i] = 255; |
813 | } | 811 | } |
814 | 812 | ||
815 | free(temp); | 813 | free(temp); |
@@ -850,6 +848,36 @@ public: | @@ -850,6 +848,36 @@ public: | ||
850 | return true; | 848 | return true; |
851 | } | 849 | } |
852 | 850 | ||
851 | + /// Copies all spectra corresponding to nonzero values of a mask into a pre-allocated matrix of size (B x P) | ||
852 | + /// where P is the number of masked pixels and B is the number of bands. The allocated memory can be accessed | ||
853 | + /// using the following indexing: i = p*B + b | ||
854 | + /// @param matrix is the destination for the pixel data | ||
855 | + /// @param mask is the mask | ||
856 | + bool sift(T* matrix, unsigned char* mask){ | ||
857 | + size_t Lbytes = sizeof(T) * X(); | ||
858 | + T* line = (T*) malloc( Lbytes ); //allocate space for a line | ||
859 | + | ||
860 | + file.seekg(0, std::ios::beg); //seek to the beginning of the file | ||
861 | + | ||
862 | + size_t pl; | ||
863 | + size_t p = 0; //create counter variables | ||
864 | + for(size_t y = 0; y < Y(); y++){ //for each line in the data set | ||
865 | + for(size_t b = 0; b < Z(); b++){ //for each band in the data set | ||
866 | + pl = 0; //initialize the pixel offset for the current line to zero (0) | ||
867 | + file.read( (char*)line, Lbytes ); //read the current line | ||
868 | + for(size_t x = 0; x < X(); x++){ | ||
869 | + if(mask[y * X() + x]){ //if the current pixel is masked | ||
870 | + size_t i = (p + pl) * Z() + b; //calculate the index in the sifted matrix | ||
871 | + matrix[i] = line[x]; //store the current value in the line at the correct matrix location | ||
872 | + pl++; //increment the pixel pointer | ||
873 | + } | ||
874 | + } | ||
875 | + } | ||
876 | + p += pl; //add the line increment to the running pixel index | ||
877 | + } | ||
878 | + return true; | ||
879 | + } | ||
880 | + | ||
853 | /// Saves to disk only those spectra corresponding to mask values != 0 | 881 | /// Saves to disk only those spectra corresponding to mask values != 0 |
854 | /// Unlike the BIP and BSQ versions of this function, this version saves a different format: the BIL file is saved as a BIP | 882 | /// Unlike the BIP and BSQ versions of this function, this version saves a different format: the BIL file is saved as a BIP |
855 | bool sift(std::string outfile, unsigned char* p, bool PROGRESS = false){ | 883 | bool sift(std::string outfile, unsigned char* p, bool PROGRESS = false){ |
stim/envi/bip.h
@@ -526,7 +526,7 @@ public: | @@ -526,7 +526,7 @@ public: | ||
526 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) | 526 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
527 | /// @param pos2 is the label value for the second peak (denominator) position | 527 | /// @param pos2 is the label value for the second peak (denominator) position |
528 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 528 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
529 | - bool ph_to_ph(double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, T * result){ | 529 | + bool ph_to_ph(T* result, double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, unsigned char* mask = NULL){ |
530 | 530 | ||
531 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | 531 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
532 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | 532 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
@@ -556,8 +556,8 @@ public: | @@ -556,8 +556,8 @@ public: | ||
556 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) | 556 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
557 | /// @param pos2 is the label value for the second peak (denominator) position | 557 | /// @param pos2 is the label value for the second peak (denominator) position |
558 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 558 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
559 | - bool pa_to_ph(double lb1, double rb1, double lab1, double rab1, | ||
560 | - double lb2, double rb2, double pos, T* result){ | 559 | + bool pa_to_ph(T* result, double lb1, double rb1, double lab1, double rab1, |
560 | + double lb2, double rb2, double pos, unsigned char* mask = NULL){ | ||
561 | 561 | ||
562 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | 562 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
563 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | 563 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
@@ -589,8 +589,8 @@ public: | @@ -589,8 +589,8 @@ public: | ||
589 | /// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator) | 589 | /// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator) |
590 | /// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator) | 590 | /// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator) |
591 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 591 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
592 | - bool pa_to_pa(double lb1, double rb1, double lab1, double rab1, | ||
593 | - double lb2, double rb2, double lab2, double rab2, T* result){ | 592 | + bool pa_to_pa(T* result, double lb1, double rb1, double lab1, double rab1, |
593 | + double lb2, double rb2, double lab2, double rab2, unsigned char* mask = NULL){ | ||
594 | 594 | ||
595 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | 595 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
596 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | 596 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
@@ -699,7 +699,7 @@ public: | @@ -699,7 +699,7 @@ public: | ||
699 | /// @param lab is the label for the start of the peak | 699 | /// @param lab is the label for the start of the peak |
700 | /// @param rab is the label for the end of the peak | 700 | /// @param rab is the label for the end of the peak |
701 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 701 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
702 | - bool cpoint(double lb, double rb, double lab, double rab, T* result){ | 702 | + bool centroid(T* result, double lb, double rb, double lab, double rab, unsigned char* mask = NULL){ |
703 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | 703 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
704 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | 704 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
705 | 705 | ||
@@ -708,9 +708,7 @@ public: | @@ -708,9 +708,7 @@ public: | ||
708 | area(lb, rb, lab, rab, p2); | 708 | area(lb, rb, lab, rab, p2); |
709 | //calculate the ratio in result | 709 | //calculate the ratio in result |
710 | for(unsigned long long i = 0; i < X() * Y(); i++){ | 710 | for(unsigned long long i = 0; i < X() * Y(); i++){ |
711 | - if(p1[i] == 0 && p2[i] ==0) | ||
712 | - result[i] = 1; | ||
713 | - else | 711 | + if(mask == NULL || mask[i]) |
714 | result[i] = p1[i] / p2[i]; | 712 | result[i] = p1[i] / p2[i]; |
715 | } | 713 | } |
716 | 714 | ||
@@ -726,16 +724,16 @@ public: | @@ -726,16 +724,16 @@ public: | ||
726 | /// @param mask_band is the band used to specify the mask | 724 | /// @param mask_band is the band used to specify the mask |
727 | /// @param threshold is the threshold used to determine if the mask value is true or false | 725 | /// @param threshold is the threshold used to determine if the mask value is true or false |
728 | /// @param p is a pointer to a pre-allocated array at least X * Y in size | 726 | /// @param p is a pointer to a pre-allocated array at least X * Y in size |
729 | - bool build_mask(double mask_band, double threshold, unsigned char* p, bool PROGRESS = false){ | 727 | + bool build_mask(unsigned char* mask, double mask_band, double threshold, bool PROGRESS = false){ |
730 | 728 | ||
731 | T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band | 729 | T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band |
732 | band(temp, mask_band, PROGRESS); | 730 | band(temp, mask_band, PROGRESS); |
733 | 731 | ||
734 | for (unsigned long long i = 0; i < X() * Y();i++) { | 732 | for (unsigned long long i = 0; i < X() * Y();i++) { |
735 | if (temp[i] < threshold) | 733 | if (temp[i] < threshold) |
736 | - p[i] = 0; | 734 | + mask[i] = 0; |
737 | else | 735 | else |
738 | - p[i] = 255; | 736 | + mask[i] = 255; |
739 | } | 737 | } |
740 | 738 | ||
741 | free(temp); | 739 | free(temp); |
@@ -776,6 +774,33 @@ public: | @@ -776,6 +774,33 @@ public: | ||
776 | return true; //return true | 774 | return true; //return true |
777 | } | 775 | } |
778 | 776 | ||
777 | + /// Copies all spectra corresponding to nonzero values of a mask into a pre-allocated matrix of size (B x P) | ||
778 | + /// where P is the number of masked pixels and B is the number of bands. The allocated memory can be accessed | ||
779 | + /// using the following indexing: i = p*B + b | ||
780 | + /// @param matrix is the destination for the pixel data | ||
781 | + /// @param mask is the mask | ||
782 | + bool sift(T* matrix, unsigned char* mask){ | ||
783 | + size_t Bbytes = sizeof(T) * Z(); | ||
784 | + size_t XY = X() * Y(); | ||
785 | + T* band = (T*) malloc( Bbytes ); //allocate space for a line | ||
786 | + | ||
787 | + file.seekg(0, std::ios::beg); //seek to the beginning of the file | ||
788 | + | ||
789 | + size_t p = 0; //create counter variables | ||
790 | + for(size_t xy = 0; xy < XY; xy++){ //for each pixel | ||
791 | + if(mask[xy]){ //if the current pixel is masked | ||
792 | + file.read( (char*)band, Bbytes ); //read the current line | ||
793 | + for(size_t b = 0; b < Z(); b++){ //copy each band value to the sifted matrix | ||
794 | + size_t i = p * Z() + b; //calculate the index in the sifted matrix | ||
795 | + matrix[i] = band[b]; //store the current value in the line at the correct matrix location | ||
796 | + } | ||
797 | + p++; //increment the pixel pointer | ||
798 | + } | ||
799 | + else | ||
800 | + file.seekg(Bbytes, std::ios::cur); //otherwise skip this band | ||
801 | + } | ||
802 | + return true; | ||
803 | + } | ||
779 | 804 | ||
780 | /// Saves to disk only those spectra corresponding to mask values != 0 | 805 | /// Saves to disk only those spectra corresponding to mask values != 0 |
781 | bool sift(std::string outfile, unsigned char* mask, bool PROGRESS = false){ | 806 | bool sift(std::string outfile, unsigned char* mask, bool PROGRESS = false){ |
stim/envi/bsq.h
@@ -436,9 +436,7 @@ public: | @@ -436,9 +436,7 @@ public: | ||
436 | cur = (T*) malloc(S); | 436 | cur = (T*) malloc(S); |
437 | cur2 = (T*) malloc(S); | 437 | cur2 = (T*) malloc(S); |
438 | 438 | ||
439 | - memset(result, (char)0, S); | ||
440 | - | ||
441 | - //find the wavelenght position in the whole band | 439 | + //find the wavelength position in the whole band |
442 | unsigned long long n = w.size(); | 440 | unsigned long long n = w.size(); |
443 | unsigned long long ai = 0; //left bound position | 441 | unsigned long long ai = 0; //left bound position |
444 | unsigned long long bi = n - 1; //right bound position | 442 | unsigned long long bi = n - 1; //right bound position |
@@ -450,26 +448,30 @@ public: | @@ -450,26 +448,30 @@ public: | ||
450 | std::cout<<"ERROR: left bound or right bound out of bandwidth"<<std::endl; | 448 | std::cout<<"ERROR: left bound or right bound out of bandwidth"<<std::endl; |
451 | exit(1); | 449 | exit(1); |
452 | } | 450 | } |
453 | - //to make sure rigth bound is bigger than left bound | 451 | + //to make sure right bound is bigger than left bound |
454 | else if(lb > rb){ | 452 | else if(lb > rb){ |
455 | std::cout<<"ERROR: right bound should be bigger than left bound"<<std::endl; | 453 | std::cout<<"ERROR: right bound should be bigger than left bound"<<std::endl; |
456 | exit(1); | 454 | exit(1); |
457 | } | 455 | } |
458 | 456 | ||
459 | - //get the position of lb and rb | ||
460 | - while (lab >= w[ai]){ | 457 | + //find the indices of the left and right baseline points |
458 | + while (lab >= w[ai]){ | ||
461 | ai++; | 459 | ai++; |
462 | } | 460 | } |
463 | while (rab <= w[bi]){ | 461 | while (rab <= w[bi]){ |
464 | bi--; | 462 | bi--; |
465 | } | 463 | } |
466 | 464 | ||
467 | - band(lp, lb); | 465 | + band(lp, lb); //get the band images for the left and right baseline points |
468 | band(rp, rb); | 466 | band(rp, rb); |
469 | 467 | ||
470 | - //calculate the beginning and the ending part | ||
471 | - baseline_band(lb, rb, lp, rp, rab, cur2); //ending part | ||
472 | - baseline_band(lb, rb, lp, rp, w[bi], cur); | 468 | + // calculate the average value of the indexed region |
469 | + memset(result, 0, S); //initialize the integral to zero (0) | ||
470 | + | ||
471 | + //integrate the region between the specified bands and the closest indexed band | ||
472 | + // this integrates the "tails" of the spectrum that lie outside the main indexed region | ||
473 | + baseline_band(lb, rb, lp, rp, rab, cur2); //calculate the image for the right-most band in the integral | ||
474 | + baseline_band(lb, rb, lp, rp, w[bi], cur); //calculate the image for the right-most indexed band | ||
473 | for(unsigned long long j = 0; j < XY; j++){ | 475 | for(unsigned long long j = 0; j < XY; j++){ |
474 | result[j] += (T)((rab - w[bi]) * ((double)cur[j] + (double)cur2[j]) / 2.0); | 476 | result[j] += (T)((rab - w[bi]) * ((double)cur[j] + (double)cur2[j]) / 2.0); |
475 | } | 477 | } |
@@ -479,13 +481,12 @@ public: | @@ -479,13 +481,12 @@ public: | ||
479 | result[j] += (T)((w[ai] - lab) * ((double)cur[j] + (double)cur2[j]) / 2.0); | 481 | result[j] += (T)((w[ai] - lab) * ((double)cur[j] + (double)cur2[j]) / 2.0); |
480 | } | 482 | } |
481 | 483 | ||
482 | - //calculate the area | 484 | + //integrate the main indexed region |
483 | ai++; | 485 | ai++; |
484 | - for(unsigned long long i = ai; i <= bi ;i++) | 486 | + for(unsigned long long i = ai; i <= bi ;i++) //for each band in the integral |
485 | { | 487 | { |
486 | - baseline_band(lb, rb, lp, rp, w[ai], cur2); | ||
487 | - for(unsigned long long j = 0; j < XY; j++) | ||
488 | - { | 488 | + baseline_band(lb, rb, lp, rp, w[ai], cur2); //get the baselined band |
489 | + for(unsigned long long j = 0; j < XY; j++){ //for each pixel in that band | ||
489 | result[j] += (T)((w[ai] - w[ai-1]) * ((double)cur[j] + (double)cur2[j]) / 2.0); | 490 | result[j] += (T)((w[ai] - w[ai-1]) * ((double)cur[j] + (double)cur2[j]) / 2.0); |
490 | } | 491 | } |
491 | std::swap(cur,cur2); //swap the band pointers | 492 | std::swap(cur,cur2); //swap the band pointers |
@@ -507,20 +508,22 @@ public: | @@ -507,20 +508,22 @@ public: | ||
507 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) | 508 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
508 | /// @param pos2 is the label value for the second peak (denominator) position | 509 | /// @param pos2 is the label value for the second peak (denominator) position |
509 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 510 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
510 | - bool ph_to_ph(double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, T * result){ | 511 | + bool ph_to_ph(T* result, double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, unsigned char* mask = NULL){ |
511 | 512 | ||
512 | - T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | ||
513 | - T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | 513 | + size_t XYbytes = X() * Y() * sizeof(T); //calculate the size of the band image (in bytes) |
514 | + | ||
515 | + T* p1 = (T*)malloc(XYbytes); //allocate space for both bands in the ratio | ||
516 | + T* p2 = (T*)malloc(XYbytes); | ||
514 | 517 | ||
518 | + memset(result, 0, XYbytes); //initialize the ratio to zero | ||
515 | //get the two peak band | 519 | //get the two peak band |
516 | height(lb1, rb1, pos1, p1); | 520 | height(lb1, rb1, pos1, p1); |
517 | height(lb2, rb2, pos2, p2); | 521 | height(lb2, rb2, pos2, p2); |
518 | //calculate the ratio in result | 522 | //calculate the ratio in result |
519 | for(unsigned long long i = 0; i < X() * Y(); i++){ | 523 | for(unsigned long long i = 0; i < X() * Y(); i++){ |
520 | - if(p1[i] == 0 && p2[i] ==0) | ||
521 | - result[i] = 1; | ||
522 | - else | 524 | + if(mask == NULL || mask[i]){ |
523 | result[i] = p1[i] / p2[i]; | 525 | result[i] = p1[i] / p2[i]; |
526 | + } | ||
524 | } | 527 | } |
525 | 528 | ||
526 | free(p1); | 529 | free(p1); |
@@ -537,20 +540,20 @@ public: | @@ -537,20 +540,20 @@ public: | ||
537 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) | 540 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
538 | /// @param pos2 is the label value for the second peak (denominator) position | 541 | /// @param pos2 is the label value for the second peak (denominator) position |
539 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 542 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
540 | - bool pa_to_ph(double lb1, double rb1, double lab1, double rab1, | ||
541 | - double lb2, double rb2, double pos, T* result){ | 543 | + bool pa_to_ph(T* result, double lb1, double rb1, double lab1, double rab1, |
544 | + double lb2, double rb2, double pos, unsigned char* mask = NULL){ | ||
542 | 545 | ||
543 | - T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | ||
544 | - T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | 546 | + size_t bytes = X() * Y() * sizeof(T); |
547 | + T* p1 = (T*)malloc(bytes); //allocate space for both ratio components | ||
548 | + T* p2 = (T*)malloc(bytes); | ||
545 | 549 | ||
550 | + memset(result, 0, bytes); //initialize the ratio to zero | ||
546 | //get the area and the peak band | 551 | //get the area and the peak band |
547 | area(lb1, rb1, lab1, rab1, p1); | 552 | area(lb1, rb1, lab1, rab1, p1); |
548 | height(lb2, rb2, pos, p2); | 553 | height(lb2, rb2, pos, p2); |
549 | //calculate the ratio in result | 554 | //calculate the ratio in result |
550 | for(unsigned long long i = 0; i < X() * Y(); i++){ | 555 | for(unsigned long long i = 0; i < X() * Y(); i++){ |
551 | - if(p1[i] == 0 && p2[i] ==0) | ||
552 | - result[i] = 1; | ||
553 | - else | 556 | + if(mask == NULL || mask[i]) |
554 | result[i] = p1[i] / p2[i]; | 557 | result[i] = p1[i] / p2[i]; |
555 | } | 558 | } |
556 | 559 | ||
@@ -570,21 +573,21 @@ public: | @@ -570,21 +573,21 @@ public: | ||
570 | /// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator) | 573 | /// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator) |
571 | /// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator) | 574 | /// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator) |
572 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 575 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
573 | - bool pa_to_pa(double lb1, double rb1, double lab1, double rab1, | ||
574 | - double lb2, double rb2, double lab2, double rab2, T* result){ | 576 | + bool pa_to_pa(T* result, double lb1, double rb1, double lab1, double rab1, |
577 | + double lb2, double rb2, double lab2, double rab2, unsigned char* mask = NULL){ | ||
575 | 578 | ||
576 | - T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | ||
577 | - T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | 579 | + size_t bytes = X() * Y() * sizeof(T); |
580 | + T* p1 = (T*)malloc(bytes); //allocate space for each of the operands | ||
581 | + T* p2 = (T*)malloc(bytes); | ||
578 | 582 | ||
583 | + memset(result, 0, bytes); //initialize the ratio result to zero (0) | ||
579 | //get the area and the peak band | 584 | //get the area and the peak band |
580 | area(lb1, rb1, lab1, rab1, p1); | 585 | area(lb1, rb1, lab1, rab1, p1); |
581 | area(lb2, rb2, lab2, rab2, p2); | 586 | area(lb2, rb2, lab2, rab2, p2); |
582 | //calculate the ratio in result | 587 | //calculate the ratio in result |
583 | for(unsigned long long i = 0; i < X() * Y(); i++){ | 588 | for(unsigned long long i = 0; i < X() * Y(); i++){ |
584 | - if(p1[i] == 0 && p2[i] ==0) | ||
585 | - result[i] = 1; | ||
586 | - else | ||
587 | - result[i] = p1[i] / p2[i]; | 589 | + if(mask == NULL || mask[i]) //if the pixel is masked |
590 | + result[i] = p1[i] / p2[i]; //calculate the ratio | ||
588 | } | 591 | } |
589 | 592 | ||
590 | free(p1); | 593 | free(p1); |
@@ -592,7 +595,7 @@ public: | @@ -592,7 +595,7 @@ public: | ||
592 | return true; | 595 | return true; |
593 | } | 596 | } |
594 | 597 | ||
595 | - /// Compute the definite integral of a baseline corrected peak. | 598 | + /// Compute the definite integral of a baseline corrected peak weighted by the corresponding wavelength |
596 | 599 | ||
597 | /// @param lb is the label value for the left baseline point | 600 | /// @param lb is the label value for the left baseline point |
598 | /// @param rb is the label value for the right baseline point | 601 | /// @param rb is the label value for the right baseline point |
@@ -613,8 +616,6 @@ public: | @@ -613,8 +616,6 @@ public: | ||
613 | cur = (T*) malloc(S); | 616 | cur = (T*) malloc(S); |
614 | cur2 = (T*) malloc(S); | 617 | cur2 = (T*) malloc(S); |
615 | 618 | ||
616 | - memset(result, (char)0, S); | ||
617 | - | ||
618 | //find the wavelenght position in the whole band | 619 | //find the wavelenght position in the whole band |
619 | unsigned long long n = w.size(); | 620 | unsigned long long n = w.size(); |
620 | unsigned long long ai = 0; //left bound position | 621 | unsigned long long ai = 0; //left bound position |
@@ -642,6 +643,8 @@ public: | @@ -642,6 +643,8 @@ public: | ||
642 | band(lp, lb); | 643 | band(lp, lb); |
643 | band(rp, rb); | 644 | band(rp, rb); |
644 | 645 | ||
646 | + memset(result, (char)0, S); //initialize the integral to zero (0) | ||
647 | + | ||
645 | //calculate the beginning and the ending part | 648 | //calculate the beginning and the ending part |
646 | baseline_band(lb, rb, lp, rp, rab, cur2); //ending part | 649 | baseline_band(lb, rb, lp, rp, rab, cur2); //ending part |
647 | baseline_band(lb, rb, lp, rp, w[bi], cur); | 650 | baseline_band(lb, rb, lp, rp, w[bi], cur); |
@@ -656,12 +659,11 @@ public: | @@ -656,12 +659,11 @@ public: | ||
656 | 659 | ||
657 | //calculate f(x) times x | 660 | //calculate f(x) times x |
658 | ai++; | 661 | ai++; |
659 | - for(unsigned long long i = ai; i <= bi ;i++) | ||
660 | - { | 662 | + for(unsigned long long i = ai; i <= bi ;i++){ |
661 | baseline_band(lb, rb, lp, rp, w[ai], cur2); | 663 | baseline_band(lb, rb, lp, rp, w[ai], cur2); |
662 | - for(unsigned long long j = 0; j < XY; j++) | ||
663 | - { | ||
664 | - result[j] += (T)((w[ai] - w[ai-1]) * (w[ai] + w[ai-1]) * ((double)cur[j] + (double)cur2[j]) / 4.0); | 664 | + for(unsigned long long j = 0; j < XY; j++){ |
665 | + T v = (T)((w[ai] - w[ai-1]) * (w[ai] + w[ai-1]) * ((double)cur[j] + (double)cur2[j]) / 4.0); | ||
666 | + result[j] += v; | ||
665 | } | 667 | } |
666 | std::swap(cur,cur2); //swap the band pointers | 668 | std::swap(cur,cur2); //swap the band pointers |
667 | } | 669 | } |
@@ -674,25 +676,27 @@ public: | @@ -674,25 +676,27 @@ public: | ||
674 | } | 676 | } |
675 | 677 | ||
676 | /// Compute the centroid of a baseline corrected peak. | 678 | /// Compute the centroid of a baseline corrected peak. |
679 | + /// Note that the values for the centroid can be outside of [lab, rab] if the spectrum goes negative. | ||
677 | 680 | ||
678 | /// @param lb is the label value for the left baseline point | 681 | /// @param lb is the label value for the left baseline point |
679 | /// @param rb is the label value for the right baseline point | 682 | /// @param rb is the label value for the right baseline point |
680 | /// @param lab is the label for the start of the peak | 683 | /// @param lab is the label for the start of the peak |
681 | /// @param rab is the label for the end of the peak | 684 | /// @param rab is the label for the end of the peak |
682 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 685 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
683 | - bool cpoint(double lb, double rb, double lab, double rab, T* result){ | ||
684 | - T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | 686 | + bool centroid(T* result, double lb, double rb, double lab, double rab, unsigned char* mask = NULL){ |
687 | + size_t bytes = X() * Y() * sizeof(T); //calculate the number of bytes in a band image | ||
688 | + T* p1 = (T*)malloc(X() * Y() * sizeof(T)); //allocate space for both operands | ||
685 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | 689 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
686 | 690 | ||
691 | + memset(result, 0, bytes); //initialize the ratio result to zero (0) | ||
687 | //get the area and the peak band | 692 | //get the area and the peak band |
688 | x_area(lb, rb, lab, rab, p1); | 693 | x_area(lb, rb, lab, rab, p1); |
689 | area(lb, rb, lab, rab, p2); | 694 | area(lb, rb, lab, rab, p2); |
690 | //calculate the ratio in result | 695 | //calculate the ratio in result |
691 | for(unsigned long long i = 0; i < X() * Y(); i++){ | 696 | for(unsigned long long i = 0; i < X() * Y(); i++){ |
692 | - if(p1[i] == 0 && p2[i] ==0) | ||
693 | - result[i] = 1; | ||
694 | - else | 697 | + if(mask == NULL || mask[i]){ |
695 | result[i] = p1[i] / p2[i]; | 698 | result[i] = p1[i] / p2[i]; |
699 | + } | ||
696 | } | 700 | } |
697 | 701 | ||
698 | free(p1); | 702 | free(p1); |
@@ -707,16 +711,16 @@ public: | @@ -707,16 +711,16 @@ public: | ||
707 | /// @param mask_band is the band used to specify the mask | 711 | /// @param mask_band is the band used to specify the mask |
708 | /// @param threshold is the threshold used to determine if the mask value is true or false | 712 | /// @param threshold is the threshold used to determine if the mask value is true or false |
709 | /// @param p is a pointer to a pre-allocated array at least X * Y in size | 713 | /// @param p is a pointer to a pre-allocated array at least X * Y in size |
710 | - bool build_mask(double mask_band, double threshold, unsigned char* p = NULL, bool PROGRESS = false){ | 714 | + bool build_mask(unsigned char* mask, double mask_band, double threshold, bool PROGRESS = false){ |
711 | 715 | ||
712 | T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band | 716 | T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band |
713 | band(temp, mask_band); | 717 | band(temp, mask_band); |
714 | 718 | ||
715 | for (unsigned long long i = 0; i < X() * Y(); i++) { | 719 | for (unsigned long long i = 0; i < X() * Y(); i++) { |
716 | if (temp[i] < threshold) | 720 | if (temp[i] < threshold) |
717 | - p[i] = 0; | 721 | + mask[i] = 0; |
718 | else | 722 | else |
719 | - p[i] = 255; | 723 | + mask[i] = 255; |
720 | 724 | ||
721 | if(PROGRESS) progress = (double) (i+1) / (X() * Y()) * 100; | 725 | if(PROGRESS) progress = (double) (i+1) / (X() * Y()) * 100; |
722 | } | 726 | } |
stim/envi/envi.h
@@ -475,31 +475,31 @@ public: | @@ -475,31 +475,31 @@ public: | ||
475 | /// @param mask_band is the label for the band that will be used to build the mask | 475 | /// @param mask_band is the label for the band that will be used to build the mask |
476 | /// @param threshold is a value selected such that all band values greater than threshold will have a mask value of 'true' | 476 | /// @param threshold is a value selected such that all band values greater than threshold will have a mask value of 'true' |
477 | /// @param p is memory of size X*Y that will store the resulting mask | 477 | /// @param p is memory of size X*Y that will store the resulting mask |
478 | - bool build_mask(double mask_band, double threshold, unsigned char* p = NULL, bool PROGRESS = false) { | 478 | + bool build_mask(unsigned char* mask, double mask_band, double threshold, bool PROGRESS = false) { |
479 | 479 | ||
480 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 480 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
481 | if(header.data_type ==envi_header::float32) | 481 | if(header.data_type ==envi_header::float32) |
482 | - return ((bsq<float>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | 482 | + return ((bsq<float>*)file)->build_mask(mask, mask_band, threshold, PROGRESS); |
483 | else if(header.data_type == envi_header::float64) | 483 | else if(header.data_type == envi_header::float64) |
484 | - return ((bsq<double>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | 484 | + return ((bsq<double>*)file)->build_mask(mask, mask_band, threshold, PROGRESS); |
485 | else | 485 | else |
486 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 486 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
487 | } | 487 | } |
488 | 488 | ||
489 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file | 489 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
490 | if(header.data_type ==envi_header::float32) | 490 | if(header.data_type ==envi_header::float32) |
491 | - return ((bil<float>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | 491 | + return ((bil<float>*)file)->build_mask(mask, mask_band, threshold, PROGRESS); |
492 | else if(header.data_type == envi_header::float64) | 492 | else if(header.data_type == envi_header::float64) |
493 | - return ((bil<double>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | 493 | + return ((bil<double>*)file)->build_mask(mask, mask_band, threshold, PROGRESS); |
494 | else | 494 | else |
495 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 495 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
496 | } | 496 | } |
497 | 497 | ||
498 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file | 498 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
499 | if(header.data_type ==envi_header::float32) | 499 | if(header.data_type ==envi_header::float32) |
500 | - return ((bip<float>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | 500 | + return ((bip<float>*)file)->build_mask(mask, mask_band, threshold, PROGRESS); |
501 | else if(header.data_type == envi_header::float64) | 501 | else if(header.data_type == envi_header::float64) |
502 | - return ((bip<double>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | 502 | + return ((bip<double>*)file)->build_mask(mask, mask_band, threshold, PROGRESS); |
503 | else | 503 | else |
504 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 504 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
505 | } | 505 | } |
@@ -507,6 +507,36 @@ public: | @@ -507,6 +507,36 @@ public: | ||
507 | return false; | 507 | return false; |
508 | } | 508 | } |
509 | 509 | ||
510 | + /// Creates a mask with a true value for all pixels that contain finite values | ||
511 | + void mask_finite(unsigned char* mask, bool PROGRESS = false){ | ||
512 | + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | ||
513 | + if(header.data_type ==envi_header::float32) | ||
514 | + ((bsq<float>*)file)->mask_finite(mask, PROGRESS); | ||
515 | + else if(header.data_type == envi_header::float64) | ||
516 | + ((bsq<double>*)file)->mask_finite(mask, PROGRESS); | ||
517 | + else | ||
518 | + std::cout<<"ERROR: unidentified data type"<<std::endl; | ||
519 | + } | ||
520 | + | ||
521 | + else if(header.interleave == envi_header::BIL){ //if the infile is bil file | ||
522 | + if(header.data_type ==envi_header::float32) | ||
523 | + ((bil<float>*)file)->mask_finite(mask, PROGRESS); | ||
524 | + else if(header.data_type == envi_header::float64) | ||
525 | + ((bil<double>*)file)->mask_finite(mask, PROGRESS); | ||
526 | + else | ||
527 | + std::cout<<"ERROR: unidentified data type"<<std::endl; | ||
528 | + } | ||
529 | + | ||
530 | + else if(header.interleave == envi_header::BIP){ //if the infile is bip file | ||
531 | + if(header.data_type ==envi_header::float32) | ||
532 | + ((bip<float>*)file)->mask_finite(mask, PROGRESS); | ||
533 | + else if(header.data_type == envi_header::float64) | ||
534 | + ((bip<double>*)file)->mask_finite(mask, PROGRESS); | ||
535 | + else | ||
536 | + std::cout<<"ERROR: unidentified data type"<<std::endl; | ||
537 | + } | ||
538 | + } | ||
539 | + | ||
510 | /// Applies a mask to the ENVI file. | 540 | /// Applies a mask to the ENVI file. |
511 | 541 | ||
512 | /// @param outfile is the name of the resulting masked output file | 542 | /// @param outfile is the name of the resulting masked output file |
@@ -560,17 +590,31 @@ public: | @@ -560,17 +590,31 @@ public: | ||
560 | return ((bsq<float>*)file)->sift((float*)matrix, p); | 590 | return ((bsq<float>*)file)->sift((float*)matrix, p); |
561 | else if (header.data_type == envi_header::float64) | 591 | else if (header.data_type == envi_header::float64) |
562 | return ((bsq<double>*)file)->sift((double*)matrix, p); | 592 | return ((bsq<double>*)file)->sift((double*)matrix, p); |
563 | - else | 593 | + else{ |
564 | std::cout << "ERROR: unidentified data type" << std::endl; | 594 | std::cout << "ERROR: unidentified data type" << std::endl; |
595 | + exit(1); | ||
596 | + } | ||
565 | } | 597 | } |
566 | 598 | ||
567 | if (header.interleave == envi_header::BIP){ | 599 | if (header.interleave == envi_header::BIP){ |
568 | - std::cout<<"Memory sifting not supported for BIP files"<<std::endl; | ||
569 | - exit(1); | 600 | + if (header.data_type == envi_header::float32) |
601 | + return ((bip<float>*)file)->sift((float*)matrix, p); | ||
602 | + else if (header.data_type == envi_header::float64) | ||
603 | + return ((bip<double>*)file)->sift((double*)matrix, p); | ||
604 | + else{ | ||
605 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
606 | + exit(1); | ||
607 | + } | ||
570 | } | 608 | } |
571 | if (header.interleave == envi_header::BIL){ | 609 | if (header.interleave == envi_header::BIL){ |
572 | - std::cout<<"Memory sifting not supported for BIL files"<<std::endl; | ||
573 | - exit(1); | 610 | + if (header.data_type == envi_header::float32) |
611 | + return ((bil<float>*)file)->sift((float*)matrix, p); | ||
612 | + else if (header.data_type == envi_header::float64) | ||
613 | + return ((bil<double>*)file)->sift((double*)matrix, p); | ||
614 | + else{ | ||
615 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
616 | + exit(1); | ||
617 | + } | ||
574 | } | 618 | } |
575 | return false; | 619 | return false; |
576 | 620 | ||
@@ -684,30 +728,30 @@ public: | @@ -684,30 +728,30 @@ public: | ||
684 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) | 728 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
685 | /// @param pos2 is the label value for the second peak (denominator) position | 729 | /// @param pos2 is the label value for the second peak (denominator) position |
686 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 730 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
687 | - bool ph_to_ph(double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, void * result){ | 731 | + bool ph_to_ph(void * result, double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, unsigned char* mask){ |
688 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 732 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
689 | if(header.data_type ==envi_header::float32) | 733 | if(header.data_type ==envi_header::float32) |
690 | - return ((bsq<float>*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (float*)result); | 734 | + return ((bsq<float>*)file)->ph_to_ph((float*)result, lb1, rb1, pos1, lb2, rb2, pos2, mask); |
691 | else if(header.data_type == envi_header::float64) | 735 | else if(header.data_type == envi_header::float64) |
692 | - return ((bsq<double>*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (double*)result); | 736 | + return ((bsq<double>*)file)->ph_to_ph((double*)result, lb1, rb1, pos1, lb2, rb2, pos2, mask); |
693 | else | 737 | else |
694 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 738 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
695 | } | 739 | } |
696 | 740 | ||
697 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file | 741 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
698 | if(header.data_type ==envi_header::float32) | 742 | if(header.data_type ==envi_header::float32) |
699 | - return ((bil<float>*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (float*)result); | 743 | + return ((bil<float>*)file)->ph_to_ph((float*)result, lb1, rb1, pos1, lb2, rb2, pos2, mask); |
700 | else if(header.data_type == envi_header::float64) | 744 | else if(header.data_type == envi_header::float64) |
701 | - return ((bil<double>*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (double*)result); | 745 | + return ((bil<double>*)file)->ph_to_ph((double*)result, lb1, rb1, pos1, lb2, rb2, pos2, mask); |
702 | else | 746 | else |
703 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 747 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
704 | } | 748 | } |
705 | 749 | ||
706 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file | 750 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
707 | if(header.data_type ==envi_header::float32) | 751 | if(header.data_type ==envi_header::float32) |
708 | - return ((bip<float>*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (float*)result); | 752 | + return ((bip<float>*)file)->ph_to_ph((float*)result, lb1, rb1, pos1, lb2, rb2, pos2, mask); |
709 | else if(header.data_type == envi_header::float64) | 753 | else if(header.data_type == envi_header::float64) |
710 | - return ((bip<double>*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (double*)result); | 754 | + return ((bip<double>*)file)->ph_to_ph((double*)result, lb1, rb1, pos1, lb2, rb2, pos2, mask); |
711 | else | 755 | else |
712 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 756 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
713 | } | 757 | } |
@@ -728,30 +772,30 @@ public: | @@ -728,30 +772,30 @@ public: | ||
728 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) | 772 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
729 | /// @param pos2 is the label value for the second peak (denominator) position | 773 | /// @param pos2 is the label value for the second peak (denominator) position |
730 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 774 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
731 | - bool pa_to_ph(double lb1, double rb1, double lab1, double rab1, double lb2, double rb2, double pos, void * result){ | 775 | + bool pa_to_ph(void* result, double lb1, double rb1, double lab1, double rab1, double lb2, double rb2, double pos, unsigned char* mask = NULL){ |
732 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 776 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
733 | if(header.data_type ==envi_header::float32) | 777 | if(header.data_type ==envi_header::float32) |
734 | - return ((bsq<float>*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (float*)result); | 778 | + return ((bsq<float>*)file)->pa_to_ph((float*)result, lb1, rb1, lab1, rab1, lb2, rb2, pos, mask); |
735 | else if(header.data_type == envi_header::float64) | 779 | else if(header.data_type == envi_header::float64) |
736 | - return ((bsq<double>*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (double*)result); | 780 | + return ((bsq<double>*)file)->pa_to_ph((double*)result, lb1, rb1, lab1, rab1, lb2, rb2, pos, mask); |
737 | else | 781 | else |
738 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 782 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
739 | } | 783 | } |
740 | 784 | ||
741 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file | 785 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
742 | if(header.data_type ==envi_header::float32) | 786 | if(header.data_type ==envi_header::float32) |
743 | - return ((bil<float>*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (float*)result); | 787 | + return ((bil<float>*)file)->pa_to_ph((float*)result, lb1, rb1, lab1, rab1, lb2, rb2, pos, mask); |
744 | else if(header.data_type == envi_header::float64) | 788 | else if(header.data_type == envi_header::float64) |
745 | - return ((bil<double>*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (double*)result); | 789 | + return ((bil<double>*)file)->pa_to_ph((double*)result, lb1, rb1, lab1, rab1, lb2, rb2, pos, mask); |
746 | else | 790 | else |
747 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 791 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
748 | } | 792 | } |
749 | 793 | ||
750 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file | 794 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
751 | if(header.data_type ==envi_header::float32) | 795 | if(header.data_type ==envi_header::float32) |
752 | - return ((bip<float>*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (float*)result); | 796 | + return ((bip<float>*)file)->pa_to_ph((float*)result, lb1, rb1, lab1, rab1, lb2, rb2, pos, mask); |
753 | else if(header.data_type == envi_header::float64) | 797 | else if(header.data_type == envi_header::float64) |
754 | - return ((bip<double>*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (double*)result); | 798 | + return ((bip<double>*)file)->pa_to_ph((double*)result, lb1, rb1, lab1, rab1, lb2, rb2, pos, mask); |
755 | else | 799 | else |
756 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 800 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
757 | } | 801 | } |
@@ -774,31 +818,31 @@ public: | @@ -774,31 +818,31 @@ public: | ||
774 | /// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator) | 818 | /// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator) |
775 | /// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator) | 819 | /// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator) |
776 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 820 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
777 | - bool pa_to_pa(double lb1, double rb1, double lab1, double rab1, | ||
778 | - double lb2, double rb2, double lab2, double rab2, void* result){ | 821 | + bool pa_to_pa(void* result, double lb1, double rb1, double lab1, double rab1, |
822 | + double lb2, double rb2, double lab2, double rab2, unsigned char* mask = NULL){ | ||
779 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 823 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
780 | if(header.data_type ==envi_header::float32) | 824 | if(header.data_type ==envi_header::float32) |
781 | - return ((bsq<float>*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (float*)result); | 825 | + return ((bsq<float>*)file)->pa_to_pa((float*)result, lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, mask); |
782 | else if(header.data_type == envi_header::float64) | 826 | else if(header.data_type == envi_header::float64) |
783 | - return ((bsq<double>*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (double*)result); | 827 | + return ((bsq<double>*)file)->pa_to_pa((double*)result, lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, mask); |
784 | else | 828 | else |
785 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 829 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
786 | } | 830 | } |
787 | 831 | ||
788 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file | 832 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
789 | if(header.data_type ==envi_header::float32) | 833 | if(header.data_type ==envi_header::float32) |
790 | - return ((bil<float>*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (float*)result); | 834 | + return ((bil<float>*)file)->pa_to_pa((float*)result, lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, mask); |
791 | else if(header.data_type == envi_header::float64) | 835 | else if(header.data_type == envi_header::float64) |
792 | - return ((bil<double>*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (double*)result); | 836 | + return ((bil<double>*)file)->pa_to_pa((double*)result, lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, mask); |
793 | else | 837 | else |
794 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 838 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
795 | } | 839 | } |
796 | 840 | ||
797 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file | 841 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
798 | if(header.data_type ==envi_header::float32) | 842 | if(header.data_type ==envi_header::float32) |
799 | - return ((bip<float>*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (float*)result); | 843 | + return ((bip<float>*)file)->pa_to_pa((float*)result, lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, mask); |
800 | else if(header.data_type == envi_header::float64) | 844 | else if(header.data_type == envi_header::float64) |
801 | - return ((bip<double>*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (double*)result); | 845 | + return ((bip<double>*)file)->pa_to_pa((double*)result, lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, mask); |
802 | else | 846 | else |
803 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 847 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
804 | } | 848 | } |
@@ -817,30 +861,30 @@ public: | @@ -817,30 +861,30 @@ public: | ||
817 | /// @param lab is the label for the start of the peak | 861 | /// @param lab is the label for the start of the peak |
818 | /// @param rab is the label for the end of the peak | 862 | /// @param rab is the label for the end of the peak |
819 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size | 863 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
820 | - bool cpoint(double lb1, double rb1, double lab1, double rab1, void* result){ | 864 | + bool centroid(void* result, double lb1, double rb1, double lab1, double rab1, unsigned char* mask = NULL){ |
821 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | 865 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
822 | if(header.data_type ==envi_header::float32) | 866 | if(header.data_type ==envi_header::float32) |
823 | - return ((bsq<float>*)file)->cpoint(lb1, rb1, lab1, rab1, (float*)result); | 867 | + return ((bsq<float>*)file)->centroid((float*)result, lb1, rb1, lab1, rab1, mask); |
824 | else if(header.data_type == envi_header::float64) | 868 | else if(header.data_type == envi_header::float64) |
825 | - return ((bsq<double>*)file)->cpoint(lb1, rb1, lab1, rab1, (double*)result); | 869 | + return ((bsq<double>*)file)->centroid((double*)result, lb1, rb1, lab1, rab1, mask); |
826 | else | 870 | else |
827 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 871 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
828 | } | 872 | } |
829 | 873 | ||
830 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file | 874 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
831 | if(header.data_type ==envi_header::float32) | 875 | if(header.data_type ==envi_header::float32) |
832 | - return ((bil<float>*)file)->cpoint(lb1, rb1, lab1, rab1, (float*)result); | 876 | + return ((bil<float>*)file)->centroid((float*)result, lb1, rb1, lab1, rab1, mask); |
833 | else if(header.data_type == envi_header::float64) | 877 | else if(header.data_type == envi_header::float64) |
834 | - return ((bil<double>*)file)->cpoint(lb1, rb1, lab1, rab1, (double*)result); | 878 | + return ((bil<double>*)file)->centroid((double*)result, lb1, rb1, lab1, rab1, mask); |
835 | else | 879 | else |
836 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 880 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
837 | } | 881 | } |
838 | 882 | ||
839 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file | 883 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
840 | if(header.data_type ==envi_header::float32) | 884 | if(header.data_type ==envi_header::float32) |
841 | - return ((bip<float>*)file)->cpoint(lb1, rb1, lab1, rab1,(float*)result); | 885 | + return ((bip<float>*)file)->centroid((float*)result, lb1, rb1, lab1, rab1, mask); |
842 | else if(header.data_type == envi_header::float64) | 886 | else if(header.data_type == envi_header::float64) |
843 | - return ((bip<double>*)file)->cpoint(lb1, rb1, lab1, rab1, (double*)result); | 887 | + return ((bip<double>*)file)->centroid((double*)result, lb1, rb1, lab1, rab1, mask); |
844 | else | 888 | else |
845 | std::cout<<"ERROR: unidentified data type"<<std::endl; | 889 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
846 | } | 890 | } |
stim/envi/hsi.h
@@ -6,6 +6,12 @@ | @@ -6,6 +6,12 @@ | ||
6 | #include <cstring> | 6 | #include <cstring> |
7 | #include <utility> | 7 | #include <utility> |
8 | 8 | ||
9 | +#ifdef _WIN32 | ||
10 | + #include <float.h> | ||
11 | +#else | ||
12 | + #include<cmath> | ||
13 | +#endif | ||
14 | + | ||
9 | namespace stim{ | 15 | namespace stim{ |
10 | 16 | ||
11 | /** | 17 | /** |
@@ -113,6 +119,46 @@ protected: | @@ -113,6 +119,46 @@ protected: | ||
113 | 119 | ||
114 | return c[2] * R[0] * R[1] + c[1] * R[0] + c[0]; //calculate and return the index (trust me this works) | 120 | return c[2] * R[0] * R[1] + c[1] * R[0] + c[0]; //calculate and return the index (trust me this works) |
115 | } | 121 | } |
122 | + | ||
123 | + /// Returns the 3D coordinates of a specified index | ||
124 | + void xyb(size_t idx, size_t& x, size_t& y, size_t& b){ | ||
125 | + | ||
126 | + size_t c[3]; | ||
127 | + | ||
128 | + c[2] = idx / (R[0] * R[1]); | ||
129 | + c[1] = (idx - c[2] * R[0] * R[1]) / R[0]; | ||
130 | + c[0] = idx - c[2] * R[0] * R[1] - c[1] * R[0]; | ||
131 | + | ||
132 | + x = c[O[0]]; | ||
133 | + y = c[O[1]]; | ||
134 | + b = c[O[2]]; | ||
135 | + } | ||
136 | + | ||
137 | +public: | ||
138 | + /// Get a mask that has all pixels with inf or NaN values masked out (false) | ||
139 | + void mask_finite(unsigned char* mask, bool PROGRESS = false){ | ||
140 | + size_t XY = X() * Y(); | ||
141 | + memset(mask, 255, XY * sizeof(unsigned char)); //initialize the mask to zero (0) | ||
142 | + T* page = (T*)malloc(R[0] * R[1] * sizeof(T)); //allocate space for a page of data | ||
143 | + | ||
144 | + for(size_t p = 0; p < R[2]; p++){ //for each page | ||
145 | + binary<T>::read_page(page, p); //read a page | ||
146 | + for(size_t i = 0; i < R[0] * R[1]; i++){ //for each pixel in that page | ||
147 | + | ||
148 | +#ifdef _WIN32 | ||
149 | + if(!_finite(page[i])){ //if the value at index i is finite | ||
150 | +#else | ||
151 | + if(!std::isfinite(page[i])){ //C++11 implementation | ||
152 | +#endif | ||
153 | + size_t x, y, b; | ||
154 | + xyb(p * R[0] * R[1] + i, x, y, b); //find the 3D coordinates of the value | ||
155 | + mask[ y * X() + x ] = 0; //mask the pixel (it's not bad) | ||
156 | + } | ||
157 | + } | ||
158 | + if(PROGRESS) progress = (double)(p + 1) / (double)R[2] * 100; | ||
159 | + } | ||
160 | + } | ||
161 | + | ||
116 | }; | 162 | }; |
117 | 163 | ||
118 | } //end namespace STIM | 164 | } //end namespace STIM |
stim/parser/arguments.h
@@ -97,7 +97,7 @@ namespace stim{ | @@ -97,7 +97,7 @@ namespace stim{ | ||
97 | } | 97 | } |
98 | 98 | ||
99 | //return the value of a floating point option | 99 | //return the value of a floating point option |
100 | - float as_float(size_t n = 0) | 100 | + double as_float(size_t n = 0) |
101 | { | 101 | { |
102 | if(!flag) | 102 | if(!flag) |
103 | { | 103 | { |