Isis 3 Programmer Reference
LroWideAngleCamera.cpp
Go to the documentation of this file.
1 
21 #include "LroWideAngleCamera.h"
24 
25 #include <sstream>
26 #include <iomanip>
27 
28 #include <QString>
29 #include <QVector>
30 
31 #include "CameraFocalPlaneMap.h"
32 #include "CameraSkyMap.h"
33 #include "CollectorMap.h"
34 #include "IException.h"
35 #include "IString.h"
36 #include "iTime.h"
37 #include "NaifStatus.h"
40 
41 using namespace std;
42 namespace Isis {
53  LroWideAngleCamera::LroWideAngleCamera(Cube &cube) :
54  PushFrameCamera(cube) {
55 
57 
58  m_spacecraftNameLong = "Lunar Reconnaissance Orbiter";
59  m_spacecraftNameShort = "LRO";
60 
61  // Set up the camera characteristics
64  SetPixelPitch();
65 
66  Pvl &lab = *cube.label();
67 
68  // Get the ephemeris time from the labels
69  double et;
70  PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse);
71  QString stime = inst["SpacecraftClockStartCount"];
72  et = getClockTime(stime).Et();
73 
74  p_exposureDur = toDouble(inst["ExposureDuration"]);
75  // TODO: Changed et - exposure to et + exposure.
76  // Think about if this is correct
77  p_etStart = et + ((p_exposureDur / 1000.0) / 2.0);
78 
79  // Compute the framelet size and number of framelets
80  QString instId = inst["InstrumentId"][0].toUpper();
81 
82  int frameletSize = 14;
83  int sumMode = 1;
84  int filterIKBase = 10;
85 
86  if (instId == "WAC-UV") {
87  sumMode = 4;
88  frameletSize = 16;
89  filterIKBase = 15 - 1; // New UV IK code = filterIKBase + BANDID
90  m_instrumentNameLong = "Wide Angle Camera Ultra Violet";
91  m_instrumentNameShort = "WAC-UV";
92  }
93  else if (instId == "WAC-VIS") {
94  sumMode = 1;
95  frameletSize = 14;
96  filterIKBase = 10 - 3; // New VIS IK code = filterIKBase + BANDID
97  m_instrumentNameLong = "Wide Angle Camera Visual";
98  m_instrumentNameShort = "WAC-VIS";
99  }
100  else {
101  QString msg = "Invalid value [" + instId
102  + "] for keyword [InstrumentId]";
104  }
105 
106  p_nframelets = (int) (ParentLines() / (frameletSize / sumMode));
107 
108  // Setup the line detector offset map for each filter
109  int nbands = (int) lab.findKeyword("Bands", PvlObject::Traverse);
110  const PvlGroup &bandBin = lab.findGroup("BandBin", Pvl::Traverse);
111  const PvlKeyword &filtNames = bandBin["Center"];
112 
113  // Sanity check
114  if (nbands != filtNames.size()) {
115  ostringstream mess;
116  mess << "Number bands in (file) label (" << nbands
117  << ") do not match number of values in BandBin/Center keyword ("
118  << filtNames.size() << ") - required for band-dependent geoemtry";
119  throw IException(IException::User, mess.str(), _FILEINFO_);
120  }
121 
122  // Is the data flipped?
123  bool dataflipped = (inst["DataFlipped"][0].toUpper() == "YES");
124 
125  // Now create detector offsets
126  QString instCode = "INS" + QString::number(naifIkCode());
127 
128  QString ikernKey = instCode + "_FILTER_BANDCENTER";
129  IntParameterList fbc = GetVector(ikernKey);
130 
131  ikernKey = instCode + "_FILTER_OFFSET";
132  IntParameterList foffset = GetVector(ikernKey);
133 
134  // Get band ID to determine new filter dependent IK codes
135  ikernKey = instCode + "_FILTER_BANDID";
136  IntParameterList fbandid = GetVector(ikernKey);
137 
138 
139  // Create a map of filter wavelength to offset. Also needs a reverse
140  // lookup to order the offset into the CCD (ascending sort provided
141  // automagically be CollectorMap).
142  CollectorMap<int, int> filterToDetectorOffset, wavel,filterIKCode;
143  for (int i = 0 ; i < foffset.size() ; i++) {
144  filterToDetectorOffset.add(fbc[i], foffset[i]);
145  wavel.add(foffset[i], fbc[i]);
146  filterIKCode.add(fbc[i], naifIkCode() - (filterIKBase + fbandid[i])); // New IK code
147  }
148 
149  // Construct special format for framelet offsets into CCD. Uses the above
150  // reverse map. Need only get the value (wavelength) of the map as the
151  // key (offset) is sorted above.
152  int frameletOffsetFactor = inst["ColorOffset"];
153  if ( dataflipped ) frameletOffsetFactor *= -1;
154  CollectorMap<int, int> filterToFrameletOffset;
155  for (int j = 0 ; j < wavel.size() ; j++) {
156  int wavelen = wavel.getNth(j);
157  filterToFrameletOffset.add(wavelen, j * frameletOffsetFactor);
158  }
159 
160  // Now map the actual filters that exist in cube to camera components or
161  // storage vectors for later band selection (see SetBand(vband))
162  for (int i = 0; i < filtNames.size(); i++) {
163  if (!filterToDetectorOffset.exists(filtNames[i].toInt())) {
164  QString msg = "Unrecognized filter name [" + filtNames[i] + "]";
166  }
167 
168  p_detectorStartLines.push_back(filterToDetectorOffset.get(filtNames[i].toInt()));
169  p_frameletOffsets.push_back(filterToFrameletOffset.get(filtNames[i].toInt()));
170 
171  QString kBase = "INS" + QString::number(filterIKCode.get(filtNames[i].toInt()));
172  p_focalLength.push_back(getDouble(kBase+"_FOCAL_LENGTH"));
173  p_boreSightSample.push_back(getDouble(kBase+"_BORESIGHT_SAMPLE"));
174  p_boreSightLine.push_back(getDouble(kBase+"_BORESIGHT_LINE"));
175  }
176 
177  // Setup detector map
178  double frameletRate = (double) inst["InterframeDelay"] / 1000.0;
180  p_etStart, frameletRate, frameletSize);
181  dmap->SetDetectorSampleSumming(sumMode);
182  dmap->SetDetectorLineSumming(sumMode);
183 
184  // flipping disabled if already flipped
185  bool flippedFramelets = dataflipped;
186  dmap->SetFrameletOrderReversed(flippedFramelets, p_nframelets);
188 
189  // get instrument-specific sample offset
190  QString instModeId = inst["InstrumentModeId"][0].toUpper();
191  // For BW mode, add the mode (0,1 (non-polar) or 2,3 (polar)) used to
192  // acquire image
193  if (instModeId == "BW") {
194  instModeId += inst["Mode"][0];
195  // There are no offsets for BW mode.. there can only be 1 filter
196  // and there must be 1 filter.
197  p_frameletOffsets[0] = 0;
198  }
199 
200  ikernKey = instCode + "_" + instModeId + "_SAMPLE_OFFSET";
201  int sampOffset = getInteger(ikernKey);
202  dmap->SetStartingDetectorSample(sampOffset+1);
203 
204  // Setup focal plane and distortion maps
207  for ( int i = 0 ; i < filtNames.size() ; i++ ) {
208  fplane->addFilter(filterIKCode.get(filtNames[i].toInt()));
209  distort->addFilter(filterIKCode.get(filtNames[i].toInt()));
210  }
211 
212  // Setup the ground and sky map
213  bool evenFramelets = (inst["Framelets"][0].toUpper() == "EVEN");
214  new PushFrameCameraGroundMap(this, evenFramelets);
215  new CameraSkyMap(this);
216 
217  SetBand(1);
218  LoadCache();
220 
221  if(instId == "WAC-UV") {
222  // geometric tiling is not worth trying for 4-line framelets
224  }
225  else {
227  }
228  }
229 
230 
231 
234  }
235 
236 
237 
243  void LroWideAngleCamera::SetBand(const int vband) {
244 
245  // Sanity check on requested band
246  int maxbands = min(p_detectorStartLines.size(), p_frameletOffsets.size());
247  if ((vband <= 0) || (vband > maxbands)) {
248  ostringstream mess;
249  mess << "Requested virtual band (" << vband
250  << ") outside valid (BandBin/Center) limits (1 - " << maxbands
251  << ")";
252  throw IException(IException::Programmer, mess.str(), _FILEINFO_);
253  }
254 
255  // Set up valid band access
256  Camera::SetBand(vband);
257  PushFrameCameraDetectorMap *dmap = NULL;
259  dmap->SetBandFirstDetectorLine(p_detectorStartLines[vband - 1]);
260  dmap->SetFrameletOffset(p_frameletOffsets[vband - 1]);
261 
262  SetFocalLength(p_focalLength[vband-1]);
263 
265  fplane->setBand(vband);
266  fplane->SetDetectorOrigin(p_boreSightSample[vband-1] + 1.0,
267  p_boreSightLine[vband-1] + 1.0);
268 
270  distort->setBand(vband);
271  return;
272  }
273 
274 
275 
280  int LroWideAngleCamera::PoolKeySize(const QString &key) const {
281  SpiceBoolean found;
282  SpiceInt n;
283  SpiceChar ctype[1];
284  dtpool_c(key.toLatin1().data(), &found, &n, ctype);
285  if (!found) n = 0;
286  return (n);
287  }
288 
289 
290 
296  QVariant poolKeySize = getStoredResult(key + "_SIZE", SpiceIntType);
297 
298  int nvals = poolKeySize.toInt();
299 
300  if (nvals == 0) {
301  nvals = PoolKeySize(key);
302  storeResult(key + "_SIZE", SpiceIntType, nvals);
303  }
304 
305  if (nvals <= 0) {
306  QString mess = "Kernel pool keyword " + key + " not found!";
308  }
309 
310  IntParameterList parms;
311  for (int i = 0 ; i < nvals ; i++) {
312  parms.push_back(getInteger(key, i));
313  }
314 
315  return (parms);
316  }
317 
318 
319 
326  return false;
327  }
328 
329 
330 
338  return (-85000);
339  }
340 
341 
342 
350  return (1);
351  }
352 
353 
354 
362  return (1);
363  }
364 }
365 
366 
367 // Plugin
379  return new Isis::LroWideAngleCamera(cube);
380 }
void SetBandFirstDetectorLine(int firstLine)
Change the starting line in the detector based on band.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
void SetFocalLength()
Reads the focal length from the instrument kernel.
Definition: Camera.cpp:1430
virtual int CkReferenceId() const
CK Reference ID - J2000.
void SetFrameletOrderReversed(bool frameletOrderReversed, int nframelets)
Changes the direction of the framelets.
int PoolKeySize(const QString &key) const
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
T & get(const K &key)
Returns the value associated with the name provided.
Definition: CollectorMap.h:583
bool IsBandIndependent()
The camera model is band dependent, so this method returns false.
double p_exposureDur
Exposure Duration value from labels.
CameraDistortionMap * DistortionMap()
Returns a pointer to the CameraDistortionMap object.
Definition: Camera.cpp:2838
void SetFrameletOffset(int frameletOffset)
Reset the frame offset.
SpiceInt getInteger(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition: Spice.cpp:949
QString m_instrumentNameLong
Full instrument name.
Definition: Camera.h:507
T & getNth(int nth)
Returns the nth value in the collection.
Definition: CollectorMap.h:640
void SetDetectorSampleSumming(const double summing)
Set sample summing mode.
void SetPixelPitch()
Reads the Pixel Pitch from the instrument kernel.
Definition: Camera.cpp:1437
void SetFrameletsGeometricallyFlipped(bool frameletsFlipped)
Mirrors the each framelet in the file.
Namespace for the standard library.
Convert between undistorted focal plane and ground coordinates.
Search child objects.
Definition: PvlObject.h:170
void SetDetectorOrigin(const double sample, const double line)
Set the detector origin.
int size() const
Returns the size of the collection.
Definition: CollectorMap.h:528
PushFrameCameraDetectorMap * DetectorMap()
Returns a pointer to the PushFrameCameraDetectorMap object.
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:164
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:162
void setBand(int vband)
Implements band-dependant distortion parameters.
void SetDetectorLineSumming(const double summing)
Set line summing mode.
int ParentLines() const
Returns the number of lines in the parent alphacube.
Definition: Camera.cpp:2818
Distort/undistort focal plane coordinates.
Generic class for Push Frame Cameras.
void SetFrame(int frameCode)
Change the frame to the given frame code.
int size() const
Returns the number of values stored in this keyword.
Definition: PvlKeyword.h:141
virtual int CkFrameId() const
CK frame ID - - Instrument Code from spacit run on CK.
QString m_instrumentNameShort
Shortened instrument name.
Definition: Camera.h:508
PvlKeyword & findKeyword(const QString &kname, FindOptions opts)
Finds a keyword in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within this...
Definition: PvlObject.cpp:148
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
bool exists(const K &key) const
Checks the existance of a particular key in the list.
Definition: CollectorMap.h:567
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
void add(const K &key, const T &value)
Adds the element to the list.
Definition: CollectorMap.h:556
LRO Wide Angle Camera Model.
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
Convert between parent image coordinates and detector coordinates.
void setBand(int vband)
Implements band-dependant focal plane parameters.
Collector/container for arbitrary items.
Definition: CollectorMap.h:435
Container for cube-like labels.
Definition: Pvl.h:135
CameraFocalPlaneMap * FocalPlaneMap()
Returns a pointer to the CameraFocalPlaneMap object.
Definition: Camera.cpp:2848
void LoadCache()
This loads the spice cache big enough for this image.
Definition: Camera.cpp:2432
~LroWideAngleCamera()
Destroys the LroWideAngleCamera object.
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
void SetStartingDetectorSample(const double sample)
Set the starting detector sample.
void SetBand(const int band)
Sets the band in the camera model.
int p_nframelets
Number of framelets in whole image.
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:43
void addFilter(int naifIkCode)
Add an additional set of parameters for a given LROC/WAC filter.
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
SpiceRotation * instrumentRotation() const
Accessor method for the instrument rotation.
Definition: Spice.cpp:1489
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Convert between undistorted focal plane and ra/dec coordinates.
Definition: CameraSkyMap.h:48
QString m_spacecraftNameShort
Shortened spacecraft name.
Definition: Camera.h:510
IntParameterList GetVector(const QString &key)
Isis::Camera * LroWideAngleCameraPlugin(Isis::Cube &cube)
This is the function that is called in order to instantiate a LroWideAngleCamera object.
void SetGeometricTilingHint(int startSize=128, int endSize=8)
This method sets the best geometric tiling size for projecting from this camera model.
Definition: Camera.cpp:2566
double Et() const
Returns the ephemeris time (TDB) representation of the time as a double.
Definition: iTime.h:139
virtual void SetBand(const int band)
Virtual method that sets the band number.
Definition: Camera.cpp:2692
Distort/undistort focal plane coordinates.
double p_etStart
Ephemeris Start iTime.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
virtual int SpkReferenceId() const
SPK Reference ID - J2000.
SpiceInt type.
Definition: Spice.h:360
void addFilter(int naifIkCode)
Add an additional set of parameters for a given LROC/WAC filter.
SpiceDouble getDouble(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition: Spice.cpp:963
IO Handler for Isis Cubes.
Definition: Cube.h:170