diff --git a/isis/src/base/apps/enlarge/enlarge.xml b/isis/src/base/apps/enlarge/enlarge.xml index 550fce2b76bab591d3e76373ee98d5fb31fc1a6a..1e8b82bb32857759e5515c2da8c22b58c00e8ab7 100644 --- a/isis/src/base/apps/enlarge/enlarge.xml +++ b/isis/src/base/apps/enlarge/enlarge.xml @@ -74,6 +74,15 @@ <change name="Sharmila Prasad" date="2011-09-15"> Fixed issue 0000280 - enlarge fails when run with a batchlist </change> + <change name="Kaitlyn Lee" date="2020-04-09"> + The SetOutputCube method from Process we were originally using called + Application::GetUserInterface(), but this became a problem when trying to + call enlarge(), or run the application, programmatically since we are no + longer using Application in the application's cpp file. Changed the call + to the one that takes in a CubeAttribute object. Also, removed the check + to see if an invalid interpolation method was passed in since the UserInterface + class checks and throws the exception and it was unreachable code. + </change> </history> <category> diff --git a/isis/src/base/apps/enlarge/enlarge_app.cpp b/isis/src/base/apps/enlarge/enlarge_app.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4769b7bc29803c3760beb98fec291f445ba27354 --- /dev/null +++ b/isis/src/base/apps/enlarge/enlarge_app.cpp @@ -0,0 +1,100 @@ +#include "enlarge_app.h" + +#include "CubeAttribute.h" +#include "Enlarge.h" +#include "IException.h" +#include "ProcessRubberSheet.h" + +using namespace std; +using namespace Isis; +namespace Isis{ + + void enlarge(UserInterface &ui, Pvl *log) { + Cube icube; + CubeAttributeInput inAtt = ui.GetInputAttribute("FROM"); + if (inAtt.bands().size() != 0) { + icube.setVirtualBands(inAtt.bands()); + } + icube.open(ui.GetFileName("FROM")); + enlarge(&icube, ui, log); + } + + void enlarge(Cube *icube, UserInterface &ui, Pvl *log) { + ProcessRubberSheet p; + p.SetInputCube(icube); + + // Input number of samples, lines, and bands + int ins = icube->sampleCount(); + int inl = icube->lineCount(); + int inb = icube->bandCount(); + + // Output samples and lines + int ons, onl; + + // Scaling factors + double sampleScale, lineScale; + + if(ui.GetString("MODE") == "SCALE") { + // Retrieve the provided scaling factors + sampleScale = ui.GetDouble("SSCALE"); + lineScale = ui.GetDouble("LSCALE"); + + // Calculate the output size. If there is a fractional pixel, round up + ons = (int)ceil(ins * sampleScale); + onl = (int)ceil(inl * lineScale); + } + else { + // Retrieve the provided sample/line dimensions in the output + ons = ui.GetInteger("ONS"); + onl = ui.GetInteger("ONL"); + + // Calculate the scaling factors + sampleScale = (double)ons / (double)ins; + lineScale = (double)onl / (double)inl; + } + + // Ensure that the calculated number of output samples and lines is greater + // than the input + if(ons < ins || onl < inl) { + string msg = "Number of output samples/lines must be greater than or equal"; + msg = msg + " to the input samples/lines."; + throw IException(IException::User, msg, _FILEINFO_); + } + + // Set up the interpolator + Interpolator *interp; + if(ui.GetString("INTERP") == "NEARESTNEIGHBOR") { + interp = new Interpolator(Interpolator::NearestNeighborType); + } + else if(ui.GetString("INTERP") == "BILINEAR") { + interp = new Interpolator(Interpolator::BiLinearType); + } + else { // CUBICCONVOLUTION + interp = new Interpolator(Interpolator::CubicConvolutionType); + } + + // Allocate the output file, the number of bands does not change in the output + QString outputFileName = ui.GetFileName("TO"); + CubeAttributeOutput &att = ui.GetOutputAttribute("TO"); + Cube *ocube = p.SetOutputCube(outputFileName, att, ons, onl, inb); + + // Set up the transform object with the calculated scale and number of + // output pixels + //Transform *transform = new Enlarge(icube, sampleScale, lineScale); + Enlarge *transform = new Enlarge(icube, sampleScale, lineScale); + p.StartProcess(*transform, *interp); + PvlGroup resultsGrp = transform->UpdateOutputLabel(ocube); + + // Cleanup + icube->close(); + ocube->close(); + p.EndProcess(); + + delete transform; + delete interp; + + // Write the results to the log + log->addGroup(resultsGrp); + } +} + diff --git a/isis/src/base/apps/enlarge/enlarge_app.h b/isis/src/base/apps/enlarge/enlarge_app.h new file mode 100644 index 0000000000000000000000000000000000000000..32206da6e955c576e7c98ced49bc12a11e5b88f2 --- /dev/null +++ b/isis/src/base/apps/enlarge/enlarge_app.h @@ -0,0 +1,14 @@ +#ifndef enlarge_app_h +#define enlarge_app_h + + +#include "Cube.h" +#include "Pvl.h" +#include "UserInterface.h" + +namespace Isis{ + extern void enlarge(Cube *icube, UserInterface &ui, Pvl *log); + extern void enlarge(UserInterface &ui, Pvl *log); +} + +#endif diff --git a/isis/src/base/apps/enlarge/main.cpp b/isis/src/base/apps/enlarge/main.cpp index 7e005121b87ad507cfaae2b38f96b467d9563dd6..5277bd14d096d083da39db75a68b33315b85ee5e 100644 --- a/isis/src/base/apps/enlarge/main.cpp +++ b/isis/src/base/apps/enlarge/main.cpp @@ -1,93 +1,27 @@ #include "Isis.h" -#include "Enlarge.h" -#include "IException.h" -#include "ProcessRubberSheet.h" +#include "enlarge_app.h" + +#include "Application.h" +#include "Pvl.h" using namespace std; using namespace Isis; void IsisMain() { - ProcessRubberSheet p; - - // Open the input cube - Cube *icube = p.SetInputCube("FROM"); - - // Input number of samples, lines, and bands - int ins = icube->sampleCount(); - int inl = icube->lineCount(); - int inb = icube->bandCount(); - - // Output samples and lines - int ons, onl; - - // Scaling factors - double sampleScale, lineScale; - UserInterface &ui = Application::GetUserInterface(); - if(ui.GetString("MODE") == "SCALE") { - // Retrieve the provided scaling factors - sampleScale = ui.GetDouble("SSCALE"); - lineScale = ui.GetDouble("LSCALE"); - - // Calculate the output size. If there is a fractional pixel, round up - ons = (int)ceil(ins * sampleScale); - onl = (int)ceil(inl * lineScale); - } - else { - // Retrieve the provided sample/line dimensions in the output - ons = ui.GetInteger("ONS"); - onl = ui.GetInteger("ONL"); - - // Calculate the scaling factors - sampleScale = (double)ons / (double)ins; - lineScale = (double)onl / (double)inl; - } - - // Ensure that the calculated number of output samples and lines is greater - // than the input - if(ons < ins || onl < inl) { - string msg = "Number of output samples/lines must be greater than or equal"; - msg = msg + " to the input samples/lines."; - throw IException(IException::User, msg, _FILEINFO_); - } - - // Set up the interpolator - Interpolator *interp; - if(ui.GetString("INTERP") == "NEARESTNEIGHBOR") { - interp = new Interpolator(Interpolator::NearestNeighborType); + Pvl appLog; + try { + enlarge(ui, &appLog); } - else if(ui.GetString("INTERP") == "BILINEAR") { - interp = new Interpolator(Interpolator::BiLinearType); + catch (...) { + for (auto grpIt = appLog.beginGroup(); grpIt!= appLog.endGroup(); grpIt++) { + Application::Log(*grpIt); + } + throw; } - else if(ui.GetString("INTERP") == "CUBICCONVOLUTION") { - interp = new Interpolator(Interpolator::CubicConvolutionType); + + for (auto grpIt = appLog.beginGroup(); grpIt!= appLog.endGroup(); grpIt++) { + Application::Log(*grpIt); } - else { - QString msg = "Unknown value for INTERP [" + - ui.GetString("INTERP") + "]"; - throw IException(IException::Programmer, msg, _FILEINFO_); - } - - // Allocate the output file, the number of bands does not change in the output - Cube *ocube = p.SetOutputCube("TO", ons, onl, inb); - - // Set up the transform object with the calculated scale and number of - // output pixels - //Transform *transform = new Enlarge(icube, sampleScale, lineScale); - Enlarge *transform = new Enlarge(icube, sampleScale, lineScale); - p.StartProcess(*transform, *interp); - PvlGroup resultsGrp = transform->UpdateOutputLabel(ocube); - - // Cleanup - icube->close(); - ocube->close(); - p.EndProcess(); - - delete transform; - delete interp; - - // Write the results to the log - Application::Log(resultsGrp); -} - +} \ No newline at end of file diff --git a/isis/src/base/apps/enlarge/tsts/Makefile b/isis/src/base/apps/enlarge/tsts/Makefile deleted file mode 100644 index 46d84c74c297304e943452a44e06b111f179a92b..0000000000000000000000000000000000000000 --- a/isis/src/base/apps/enlarge/tsts/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -BLANKS = "%-6s" -LENGTH = "%-40s" - -include $(ISISROOT)/make/isismake.tststree diff --git a/isis/src/base/apps/enlarge/tsts/default/Makefile b/isis/src/base/apps/enlarge/tsts/default/Makefile deleted file mode 100644 index f44b1aae9cf70a874f3e97423c7eb461b2365d33..0000000000000000000000000000000000000000 --- a/isis/src/base/apps/enlarge/tsts/default/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -APPNAME = enlarge - -peaks2.cub.TOLERANCE = 16 - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(APPNAME) from=$(INPUT)/peaks.cub \ - to=$(OUTPUT)/peaks.cub \ - sscale=1.0 \ - lscale=1.5 \ - interp=bilinear > /dev/null; - lowpass from=$(OUTPUT)/peaks.cub samples=1 lines=5 \ - to=$(OUTPUT)/peaks2.cub > /dev/null; - $(RM) $(OUTPUT)/peaks.cub diff --git a/isis/src/base/apps/enlarge/tsts/total/Makefile b/isis/src/base/apps/enlarge/tsts/total/Makefile deleted file mode 100644 index 2c9aadfcf8e3d2fb0779788ecf322d47004579a4..0000000000000000000000000000000000000000 --- a/isis/src/base/apps/enlarge/tsts/total/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -APPNAME = enlarge - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(APPNAME) from=$(INPUT)/isisTruth.cub \ - to=$(OUTPUT)/total.cub \ - mode=total \ - ons=126 \ - onl=189 \ - interp=nearestneighbor > /dev/null; - $(APPNAME) from=$(INPUT)/isisTruth.cub \ - to=$(OUTPUT)/scale.cub \ - sscale=1.0 \ - lscale=1.5 \ - interp=nearestneighbor > /dev/null; - cubediff from=$(OUTPUT)/total.cub \ - from2=$(OUTPUT)/scale.cub \ - to=$(OUTPUT)/comparisonTruth.txt > /dev/null; - rm -f $(OUTPUT)/total.cub; - rm -f $(OUTPUT)/scale.cub; diff --git a/isis/src/base/objs/Process/Process.cpp b/isis/src/base/objs/Process/Process.cpp index 7c46b618ec71cf64d6b5a75246aa1958f6512907..2d50d274acaad85a64546b088c8f68ba7553b024 100644 --- a/isis/src/base/objs/Process/Process.cpp +++ b/isis/src/base/objs/Process/Process.cpp @@ -308,12 +308,12 @@ namespace Isis { << ",nb=" << nb << "]"; throw IException(IException::Programmer, message.str().c_str(), _FILEINFO_); } - QString fname = Application::GetUserInterface().GetFileName(parameter); Isis::CubeAttributeOutput &atts = Application::GetUserInterface().GetOutputAttribute(parameter); return SetOutputCube(fname, atts, ns, nl, nb); } + /** * Allocates a output cube whose name and size is specified by the programmer. * @@ -350,7 +350,6 @@ namespace Isis { cube->setByteOrder(att.byteOrder()); cube->setFormat(att.fileFormat()); cube->setLabelsAttached(att.labelAttachment() == AttachedLabel); - if(att.propagatePixelType()) { if(InputCubes.size() > 0) { cube->setPixelType(InputCubes[0]->pixelType()); @@ -409,7 +408,7 @@ namespace Isis { // Allocate the cube cube->create(fname); - + // Transfer labels from the first input cube if((p_propagateLabels) && (InputCubes.size() > 0)) { Isis::PvlObject &incube = @@ -468,7 +467,6 @@ namespace Isis { delete cube; throw; } - // Everything is fine so save the cube on the stack AddOutputCube(cube); return cube; diff --git a/isis/tests/Fixtures.cpp b/isis/tests/Fixtures.cpp index 66ac085b9999bafc4d5616727608b2c20a6ebcb3..0c76bed4aef164710113c41010ef35ffe8b5d3af 100644 --- a/isis/tests/Fixtures.cpp +++ b/isis/tests/Fixtures.cpp @@ -1,4 +1,6 @@ #include "Fixtures.h" +#include "LineManager.h" + namespace Isis { @@ -21,6 +23,14 @@ namespace Isis { testCube = new Cube(); testCube->fromIsd(tempDir.path() + "/default.cub", label, isd, "rw"); + LineManager line(*testCube); + for(line.begin(); !line.end(); line++) { + for(int i = 0; i < line.size(); i++) { + line[i] = (double) 1; + } + testCube->write(line); + } + projTestCube = new Cube(); projTestCube->fromIsd(tempDir.path() + "/default.level2.cub", projLabel, isd, "rw"); } diff --git a/isis/tests/Fixtures.h b/isis/tests/Fixtures.h index 505773ff321390294307e75e2b1093da9e271aed..b606ac21d2028a633a0d0cc78ffa958b528b03e9 100644 --- a/isis/tests/Fixtures.h +++ b/isis/tests/Fixtures.h @@ -11,11 +11,10 @@ #include <nlohmann/json.hpp> -#include "IException.h" -#include "PvlGroup.h" - #include "Cube.h" +#include "IException.h" #include "Pvl.h" +#include "PvlGroup.h" #include "PvlObject.h" #include "ControlNet.h" #include "FileList.h" diff --git a/isis/tests/FunctionalTestsEnlarge.cpp b/isis/tests/FunctionalTestsEnlarge.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83b9e855f3b77de21a9845d0e2938edbaa8e25c9 --- /dev/null +++ b/isis/tests/FunctionalTestsEnlarge.cpp @@ -0,0 +1,111 @@ +#include "enlarge_app.h" + +#include <QTemporaryFile> +#include <QTextStream> +#include <QStringList> + +#include "Fixtures.h" +#include "PvlGroup.h" +#include "TestUtilities.h" + +#include "gmock/gmock.h" + +using namespace Isis; + +static QString APP_XML = FileName("$ISISROOT/bin/xml/enlarge.xml").expanded(); + +TEST_F(DefaultCube, FunctionalTestEnlargeDefaultParameters) { + QVector<QString> args = {"to=" + tempDir.path()+"/output.cub"}; + UserInterface options(APP_XML, args); + Pvl appLog; + enlarge(testCube, options, &appLog); + + PvlGroup groundPoint = appLog.findGroup("Results"); + + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("InputLines"), 10); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("InputSamples"), 10); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("StartingLine"), 1); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("StartingSample"), 1); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("EndingLine"), 10); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("EndingSample"), 10); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("LineIncrement"), 1.0); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("SampleIncrement"), 1.0); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("OutputLines"), 10); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("OutputSamples"), 10); +} + +TEST_F(DefaultCube, FunctionalTestEnlargeScale) { + QVector<QString> args = {"to=" + tempDir.path()+"/output.cub", "sscale=2", "lscale=4"}; + UserInterface options(APP_XML, args); + Pvl appLog; + enlarge(testCube, options, &appLog); + + PvlGroup groundPoint = appLog.findGroup("Results"); + + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("LineIncrement"), .25); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("SampleIncrement"), .5); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("OutputLines"), 40); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("OutputSamples"), 20); +} + +TEST_F(DefaultCube, FunctionalTestEnlargeTotal) { + QVector<QString> args = {"to=" + tempDir.path()+"/output.cub", "mode=total", "ons=20", "onl=40"}; + UserInterface options(APP_XML, args); + Pvl appLog; + enlarge(testCube, options, &appLog); + + PvlGroup groundPoint = appLog.findGroup("Results"); + + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("LineIncrement"), .25); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("SampleIncrement"), .5); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("OutputLines"), 40); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("OutputSamples"), 20); +} + +TEST_F(DefaultCube, FunctionalTestEnlargeSmallDimensions) { + QVector<QString> args = {"to=" + tempDir.path()+"/output.cub", "mode=total", "ons=10", "onl=1"}; + UserInterface options(APP_XML, args); + Pvl appLog; + + QString message = "Number of output samples/lines must be greater than or equal"; + try { + enlarge(testCube, options, &appLog); + FAIL() << "Expected an exception to be thrown"; + } + catch(Isis::IException &e) { + EXPECT_PRED_FORMAT2(Isis::AssertIExceptionMessage, e, message); + } + catch(...) { + FAIL() << "Expected error message: \"" << message.toStdString() << "\""; + } +} + +TEST_F(DefaultCube, FunctionalTestEnlargeNearestNeighbor) { + QVector<QString> args = {"to=" + tempDir.path()+"/output.cub", "interp=nearestneighbor"}; + UserInterface options(APP_XML, args); + Pvl appLog; + enlarge(testCube, options, &appLog); + + PvlGroup groundPoint = appLog.findGroup("Results"); + // Just make sure the applications runs without error. Tests the interpolation method in + // the enlarge object. + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("LineIncrement"), 1.0); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("SampleIncrement"), 1.0); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("OutputLines"), 10); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("OutputSamples"), 10); +} + +TEST_F(DefaultCube, FunctionalTestEnlargeBilinear) { + QVector<QString> args = {"to=" + tempDir.path()+"/output.cub", "interp=bilinear"}; + UserInterface options(APP_XML, args); + Pvl appLog; + enlarge(testCube, options, &appLog); + + PvlGroup groundPoint = appLog.findGroup("Results"); + // Just make sure the applications runs without error. Tests the interpolation method in + // the enlarge object. + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("LineIncrement"), 1.0); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("SampleIncrement"), 1.0); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("OutputLines"), 10); + EXPECT_DOUBLE_EQ( (double) groundPoint.findKeyword("OutputSamples"), 10); +} \ No newline at end of file diff --git a/isis/tests/data/defaultImage/defaultCube.pvl b/isis/tests/data/defaultImage/defaultCube.pvl index ef5198a6981fce94be54997678aeb1bd255f873c..1e8865000fd3b3e0130e144b4c77622d2a07864e 100644 Binary files a/isis/tests/data/defaultImage/defaultCube.pvl and b/isis/tests/data/defaultImage/defaultCube.pvl differ