Isis 3 Programmer Reference
LroWideAngleCamera.cpp
1 
7 /* SPDX-License-Identifier: CC0-1.0 */
8 
9 #include "LroWideAngleCamera.h"
10 #include "LroWideAngleCameraFocalPlaneMap.h"
11 #include "LroWideAngleCameraDistortionMap.h"
12 
13 #include <sstream>
14 #include <iomanip>
15 
16 #include <QString>
17 #include <QVector>
18 
19 #include "CameraFocalPlaneMap.h"
20 #include "CameraSkyMap.h"
21 #include "CollectorMap.h"
22 #include "IException.h"
23 #include "IString.h"
24 #include "iTime.h"
25 #include "NaifStatus.h"
26 #include "PushFrameCameraDetectorMap.h"
27 #include "PushFrameCameraGroundMap.h"
28 
29 using namespace std;
30 namespace Isis {
41  LroWideAngleCamera::LroWideAngleCamera(Cube &cube) :
42  PushFrameCamera(cube) {
43 
45 
46  m_spacecraftNameLong = "Lunar Reconnaissance Orbiter";
47  m_spacecraftNameShort = "LRO";
48 
49  // Set up the camera characteristics
52  SetPixelPitch();
53 
54  Pvl &lab = *cube.label();
55 
56  // Get the ephemeris time from the labels
57  double et;
58  PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse);
59  QString stime = inst["SpacecraftClockStartCount"];
60  et = getClockTime(stime).Et();
61 
62  p_exposureDur = toDouble(inst["ExposureDuration"]);
63  // TODO: Changed et - exposure to et + exposure.
64  // Think about if this is correct
65  p_etStart = et + ((p_exposureDur / 1000.0) / 2.0);
66 
67  // Compute the framelet size and number of framelets
68  QString instId = inst["InstrumentId"][0].toUpper();
69 
70  int frameletSize = 14;
71  int sumMode = 1;
72  int filterIKBase = 10;
73 
74  if (instId == "WAC-UV") {
75  sumMode = 4;
76  frameletSize = 16;
77  filterIKBase = 15 - 1; // New UV IK code = filterIKBase + BANDID
78  m_instrumentNameLong = "Wide Angle Camera Ultra Violet";
79  m_instrumentNameShort = "WAC-UV";
80  }
81  else if (instId == "WAC-VIS") {
82  sumMode = 1;
83  frameletSize = 14;
84  filterIKBase = 10 - 3; // New VIS IK code = filterIKBase + BANDID
85  m_instrumentNameLong = "Wide Angle Camera Visual";
86  m_instrumentNameShort = "WAC-VIS";
87  }
88  else {
89  QString msg = "Invalid value [" + instId
90  + "] for keyword [InstrumentId]";
91  throw IException(IException::User, msg, _FILEINFO_);
92  }
93 
94  p_nframelets = (int) (ParentLines() / (frameletSize / sumMode));
95 
96  // Setup the line detector offset map for each filter
97  int nbands = (int) lab.findKeyword("Bands", PvlObject::Traverse);
98  const PvlGroup &bandBin = lab.findGroup("BandBin", Pvl::Traverse);
99  const PvlKeyword &filtNames = bandBin["Center"];
100 
101  // Sanity check
102  if (nbands != filtNames.size()) {
103  ostringstream mess;
104  mess << "Number bands in (file) label (" << nbands
105  << ") do not match number of values in BandBin/Center keyword ("
106  << filtNames.size() << ") - required for band-dependent geoemtry";
107  throw IException(IException::User, mess.str(), _FILEINFO_);
108  }
109 
110  // Is the data flipped?
111  bool dataflipped = (inst["DataFlipped"][0].toUpper() == "YES");
112 
113  // Now create detector offsets
114  QString instCode = "INS" + QString::number(naifIkCode());
115 
116  QString ikernKey = instCode + "_FILTER_BANDCENTER";
117  IntParameterList fbc = GetVector(ikernKey);
118 
119  ikernKey = instCode + "_FILTER_OFFSET";
120  IntParameterList foffset = GetVector(ikernKey);
121 
122  // Get band ID to determine new filter dependent IK codes
123  ikernKey = instCode + "_FILTER_BANDID";
124  IntParameterList fbandid = GetVector(ikernKey);
125 
126 
127  // Create a map of filter wavelength to offset. Also needs a reverse
128  // lookup to order the offset into the CCD (ascending sort provided
129  // automagically be CollectorMap).
130  CollectorMap<int, int> filterToDetectorOffset, wavel,filterIKCode;
131  for (int i = 0 ; i < foffset.size() ; i++) {
132  filterToDetectorOffset.add(fbc[i], foffset[i]);
133  wavel.add(foffset[i], fbc[i]);
134  filterIKCode.add(fbc[i], naifIkCode() - (filterIKBase + fbandid[i])); // New IK code
135  }
136 
137  // Construct special format for framelet offsets into CCD. Uses the above
138  // reverse map. Need only get the value (wavelength) of the map as the
139  // key (offset) is sorted above.
140  int frameletOffsetFactor = inst["ColorOffset"];
141  if ( dataflipped ) frameletOffsetFactor *= -1;
142  CollectorMap<int, int> filterToFrameletOffset;
143  for (int j = 0 ; j < wavel.size() ; j++) {
144  int wavelen = wavel.getNth(j);
145  filterToFrameletOffset.add(wavelen, j * frameletOffsetFactor);
146  }
147 
148  // Now map the actual filters that exist in cube to camera components or
149  // storage vectors for later band selection (see SetBand(vband))
150  for (int i = 0; i < filtNames.size(); i++) {
151  if (!filterToDetectorOffset.exists(filtNames[i].toInt())) {
152  QString msg = "Unrecognized filter name [" + filtNames[i] + "]";
153  throw IException(IException::Programmer, msg, _FILEINFO_);
154  }
155 
156  p_detectorStartLines.push_back(filterToDetectorOffset.get(filtNames[i].toInt()));
157  p_frameletOffsets.push_back(filterToFrameletOffset.get(filtNames[i].toInt()));
158 
159  QString kBase = "INS" + QString::number(filterIKCode.get(filtNames[i].toInt()));
160  p_focalLength.push_back(getDouble(kBase+"_FOCAL_LENGTH"));
161  p_boreSightSample.push_back(getDouble(kBase+"_BORESIGHT_SAMPLE"));
162  p_boreSightLine.push_back(getDouble(kBase+"_BORESIGHT_LINE"));
163  }
164 
165  // Setup detector map
166  double frameletRate = (double) inst["InterframeDelay"] / 1000.0;
168  p_etStart, frameletRate, frameletSize);
169  dmap->SetDetectorSampleSumming(sumMode);
170  dmap->SetDetectorLineSumming(sumMode);
171 
172  // flipping disabled if already flipped
173  bool flippedFramelets = dataflipped;
174  dmap->SetFrameletOrderReversed(flippedFramelets, p_nframelets);
176 
177  // get instrument-specific sample offset
178  QString instModeId = inst["InstrumentModeId"][0].toUpper();
179  // For BW mode, add the mode (0,1 (non-polar) or 2,3 (polar)) used to
180  // acquire image
181  if (instModeId == "BW") {
182  instModeId += inst["Mode"][0];
183  // There are no offsets for BW mode.. there can only be 1 filter
184  // and there must be 1 filter.
185  p_frameletOffsets[0] = 0;
186  }
187 
188  ikernKey = instCode + "_" + instModeId + "_SAMPLE_OFFSET";
189  int sampOffset = getInteger(ikernKey);
190  dmap->SetStartingDetectorSample(sampOffset+1);
191 
192  // Setup focal plane and distortion maps
195  for ( int i = 0 ; i < filtNames.size() ; i++ ) {
196  fplane->addFilter(filterIKCode.get(filtNames[i].toInt()));
197  distort->addFilter(filterIKCode.get(filtNames[i].toInt()));
198  }
199 
200  // Setup the ground and sky map
201  bool evenFramelets = (inst["Framelets"][0].toUpper() == "EVEN");
202  new PushFrameCameraGroundMap(this, evenFramelets);
203  new CameraSkyMap(this);
204 
205  SetBand(1);
206  LoadCache();
208 
209  if(instId == "WAC-UV") {
210  // geometric tiling is not worth trying for 4-line framelets
212  }
213  else {
215  }
216  }
217 
218 
219 
222  }
223 
224 
225 
231  void LroWideAngleCamera::SetBand(const int vband) {
232 
233  // Sanity check on requested band
234  int maxbands = min(p_detectorStartLines.size(), p_frameletOffsets.size());
235  if ((vband <= 0) || (vband > maxbands)) {
236  ostringstream mess;
237  mess << "Requested virtual band (" << vband
238  << ") outside valid (BandBin/Center) limits (1 - " << maxbands
239  << ")";
240  throw IException(IException::Programmer, mess.str(), _FILEINFO_);
241  }
242 
243  // Set up valid band access
244  Camera::SetBand(vband);
245  PushFrameCameraDetectorMap *dmap = NULL;
247  dmap->SetBandFirstDetectorLine(p_detectorStartLines[vband - 1]);
248  dmap->SetFrameletOffset(p_frameletOffsets[vband - 1]);
249 
250  SetFocalLength(p_focalLength[vband-1]);
251 
253  fplane->setBand(vband);
254  fplane->SetDetectorOrigin(p_boreSightSample[vband-1] + 1.0,
255  p_boreSightLine[vband-1] + 1.0);
256 
258  distort->setBand(vband);
259  return;
260  }
261 
262 
263 
268  int LroWideAngleCamera::PoolKeySize(const QString &key) const {
269  SpiceBoolean found;
270  SpiceInt n;
271  SpiceChar ctype[1];
272  dtpool_c(key.toLatin1().data(), &found, &n, ctype);
273  if (!found) n = 0;
274  return (n);
275  }
276 
277 
278 
284  QVariant poolKeySize = getStoredResult(key + "_SIZE", SpiceIntType);
285 
286  int nvals = poolKeySize.toInt();
287 
288  if (nvals == 0) {
289  nvals = PoolKeySize(key);
290  storeResult(key + "_SIZE", SpiceIntType, nvals);
291  }
292 
293  if (nvals <= 0) {
294  QString mess = "Kernel pool keyword " + key + " not found!";
295  throw IException(IException::Programmer, mess, _FILEINFO_);
296  }
297 
298  IntParameterList parms;
299  for (int i = 0 ; i < nvals ; i++) {
300  parms.push_back(getInteger(key, i));
301  }
302 
303  return (parms);
304  }
305 
306 
307 
314  return false;
315  }
316 
317 
318 
326  return (-85000);
327  }
328 
329 
330 
338  return (1);
339  }
340 
341 
342 
350  return (1);
351  }
352 }
353 
354 
355 // Plugin
366 extern "C" Isis::Camera *LroWideAngleCameraPlugin(Isis::Cube &cube) {
367  return new Isis::LroWideAngleCamera(cube);
368 }
Isis::Spice::SpiceIntType
@ SpiceIntType
SpiceInt type.
Definition: Spice.h:351
Isis::Camera::SetBand
virtual void SetBand(const int band)
Virtual method that sets the band number.
Definition: Camera.cpp:2680
Isis::LroWideAngleCamera::GetVector
IntParameterList GetVector(const QString &key)
Definition: LroWideAngleCamera.cpp:283
Isis::CameraFocalPlaneMap::SetDetectorOrigin
void SetDetectorOrigin(const double sample, const double line)
Set the detector origin.
Definition: CameraFocalPlaneMap.cpp:293
Isis::PushFrameCameraDetectorMap::SetFrameletOffset
void SetFrameletOffset(int frameletOffset)
Reset the frame offset.
Definition: PushFrameCameraDetectorMap.cpp:270
Isis::Camera::SetGeometricTilingHint
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:2554
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::LroWideAngleCamera::CkFrameId
virtual int CkFrameId() const
CK frame ID - - Instrument Code from spacit run on CK.
Definition: LroWideAngleCamera.cpp:325
Isis::Camera::ParentLines
int ParentLines() const
Returns the number of lines in the parent alphacube.
Definition: Camera.cpp:2806
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::LroWideAngleCamera::~LroWideAngleCamera
~LroWideAngleCamera()
Destroys the LroWideAngleCamera object.
Definition: LroWideAngleCamera.cpp:221
Isis::CollectorMap::getNth
T & getNth(int nth)
Returns the nth value in the collection.
Definition: CollectorMap.h:624
Isis::Spice::naifIkCode
SpiceInt naifIkCode() const
This returns the NAIF IK code to use when reading from instrument kernels.
Definition: Spice.cpp:968
Isis::PushFrameCameraDetectorMap::SetFrameletOrderReversed
void SetFrameletOrderReversed(bool frameletOrderReversed, int nframelets)
Changes the direction of the framelets.
Definition: PushFrameCameraDetectorMap.cpp:340
Isis::PushFrameCameraDetectorMap::SetFrameletsGeometricallyFlipped
void SetFrameletsGeometricallyFlipped(bool frameletsFlipped)
Mirrors the each framelet in the file.
Definition: PushFrameCameraDetectorMap.cpp:359
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::CollectorMap::get
T & get(const K &key)
Returns the value associated with the name provided.
Definition: CollectorMap.h:567
Isis::LroWideAngleCameraDistortionMap
Distort/undistort focal plane coordinates.
Definition: LroWideAngleCameraDistortionMap.h:47
Isis::CameraDetectorMap::SetDetectorSampleSumming
void SetDetectorSampleSumming(const double summing)
Set sample summing mode.
Definition: CameraDetectorMap.h:108
Isis::CollectorMap::size
int size() const
Returns the size of the collection.
Definition: CollectorMap.h:512
Isis::Spice::getInteger
SpiceInt getInteger(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition: Spice.cpp:1025
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::NaifStatus::CheckErrors
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:28
Isis::LroWideAngleCamera::IsBandIndependent
bool IsBandIndependent()
The camera model is band dependent, so this method returns false.
Definition: LroWideAngleCamera.cpp:313
Isis::Camera
Definition: Camera.h:236
Isis::LroWideAngleCamera::p_exposureDur
double p_exposureDur
Exposure Duration value from labels.
Definition: LroWideAngleCamera.h:103
Isis::Spice::instrumentRotation
virtual SpiceRotation * instrumentRotation() const
Accessor method for the instrument rotation.
Definition: Spice.cpp:1622
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::PushFrameCamera::DetectorMap
PushFrameCameraDetectorMap * DetectorMap()
Returns a pointer to the PushFrameCameraDetectorMap object.
Definition: PushFrameCamera.h:62
Isis::CollectorMap::exists
bool exists(const K &key) const
Checks the existance of a particular key in the list.
Definition: CollectorMap.h:551
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::LroWideAngleCameraDistortionMap::addFilter
void addFilter(int naifIkCode)
Add an additional set of parameters for a given LROC/WAC filter.
Definition: LroWideAngleCameraDistortionMap.cpp:55
Isis::LroWideAngleCamera::p_etStart
double p_etStart
Ephemeris Start iTime.
Definition: LroWideAngleCamera.h:102
Isis::LroWideAngleCamera::SpkReferenceId
virtual int SpkReferenceId() const
SPK Reference ID - J2000.
Definition: LroWideAngleCamera.cpp:349
Isis::LroWideAngleCameraDistortionMap::setBand
void setBand(int vband)
Implements band-dependant distortion parameters.
Definition: LroWideAngleCameraDistortionMap.cpp:79
Isis::LroWideAngleCameraFocalPlaneMap
Distort/undistort focal plane coordinates.
Definition: LroWideAngleCameraFocalPlaneMap.h:33
Isis::LroWideAngleCamera::PoolKeySize
int PoolKeySize(const QString &key) const
Definition: LroWideAngleCamera.cpp:268
Isis::LroWideAngleCameraFocalPlaneMap::setBand
void setBand(int vband)
Implements band-dependant focal plane parameters.
Definition: LroWideAngleCameraFocalPlaneMap.cpp:86
Isis::PushFrameCamera
Generic class for Push Frame Cameras.
Definition: PushFrameCamera.h:35
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::SetStartingDetectorSample
void SetStartingDetectorSample(const double sample)
Set the starting detector sample.
Definition: CameraDetectorMap.h:79
Isis::CollectorMap::add
void add(const K &key, const T &value)
Adds the element to the list.
Definition: CollectorMap.h:540
Isis::toDouble
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:149
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::CollectorMap
Collector/container for arbitrary items.
Definition: CollectorMap.h:419
Isis::LroWideAngleCamera::SetBand
void SetBand(const int band)
Sets the band in the camera model.
Definition: LroWideAngleCamera.cpp:231
Isis::Cube::label
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1701
Isis::CameraSkyMap
Convert between undistorted focal plane and ra/dec coordinates.
Definition: CameraSkyMap.h:31
Isis::PushFrameCameraDetectorMap::SetBandFirstDetectorLine
void SetBandFirstDetectorLine(int firstLine)
Change the starting line in the detector based on band.
Definition: PushFrameCameraDetectorMap.cpp:308
Isis::PvlKeyword::size
int size() const
Returns the number of values stored in this keyword.
Definition: PvlKeyword.h:125
Isis::LroWideAngleCamera
LRO Wide Angle Camera Model.
Definition: LroWideAngleCamera.h:85
Isis::LroWideAngleCameraFocalPlaneMap::addFilter
void addFilter(int naifIkCode)
Add an additional set of parameters for a given LROC/WAC filter.
Definition: LroWideAngleCameraFocalPlaneMap.cpp:55
Isis::PvlObject::findKeyword
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:177
Isis::LroWideAngleCamera::CkReferenceId
virtual int CkReferenceId() const
CK Reference ID - J2000.
Definition: LroWideAngleCamera.cpp:337
Isis::Spice::getDouble
SpiceDouble getDouble(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition: Spice.cpp:1039
QVector< int >
Isis::SpiceRotation::SetFrame
void SetFrame(int frameCode)
Change the frame to the given frame code.
Definition: SpiceRotation.cpp:214
Isis::PushFrameCameraGroundMap
Convert between undistorted focal plane and ground coordinates.
Definition: PushFrameCameraGroundMap.h:34
Isis::Camera::m_spacecraftNameShort
QString m_spacecraftNameShort
Shortened spacecraft name.
Definition: Camera.h:499
Isis::PushFrameCameraDetectorMap
Convert between parent image coordinates and detector coordinates.
Definition: PushFrameCameraDetectorMap.h:45
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::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
Isis::LroWideAngleCamera::p_nframelets
int p_nframelets
Number of framelets in whole image.
Definition: LroWideAngleCamera.h:104