From 8791a7aae627de8acbe3a41b1f97ddec3e723f35 Mon Sep 17 00:00:00 2001 From: Austin Sanders Date: Thu, 9 Sep 2021 14:39:36 -0700 Subject: [PATCH 1/4] Updated translation files to support PSA compliant labels --- .../TgoCassisExportedInstrument.trn | 1 + .../TgoCassisExportedInstrument_PSA.trn | 169 +++++++++++++++ .../tgocassis2isis/TgoCassisMapping_PSA.trn | 195 ++++++++++++++++++ 3 files changed, 365 insertions(+) create mode 100644 isis/src/tgo/apps/tgocassis2isis/TgoCassisExportedInstrument_PSA.trn create mode 100644 isis/src/tgo/apps/tgocassis2isis/TgoCassisMapping_PSA.trn diff --git a/isis/src/tgo/apps/tgocassis2isis/TgoCassisExportedInstrument.trn b/isis/src/tgo/apps/tgocassis2isis/TgoCassisExportedInstrument.trn index efd56e1d96..cd1990fa9f 100644 --- a/isis/src/tgo/apps/tgocassis2isis/TgoCassisExportedInstrument.trn +++ b/isis/src/tgo/apps/tgocassis2isis/TgoCassisExportedInstrument.trn @@ -101,6 +101,7 @@ End_Group Group = ExposureDuration Auto + Optional InputPosition = (Observation_Area, Discipline_Area, img:Imaging, img:Imaging_Instrument_Parameters) InputKey = img:exposure_duration OutputName = ExposureDuration diff --git a/isis/src/tgo/apps/tgocassis2isis/TgoCassisExportedInstrument_PSA.trn b/isis/src/tgo/apps/tgocassis2isis/TgoCassisExportedInstrument_PSA.trn new file mode 100644 index 0000000000..867325b5f2 --- /dev/null +++ b/isis/src/tgo/apps/tgocassis2isis/TgoCassisExportedInstrument_PSA.trn @@ -0,0 +1,169 @@ +# Translates CaSSIS xml labels into the Instrument PvlGroup values +# for the ingested ISIS cube labels. +# +# The Dependencies keyword specifies a tag or attribute at the same level as +# the InputKey that uniquely identifies the InputKey. +# +# Consider the following translation group and xml +# +# Group = Samples +# Auto +# InputPosition = (Array_2D_Image, Axis_Array) +# Dependencies = "tag@axis_name|Sample" +# InputKey = elements +# OutputName = Samples +# OutputPosition = (Group, Dimensions) +# Translation = (*, *) +# End_Group +# +# +# +# Line +# 1 +# 2048 +# +# +# Sample +# 2 +# 279 +# +# +# +# There are two Axis_Array tags below Array_2D_Image and both of them have an +# elements tag. So, the Dependencies keyword specifies to take the value of +# the elements tag under the second Axis_Array array tag because it also has a +# axis_name tag with a value of Sample. +# +# +# This translation table is for translating CaSSIS xml labels into pvl cube +# labels. +# +# See $ISISROOT/appdata/translations/XmlExample.trn for an example xml translation table +# and documentation for the different options. +# +# history 2018-05-17 Kaitlyn Lee - Added ObservationId with a placeholder value for now. + +Group = SpacecraftName + Auto + InputPosition = (Observation_Area, Observing_System, Observing_System_Component) + InputKeyDependencies = "tag@type|Host" + InputKey = name + OutputName = SpacecraftName + OutputPosition = (Object,IsisCube,Group,Instrument) + Translation = (*, *) +End_Group + + + +Group = InstrumentId + Auto + InputPosition = (Observation_Area, Observing_System, Observing_System_Component) + InputKeyDependencies = "tag@type|Instrument" + InputKey = name + OutputName = InstrumentId + OutputPosition = (Object,IsisCube,Group,Instrument) + Translation = (*, *) +End_Group + +Group = Expanded + Auto + InputDefault = 1 + InputPosition = (Observation_Area, Observing_System, Observing_System_Component) + InputKeyDependencies = "tag@type|Host" + InputKey = name + OutputName = Expanded + OutputPosition = (Object,IsisCube,Group,Instrument) + Translation = (1, *) +End_Group + +Group = ObservationId + Auto + InputPosition = (Identification_Area, Alias_List, Alias) + InputKey = alternate_id + OutputName = ObservationId + OutputPosition = (Object, IsisCube, Group, Archive) + Translation = (*, *) +End_Group + +Group = TargetName + Auto + InputPosition = (Observation_Area, Target_Identification) + InputKey = name + OutputName = TargetName + OutputPosition = (Object,IsisCube,Group,Instrument) + Translation = (*, *) +End_Group + +Group = StartTime + Auto + InputPosition = (Observation_Area, Time_Coordinates) + InputKey = start_date_time + OutputName = StartTime + OutputPosition = (Object,IsisCube,Group,Instrument) + Translation = (*, *) +End_Group + +Group = ExposureDuration + Auto + InputPosition = (Observation_Area, Mission_Area, em16_tgo_cas:Cassis_Data, em16_tgo_cas:PEHK_Derived_Data) + InputKey = em16_tgo_cas:exposure_time + OutputName = ExposureDuration + OutputPosition = (Object, IsisCube, Group, Instrument) + Translation = (*, *) +End_Group + +Group = Filter + Auto + InputPosition = (Observation_Area, Discipline_Area, img:Imaging, img:Optical_Filter) + InputKey = img:filter_name + OutputName = Filter + OutputPosition = (Object,IsisCube,Group,Instrument) + Translation = (*, *) +End_Group + +Group = FilterName + Auto + InputPosition = (Observation_Area, Discipline_Area, img:Imaging, img:Optical_Filter) + InputKey = img:filter_name + OutputName = Filter + OutputPosition = (Object,IsisCube,Group,BandBin) + Translation = (*, *) +End_Group + +Group = Center + Auto + InputPosition = (Observation_Area, Discipline_Area, img:Imaging, img:Optical_Filter) + InputKey = img:filter_name + OutputName = Center + OutputPosition = (Object, IsisCube, Group, BandBin) + Translation = (675, PAN) + Translation = (485, BLU) + Translation = (840, RED) + Translation = (985, NIR) + +End_Group + +Group = Width + Auto + InputPosition = (Observation_Area, Discipline_Area, img:Imaging, img:Optical_Filter) + InputKey = img:filter_name + OutputName = Width + OutputPosition = (Object, IsisCube, Group, BandBin) + Translation = (250, PAN) + Translation = (165, BLU) + Translation = (100, RED) + Translation = (220, NIR) + +End_Group + +Group = Expanded + Auto + Optional + InputPosition = (CaSSIS_Header, DERIVED_HEADER_DATA) + InputKey = Expanded + OutputName = Expanded + OutputPosition = (Object, IsisCube, Group, Instrument) + Translation = (*, *) +End_Group + +End diff --git a/isis/src/tgo/apps/tgocassis2isis/TgoCassisMapping_PSA.trn b/isis/src/tgo/apps/tgocassis2isis/TgoCassisMapping_PSA.trn new file mode 100644 index 0000000000..465eed0cf7 --- /dev/null +++ b/isis/src/tgo/apps/tgocassis2isis/TgoCassisMapping_PSA.trn @@ -0,0 +1,195 @@ +# Translates CaSSIS xml labels into the Mapping PvlGroup values +# for the ingested ISIS cube labels. +# +# The Dependencies keyword specifies a tag or attribute at the same level as +# the InputKey that uniquely identifies the InputKey. +# +# Consider the following translation group and xml +# +# Group = Samples +# Auto +# InputPosition = (Array_2D_Image, Axis_Array) +# Dependencies = "tag@axis_name|Sample" +# InputKey = elements +# OutputName = Samples +# OutputPosition = (Group, Dimensions) +# Translation = (*, *) +# End_Group +# +# +# +# Line +# 1 +# 2048 +# +# +# Sample +# 2 +# 279 +# +# +# +# +# history 2018-08-09 Jeannie Backer - Changed group name from MapProjection +# to ProjectionName. + +Group = ProjectionName + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Reference_Information, cart:Horizontal_Coordinate_System_Definition, cart:Planar, cart:Map_Projection) + InputKey = cart:map_projection_name + OutputName = ProjectionName + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +Group = CenterLongitude + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Reference_Information, cart:Horizontal_Coordinate_System_Definition, cart:Planar, cart:Map_Projection, cart:Equirectangular) + InputKey = cart:longitude_of_central_meridian + OutputName = CenterLongitude + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +Group = CenterLatitude + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Reference_Information, cart:Horizontal_Coordinate_System_Definition, cart:Planar, cart:Map_Projection, cart:Equirectangular) + InputKey = cart:latitude_of_projection_origin + OutputName = CenterLatitude + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +# input has different scales for x and y, but ISIS doesn't distinguish, so use x +Group = Scale + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Reference_Information, cart:Horizontal_Coordinate_System_Definition, cart:Planar, cart:Planar_Coordinate_Information, cart:Coordinate_Representation) + InputKey = cart:pixel_scale_x + OutputName = Scale + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +# input has different pixel resolutions for x and y, but ISIS doesn't distinguish, so use x +Group = PixelResolution + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Reference_Information, cart:Horizontal_Coordinate_System_Definition, cart:Planar, cart:Planar_Coordinate_Information, cart:Coordinate_Representation) + InputKey = cart:pixel_resolution_x + OutputName = PixelResolution + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +Group = MaximumLatitude + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Domain, cart:Bounding_Coordinates) + InputKey = cart:north_bounding_coordinate + OutputName = MaximumLatitude + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +Group = MinimumLatitude + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Domain, cart:Bounding_Coordinates) + InputKey = cart:south_bounding_coordinate + OutputName = MinimumLatitude + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +Group = MaximumLongitude + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Domain, cart:Bounding_Coordinates) + InputKey = cart:west_bounding_coordinate + OutputName = MaximumLongitude + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +Group = MinimumLongitude + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Domain, cart:Bounding_Coordinates) + InputKey = cart:east_bounding_coordinate + OutputName = MinimumLongitude + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +Group = UpperLeftCornerX + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Reference_Information, cart:Horizontal_Coordinate_System_Definition, cart:Planar, cart:Geo_Transformation) + InputKey = cart:upperleft_corner_x + OutputName = UpperLeftCornerX + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +Group = UpperLeftCornerY + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Reference_Information, cart:Horizontal_Coordinate_System_Definition, cart:Planar, cart:Geo_Transformation) + InputKey = cart:upperleft_corner_y + OutputName = UpperLeftCornerY + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +Group = EquatorialRadius + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Reference_Information, cart:Horizontal_Coordinate_System_Definition, cart:Geodetic_Model) + InputKey = cart:a_axis_radius + OutputName = EquatorialRadius + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +Group = PolarRadius + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Reference_Information, cart:Horizontal_Coordinate_System_Definition, cart:Geodetic_Model) + InputKey = cart:c_axis_radius + OutputName = PolarRadius + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +Group = LatitudeType + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Reference_Information, cart:Horizontal_Coordinate_System_Definition, cart:Geodetic_Model) + InputKey = cart:latitude_type + OutputName = LatitudeType + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (Planetocentric, planetocentric) + Translation = (*, *) +End_Group + +Group = LongitudeDirection + Auto + InputPosition = (Observation_Area, Discipline_Area, cart:Cartography, cart:Spatial_Reference_Information, cart:Horizontal_Coordinate_System_Definition, cart:Geodetic_Model) + InputKey = cart:longitude_direction + OutputName = LongitudeDirection + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (PositiveEast, "Positive East") + Translation = (PositiveWest, "Positive West") +End_Group + +Group = TargetName + Auto + InputPosition = (Observation_Area, Target_Identification) + InputKey = name + OutputName = TargetName + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +# Does not exist in xml label +Group = LongitudeDomain + Auto + InputDefault = 360 + InputPosition = (Nothing, Nothing) + InputKey = Nothing + OutputName = LongitudeDomain + OutputPosition = (Object,IsisCube,Group,Mapping) + Translation = (*, *) +End_Group + +End From 43c31e74201ec25230ce7f26fe8e6cc169ebae78 Mon Sep 17 00:00:00 2001 From: Austin Sanders Date: Thu, 9 Sep 2021 14:41:08 -0700 Subject: [PATCH 2/4] Added logic to support PSA labels --- .../apps/tgocassis2isis/tgocassis2isis.cpp | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/isis/src/tgo/apps/tgocassis2isis/tgocassis2isis.cpp b/isis/src/tgo/apps/tgocassis2isis/tgocassis2isis.cpp index e886a24efd..7059b992dd 100644 --- a/isis/src/tgo/apps/tgocassis2isis/tgocassis2isis.cpp +++ b/isis/src/tgo/apps/tgocassis2isis/tgocassis2isis.cpp @@ -56,8 +56,16 @@ namespace Isis { Cube *outputCube = importer.SetOutputCube(ui.GetFileName("TO"), att); QString transRawFile = "TgoCassisInstrument.trn"; - QString transExportFile = "TgoCassisExportedInstrument.trn"; - + QFile xmlFile(xmlFileName.expanded()); + QDomDocument xmlDoc; + xmlDoc.setContent(&xmlFile, true); + // If any instances of "Optical_Filter" exist, use PSA .trn file + QString transExportFile; + if (xmlDoc.elementsByTagName("Optical_Filter").size()){ + transExportFile = "TgoCassisExportedInstrument_PSA.trn"; + } else { + transExportFile = "TgoCassisExportedInstrument.trn"; + } // first assume lev1b image Pvl *outputLabel = outputCube->label(); QString target = ""; @@ -86,17 +94,17 @@ namespace Isis { if (!outputCube->group("Archive").hasKeyword("ObservationId")){ convertUniqueIdToObservationId(*outputLabel); } - + FileName outputCubeFileName(ui.GetFileName("TO")); - + OriginalXmlLabel xmlLabel; xmlLabel.readFromXmlFile(xmlFileName); - + importer.StartProcess(); - + // Write out original label before closing the cube outputCube->write(xmlLabel); - + importer.EndProcess(); } catch (IException &e) { @@ -189,8 +197,16 @@ namespace Isis { //Translate the Mapping Group try { QString missionDir = "$ISISROOT/appdata/translations/"; - FileName mapTransFile(missionDir + "TgoCassisMapping.trn"); - + QDomDocument xmlDoc; + QFile xmlFile(xmlFileName.expanded()); + xmlDoc.setContent(&xmlFile, true); + // If any instances of "Observing_System_Component" exist, use PSA .trn file + FileName mapTransFile; + if (xmlDoc.elementsByTagName("cart:a_axis_radius").size()){ + mapTransFile = FileName(missionDir + "TgoCassisMapping_PSA.trn"); + } else { + mapTransFile = FileName(missionDir + "TgoCassisMapping.trn"); + } // Get the translation manager ready for translating the mapping label XmlToPvlTranslationManager labelXMappinglater(xmlFileName, mapTransFile.expanded()); @@ -309,8 +325,9 @@ namespace Isis { PvlGroup &inst = outputLabel->findGroup("Instrument", Pvl::Traverse); // Add units of measurement to keywords from translation table - inst.findKeyword("ExposureDuration").setUnits("seconds"); - + if (inst.hasKeyword("ExposureDuration")){ + inst.findKeyword("ExposureDuration").setUnits("seconds"); + } // Translate BandBin group FileName bandBinTransFile(missionDir + "TgoCassisBandBin.trn"); XmlToPvlTranslationManager bandBinXlater(inputLabel, bandBinTransFile.expanded()); @@ -514,5 +531,3 @@ namespace Isis { } } - - From 8c58adefd3d82f7c22369d85130a051da980da35 Mon Sep 17 00:00:00 2001 From: Austin Sanders Date: Thu, 9 Sep 2021 14:42:01 -0700 Subject: [PATCH 3/4] Test data for PSA labels --- .../MY36_015782_024_0_PAN_cropped.dat | Bin 0 -> 6000 bytes .../MY36_015782_024_0_PAN_cropped.xml | 452 ++++++++++++++++++ 2 files changed, 452 insertions(+) create mode 100644 isis/tests/data/tgoCassis/tgocassis2isis/MY36_015782_024_0_PAN_cropped.dat create mode 100755 isis/tests/data/tgoCassis/tgocassis2isis/MY36_015782_024_0_PAN_cropped.xml diff --git a/isis/tests/data/tgoCassis/tgocassis2isis/MY36_015782_024_0_PAN_cropped.dat b/isis/tests/data/tgoCassis/tgocassis2isis/MY36_015782_024_0_PAN_cropped.dat new file mode 100644 index 0000000000000000000000000000000000000000..2e0a4be017141862c569ad6b05e4734e33fa33ce GIT binary patch literal 6000 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 WkBdzvk1k#V>UynylR3lt{Qm-;GSF%O literal 0 HcmV?d00001 diff --git a/isis/tests/data/tgoCassis/tgocassis2isis/MY36_015782_024_0_PAN_cropped.xml b/isis/tests/data/tgoCassis/tgocassis2isis/MY36_015782_024_0_PAN_cropped.xml new file mode 100755 index 0000000000..9ae0328bf4 --- /dev/null +++ b/isis/tests/data/tgoCassis/tgocassis2isis/MY36_015782_024_0_PAN_cropped.xml @@ -0,0 +1,452 @@ + + + + + + + + + + + urn:esa:psa:em16_tgo_cas:data_derived:my36_015782_024_0_pan + 1.0 + PDS4 product exported from ISIS3 cube. + 1.15.0.0 + Product_Observational + + + MY36_015782_024_0 + CaSSIS Internal Identifier + + + + + 2021-07-06 + 1.0 + Created PDS4 output product from ISIS cube with the tgocassisrdrgen application from ISIS version 4.4.0 . + + + + + + 2021-06-07T00:31:03.723Z + 2021-06-07T00:31:14.193Z + 10.180834712301 + 55.415973760255 + + + Science + Derived + Summary of Results + + Near Infrared + Surface + Imaging + + + + ExoMars 2016 + Mission + + urn:esa:psa:context:investigation:mission.em16 + data_to_investigation + This is the PDS4 logical identifier for the ExoMars Trace Gas Orbiter mission. + + + + + TRACE GAS ORBITER + Host + Instrument Host + + urn:esa:psa:context:instrument_host:spacecraft.tgo + is_instrument_host + + + + CaSSIS + Instrument + Colour and Stereo Surface Imaging System + (CaSSIS) on the Exomars Trace Gas Orbiter which is a + push-frame cmos visible reflecting telescope + + urn:esa:psa:context:instrument:tgo.cassis + is_instrument + + + + + Mars + Planet + Planet Mars + + urn:nasa:pds:context:target:planet.mars + data_to_target + + + + + Science Phase + psp + 015782 + + + SCI + CASSIS Science + Imager + + + No pointing + No pointing + 837628000 + + + Geometry_Pipeline + 1.0.1 + + + Radiometric Pipeline + v1.01 + + + Header_Creation: c_new_header + V3.2 (16-Feb-2017) + + + SC TM Conversion: c_sc_file_resolution + V1.5 (22-Mar-2018) + + + Mechanism HK validity flag set: c_rot_mechanism_validity + V1.0 (02-May-2019) + + + SC TM Conversion: c_batch_sc_tm_packets + V1.40 (03-Dec-2019) + + + Bias Subtraction (bias_short_190313.dat): c_remove_bias + V1.13 (13-Mar-2019) + + + Flat field removal (flat_field_190313.dat): c_remove_flat + V1.14 (13-Mar-2019) + + + Bad pixel removal ( 9 pixels replaced): c_remove_badpix + V1.01 (03-Apr-2019) + + + Expansion: c_expand + V1.1 + + + Absolute_Calibration: c_absolute_calibration + V1.1 + + + SC TM Conversion: c_top_batch_level0tolevel1a + V1.16 (10-Jul-2020) + + + Command_Verification: c_top_batch_level1atolevel1 + V1.11 + + + Photometric_correction: c_correct_straylight_level1 + V2.05 + + + + 1.143e-005 + rad/px + BLU RED NIR PAN + + + 250.009 + JPEG-LS + 3.109 + 3.014 + + 0.00 + + 4.26194e-005 + #/DN + + + 0 + 0 + 0 + 0 + 0 + 0 + 1.018e-003 + 4 + 2735 + K*10 + 2732 + K*10 + 2626 + K*10 + 2047 + 633 + 0 + 354 + 1535 + 967 + 512 + 712 + 1727 + 1303 + 320 + 1048 + 1727 + 1664 + 320 + 1409 + 63 + -1 + 0 + 0 + 63 + -1 + 0 + 0 + + + 0.8749 + M + 6.48 + Three-mirror anastigmat with powered fold mirror + + + Three-mirror anastigmat with powered fold mirror + 10.0 + MICRON + 10.0 + MICRON + SI CMOS HYBRID (OSPREY 2K) + 61.0 + ELECTRON + + + 3.873 + 9.250 + 2.9401 + 1.5929 + 367.0 + 257.091527 + deg (East Planetocentric) + 22.312523 + deg (Planetocentric) + 0.8804 + 0.9815 + 2.6279 + 0.8653 + 0.9309 + 2.6472 + 55.416 + -64.568 + 237.059 + 24.325 + 409.235 + ASCENDING + -68.514 + 278.279 + true + + + 30 + + + 164 + M041 + + + + + + + Image_Array_Object + display_settings_to_array + + + Sample + Left to Right + Line + Top to Bottom + + + + + Image_Array_Object + imaging_parameters_to_image_object + + + PAN + PAN + 231.5 + 677.4 + + + + + Image_Array_Object + cartography_parameters_to_image_object + + + + 257.01272950127 + 257.31376427531 + 22.889184664064 + 22.253261430151 + + + + + + + Equirectangular + + 0.0 + 20.0 + 180.0 + + + + Coordinate Pair + + 4.0 + 4.0 + 14808.391167037 + 14808.391167037 + + + + 4286632.0 + 1355808.0 + + + + Planetocentric + 3393833.261 + 3393833.261 + 3393833.261 + Positive East + Body-fixed Non-rotating + + + + + + + + em16_cassis.tm + + + + + Sample + Left to Right + Line + Top to Bottom + + + 270.0 + 0.0 + + J2000 + + + + + 2021-06-07T00:31:03.723Z + + + 3796.5 + 2.2909610 + 1.6595426 + 409.235 + + + + + + + Upper Left Corner + 22.287994812409 + 257.18736665772 + + + Upper Right Corner + 22.253269143531 + 257.01774681231 + + + Lower Right Corner + 22.780084761799 + 257.13840206251 + + + Lower Left Corner + 22.814756212254 + 257.30905532131 + + + 359.37934400953 + + + + + Center + 25.428425703542 + 8.0711133108878 + 25.375868707623 + + + + + + + + + urn:esa:psa:em16_tgo_cas:data_calibrated:cas_cal_sc_20210607t003104-20210607t003118-pan-837628000-sti + data_to_calibrated_product + + + + + MY36_015782_024_0_PAN_cropped.dat + + + Image_Array_Object + 0 + 2 + Last Index Fastest + Pixel values are in units of I/F (intensity/flux). I/F is defined asthe ratio of the observed radiance and the radiance of a 100% lambertian reflector with the sun and camera orthogonal to the observing surface. + + IEEE754LSBSingle + 1.0 + 0.0 + + + Sample + 500 + 1 + + + Line + 3 + 2 + + + -3.40282265508890445e+38 + -3.40282326356119256e+38 + -3.4028234663852886e+38 + -3.40282306073709653e+38 + -3.40282285791300049e+38 + + + + + From 5c6627caf77cd53aec9a6b0a96a4a0b1a4cd33e2 Mon Sep 17 00:00:00 2001 From: Austin Sanders Date: Thu, 9 Sep 2021 14:42:16 -0700 Subject: [PATCH 4/4] Added a test for PSA labels --- isis/tests/FunctionalTestsTgocassis2isis.cpp | 120 ++++++++++++++----- 1 file changed, 89 insertions(+), 31 deletions(-) diff --git a/isis/tests/FunctionalTestsTgocassis2isis.cpp b/isis/tests/FunctionalTestsTgocassis2isis.cpp index 450b6ce191..e20a678d07 100644 --- a/isis/tests/FunctionalTestsTgocassis2isis.cpp +++ b/isis/tests/FunctionalTestsTgocassis2isis.cpp @@ -17,10 +17,10 @@ static QString APP_XML = FileName("$ISISROOT/bin/xml/tgocassis2isis.xml").expand TEST(TgoCassis2Isis, TgoCassis2IsisTestBlu) { QTemporaryDir prefix; QString cubeFileName = prefix.path() + "/blu_out.cub"; - QVector args = {"from=data/tgoCassis/CAS-MCO-2016-11-26T22.50.27.381-BLU-03005-B1.xml", + QVector args = {"from=data/tgoCassis/CAS-MCO-2016-11-26T22.50.27.381-BLU-03005-B1.xml", "to=" + cubeFileName }; UserInterface options(APP_XML, args); - + try { tgocassis2isis(options); } @@ -45,12 +45,12 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestBlu) { EXPECT_EQ(inst["ExposureDuration"][0].toStdString(), "1.440e-003"); EXPECT_EQ(int(inst["SummingMode"]), 0); EXPECT_EQ(inst["Filter"][0].toStdString(), "BLU"); - + // Archive Group PvlGroup &archive = isisLabel->findGroup("Archive", Pvl::Traverse); EXPECT_EQ(archive["DataSetId"][0].toStdString(), "TBD"); EXPECT_EQ(archive["ProductVersionId"][0].toStdString(), "UNK"); - EXPECT_EQ(archive["ProductCreationTime"][0].toStdString(), "2017-10-03T10:50:12"); + EXPECT_EQ(archive["ProductCreationTime"][0].toStdString(), "2017-10-03T10:50:12"); EXPECT_DOUBLE_EQ(double(archive["ScalingFactor"]), 1.0); EXPECT_DOUBLE_EQ(double(archive["Offset"]), 0.0); EXPECT_DOUBLE_EQ(double(archive["PredictMaximumExposureTime"]), 1.5952); @@ -67,12 +67,12 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestBlu) { EXPECT_EQ(int(archive["ImageFrequency"]), 400000); EXPECT_EQ(int(archive["NumberOfWindows"]), 6); EXPECT_EQ(int(archive["UniqueIdentifier"]), 100799268); - EXPECT_EQ(archive["ExposureTimestamp"][0].toStdString(), "2f015435767e275a"); + EXPECT_EQ(archive["ExposureTimestamp"][0].toStdString(), "2f015435767e275a"); EXPECT_DOUBLE_EQ(double(archive["ExposureTimePEHK"]), 1.440e-003); EXPECT_DOUBLE_EQ(double(archive["PixelsPossiblySaturated"]), 0.00); EXPECT_EQ(int(archive["WindowCount"]), 3); EXPECT_EQ(int(archive["Window1Binning"]), 0); - EXPECT_EQ(int(archive["Window1StartSample"]), 0); + EXPECT_EQ(int(archive["Window1StartSample"]), 0); EXPECT_EQ(int(archive["Window1EndSample"]), 2047); EXPECT_EQ(int(archive["Window1StartLine"]), 354); EXPECT_EQ(int(archive["Window1EndLine"]), 632); @@ -85,7 +85,7 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestBlu) { EXPECT_EQ(int(archive["Window3StartSample"]), 0); EXPECT_EQ(int(archive["Window3EndSample"]), 2047); EXPECT_EQ(int(archive["Window3StartLine"]), 1048); - EXPECT_EQ(int(archive["Window3EndLine"]), 1302); + EXPECT_EQ(int(archive["Window3EndLine"]), 1302); EXPECT_EQ(int(archive["Window4Binning"]), 0); EXPECT_EQ(int(archive["Window4StartSample"]), 1024); EXPECT_EQ(int(archive["Window4EndSample"]), 1087); @@ -126,10 +126,10 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestBlu) { TEST(TgoCassis2Isis, TgoCassis2IsisTestRed) { QTemporaryDir prefix; QString cubeFileName = prefix.path() + "/red_out.cub"; - QVector args = {"from=data/tgoCassis/CAS-MCO-2016-11-26T22.50.27.381-RED-01005-B1.xml", + QVector args = {"from=data/tgoCassis/CAS-MCO-2016-11-26T22.50.27.381-RED-01005-B1.xml", "to=" + cubeFileName }; UserInterface options(APP_XML, args); - + try { tgocassis2isis(options); } @@ -154,7 +154,7 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestRed) { EXPECT_EQ(inst["ExposureDuration"][0].toStdString(), "1.440e-003"); EXPECT_EQ(int(inst["SummingMode"]), 0); EXPECT_EQ(inst["Filter"][0].toStdString(), "RED"); - + // Archive Group PvlGroup &archive = isisLabel->findGroup("Archive", Pvl::Traverse); EXPECT_DOUBLE_EQ(double(archive["ScalingFactor"]), 1.0); @@ -173,7 +173,7 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestRed) { EXPECT_EQ(int(archive["ImageFrequency"]), 400000); EXPECT_EQ(int(archive["NumberOfWindows"]), 6); EXPECT_EQ(int(archive["UniqueIdentifier"]), 100799268); - EXPECT_EQ(archive["ExposureTimestamp"][0].toStdString(), "2f015435767e275a"); + EXPECT_EQ(archive["ExposureTimestamp"][0].toStdString(), "2f015435767e275a"); EXPECT_DOUBLE_EQ(double(archive["ExposureTimePEHK"]), 1.440e-003); EXPECT_DOUBLE_EQ(double(archive["PixelsPossiblySaturated"]), 0.16); EXPECT_EQ(archive["ObservationId"][0].toStdString(), "CRUS_049218_201_0"); @@ -200,10 +200,10 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestRed) { TEST(TgoCassis2Isis, TgoCassis2IsisTestNir) { QTemporaryDir prefix; QString cubeFileName = prefix.path() + "/nir_out.cub"; - QVector args = {"from=data/tgoCassis/CAS-MCO-2016-11-26T22.50.27.381-NIR-02005-B1.xml", + QVector args = {"from=data/tgoCassis/CAS-MCO-2016-11-26T22.50.27.381-NIR-02005-B1.xml", "to=" + cubeFileName }; UserInterface options(APP_XML, args); - + try { tgocassis2isis(options); } @@ -228,7 +228,7 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestNir) { EXPECT_EQ(inst["ExposureDuration"][0].toStdString(), "1.440e-003"); EXPECT_EQ(int(inst["SummingMode"]), 0); EXPECT_EQ(inst["Filter"][0].toStdString(), "NIR"); - + // Archive Group PvlGroup &archive = isisLabel->findGroup("Archive", Pvl::Traverse); EXPECT_DOUBLE_EQ(double(archive["ScalingFactor"]), 1.0); @@ -247,7 +247,7 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestNir) { EXPECT_EQ(int(archive["ImageFrequency"]), 400000); EXPECT_EQ(int(archive["NumberOfWindows"]), 6); EXPECT_EQ(int(archive["UniqueIdentifier"]), 100799268); - EXPECT_EQ(archive["ExposureTimestamp"][0].toStdString(), "2f015435767e275a"); + EXPECT_EQ(archive["ExposureTimestamp"][0].toStdString(), "2f015435767e275a"); EXPECT_DOUBLE_EQ(double(archive["ExposureTimePEHK"]), 1.440e-003); EXPECT_DOUBLE_EQ(double(archive["PixelsPossiblySaturated"]), 0.00); EXPECT_EQ(archive["ObservationId"][0].toStdString(), "CRUS_049218_201_0"); @@ -274,10 +274,10 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestNir) { TEST(TgoCassis2Isis, TgoCassis2IsisTestPan) { QTemporaryDir prefix; QString cubeFileName = prefix.path() + "/pan_out.cub"; - QVector args = {"from=data/tgoCassis/CAS-MCO-2016-11-26T22.50.27.381-PAN-00005-B1.xml", + QVector args = {"from=data/tgoCassis/CAS-MCO-2016-11-26T22.50.27.381-PAN-00005-B1.xml", "to=" + cubeFileName }; UserInterface options(APP_XML, args); - + try { tgocassis2isis(options); } @@ -302,7 +302,7 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestPan) { EXPECT_EQ(inst["ExposureDuration"][0].toStdString(), "1.440e-003"); EXPECT_EQ(int(inst["SummingMode"]), 0); EXPECT_EQ(inst["Filter"][0].toStdString(), "PAN"); - + // Archive Group PvlGroup &archive = isisLabel->findGroup("Archive", Pvl::Traverse); EXPECT_DOUBLE_EQ(double(archive["ScalingFactor"]), 1.0); @@ -321,7 +321,7 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestPan) { EXPECT_EQ(int(archive["ImageFrequency"]), 400000); EXPECT_EQ(int(archive["NumberOfWindows"]), 6); EXPECT_EQ(int(archive["UniqueIdentifier"]), 100799268); - EXPECT_EQ(archive["ExposureTimestamp"][0].toStdString(), "2f015435767e275a"); + EXPECT_EQ(archive["ExposureTimestamp"][0].toStdString(), "2f015435767e275a"); EXPECT_DOUBLE_EQ(double(archive["ExposureTimePEHK"]), 1.440e-003); EXPECT_DOUBLE_EQ(double(archive["PixelsPossiblySaturated"]), 29.17); EXPECT_EQ(archive["ObservationId"][0].toStdString(), "CRUS_049218_201_0"); @@ -348,10 +348,10 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestPan) { TEST(TgoCassis2Isis, TgoCassis2IsisTestInstrumentError) { QTemporaryDir prefix; QString cubeFileName = prefix.path() + "/error.cub"; - QVector args = {"from=data/tgoCassis/tgocassis2isis/CAS-MCO-2016-11-26T22.35.51.907-RED-01033-B1-InstrumentError.xml", + QVector args = {"from=data/tgoCassis/tgocassis2isis/CAS-MCO-2016-11-26T22.35.51.907-RED-01033-B1-InstrumentError.xml", "to=" + cubeFileName }; UserInterface options(APP_XML, args); - + try { tgocassis2isis(options); FAIL() << "Should throw an exception" << std::endl; @@ -364,10 +364,10 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestInstrumentError) { TEST(TgoCassis2Isis, TgoCassis2IsisTestSpacecraftError) { QTemporaryDir prefix; QString cubeFileName = prefix.path() + "/error.cub"; - QVector args = {"from=data/tgoCassis/tgocassis2isis/CAS-MCO-2016-11-26T22.35.51.907-RED-01033-B1-SpacecraftError.xml", + QVector args = {"from=data/tgoCassis/tgocassis2isis/CAS-MCO-2016-11-26T22.35.51.907-RED-01033-B1-SpacecraftError.xml", "to=" + cubeFileName }; UserInterface options(APP_XML, args); - + try { tgocassis2isis(options); FAIL() << "Should throw an exception" << std::endl; @@ -380,10 +380,10 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestSpacecraftError) { TEST(TgoCassis2Isis, TgoCassis2IsisTestFilterError) { QTemporaryDir prefix; QString cubeFileName = prefix.path() + "/error.cub"; - QVector args = {"from=data/tgoCassis/tgocassis2isis/CAS-MCO-2016-11-20T15.30.00.349-DMP-00000-00.xml", + QVector args = {"from=data/tgoCassis/tgocassis2isis/CAS-MCO-2016-11-20T15.30.00.349-DMP-00000-00.xml", "to=" + cubeFileName }; UserInterface options(APP_XML, args); - + try { tgocassis2isis(options); FAIL() << "Should throw an exception" << std::endl; @@ -396,10 +396,10 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestFilterError) { TEST(TgoCassis2Isis, TgoCassis2IsisTestReingestedUnproj) { QTemporaryDir prefix; QString cubeFileName = prefix.path() + "/reingested_unproj.cub"; - QVector args = {"from=data/tgoCassis/tgocassis2isis/CAS-MCO-2016-11-26T22.50.30.181-RED-01012-B1_rdrgen.xml", + QVector args = {"from=data/tgoCassis/tgocassis2isis/CAS-MCO-2016-11-26T22.50.30.181-RED-01012-B1_rdrgen.xml", "to=" + cubeFileName }; UserInterface options(APP_XML, args); - + try { tgocassis2isis(options); } @@ -423,7 +423,7 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestReingestedUnproj) { EXPECT_EQ(inst["ExposureDuration"][0].toStdString(), "1.488e-003"); EXPECT_EQ(int(inst["SummingMode"]), 0); EXPECT_EQ(inst["Filter"][0].toStdString(), "RED"); - + // Archive Group PvlGroup &archive = isisLabel->findGroup("Archive", Pvl::Traverse); EXPECT_EQ(archive["ObservationId"][0].toStdString(), "MY34_002002_211_2"); @@ -453,10 +453,10 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestReingestedUnproj) { TEST(TgoCassis2Isis, TgoCassis2IsisTestReingestedProj) { QTemporaryDir prefix; QString cubeFileName = prefix.path() + "/reingested_unproj.cub"; - QVector args = {"from=data/tgoCassis/tgocassis2isis/CAS-MCO-2016-11-26T22.50.30.181-RED-01012-B1_proj_rdrgen.xml", + QVector args = {"from=data/tgoCassis/tgocassis2isis/CAS-MCO-2016-11-26T22.50.30.181-RED-01012-B1_proj_rdrgen.xml", "to=" + cubeFileName }; UserInterface options(APP_XML, args); - + try { tgocassis2isis(options); } @@ -480,7 +480,7 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestReingestedProj) { EXPECT_EQ(inst["ExposureDuration"][0].toStdString(), "1.488e-003"); EXPECT_EQ(int(inst["SummingMode"]), 0); EXPECT_EQ(inst["Filter"][0].toStdString(), "RED"); - + // Archive Group PvlGroup &archive = isisLabel->findGroup("Archive", Pvl::Traverse); EXPECT_EQ(archive["ObservationId"][0].toStdString(), "MY34_002002_211_2"); @@ -506,3 +506,61 @@ TEST(TgoCassis2Isis, TgoCassis2IsisTestReingestedProj) { EXPECT_EQ(hist->ValidPixels(), 226); EXPECT_NEAR(hist->StandardDeviation(), 0.0031668801306310155, 0.0001); } + + +TEST(TgoCassis2Isis, TgoCassis2IsisTestPSALabel) { + QTemporaryDir prefix; + QString cubeFileName = prefix.path() + "/psa.cub"; + QVector args = {"from=data/tgoCassis/tgocassis2isis/MY36_015782_024_0_PAN_cropped.xml", + "to=" + cubeFileName }; + UserInterface options(APP_XML, args); + + try { + tgocassis2isis(options); + } + catch (IException &e) { + FAIL() << "Unable to ingest image: " << e.toString().toStdString().c_str() << std::endl; + } + Cube cube(cubeFileName); + Pvl *isisLabel = cube.label(); + + // Dimensions Group + EXPECT_EQ(cube.sampleCount(), 500); + EXPECT_EQ(cube.lineCount(), 3); + EXPECT_EQ(cube.bandCount(), 1); + + // Instrument Group + PvlGroup &inst = isisLabel->findGroup("Instrument", Pvl::Traverse); + EXPECT_EQ(inst["SpacecraftName"][0].toStdString(), "TRACE GAS ORBITER"); + EXPECT_EQ(inst["InstrumentId"][0].toStdString(), "CaSSIS"); + EXPECT_EQ(inst["TargetName"][0].toStdString(), "Mars" ); + EXPECT_EQ(inst["StartTime"][0].toStdString(), "2021-06-07T00:31:03.723"); + EXPECT_EQ(inst["ExposureDuration"][0].toStdString(), "1.018e-003"); + EXPECT_EQ(int(inst["SummingMode"]), 0); + EXPECT_EQ(inst["Filter"][0].toStdString(), "PAN"); + + // Archive Group + PvlGroup &archive = isisLabel->findGroup("Archive", Pvl::Traverse); + EXPECT_EQ(archive["ObservationId"][0].toStdString(), "MY36_015782_024_0"); + EXPECT_EQ(archive["ProductVersionId"][0].toStdString(), "1.0"); + EXPECT_EQ(archive["ScalingFactor"][0].toStdString(), "1.0"); + EXPECT_EQ(archive["YearDoy"][0].toStdString(), "2021158"); + + // BandBin Group + PvlGroup &bandbin = isisLabel->findGroup("BandBin", Pvl::Traverse); + EXPECT_EQ(bandbin["FilterName"][0].toStdString(), "PAN"); + EXPECT_DOUBLE_EQ(double(bandbin["Center"]), 675); + EXPECT_DOUBLE_EQ(double(bandbin["Width"]), 250); + EXPECT_EQ(bandbin["NaifIkCode"][0].toStdString(), "-143421"); + + // Kernels Group + PvlGroup &kernels = isisLabel->findGroup("Kernels", Pvl::Traverse); + EXPECT_EQ(int(kernels["NaifFrameCode"]), -143400); + + Histogram *hist = cube.histogram(); + + EXPECT_NEAR(hist->Average(), 0.2833722, 0.0000001); + EXPECT_DOUBLE_EQ(hist->Sum(), 326.72824501991272); + EXPECT_EQ(hist->ValidPixels(), 1153); + EXPECT_NEAR(hist->StandardDeviation(), 0.001798, 0.000001); +}