Isis 3 Programmer Reference
ThemisIrCamera.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "ThemisIrCamera.h"
10#include "ThemisIrDistortionMap.h"
11
12#include <QString>
13
14#include "CameraFocalPlaneMap.h"
15#include "IException.h"
16#include "iTime.h"
17#include "LineScanCameraDetectorMap.h"
18#include "LineScanCameraGroundMap.h"
19#include "LineScanCameraSkyMap.h"
20#include "NaifStatus.h"
21
22using namespace std;
23namespace Isis {
33 m_instrumentNameLong = "Thermal Emission Imaging System Infrared";
34 m_instrumentNameShort = "Themis-IR";
35 m_spacecraftNameLong = "Mars Odyssey";
36 m_spacecraftNameShort = "Odyssey";
37
39 // Set the detector size
40 SetPixelPitch(0.05);
41 SetFocalLength(203.9213);
42
43 // Get the start time. This includes adding a time offset that could
44 // have been put in the labels during ingestion (thm2isis). This is meant
45 // to handle a random timing errors which can be up to four pixels
46 Pvl &lab = *cube.label();
47 PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse);
48 QString stime = inst["SpacecraftClockCount"];
49 p_etStart = getClockTime(stime).Et();
50
51 double offset = inst["SpacecraftClockOffset"];
52 p_etStart += offset;
53
54 // If bands have been extracted from the original image then we
55 // need to read the band bin group so we can map from the cube band
56 // number to the instrument band number
57 PvlGroup &bandBin = lab.findGroup("BandBin", Pvl::Traverse);
58 PvlKeyword &orgBand = bandBin["FilterNumber"];
59 for(int i = 0; i < orgBand.size(); i++) {
60 p_originalBand.push_back(toInt(orgBand[i]));
61 }
62
63 // Themis IR had a summing mode added. This directly affects the line
64 // rate. That is, the seconds per line. In the Kieffer-Torson model
65 // the line rates was 33.2804 ms per line in SumMode = 1. In the
66 // Duxbury model it is 33.2871 based on 1/22/2009 email with a readout
67 // rate of 30.0417 lines/second
68 int sumMode = 1;
69 if(inst.hasKeyword("SpatialSumming")) {
70 sumMode = inst["SpatialSumming"];
71 }
72 p_lineRate = 33.2871 / 1000.0 * sumMode;
73
74 // If the TDI mode is enabled then 16 line in the detector are summed
75 // to improve the SNR. In the SetBand method we will the TDI mode to
76 // determine line offset for the band.
77 p_tdiMode = (QString) inst["TimeDelayIntegration"];
78
79 // The detector map tells us how to convert from image coordinates to
80 // detector coordinates. In our case, a (sample,line) to a (sample,time)
81 // This is band dependent so it will change in SetBand
82 LineScanCameraDetectorMap *detectorMap = new LineScanCameraDetectorMap(this, p_etStart, p_lineRate);
83 detectorMap->SetDetectorSampleSumming(sumMode);
84 detectorMap->SetDetectorLineSumming(sumMode);
85
86 // The focal plane map tells us how to go from detector position
87 // to focal plane x/y (distorted). That is, (sample,time) to (x,y).
88 // This is band dependent so it will change in SetBand
89 CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, naifIkCode());
90
91 // The boresight sample in the K-T model was 164.25. In Duxbury's it is
92 // 160.5 or half the detector width. The detector offset varies by band
93 // and is set to the proper value for band 1 for now
94 focalMap->SetDetectorOrigin(160.5, 0.0);
95 focalMap->SetDetectorOffset(0.0, 120.5 - 8.5);
96
97 // The camera has a distortion map which scales in the X direction,
98 // effectively a variable focal length, and an independent Y direction.
99 // Both are based on the band number
100 new ThemisIrDistortionMap(this);
101
102 // Setup the ground and sky map
103 new LineScanCameraGroundMap(this);
104 new LineScanCameraSkyMap(this);
105
106 LoadCache();
108 }
109
110
119 void ThemisIrCamera::SetBand(const int vband) {
120 // Lookup the original band from the band bin group. Unless there is
121 // a reference band which means the data has all been aligned in the
122 // band dimension
123 int band;
124 if(HasReferenceBand()) {
125 band = ReferenceBand();
126 if((band < 1) || (band > 10)) {
127 string msg = "Invalid Reference Band [" + IString(band) + "]";
128 throw IException(IException::User, msg, _FILEINFO_);
129 }
130 }
131 else {
132 if(vband > (int) p_originalBand.size()) {
133 string msg = "Band number out of array bounds in ThemisIRCamera";
134 throw IException(IException::Programmer, msg, _FILEINFO_);
135 }
136 band = p_originalBand[vband-1];
137 }
138
139 // Get the detector line in the CCD. If TDI mode is enabled then
140 // we used the middle of the 16 lines which were summed. Otherwise
141 // an individual line was read out. It is not clear where/how the
142 // noTDI offsets were derived. Hopefully from some THEMIS document.
143 // They were copied from ISIS2 code and the only suspicious value is
144 // at 52. Also, Duxbury's 1/22/09 email used 128.5 vs 129.5 for the
145 // center of the TDI enable detector line positions.
146 double detectorLine;
147 if(p_tdiMode == "ENABLED") {
148 double bandDetector_TDI[] = {8.5, 24.5, 50.5, 76.5, 102.5,
149 128.5, 154.5, 180.5, 205.5, 231.5
150 };
151 detectorLine = bandDetector_TDI[band-1];
152 }
153 else {
154 int bandDetector_noTDI[] = {9, 24, 52, 77, 102, 129, 155, 181, 206, 232};
155 detectorLine = (double) bandDetector_noTDI[band-1];
156 }
157
158 // Compute the time offset for this band (using detector line)
159 // Subtracting 1.0 as in Duxbury's example would be the offset to
160 // the center of the pixel but we want to the top edge so we
161 // subtract 0.5
162 p_bandTimeOffset = (detectorLine - 0.5) * p_lineRate;
163 p_bandTimeOffset /= this->DetectorMap()->LineScaleFactor();
164
165 // Adjust the starting time in the detector map for this band
166 LineScanCameraDetectorMap *detectorMap =
168 detectorMap->SetStartTime(p_etStart + p_bandTimeOffset);
169
170 // Compute the along track offset at this detector line. That is,
171 // the number of pixels away from the boresight line. In the K-T model
172 // the boresight line was 109.5. In Duxbury's it is half of the
173 // detector height or 120.5
174 double alongtrackOffset = 120.5 - detectorLine;
175
176 // Adjust alongtrackOffset using Kirk's empirically fitted numbers from
177 // Apr 2009
178 double empiricalOffset[] = { -0.076, -0.098, -0.089, -0.022, 0.0,
179 -0.020, -0.005, -0.069, 0.025, 0.0
180 };
181 alongtrackOffset += empiricalOffset[band-1];
182 this->FocalPlaneMap()->SetDetectorOffset(0.0, alongtrackOffset);
183
184 // Adjust the sample boresight using Kirk's empirically fitted numbers
185 // from Apr 2009
186 double sampleBoresight = 160.5;
187 double empiricalBoresightOffset[] = { 0.021, 0.027, 0.005, 0.005, 0.0,
188 -0.007, -0.012, -0.039, -0.045, 0.0
189 };
190 sampleBoresight -= empiricalBoresightOffset[band-1];
191 this->FocalPlaneMap()->SetDetectorOrigin(sampleBoresight, 0.0);
192
193 // Finally, adjust the optical distortion model based on the band
194 ThemisIrDistortionMap *distMap =
196 distMap->SetBand(band);
197 }
198}
199
200
201// Plugin
212extern "C" Isis::Camera *ThemisIrCameraPlugin(Isis::Cube &cube) {
213 return new Isis::ThemisIrCamera(cube);
214}
virtual double LineScaleFactor() const
Return scaling factor for computing line resolution.
Convert between distorted focal plane and detector coordinates.
void SetDetectorOffset(const double sampleOffset, const double lineOffset)
Set the detector offset.
void SetDetectorOrigin(const double sample, const double line)
Set the detector origin.
QString m_spacecraftNameLong
Full spacecraft name.
Definition Camera.h:499
int ReferenceBand() const
Returns the reference band.
Definition Camera.cpp:2689
void SetFocalLength()
Reads the focal length from the instrument kernel.
Definition Camera.cpp:1422
void SetPixelPitch()
Reads the Pixel Pitch from the instrument kernel.
Definition Camera.cpp:1429
void LoadCache()
This loads the spice cache big enough for this image.
Definition Camera.cpp:2450
QString m_instrumentNameShort
Shortened instrument name.
Definition Camera.h:498
CameraDistortionMap * DistortionMap()
Returns a pointer to the CameraDistortionMap object.
Definition Camera.cpp:2856
QString m_spacecraftNameShort
Shortened spacecraft name.
Definition Camera.h:500
bool HasReferenceBand() const
Checks to see if the Camera object has a reference band.
Definition Camera.cpp:2700
CameraFocalPlaneMap * FocalPlaneMap()
Returns a pointer to the CameraFocalPlaneMap object.
Definition Camera.cpp:2866
QString m_instrumentNameLong
Full instrument name.
Definition Camera.h:497
IO Handler for Isis Cubes.
Definition Cube.h:168
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition Cube.cpp:1707
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Adds specific functionality to C++ strings.
Definition IString.h:165
Convert between parent image coordinates and detector coordinates.
void SetStartTime(const double etStart)
Reset the starting ephemeris time.
Convert between undistorted focal plane and ground coordinates.
Generic class for Line Scan Cameras.
LineScanCameraDetectorMap * DetectorMap()
Returns a pointer to the LineScanCameraDetectorMap object.
Convert between undistorted focal plane and ra/dec coordinates.
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
A single keyword-value pair.
Definition PvlKeyword.h:87
@ Traverse
Search child objects.
Definition PvlObject.h:158
virtual iTime getClockTime(QString clockValue, int sclkCode=-1, bool clockTicks=false)
This converts the spacecraft clock ticks value (clockValue) to an iTime.
Definition Spice.cpp:1060
SpiceInt naifIkCode() const
This returns the NAIF IK code to use when reading from instrument kernels.
Definition Spice.cpp:975
THEMIS IR Camera.
void SetBand(const int band)
Change the THEMIS IR camera parameters based on the band number.
ThemisIrCamera(Cube &cube)
Constructor for the Themis Ir Camera Model.
Distort/undistort focal plane coordinates.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition IString.cpp:93
Namespace for the standard library.