From 549a9041186b1747d3212232aa9c7bd2c9f2bf9c Mon Sep 17 00:00:00 2001 From: Amy Stamile <74275278+amystamile-usgs@users.noreply.github.com> Date: Tue, 29 Oct 2024 10:13:58 -0700 Subject: [PATCH] Adds Chandrayaan2 to isisimport (#5648) * Adds chandrayaan2 to isisimport * Addressed PR feedback --- CHANGELOG.md | 1 + isis/appdata/import/PDS4/Chandrayaan2TMC2.tpl | 96 ++++++++++ isis/appdata/import/fileTemplate.tpl | 5 + isis/src/base/apps/isisimport/isisimport.cpp | 12 ++ .../FunctionalTestsIsisImportChandrayaan2.cpp | 175 ++++++++++++++++++ ..._tmc_nca_20191128T0035389755_b_brw_d18.xml | 91 +++++++++ 6 files changed, 380 insertions(+) create mode 100644 isis/appdata/import/PDS4/Chandrayaan2TMC2.tpl create mode 100644 isis/tests/FunctionalTestsIsisImportChandrayaan2.cpp create mode 100644 isis/tests/data/isisimport/chan2/ch2_tmc_nca_20191128T0035389755_b_brw_d18.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 6edf242875..afc29fcea2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ release. - Added TOVECT output parameter which generate a geospatial CSV file with a VRT metadata sidecar file [#5571](https://github.com/DOI-USGS/ISIS3/issues/5571) - Added Vectorize to ProcessGroundPolygon library - Added gtest files for the app and unit test +- Added Chandrayaan2 template for isisimport ### Changed - Refactored the pixel2map app diff --git a/isis/appdata/import/PDS4/Chandrayaan2TMC2.tpl b/isis/appdata/import/PDS4/Chandrayaan2TMC2.tpl new file mode 100644 index 0000000000..dd05ce68a7 --- /dev/null +++ b/isis/appdata/import/PDS4/Chandrayaan2TMC2.tpl @@ -0,0 +1,96 @@ +{% set file_name = Product_Observational.File_Area_Observational.File.file_name %} +{% set sensor = FindCH2Sensor(file_name) %} + +{% set ImageArray = Product_Observational.File_Area_Observational.Array_2D_Image %} + +Object = IsisCube + Object = Core + Group = Dimensions + Samples = {{ ImageArray.Axis_Array.0.elements }} + Lines = {{ ImageArray.Axis_Array.1.elements }} + Bands = 1 + End_Group + + Group = Pixels + {% set pixelType = ImageArray.Element_Array.data_type %} + {% if exists("Product_Observational.File_Area_Observational.Array_2D_Image.Element_Array.data_type") %} + Type = {% if pixelType == "IEEE754LSBDouble" %} Double + {% else if pixelType == "IEEE754LSBSingle" %} Real + {% else if pixelType == "IEEE754MSBDouble" %} Double + {% else if pixelType == "IEEE754MSBSingle" %} Real + {% else if pixelType == "SignedByte" %} SignedByte + {% else if pixelType == "SignedLSB2" %} SignedWord + {% else if pixelType == "SignedLSB4" %} SignedInteger + {% else if pixelType == "SignedMSB2" %} SignedWord + {% else if pixelType == "SignedMSB4" %} SignedInteger + {% else if pixelType == "UnsignedByte" %} UnsignedByte + {% else if pixelType == "UnsignedLSB2" %} UnsignedWord + {% else if pixelType == "UnsignedLSB4" %} UnsignedInteger + {% else if pixelType == "UnsignedMSB2" %} UnsignedWord + {% else if pixelType == "UnsignedMSB4" %} UnsignedInteger + {% else %} Real + {% endif %} + ByteOrder = {% if pixelType == "IEEE754LSBDouble" %} LSB + {% else if pixelType == "IEEE754LSBSingle" %} LSB + {% else if pixelType == "IEEE754MSBDouble" %} MSB + {% else if pixelType == "IEEE754MSBSingle" %} MSB + {% else if pixelType == "SignedByte" %} LSB + {% else if pixelType == "SignedLSB2" %} LSB + {% else if pixelType == "SignedLSB4" %} LSB + {% else if pixelType == "SignedMSB2" %} MSB + {% else if pixelType == "SignedMSB4" %} MSB + {% else if pixelType == "UnsignedByte" %} LSB + {% else if pixelType == "UnsignedLSB2" %} LSB + {% else if pixelType == "UnsignedLSB4" %} LSB + {% else if pixelType == "UnsignedMSB2" %} MSB + {% else if pixelType == "UnsignedMSB4" %} MSB + {% else %} Lsb + {% endif %} + {% else %} + Type = Real + ByteOrder = Lsb + {% endif %} + + Base = {% if exists("Product_Observational.File_Area_Observational.Array_2D_Image.Element_Array.value_offset") %} + {{ ImageArray.Element_Array.value_offset }} + {% else if exists("Product_Observational.File_Area_Observational.Array_2D_Image.offset._text") %} + {{ ImageArray.offset._text }} + {% else %} + 0 + {% endif %} + Multiplier = {% if exists("Product_Observational.File_Area_Observational.Array_2D_Image.Element_Array.scaling_factor") %} + {{ ImageArray.Element_Array.scaling_factor._text }} + {% else %} + 1 + {% endif %} + End_Group + End_Object + + Group = Instrument + SpacecraftName = {{ Product_Observational.Observation_Area.Investigation_Area.name }} + {% set inst_name = Product_Observational.Observation_Area.Observing_System.Observing_System_Component.1.name %} + {% if inst_name == "terrain mapping camera" %} + InstrumentId = TMC-2 + {% endif %} + TargetName = {{ Product_Observational.Observation_Area.Target_Identification.name }} + StartTime = {{ RemoveStartTimeZ(Product_Observational.Observation_Area.Time_Coordinates.start_date_time) }} + StopTime = {{ RemoveStartTimeZ(Product_Observational.Observation_Area.Time_Coordinates.stop_date_time) }} + End_Group + + Group = BandBin + Center = 675 + Width = 175 + End_Group + + Group = Kernels + NaifFrameCode = {% if sensor == "a" %}-152212 + {% else if sensor == "f" %}-152211 + {% else if sensor == "n" %}-152210 + {% endif %} + + End_Group +End_Object + +Object = Translation +End_Object +End diff --git a/isis/appdata/import/fileTemplate.tpl b/isis/appdata/import/fileTemplate.tpl index 94535c6988..61db724210 100644 --- a/isis/appdata/import/fileTemplate.tpl +++ b/isis/appdata/import/fileTemplate.tpl @@ -93,6 +93,11 @@ {%- if InstrumentId == "OSINAC" or InstrumentId == "OSIWAC"-%} {%- set InstrumentId="Osiris" -%} {%- endif -%} +{%- else if SpacecraftName == "Chandrayaan-2"-%} + {%- set SpacecraftId="Chandrayaan2" -%} + {%- if InstrumentId == "terrain mapping camera"-%} + {%- set InstrumentId="TMC2" -%} + {%- endif -%} {%- endif -%} {#- Combine the pieces to output the file name to be used to import an image into a cube -#} diff --git a/isis/src/base/apps/isisimport/isisimport.cpp b/isis/src/base/apps/isisimport/isisimport.cpp index 2c6f2bfb60..71f20d1b05 100644 --- a/isis/src/base/apps/isisimport/isisimport.cpp +++ b/isis/src/base/apps/isisimport/isisimport.cpp @@ -341,6 +341,18 @@ namespace Isis { return inputString.substr(index, 1); }); + + + /** + * Find sensor type from Chandrayaan2 label's file_name + */ + env.add_callback("FindCH2Sensor", 1, [](Arguments& args) { + std::string fileName = args.at(0)->get<string>(); + + char sensor = fileName[10]; + + return std::string(1, sensor); + }); // end of inja callbacks diff --git a/isis/tests/FunctionalTestsIsisImportChandrayaan2.cpp b/isis/tests/FunctionalTestsIsisImportChandrayaan2.cpp new file mode 100644 index 0000000000..b95d506d43 --- /dev/null +++ b/isis/tests/FunctionalTestsIsisImportChandrayaan2.cpp @@ -0,0 +1,175 @@ +#include <iostream> +#include <time.h> + +#include <QRegExp> +#include <QString> +#include <QTemporaryDir> +#include <QTemporaryFile> +#include <QFileInfo> +#include <QDataStream> +#include <QTextStream> +#include <QByteArray> +#include <QDataStream> + +#include <nlohmann/json.hpp> +#include "TempFixtures.h" +#include "Histogram.h" +#include "md5wrapper.h" +#include "Pvl.h" +#include "PvlGroup.h" +#include "PvlKeyword.h" +#include "TestUtilities.h" +#include "isisimport.h" +#include "gmock/gmock.h" + +using namespace Isis; +using namespace testing; +using json = nlohmann::json; + +static QString APP_XML = FileName("$ISISROOT/bin/xml/isisimport.xml").expanded(); + +TEST_F(TempTestingFiles, FunctionalTestIsisImportChandrayaan2){ + std::istringstream PvlInput(R"( + Object = IsisCube + Object = Core + StartByte = 65537 + Format = Tile + TileSamples = 128 + TileLines = 400 + + Group = Dimensions + Samples = 17891 + Lines = 400 + Bands = 1 + End_Group + + Group = Pixels + Type = UnsignedByte + ByteOrder = Lsb + Base = 0.0 + Multiplier = 1.0 + End_Group + End_Object + + Group = Instrument + SpacecraftName = Chandrayaan-2 + InstrumentId = TMC-2 + TargetName = Moon + StartTime = 2019-11-28T00:35:38.9755 + StopTime = 2019-11-28T00:45:17.9161 + End_Group + + Group = BandBin + Center = 675 + Width = 175 + End_Group + + Group = Kernels + NaifFrameCode = -152212 + End_Group + End_Object + + Object = Label + Bytes = 65536 + End_Object + + Object = History + Name = IsisCube + StartByte = 7233537 + Bytes = 703 + End_Object + + Object = OriginalXmlLabel + Name = IsisCube + StartByte = 7234240 + Bytes = 4223 + ByteOrder = Lsb + End_Object + End + )"); + QString dataFilePath= "data/isisimport/chan2/ch2_tmc_nca_20191128T0035389755_b_brw_d18.xml"; + QString dataFileName = "ch2_tmc_nca_20191128T0035389755_b_brw_d18.xml"; + QString imageFileName = "ch2_tmc_nca_20191128T0035389755_b_brw_d18.img"; + QString cubeFileName = tempDir.path() + "/output.cub"; + + int samples = 400; + int lines = 17891; + int bytes = 2; + + // create a temp img file and write data to it + QFile tempImgFile(tempDir.path() + "/" + imageFileName); + + if(!tempImgFile.open(QFile::WriteOnly | QFile::Text)){ + FAIL() << " Could not open file for writing"; + } + QDataStream out(&tempImgFile); + + // generate lines + QByteArray writeToFile = QByteArray(); + short int fill = 0; + for(int i=-1; i<(samples * bytes); i++){ + writeToFile.append(fill); + } + + // write the lines to the temp file + for(int i=0; i<lines; i++){ + QDataStream out(&tempImgFile); + out << writeToFile; + } + tempImgFile.flush(); + tempImgFile.close(); + + // create a temp data file and copy the contents of the xml in to it + QFile tempDataFile(tempDir.path() + "/" + dataFileName); + + if(!tempDataFile.open(QFile::ReadWrite | QFile::Text)){ + FAIL() << " Could not open file for writing"; + } + + // open xml to get data + QFile realXmlFile(dataFilePath); + if (!realXmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) + { + FAIL() << "Failed to open file"; + } + + QTextStream xmlData(&tempDataFile); + xmlData << realXmlFile.readAll(); + + tempDataFile.close(); + realXmlFile.close(); + + QFileInfo fileInfo(tempDataFile); + + // testing with template + QVector<QString> args = {"from=" + fileInfo.absoluteFilePath(), "to=" + cubeFileName}; + UserInterface options(APP_XML, args); + isisimport(options); + + Pvl truthLabel; + PvlInput >> truthLabel; + + Cube outCube(cubeFileName); + Pvl *outLabel = outCube.label(); + + PvlGroup truthGroup = truthLabel.findGroup("Dimensions", Pvl::Traverse); + PvlGroup &outGroup = outLabel->findGroup("Dimensions", Pvl::Traverse); + EXPECT_PRED_FORMAT2(AssertPvlGroupEqual, outGroup, truthGroup); + + truthGroup = truthLabel.findGroup("Pixels", Pvl::Traverse); + outGroup = outLabel->findGroup("Pixels", Pvl::Traverse); + EXPECT_PRED_FORMAT2(AssertPvlGroupEqual, outGroup, truthGroup); + + truthGroup = truthLabel.findGroup("Instrument", Pvl::Traverse); + outGroup = outLabel->findGroup("Instrument", Pvl::Traverse); + EXPECT_PRED_FORMAT2(AssertPvlGroupEqual, outGroup, truthGroup); + + truthGroup = truthLabel.findGroup("BandBin", Pvl::Traverse); + outGroup = outLabel->findGroup("BandBin", Pvl::Traverse); + EXPECT_PRED_FORMAT2(AssertPvlGroupEqual, outGroup, truthGroup); + + truthGroup = truthLabel.findGroup("Kernels", Pvl::Traverse); + outGroup = outLabel->findGroup("Kernels", Pvl::Traverse); + EXPECT_PRED_FORMAT2(AssertPvlGroupEqual, outGroup, truthGroup); + +} \ No newline at end of file diff --git a/isis/tests/data/isisimport/chan2/ch2_tmc_nca_20191128T0035389755_b_brw_d18.xml b/isis/tests/data/isisimport/chan2/ch2_tmc_nca_20191128T0035389755_b_brw_d18.xml new file mode 100644 index 0000000000..f03cd63916 --- /dev/null +++ b/isis/tests/data/isisimport/chan2/ch2_tmc_nca_20191128T0035389755_b_brw_d18.xml @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><Product_Observational xmlns="http://pds.nasa.gov/pds4/pds/v1" xmlns:disp="http://pds.nasa.gov/pds4/disp/v1" xmlns:pds="http://pds.nasa.gov/pds4/pds/v1" xmlns:sp="http://pds.nasa.gov/pds4/sp/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pds.nasa.gov/pds4/pds/v1 http://pds.nasa.gov/pds4/pds/v1/PDS4_PDS_1B00.xsd http://pds.nasa.gov/pds4/disp/v1 http://pds.nasa.gov/pds4/disp/v1/PDS4_DISP_1301.xsd http://pds.nasa.gov/pds4/sp/v1 http://pds.nasa.gov/pds4/sp/v1/PDS4_SP_1100.xsd"> + <Identification_Area> + <logical_identifier>urn:isro:isda:ch2_cho.tmc:data_calibrated:ch2_tmc_nca_20191128t0035389755_b_brw_d18</logical_identifier> + <version_id>1.0</version_id> + <title>Chandrayaan-2 Orbiter TMC 2 Experiment</title> + <information_model_version>1.11.0.0</information_model_version> + <product_class>Product_Observational</product_class> + <Modification_History> + <Modification_Detail> + <modification_date>2019-05-07</modification_date> + <version_id>1.0</version_id> + <description>PDS4 product label created by SAC Optical DP Team</description> + </Modification_Detail> + </Modification_History> + </Identification_Area> + <Observation_Area> + <Time_Coordinates> + <start_date_time>2019-11-28T00:35:38.9755Z</start_date_time> + <stop_date_time>2019-11-28T00:45:17.9161Z</stop_date_time> + </Time_Coordinates> + <Primary_Result_Summary> + <purpose>Science</purpose> + <processing_level>Calibrated</processing_level> + </Primary_Result_Summary> + <Investigation_Area> + <name>Chandrayaan-2</name> + <type>Mission</type> + <Internal_Reference> + <lidvid_reference>urn:isro:isda:context:investigation:mission.chandrayaan2::1.0</lidvid_reference> + <reference_type>data_to_investigation</reference_type> + </Internal_Reference> + </Investigation_Area> + <Observing_System> + <Observing_System_Component> + <name>Chandrayaan 2 Orbiter</name> + <type>Spacecraft</type> + <description> + Chandrayaan-2 Orbiter is an Orbiter craft under the Chandrayaan-2 Spacecraft + consists of various scientific instruments. + </description> + </Observing_System_Component> + <Observing_System_Component> + <name>terrain mapping camera</name> + <type>Instrument</type> + <description> + TMC-2 (Terrain Mapping Camera) is one of the scientific instrument hosted + on the Chandrayaan-2 Orbiter. The instrument is passive electro-optical + imaging camera operating in visible-panchromatic band (500-800nm), + comprising three optical sensors Fore, Nadir and Aft placed with angles + of +25 deg, 0 deg and -25 deg to have three stereo views of the same target + as spacecraft moves along the track. + </description> + </Observing_System_Component> + </Observing_System> + <Target_Identification> + <name>Moon</name> + <type>Satellite</type> + <description>Moon is a natural satellite of Earth</description> + </Target_Identification> + </Observation_Area> + <File_Area_Observational> + <File> + <file_name>ch2_tmc_nca_20191128T0035389755_b_brw_d18.png</file_name> + <creation_date_time>2022-08-31T15:12:42</creation_date_time> + <file_size unit="byte">4068283</file_size> + <md5_checksum>43778d970f10bfcf651cc35ef2e11bbd</md5_checksum> + <comment> + This File contains the count calibrated sub sampled browse image + md5_checksum is provided for ensuring data integrity when users are downloading the data. + </comment> + </File> + <Array_2D_Image> + <offset unit="byte">0</offset> + <axes>2</axes> + <axis_index_order>Last Index Fastest</axis_index_order> + <Element_Array> + <data_type>UnsignedByte</data_type> + </Element_Array> + <Axis_Array> + <axis_name>Line</axis_name> + <elements>17891</elements> + <sequence_number>1</sequence_number> + </Axis_Array> + <Axis_Array> + <axis_name>Sample</axis_name> + <elements>400</elements> + <sequence_number>2</sequence_number> + </Axis_Array> + </Array_2D_Image> + </File_Area_Observational> +</Product_Observational> \ No newline at end of file -- GitLab