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 
22 using namespace std;
23 namespace Isis {
32  ThemisIrCamera::ThemisIrCamera(Cube &cube) : LineScanCamera(cube) {
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
212 extern "C" Isis::Camera *ThemisIrCameraPlugin(Isis::Cube &cube) {
213  return new Isis::ThemisIrCamera(cube);
214 }
Isis::LineScanCameraSkyMap
Convert between undistorted focal plane and ra/dec coordinates.
Definition: LineScanCameraSkyMap.h:34
Isis::CameraFocalPlaneMap::SetDetectorOrigin
void SetDetectorOrigin(const double sample, const double line)
Set the detector origin.
Definition: CameraFocalPlaneMap.cpp:293
Isis::PvlObject::findGroup
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:129
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::Spice::naifIkCode
SpiceInt naifIkCode() const
This returns the NAIF IK code to use when reading from instrument kernels.
Definition: Spice.cpp:968
Isis::Camera::m_instrumentNameLong
QString m_instrumentNameLong
Full instrument name.
Definition: Camera.h:496
Isis::Spice::getClockTime
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:1053
Isis::CameraDetectorMap::SetDetectorSampleSumming
void SetDetectorSampleSumming(const double summing)
Set sample summing mode.
Definition: CameraDetectorMap.h:108
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::Camera::DistortionMap
CameraDistortionMap * DistortionMap()
Returns a pointer to the CameraDistortionMap object.
Definition: Camera.cpp:2826
Isis::CameraFocalPlaneMap::SetDetectorOffset
void SetDetectorOffset(const double sampleOffset, const double lineOffset)
Set the detector offset.
Definition: CameraFocalPlaneMap.cpp:324
Isis::Camera::HasReferenceBand
bool HasReferenceBand() const
Checks to see if the Camera object has a reference band.
Definition: Camera.cpp:2670
Isis::NaifStatus::CheckErrors
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:28
Isis::Camera
Definition: Camera.h:236
Isis::ThemisIrCamera
THEMIS IR Camera.
Definition: ThemisIrCamera.h:54
Isis::LineScanCameraDetectorMap::SetStartTime
void SetStartTime(const double etStart)
Reset the starting ephemeris time.
Definition: LineScanCameraDetectorMap.cpp:47
Isis::CameraDetectorMap::SetDetectorLineSumming
void SetDetectorLineSumming(const double summing)
Set line summing mode.
Definition: CameraDetectorMap.h:123
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::iTime::Et
double Et() const
Returns the ephemeris time (TDB) representation of the time as a double.
Definition: iTime.h:126
Isis::Camera::SetPixelPitch
void SetPixelPitch()
Reads the Pixel Pitch from the instrument kernel.
Definition: Camera.cpp:1418
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::toInt
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition: IString.cpp:93
Isis::ThemisIrCamera::SetBand
void SetBand(const int band)
Change the THEMIS IR camera parameters based on the band number.
Definition: ThemisIrCamera.cpp:119
Isis::ThemisIrDistortionMap
Distort/undistort focal plane coordinates.
Definition: ThemisIrDistortionMap.h:35
Isis::LineScanCamera
Generic class for Line Scan Cameras.
Definition: LineScanCamera.h:36
Isis::LineScanCameraGroundMap
Convert between undistorted focal plane and ground coordinates.
Definition: LineScanCameraGroundMap.h:49
Isis::Cube
IO Handler for Isis Cubes.
Definition: Cube.h:167
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::Camera::m_spacecraftNameLong
QString m_spacecraftNameLong
Full spacecraft name.
Definition: Camera.h:498
Isis::CameraDetectorMap::LineScaleFactor
virtual double LineScaleFactor() const
Return scaling factor for computing line resolution.
Definition: CameraDetectorMap.cpp:183
Isis::Camera::FocalPlaneMap
CameraFocalPlaneMap * FocalPlaneMap()
Returns a pointer to the CameraFocalPlaneMap object.
Definition: Camera.cpp:2836
Isis::IException::Programmer
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:146
std
Namespace for the standard library.
Isis::Camera::LoadCache
void LoadCache()
This loads the spice cache big enough for this image.
Definition: Camera.cpp:2420
Isis::Camera::m_instrumentNameShort
QString m_instrumentNameShort
Shortened instrument name.
Definition: Camera.h:497
Isis::CameraFocalPlaneMap
Convert between distorted focal plane and detector coordinates.
Definition: CameraFocalPlaneMap.h:85
Isis::Cube::label
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1701
Isis::PvlKeyword::size
int size() const
Returns the number of values stored in this keyword.
Definition: PvlKeyword.h:125
Isis::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
Isis::Camera::ReferenceBand
int ReferenceBand() const
Returns the reference band.
Definition: Camera.cpp:2659
Isis::LineScanCamera::DetectorMap
LineScanCameraDetectorMap * DetectorMap()
Returns a pointer to the LineScanCameraDetectorMap object.
Definition: LineScanCamera.h:72
Isis::Camera::m_spacecraftNameShort
QString m_spacecraftNameShort
Shortened spacecraft name.
Definition: Camera.h:499
Isis::Camera::SetFocalLength
void SetFocalLength()
Reads the focal length from the instrument kernel.
Definition: Camera.cpp:1411
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::LineScanCameraDetectorMap
Convert between parent image coordinates and detector coordinates.
Definition: LineScanCameraDetectorMap.h:37
Isis::IException::User
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition: IException.h:126