-
Notifications
You must be signed in to change notification settings - Fork 179
Add ShadowCam ISIS #6011
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
Merged
Merged
Add ShadowCam ISIS #6011
Changes from all commits
Commits
Show all changes
51 commits
Select commit
Hold shift + click to select a range
18f343f
Implement ShadowCam ISIS apps and camera
2582cd1
Add KPLO and ShadowCam translations
a249601
Move shadowcam macro constants to constexprs in a ShadowCam sub-names…
cordellmichaud 5a894d7
Refactor ShadowCamUtilities
cordellmichaud 005d2c0
Add license comment to ShadowCamConstants.h and ShadowCamUtilities.h
cordellmichaud 6957af4
Simplify ShadowCamCamera for readability
cordellmichaud ac57fde
Slightly refactor ShadowCamDistortionMap
cordellmichaud d245ae0
Refactor shadowcam2isis and fix indexing bug
cordellmichaud da167c9
Fix docstring history formatting
cordellmichaud 574a656
Cleanup shadowcamcal.cpp
cordellmichaud fc9f25f
Cleanup shadowcamcal.h to match shadowcamcal.cpp
cordellmichaud 3d6b5be
Cleanup shadowcamcal main.cpp
cordellmichaud 332b3b0
Improve WriteCube and move it to shadowcamcal
cordellmichaud 537f38b
Make include guard lowercase
cordellmichaud aa32154
Add missing scope prefix and header
cordellmichaud 0008ea7
Tidy and move bias pixel subtraction to sub-namespace in shadowcamcal
cordellmichaud 074e269
Update shadowcamcal docstring and add docstrings for WriteCube and Su…
cordellmichaud ad651ab
Refactor and move dark subtraction to shadowcamcal
cordellmichaud 1f6c70a
Changed INTRCPTCOEFF parameter to INTERCEPTCOEFF and updated document…
cordellmichaud 017f2c4
Move flatfield correction to shadowcamcal and refactor it
cordellmichaud 859dd65
Add history to CorrectFlatfield docstring
cordellmichaud 16bd1b0
Move gain correction to shadowcamcal and refactor it
cordellmichaud 4090fbc
Add additional context to CorrectDark and CorrectFlatfield docstring …
cordellmichaud e556798
Fix QString error text formatting
cordellmichaud 73a3452
Make variable naming consistent and remove debug messages
cordellmichaud e40100d
Rename, refactor, and move radiance correction to shadowcamcal
cordellmichaud 8865d71
Replace exits and cerr printouts with thrown ISIS exceptions
cordellmichaud 72d89bb
Rename GetTdiFactor instrument parameter to instrumentGroup for consi…
cordellmichaud 204e0f3
Use GetTdiFactor helper rather than repeating code
cordellmichaud d13940b
Add missing header
cordellmichaud d0dfe3f
Fix incorrect timing in ShadowCamCamera
cordellmichaud 755a5e3
Correct usage of ShadowCam constants in shadowcam2isis
cordellmichaud 240b8d8
Cleanup error messages and casting
cordellmichaud 0225b14
Remove unused TDIDirection logic from ShadowCamCamera
cordellmichaud da3ce2d
Add safe casting during index comparison
cordellmichaud 2816c11
Move CorrectRadiance so it is actually within the ShadowCam namespace
cordellmichaud 1049247
Remove now-nonexistent RadianceCoefficients include
cordellmichaud 87e5c82
Ensure LoadOutputCube's type agrees with that expected by StartProcess
cordellmichaud e546bdf
Make variable naming consistent
cordellmichaud f124ef1
Remove unused log parameter from shadowcam2isis
cordellmichaud a49bf49
Add TDI offset and constant time offset back into ShadowCamCamera timing
cordellmichaud 37c0b80
Minor change to ShadowCamCamera instrument check
cordellmichaud 87790eb
Update shadowcam2isis xml documentation and add an error if users try…
acpaquette 347e526
Added error in shadowcamcal if users try to run the program on calibr…
acpaquette 422e589
Add calibration check function
acpaquette baa87bf
Addressed comments
acpaquette af14f86
Merge pull request #1 from acpaquette/dev-shadowcam-isis
cordellmichaud 1a308c6
Add tests for shadowcam2isis
acpaquette a122909
Add tests for shadowcamcal
acpaquette 3be2757
Add tests for shadowcam camera
acpaquette 144a76d
Added missed shadowcam camera fixture
acpaquette File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
33 changes: 33 additions & 0 deletions
33
isis/appdata/serialnumbers/KploShadowCamCameraSerialNumber.trn
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| ObservationKeys =3 | ||
|
|
||
| Group = Keyword1 | ||
| Auto | ||
| InputKey = SpacecraftName | ||
| InputGroup = "IsisCube,Instrument" | ||
| InputPosition = (IsisCube, Instrument) | ||
| OutputName = Keyword1 | ||
| OutputPosition = (Group, SerialNumberKeywords) | ||
| Translation = (KPLO, "KOREA PATHFINDER LUNAR ORBITER") | ||
| Translation = (*, *) | ||
| End_Group | ||
|
|
||
| Group = Keyword2 | ||
| Auto | ||
| InputKey = ExecutionSpacecraftTime | ||
| InputGroup = "IsisCube,Instrument" | ||
| InputPosition = (IsisCube, Instrument) | ||
| OutputName = Keyword2 | ||
| OutputPosition = (Group, SerialNumberKeywords) | ||
| Translation = (*, *) | ||
| End_Group | ||
|
|
||
| Group = Keyword3 | ||
| Auto | ||
| InputKey = InstrumentId | ||
| InputGroup = "IsisCube,Instrument" | ||
| InputPosition = (IsisCube, Instrument) | ||
| OutputName = Keyword3 | ||
| OutputPosition = (Group, SerialNumberKeywords) | ||
| Translation = (*, *) | ||
| End_Group | ||
| End |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| include $(ISISROOT)/make/isismake.cat | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| include $(ISISROOT)/make/isismake.appstree | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| ifeq ($(ISISROOT), $(BLANK)) | ||
| .SILENT: | ||
| error: | ||
| echo "Please set ISISROOT"; | ||
| else | ||
| include $(ISISROOT)/make/isismake.apps | ||
| endif | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| /** 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 "Isis.h" | ||
|
|
||
| #include "Application.h" | ||
| #include "UserInterface.h" | ||
|
|
||
| #include "shadowcam2isis.h" | ||
|
|
||
| using namespace Isis; | ||
|
|
||
| void IsisMain (){ | ||
| UserInterface &ui = Application::GetUserInterface(); | ||
| shadowcam2isis(ui); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,206 @@ | ||
| /** 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 <array> | ||
| #include <cstdint> | ||
| #include <memory> | ||
|
|
||
| #include <QString> | ||
| #include <QStringBuilder> | ||
|
|
||
| #include "Buffer.h" | ||
| #include "CubeAttribute.h" | ||
| #include "FileName.h" | ||
| #include "IException.h" | ||
| #include "IString.h" | ||
| #include "ProcessByLine.h" | ||
| #include "Pvl.h" | ||
| #include "PvlGroup.h" | ||
| #include "UserInterface.h" | ||
|
|
||
| #include "ShadowCamConstants.h" | ||
| #include "ShadowCamUtilities.h" | ||
|
|
||
| #include "shadowcam2isis.h" | ||
|
|
||
| using std::uint8_t, std::uint16_t; | ||
|
|
||
| namespace Isis { | ||
|
|
||
| void shadowcam2isis(UserInterface &ui) { | ||
| try{ | ||
| const bool keepSpecial = ui.GetBoolean("KEEPSPECIALPIXELS"); | ||
| const FileName from = FileName(ui.GetCubeName("FROM")); | ||
|
|
||
| if (ShadowCam::IsCalibrated(from)) { | ||
| const QString msg = "File [" + from.name() + "] is calibrated, no need to run shadowcam2isis"; | ||
| throw IException(IException::User, msg, _FILEINFO_); | ||
| } | ||
|
|
||
| // Use a smart pointer for automatic memory management | ||
| const auto inLabel = std::make_unique<Pvl>(from.expanded()); | ||
|
|
||
| // Error check for instrument label | ||
| const PvlGroup &instrument = inLabel->findObject("IsisCube").findGroup("Instrument"); | ||
|
|
||
| if (!instrument.hasKeyword("InstrumentId") && !instrument.hasKeyword("InstrumentID")) { | ||
| const QString msg = "Keyword InstrumentID or InstrumentId was not found in labels."; | ||
| throw IException(IException::User, msg, _FILEINFO_); | ||
| } | ||
|
|
||
| if (QString::compare(instrument["InstrumentId"], "ShadowCam", Qt::CaseInsensitive) != 0) { | ||
| const QString msg = "Error: InstrumentId not equal to ShadowCam."; | ||
| throw IException(IException::User, msg, _FILEINFO_); | ||
| } | ||
|
|
||
| // Get xTerm, bTerm, lines from raw edr label | ||
| std::array<int, 6> bTerm; | ||
| bTerm.fill(9999); | ||
| std::array<int, 6> xTerm; | ||
| xTerm.fill(9999); | ||
| xTerm[5] = 4096; | ||
|
|
||
| // Load term arrays | ||
| for (int i = 0; i < 6; i++) { | ||
| if (i != 0) { | ||
| QString bTermKey = "Bterm" % toString(i); | ||
| bTerm[i] = (ShadowCam::GetFromLabels(instrument, bTermKey)).toInt(); | ||
| } | ||
|
|
||
| if (i != 5) { | ||
| QString xTermKey = "Xterm" % toString(i); | ||
| xTerm[i] = (ShadowCam::GetFromLabels(instrument, xTermKey)).toInt(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * @brief Compands DN values to 8-bit values. | ||
| * | ||
| * This function is used to create a companding table for the decompanding routine. | ||
| * | ||
| * @param dn Incoming DN pixel value. | ||
| * @param bTerm ShadowCam bterms. | ||
| * @param xTerm ShadowCam xterms. | ||
| * | ||
| * @return Companded 8-bit value. | ||
| **/ | ||
| const auto compand = [](uint16_t dn, std::array<int, 6> bTerm, std::array<int, 6> xTerm) -> uint8_t { | ||
| for (int xTermIndex = 0; static_cast<size_t>(xTermIndex) < xTerm.size(); xTermIndex++) { | ||
| if (dn < xTerm[xTermIndex]) { | ||
| return ((dn >> xTermIndex) + bTerm[xTermIndex]) & 0xff; | ||
| } | ||
| } | ||
| const QString msg = QString("Failed to compand value: %1").arg(toString(dn)); | ||
| throw IException(IException::User, msg, _FILEINFO_); | ||
| }; | ||
|
|
||
| /** | ||
| * @brief Decompands 8-bit DN values. | ||
| * | ||
| * Decompands 8-bit DN values and handles special pixels. | ||
| * | ||
| * @param in Input buffer. | ||
| * @param out Output buffer. | ||
| **/ | ||
| const auto decompand = [&compand, &bTerm, &xTerm, keepSpecial](Buffer &in, Buffer &out) -> void { | ||
| std::array<uint8_t, 4096> companding_table; | ||
|
|
||
| // Create companding table | ||
| for (uint16_t tableIndex = 0; tableIndex < companding_table.size(); tableIndex++) { | ||
| companding_table[tableIndex] = compand(tableIndex, bTerm, xTerm); | ||
| } | ||
|
|
||
| std::array<uint16_t, 256> decompanding_table; | ||
|
|
||
| // Create decompanding table | ||
| for (uint16_t decompandIndex = 0; decompandIndex < decompanding_table.size(); decompandIndex++) { | ||
| uint16_t min = 9999, max = 0; | ||
| for (uint16_t compandIndex = 0; compandIndex < 4096; compandIndex++) { | ||
| if (companding_table[compandIndex] == decompandIndex) { | ||
| if (min == 9999) { | ||
| min = compandIndex; | ||
| } | ||
| max = compandIndex; | ||
| } | ||
|
|
||
| if (min != 9999 && companding_table[compandIndex] != decompandIndex) { | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| decompanding_table[decompandIndex] = (min + max) / 2; | ||
| } | ||
|
|
||
| constexpr int bufferSize = ShadowCam::SHC_CHANNELS * ShadowCam::SHC_AFE_WIDTH; | ||
|
|
||
| // handle 8 bit special pixels first | ||
|
|
||
| // Process buffer | ||
| for (int bufferIndex = 0; bufferIndex < bufferSize; bufferIndex++) { | ||
| uint16_t tmpVal = static_cast<float> (in[bufferIndex]); | ||
| float tmpFloatVal; | ||
| if (keepSpecial) { | ||
| tmpFloatVal = ShadowCam::Set8bitMaxMintoSpecialPixelsHIS4LIS4(tmpVal); | ||
| } | ||
| else { | ||
| tmpFloatVal = static_cast<float>(tmpVal); | ||
| } | ||
|
|
||
| if (!ShadowCam::IsSpecialPixelSHC(tmpFloatVal)){ | ||
| // only decompanding non-special pixels | ||
| out[bufferIndex] = static_cast<uint16_t>(decompanding_table[(uint16_t) tmpFloatVal]); | ||
| if (out[bufferIndex] < 0) { | ||
| QString msg = QString("Value is less than zero for line: %1, pixel: %2.").arg( | ||
| QString::number(in.Line()), QString::number(bufferIndex)); | ||
| throw IException(IException::User, msg, _FILEINFO_); | ||
| } | ||
| } | ||
|
|
||
| /* | ||
| if (ShadowCam::IsSpecialPixelSHC(in[bufferIndex])) { | ||
| if (keepSpecial) | ||
| out[bufferIndex] = ShadowCam::Set8bitMaxMintoSpecialPixelsHIS4LIS4(in[bufferIndex]); | ||
| else { | ||
| // Special pixel handling | ||
| cout << "WARNING: Special pixels set to 0 or 255." << endl; | ||
| out[bufferIndex] = static_cast<float>(ShadowCam::Set_LIS_HIS_SpecialPixelsTo_0_255(in[bufferIndex])); | ||
| } | ||
| } | ||
| else { | ||
| // Decompanding non-special pixels | ||
| out[bufferIndex] = static_cast<float>(decompanding_table[(uint16_t) in[bufferIndex]]); | ||
| #if (out[bufferIndex] < 0){ | ||
| # cout << "Value is less than zero for line: " << std::to_string(in.Line()) << ", pixel: " << std::to_string(bufferIndex) << "at(i): " << std::to_string(in.at(bufferIndex)) << endl; | ||
| }*/ | ||
| } | ||
| }; | ||
|
|
||
| // Process raw EDR cube | ||
| CubeAttributeOutput outAttr = CubeAttributeOutput("+Real"); | ||
| Isis::CubeAttributeInput &att = ui.GetInputAttribute("FROM"); | ||
| ProcessByLine p; | ||
| p.SetInputCube(ui.GetCubeName("FROM"), att); | ||
| p.SetOutputCube(ui.GetCubeName("TO"), outAttr); | ||
| p.Progress()->SetText("Importing 8-bit EDR cube and decompanding..."); | ||
| p.StartProcess(decompand); | ||
| p.Progress()->SetText("Finalizing import..."); | ||
| p.Finalize(); | ||
| p.ClearCubes(); | ||
| } | ||
| catch (const IException &e) { | ||
| QString msg = QString("ISIS Exception. Unable to import ShadowCam image to ISIS"); | ||
| throw IException(e, IException::Unknown, msg, _FILEINFO_); | ||
| } | ||
| catch (const std::exception &e) { | ||
| QString msg = QString("Standard exception: %1. Unable to import ShadowCam image to ISIS").arg(QString(e.what())); | ||
| throw IException(IException::Programmer, msg, _FILEINFO_); | ||
| } | ||
| catch (...) { | ||
| throw IException(IException::Programmer, "Unknown exception occurred. Unable to import ShadowCam image to ISIS", _FILEINFO_); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #ifndef shadowcam2isis_h | ||
| #define shadowcam2isis_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 shadowcam2isis(UserInterface &ui); | ||
| } | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
|
|
||
| <application name="shadowcam2isis" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://isis.astrogeology.usgs.gov/Schemas/Application/application.xsd"> | ||
|
|
||
| <brief> | ||
| Import an ShadowCam image as an Isis cube | ||
| </brief> | ||
|
|
||
| <description> | ||
| This program takes a raw EDR image from the KPLO ShadowCam (Camera) and produces an Isis cube containing the image data. | ||
| ShadowCam images in the CDR or RDR format can be used directly, with no processing required. | ||
| </description> | ||
|
|
||
| <history> | ||
| <change name="Victor Silva" date="2022-06-25"> | ||
| Original Version | ||
| </change> | ||
| </history> | ||
|
|
||
| <category> | ||
| <missionItem>Korean Pathfinder Lunar Orbiter</missionItem> | ||
| </category> | ||
|
|
||
| <groups> | ||
| <group name="Files"> | ||
| <parameter name="FROM"> | ||
| <type>cube</type> | ||
| <fileMode>input</fileMode> | ||
| <brief> | ||
| Input cube | ||
| </brief> | ||
| <description> | ||
| The image to be processed | ||
| </description> | ||
| <filter> | ||
|
|
||
| </filter> | ||
| </parameter> | ||
|
|
||
| <parameter name="TO"> | ||
| <type>cube</type> | ||
| <pixelType>real</pixelType> | ||
| <fileMode>output</fileMode> | ||
| <brief> | ||
| Output cube | ||
| </brief> | ||
| <description> | ||
| This is the resultant cube, containing the image and label data. | ||
| </description> | ||
| <filter> | ||
| *.cub | ||
| </filter> | ||
| </parameter> | ||
| </group> | ||
|
|
||
| <group name="PixelOptions"> | ||
| <parameter name="KEEPSPECIALPIXELS"> | ||
| <type>boolean</type> | ||
| <default><item>True</item></default> | ||
| <brief> | ||
| Don't replace 0/255 with Special Pixels LIS/HIS | ||
| </brief> | ||
| <description> | ||
| Don't replace 0/255 with LIS/HIS | ||
| (default is to replace special pixels) | ||
| </description> | ||
| </parameter> | ||
| </group> | ||
| </groups> | ||
| </application> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| ifeq ($(ISISROOT), $(BLANK)) | ||
| .SILENT: | ||
| error: | ||
| echo "Please set ISISROOT"; | ||
| else | ||
| include $(ISISROOT)/make/isismake.apps | ||
| endif |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this for?