diff --git a/isis/appdata/import/PDS4/Chandrayaan2TMC2.tpl b/isis/appdata/import/PDS4/Chandrayaan2TMC2.tpl index 6457333d8a..b183ebdf63 100644 --- a/isis/appdata/import/PDS4/Chandrayaan2TMC2.tpl +++ b/isis/appdata/import/PDS4/Chandrayaan2TMC2.tpl @@ -101,8 +101,8 @@ Object = IsisCube SunAzimuth = {{ Product_Observational.Observation_Area.Mission_Area.isda_Product_Parameters.isda_sun_azimuth._text }} SunElevation = {{ Product_Observational.Observation_Area.Mission_Area.isda_Product_Parameters.isda_sun_elevation._text }} SolarIncidence = {{ Product_Observational.Observation_Area.Mission_Area.isda_Product_Parameters.isda_solar_incidence._text }} - Projection = {{ Product_Observational.Observation_Area.Mission_Area.isda_Product_Parameters.isda_projection }} - Area = {{ Product_Observational.Observation_Area.Mission_Area.isda_Product_Parameters.isda_area }} + Projection = "{{ Product_Observational.Observation_Area.Mission_Area.isda_Product_Parameters.isda_projection }}" + Area = "{{ Product_Observational.Observation_Area.Mission_Area.isda_Product_Parameters.isda_area }}" End_Group {% endif %} diff --git a/isis/appdata/translations/MissionName2DataDir.trn b/isis/appdata/translations/MissionName2DataDir.trn index f75aa2ea2d..5cd32e9053 100644 --- a/isis/appdata/translations/MissionName2DataDir.trn +++ b/isis/appdata/translations/MissionName2DataDir.trn @@ -42,6 +42,7 @@ Group = MissionName Translation = (Chandrayaan1, "CHANDRAYAAN-1 ORBITER") Translation = (Chandrayaan1, CHANDRAYAAN1_ORBITER) Translation = (Chandrayaan1, CHANDRAYAAN-1) + Translation = (Chandrayaan2, Chandrayaan-2) Translation = (Clementine1, CLEMENTINE_1) Translation = (Clementine1, "CLEMENTINE 1") Translation = (Clipper, "CLIPPER") diff --git a/isis/src/base/objs/SpiceRotation/SpiceRotation.cpp b/isis/src/base/objs/SpiceRotation/SpiceRotation.cpp index c4af96fdb7..cb49356f9d 100644 --- a/isis/src/base/objs/SpiceRotation/SpiceRotation.cpp +++ b/isis/src/base/objs/SpiceRotation/SpiceRotation.cpp @@ -2486,10 +2486,9 @@ namespace Isis { "Full cache size does NOT match cache size in LoadTimeCache -- should never happen"; throw IException(IException::Programmer, msg, _FILEINFO_); } - - SpiceDouble timeSclkdp[p_fullCacheSize]; - SpiceDouble quats[p_fullCacheSize][4]; - double avvs[p_fullCacheSize][3]; // Angular velocity vector + std::vector timeSclkdp(p_fullCacheSize); + std::vector quats(p_fullCacheSize * 4); + std::vector avvs(p_fullCacheSize * 3); // We will treat et as the sclock time and avoid converting back and forth std::vector fullRotationCache = m_orientation->getRotations(); @@ -2501,14 +2500,14 @@ namespace Isis { rotationMatrix[3], rotationMatrix[4], rotationMatrix[5], rotationMatrix[6], rotationMatrix[7], rotationMatrix[8] }; - m2q_c(CJ, quats[r]); + m2q_c(CJ, &quats[r * 4]); if (p_hasAngularVelocity) { ale::Vec3d angularVelocity = angularVelocities[r]; - vequ_c((SpiceDouble *) &angularVelocity.x, avvs[r]); + vequ_c((SpiceDouble *) &angularVelocity.x, &avvs[r*3]); } } - double cubeStarts = timeSclkdp[0]; //,timsSclkdp[ckBlob.Records()-1] }; + double cubeStarts = timeSclkdp[0]; //,timsSclkdp[ckBlob.Records()-1] ; double radTol = 0.000000017453; //.000001 degrees Make this instrument dependent TODO SpiceInt avflag = 1; // Don't use angular velocity for now SpiceInt nints = 1; // Always make an observation a single interpolation interval @@ -2516,8 +2515,8 @@ namespace Isis { SpiceInt intarr[p_fullCacheSize]; // Integer work array SpiceInt sizOut = p_fullCacheSize; // Size of downsized cache - ck3sdn(radTol, avflag, (int *) &sizOut, timeSclkdp, (doublereal *) quats, - (SpiceDouble *) avvs, nints, &cubeStarts, dparr, (int *) intarr); + ck3sdn(radTol, avflag, (int *) &sizOut, &timeSclkdp[0], (doublereal *) &quats[0], + (SpiceDouble *) &avvs[0], nints, &cubeStarts, dparr, (int *) intarr); // Clear full cache and load with downsized version p_cacheTime.clear(); @@ -2538,9 +2537,9 @@ namespace Isis { et = timeSclkdp[r]; p_cacheTime.push_back(et); std::vector CJ(9); - q2m_c(quats[r], (SpiceDouble( *)[3]) &CJ[0]); + q2m_c(&quats[r*4], (SpiceDouble(*)[3]) &CJ[0]); rotationCache.push_back(CJ); - vequ_c(avvs[r], (SpiceDouble *) &av[0]); + vequ_c(&avvs[r*3], (SpiceDouble *) &av[0]); avCache.push_back(av); } diff --git a/isis/src/base/objs/SpiceRotation/SpiceRotation.h b/isis/src/base/objs/SpiceRotation/SpiceRotation.h index 3d47858b83..e1319253a8 100644 --- a/isis/src/base/objs/SpiceRotation/SpiceRotation.h +++ b/isis/src/base/objs/SpiceRotation/SpiceRotation.h @@ -427,7 +427,7 @@ namespace Isis { int p_axis1; //!< Axis of rotation for angle 1 of rotation int p_axis2; //!< Axis of rotation for angle 2 of rotation int p_axis3; //!< Axis of rotation for angle 3 of rotation - ale::Orientations *m_orientation; //! Cached orientation information + ale::Orientations *m_orientation = nullptr; //! Cached orientation information private: // method diff --git a/isis/src/chandrayaan2/Makefile b/isis/src/chandrayaan2/Makefile new file mode 100644 index 0000000000..94a4a5fab5 --- /dev/null +++ b/isis/src/chandrayaan2/Makefile @@ -0,0 +1 @@ +include $(ISISROOT)/make/isismake.cat \ No newline at end of file diff --git a/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Camera.plugin b/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Camera.plugin new file mode 100644 index 0000000000..f3d16f2052 --- /dev/null +++ b/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Camera.plugin @@ -0,0 +1,6 @@ +Group = CHANDRAYAAN-2/TMC-2 + Version = 1 + Library = Chandrayaan2TmcCamera + Routine = Chandrayaan2TmcCameraPlugin +EndGroup + diff --git a/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Chandrayaan2TmcCamera.cpp b/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Chandrayaan2TmcCamera.cpp new file mode 100644 index 0000000000..7855b5b031 --- /dev/null +++ b/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Chandrayaan2TmcCamera.cpp @@ -0,0 +1,119 @@ +/** 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 "Chandrayaan2TmcCamera.h" + +#include + +#include "Affine.h" +#include "CameraDistortionMap.h" +#include "CameraFocalPlaneMap.h" +#include "IException.h" +#include "iTime.h" +#include "IString.h" +#include "LineScanCameraDetectorMap.h" +#include "LineScanCameraGroundMap.h" +#include "LineScanCameraSkyMap.h" +#include "NaifStatus.h" + +using namespace std; +namespace Isis { + /** + * Constructs a Chandrayaan 2 TMC Camera object using the image labels. + * + */ + Chandrayaan2TmcCamera::Chandrayaan2TmcCamera(Cube &cube) : LineScanCamera(cube) { + m_instrumentNameLong = "Terrain Mapping Camera-2"; + m_instrumentNameShort = "TMC-2"; + m_spacecraftNameLong = "Chandrayaan 2"; + m_spacecraftNameShort = "Chan2"; + + NaifStatus::CheckErrors(); + // Set up the camera info from ik/iak kernels + SetFocalLength(); + //Chandrayaan2 iak uses INS-152???_PIXEL_SIZE instead of PIXEL_PITCH + QString ikernKey = "INS" + toString(naifIkCode()) + "_PIXEL_SIZE"; + // Pixel size is specified in meters, we need it in mm + SetPixelPitch(getDouble(ikernKey)*1000); + + // Get the start time from labels + Pvl &lab = *cube.label(); + PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse); + QString stime = (QString)inst["StartTime"]; + SpiceDouble etStart=0; + etStart = iTime(stime).Et(); + + double csum = 1; + if (inst.hasKeyword("SpatialSumming")){ + csum = inst["SpatialSumming"]; + } + double lineRate = (double) inst["LineExposureDuration"] / 1000; + + // Setup detector map + LineScanCameraDetectorMap *detectorMap = + new LineScanCameraDetectorMap(this, etStart, lineRate); + detectorMap->SetDetectorSampleSumming(csum); + + // Setup focal plane map + CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, naifIkCode()); + + // Retrieve boresight location from instrument kernel (IK) (addendum?) + QString centerKey = "INS" + toString((int)naifIkCode()) + "_CENTER"; + double sampleCenter = getDouble(centerKey, 0); + double lineCenter = getDouble(centerKey, 1); + + focalMap->SetDetectorOrigin(sampleCenter, lineCenter); + focalMap->SetDetectorOffset(0.0, 0.0); + + // @TODO set no distortion? No values in IK + // Setup distortion map + CameraDistortionMap *distMap = new CameraDistortionMap(this); + distMap->SetDistortion(naifIkCode()); + + // Setup the ground and sky map + new LineScanCameraGroundMap(this); + new LineScanCameraSkyMap(this); + + + // Set proper end frame + int tmcFrame(0); + if (naifIkCode() == -152210) { + // Frame DAWN_VIR_VIS : DAWN_VIR_VIS_ZERO + tmcFrame = -152220; + } + else if (naifIkCode() == -152211) { // (channelId == "IR) + // Frame DAWN_VIR_IR : DAWN_VIR_IR_ZERO + tmcFrame = -152221; + } + else if (naifIkCode() == -152212) { + tmcFrame = -152222; + } + else { + QString msg = "Unknown frame code [" + toString(naifIkCode()) + "] for Chandrayaan2 TMC Camera."; + throw IException(IException::Programmer, msg, _FILEINFO_); + } + + instrumentRotation()->SetFrame(tmcFrame); + + LoadCache(); + NaifStatus::CheckErrors(); + } +} + + +/** + * This is the function that is called in order to instantiate an Chandrayaan2TmcCamera object. + * + * @param cube The input cube from which to instantiate the camera model. + * + * @return Isis::Camera* Chandrayaan2TmcCamera + * + */ +extern "C" Isis::Camera *Chandrayaan2TmcCameraPlugin(Isis::Cube &cube) { + return new Isis::Chandrayaan2TmcCamera(cube); +} diff --git a/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Chandrayaan2TmcCamera.h b/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Chandrayaan2TmcCamera.h new file mode 100644 index 0000000000..71281f99cb --- /dev/null +++ b/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Chandrayaan2TmcCamera.h @@ -0,0 +1,52 @@ +#ifndef TMCCamera_h +#define TMCCamera_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 "LineScanCamera.h" + +namespace Isis { + /** + * @brief Chandrayaan2 TMC (Terrain Mapping Camera) Camera Model + * + * This is the camera model for the Chandrayaan2 Terrain Mapping Camera + */ + class Chandrayaan2TmcCamera : public LineScanCamera { + public: + Chandrayaan2TmcCamera(Cube &cube); + + //! Destroys the CTXCamera object. + ~Chandrayaan2TmcCamera() {}; + + /** + * CK frame ID - - Instrument Code from spacit run on CK + * + * @return @b int The appropriate instrument code for the "Camera-matrix" + * Kernel Frame ID + */ + virtual int CkFrameId() const { return (-152001); } + + /** + * CK Reference ID - MRO_MME_OF_DATE + * + * @return @b int The appropriate instrument code for the "Camera-matrix" + * Kernel Reference ID + */ + virtual int CkReferenceId() const { return (1); } + + /** + * SPK Reference ID - J2000 + * + * @return @b int The appropriate instrument code for the Spacecraft + * Kernel Reference ID + */ + virtual int SpkReferenceId() const { return (1); } + }; +}; +#endif diff --git a/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Chandrayaan2TmcCamera.truth b/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Chandrayaan2TmcCamera.truth new file mode 100644 index 0000000000..d12fefb6cb --- /dev/null +++ b/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Chandrayaan2TmcCamera.truth @@ -0,0 +1,36 @@ +Unit Test for Chandrayaan1M3Camera... +FileName: out.cub +CK Frame: -152210 + +Kernel IDs: +CK Frame ID = -152001 +CK Reference ID = 1 +SPK Target ID = -152 +SPK Reference ID = 1 + +Spacecraft Name Long: Chandrayaan 2 +Spacecraft Name Short: Chan2 +Instrument Name Long: Terrain Mapping Camera-2 +Instrument Name Short: TMC-2 + +For upper left corner ... +DeltaSample = 0.000000000 +DeltaLine = 0.000000000 + +For upper right corner ... +DeltaSample = 0.000000000 +DeltaLine = 0.000000000 + +For lower left corner ... +DeltaSample = 0.000000000 +DeltaLine = 0.000000000 + +For lower right corner ... +DeltaSample = 0.000000000 +DeltaLine = 0.000000000 + +For center pixel position ... +Latitude OK +Longitude OK +RightAscension = 120.8153761895855354 +Declination = -23.1624991236805506 diff --git a/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Makefile b/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Makefile new file mode 100644 index 0000000000..f122bc8822 --- /dev/null +++ b/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/Makefile @@ -0,0 +1,7 @@ +ifeq ($(ISISROOT), $(BLANK)) +.SILENT: +error: + echo "Please set ISISROOT"; +else + include $(ISISROOT)/make/isismake.objs +endif \ No newline at end of file diff --git a/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/unitTest.cpp b/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/unitTest.cpp new file mode 100644 index 0000000000..d0d2a97ac7 --- /dev/null +++ b/isis/src/chandrayaan2/objs/Chandrayaan2TmcCamera/unitTest.cpp @@ -0,0 +1,124 @@ +/** 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 +#include + +#include "Camera.h" +#include "CameraFactory.h" +#include "FileName.h" +#include "IException.h" +#include "Preference.h" +#include "Pvl.h" + +using namespace std; +using namespace Isis; + +void TestLineSamp(Camera *cam, double samp, double line); + + +int main(void) { + Preference::Preferences(true); + + + cout << "Unit Test for Chandrayaan1M3Camera..." << endl; + try { + // These should be lat/lon at center of image. To obtain these numbers for a new cube/camera, + // set both the known lat and known lon to zero and copy the unit test output "Latitude off by: " + // and "Longitude off by: " values directly into these variables. NOTE: These are only used + // for the center of the image test, not the corners. + double knownLat = 61.50040250242506; + double knownLon = 74.89590535143694; + + Cube c("/Users/arsanders/chandrayaan/data/calibrated/20191127/out.cub", "r"); + Camera *cam = CameraFactory::Create(c); + cout << "FileName: " << FileName(c.fileName()).name() << endl; + cout << "CK Frame: " << cam->instrumentRotation()->Frame() << endl << endl; + cout.setf(std::ios::fixed); + cout << setprecision(9); + + // Test kernel IDs + cout << "Kernel IDs: " << endl; + cout << "CK Frame ID = " << cam->CkFrameId() << endl; + cout << "CK Reference ID = " << cam->CkReferenceId() << endl; + cout << "SPK Target ID = " << cam->SpkTargetId() << endl; + cout << "SPK Reference ID = " << cam->SpkReferenceId() << endl << endl; + + // Test name methods + cout << "Spacecraft Name Long: " << cam->spacecraftNameLong() << endl; + cout << "Spacecraft Name Short: " << cam->spacecraftNameShort() << endl; + cout << "Instrument Name Long: " << cam->instrumentNameLong() << endl; + cout << "Instrument Name Short: " << cam->instrumentNameShort() << endl << endl; + + // Test all four corners to make sure the conversions are right + cout << "For upper left corner ..." << endl; + TestLineSamp(cam, 0.5, 0.5); + + cout << "For upper right corner ..." << endl; + TestLineSamp(cam, 608.4999, 0.5); + + cout << "For lower left corner ..." << endl; + TestLineSamp(cam, 0.5, 564.4999); + + cout << "For lower right corner ..." << endl; + TestLineSamp(cam, 608.4999, 564.4999); + + double samp = 304.0; + double line = 282.0; + cout << "For center pixel position ..." << endl; + + if (!cam->SetImage(samp, line)) { + cout << "ERROR" << endl; + return 0; + } + + if (abs(cam->UniversalLatitude() - knownLat) < 1E-10) { + cout << "Latitude OK" << endl; + } + else { + cout << setprecision(16) << "Latitude off by: " << cam->UniversalLatitude() - knownLat << endl; + } + + if (abs(cam->UniversalLongitude() - knownLon) < 1E-10) { + cout << "Longitude OK" << endl; + } + else { + cout << setprecision(16) << "Longitude off by: " << cam->UniversalLongitude() - knownLon << endl; + } + + cout << "RightAscension = " << cam->RightAscension() << endl; + cout << "Declination = " << cam->Declination() << endl; + + } + catch (IException &e) { + e.print(); + } +} + + +void TestLineSamp(Camera *cam, double samp, double line) { + bool success = cam->SetImage(samp, line); + + if (success) { + success = cam->SetUniversalGround(cam->UniversalLatitude(), cam->UniversalLongitude()); + } + + if (success) { + double deltaSamp = samp - cam->Sample(); + double deltaLine = line - cam->Line(); + if (fabs(deltaSamp) < 1.0E-4) deltaSamp = 0; + if (fabs(deltaLine) < 1.0E-4) deltaLine = 0; + cout << "DeltaSample = " << deltaSamp << endl; + cout << "DeltaLine = " << deltaLine << endl << endl; + } + else { + cout << "DeltaSample = ERROR" << endl; + cout << "DeltaLine = ERROR" << endl << endl; + } +} + diff --git a/isis/src/chandrayaan2/objs/Makefile b/isis/src/chandrayaan2/objs/Makefile new file mode 100644 index 0000000000..5955762018 --- /dev/null +++ b/isis/src/chandrayaan2/objs/Makefile @@ -0,0 +1 @@ +include $(ISISROOT)/make/isismake.objstree