Skip to content

Commit

Permalink
Convert dstripe to gtests (#5665)
Browse files Browse the repository at this point in the history
* Convert dstripe to gtests

* add changelog

* Fixed build error
  • Loading branch information
amystamile-usgs authored Nov 13, 2024
1 parent 1764f59 commit a2cccf1
Show file tree
Hide file tree
Showing 10 changed files with 1,148 additions and 129 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ file. Slightly modified the FunctionalTestJigsawBundleXYZ ctest accordingly. Iss
- Fixed FunctionalTestCamstatsDefaultParameters test by increasing the runtime speed [#5459](https://github.com/DOI-USGS/ISIS3/issues/5459)
- Fixed XmlToJson namespaced key conversion [#5652](https://github.com/DOI-USGS/ISIS3/pull/5652)
- Fixed PHOTOMET not accepting backplanes [#5281](https://github.com/DOI-USGS/ISIS3/issues/5281)
- Fixed dstripe parallel test failing by converting tests to gtests [#5613](https://github.com/DOI-USGS/ISIS3/issues/5613)

## [8.3.0] - 2024-09-30

Expand Down
139 changes: 139 additions & 0 deletions isis/src/base/apps/dstripe/dstripe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/** 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 "dstripe.h"

#include <QFile>

#include "Application.h"
#include "ProcessByLine.h"
#include "ProgramLauncher.h"
#include "SpecialPixel.h"

using namespace std;

namespace Isis {

void difference(vector<Buffer *> &input, vector<Buffer *> &output);

void dstripe(UserInterface &ui) {
Cube icube;
CubeAttributeInput inAtt = ui.GetInputAttribute("FROM");
if (inAtt.bands().size() != 0) {
icube.setVirtualBands(inAtt.bands());
}
icube.open(ui.GetCubeName("FROM"));
dstripe(&icube, ui);
}

void dstripe(Cube *icube, UserInterface &ui) {
ProcessByLine p;
int highLines, highSamples, lowLines, lowSamples;
p.SetInputCube(icube);
// Get the boxcar sizes to be used by the low and highpass filters
// All numbers have to be odd. If nothing is entered into the UI,
// NS and/or NL are used.
if (ui.GetString("MODE") == "VERTICAL") {
if (ui.WasEntered("VHNS")) {
highSamples = ui.GetInteger("VHNS");
} else {
highSamples = icube->sampleCount();
if (highSamples % 2 == 0) highSamples -= 1;
}

if (ui.WasEntered("VLNL")) {
lowLines = ui.GetInteger("VLNL");
} else {
lowLines = icube->lineCount();
if (lowLines % 2 == 0) lowLines -= 1;
}

lowSamples = ui.GetInteger("VLNS");
highLines = ui.GetInteger("VHNL");
} else {
if (ui.WasEntered("HHNL")) {
highLines = ui.GetInteger("HHNL");
} else {
highLines = icube->lineCount();
if (highLines % 2 == 0) highLines -= 1;
}

if (ui.WasEntered("HLNS")) {
lowSamples = ui.GetInteger("HLNS");
} else {
lowSamples = icube->sampleCount();
if (lowSamples % 2 == 0) lowSamples -= 1;
}

highSamples = ui.GetInteger("HHNS");
lowLines = ui.GetInteger("HLNL");
}

// Algorithm: lowpass(from, temp) -> hipass(temp, noise) -> to = from-noise

// Run lowpass filter on input
QString tempFileName =
FileName::createTempFile("$TEMPORARY/dstripe.temporary.cub").expanded();
QString lowParams = "";
lowParams += "from= " + ui.GetCubeName("FROM");
lowParams += " to= " + tempFileName + " ";
lowParams += " samples= " + toString(lowSamples);
lowParams += " lines= " + toString(lowLines);

ProgramLauncher::RunIsisProgram("lowpass", lowParams);

// Make a copy of the lowpass filter results if the user wants it
if (!ui.GetBoolean("DELETENOISE")) {
QString lowParams = "";
lowParams += "from= " + ui.GetCubeName("FROM");
lowParams += " to= " + ui.GetCubeName("LPFNOISE");
lowParams += " samples= " + toString(lowSamples);
lowParams += " lines= " + toString(lowLines);
ProgramLauncher::RunIsisProgram("lowpass", lowParams);
}

// Run highpass filter after lowpass is done, i.e. highpass(lowpass(input))
QString tempNoiseFileName =
FileName::createTempFile("$TEMPORARY/dstripe.noise.temporary.cub")
.expanded();
QString highParams = "";
highParams += " from= " + tempFileName + " ";
highParams += " to= " + tempNoiseFileName + " ";
highParams += " samples= " + toString(highSamples);
highParams += " lines= " + toString(highLines);

ProgramLauncher::RunIsisProgram("highpass", highParams);
QFile::remove(tempFileName);

// Take the difference (FROM-NOISE) and write it to output
CubeAttributeInput inatt;
p.SetInputCube(tempNoiseFileName, inatt);
CubeAttributeOutput &outatt = ui.GetOutputAttribute("TO");
p.SetOutputCube(ui.GetCubeName("TO"), outatt);
p.StartProcess(difference);
p.EndProcess();
if (ui.GetBoolean("DELETENOISE")) {
QFile::remove(tempNoiseFileName);
}
}

// Subtracts noise from the input buffer, resulting in a cleaner output image
void difference(vector<Buffer *> &input, vector<Buffer *> &output) {
Buffer &from = *input[0];
Buffer &noise = *input[1];
Buffer &to = *output[0];

for(int i = 0; i < from.size(); i++) {
if(IsSpecial(from[i]) || IsSpecial(noise[i])) {
to[i] = from[i];
}
else {
to[i] = from[i] - noise[i];
}
}
}

} // namespace Isis
19 changes: 19 additions & 0 deletions isis/src/base/apps/dstripe/dstripe.h
Original file line number Diff line number Diff line change
@@ -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 dstripe_h
#define dstripe_h

#include "Cube.h"
#include "UserInterface.h"

namespace Isis {
extern void dstripe(Cube *icube, UserInterface &ui);
extern void dstripe(UserInterface &ui);
}

#endif
120 changes: 8 additions & 112 deletions isis/src/base/apps/dstripe/main.cpp
Original file line number Diff line number Diff line change
@@ -1,123 +1,19 @@
#include "Isis.h"
/** 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. **/

#include <QFile>
/* SPDX-License-Identifier: CC0-1.0 */
#include "Isis.h"

#include "dstripe.h"
#include "Application.h"
#include "ProcessByLine.h"
#include "ProgramLauncher.h"
#include "SpecialPixel.h"

using namespace std;
using namespace Isis;

void difference(vector<Buffer *> &input, vector<Buffer *> &output);

void IsisMain() {
ProcessByLine p;
Cube *icube = p.SetInputCube("FROM");
UserInterface &ui = Application::GetUserInterface();
int highLines, highSamples, lowLines, lowSamples;

// Get the boxcar sizes to be used by the low and highpass filters
// All numbers have to be odd. If nothing is entered into the UI,
// NS and/or NL are used.
if(ui.GetString("MODE") == "VERTICAL") {
if(ui.WasEntered("VHNS")) {
highSamples = ui.GetInteger("VHNS");
}
else {
highSamples = icube->sampleCount();
if(highSamples % 2 == 0) highSamples -= 1;
}

if(ui.WasEntered("VLNL")) {
lowLines = ui.GetInteger("VLNL");
}
else {
lowLines = icube->lineCount();
if(lowLines % 2 == 0) lowLines -= 1;
}

lowSamples = ui.GetInteger("VLNS");
highLines = ui.GetInteger("VHNL");
}
else {
if(ui.WasEntered("HHNL")) {
highLines = ui.GetInteger("HHNL");
}
else {
highLines = icube->lineCount();
if(highLines % 2 == 0) highLines -= 1;
}

if(ui.WasEntered("HLNS")) {
lowSamples = ui.GetInteger("HLNS");
}
else {
lowSamples = icube->sampleCount();
if(lowSamples % 2 == 0) lowSamples -= 1;
}

highSamples = ui.GetInteger("HHNS");
lowLines = ui.GetInteger("HLNL");
}

// Algorithm: lowpass(from, temp) -> hipass(temp, noise) -> to = from-noise

// Run lowpass filter on input
QString tempFileName = FileName::createTempFile("$TEMPORARY/dstripe.temporary.cub").expanded();
QString lowParams = "";
lowParams += "from= " + ui.GetCubeName("FROM");
lowParams += " to= " + tempFileName + " ";
lowParams += " samples= " + toString(lowSamples);
lowParams += " lines= " + toString(lowLines);

ProgramLauncher::RunIsisProgram("lowpass", lowParams);

// Make a copy of the lowpass filter results if the user wants it
if(!ui.GetBoolean("DELETENOISE")) {
QString lowParams = "";
lowParams += "from= " + ui.GetCubeName("FROM");
lowParams += " to= " + ui.GetCubeName("LPFNOISE");
lowParams += " samples= " + toString(lowSamples);
lowParams += " lines= " + toString(lowLines);
ProgramLauncher::RunIsisProgram("lowpass", lowParams);
}

// Run highpass filter after lowpass is done, i.e. highpass(lowpass(input))
QString tempNoiseFileName = FileName::createTempFile("$TEMPORARY/dstripe.noise.temporary.cub").expanded();
QString highParams = "";
highParams += " from= "+tempFileName + " ";
highParams += " to= " + tempNoiseFileName + " ";
highParams += " samples= " + toString(highSamples);
highParams += " lines= " + toString(highLines);

ProgramLauncher::RunIsisProgram("highpass", highParams);
QFile::remove(tempFileName);

// Take the difference (FROM-NOISE) and write it to output
CubeAttributeInput att;
p.SetInputCube(tempNoiseFileName, att);
p.SetOutputCube("TO");
p.StartProcess(difference);
p.EndProcess();
if(ui.GetBoolean("DELETENOISE")) {
QFile::remove(tempNoiseFileName);
}
dstripe(ui);
}

// Subtracts noise from the input buffer, resulting in a cleaner output image
void difference(vector<Buffer *> &input, vector<Buffer *> &output) {
Buffer &from = *input[0];
Buffer &noise = *input[1];
Buffer &to = *output[0];

for(int i = 0; i < from.size(); i++) {
if(IsSpecial(from[i]) || IsSpecial(noise[i])) {
to[i] = from[i];
}
else {
to[i] = from[i] - noise[i];
}
}
}
4 changes: 0 additions & 4 deletions isis/src/base/apps/dstripe/tsts/Makefile

This file was deleted.

7 changes: 0 additions & 7 deletions isis/src/base/apps/dstripe/tsts/default/Makefile

This file was deleted.

6 changes: 0 additions & 6 deletions isis/src/base/apps/dstripe/tsts/parallel/Makefile

This file was deleted.

60 changes: 60 additions & 0 deletions isis/tests/FunctionalTestsDstripe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <QTemporaryDir>

#include "Fixtures.h"
#include "Pvl.h"
#include "PvlGroup.h"
#include "TestUtilities.h"
#include "Histogram.h"

#include "dstripe.h"

#include "gtest/gtest.h"

using namespace Isis;

static QString APP_XML = FileName("$ISISROOT/bin/xml/dstripe.xml").expanded();

TEST(Dstripe, FunctionalTestDstripeName) {
QTemporaryDir prefix;
QString outCubeFileName = prefix.path() + "/outTemp.cub";
QVector<QString> args = {"from=data/dstripe/dstripe-default.cub",
"to=" + outCubeFileName};

UserInterface options(APP_XML, args);
try {
dstripe(options);
} catch (IException &e) {
FAIL() << "Unable to open image: " << e.what() << std::endl;
}

Cube cube(outCubeFileName);

std::unique_ptr<Histogram> hist (cube.histogram(0));
EXPECT_NEAR(hist->Average(), 99.405224835973755, .000001);
EXPECT_NEAR(hist->Sum(), 19877864, .000001);
EXPECT_EQ(hist->ValidPixels(), 199968);
EXPECT_NEAR(hist->StandardDeviation(), 18.246570191788862, .000001);
}

TEST(Dstripe, FunctionalTestDstripeParallel) {
QTemporaryDir prefix;
QString outCubeFileName = prefix.path() + "/outTemp.cub";
QVector<QString> args = {"from=data/dstripe/dstripe-parallel.cub",
"mode=vert", "vlnl=51", "vhns=51",
"to=" + outCubeFileName};

UserInterface options(APP_XML, args);
try {
dstripe(options);
} catch (IException &e) {
FAIL() << "Unable to open image: " << e.what() << std::endl;
}

Cube cube(outCubeFileName);

std::unique_ptr<Histogram> hist (cube.histogram(0));
EXPECT_NEAR(hist->Average(), 2.2391462548711162e-05, .000001);
EXPECT_NEAR(hist->Sum(), 0.71652680155875714, .000001);
EXPECT_EQ(hist->ValidPixels(), 32000);
EXPECT_NEAR(hist->StandardDeviation(), 3.2450333566072249e-06, .000001);
}
Binary file added isis/tests/data/dstripe/dstripe-default.cub
Binary file not shown.
Loading

0 comments on commit a2cccf1

Please sign in to comment.