Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Hayabusa2 translation #5433

Merged
merged 5 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ release.
- Added new option in `ctxcal` to use monthly computed flatfield files for "Frown" removal in CTX images. [#5338](https://github.com/DOI-USGS/ISIS3/pull/5338)
- CSMCamera can now read and use the body rotation from ALE produced ISDs [#5072](https://github.com/DOI-USGS/ISIS3/pull/5072)
- CSMSkyMap added to CSMCamera for use with local rover projections in ISIS [#5072](https://github.com/DOI-USGS/ISIS3/pull/5072)
- Added new Hayabusa2 translation for `SpacecraftName` to accept `HAYABUSA2` [#5395](https://github.com/DOI-USGS/ISIS3/issues/5395)
- Added ALLOWERROR parameter to campt [#5393](https://github.com/DOI-USGS/ISIS3/pull/5393)
- OSIRIS-REx Tagcams instrument support, tests, and test data added [#5424](https://github.com/DOI-USGS/ISIS3/issues/5424)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Group = SpacecraftName
InputPosition = FitsLabels
OutputName = SpacecraftName
OutputPosition = (Object, IsisCube, Group, Instrument)
Translation = (HAYABUSA-2, HAYABUSA2)
Translation = (*, *)
End_Group

Expand Down
136 changes: 136 additions & 0 deletions isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/** 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 <QString>

#include "FileName.h"
#include "iTime.h"
#include "OriginalLabel.h"
#include "ProcessImportFits.h"
#include "Pvl.h"
#include "PvlGroup.h"
#include "PvlKeyword.h"
#include "PvlObject.h"
#include "PvlToPvlTranslationManager.h"
#include "UserInterface.h"

using namespace std;

namespace Isis {

// Cube *outputCube = NULL;

void hyb2onc2isis(UserInterface &ui) {
ProcessImportFits importFits;
importFits.setFitsFile(FileName(ui.GetFileName("FROM")));
importFits.setProcessFileStructure(0);

CubeAttributeOutput &att = ui.GetOutputAttribute("TO");
Cube *outputCube = importFits.SetOutputCube(ui.GetCubeName("TO"), att);

// Get the directory where the Hayabusa translation tables are.
QString transDir = "$ISISROOT/appdata/translations/";

// Create a PVL to store the translated labels in
Pvl outputLabel;

// Get the FITS label
Pvl fitsLabel;
fitsLabel.addGroup(importFits.fitsImageLabel(0));

try {
fitsLabel.addGroup(importFits.extraFitsLabel(0));
}
catch (IException &e) {
QString msg = "Input file [" + FileName(ui.GetFileName("FROM")).expanded() +
"] does not appear to be a Hayabusa2/ONC label file.";
throw IException(e, IException::Unknown, msg, _FILEINFO_);
}

QString instid;
QString missid;
try {
instid = fitsLabel.findGroup("FitsLabels").findKeyword("INSTRUME")[0];
missid = fitsLabel.findGroup("FitsLabels").findKeyword ("SPCECRFT")[0];
}
catch (IException &e) {
QString msg = "Unable to read instrument ID, [INSTRUME], or spacecraft ID, [SPCECRFT], "
"from input file [" + FileName(ui.GetFileName("FROM")).expanded() + "]";
throw IException(e, IException::Io,msg, _FILEINFO_);
}

missid = missid.simplified().trimmed();
if ((QString::compare(missid, "HAYABUSA2", Qt::CaseInsensitive) != 0) && (QString::compare(missid, "HAYABUSA-2", Qt::CaseInsensitive) != 0)) {
QString msg = "Input file [" + FileName(ui.GetFileName("FROM")).expanded() +
"] does not appear to be a Hayabusa2 label file.";
throw IException(IException::Unknown, msg, _FILEINFO_);
}
instid = instid.simplified().trimmed();
if (QString::compare(instid, "Optical Navigation Camera", Qt::CaseInsensitive) != 0) {
QString msg = "Input file [" + FileName(ui.GetFileName("FROM")).expanded() +
"] does not appear to be a Hayabusa2/ONC label file.";
throw IException(IException::Unknown, msg, _FILEINFO_);
}

// Translate the Instrument group
FileName transFile(transDir + "Hayabusa2OncInstrument.trn");
PvlToPvlTranslationManager instrumentXlater (fitsLabel, transFile.expanded());
instrumentXlater.Auto(outputLabel);

// Update target if user specifies it
PvlGroup &instGrp = outputLabel.findGroup("Instrument",Pvl::Traverse);
QString target;
if (ui.WasEntered("TARGET")) {
instGrp["TargetName"] = ui.GetString("TARGET");
}
instGrp["ExposureDuration"].setUnits("seconds");
outputCube->putGroup(instGrp);

// Translate the BandBin group
transFile = transDir + "Hayabusa2OncBandBin.trn";
PvlToPvlTranslationManager bandBinXlater (fitsLabel, transFile.expanded());
bandBinXlater.Auto(outputLabel);
PvlGroup &bandGrp = outputLabel.findGroup("BandBin",Pvl::Traverse);
if (bandGrp.hasKeyword("Width")) { // if width exists, then so must center
bandGrp["Width"].setUnits("nanometers");
bandGrp["Center"].setUnits("nanometers");
}
outputCube->putGroup(outputLabel.findGroup("BandBin",Pvl::Traverse));

// Translate the Archive group
transFile = transDir + "Hayabusa2OncArchive.trn";
PvlToPvlTranslationManager archiveXlater (fitsLabel, transFile.expanded());
archiveXlater.Auto(outputLabel);
PvlGroup &archGrp = outputLabel.findGroup("Archive", Pvl::Traverse);
QString source = archGrp.findKeyword("SourceProductId")[0];
archGrp["SourceProductId"].setValue(FileName(source).baseName());

// Create YearDoy keyword in Archive group
iTime stime(outputLabel.findGroup("Instrument", Pvl::Traverse)["StartTime"][0]);
PvlKeyword yeardoy("YearDoy", toString(stime.Year()*1000 + stime.DayOfYear()));
archGrp.addKeyword(yeardoy);
outputCube->putGroup(archGrp);


// Create a Kernels group
transFile = transDir + "Hayabusa2OncKernels.trn";
PvlToPvlTranslationManager kernelsXlater(fitsLabel, transFile.expanded());
kernelsXlater.Auto(outputLabel);
outputCube->putGroup(outputLabel.findGroup("Kernels", Pvl::Traverse));

// Now write the FITS augmented label as the original label
// Save the input FITS label in the Cube original labels
OriginalLabel originalLabel(fitsLabel);
outputCube->write(originalLabel);

// Convert the image data
importFits.Progress()->SetText("Importing Hayabusa2 image");
importFits.StartProcess();
importFits.Finalize();
}
}
18 changes: 18 additions & 0 deletions isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef hyb2onc2isis_h
#define hyb2onc2isis_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. **/

/* SPDX-License-Identifier: CC0-1.0 */

#include "UserInterface.h"

namespace Isis {
extern void hyb2onc2isis(UserInterface &ui);
}

#endif
122 changes: 4 additions & 118 deletions isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,128 +8,14 @@ find files of those names at the top level of this repository. **/

#include "Isis.h"

#include <QString>

#include "FileName.h"
#include "iTime.h"
#include "OriginalLabel.h"
#include "ProcessImportFits.h"
#include "Pvl.h"
#include "PvlGroup.h"
#include "PvlKeyword.h"
#include "PvlObject.h"
#include "PvlToPvlTranslationManager.h"
#include "UserInterface.h"
#include "Application.h"
#include "hyb2onc2isis.h"

using namespace std;
using namespace Isis;

void IsisMain () {

ProcessImportFits importFits;
void IsisMain() {
UserInterface &ui = Application::GetUserInterface();
importFits.setFitsFile(FileName(ui.GetFileName("FROM")));
importFits.setProcessFileStructure(0);

Cube *outputCube = importFits.SetOutputCube("TO");

// Get the directory where the Hayabusa translation tables are.
QString transDir = "$ISISROOT/appdata/translations/";

// Create a PVL to store the translated labels in
Pvl outputLabel;

// Get the FITS label
Pvl fitsLabel;
fitsLabel.addGroup(importFits.fitsImageLabel(0));
try {
fitsLabel.addGroup(importFits.extraFitsLabel(0));
}
catch (IException &e) {
QString msg = "Input file [" + FileName(ui.GetFileName("FROM")).expanded() +
"] does not appear to be a Hayabusa2/ONC label file.";
throw IException(e, IException::Unknown, msg, _FILEINFO_);
}

QString instid;
QString missid;
try {
instid = fitsLabel.findGroup("FitsLabels").findKeyword("INSTRUME")[0];
missid = fitsLabel.findGroup("FitsLabels").findKeyword ("SPCECRFT")[0];
}
catch (IException &e) {
QString msg = "Unable to read instrument ID, [INSTRUME], or spacecraft ID, [SPCECRFT], "
"from input file [" + FileName(ui.GetFileName("FROM")).expanded() + "]";
throw IException(e, IException::Io,msg, _FILEINFO_);
}

missid = missid.simplified().trimmed();
if ((QString::compare(missid, "HAYABUSA2", Qt::CaseInsensitive) != 0) && (QString::compare(missid, "HAYABUSA-2", Qt::CaseInsensitive) != 0)) {
QString msg = "Input file [" + FileName(ui.GetFileName("FROM")).expanded() +
"] does not appear to be a Hayabusa2 label file.";
throw IException(IException::Unknown, msg, _FILEINFO_);
}
instid = instid.simplified().trimmed();
if (QString::compare(instid, "Optical Navigation Camera", Qt::CaseInsensitive) != 0) {
QString msg = "Input file [" + FileName(ui.GetFileName("FROM")).expanded() +
"] does not appear to be a Hayabusa2/ONC label file.";
throw IException(IException::Unknown, msg, _FILEINFO_);
}

// Translate the Instrument group
FileName transFile(transDir + "Hayabusa2OncInstrument.trn");
PvlToPvlTranslationManager instrumentXlater (fitsLabel, transFile.expanded());
instrumentXlater.Auto(outputLabel);

// Update target if user specifies it
PvlGroup &instGrp = outputLabel.findGroup("Instrument",Pvl::Traverse);
QString target;
if (ui.WasEntered("TARGET")) {
instGrp["TargetName"] = ui.GetString("TARGET");
}
instGrp["ExposureDuration"].setUnits("seconds");
outputCube->putGroup(instGrp);

// Translate the BandBin group
transFile = transDir + "Hayabusa2OncBandBin.trn";
PvlToPvlTranslationManager bandBinXlater (fitsLabel, transFile.expanded());
bandBinXlater.Auto(outputLabel);
PvlGroup &bandGrp = outputLabel.findGroup("BandBin",Pvl::Traverse);
if (bandGrp.hasKeyword("Width")) { // if width exists, then so must center
bandGrp["Width"].setUnits("nanometers");
bandGrp["Center"].setUnits("nanometers");
}
outputCube->putGroup(outputLabel.findGroup("BandBin",Pvl::Traverse));

// Translate the Archive group
transFile = transDir + "Hayabusa2OncArchive.trn";
PvlToPvlTranslationManager archiveXlater (fitsLabel, transFile.expanded());
archiveXlater.Auto(outputLabel);
PvlGroup &archGrp = outputLabel.findGroup("Archive", Pvl::Traverse);
QString source = archGrp.findKeyword("SourceProductId")[0];
archGrp["SourceProductId"].setValue(FileName(source).baseName());

// Create YearDoy keyword in Archive group
iTime stime(outputLabel.findGroup("Instrument", Pvl::Traverse)["StartTime"][0]);
PvlKeyword yeardoy("YearDoy", toString(stime.Year()*1000 + stime.DayOfYear()));
archGrp.addKeyword(yeardoy);
outputCube->putGroup(archGrp);


// Create a Kernels group
transFile = transDir + "Hayabusa2OncKernels.trn";
PvlToPvlTranslationManager kernelsXlater(fitsLabel, transFile.expanded());
kernelsXlater.Auto(outputLabel);
outputCube->putGroup(outputLabel.findGroup("Kernels", Pvl::Traverse));

// Now write the FITS augmented label as the original label
// Save the input FITS label in the Cube original labels
OriginalLabel originalLabel(fitsLabel);
outputCube->write(originalLabel);

// Convert the image data
importFits.Progress()->SetText("Importing Hayabusa2 image");
importFits.StartProcess();
importFits.Finalize();

hyb2onc2isis(ui);
}
77 changes: 77 additions & 0 deletions isis/tests/FunctionalTestsHyb2onc2isis.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include <QTemporaryDir>
#include <QFile>

#include "hyb2onc2isis.h"
#include "Pvl.h"
#include "PvlGroup.h"
#include "TestUtilities.h"
#include "Histogram.h"
#include "OriginalLabel.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

using namespace Isis;
using ::testing::HasSubstr;

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

TEST(Hyb2onc2isis, Hyb2onc2isisTestDefault) {
QTemporaryDir prefix;
QString cubeFileName = prefix.path() + "/hyb2onc2isisTEMP.cub";
QVector<QString> args = {"from=data/hyb2onc2isis/hyb2_onc_20151203_000006_w2f_l2a.fit",
"to=" + cubeFileName };

UserInterface options(APP_XML, args);
try {
hyb2onc2isis(options);
}
catch (IException &e) {
FAIL() << "Unable to ingest HYB2ONC image: " << e.toString().toStdString().c_str() << std::endl;
}
Cube cube(cubeFileName);
Pvl *isisLabel = cube.label();

// Dimensions Group
ASSERT_EQ(cube.sampleCount(), 1024);
ASSERT_EQ(cube.lineCount(), 1024);
ASSERT_EQ(cube.bandCount(), 1);

// Pixels Group
ASSERT_EQ(PixelTypeName(cube.pixelType()), "Real");
ASSERT_EQ(ByteOrderName(cube.byteOrder()), "Lsb");
ASSERT_DOUBLE_EQ(cube.base(), 0.0);
ASSERT_DOUBLE_EQ(cube.multiplier(), 1.0);

// Instrument Group
PvlGroup &inst = isisLabel->findGroup("Instrument", Pvl::Traverse);
ASSERT_EQ(inst["SpacecraftName"][0].toStdString(), "HAYABUSA-2");
ASSERT_EQ(inst["InstrumentId"][0].toStdString(), "ONC-W2" );
ASSERT_EQ(inst["StartTime"][0].toStdString(), "2015-12-03T00:00:06.637" );
ASSERT_EQ(inst["StopTime"][0].toStdString(), "2015-12-03T00:00:06.641" );
ASSERT_EQ(inst["SpacecraftClockStartCount"][0].toStdString(), "1/1009473117" );
ASSERT_EQ(inst["TargetName"][0].toStdString(), "Earth" );

// Archive Group
PvlGroup &archive = isisLabel->findGroup("Archive", Pvl::Traverse);
ASSERT_EQ(archive["ProducerId"][0].toStdString(), "ISAS/JAXA" );
ASSERT_EQ(archive["FormatType"][0].toStdString(), "HAYABUSA2 IMAGE ONC L2a" );
ASSERT_EQ(archive["Contenttype"][0].toStdString(), "ONC-W2 NON SMEARCORRECTED");
ASSERT_EQ(archive["SourceProductId"][0].toStdString(), "hyb2_onc_20151203_000006_w2f_l2a" );

// Kernels Group
PvlGroup &kernel = isisLabel->findGroup("Kernels", Pvl::Traverse);
ASSERT_EQ(int(kernel["NaifFrameCode"]), -37120);

std::unique_ptr<Histogram> hist (cube.histogram());

ASSERT_NEAR(hist->Average(), 297.8918, .0001);
ASSERT_DOUBLE_EQ(hist->Sum(), 312362230);
ASSERT_EQ(hist->ValidPixels(), 1048576);
ASSERT_NEAR(hist->StandardDeviation(), 65.75840, .00001);

// check original label exists
Pvl ogLabel = cube.readOriginalLabel().ReturnLabels();
PvlGroup &fitsLabel = ogLabel.findGroup("FitsLabels", Pvl::Traverse);
ASSERT_EQ(fitsLabel["SPCECRFT"][0].toStdString(), "HAYABUSA2" );
}
61 changes: 61 additions & 0 deletions isis/tests/data/hyb2onc2isis/hyb2_onc_20151203_000006_w2f_l2a.fit

Large diffs are not rendered by default.