diff --git a/isis/src/base/objs/Cube/Cube.h b/isis/src/base/objs/Cube/Cube.h index eff3b9b33a..559aca34d4 100644 --- a/isis/src/base/objs/Cube/Cube.h +++ b/isis/src/base/objs/Cube/Cube.h @@ -325,7 +325,7 @@ namespace Isis { void putGroup(const PvlGroup &group); void latLonRange(double &minLatitude, double &maxLatitude, double &minLongitude, double &maxLongitude); - + FileName realDataFileName() const; private: void applyVirtualBandsToLabel(); @@ -333,7 +333,6 @@ namespace Isis { void construct(); QFile *dataFile() const; - FileName realDataFileName() const; void initialize(); void initCoreFromLabel(const Pvl &label); diff --git a/isis/src/base/objs/Cube/CubeIoHandler.h b/isis/src/base/objs/Cube/CubeIoHandler.h index 016371815b..a5114ec4fe 100644 --- a/isis/src/base/objs/Cube/CubeIoHandler.h +++ b/isis/src/base/objs/Cube/CubeIoHandler.h @@ -127,8 +127,6 @@ namespace Isis { virtual void updateLabels(Pvl &labels) = 0; QMutex *dataFileMutex(); - - protected: int bandCount() const; int getBandCountInChunk() const; BigInt getBytesPerChunk() const; @@ -137,13 +135,15 @@ namespace Isis { int getChunkCountInSampleDimension() const; int getChunkIndex(const RawCubeChunk &) const; BigInt getDataStartByte() const; - QFile * getDataFile(); int lineCount() const; int getLineCountInChunk() const; PixelType pixelType() const; int sampleCount() const; int getSampleCountInChunk() const; + protected: + QFile * getDataFile(); + void setChunkSizes(int numSamples, int numLines, int numBands); /** diff --git a/isis/src/base/objs/Cube/Cube_truth.txt b/isis/src/base/objs/Cube/Cube_truth.txt deleted file mode 100644 index cfa3c15e76..0000000000 --- a/isis/src/base/objs/Cube/Cube_truth.txt +++ /dev/null @@ -1,346 +0,0 @@ -Unit test for Cube -Constructing cube ... -File = -Samps = 0 -Lines = 0 -Bands = 0 -Base = 0 -Mult = 1 -Type = 7 -Atchd = 1 -Format = 1 -Open = 0 -R/O = N/A -R/W = N/A -Lbytes = 65536 - -Creating 32-bit cube ... -File = IsisCube_00.cub -Samps = 150 -Lines = 200 -Bands = 2 -Base = 0 -Mult = 1 -Type = 7 -Atchd = 1 -Format = 1 -Open = 1 -R/O = 0 -R/W = 1 -Lbytes = 65536 - -Write cube ... -Opening cube ... -File = IsisCube_01.cub -Samps = 150 -Lines = 200 -Bands = 2 -Base = 0 -Mult = 1 -Type = 7 -Atchd = 1 -Format = 1 -Open = 1 -R/O = 1 -R/W = 0 -Lbytes = 6563 - -Comparing cube ... - -Creating 8-bit cube ... -Comparing cube ... -File = IsisCube_02.lbl -Samps = 150 -Lines = 200 -Bands = 1 -Base = 200 -Mult = -1 -Type = 1 -Atchd = 0 -Format = 0 -Open = 1 -R/O = 1 -R/W = 0 -Lbytes = 419 - -Creating 16-bit cube ... -Comparing cube ... -File = IsisCube_03.cub -Samps = 150 -Lines = 200 -Bands = 2 -Base = 30000 -Mult = -1 -Type = 4 -Atchd = 1 -Format = 1 -Open = 1 -R/O = 1 -R/W = 0 -Lbytes = 65536 - -Testing histogram method, band 1 ... -Average: 14900 -Standard Dev: 8602.66 -Mode: 149.148 -Total Pixels: 30000 -Null Pixels: 0 - -Testing histogram method, all bands ... -Average: 29800 -Standard Dev: 17205.2 -Mode: 149.148 -Total Pixels: 60000 -Null Pixels: 0 - -**PROGRAMMER ERROR** Invalid band in [CubeInfo::Histogram]. -**PROGRAMMER ERROR** Cannot create histogram object for an unopened cube. - -Testing statistics method, band 1 ... -Average: 14900 -Standard Dev: 8602.66 -Total Pixels: 30000 -Null Pixels: 0 - -Testing statistics method, all bands ... -Average: 29800 -Standard Dev: 17205.2 -Total Pixels: 60000 -Null Pixels: 0 - -**PROGRAMMER ERROR** Invalid band in [CubeInfo::Statistics]. -**PROGRAMMER ERROR** Cannot create statistics object for an unopened cube. - -Virtual band tests -Nbands = 2 -Band 1 = 1 -Band 2 = 2 - -Nbands = 1 -Band 1 = 2 - -ReOpen tests -File = IsisCube_01.cub -Samps = 150 -Lines = 200 -Bands = 1 -Base = 0 -Mult = 1 -Type = 7 -Atchd = 1 -Format = 1 -Open = 1 -R/O = 1 -R/W = 0 -Lbytes = 6563 - -File = IsisCube_01.cub -Samps = 150 -Lines = 200 -Bands = 1 -Base = 0 -Mult = 1 -Type = 7 -Atchd = 1 -Format = 1 -Open = 1 -R/O = 0 -R/W = 1 -Lbytes = 6563 - -File = IsisCube_01.cub -Samps = 150 -Lines = 200 -Bands = 1 -Base = 0 -Mult = 1 -Type = 7 -Atchd = 1 -Format = 1 -Open = 1 -R/O = 1 -R/W = 0 -Lbytes = 6563 - -Testing reading past cube boundaries ... -Constructing cube ... - -File = IsisCube_boundary.cub -Samps = 10 -Lines = 10 -Bands = 4 -Base = 0 -Mult = 1 -Type = 7 -Atchd = 1 -Format = 1 -Open = 1 -R/O = 0 -R/W = 1 -Lbytes = 65536 - -Reading completely within cube boundaries ... - Comparing results ... -Reading completely outside band boundaries ... - Comparing results ... - -Reading partially within band boundaries ... - Reading bands 0 (should be null) and 1 (should be 1.0)... - Comparing results ... - Reading bands 4 (should be 1.0) and 5 (should be null)... - Comparing results ... - -Testing reading past cube boundaries with virtual bands (2, 1, 3, 4, 2)... -Reading completely outside virtual band boundaries ... - Comparing results starting at band 6... - Comparing results starting at band 1000... - Comparing results starting at band -1... - -Reading partially within virtual band boundaries ... -Comparing results ... - -Testing one line BSQ cube (where chunk dimensions == buffer shape) ... -Constructing cube ... - -File = IsisCube_bsqOneLine.cub -Samps = 3 -Lines = 1 -Bands = 3 -Base = 0 -Mult = 1 -Type = 7 -Atchd = 1 -Format = 0 -Open = 1 -R/O = 0 -R/W = 1 -Lbytes = 65536 - -Testing reading ascending repeating virtual bands (1, 2, 2, 3)... - -Testing reading skipped ascending virtual bands (1, 3, 3)... - -Testing reading outside of cube boundaries with virtual bands (1, 5)... - -Testing reading descending virtual bands (3, 1, 3)... - -Testing creating large BSQ where samples exceed 1GB chunk size limit ... -Constructing cube ... - -File = IsisCube_largebsq.cub -Samps = 268435457 -Lines = 2 -Bands = 1 -Base = 0 -Mult = 1 -Type = 7 -Atchd = 1 -Format = 0 -Open = 1 -R/O = 0 -R/W = 1 -Lbytes = 65536 - - -Testing creating BSQ cube where size of sample pixels exceeds cube's lineCount ... -Constructing cube ... - -File = IsisCube_bsq.cub -Samps = 15000 -Lines = 18000 -Bands = 1 -Base = 0 -Mult = 1 -Type = 7 -Atchd = 1 -Format = 0 -Open = 1 -R/O = 0 -R/W = 1 -Lbytes = 65536 - - -Testing errors ... -**PROGRAMMER ERROR** You already have a cube opened. -**PROGRAMMER ERROR** You already have a cube opened. -**PROGRAMMER ERROR** Cannot write to the cube [IsisCube_01.cub] because it is opened read-only. -**I/O ERROR** Unable to open [blah]. -**PROGRAMMER ERROR** Out of array bounds [2]. -**PROGRAMMER ERROR** Out of array bounds [0]. -**PROGRAMMER ERROR** Try opening a file before you read it. -**PROGRAMMER ERROR** Tried to write to a cube before opening/creating it. -**PROGRAMMER ERROR** Number of samples [0], lines [0], or bands [0] cannot be less than 1. -**I/O ERROR** Label space is full in [IsisCube_04.cub] unable to write labels. -**USER ERROR** The cube you are attempting to create [IsisCube_05] is [33527GB]. This is larger than the current allowed size of [12GB]. The cube dimensions were (S,L,B) [1000000, 1000000, 9] with [4] bytes per pixel. If you still wish to create this cube, the maximum value can be changed in your personal preference file located in [~/.Isis/IsisPreferences] within the group CubeCustomization, keyword MaximumSize. If you do not have an ISISPreference file, please refer to the documentation 'Environment and Preference Setup'. Error. -**PROGRAMMER ERROR** Unknown value for access [a]. Expected 'r' or 'rw'. -**PROGRAMMER ERROR** SetDimensions: Invalid number of sample, lines or bands. -**PROGRAMMER ERROR** SetDimensions: Invalid number of sample, lines or bands. -**PROGRAMMER ERROR** SetDimensions: Invalid number of sample, lines or bands. -**I/O ERROR** Failed to open [...] with read/write access. -**ERROR** Cannot create the cube [shouldntExist.cub] with a pixel type set to None. -**PROGRAMMER ERROR** Cannot add a group to the label of cube [IsisCube_06.cub] because it is opened read-only. - -Test creating an ecub -Object = IsisCube - Object = Core - ^DnFile = $ISISTESTDATA/isis/src/base/unitTestData/isisTruth.cub - End_Object - - Group = TestGroup - End_Group -End_Object - -Object = Label - Bytes = 65536 -End_Object -End -0 0 0 20 20 20 39 39 39 0 20 39 0 20 39 0 20 39 -**ERROR** The cube [isisTruth_external.ecub] does not support storing DN data because it is using an external file for DNs. - -Test creating an ecub from an ecub -Object = IsisCube - Object = Core - ^DnFile = isisTruth_external.ecub - End_Object -End_Object - -Object = Label - Bytes = 65536 -End_Object -End -0 0 0 20 20 20 39 39 39 0 20 39 0 20 39 0 20 39 -**ERROR** The cube [isisTruth_external2.ecub] does not support storing DN data because it is using an external file for DNs. - -Test reading an ecub -Object = IsisCube - Object = Core - ^DnFile = $ISISTESTDATA/isis/src/base/unitTestData/isisTruth.cub - End_Object - - Group = TestGroup - End_Group - - Group = TestGroup2 - End_Group -End_Object - -Object = Label - Bytes = 65536 -End_Object -End -0 0 0 20 20 20 39 39 39 0 20 39 0 20 39 0 20 39 -**PROGRAMMER ERROR** Cannot write to the cube [isisTruth_external.ecub] because it is opened read-only. - -Test reading an ecub that points to another ecub -Object = IsisCube - Object = Core - ^DnFile = isisTruth_external.ecub - End_Object -End_Object - -Object = Label - Bytes = 65536 -End_Object -End -0 0 0 20 20 20 39 39 39 0 20 39 0 20 39 0 20 39 -**PROGRAMMER ERROR** Cannot write to the cube [isisTruth_external2.ecub] because it is opened read-only. diff --git a/isis/src/base/objs/Cube/unitTest_disabled.cpp b/isis/src/base/objs/Cube/unitTest_disabled.cpp deleted file mode 100644 index d0cb588bed..0000000000 --- a/isis/src/base/objs/Cube/unitTest_disabled.cpp +++ /dev/null @@ -1,1013 +0,0 @@ -/** This is free and unencumbered software released into the public domain. -The authors of ISIS do not claim copyright on the contents of this file. -For more details about the LICENSE terms and the AUTHORS, you will -find files of those names at the top level of this repository. **/ - -/* SPDX-License-Identifier: CC0-1.0 */ -#include - -#include -#include - -#include "IException.h" -#include "Brick.h" -#include "Cube.h" -#include "CubeAttribute.h" -#include "FileName.h" -#include "LineManager.h" -#include "Pvl.h" -#include "Preference.h" -#include "Histogram.h" -#include "SpecialPixel.h" -#include "Statistics.h" - -using namespace std; -using namespace Isis; - - -int main(int argc, char *argv[]) { - Preference::Preferences(true); - - try { - void Report(Cube & c); - cerr << "Unit test for Cube" << endl; - - cerr << "Constructing cube ... " << endl; - Cube out; - Report(out); - - // Test create and write methods - cerr << "Creating 32-bit cube ... " << endl; - out.setDimensions(150, 200, 2); - out.create("$TMP/IsisCube_00"); - Report(out); - - cerr << "Write cube ... " << endl; - LineManager line(out); - long j = 0; - for(line.begin(); !line.end(); line++) { - for(int i = 0; i < line.size(); i++) { - line[i] = (double) j; - j++; - } - j--; - out.write(line); - } - - // Copy returns the resulting Cube, we don't care about it (but we need it to flush) so delete - delete out.copy("$TMP/IsisCube_01", CubeAttributeOutput()); - out.close(); - - // Test the open and read methods - cerr << "Opening cube ... " << endl; - Cube in("$TMP/IsisCube_01"); - Report(in); - - cerr << "Comparing cube ... " << endl; - LineManager inLine(in); - j = 0; - for(inLine.begin(); !inLine.end(); inLine++) { - in.read(inLine); - for(int i = 0; i < inLine.size(); i++) { - if(inLine[i] != (double) j) { - cerr << "Problem at" - << " line " << inLine.Line() - << " sample " << i + 1 - << " band " << inLine.Band() << ": " - << inLine[i] << " != " << double(j) << endl; - return 1; - } - j++; - } - j--; - } - in.close(); - cerr << endl; - - // Test other options for output - cerr << "Creating 8-bit cube ... " << endl; - Cube out2; - out2.setDimensions(150, 200, 1); - out2.setLabelsAttached(false); - out2.setBaseMultiplier(200.0, -1.0); -// out2.SetByteOrder(Msb); - out2.setByteOrder(ISIS_LITTLE_ENDIAN ? Msb : Lsb); - out2.setFormat(Cube::Bsq); - out2.setLabelSize(1000); - out2.setPixelType(UnsignedByte); - out2.create("$TMP/IsisCube_02"); - - j = 0; - LineManager oline(out2); - for(oline.begin(); !oline.end(); oline++) { - for(int i = 0; i < oline.size(); i++) { - oline[i] = (double) j; - } - out2.clearIoCache(); - out2.write(oline); - j++; - } - out2.close(); - - cerr << "Comparing cube ... " << endl; - Cube in2; - try { - in2.open("$TMP/IsisCube_02"); - } - catch (IException &e) { - e.print(); - } - Report(in2); - j = 0; - LineManager inLine2(in2); - for(inLine2.begin(); !inLine2.end(); inLine2++) { - in2.read(inLine2); - for(int i = 0; i < inLine2.size(); i++) { - if(inLine2[i] != (double) j) { - cerr << "Problem at line " << inLine2.Line() - << " sample " << i + 1 << ": " - << inLine2[i] << " != " << double(j) << endl; - return 1; - } - } - in2.clearIoCache(); - j++; - } - in2.close(); - - - // Test other options for output - cerr << "Creating 16-bit cube ... " << endl; - Cube out3; - out3.setDimensions(150, 200, 2); - out3.setBaseMultiplier(30000.0, -1.0); -// out3.SetByteOrder(Msb); - out2.setByteOrder(ISIS_LITTLE_ENDIAN ? Msb : Lsb); - out3.setPixelType(SignedWord); - out3.create("$TMP/IsisCube_03"); - - j = 0; - LineManager oline3(out3); - for(oline3.begin(); !oline3.end(); oline3++) { - for(int i = 0; i < oline3.size(); i++) { - oline3[i] = (double) j; - j++; - } - out3.write(oline3); - } - out3.close(); - - cerr << "Comparing cube ... " << endl; - Cube in3; - in3.open("$TMP/IsisCube_03"); - Report(in3); - j = 0; - LineManager inLine3(in3); - for(inLine3.begin(); !inLine3.end(); inLine3++) { - in3.read(inLine3); - in3.clearIoCache(); - for(int i = 0; i < inLine3.size(); i++) { - if(inLine3[i] != (double) j) { - cerr << "Problem at line " << inLine3.Line() - << " sample " << i + 1 << " band " << inLine3.Band() << ": " - << inLine3[i] << " != " << double(j) << endl; - return 1; - } - j++; - } - } - in3.close(); - - - in.open("$TMP/IsisCube_01"); - - // Test Histogram object on a single band, 1 by default - cerr << "Testing histogram method, band 1 ... " << endl; - Histogram *bandOneHist = in.histogram(); - cerr << "Average: " << bandOneHist->Average() << endl; - cerr << "Standard Dev: " << bandOneHist->StandardDeviation() << endl; - cerr << "Mode: " << bandOneHist->Mode() << endl; - cerr << "Total Pixels: " << bandOneHist->TotalPixels() << endl; - cerr << "Null Pixels: " << bandOneHist->NullPixels() << endl; - cerr << endl; - delete bandOneHist; - bandOneHist = NULL; - - // Test histogram object on all bands - cerr << "Testing histogram method, all bands ... " << endl; - Histogram *allBandsHistogram = in.histogram(0); - cerr << "Average: " << allBandsHistogram->Average() << endl; - cerr << "Standard Dev: " << allBandsHistogram->StandardDeviation() << endl; - cerr << "Mode: " << allBandsHistogram->Mode() << endl; - cerr << "Total Pixels: " << allBandsHistogram->TotalPixels() << endl; - cerr << "Null Pixels: " << allBandsHistogram->NullPixels() << endl; - cerr << endl; - delete allBandsHistogram; - allBandsHistogram = NULL; - - // Check error for too few (negative) bands - try { - in.histogram(-1); - } - catch (IException &e) { - e.print(); - } - - // Check error for histogram object on a closed cube - try { - // out has already been closed - out.histogram(0); - } - catch (IException &e) - { - e.print(); - } - - cerr << endl; - - // Test statistics object on a single band, 1 by default - cerr << "Testing statistics method, band 1 ... " << endl; - Statistics *bandOneStats = in.statistics(); - cerr << "Average: " << bandOneStats->Average() << endl; - cerr << "Standard Dev: " << bandOneStats->StandardDeviation() << endl; - cerr << "Total Pixels: " << bandOneStats->TotalPixels() << endl; - cerr << "Null Pixels: " << bandOneStats->NullPixels() << endl; - cerr << endl; - delete bandOneStats; - bandOneStats = NULL; - - // Test statistics object on all bands - cerr << "Testing statistics method, all bands ... " << endl; - Statistics *allBandsStats = in.statistics(0); - cerr << "Average: " << allBandsStats->Average() << endl; - cerr << "Standard Dev: " << allBandsStats->StandardDeviation() << endl; - cerr << "Total Pixels: " << allBandsStats->TotalPixels() << endl; - cerr << "Null Pixels: " << allBandsStats->NullPixels() << endl; - cerr << endl; - delete allBandsStats; - allBandsStats = NULL; - - // Check error for too few (negative) bands - try { - in.statistics(-1); - } - catch (IException &e) { - e.print(); - } - - // Check error for statistics object on a closed cube - try { - // out has already been closed - out.statistics(0); - } - catch (IException &e) - { - e.print(); - } - - cerr << endl; - - cerr << "Virtual band tests" << endl; // Virtual Band tests - - cerr << "Nbands = " << in.bandCount() << endl; - cerr << "Band 1 = " << in.physicalBand(1) << endl; - cerr << "Band 2 = " << in.physicalBand(2) << endl; - in.close(); - cerr << endl; - - QList vbands; - vbands.push_back("2"); - in.setVirtualBands(vbands); - in.open("$TMP/IsisCube_01"); - cerr << "Nbands = " << in.bandCount() << endl; - cerr << "Band 1 = " << in.physicalBand(1) << endl; - cerr << endl; - - // Test ReOpen - cerr << "ReOpen tests" << endl; - Report(in); - in.reopen("rw"); - Report(in); - in.reopen("r"); - Report(in); - - // Test reading past cube boundaries. - // First create a new cube for us to test and fill it with ones. - cerr << "Testing reading past cube boundaries ... " << endl; - cerr << "Constructing cube ... " << endl << endl; - Cube boundaryTestCube; - boundaryTestCube.setDimensions(10, 10, 4); - boundaryTestCube.create("$TMP/IsisCube_boundary"); - Report(boundaryTestCube); - LineManager boundaryLine(boundaryTestCube); - - for(boundaryLine.begin(); !boundaryLine.end(); boundaryLine++) { - for(int i = 0; i < boundaryLine.size(); i++) { - boundaryLine[i] = 1.0; - } - boundaryTestCube.write(boundaryLine); - } - - // Now read past the cube boundaries and compare the results to what we - // expect. All valid positions in the brick should be filled with ones since - // our cube is entirely filled with ones, and any parts that fall outside of - // the cube should be nulls. - cerr << "Reading completely within cube boundaries ... " << endl; - Brick readBrick(1, 1, 2, boundaryTestCube.pixelType()); - readBrick.SetBasePosition(1, 1, 1); - boundaryTestCube.read(readBrick); - - cerr << "\tComparing results ... " << endl; - for(int i = 0; i < readBrick.size(); i++) { - if (readBrick[i] != 1.0) { - cerr << "\tNot all values in brick were 1.0." << endl; - return 1; - } - } - - cerr << "Reading completely outside band boundaries ... " << endl; - readBrick.SetBasePosition(1, 1, -1); - boundaryTestCube.read(readBrick); - - cerr << "\tComparing results ... " << endl; - for(int i = 0; i < readBrick.size(); i++) { - if (readBrick[i] != Null) { - cerr << "\tNot all values in brick were Null." << endl; - return 1; - } - } - cerr << endl; - - // Read before the bands start in the cube. - cerr << "Reading partially within band boundaries ... " << endl; - cerr << "\t Reading bands 0 (should be null) and 1 (should be 1.0)... " << endl; - cerr << "\t\t Comparing results ... " << endl; - readBrick.SetBasePosition(1, 1, 0); - boundaryTestCube.read(readBrick); - - if (readBrick[0] != Null) { - cerr << "\t\t Value outside cube boundary was not Null." << endl; - return 1; - } - if (readBrick[1] != 1.0) { - cerr << "\t\t Value inside cube boundary was not 1.0." << endl; - return 1; - } - - cerr << "\t Reading bands 4 (should be 1.0) and 5 (should be null)... " << endl; - cerr << "\t\t Comparing results ... " << endl; - // Read after the bands start in the cube. - readBrick.SetBasePosition(1, 1, 4); - boundaryTestCube.read(readBrick); - - if (readBrick[0] != 1.0) { - cerr << "\t\t Value inside cube boundary was not 1.0." << endl; - return 1; - } - if (readBrick[1] != Null) { - cerr << "\t\t Value outside cube boundary was not Null." << endl; - return 1; - } - cerr << endl; - - boundaryTestCube.close(); - - // Test reading outside a cube with virtual bands. - cerr << "Testing reading past cube boundaries with virtual bands (2, 1, 3, 4, 2)... " << endl; - QList virtualBands; - virtualBands.push_back("2"); - virtualBands.push_back("1"); - virtualBands.push_back("3"); - virtualBands.push_back("4"); - virtualBands.push_back("2"); - boundaryTestCube.setVirtualBands(virtualBands); - boundaryTestCube.open("$TMP/IsisCube_boundary"); - - cerr << "Reading completely outside virtual band boundaries ... " << endl; - readBrick.SetBasePosition(1, 1, 6); - boundaryTestCube.read(readBrick); - - cerr << "\tComparing results starting at band 6... " << endl; - for(int i = 0; i < readBrick.size(); i++) { - if (readBrick[i] != Null) { - cerr << "\tNot all values in brick (outside cube boundary) were Null. " << i << endl; - return 1; - } - } - - cerr << "\tComparing results starting at band 1000... " << endl; - readBrick.SetBasePosition(1, 1, 1000); - boundaryTestCube.read(readBrick); - for(int i = 0; i < readBrick.size(); i++) { - if (readBrick[i] != Null) { - cerr << "\tNot all values in brick (outside cube boundary) were Null." << endl; - return 1; - } - } - - cerr << "\tComparing results starting at band -1... " << endl; - readBrick.SetBasePosition(1, 1, -1); - boundaryTestCube.read(readBrick); - for(int i = 0; i < readBrick.size(); i++) { - if (readBrick[i] != Null) { - cerr << "Not all values in brick (outside cube boundary) were Null. " << endl; - return 1; - } - } - cerr << endl; - - // Read before the bands start in the cube. - cerr << "Reading partially within virtual band boundaries ... " << endl; - readBrick.SetBasePosition(1, 1, 0); - boundaryTestCube.read(readBrick); - - cerr << "Comparing results ... " << endl; - if (readBrick[0] != Null) { - cerr << "Value outside cube boundary (band 0) was not Null." << endl; - return 1; - } - if (readBrick[1] != 1.0) { - cerr << "Value inside cube boundary (band 1) was not 1.0." << endl; - return 1; - } - - // Read after the bands start in the cube. - readBrick.SetBasePosition(1, 1, 5); - boundaryTestCube.read(readBrick); - - if (readBrick[0] != 1.0) { - cerr << "Value inside cube boundary (band 5) was not 1.0." << endl; - return 1; - } - if (readBrick[1] != Null) { - cerr << "Value outside cube boundary (band 6) was not Null." << endl; - return 1; - } - - // Resize the brick to be have many more bands than the cube, and position - // it before the start of the bands. We should get nulls, then some values, - // then more nulls. - readBrick.Resize(1, 1, 20); - readBrick.SetBasePosition(1, 1, -10); - boundaryTestCube.read(readBrick); - for (int i = 0; i < readBrick.size(); i++) { - if (i >= 11 && i <= 15) { - if (readBrick[i] != 1.0) { - cerr << "Value inside cube boundary, at brick band " << i + 1 << " was not 1.0." << endl; - return 1; - } - } - else { - if (readBrick[i] != Null) { - cerr << "Value outside cube boundary, at brick band " << i + 1 - << " was not Null." << endl; - return 1; - } - } - } - cerr << endl; - boundaryTestCube.close(); - - - // Test cube where its chunk size is the same as its buffer shape - cerr << "Testing one line BSQ cube (where chunk dimensions == buffer shape) ... " << endl; - cerr << "Constructing cube ... " << endl << endl; - Cube bsqOneLineTestCube; - bsqOneLineTestCube.setDimensions(3, 1, 3); - bsqOneLineTestCube.setFormat(Cube::Bsq); - bsqOneLineTestCube.create("$TMP/IsisCube_bsqOneLine"); - Report(bsqOneLineTestCube); - LineManager oneLine(bsqOneLineTestCube); - - // our cube will be 1, 2, 3 - // 2, 3, 4 - // 3, 4, 5 - for (oneLine.begin(); !oneLine.end(); oneLine++) { - for (int i = 0; i < oneLine.size(); i++) { - oneLine[i] = 1 * i + oneLine.Band(); - } - bsqOneLineTestCube.write(oneLine); - } - bsqOneLineTestCube.close(); - - // Simulate reading of an S x 1 x B cube - Brick readLineBrick(3, 1, 1, bsqOneLineTestCube.pixelType()); - - // Test reading repeated ascending virtual bands - cerr << "Testing reading ascending repeating virtual bands (1, 2, 2, 3)... " << endl; - virtualBands.clear(); - virtualBands.push_back("1"); - virtualBands.push_back("2"); - virtualBands.push_back("2"); - virtualBands.push_back("3"); - bsqOneLineTestCube.setVirtualBands(virtualBands); - bsqOneLineTestCube.open("$TMP/IsisCube_bsqOneLine"); - for (int sb = 1; sb <= virtualBands.size(); sb++) { - readLineBrick.SetBasePosition(1, 1, sb); - bsqOneLineTestCube.read(readLineBrick); - for (int i = 0; i < readLineBrick.size(); i++) { - if (readLineBrick[i] != (i + virtualBands[readLineBrick.Band()-1].toInt())) { - cerr << "Virtual bands accessed incorrectly at brick band " - << readLineBrick.Band() << endl; - return 1; - } - } - } - cerr << endl; - bsqOneLineTestCube.close(); - - // Test reading skipped ascending virtual bands - cerr << "Testing reading skipped ascending virtual bands (1, 3, 3)... " << endl; - virtualBands.clear(); - virtualBands.push_back("1"); - virtualBands.push_back("3"); - virtualBands.push_back("3"); - bsqOneLineTestCube.setVirtualBands(virtualBands); - bsqOneLineTestCube.open("$TMP/IsisCube_bsqOneLine"); - for (int sb = 1; sb <= virtualBands.size(); sb++) { - readLineBrick.SetBasePosition(1, 1, sb); - bsqOneLineTestCube.read(readLineBrick); - for (int i = 0; i < readLineBrick.size(); i++) { - if (readLineBrick[i] != (i + virtualBands[readLineBrick.Band()-1].toInt())) { - cerr << "Virtual bands accessed incorrectly at virtual band " - << virtualBands[readLineBrick.Band() - 1] << endl; - return 1; - } - } - } - cerr << endl; - bsqOneLineTestCube.close(); - - // Test reading outside boundaries - cerr << "Testing reading outside of cube boundaries with virtual bands (1, 5)... " << endl; - virtualBands.clear(); - virtualBands.push_back("1"); - virtualBands.push_back("5"); - bsqOneLineTestCube.setVirtualBands(virtualBands); - bsqOneLineTestCube.open("$TMP/IsisCube_bsqOneLine"); - for (int sb = 1; sb <= virtualBands.size(); sb++) { - readLineBrick.SetBasePosition(1, 1, sb); - bsqOneLineTestCube.read(readLineBrick); - for (int i = 0; i < readLineBrick.size(); i++) { - if (readLineBrick.Band() == 1) { - if (readLineBrick[i] != (i + virtualBands[readLineBrick.Band()-1].toInt())) { - cerr << "Virtual bands accessed incorrectly at virtual band " - << virtualBands[readLineBrick.Band() - 1] << endl; - return 1; - } - } - else { - if (readLineBrick[i] != Null) { - cerr << "Value outside cube boundary at virtual band " - << virtualBands[readLineBrick.Band() - 1] << endl; - } - } - } - } - cerr << endl; - bsqOneLineTestCube.close(); - - // Test reading descending bands - cerr << "Testing reading descending virtual bands (3, 1, 3)... " << endl; - virtualBands.clear(); - virtualBands.push_back("3"); - virtualBands.push_back("1"); - virtualBands.push_back("3"); - bsqOneLineTestCube.setVirtualBands(virtualBands); - bsqOneLineTestCube.open("$TMP/IsisCube_bsqOneLine"); - for (int sb = 1; sb <= virtualBands.size(); sb++) { - readLineBrick.SetBasePosition(1, 1, sb); - bsqOneLineTestCube.read(readLineBrick); - for (int i = 0; i < readLineBrick.size(); i++) { - if (readLineBrick[i] != (i + virtualBands[readLineBrick.Band()-1].toInt())) { - cerr << "Virtual bands accessed incorrectly at virtual band " - << virtualBands[readLineBrick.Band() - 1] << endl; - return 1; - } - } - } - cerr << endl; - bsqOneLineTestCube.close(); - - - // Test creating a bsq cube that exceeds 1GB sample size limit to test CubeBsqHandler - cerr << "Testing creating large BSQ where samples exceed 1GB chunk size limit ... " << endl; - cerr << "Constructing cube ... " << endl << endl; - Cube largebsqTestCube; - // 2^28 x 2 x 1 cube -> 2^28 + 1 > 2^30 / (4*2^28), exceeds limit - int limitExceeded = (1 << 28) + 1; - largebsqTestCube.setDimensions(limitExceeded, 2, 1); - largebsqTestCube.setFormat(Cube::Bsq); - largebsqTestCube.create("$TMP/IsisCube_largebsq"); - Report(largebsqTestCube); - - cerr << endl; - largebsqTestCube.close(); - - - // Test bsq cube that has a linecount > maximum chunk line size to test CubeBsqHandler - cerr << "Testing creating BSQ cube where size of sample pixels exceeds cube's lineCount ... " - << endl; - cerr << "Constructing cube ... " << endl << endl; - Cube bsqTestCube; - // maxLineSize = 2^30 / (4 * 15000) = 17895 < 18000 - bsqTestCube.setDimensions(15000, 18000, 1); - bsqTestCube.setFormat(Cube::Bsq); - bsqTestCube.create("$TMP/IsisCube_bsq"); - Report(bsqTestCube); - - cerr << endl; - bsqTestCube.close(); - - - // Check errors - cerr << "Testing errors ... " << endl; - try { - in.open("blah"); - } - catch (IException &e) { - e.print(); - } - - try { - in.create("blah"); - } - catch (IException &e) { - e.print(); - } - - try { - in.write(inLine3); - } - catch (IException &e) { - e.print(); - } - - try { - Cube in; - in.open("blah"); - } - catch (IException &e) { - e.print(); - } - - try { - in.physicalBand(2); - } - catch (IException &e) { - e.print(); - } - - try { - in.physicalBand(0); - } - catch (IException &e) { - e.print(); - } - - try { - Cube in; - in.read(inLine3); - } - catch (IException &e) { - e.print(); - } - - try { - Cube in; - in.write(inLine3); - } - catch (IException &e) { - e.print(); - } - - try { - Cube out; - out.create("$TMP/IsisCube_04"); - out.close(); - } - catch (IException &e) { - e.print(); - } - - try { - Cube out; - out.setLabelSize(15); - out.setDimensions(1, 1, 1); - out.create("$TMP/IsisCube_04"); - out.close(); - } - catch (IException &e) { - e.print(); - } - - try { - Cube out; - out.setDimensions(1000000, 1000000, 9); - out.create("$TMP/IsisCube_05"); - out.close(); - } - catch (IException &e) { - e.print(); - } - try { - Cube in; - in.open("$TMP/IsisCube_01", "a"); - } - catch (IException &e) { - e.print(); - } - try { - Cube in; - in.setDimensions(0, 0, 0); - } - catch (IException &e) { - e.print(); - } - try { - Cube in; - in.setDimensions(1, 0, 0); - } - catch (IException &e) { - e.print(); - } - try { - Cube in; - in.setDimensions(1, 1, 0); - } - catch (IException &e) { - e.print(); - } - - Cube in4; - try { - in4.open("$ISISTESTDATA/isis/src/base/unitTestData/$TMP/isisTruth.cub"); - } - catch (IException &e) { - e.print(); - } - - try { - in4.reopen("rw"); - } - catch (IException &e) { - QString error = e.toString(); - error = error.replace(QRegExp("\\[[^\\]]*\\]"), "[...]"); - cerr << error.toStdString() << endl; - } - - in4.setPixelType(None); - try { - in4.setDimensions(1, 1, 1); - in4.create("shouldntExist.cub"); - } - catch (IException &e) { - e.print(); - } - try { - Cube externalData; - externalData.setDimensions(1024, 1024, 1); - externalData.create("$TMP/IsisCube_06"); - externalData.reopen("r"); - externalData.putGroup(PvlGroup("TestGroup2")); - } - catch (IException &e) { - e.print(); - } - } - catch (IException &e) { - e.print(); - } - - cerr << endl << "Test creating an ecub" << endl; - { - Cube externalData; - externalData.setExternalDnData("$ISISTESTDATA/isis/src/base/unitTestData/$TMP/isisTruth.cub"); - externalData.create("$TMP/isisTruth_external.ecub"); - externalData.putGroup(PvlGroup("TestGroup")); - cerr << *externalData.label() << endl; - - Brick readBrick(3, 3, 2, externalData.pixelType()); - readBrick.SetBasePosition(1, 1, 1); - externalData.read(readBrick); - for (int index = 0; index < readBrick.size(); index++) { - if (readBrick[index] == Null) { - cerr << "N "; - } - else { - cerr << readBrick[index] << " "; - } - } - cerr << endl; - - try { - externalData.write(readBrick); - } - catch (IException &e) { - e.print(); - } - } - - cerr << endl << "Test creating an ecub from an ecub" << endl; - { - Cube externalData; - externalData.setExternalDnData("$TMP/isisTruth_external.ecub"); - externalData.create("$TMP/isisTruth_external2.ecub"); - cerr << *externalData.label() << endl; - - Brick readBrick(3, 3, 2, externalData.pixelType()); - readBrick.SetBasePosition(1, 1, 1); - externalData.read(readBrick); - for (int index = 0; index < readBrick.size(); index++) { - if (readBrick[index] == Null) { - cerr << "N "; - } - else { - cerr << readBrick[index] << " "; - } - } - cerr << endl; - - try { - externalData.write(readBrick); - } - catch (IException &e) { - e.print(); - } - } - - cerr << endl << "Test reading an ecub" << endl; - { - Cube externalData; - externalData.open("$TMP/isisTruth_external", "rw"); - externalData.putGroup(PvlGroup("TestGroup2")); - externalData.reopen("r"); - cerr << *externalData.label() << endl; - - Brick readBrick(3, 3, 2, externalData.pixelType()); - readBrick.SetBasePosition(1, 1, 1); - externalData.read(readBrick); - for (int index = 0; index < readBrick.size(); index++) { - if (readBrick[index] == Null) { - cerr << "N "; - } - else { - cerr << readBrick[index] << " "; - } - } - cerr << endl; - - try { - externalData.write(readBrick); - } - catch (IException &e) { - e.print(); - } - } - - cerr << endl << "Test reading an ecub that points to another ecub" << endl; - { - Cube externalData; - externalData.open("$TMP/isisTruth_external2"); - cerr << *externalData.label() << endl; - - Brick readBrick(3, 3, 2, externalData.pixelType()); - readBrick.SetBasePosition(1, 1, 1); - externalData.read(readBrick); - for (int index = 0; index < readBrick.size(); index++) { - if (readBrick[index] == Null) { - cerr << "N "; - } - else { - cerr << readBrick[index] << " "; - } - } - cerr << endl; - - try { - externalData.write(readBrick); - } - catch (IException &e) { - e.print(); - } - } - -//cerr << endl << "Test reading an ecub that points to detached lbl" << endl; -//{ -// Cube externalData; -// externalData.setExternalDnData("$TMP/IsisCube_02.lbl"); -// externalData.create("$TMP/isisTruth_external3.ecub"); -// cerr << *externalData.label() << endl; -// -// Brick readBrick(3, 3, 2, externalData.pixelType()); -// readBrick.SetBasePosition(1, 1, 1); -// externalData.read(readBrick); -// for (int index = 0; index < readBrick.size(); index++) { -// if (readBrick[index] == Null) { -// cerr << "N "; -// } -// else { -// cerr << readBrick[index] << " "; -// } -// } -// cerr << endl; -// -// try { -// externalData.write(readBrick); -// } -// catch (IException &e) { -// e.print(); -// } -//} -// -//cerr << endl << "Test copying an ecub that points to detached lbl" << endl; -//{ -// Cube externalData; -// externalData.open("$TMP/isisTruth_external3.ecub"); -// Cube *copiedCube = externalData.copy("$TMP/isisTruth_external3.copy.ecub", -// CubeAttributeOutput("+External")); -// cerr << *copiedCube->label() << endl; -// -// Brick readBrick(3, 3, 2, copiedCube->pixelType()); -// readBrick.SetBasePosition(1, 1, 1); -// copiedCube->read(readBrick); -// for (int index = 0; index < readBrick.size(); index++) { -// if (readBrick[index] == Null) { -// cerr << "N "; -// } -// else { -// cerr << readBrick[index] << " "; -// } -// } -// cerr << endl; -// -// try { -// copiedCube->write(readBrick); -// } -// catch (IException &e) { -// e.print(); -// } -// // need to deallocate our copied cube -// copiedCube->close(); -// delete copiedCube; -// copiedCube = NULL; -// -//} - - remove("$TMP/IsisCube_00.cub"); - remove("$TMP/IsisCube_01.cub"); - remove("$TMP/IsisCube_02.cub"); - remove("$TMP/IsisCube_02.lbl"); - remove("$TMP/IsisCube_03.cub"); - remove("$TMP/IsisCube_04.cub"); - remove("$TMP/IsisCube_05.cub"); - remove("$TMP/IsisCube_06.cub"); - remove("$TMP/IsisCube_boundary.cub"); - remove("$TMP/IsisCube_bsq.cub"); - remove("$TMP/IsisCube_bsqOneLine.cub"); - remove("$TMP/IsisCube_largebsq.cub"); - remove("$TMP/isisTruth_external.ecub"); - remove("$TMP/isisTruth_external2.ecub"); - // remove("$TMP/isisTruth_external3.ecub"); - // remove("$TMP/isisTruth_external3.copy.ecub"); - - return 0; -} - - -void Report(Cube &c) { - cerr << "File = " << IString(QFileInfo(c.fileName()).fileName()) << endl; - cerr << "Samps = " << c.sampleCount() << endl; - cerr << "Lines = " << c.lineCount() << endl; - cerr << "Bands = " << c.bandCount() << endl; - cerr << "Base = " << c.base() << endl; - cerr << "Mult = " << c.multiplier() << endl; - cerr << "Type = " << c.pixelType() << endl; -// cerr << "Order = " << c.ByteOrder() << endl; // Needs to be system independent - cerr << "Atchd = " << c.labelsAttached() << endl; - cerr << "Format = " << c.format() << endl; - cerr << "Open = " << c.isOpen() << endl; - try { - cerr << "R/O = "; - cerr.flush(); - cerr << c.isReadOnly(); - } - catch (IException &e) { - cerr << "N/A"; - } - - cerr << endl; - - try { - cerr << "R/W = "; - cerr.flush(); - cerr << c.isReadWrite(); - } - catch (IException &e) { - cerr << "N/A"; - } - - cerr << endl; - cerr << "Lbytes = " << c.labelSize() << endl; - cerr << endl; -} diff --git a/isis/tests/CubeBsqHandlerTests.cpp b/isis/tests/CubeBsqHandlerTests.cpp new file mode 100644 index 0000000000..6b07c10e06 --- /dev/null +++ b/isis/tests/CubeBsqHandlerTests.cpp @@ -0,0 +1,563 @@ +#include +#include +#include + +#include +using json = nlohmann::json; + +#include "Brick.h" +#include "CubeIoHandler.h" +#include "CubeBsqHandler.h" +#include "CubeTileHandler.h" +#include "LineManager.h" +#include "SpecialPixel.h" + +#include "CubeFixtures.h" +#include "TestUtilities.h" + +#include "gmock/gmock.h" + +using namespace Isis; + +TEST_F(SmallCube, TestCubeBsqHandlerRead) { + QString path = testCube->fileName(); + QFile dataFile(path); + if (!dataFile.open(QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + CubeBsqHandler ioHandler(&dataFile, nullptr, *testCube->label(), true); + Brick readBrick(1, 1, 2, testCube->pixelType()); + readBrick.SetBasePosition(1, 1, 1); + ioHandler.read(readBrick); + + EXPECT_EQ(readBrick.size(), 2); + EXPECT_EQ(readBrick[0], 0); + EXPECT_EQ(readBrick[1], 100); +} + +TEST_F(SmallCube, TestCubeBsqHandlerReadPastBoundary) { + QString path = testCube->fileName(); + QFile dataFile(path); + if (!dataFile.open(QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + CubeBsqHandler ioHandler(&dataFile, nullptr, *testCube->label(), true); + Brick readBrick(1, 1, 2, testCube->pixelType()); + readBrick.SetBasePosition(1, 1, -1); + ioHandler.read(readBrick); + + EXPECT_EQ(readBrick.size(), 2); + EXPECT_EQ(readBrick[0], NULL8); + EXPECT_EQ(readBrick[1], NULL8); +} + +TEST_F(SmallCube, TestCubeBsqHandlerReadBeforeStart) { + QString path = testCube->fileName(); + QFile dataFile(path); + if (!dataFile.open(QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + CubeBsqHandler ioHandler(&dataFile, nullptr, *testCube->label(), true); + Brick readBrick(1, 1, 2, testCube->pixelType()); + readBrick.SetBasePosition(1, 1, 0); + ioHandler.read(readBrick); + + EXPECT_EQ(readBrick.size(), 2); + EXPECT_EQ(readBrick[0], NULL8); + EXPECT_EQ(readBrick[1], 0); +} + +TEST_F(SmallCube, TestCubeBsqHandlerReadAfterEnd) { + QString path = testCube->fileName(); + QFile dataFile(path); + if (!dataFile.open(QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + CubeBsqHandler ioHandler(&dataFile, nullptr, *testCube->label(), true); + Brick readBrick(1, 1, 2, testCube->pixelType()); + readBrick.SetBasePosition(1, 1, 10); + ioHandler.read(readBrick); + + EXPECT_EQ(readBrick.size(), 2); + EXPECT_EQ(readBrick[0], 900); + EXPECT_EQ(readBrick[1], NULL8); +} + +TEST_F(SmallCube, TestCubeBsqHandlerReadOutsideVirtualBands) { + QString path = testCube->fileName(); + QFile dataFile(path); + if (!dataFile.open(QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + QList virtualBands; + virtualBands.push_back(2); + virtualBands.push_back(1); + virtualBands.push_back(3); + virtualBands.push_back(4); + virtualBands.push_back(2); + CubeBsqHandler ioHandler(&dataFile, &virtualBands, *testCube->label(), true); + Brick readBrick(1, 1, 2, testCube->pixelType()); + readBrick.SetBasePosition(1, 1, 6); + ioHandler.read(readBrick); + + EXPECT_EQ(readBrick.size(), 2); + EXPECT_EQ(readBrick[0], NULL8); + EXPECT_EQ(readBrick[1], NULL8); + + readBrick.SetBasePosition(1, 1, 1000); + ioHandler.read(readBrick); + + EXPECT_EQ(readBrick[0], NULL8); + EXPECT_EQ(readBrick[1], NULL8); + + + readBrick.SetBasePosition(1, 1, -1); + ioHandler.read(readBrick); + + EXPECT_EQ(readBrick[0], NULL8); + EXPECT_EQ(readBrick[1], NULL8); +} + +TEST_F(SmallCube, TestCubeBsqHandlerReadEdgeVirtualBands) { + QString path = testCube->fileName(); + QFile dataFile(path); + if (!dataFile.open(QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + QList virtualBands; + virtualBands.push_back(2); + virtualBands.push_back(1); + virtualBands.push_back(3); + virtualBands.push_back(4); + virtualBands.push_back(2); + CubeBsqHandler ioHandler(&dataFile, &virtualBands, *testCube->label(), true); + Brick readBrick(1, 1, 2, testCube->pixelType()); + readBrick.SetBasePosition(1, 1, 0); + ioHandler.read(readBrick); + + EXPECT_EQ(readBrick.size(), 2); + EXPECT_EQ(readBrick[0], NULL8); + EXPECT_EQ(readBrick[1], 100); + + readBrick.SetBasePosition(1, 1, 5); + ioHandler.read(readBrick); + + EXPECT_EQ(readBrick.size(), 2); + EXPECT_EQ(readBrick[0], 100); + EXPECT_EQ(readBrick[1], NULL8); +} + +TEST_F(SmallCube, TestCubeBsqHandlerReadVirtualBands) { + QString path = testCube->fileName(); + QFile dataFile(path); + if (!dataFile.open(QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + QList virtualBands; + virtualBands.push_back(2); + virtualBands.push_back(1); + virtualBands.push_back(3); + virtualBands.push_back(4); + virtualBands.push_back(2); + virtualBands.push_back(2); + virtualBands.push_back(1); + virtualBands.push_back(3); + virtualBands.push_back(4); + virtualBands.push_back(2); + CubeBsqHandler ioHandler(&dataFile, &virtualBands, *testCube->label(), true); + Brick readBrick(1, 1, 20, testCube->pixelType()); + readBrick.SetBasePosition(1, 1, -4); + ioHandler.read(readBrick); + + EXPECT_EQ(readBrick.size(), 20); + for (int i = 0; i < 5; i++) { + EXPECT_EQ(readBrick[i], NULL8); + } + EXPECT_EQ(readBrick[5], 100); + EXPECT_EQ(readBrick[6], 0); + EXPECT_EQ(readBrick[7], 200); + EXPECT_EQ(readBrick[8], 300); + EXPECT_EQ(readBrick[9], 100); + EXPECT_EQ(readBrick[10], 100); + EXPECT_EQ(readBrick[11], 0); + EXPECT_EQ(readBrick[12], 200); + EXPECT_EQ(readBrick[13], 300); + EXPECT_EQ(readBrick[14], 100); + for (int i = 15; i < 20; i++) { + EXPECT_EQ(readBrick[i], NULL8); + } +} + +class BsqCube : public TempTestingFiles { + protected: + Cube *testCube; + + void SetUp() override { + TempTestingFiles::SetUp(); + + testCube = new Cube(); + testCube->setDimensions(3, 1, 3); + testCube->setFormat(Cube::Bsq); + QString path = tempDir.path() + "/small.cub"; + testCube->create(path); + + LineManager line(*testCube); + // our cube will be 1, 2, 3 + // 2, 3, 4 + // 3, 4, 5 + for (line.begin(); !line.end(); line++) { + for (int i = 0; i < line.size(); i++) { + line[i] = 1 * i + line.Band(); + } + testCube->write(line); + } + + // Add a BandBin group to the cube label + Pvl *label = testCube->label(); + PvlObject& cubeLabel = label->findObject("IsisCube"); + PvlGroup bandBin("BandBin"); + PvlKeyword originalBand("OriginalBand", "1"); + originalBand += "2"; + originalBand += "3"; + bandBin += originalBand; + cubeLabel.addGroup(bandBin); + testCube->close(); + testCube->open(path, "rw"); + } + + void TearDown() override { + if (testCube->isOpen()) { + testCube->close(); + } + + if (testCube) { + delete testCube; + } + } +}; + +TEST_F(BsqCube, TestCubeBsqHandlerReadRepeatedAscendingVBands) { + QString path = testCube->fileName(); + QFile dataFile(path); + if (!dataFile.open(QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + QList virtualBands; + virtualBands.push_back(1); + virtualBands.push_back(2); + virtualBands.push_back(2); + virtualBands.push_back(3); + CubeBsqHandler ioHandler(&dataFile, &virtualBands, *testCube->label(), true); + Brick readBrick(3, 1, 1, testCube->pixelType()); + + for (int sb = 1; sb <= virtualBands.size(); sb++) { + readBrick.SetBasePosition(1, 1, sb); + ioHandler.read(readBrick); + for (int i = 0; i < readBrick.size(); i++) { + EXPECT_EQ(readBrick[i], (i + virtualBands[readBrick.Band()-1])); + } + } +} + +TEST_F(BsqCube, TestCubeBsqHandlerReadSkippedAscendingVBands) { + QString path = testCube->fileName(); + QFile dataFile(path); + if (!dataFile.open(QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + QList virtualBands; + virtualBands.push_back(1); + virtualBands.push_back(3); + virtualBands.push_back(3); + CubeBsqHandler ioHandler(&dataFile, &virtualBands, *testCube->label(), true); + Brick readBrick(3, 1, 1, testCube->pixelType()); + + for (int sb = 1; sb <= virtualBands.size(); sb++) { + readBrick.SetBasePosition(1, 1, sb); + ioHandler.read(readBrick); + for (int i = 0; i < readBrick.size(); i++) { + EXPECT_EQ(readBrick[i], (i + virtualBands[readBrick.Band()-1])); + } + } +} + +TEST_F(BsqCube, TestCubeBsqHandlerReadOutOfBoundsVBands) { + QString path = testCube->fileName(); + QFile dataFile(path); + if (!dataFile.open(QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + QList virtualBands; + virtualBands.push_back(1); + virtualBands.push_back(5); + CubeBsqHandler ioHandler(&dataFile, &virtualBands, *testCube->label(), true); + Brick readBrick(3, 1, 1, testCube->pixelType()); + for (int sb = 1; sb <= virtualBands.size(); sb++) { + for (int i = 0; i < readBrick.size(); i++) { + readBrick.SetBasePosition(1, 1, sb); + ioHandler.read(readBrick); + if (readBrick.Band() == 1) { + EXPECT_EQ(readBrick[i], (i + virtualBands[readBrick.Band()-1])); + } + else { + EXPECT_EQ(readBrick[i], Null); + } + } + } +} + +TEST_F(BsqCube, TestCubeBsqHandlerReadDescendingVBands) { + QString path = testCube->fileName(); + QFile dataFile(path); + if (!dataFile.open(QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + QList virtualBands; + virtualBands.push_back(3); + virtualBands.push_back(1); + virtualBands.push_back(3); + CubeBsqHandler ioHandler(&dataFile, &virtualBands, *testCube->label(), true); + Brick readBrick(3, 1, 1, testCube->pixelType()); + + for (int sb = 1; sb <= virtualBands.size(); sb++) { + readBrick.SetBasePosition(1, 1, sb); + ioHandler.read(readBrick); + for (int i = 0; i < readBrick.size(); i++) { + EXPECT_EQ(readBrick[i], (i + virtualBands[readBrick.Band()-1])); + } + } +} + +TEST_F(TempTestingFiles, TestCubeBsqHandlerExceedSampleSizeLimit) { + std::istringstream labelStrm(R"( + Object = IsisCube + Object = Core + StartByte = 65537 + Format = Bsq + + Group = Dimensions + Samples = 268435457 + Lines = 2 + Bands = 1 + End_Group + + Group = Pixels + Type = Real + ByteOrder = Lsb + Base = 0.0 + Multiplier = 1.0 + End_Group + End_Object + + Group = Instrument + SpacecraftName = VIKING_ORBITER_1 + InstrumentId = VISUAL_IMAGING_SUBSYSTEM_CAMERA_B + TargetName = MARS + StartTime = 1977-07-09T20:05:51 + ExposureDuration = 0.008480 + SpacecraftClockCount = 33322515 + FloodModeId = ON + GainModeId = HIGH + OffsetModeId = ON + End_Group + + Group = Archive + DataSetId = VO1/VO2-M-VIS-2-EDR-V2.0 + ProductId = 387A06 + MissonPhaseName = EXTENDED_MISSION + ImageNumber = 33322515 + OrbitNumber = 387 + End_Group + + Group = BandBin + FilterName = CLEAR + FilterId = 4 + End_Group + + Group = Kernels + NaifFrameCode = -27002 + LeapSecond = $base/kernels/lsk/naif0012.tls + TargetAttitudeShape = $base/kernels/pck/pck00009.tpc + TargetPosition = (Table, $base/kernels/spk/de430.bsp, + $base/kernels/spk/mar097.bsp) + InstrumentPointing = (Table, $viking1/kernels/ck/vo1_sedr_ck2.bc, + $viking1/kernels/fk/vo1_v10.tf) + Instrument = Null + SpacecraftClock = ($viking1/kernels/sclk/vo1_fict.tsc, + $viking1/kernels/sclk/vo1_fsc.tsc) + InstrumentPosition = (Table, $viking1/kernels/spk/viking1a.bsp) + InstrumentAddendum = $viking1/kernels/iak/vikingAddendum003.ti + ShapeModel = $base/dems/molaMarsPlanetaryRadius0005.cub + InstrumentPositionQuality = Reconstructed + InstrumentPointingQuality = Reconstructed + CameraVersion = 1 + End_Group + + Group = Reseaus + Line = (5, 6, 8, 9, 10, 11, 12, 13, 14, 14, 15, 133, 134, 135, 137, + 138, 139, 140, 141, 141, 142, 143, 144, 263, 264, 266, 267, + 268, 269, 269, 270, 271, 272, 273, 393, 393, 395, 396, 397, + 398, 399, 399, 400, 401, 402, 403, 523, 524, 525, 526, 527, + 527, 528, 529, 530, 530, 532, 652, 652, 654, 655, 656, 657, + 657, 658, 659, 660, 661, 662, 781, 783, 784, 785, 786, 787, + 788, 788, 789, 790, 791, 911, 912, 913, 914, 915, 916, 917, + 918, 918, 919, 920, 921, 1040, 1041, 1043, 1044, 1045, 1045, + 1046, 1047, 1047, 1048, 1050) + Sample = (24, 142, 259, 375, 491, 607, 723, 839, 954, 1070, 1185, 24, + 84, 201, 317, 433, 549, 665, 780, 896, 1011, 1127, 1183, 25, + 142, 259, 375, 492, 607, 722, 838, 953, 1068, 1183, 25, 84, + 201, 317, 433, 549, 665, 779, 895, 1010, 1125, 1182, 25, 143, + 259, 375, 491, 607, 722, 837, 952, 1067, 1182, 25, 84, 201, + 317, 433, 548, 664, 779, 894, 1009, 1124, 1181, 25, 142, 258, + 374, 490, 605, 720, 835, 951, 1066, 1180, 24, 83, 200, 316, + 431, 547, 662, 776, 892, 1007, 1122, 1179, 23, 140, 257, 373, + 488, 603, 718, 833, 948, 1063, 1179) + Type = (1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 4, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 4, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6) + Valid = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + Template = $viking1/reseaus/vo1.visb.template.cub + Status = Nominal + End_Group + End_Object + End + )"); + + Pvl label; + labelStrm >> label; + + QString path = tempDir.path() + "/test_cube.cub"; + QFile dataFile(path); + if (!dataFile.open(QIODevice::Truncate | QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + + CubeBsqHandler ioHandler(&dataFile, nullptr, label, false); + EXPECT_EQ(ioHandler.getBytesPerChunk(), 1073741828); + EXPECT_EQ(ioHandler.getChunkCountInSampleDimension(), 1); + EXPECT_EQ(ioHandler.getSampleCountInChunk(), 268435457); + EXPECT_EQ(ioHandler.getLineCountInChunk(), 1); +} + +TEST_F(TempTestingFiles, TestCubeBsqHandlerExceedMaximumChunkLineSize) { + std::istringstream labelStrm(R"( + Object = IsisCube + Object = Core + StartByte = 65537 + Format = Bsq + + Group = Dimensions + Samples = 15000 + Lines = 18000 + Bands = 1 + End_Group + + Group = Pixels + Type = Real + ByteOrder = Lsb + Base = 0.0 + Multiplier = 1.0 + End_Group + End_Object + + Group = Instrument + SpacecraftName = VIKING_ORBITER_1 + InstrumentId = VISUAL_IMAGING_SUBSYSTEM_CAMERA_B + TargetName = MARS + StartTime = 1977-07-09T20:05:51 + ExposureDuration = 0.008480 + SpacecraftClockCount = 33322515 + FloodModeId = ON + GainModeId = HIGH + OffsetModeId = ON + End_Group + + Group = Archive + DataSetId = VO1/VO2-M-VIS-2-EDR-V2.0 + ProductId = 387A06 + MissonPhaseName = EXTENDED_MISSION + ImageNumber = 33322515 + OrbitNumber = 387 + End_Group + + Group = BandBin + FilterName = CLEAR + FilterId = 4 + End_Group + + Group = Kernels + NaifFrameCode = -27002 + LeapSecond = $base/kernels/lsk/naif0012.tls + TargetAttitudeShape = $base/kernels/pck/pck00009.tpc + TargetPosition = (Table, $base/kernels/spk/de430.bsp, + $base/kernels/spk/mar097.bsp) + InstrumentPointing = (Table, $viking1/kernels/ck/vo1_sedr_ck2.bc, + $viking1/kernels/fk/vo1_v10.tf) + Instrument = Null + SpacecraftClock = ($viking1/kernels/sclk/vo1_fict.tsc, + $viking1/kernels/sclk/vo1_fsc.tsc) + InstrumentPosition = (Table, $viking1/kernels/spk/viking1a.bsp) + InstrumentAddendum = $viking1/kernels/iak/vikingAddendum003.ti + ShapeModel = $base/dems/molaMarsPlanetaryRadius0005.cub + InstrumentPositionQuality = Reconstructed + InstrumentPointingQuality = Reconstructed + CameraVersion = 1 + End_Group + + Group = Reseaus + Line = (5, 6, 8, 9, 10, 11, 12, 13, 14, 14, 15, 133, 134, 135, 137, + 138, 139, 140, 141, 141, 142, 143, 144, 263, 264, 266, 267, + 268, 269, 269, 270, 271, 272, 273, 393, 393, 395, 396, 397, + 398, 399, 399, 400, 401, 402, 403, 523, 524, 525, 526, 527, + 527, 528, 529, 530, 530, 532, 652, 652, 654, 655, 656, 657, + 657, 658, 659, 660, 661, 662, 781, 783, 784, 785, 786, 787, + 788, 788, 789, 790, 791, 911, 912, 913, 914, 915, 916, 917, + 918, 918, 919, 920, 921, 1040, 1041, 1043, 1044, 1045, 1045, + 1046, 1047, 1047, 1048, 1050) + Sample = (24, 142, 259, 375, 491, 607, 723, 839, 954, 1070, 1185, 24, + 84, 201, 317, 433, 549, 665, 780, 896, 1011, 1127, 1183, 25, + 142, 259, 375, 492, 607, 722, 838, 953, 1068, 1183, 25, 84, + 201, 317, 433, 549, 665, 779, 895, 1010, 1125, 1182, 25, 143, + 259, 375, 491, 607, 722, 837, 952, 1067, 1182, 25, 84, 201, + 317, 433, 548, 664, 779, 894, 1009, 1124, 1181, 25, 142, 258, + 374, 490, 605, 720, 835, 951, 1066, 1180, 24, 83, 200, 316, + 431, 547, 662, 776, 892, 1007, 1122, 1179, 23, 140, 257, 373, + 488, 603, 718, 833, 948, 1063, 1179) + Type = (1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 4, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 4, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6) + Valid = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + Template = $viking1/reseaus/vo1.visb.template.cub + Status = Nominal + End_Group + End_Object + End + )"); + + Pvl label; + labelStrm >> label; + + QString path = tempDir.path() + "/test_cube.cub"; + QFile dataFile(path); + if (!dataFile.open(QIODevice::Truncate | QIODevice::ReadWrite)) { + FAIL() << "Unable to open dataFile in ReadWrite"; + } + + CubeBsqHandler ioHandler(&dataFile, nullptr, label, false); + EXPECT_EQ(ioHandler.getBytesPerChunk(), 540000000); + EXPECT_EQ(ioHandler.getChunkCountInSampleDimension(), 1); + EXPECT_EQ(ioHandler.getSampleCountInChunk(), 15000); + EXPECT_EQ(ioHandler.getLineCountInChunk(), 9000); +} \ No newline at end of file diff --git a/isis/tests/CubeTests.cpp b/isis/tests/CubeTests.cpp index 91348eb305..7f14bb1c92 100644 --- a/isis/tests/CubeTests.cpp +++ b/isis/tests/CubeTests.cpp @@ -6,8 +6,13 @@ using json = nlohmann::json; #include "Blob.h" -#include "Cube.h" +#include "Brick.h" #include "Camera.h" +#include "Cube.h" +#include "CubeAttribute.h" +#include "Histogram.h" +#include "LineManager.h" +#include "Statistics.h" #include "CubeFixtures.h" #include "TestUtilities.h" @@ -16,6 +21,38 @@ using json = nlohmann::json; using namespace Isis; + +void check_cube(Cube &cube, + QString &file, + int sampleCount, + int lineCount, + int bandCount, + double base, + double multiplier, + int pixelType, + bool attached, + int format, + int isOpen, + int isReadOnly, + int isReadWrite, + int labelSize) { + EXPECT_EQ(cube.fileName().toStdString(), file.toStdString()); + EXPECT_EQ(cube.sampleCount(), sampleCount); + EXPECT_EQ(cube.lineCount(), lineCount); + EXPECT_EQ(cube.bandCount(), bandCount); + EXPECT_EQ(cube.base(), base); + EXPECT_EQ(cube.multiplier(), multiplier); + EXPECT_EQ(cube.pixelType(), pixelType); + EXPECT_EQ(cube.labelsAttached(), attached); + EXPECT_EQ(cube.format(), format); + EXPECT_EQ(cube.isOpen(), isOpen); + if (cube.isOpen()) { + EXPECT_EQ(cube.isReadOnly(), isReadOnly); + EXPECT_EQ(cube.isReadWrite(), isReadWrite); + } + EXPECT_EQ(cube.labelSize(), labelSize); +} + TEST(CubeTest, TestCubeAttachSpiceFromIsd) { std::istringstream labelStrm(R"( Object = IsisCube @@ -239,3 +276,587 @@ TEST_F(SmallCube, TestCubeHasBlob) { EXPECT_TRUE(testCube->hasBlob("TestBlob", "SomeBlob")); EXPECT_FALSE(testCube->hasBlob("SomeOtherTestBlob", "SomeBlob")); } + +TEST_F(TempTestingFiles, TestCubeCreateWriteCopy) { + Cube out; + QString file = ""; + check_cube(out, file, 0, 0, 0, 0, 1, 7, 1, 1, 0, 0, 0, 65536); + out.setDimensions(150, 200, 2); + file = QString(tempDir.path() + "/IsisCube_00.cub"); + out.create(file); + check_cube(out, file, 150, 200, 2, 0, 1, 7, 1, 1, 1, 0, 1, 65536); + + LineManager line(out); + long j = 0; + for(line.begin(); !line.end(); line++) { + for(int i = 0; i < line.size(); i++) { + line[i] = (double) j; + j++; + } + j--; + out.write(line); + } + + // Copy returns the resulting Cube, we don't care about it (but we need it to flush) so delete + QString file2 = tempDir.path() + "/IsisCube_01.cub"; + delete out.copy(file2, CubeAttributeOutput()); + out.close(); + + // Test the open and read methods + Cube in(file2); + check_cube(in, file2, 150, 200, 2, 0, 1, 7, 1, 1, 1, 1, 0, 6563); + + LineManager inLine(in); + j = 0; + for(inLine.begin(); !inLine.end(); inLine++) { + in.read(inLine); + for(int i = 0; i < inLine.size(); i++) { + EXPECT_NEAR(inLine[i], (double) j, 1e-15); + j++; + } + j--; + } + in.close(); +} + +TEST_F(TempTestingFiles, TestCubeCreateWrite8bit) { + Cube out; + QString file = ""; + check_cube(out, file, 0, 0, 0, 0, 1, 7, 1, 1, 0, 0, 0, 65536); + out.setDimensions(150, 200, 1); + out.setLabelsAttached(0); + out.setBaseMultiplier(200.0, -1.0); + out.setByteOrder(ISIS_LITTLE_ENDIAN ? Msb : Lsb); + out.setFormat(Cube::Bsq); + out.setLabelSize(1000); + out.setPixelType(UnsignedByte); + check_cube(out, file, 150, 200, 1, 200, -1, 1, 0, 0, 0, 0, 0, 1000); + file = QString(tempDir.path() + "/IsisCube_00.cub"); + out.create(file); + + long j = 0; + LineManager oline(out); + for(oline.begin(); !oline.end(); oline++) { + for(int i = 0; i < oline.size(); i++) { + oline[i] = (double) j; + } + out.clearIoCache(); + out.write(oline); + j++; + } + out.close(); + + Cube in; + file = QString(tempDir.path() + "/IsisCube_00.lbl"); + try { + in.open(file); + } + catch (IException &e) { + e.print(); + } + check_cube(in, file, 150, 200, 1, 200, -1, 1, 0, 0, 1, 1, 0, 419); + j = 0; + LineManager inLine(in); + for(inLine.begin(); !inLine.end(); inLine++) { + in.read(inLine ); + for(int i = 0; i < inLine.size(); i++) { + EXPECT_NEAR(inLine[i], (double) j, 1e-15); + } + in.clearIoCache(); + j++; + } + in.close(); +} + +TEST_F(TempTestingFiles, TestCubeCreateWrite16bit) { + Cube out; + QString file = ""; + check_cube(out, file, 0, 0, 0, 0, 1, 7, 1, 1, 0, 0, 0, 65536); + out.setDimensions(150, 200, 2); + out.setBaseMultiplier(30000.0, -1.0); + out.setByteOrder(ISIS_LITTLE_ENDIAN ? Msb : Lsb); + out.setPixelType(SignedWord); + check_cube(out, file, 150, 200, 2, 30000, -1, 4, 1, 1, 0, 0, 0, 65536); + file = QString(tempDir.path() + "/IsisCube.cub"); + out.create(file); + + long j = 0; + LineManager oline(out); + for(oline.begin(); !oline.end(); oline++) { + for(int i = 0; i < oline.size(); i++) { + oline[i] = (double) j; + } + out.clearIoCache(); + out.write(oline); + j++; + } + out.close(); + + Cube in; + try { + in.open(file); + } + catch (IException &e) { + e.print(); + } + check_cube(in, file, 150, 200, 2, 30000, -1, 4, 1, 1, 1, 1, 0, 65536); + j = 0; + LineManager inLine(in); + for(inLine.begin(); !inLine.end(); inLine++) { + in.read(inLine ); + for(int i = 0; i < inLine.size(); i++) { + EXPECT_NEAR(inLine[i], (double) j, 1e-15); + } + in.clearIoCache(); + j++; + } + in.close(); +} + +TEST_F(SmallCube, TestCubeHistorgramBand1) { + Histogram *bandHist = testCube->histogram(1); + EXPECT_DOUBLE_EQ(bandHist->Average(), 49.5); + EXPECT_DOUBLE_EQ(bandHist->StandardDeviation(), 29.011491975882016); + EXPECT_DOUBLE_EQ(bandHist->Mode(), 0); + EXPECT_DOUBLE_EQ(bandHist->TotalPixels(), 100); + EXPECT_DOUBLE_EQ(bandHist->NullPixels(), 0); + delete bandHist; +} + +TEST_F(SmallCube, TestCubeHistorgramAll) { + Histogram *bandHist = testCube->histogram(0); + EXPECT_DOUBLE_EQ(bandHist->Average(), 499.5); + EXPECT_DOUBLE_EQ(bandHist->StandardDeviation(), 288.81943609574938); + EXPECT_DOUBLE_EQ(bandHist->Mode(), 0); + EXPECT_DOUBLE_EQ(bandHist->TotalPixels(), 1000); + EXPECT_DOUBLE_EQ(bandHist->NullPixels(), 0); + delete bandHist; +} + +TEST_F(SmallCube, TestCubeStatisticsBand1) { + Statistics *bandHist = testCube->statistics(1); + EXPECT_DOUBLE_EQ(bandHist->Average(), 49.5); + EXPECT_DOUBLE_EQ(bandHist->StandardDeviation(), 29.011491975882016); + EXPECT_DOUBLE_EQ(bandHist->TotalPixels(), 100); + EXPECT_DOUBLE_EQ(bandHist->NullPixels(), 0); + delete bandHist; +} + +TEST_F(SmallCube, TestCubeStatisticsAll) { + Statistics *bandHist = testCube->statistics(0); + EXPECT_DOUBLE_EQ(bandHist->Average(), 499.5); + EXPECT_DOUBLE_EQ(bandHist->StandardDeviation(), 288.81943609574938); + EXPECT_DOUBLE_EQ(bandHist->TotalPixels(), 1000); + EXPECT_DOUBLE_EQ(bandHist->NullPixels(), 0); + delete bandHist; +} + +TEST_F(SmallCube, TestCubeNegativeHistStatsBand) { + try { + testCube->histogram(-1); + FAIL() << "Expected an exception to be thrown"; + } + catch (IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Invalid band in [CubeInfo::Histogram]")) + << e.toString().toStdString(); + } + + try { + testCube->statistics(-1); + FAIL() << "Expected an exception to be thrown"; + } + catch (IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Invalid band in [CubeInfo::Statistics]")) + << e.toString().toStdString(); + } +} + +TEST(CubeTest, TestCubeNoHistStats) { + Cube cube; + try { + cube.histogram(); + FAIL() << "Expected an exception to be thrown"; + } + catch (IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Cannot create histogram object for an unopened cube")) + << e.toString().toStdString(); + } + + try { + cube.statistics(); + FAIL() << "Expected an exception to be thrown"; + } + catch (IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Cannot create statistics object for an unopened cube")) + << e.toString().toStdString(); + } +} + +TEST_F(SmallCube, TestCubePhyscialBands) { + EXPECT_EQ(testCube->bandCount(), 10); + for (int i = 0; i < testCube->bandCount(); i++) { + EXPECT_EQ(testCube->physicalBand(i), i); + } +} + +TEST_F(SmallCube, TestCubeVirutalBands) { + QString path = testCube->fileName(); + testCube->close(); + QList vbands = {"2", "3", "4", "5", "6", "7", "8", "9", "10"}; + testCube->setVirtualBands(vbands); + testCube->open(path); + EXPECT_EQ(testCube->bandCount(), 9); + for (int i = 1; i < vbands.size() + 1; i++) { + EXPECT_EQ(testCube->physicalBand(i), i + 1); + } +} + +TEST_F(SmallCube, TestCubeReopenRW) { + QString path = testCube->fileName(); + check_cube(*testCube, path, 10, 10, 10, 0, 1, 7, 1, 1, 1, 0, 1, 65536); + testCube->reopen("rw"); + check_cube(*testCube, path, 10, 10, 10, 0, 1, 7, 1, 1, 1, 0, 1, 65536); +} + +TEST_F(SmallCube, TestCubeReopenR) { + QString path = testCube->fileName(); + check_cube(*testCube, path, 10, 10, 10, 0, 1, 7, 1, 1, 1, 0, 1, 65536); + testCube->reopen("r"); + check_cube(*testCube, path, 10, 10, 10, 0, 1, 7, 1, 1, 1, 1, 0, 65536); +} + +TEST_F(SmallCube, TestCubeAlreadyOpenOpen) { + try { + testCube->open("blah"); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("You already have a cube opened.")) + << e.toString().toStdString(); + } +} + +TEST_F(SmallCube, TestCubeAlreadyOpenCreate) { + try { + testCube->create("blah"); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("You already have a cube opened.")) + << e.toString().toStdString(); + } +} + +TEST_F(TempTestingFiles, TestCubeWriteToReadOnly) { + Cube testCube; + QString file = QString(tempDir.path() + "/IsisCube_00.cub"); + testCube.setDimensions(10, 10, 1); + testCube.create(file); + testCube.close(); + testCube.open(file, "r"); + LineManager line(testCube); + double pixelValue = 0.0; + for(int i = 0; i < line.size(); i++) { + line[i] = (double) pixelValue++; + } + + try { + testCube.write(line); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Cannot write to the cube [IsisCube_00.cub] because it is opened read-only.")) + << e.toString().toStdString(); + } +} + +TEST(CubeTest, TestCubeOpenNonexistentCube) { + try { + Cube testCube; + testCube.open("blah"); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Unable to open [blah].")) + << e.toString().toStdString(); + } +} + +TEST_F(SmallCube, TestCubePhyscialBandOutOfBounds) { + QString path = testCube->fileName(); + testCube->close(); + QList vbands = {"1", "2", "3", "4", "5"}; + testCube->setVirtualBands(vbands); + testCube->open(path); + try { + std::cout << testCube->bandCount() << std::endl; + int band = testCube->physicalBand(6); + std::cout << band << std::endl; + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Out of array bounds [6].")) + << e.toString().toStdString(); + } + + try { + testCube->physicalBand(0); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Out of array bounds [0].")) + << e.toString().toStdString(); + } +} + +TEST(CubeTest, TestCubeReadBlankCube) { + Cube testCube; + testCube.setDimensions(10, 10, 1); + LineManager line(testCube); + try { + testCube.read(line); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Try opening a file before you read it.")) + << e.toString().toStdString(); + } +} + +TEST(CubeTest, TestCubeWriteBlankCube) { + Cube testCube; + testCube.setDimensions(10, 10, 1); + LineManager line(testCube); + double pixelValue = 0.0; + for(int i = 0; i < line.size(); i++) { + line[i] = (double) pixelValue++; + } + try { + testCube.write(line); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Tried to write to a cube before opening/creating it.")) + << e.toString().toStdString(); + } +} + +TEST_F(TempTestingFiles, TestCubeCreateZeroDimCube) { + Cube testCube; + try { + testCube.create(tempDir.path() + "/IsisCube_00.cub"); + testCube.close(); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Number of samples [0], lines [0], or bands [0] cannot be less than 1.")) + << e.toString().toStdString(); + } +} + +TEST_F(TempTestingFiles, TestCubeCreateSmallLabel) { + Cube testCube; + try { + testCube.setLabelSize(15); + testCube.setDimensions(1, 1, 1); + testCube.create(tempDir.path() + "/IsisCube_00.cub"); + testCube.close(); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Label space is full in [IsisCube_00.cub] unable to write labels.")) + << e.toString().toStdString(); + } +} + +TEST_F(TempTestingFiles, TestCubeCreateTooBig) { + Cube testCube; + try { + testCube.setDimensions(1000000, 1000000, 9); + testCube.create("IsisCube_00.cub"); + testCube.close(); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("The cube you are attempting to create [IsisCube_00.cub] is [33527GB]. " + "This is larger than the current allowed size of [12GB]. The cube " + "dimensions were (S,L,B) [1000000, 1000000, 9] with [4] bytes per pixel. " + "If you still wish to create this cube, the maximum value can be changed " + "in your personal preference file located in [~/.Isis/IsisPreferences] " + "within the group CubeCustomization, keyword MaximumSize. If you do not have " + "an ISISPreference file, please refer to the documentation 'Environment and Preference Setup'. Error.")) + << e.toString().toStdString(); + } +} + +TEST_F(SmallCube, TestCubeOpenBadAccessor) { + try { + Cube localTestCube; + localTestCube.open(testCube->fileName(), "a"); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Unknown value for access [a]. Expected 'r' or 'rw'.")) + << e.toString().toStdString(); + } +} + +TEST(CubeTest, TestCubeInvalidDimSamples) { + try { + Cube testCube; + testCube.setDimensions(0, 1, 1); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("SetDimensions: Invalid number of sample, lines or bands.")) + << e.toString().toStdString(); + } +} + +TEST(CubeTest, TestCubeInvalidDimLines) { + try { + Cube testCube; + testCube.setDimensions(1, 0, 1); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("SetDimensions: Invalid number of sample, lines or bands.")) + << e.toString().toStdString(); + } +} + +TEST(CubeTest, TestCubeInvalidDimBands) { + try { + Cube testCube; + testCube.setDimensions(1, 1, 0); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("SetDimensions: Invalid number of sample, lines or bands.")) + << e.toString().toStdString(); + } +} + +TEST(CubeTest, TestCubeNonePixelType) { + try { + Cube testCube; + testCube.setPixelType(None); + testCube.setDimensions(1, 1, 1); + testCube.create("IsisCube_00.cub"); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Cannot create the cube [IsisCube_00.cub] with a pixel type set to None.")) + << e.toString().toStdString(); + } +} + +TEST_F(TempTestingFiles, TestCubeAddGroupReadOnly) { + try { + Cube testCube; + testCube.setDimensions(1024, 1024, 1); + testCube.create(tempDir.path() + "/IsisCube_00.cub"); + testCube.reopen("r"); + testCube.putGroup(PvlGroup("TestGroup2")); + FAIL() << "Expected an exception to be thrown"; + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("Cannot add a group to the label of cube [IsisCube_00.cub] because it is opened read-only.")) + << e.toString().toStdString(); + } +} + +TEST_F(SmallCube, TestCubeCreateECube) { + Cube localTestCube; + QString path = testCube->fileName(); + localTestCube.setExternalDnData(path); + localTestCube.create(tempDir.path() + "/isisTruth_external.ecub"); + localTestCube.putGroup(PvlGroup("TestGroup")); + EXPECT_EQ(localTestCube.realDataFileName().expanded(), path); + EXPECT_TRUE(localTestCube.hasGroup("TestGroup")); + + path = localTestCube.fileName(); + check_cube(localTestCube, path, 10, 10, 10, 0, 1, 7, 2, 1, 1, 0, 1, 65536); +} + +class ECube : public SmallCube { + protected: + Cube * testECube; + + void SetUp() override { + SmallCube::SetUp(); + testECube = new Cube(); + testECube->setExternalDnData(testCube->fileName()); + QString path = tempDir.path() + "/external.ecub"; + testECube->create(path); + + testECube->close(); + testECube->open(path, "rw"); + } + + void TearDown() override { + if (testECube->isOpen()) { + testECube->close(); + } + + if (testECube) { + delete testECube; + } + SmallCube::TearDown(); + } +}; + +TEST_F(ECube, TestCubeCreateECubeFromECube) { + QString path1 = testECube->fileName(); + + Cube localTestCube; + localTestCube.setExternalDnData(path1); + QString path2 = tempDir.path() + "/isisTruth_external2.ecub"; + localTestCube.create(path2); + EXPECT_EQ(localTestCube.realDataFileName().expanded(), testCube->fileName()); + + check_cube(localTestCube, path2, 10, 10, 10, 0, 1, 7, 2, 1, 1, 0, 1, 65536); +} + +TEST_F(ECube, TestCubeECubeRead) { + Brick readBrick(3, 3, 2, testECube->pixelType()); + readBrick.SetBasePosition(1, 1, 1); + testECube->read(readBrick); + std::vector truth = {0, 1, 2, 10, 11, 12, 20, 21, 22, 100, 101, 102, 110, 111, 112, 120, 121, 122}; + for (int index = 0; index < readBrick.size(); index++) { + EXPECT_EQ(readBrick[index], truth[index]); + } +} + +TEST_F(ECube, TestCubeECubeWrite) { + Brick writeBrick(3, 3, 2, testECube->pixelType()); + writeBrick.SetBasePosition(1, 1, 1); + for (int index = 0; index < writeBrick.size(); index++) { + writeBrick[index] = 1.0; + } + try { + testECube->write(writeBrick); + FAIL(); + } + catch(IException &e) { + EXPECT_TRUE(e.toString().toLatin1().contains("The cube [external.ecub] does not support storing DN data because it is using an external file for DNs.")) + << e.toString().toStdString(); + } +} + +TEST_F(ECube, TestCubeECubeFromECubeRead) { + QString path1 = testECube->fileName(); + + Cube localTestCube; + localTestCube.setExternalDnData(path1); + QString path2 = tempDir.path() + "/isisTruth_external2.ecub"; + localTestCube.create(path2); + + Brick readBrick(3, 3, 2, localTestCube.pixelType()); + readBrick.SetBasePosition(1, 1, 1); + localTestCube.read(readBrick); + std::vector truth = {0, 1, 2, 10, 11, 12, 20, 21, 22, 100, 101, 102, 110, 111, 112, 120, 121, 122}; + for (int index = 0; index < readBrick.size(); index++) { + EXPECT_EQ(readBrick[index], truth[index]); + } +}