Skip to content

Commit

Permalink
Bandtrim has been refactored to be callable; old Makefile tests have …
Browse files Browse the repository at this point in the history
…been removed and replaced by gtests. Addresses #5571.
  • Loading branch information
kledmundson committed Jul 31, 2024
1 parent 9ac2592 commit f466c64
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 44 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ release.
- Added backplane options for SunIllumination and SurfaceObliqueDetectorResolution to phocube [#5467](https://github.com/DOI-USGS/ISIS3/issues/5467)

### Changed
- Bandtrim has been refactored to be callable; old Makefile tests have been removed and replaced by gtests. Issue: [#5571](https://github.com/USGS-Astrogeology/ISIS3/issues/5571)
- Added jigsaw error message for csminit'd images without csm parameters[#5486](https://github.com/DOI-USGS/ISIS3/issues/5486)
- Changed `qwt` dependency version to 6.2.0 or below [#5498](https://github.com/DOI-USGS/ISIS3/issues/5498)
- Pinned `suitesparse` dependency version to maximum not including 7.7.0 [#5496](https://github.com/DOI-USGS/ISIS3/issues/5496)
Expand Down
74 changes: 74 additions & 0 deletions isis/src/base/apps/bandtrim/bandtrim.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/** 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 "bandtrim.h"

#include "Cube.h"
#include "ProcessByBrick.h"
#include "SpecialPixel.h"

namespace Isis {

// Process to trim spectral pixels if any are null
void BandTrimSpectral(Buffer &in, Buffer &out);

/**
* Bandtrim searches for NULL pixels in all bands of a cube.
* When a NULL pixel is found the corresponding pixel is set
* to NULL in all other bands.
*
* @param ui User Interface with application parameters
*/
void bandtrim(UserInterface &ui) {

// open cube
Cube icube;
icube.open(ui.GetCubeName("FROM"));

bandtrim(&icube, ui);
}


/**
* Bandtrim searches for NULL pixels in all bands of a cube.
* When a NULL pixel is found the corresponding pixel is set
* to NULL in all other bands.
*
* @param icube Input cube
* @param ui User Interface with application parameters
*/
void bandtrim(Cube *icube, UserInterface &ui) {
ProcessByBrick p;
p.SetInputCube(icube);
p.SetBrickSize(1, 1, icube->bandCount());

QString fname = ui.GetCubeName("TO");
CubeAttributeOutput &atts = ui.GetOutputAttribute("TO");
p.SetOutputCube(fname, atts);

p.StartProcess(BandTrimSpectral);
p.EndProcess();
}

// Process to trim spectral pixels if any are null
void BandTrimSpectral(Buffer &in, Buffer &out) {
// Copy input to output and check to see if we should null
bool nullPixels = false;
for(int i = 0; i < in.size(); i++) {
out[i] = in[i];
if(in[i] == Isis::Null) nullPixels = true;
}

// Null all pixels in the spectra if necessary
if(nullPixels) {
for(int i = 0; i < in.size(); i++) {
out[i] = Isis::Null;
}
}
}
}
19 changes: 19 additions & 0 deletions isis/src/base/apps/bandtrim/bandtrim.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 bandtrim_h
#define bandtrim_h

#include "UserInterface.h"

namespace Isis{
extern void bandtrim(UserInterface &ui);
extern void bandtrim(Cube *iCube, UserInterface &ui);
}

#endif
3 changes: 3 additions & 0 deletions isis/src/base/apps/bandtrim/bandtrim.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
<change name="Steven Lambright" date="2008-05-12">
Removed references to CubeInfo
</change>
<change name="Ken Edmundson" date="2024-07-31">
Converted to callable app and converted Makefile tests to gtests.
</change>
</history>

<groups>
Expand Down
42 changes: 14 additions & 28 deletions isis/src/base/apps/bandtrim/main.cpp
Original file line number Diff line number Diff line change
@@ -1,34 +1,20 @@
#include "Isis.h"
#include "ProcessByBrick.h"
#include "SpecialPixel.h"
/** This is free and unencumbered software released into the public domain.
using namespace std;
using namespace Isis;
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. **/

void BandTrim(Buffer &in, Buffer &out);
/* SPDX-License-Identifier: CC0-1.0 */

void IsisMain() {
ProcessByBrick p;
Cube *icube = p.SetInputCube("FROM");
p.SetBrickSize(1, 1, icube->bandCount());
p.SetOutputCube("TO");
p.StartProcess(BandTrim);
p.EndProcess();
}
#include "Isis.h"

// Trim spectral pixels if anyone of them is null
void BandTrim(Buffer &in, Buffer &out) {
// Copy input to output and check to see if we should null
bool nullPixels = false;
for(int i = 0; i < in.size(); i++) {
out[i] = in[i];
if(in[i] == Isis::Null) nullPixels = true;
}
#include "bandtrim.h"

// Null all pixels in the spectra if necessary
if(nullPixels) {
for(int i = 0; i < in.size(); i++) {
out[i] = Isis::Null;
}
}
#include "Application.h"

using namespace Isis;

void IsisMain() {
UserInterface &ui = Application::GetUserInterface();
bandtrim(ui);
}
4 changes: 0 additions & 4 deletions isis/src/base/apps/bandtrim/tsts/Makefile

This file was deleted.

6 changes: 0 additions & 6 deletions isis/src/base/apps/bandtrim/tsts/default/Makefile

This file was deleted.

6 changes: 0 additions & 6 deletions isis/src/base/apps/bandtrim/tsts/oneband/Makefile

This file was deleted.

192 changes: 192 additions & 0 deletions isis/tests/FunctionalTestsBandtrim.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@

#include <QString>
#include <QVector>

#include "Brick.h"
#include "CameraFixtures.h"
#include "Histogram.h"
#include "bandtrim.h"

#include "gtest/gtest.h"

using namespace Isis;

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

/**
* BandtrimDefault Test
*
* BandtrimDefault test given a single 5x5 input cube with 7 bands.
* One pixel in each band is set to Isis::Null as below.
* N implies a Null pixel, N1 is band 1, N2 is band 2, etc.
* All Null pixels should be duplicated across each band in the
* output Cube.
*
* The output cube is verified by checking the histogram statistics
* for each band.
*
* | |N1| |N2| |
* | | | | | |
* |N3| |N4| |N5|
* | | | | | |
* | |N6| |N7| |
*
* INPUT: testCube from DefaultCube fixture modified as above.
*
* OUTPUT: bandtrimDefaultOut.cub
*
*/
TEST_F(DefaultCube, FunctionalTestBandtrimDefault) {

// reduce test cube size, create seven bands
resizeCube(5, 5, 7);

// set one pixel in each of the seven bands to Isis::Null
// following the pattern in the comment block above

Brick b(1, 1, 1, testCube->pixelType()); // create buffer of size 1 pixel

b.SetBasePosition(2, 1, 1);
b[0] = Isis::Null;
testCube->write(b);

b.SetBasePosition(4, 1, 2);
b[0] = Isis::Null;
testCube->write(b);

b.SetBasePosition(1, 3, 3);
b[0] = Isis::Null;
testCube->write(b);

b.SetBasePosition(3, 3, 4);
b[0] = Isis::Null;
testCube->write(b);

b.SetBasePosition(5, 3, 5);
b[0] = Isis::Null;
testCube->write(b);

b.SetBasePosition(2, 5, 6);
b[0] = Isis::Null;
testCube->write(b);

b.SetBasePosition(4, 5, 7);
b[0] = Isis::Null;
testCube->write(b);

// run bandtrim
QVector<QString> args = {"to=" + tempDir.path() + "/bandtrimDefaultOut.cub"};
UserInterface ui(APP_XML, args);

try {
bandtrim(testCube, ui);
}
catch(IException &e) {
FAIL() << e.toString().toStdString().c_str() << std::endl;
}

// Open output cube
Cube outCube(tempDir.path() + "/bandtrimDefaultOut.cub");

// validate histogram statistics for each band in output cube
std::unique_ptr<Histogram> band1Hist (outCube.histogram(1));
std::unique_ptr<Histogram> band2Hist (outCube.histogram(2));
std::unique_ptr<Histogram> band3Hist (outCube.histogram(3));
std::unique_ptr<Histogram> band4Hist (outCube.histogram(4));
std::unique_ptr<Histogram> band5Hist (outCube.histogram(5));
std::unique_ptr<Histogram> band6Hist (outCube.histogram(6));
std::unique_ptr<Histogram> band7Hist (outCube.histogram(7));

EXPECT_EQ(band1Hist->ValidPixels(), 18);
EXPECT_EQ(band1Hist->Average(), 13);
EXPECT_EQ(band1Hist->Sum(), 234);
EXPECT_EQ(band2Hist->ValidPixels(), 18);
EXPECT_EQ(band2Hist->Average(), 38);
EXPECT_EQ(band2Hist->Sum(), 684);
EXPECT_EQ(band3Hist->ValidPixels(), 18);
EXPECT_EQ(band3Hist->Average(), 63);
EXPECT_EQ(band3Hist->Sum(), 1134);
EXPECT_EQ(band4Hist->ValidPixels(), 18);
EXPECT_EQ(band4Hist->Average(), 88);
EXPECT_EQ(band4Hist->Sum(), 1584);
EXPECT_EQ(band5Hist->ValidPixels(), 18);
EXPECT_EQ(band5Hist->Average(), 113);
EXPECT_EQ(band5Hist->Sum(), 2034);
EXPECT_EQ(band6Hist->ValidPixels(), 18);
EXPECT_EQ(band6Hist->Average(), 138);
EXPECT_EQ(band6Hist->Sum(), 2484);
EXPECT_EQ(band7Hist->ValidPixels(), 18);
EXPECT_EQ(band7Hist->Average(), 163);
EXPECT_EQ(band7Hist->Sum(), 2934);

outCube.close();
}


/**
* BandtrimOneBand Test
*
* BandtrimDefault test given a single 5x5 input cube with 1 band.
* The four pixels in the upper left corner are set to Isis::Null
* as below. N implies a Null pixel.
*
* The output cube is verified by checking histogram statistics.
*
* |N|N| | | |
* |N|N| | | |
* | | | | | |
* | | | | | |
* | | | | | |
*
* INPUT: testCube from DefaultCube fixture
*
* OUTPUT: bandtrimOneBandOut.cub
*/
TEST_F(DefaultCube, FunctionalTestBandtrimOneBand) {

// reduce test cube size
resizeCube(5, 5, 1);

// set 4 pixel block in upper left corner to Isis::Null
Brick b(1, 1, 1, testCube->pixelType()); // create buffer of size 4 pixels
b.SetBasePosition(1, 1, 1);
b[0] = Isis::Null;
testCube->write(b);

b.SetBasePosition(2, 1, 1);
b[0] = Isis::Null;
testCube->write(b);

b.SetBasePosition(1, 2, 1);
b[0] = Isis::Null;
testCube->write(b);

b.SetBasePosition(2, 2, 1);
b[0] = Isis::Null;
testCube->write(b);

// run bandtrim
QVector<QString> args = {"to=" + tempDir.path() + "/bandtrimOneBandOut.cub"};

UserInterface ui(APP_XML, args);

try {
bandtrim(testCube, ui);
}
catch(IException &e) {
FAIL() << e.toString().toStdString().c_str() << std::endl;
}

// Open output cube
Cube outCube(tempDir.path() + "/bandtrimOneBandOut.cub");

// validate histogram statistics for each band in output cube
std::unique_ptr<Histogram> band1Hist (outCube.histogram(1));

EXPECT_EQ(band1Hist->ValidPixels(), 21);
EXPECT_EQ(band1Hist->Average(), 14.714285714285714);
EXPECT_EQ(band1Hist->Sum(), 309);

outCube.close();
}

0 comments on commit f466c64

Please sign in to comment.