Isis 3.0 Programmer Reference
Back | Home
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:1485
int size() const
Returns the number of values stored in this keyword.
Definition: PvlKeyword.h:141
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:2886
virtual double LineScaleFactor() const
Return scaling factor for computing line resolution.
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:494
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
void SetDetectorSampleSumming(const double summing)
Set sample summing mode.
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1298
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition: IString.cpp:108
int ReferenceBand() const
Returns the reference band.
Definition: Camera.cpp:2721
void SetPixelPitch()
Reads the Pixel Pitch from the instrument kernel.
Definition: Camera.cpp:1492
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:154
double Et() const
Returns the ephemeris time (TDB) representation of the time as a double.
Definition: iTime.h:135
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:2732
Convert between undistorted focal plane and ground coordinates.
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:495
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:134
A single keyword-value pair.
Definition: PvlKeyword.h:98
Container for cube-like labels.
Definition: Pvl.h:135
CameraFocalPlaneMap * FocalPlaneMap()
Returns a pointer to the CameraFocalPlaneMap object.
Definition: Camera.cpp:2896
Convert between undistorted focal plane and ra/dec coordinates.
void LoadCache()
This loads the spice cache big enough for this image.
Definition: Camera.cpp:2489
QString m_spacecraftNameLong
Full spacecraft name.
Definition: Camera.h:496
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:99
SpiceInt naifIkCode() const
This returns the NAIF IK code to use when reading from instrument kernels.
Definition: Spice.cpp:888
Adds specific functionality to C++ strings.
Definition: IString.h:179
iTime getClockTime(QString clockValue, int sclkCode=-1)
This converts the spacecraft clock ticks value (clockValue) to an iTime.
Definition: Spice.cpp:969
QString m_spacecraftNameShort
Shortened spacecraft name.
Definition: Camera.h:497
Convert between parent image coordinates and detector coordinates.
void SetStartTime(const double etStart)
Reset the starting ephemeris time.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Distort/undistort focal plane coordinates.
IO Handler for Isis Cubes.
Definition: Cube.h:158

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:30:45