diff --git a/CHANGELOG.md b/CHANGELOG.md index 3edf20364f..c69abfac0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ release. - Added backplane options for SunIllumination and SurfaceObliqueDetectorResolution to phocube [#5467](https://github.com/DOI-USGS/ISIS3/issues/5467) ### Changed +- Explode has been refactored to be callable; old Makefile test has been removed and replaced by a gtest. Issue: [#5557](https://github.com/USGS-Astrogeology/ISIS3/issues/5557) - Isisminer has been refactored to be callable; old Makefile tests have been removed and replaced by gtests. Issue: [#5516](https://github.com/USGS-Astrogeology/ISIS3/issues/5516) - Algebra has been refactored to be callable; old Makefile tests have been removed and replaced by gtests. Issue: [#5594](https://github.com/USGS-Astrogeology/ISIS3/issues/5594) - Photrim has been refactored to be callable; old Makefile tests have been removed and replaced by gtests. Issue: [#5581](https://github.com/USGS-Astrogeology/ISIS3/issues/5581) diff --git a/isis/src/base/apps/explode/explode.cpp b/isis/src/base/apps/explode/explode.cpp new file mode 100644 index 0000000000..fdf39bb727 --- /dev/null +++ b/isis/src/base/apps/explode/explode.cpp @@ -0,0 +1,97 @@ +/** 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 "explode.h" + +#include "ProcessByLine.h" +#include "IException.h" +#include "FileName.h" + +namespace Isis { + + // Line processing routine + void CopyBand(Buffer &in, Buffer &out); + + /** + * Extracts each band of the input cube into a separate one band cube file. + * Given the output base name of "base", each output cube will be named + * e.g. base.band#.cub. The appropiate BandBin group will be created. + * + * @param ui User Interface with application parameters + */ + void explode(UserInterface &ui) { + + // open input cube + Cube icube; + icube.open(ui.GetCubeName("FROM")); + + explode(&icube, ui); + } + + + /** + * Extracts each band of the input cube into a separate one band cube file. + * Given the output base name of "base", each output cube will be named + * e.g. base.band#.cub. The appropiate BandBin group will be created. + * + * @param ui User Interface with application parameters + * @param icube Input cube + */ + void explode(Cube *icube, UserInterface &ui) { + + Process p; + p.SetInputCube(icube); + int samps = icube->sampleCount(); + int lines = icube->lineCount(); + int bands = icube->bandCount(); + QString infile = icube->fileName(); + + // We get the output filename so we can add attributes and extensions + QString outbase = ui.GetCubeName("TO"); + CubeAttributeOutput &outatt = ui.GetOutputAttribute("TO"); + + // Loop and extract each band + for(int band = 1; band <= bands; band++) { + int pband = icube->physicalBand(band); + QString sband(toString(pband)); + + ProcessByLine p2; + Progress *prog = p2.Progress(); + prog->SetText("Exploding band " + sband); + + CubeAttributeInput inatt("+" + sband); + p2.SetInputCube(infile, inatt); + + QString outfile = outbase + ".band"; + if(pband / 1000 == 0) { + outfile += "0"; + if(pband / 100 == 0) { + outfile += "0"; + if(pband / 10 == 0) { + outfile += "0"; + } + } + } + outfile += sband + ".cub"; + p2.SetOutputCube(outfile, outatt, samps, lines, 1); + + p2.StartProcess(CopyBand); + p2.EndProcess(); + } + + // Cleanup + p.EndProcess(); + } + + // Line processing routine + void CopyBand(Buffer &in, Buffer &out) { + for(int i = 0; i < in.size(); i++) { + out[i] = in[i]; + } + } +} diff --git a/isis/src/base/apps/explode/explode.h b/isis/src/base/apps/explode/explode.h new file mode 100644 index 0000000000..cc945f280e --- /dev/null +++ b/isis/src/base/apps/explode/explode.h @@ -0,0 +1,19 @@ +/** 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 */ + +#ifndef explode_h +#define explode_h + +#include "UserInterface.h" + +namespace Isis{ + extern void explode(UserInterface &ui); + extern void explode(Cube *icube, UserInterface &ui); +} + +#endif diff --git a/isis/src/base/apps/explode/explode.xml b/isis/src/base/apps/explode/explode.xml index adaef0f307..c9c7e6e8ca 100644 --- a/isis/src/base/apps/explode/explode.xml +++ b/isis/src/base/apps/explode/explode.xml @@ -35,6 +35,9 @@ Removed references to CubeInfo + + Converted to callable app and converted Makefile test to gtest. + diff --git a/isis/src/base/apps/explode/main.cpp b/isis/src/base/apps/explode/main.cpp index 7a75d1ccba..f2ff2442ee 100644 --- a/isis/src/base/apps/explode/main.cpp +++ b/isis/src/base/apps/explode/main.cpp @@ -1,63 +1,20 @@ -#include "Isis.h" -#include "ProcessByLine.h" -#include "IException.h" -#include "FileName.h" - -using namespace std; -using namespace Isis; - -void CopyBand(Buffer &in, Buffer &out); +/** This is free and unencumbered software released into the public domain. -void IsisMain() { - // Get the cube to explode - Process p; - Cube *icube = p.SetInputCube("FROM"); - int samps = icube->sampleCount(); - int lines = icube->lineCount(); - int bands = icube->bandCount(); - QString infile = icube->fileName(); - - // We the output filename so we can add attributes and extensions - UserInterface &ui = Application::GetUserInterface(); - QString outbase = ui.GetCubeName("TO"); - CubeAttributeOutput &outatt = ui.GetOutputAttribute("TO"); +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. **/ - // Loop and extract each band - for(int band = 1; band <= bands; band++) { - int pband = icube->physicalBand(band); - QString sband(toString(pband)); +/* SPDX-License-Identifier: CC0-1.0 */ - ProcessByLine p2; - Progress *prog = p2.Progress(); - prog->SetText("Exploding band " + sband); - - CubeAttributeInput inatt("+" + sband); - p2.SetInputCube(infile, inatt); +#include "Isis.h" - QString outfile = outbase + ".band"; - if(pband / 1000 == 0) { - outfile += "0"; - if(pband / 100 == 0) { - outfile += "0"; - if(pband / 10 == 0) { - outfile += "0"; - } - } - } - outfile += sband + ".cub"; - p2.SetOutputCube(outfile, outatt, samps, lines, 1); +#include "explode.h" - p2.StartProcess(CopyBand); - p2.EndProcess(); - } +#include "Application.h" - // Cleanup - p.EndProcess(); -} +using namespace Isis; -// Line processing routine -void CopyBand(Buffer &in, Buffer &out) { - for(int i = 0; i < in.size(); i++) { - out[i] = in[i]; - } +void IsisMain() { + UserInterface &ui = Application::GetUserInterface(); + explode(ui); } diff --git a/isis/src/base/apps/explode/tsts/Makefile b/isis/src/base/apps/explode/tsts/Makefile deleted file mode 100644 index 46d84c74c2..0000000000 --- a/isis/src/base/apps/explode/tsts/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -BLANKS = "%-6s" -LENGTH = "%-40s" - -include $(ISISROOT)/make/isismake.tststree diff --git a/isis/src/base/apps/explode/tsts/case01/Makefile b/isis/src/base/apps/explode/tsts/case01/Makefile deleted file mode 100644 index e58baa1d0d..0000000000 --- a/isis/src/base/apps/explode/tsts/case01/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -APPNAME = explode - -include $(ISISROOT)/make/isismake.tsts - -commands: - $(APPNAME) from=$(INPUT)/isisTruth.cub \ - to= $(OUTPUT)/explTruth1 > /dev/null; diff --git a/isis/tests/FunctionalTestsExplode.cpp b/isis/tests/FunctionalTestsExplode.cpp new file mode 100644 index 0000000000..b639d8a25c --- /dev/null +++ b/isis/tests/FunctionalTestsExplode.cpp @@ -0,0 +1,80 @@ +#include "explode.h" + +#include +#include + +#include "CameraFixtures.h" +#include "Cube.h" +#include "Histogram.h" + +#include "gtest/gtest.h" + +using namespace Isis; + +static QString APP_XML = FileName("$ISISROOT/bin/xml/explode.xml").expanded(); + +/** + * ExplodeDefault Test + * + * ExplodeDefault test given a single 5x5 input cube with 2 bands. + * + * The output cube is verified by checking the histogram statistics + * for each band. + * + * INPUT: testCube from DefaultCube fixture resized to 5x5x1 + * + * OUTPUT: 1) explodeOut.band0001.cub + * 2) explodeOut.band0002.cub + */ +TEST_F(DefaultCube, FunctionalTestExplodeDefault) { + + // reduce test cube size and create two bands + resizeCube(5, 5, 2); + + // close and reopen test cube to ensure dn buffer is available + testCube->reopen("r"); + + // run explode + QVector args = {"to=" + tempDir.path() + "/explodeOut"}; + UserInterface ui(APP_XML, args); + + try { + explode(testCube, ui); + } + catch(IException &e) { + FAIL() << e.toString().toStdString().c_str() << std::endl; + } + + // validate band 1 output cube + Cube outCube1(tempDir.path() + "/explodeOut.band0001.cub"); + + ASSERT_EQ(outCube1.sampleCount(), 5); + ASSERT_EQ(outCube1.lineCount(), 5); + ASSERT_EQ(outCube1.bandCount(), 1); + + std::unique_ptr inCubeBand1Hist (testCube->histogram(1)); + std::unique_ptr outCube1Hist (outCube1.histogram(1)); + + EXPECT_NEAR(outCube1Hist->Average(), inCubeBand1Hist->Average(), .000001); + EXPECT_NEAR(outCube1Hist->Sum(), inCubeBand1Hist->Sum(), .000001); + EXPECT_EQ(outCube1Hist->ValidPixels(), inCubeBand1Hist->ValidPixels()); + EXPECT_EQ(outCube1Hist->TotalPixels(), inCubeBand1Hist->TotalPixels()); + EXPECT_NEAR(outCube1Hist->StandardDeviation(), inCubeBand1Hist->StandardDeviation(), .000001); + + // validate band 2 output cube + Cube outCube2(tempDir.path() + "/explodeOut.band0002.cub"); + + ASSERT_EQ(outCube2.sampleCount(), 5); + ASSERT_EQ(outCube2.lineCount(), 5); + ASSERT_EQ(outCube2.bandCount(), 1); + + std::unique_ptr inCubeBand2Hist (testCube->histogram(2)); + std::unique_ptr outCube2Hist (outCube2.histogram(1)); + + EXPECT_NEAR(outCube2Hist->Average(), inCubeBand2Hist->Average(), .000001); + EXPECT_NEAR(outCube2Hist->Sum(), inCubeBand2Hist->Sum(), .000001); + EXPECT_EQ(outCube2Hist->ValidPixels(), inCubeBand2Hist->ValidPixels()); + EXPECT_EQ(outCube2Hist->TotalPixels(), inCubeBand2Hist->TotalPixels()); + EXPECT_NEAR(outCube2Hist->StandardDeviation(), inCubeBand2Hist->StandardDeviation(), .000001); +} +