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