12#include "IException.h"
15#include "CubeAttribute.h"
17#include "LineManager.h"
19#include "Preference.h"
21#include "SpecialPixel.h"
22#include "Statistics.h"
28int main(
int argc,
char *argv[]) {
29 Preference::Preferences(
true);
32 void Report(
Cube & c);
33 cerr <<
"Unit test for Cube" << endl;
35 cerr <<
"Constructing cube ... " << endl;
40 cerr <<
"Creating 32-bit cube ... " << endl;
42 out.
create(
"$TMP/IsisCube_00");
45 cerr <<
"Write cube ... " << endl;
48 for(line.begin(); !line.end(); line++) {
49 for(
int i = 0; i < line.size(); i++) {
62 cerr <<
"Opening cube ... " << endl;
63 Cube in(
"$TMP/IsisCube_01");
66 cerr <<
"Comparing cube ... " << endl;
69 for(inLine.begin(); !inLine.end(); inLine++) {
71 for(
int i = 0; i < inLine.size(); i++) {
72 if(inLine[i] != (
double) j) {
74 <<
" line " << inLine.Line()
75 <<
" sample " << i + 1
76 <<
" band " << inLine.Band() <<
": "
77 << inLine[i] <<
" != " << double(j) << endl;
88 cerr <<
"Creating 8-bit cube ... " << endl;
98 out2.
create(
"$TMP/IsisCube_02");
102 for(oline.begin(); !oline.end(); oline++) {
103 for(
int i = 0; i < oline.size(); i++) {
104 oline[i] = (double) j;
112 cerr <<
"Comparing cube ... " << endl;
115 in2.
open(
"$TMP/IsisCube_02");
123 for(inLine2.begin(); !inLine2.end(); inLine2++) {
125 for(
int i = 0; i < inLine2.size(); i++) {
126 if(inLine2[i] != (
double) j) {
127 cerr <<
"Problem at line " << inLine2.Line()
128 <<
" sample " << i + 1 <<
": "
129 << inLine2[i] <<
" != " << double(j) << endl;
140 cerr <<
"Creating 16-bit cube ... " << endl;
147 out3.
create(
"$TMP/IsisCube_03");
151 for(oline3.begin(); !oline3.end(); oline3++) {
152 for(
int i = 0; i < oline3.size(); i++) {
153 oline3[i] = (double) j;
160 cerr <<
"Comparing cube ... " << endl;
162 in3.
open(
"$TMP/IsisCube_03");
166 for(inLine3.begin(); !inLine3.end(); inLine3++) {
169 for(
int i = 0; i < inLine3.size(); i++) {
170 if(inLine3[i] != (
double) j) {
171 cerr <<
"Problem at line " << inLine3.Line()
172 <<
" sample " << i + 1 <<
" band " << inLine3.Band() <<
": "
173 << inLine3[i] <<
" != " << double(j) << endl;
182 in.open(
"$TMP/IsisCube_01");
185 cerr <<
"Testing histogram method, band 1 ... " << endl;
187 cerr <<
"Average: " << bandOneHist->
Average() << endl;
189 cerr <<
"Mode: " << bandOneHist->
Mode() << endl;
190 cerr <<
"Total Pixels: " << bandOneHist->
TotalPixels() << endl;
191 cerr <<
"Null Pixels: " << bandOneHist->
NullPixels() << endl;
197 cerr <<
"Testing histogram method, all bands ... " << endl;
198 Histogram *allBandsHistogram = in.histogram(0);
199 cerr <<
"Average: " << allBandsHistogram->
Average() << endl;
201 cerr <<
"Mode: " << allBandsHistogram->
Mode() << endl;
202 cerr <<
"Total Pixels: " << allBandsHistogram->
TotalPixels() << endl;
203 cerr <<
"Null Pixels: " << allBandsHistogram->
NullPixels() << endl;
205 delete allBandsHistogram;
206 allBandsHistogram = NULL;
229 cerr <<
"Testing statistics method, band 1 ... " << endl;
231 cerr <<
"Average: " << bandOneStats->
Average() << endl;
233 cerr <<
"Total Pixels: " << bandOneStats->
TotalPixels() << endl;
234 cerr <<
"Null Pixels: " << bandOneStats->
NullPixels() << endl;
240 cerr <<
"Testing statistics method, all bands ... " << endl;
242 cerr <<
"Average: " << allBandsStats->
Average() << endl;
244 cerr <<
"Total Pixels: " << allBandsStats->
TotalPixels() << endl;
245 cerr <<
"Null Pixels: " << allBandsStats->
NullPixels() << endl;
247 delete allBandsStats;
248 allBandsStats = NULL;
270 cerr <<
"Virtual band tests" << endl;
272 cerr <<
"Nbands = " << in.bandCount() << endl;
273 cerr <<
"Band 1 = " << in.physicalBand(1) << endl;
274 cerr <<
"Band 2 = " << in.physicalBand(2) << endl;
279 vbands.push_back(
"2");
280 in.setVirtualBands(vbands);
281 in.open(
"$TMP/IsisCube_01");
282 cerr <<
"Nbands = " << in.bandCount() << endl;
283 cerr <<
"Band 1 = " << in.physicalBand(1) << endl;
287 cerr <<
"ReOpen tests" << endl;
296 cerr <<
"Testing reading past cube boundaries ... " << endl;
297 cerr <<
"Constructing cube ... " << endl << endl;
298 Cube boundaryTestCube;
300 boundaryTestCube.
create(
"$TMP/IsisCube_boundary");
301 Report(boundaryTestCube);
304 for(boundaryLine.begin(); !boundaryLine.end(); boundaryLine++) {
305 for(
int i = 0; i < boundaryLine.size(); i++) {
306 boundaryLine[i] = 1.0;
308 boundaryTestCube.
write(boundaryLine);
315 cerr <<
"Reading completely within cube boundaries ... " << endl;
317 readBrick.SetBasePosition(1, 1, 1);
318 boundaryTestCube.
read(readBrick);
320 cerr <<
"\tComparing results ... " << endl;
321 for(
int i = 0; i < readBrick.size(); i++) {
322 if (readBrick[i] != 1.0) {
323 cerr <<
"\tNot all values in brick were 1.0." << endl;
328 cerr <<
"Reading completely outside band boundaries ... " << endl;
329 readBrick.SetBasePosition(1, 1, -1);
330 boundaryTestCube.
read(readBrick);
332 cerr <<
"\tComparing results ... " << endl;
333 for(
int i = 0; i < readBrick.size(); i++) {
334 if (readBrick[i] !=
Null) {
335 cerr <<
"\tNot all values in brick were Null." << endl;
342 cerr <<
"Reading partially within band boundaries ... " << endl;
343 cerr <<
"\t Reading bands 0 (should be null) and 1 (should be 1.0)... " << endl;
344 cerr <<
"\t\t Comparing results ... " << endl;
345 readBrick.SetBasePosition(1, 1, 0);
346 boundaryTestCube.
read(readBrick);
348 if (readBrick[0] !=
Null) {
349 cerr <<
"\t\t Value outside cube boundary was not Null." << endl;
352 if (readBrick[1] != 1.0) {
353 cerr <<
"\t\t Value inside cube boundary was not 1.0." << endl;
357 cerr <<
"\t Reading bands 4 (should be 1.0) and 5 (should be null)... " << endl;
358 cerr <<
"\t\t Comparing results ... " << endl;
360 readBrick.SetBasePosition(1, 1, 4);
361 boundaryTestCube.
read(readBrick);
363 if (readBrick[0] != 1.0) {
364 cerr <<
"\t\t Value inside cube boundary was not 1.0." << endl;
367 if (readBrick[1] !=
Null) {
368 cerr <<
"\t\t Value outside cube boundary was not Null." << endl;
373 boundaryTestCube.
close();
376 cerr <<
"Testing reading past cube boundaries with virtual bands (2, 1, 3, 4, 2)... " << endl;
378 virtualBands.push_back(
"2");
379 virtualBands.push_back(
"1");
380 virtualBands.push_back(
"3");
381 virtualBands.push_back(
"4");
382 virtualBands.push_back(
"2");
384 boundaryTestCube.
open(
"$TMP/IsisCube_boundary");
386 cerr <<
"Reading completely outside virtual band boundaries ... " << endl;
387 readBrick.SetBasePosition(1, 1, 6);
388 boundaryTestCube.
read(readBrick);
390 cerr <<
"\tComparing results starting at band 6... " << endl;
391 for(
int i = 0; i < readBrick.size(); i++) {
392 if (readBrick[i] !=
Null) {
393 cerr <<
"\tNot all values in brick (outside cube boundary) were Null. " << i << endl;
398 cerr <<
"\tComparing results starting at band 1000... " << endl;
399 readBrick.SetBasePosition(1, 1, 1000);
400 boundaryTestCube.
read(readBrick);
401 for(
int i = 0; i < readBrick.size(); i++) {
402 if (readBrick[i] !=
Null) {
403 cerr <<
"\tNot all values in brick (outside cube boundary) were Null." << endl;
408 cerr <<
"\tComparing results starting at band -1... " << endl;
409 readBrick.SetBasePosition(1, 1, -1);
410 boundaryTestCube.
read(readBrick);
411 for(
int i = 0; i < readBrick.size(); i++) {
412 if (readBrick[i] !=
Null) {
413 cerr <<
"Not all values in brick (outside cube boundary) were Null. " << endl;
420 cerr <<
"Reading partially within virtual band boundaries ... " << endl;
421 readBrick.SetBasePosition(1, 1, 0);
422 boundaryTestCube.
read(readBrick);
424 cerr <<
"Comparing results ... " << endl;
425 if (readBrick[0] !=
Null) {
426 cerr <<
"Value outside cube boundary (band 0) was not Null." << endl;
429 if (readBrick[1] != 1.0) {
430 cerr <<
"Value inside cube boundary (band 1) was not 1.0." << endl;
435 readBrick.SetBasePosition(1, 1, 5);
436 boundaryTestCube.
read(readBrick);
438 if (readBrick[0] != 1.0) {
439 cerr <<
"Value inside cube boundary (band 5) was not 1.0." << endl;
442 if (readBrick[1] !=
Null) {
443 cerr <<
"Value outside cube boundary (band 6) was not Null." << endl;
450 readBrick.Resize(1, 1, 20);
451 readBrick.SetBasePosition(1, 1, -10);
452 boundaryTestCube.
read(readBrick);
453 for (
int i = 0; i < readBrick.size(); i++) {
454 if (i >= 11 && i <= 15) {
455 if (readBrick[i] != 1.0) {
456 cerr <<
"Value inside cube boundary, at brick band " << i + 1 <<
" was not 1.0." << endl;
461 if (readBrick[i] !=
Null) {
462 cerr <<
"Value outside cube boundary, at brick band " << i + 1
463 <<
" was not Null." << endl;
469 boundaryTestCube.
close();
473 cerr <<
"Testing one line BSQ cube (where chunk dimensions == buffer shape) ... " << endl;
474 cerr <<
"Constructing cube ... " << endl << endl;
475 Cube bsqOneLineTestCube;
478 bsqOneLineTestCube.
create(
"$TMP/IsisCube_bsqOneLine");
479 Report(bsqOneLineTestCube);
485 for (oneLine.begin(); !oneLine.end(); oneLine++) {
486 for (
int i = 0; i < oneLine.size(); i++) {
487 oneLine[i] = 1 * i + oneLine.Band();
489 bsqOneLineTestCube.
write(oneLine);
491 bsqOneLineTestCube.
close();
497 cerr <<
"Testing reading ascending repeating virtual bands (1, 2, 2, 3)... " << endl;
498 virtualBands.clear();
499 virtualBands.push_back(
"1");
500 virtualBands.push_back(
"2");
501 virtualBands.push_back(
"2");
502 virtualBands.push_back(
"3");
504 bsqOneLineTestCube.
open(
"$TMP/IsisCube_bsqOneLine");
505 for (
int sb = 1; sb <= virtualBands.size(); sb++) {
506 readLineBrick.SetBasePosition(1, 1, sb);
507 bsqOneLineTestCube.
read(readLineBrick);
508 for (
int i = 0; i < readLineBrick.size(); i++) {
509 if (readLineBrick[i] != (i + virtualBands[readLineBrick.Band()-1].toInt())) {
510 cerr <<
"Virtual bands accessed incorrectly at brick band "
511 << readLineBrick.Band() << endl;
517 bsqOneLineTestCube.
close();
520 cerr <<
"Testing reading skipped ascending virtual bands (1, 3, 3)... " << endl;
521 virtualBands.clear();
522 virtualBands.push_back(
"1");
523 virtualBands.push_back(
"3");
524 virtualBands.push_back(
"3");
526 bsqOneLineTestCube.
open(
"$TMP/IsisCube_bsqOneLine");
527 for (
int sb = 1; sb <= virtualBands.size(); sb++) {
528 readLineBrick.SetBasePosition(1, 1, sb);
529 bsqOneLineTestCube.
read(readLineBrick);
530 for (
int i = 0; i < readLineBrick.size(); i++) {
531 if (readLineBrick[i] != (i + virtualBands[readLineBrick.Band()-1].toInt())) {
532 cerr <<
"Virtual bands accessed incorrectly at virtual band "
533 << virtualBands[readLineBrick.Band() - 1] << endl;
539 bsqOneLineTestCube.
close();
542 cerr <<
"Testing reading outside of cube boundaries with virtual bands (1, 5)... " << endl;
543 virtualBands.clear();
544 virtualBands.push_back(
"1");
545 virtualBands.push_back(
"5");
547 bsqOneLineTestCube.
open(
"$TMP/IsisCube_bsqOneLine");
548 for (
int sb = 1; sb <= virtualBands.size(); sb++) {
549 readLineBrick.SetBasePosition(1, 1, sb);
550 bsqOneLineTestCube.
read(readLineBrick);
551 for (
int i = 0; i < readLineBrick.size(); i++) {
552 if (readLineBrick.Band() == 1) {
553 if (readLineBrick[i] != (i + virtualBands[readLineBrick.Band()-1].toInt())) {
554 cerr <<
"Virtual bands accessed incorrectly at virtual band "
555 << virtualBands[readLineBrick.Band() - 1] << endl;
560 if (readLineBrick[i] !=
Null) {
561 cerr <<
"Value outside cube boundary at virtual band "
562 << virtualBands[readLineBrick.Band() - 1] << endl;
568 bsqOneLineTestCube.
close();
571 cerr <<
"Testing reading descending virtual bands (3, 1, 3)... " << endl;
572 virtualBands.clear();
573 virtualBands.push_back(
"3");
574 virtualBands.push_back(
"1");
575 virtualBands.push_back(
"3");
577 bsqOneLineTestCube.
open(
"$TMP/IsisCube_bsqOneLine");
578 for (
int sb = 1; sb <= virtualBands.size(); sb++) {
579 readLineBrick.SetBasePosition(1, 1, sb);
580 bsqOneLineTestCube.
read(readLineBrick);
581 for (
int i = 0; i < readLineBrick.size(); i++) {
582 if (readLineBrick[i] != (i + virtualBands[readLineBrick.Band()-1].toInt())) {
583 cerr <<
"Virtual bands accessed incorrectly at virtual band "
584 << virtualBands[readLineBrick.Band() - 1] << endl;
590 bsqOneLineTestCube.
close();
594 cerr <<
"Testing creating large BSQ where samples exceed 1GB chunk size limit ... " << endl;
595 cerr <<
"Constructing cube ... " << endl << endl;
596 Cube largebsqTestCube;
598 int limitExceeded = (1 << 28) + 1;
601 largebsqTestCube.
create(
"$TMP/IsisCube_largebsq");
602 Report(largebsqTestCube);
605 largebsqTestCube.
close();
609 cerr <<
"Testing creating BSQ cube where size of sample pixels exceeds cube's lineCount ... "
611 cerr <<
"Constructing cube ... " << endl << endl;
616 bsqTestCube.
create(
"$TMP/IsisCube_bsq");
624 cerr <<
"Testing errors ... " << endl;
686 out.
create(
"$TMP/IsisCube_04");
697 out.
create(
"$TMP/IsisCube_04");
707 out.
create(
"$TMP/IsisCube_05");
715 in.
open(
"$TMP/IsisCube_01",
"a");
744 in4.
open(
"$ISISTESTDATA/isis/src/base/unitTestData/$TMP/isisTruth.cub");
755 error = error.replace(QRegExp(
"\\[[^\\]]*\\]"),
"[...]");
756 cerr << error.toStdString() << endl;
762 in4.
create(
"shouldntExist.cub");
770 externalData.
create(
"$TMP/IsisCube_06");
782 cerr << endl <<
"Test creating an ecub" << endl;
785 externalData.
setExternalDnData(
"$ISISTESTDATA/isis/src/base/unitTestData/$TMP/isisTruth.cub");
786 externalData.
create(
"$TMP/isisTruth_external.ecub");
788 cerr << *externalData.
label() << endl;
791 readBrick.SetBasePosition(1, 1, 1);
792 externalData.
read(readBrick);
793 for (
int index = 0; index < readBrick.size(); index++) {
794 if (readBrick[index] ==
Null) {
798 cerr << readBrick[index] <<
" ";
804 externalData.
write(readBrick);
811 cerr << endl <<
"Test creating an ecub from an ecub" << endl;
815 externalData.
create(
"$TMP/isisTruth_external2.ecub");
816 cerr << *externalData.
label() << endl;
819 readBrick.SetBasePosition(1, 1, 1);
820 externalData.
read(readBrick);
821 for (
int index = 0; index < readBrick.size(); index++) {
822 if (readBrick[index] ==
Null) {
826 cerr << readBrick[index] <<
" ";
832 externalData.
write(readBrick);
839 cerr << endl <<
"Test reading an ecub" << endl;
842 externalData.
open(
"$TMP/isisTruth_external",
"rw");
845 cerr << *externalData.
label() << endl;
848 readBrick.SetBasePosition(1, 1, 1);
849 externalData.
read(readBrick);
850 for (
int index = 0; index < readBrick.size(); index++) {
851 if (readBrick[index] ==
Null) {
855 cerr << readBrick[index] <<
" ";
861 externalData.
write(readBrick);
868 cerr << endl <<
"Test reading an ecub that points to another ecub" << endl;
871 externalData.
open(
"$TMP/isisTruth_external2");
872 cerr << *externalData.
label() << endl;
875 readBrick.SetBasePosition(1, 1, 1);
876 externalData.
read(readBrick);
877 for (
int index = 0; index < readBrick.size(); index++) {
878 if (readBrick[index] ==
Null) {
882 cerr << readBrick[index] <<
" ";
888 externalData.
write(readBrick);
957 remove(
"$TMP/IsisCube_00.cub");
958 remove(
"$TMP/IsisCube_01.cub");
959 remove(
"$TMP/IsisCube_02.cub");
960 remove(
"$TMP/IsisCube_02.lbl");
961 remove(
"$TMP/IsisCube_03.cub");
962 remove(
"$TMP/IsisCube_04.cub");
963 remove(
"$TMP/IsisCube_05.cub");
964 remove(
"$TMP/IsisCube_06.cub");
965 remove(
"$TMP/IsisCube_boundary.cub");
966 remove(
"$TMP/IsisCube_bsq.cub");
967 remove(
"$TMP/IsisCube_bsqOneLine.cub");
968 remove(
"$TMP/IsisCube_largebsq.cub");
969 remove(
"$TMP/isisTruth_external.ecub");
970 remove(
"$TMP/isisTruth_external2.ecub");
978void Report(
Cube &c) {
979 cerr <<
"File = " <<
IString(QFileInfo(c.
fileName()).fileName()) << endl;
981 cerr <<
"Lines = " << c.
lineCount() << endl;
982 cerr <<
"Bands = " << c.
bandCount() << endl;
983 cerr <<
"Base = " << c.
base() << endl;
985 cerr <<
"Type = " << c.
pixelType() << endl;
988 cerr <<
"Format = " << c.
format() << endl;
989 cerr <<
"Open = " << c.
isOpen() << endl;
1011 cerr <<
"Lbytes = " << c.
labelSize() << endl;
Buffer for containing a three dimensional section of an image.
Manipulate and parse attributes of output cube filenames.
IO Handler for Isis Cubes.
void clearIoCache()
This will clear excess RAM used for quicker IO in the cube.
void setPixelType(PixelType pixelType)
Used prior to the Create method, this will specify the output pixel type.
void setFormat(Format format)
Used prior to the Create method, this will specify the format of the cube, either band,...
virtual Histogram * histogram(const int &band=1, QString msg="Gathering histogram")
This method returns a pointer to a Histogram object which allows the program to obtain and use variou...
double multiplier() const
Returns the multiplier value for converting 8-bit/16-bit pixels to 32-bit.
void setLabelsAttached(bool attached)
Use prior to calling create, this sets whether or not to use separate label and data files.
Statistics * statistics(const int &band=1, QString msg="Gathering statistics")
This method returns a pointer to a Statistics object which allows the program to obtain and use vario...
void setDimensions(int ns, int nl, int nb)
Used prior to the Create method to specify the size of the cube.
void putGroup(const PvlGroup &group)
Adds a group in a Label to the cube.
bool isOpen() const
Test if a cube file has been opened/created.
void setBaseMultiplier(double base, double mult)
Used prior to the Create method, this will specify the base and multiplier for converting 8-bit/16-bi...
bool isReadOnly() const
Test if the opened cube is read-only, that is write operations will fail if this is true.
double base() const
Returns the base value for converting 8-bit/16-bit pixels to 32-bit.
Cube * copy(FileName newFile, const CubeAttributeOutput &newFileAttributes)
Copies the cube to the new fileName.
void create(const QString &cfile)
This method will create an isis cube for writing.
bool labelsAttached() const
Test if labels are attached.
void open(const QString &cfile, QString access="r")
This method will open an existing isis cube for reading or reading/writing.
PixelType pixelType() const
void setVirtualBands(const QList< QString > &vbands)
This allows the programmer to specify a subset of bands to work with.
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
@ Bsq
Cubes are stored in band-sequential format, that is the order of the pixels in the file (on disk) is:
virtual int physicalBand(const int &virtualBand) const
This method will return the physical band number given a virtual band number.
void setLabelSize(int labelBytes)
Used prior to the Create method, this will allocate a specific number of bytes in the label area for ...
virtual QString fileName() const
Returns the opened cube's filename.
void write(Blob &blob, bool overwrite=true)
This method will write a blob of data (e.g.
bool isReadWrite() const
Test if the opened cube is read-write, that is read and write operations should succeed if this is tr...
void setExternalDnData(FileName cubeFileWithDnData)
Used to set external dn data to cube.
void close(bool remove=false)
Closes the cube and updates the labels.
int labelSize(bool actual=false) const
Returns the number of bytes used by the label.
virtual int bandCount() const
Returns the number of virtual bands for the cube.
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
void reopen(QString access="r")
This method will reopen an isis sube for reading or reading/writing.
void setByteOrder(ByteOrder byteOrder)
Used prior to the Create method, this will specify the byte order of pixels, either least or most sig...
Container of a cube histogram.
double Mode() const
Returns the mode.
QString toString() const
Returns a string representation of this exception.
void print() const
Prints a string representation of this exception to stderr.
Adds specific functionality to C++ strings.
Buffer manager, for moving through a cube in lines.
Contains multiple PvlContainers.
This class is used to accumulate statistics on double arrays.
BigInt NullPixels() const
Returns the total number of NULL pixels encountered.
double Average() const
Computes and returns the average.
BigInt TotalPixels() const
Returns the total number of pixels processed (valid and invalid).
double StandardDeviation() const
Computes and returns the standard deviation.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
const double Null
Value for an Isis Null pixel.
Namespace for the standard library.