USGS

Isis 3.0 Object Programmers' Reference

Home

ThemisIrCamera.cpp
Go to the documentation of this file.
1 
21 #include "ThemisIrCamera.h"
22 #include "ThemisIrDistortionMap.h"
23 
24 #include "CameraFocalPlaneMap.h"
25 #include "IException.h"
26 #include "iTime.h"
29 #include "LineScanCameraSkyMap.h"
30 #include "NaifStatus.h"
31 
32 using namespace std;
33 namespace Isis {
42  ThemisIrCamera::ThemisIrCamera(Cube &cube) : LineScanCamera(cube) {
44  // Set the detector size
45  SetPixelPitch(0.05);
46  SetFocalLength(203.9213);
47 
48  // Get the start time. This includes adding a time offset that could
49  // have been put in the labels during ingestion (thm2isis). This is meant
50  // to handle a random timing errors which can be up to four pixels
51  Pvl &lab = *cube.label();
52  PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse);
53  QString stime = inst["SpacecraftClockCount"];
54  p_etStart = getClockTime(stime).Et();
55 
56  double offset = inst["SpacecraftClockOffset"];
57  p_etStart += offset;
58 
59  // If bands have been extracted from the original image then we
60  // need to read the band bin group so we can map from the cube band
61  // number to the instrument band number
62  PvlGroup &bandBin = lab.findGroup("BandBin", Pvl::Traverse);
63  PvlKeyword &orgBand = bandBin["FilterNumber"];
64  for(int i = 0; i < orgBand.size(); i++) {
65  p_originalBand.push_back(toInt(orgBand[i]));
66  }
67 
68  // Themis IR had a summing mode added. This directly affects the line
69  // rate. That is, the seconds per line. In the Kieffer-Torson model
70  // the line rates was 33.2804 ms per line in SumMode = 1. In the
71  // Duxbury model it is 33.2871 based on 1/22/2009 email with a readout
72  // rate of 30.0417 lines/second
73  int sumMode = 1;
74  if(inst.hasKeyword("SpatialSumming")) {
75  sumMode = inst["SpatialSumming"];
76  }
77  p_lineRate = 33.2871 / 1000.0 * sumMode;
78 
79  // If the TDI mode is enabled then 16 line in the detector are summed
80  // to improve the SNR. In the SetBand method we will the TDI mode to
81  // determine line offset for the band.
82  p_tdiMode = (QString) inst["TimeDelayIntegration"];
83 
84  // The detector map tells us how to convert from image coordinates to
85  // detector coordinates. In our case, a (sample,line) to a (sample,time)
86  // This is band dependent so it will change in SetBand
87  LineScanCameraDetectorMap *detectorMap = new LineScanCameraDetectorMap(this, p_etStart, p_lineRate);
88  detectorMap->SetDetectorSampleSumming(sumMode);
89  detectorMap->SetDetectorLineSumming(sumMode);
90 
91  // The focal plane map tells us how to go from detector position
92  // to focal plane x/y (distorted). That is, (sample,time) to (x,y).
93  // This is band dependent so it will change in SetBand
94  CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, naifIkCode());
95 
96  // The boresight sample in the K-T model was 164.25. In Duxbury's it is
97  // 160.5 or half the detector width. The detector offset varies by band
98  // and is set to the proper value for band 1 for now
99  focalMap->SetDetectorOrigin(160.5, 0.0);
100  focalMap->SetDetectorOffset(0.0, 120.5 - 8.5);
101 
102  // The camera has a distortion map which scales in the X direction,
103  // effectively a variable focal length, and an independent Y direction.
104  // Both are based on the band number
105  new ThemisIrDistortionMap(this);
106 
107  // Setup the ground and sky map
108  new LineScanCameraGroundMap(this);
109  new LineScanCameraSkyMap(this);
110 
111  LoadCache();
113  }
114 
115 
124  void ThemisIrCamera::SetBand(const int vband) {
125  // Lookup the original band from the band bin group. Unless there is
126  // a reference band which means the data has all been aligned in the
127  // band dimension
128  int band;
129  if(HasReferenceBand()) {
130  band = ReferenceBand();
131  if((band < 1) || (band > 10)) {
132  string msg = "Invalid Reference Band [" + IString(band) + "]";
134  }
135  }
136  else {
137  if(vband > (int) p_originalBand.size()) {
138  string msg = "Band number out of array bounds in ThemisIRCamera";
140  }
141  band = p_originalBand[vband-1];
142  }
143 
144  // Get the detector line in the CCD. If TDI mode is enabled then
145  // we used the middle of the 16 lines which were summed. Otherwise
146  // an individual line was read out. It is not clear where/how the
147  // noTDI offsets were derived. Hopefully from some THEMIS document.
148  // They were copied from ISIS2 code and the only suspicious value is
149  // at 52. Also, Duxbury's 1/22/09 email used 128.5 vs 129.5 for the
150  // center of the TDI enable detector line positions.
151  double detectorLine;
152  if(p_tdiMode == "ENABLED") {
153  double bandDetector_TDI[] = {8.5, 24.5, 50.5, 76.5, 102.5,
154  128.5, 154.5, 180.5, 205.5, 231.5
155  };
156  detectorLine = bandDetector_TDI[band-1];
157  }
158  else {
159  int bandDetector_noTDI[] = {9, 24, 52, 77, 102, 129, 155, 181, 206, 232};
160  detectorLine = (double) bandDetector_noTDI[band-1];
161  }
162 
163  // Compute the time offset for this band (using detector line)
164  // Subtracting 1.0 as in Duxbury's example would be the offset to
165  // the center of the pixel but we want to the top edge so we
166  // subtract 0.5
167  p_bandTimeOffset = (detectorLine - 0.5) * p_lineRate;
168  p_bandTimeOffset /= this->DetectorMap()->LineScaleFactor();
169 
170  // Adjust the starting time in the detector map for this band
171  LineScanCameraDetectorMap *detectorMap =
173  detectorMap->SetStartTime(p_etStart + p_bandTimeOffset);
174 
175  // Compute the along track offset at this detector line. That is,
176  // the number of pixels away from the boresight line. In the K-T model
177  // the boresight line was 109.5. In Duxbury's it is half of the
178  // detector height or 120.5
179  double alongtrackOffset = 120.5 - detectorLine;
180 
181  // Adjust alongtrackOffset using Kirk's empirically fitted numbers from
182  // Apr 2009
183  double empiricalOffset[] = { -0.076, -0.098, -0.089, -0.022, 0.0,
184  -0.020, -0.005, -0.069, 0.025, 0.0
185  };
186  alongtrackOffset += empiricalOffset[band-1];
187  this->FocalPlaneMap()->SetDetectorOffset(0.0, alongtrackOffset);
188 
189  // Adjust the sample boresight using Kirk's empirically fitted numbers
190  // from Apr 2009
191  double sampleBoresight = 160.5;
192  double empiricalBoresightOffset[] = { 0.021, 0.027, 0.005, 0.005, 0.0,
193  -0.007, -0.012, -0.039, -0.045, 0.0
194  };
195  sampleBoresight -= empiricalBoresightOffset[band-1];
196  this->FocalPlaneMap()->SetDetectorOrigin(sampleBoresight, 0.0);
197 
198  // Finally, adjust the optical distortion model based on the band
199  ThemisIrDistortionMap *distMap =
201  distMap->SetBand(band);
202  }
203 }
204 
205 
206 // Plugin
218  return new Isis::ThemisIrCamera(cube);
219 }