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
29using namespace std;
30namespace Isis {
42 PushFrameCamera(cube) {
43
45
46 m_spacecraftNameLong = "Lunar Reconnaissance Orbiter";
48
49 // Set up the camera characteristics
50 instrumentRotation()->SetFrame(naifIkCode());
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);
175 dmap->SetFrameletsGeometricallyFlipped(false);
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
196 for ( int i = 0 ; i < filtNames.size() ; i++ ) {
197 fplane->addFilter(filterIKCode.get(filtNames[i].toInt()));
198 distort->addFilter(filterIKCode.get(filtNames[i].toInt()));
199 }
200
201 // Setup the ground and sky map
202 bool evenFramelets = (inst["Framelets"][0].toUpper() == "EVEN");
203 new PushFrameCameraGroundMap(this, evenFramelets);
204 new CameraSkyMap(this);
205
206 SetBand(1);
207 LoadCache();
209
210 if(instId == "WAC-UV") {
211 // geometric tiling is not worth trying for 4-line framelets
213 }
214 else {
216 }
217 }
218
219
220
224
225
226
232 void LroWideAngleCamera::SetBand(const int vband) {
233
234 // Sanity check on requested band
235 int maxVirtualBands = min(p_detectorStartLines.size(), p_frameletOffsets.size());
236 if (((vband <= 0) || (vband > maxVirtualBands)) && (vband > Bands())) {
237 ostringstream mess;
238 mess << "Requested virtual band (" << vband
239 << ") outside valid (BandBin/Center) limits (1 - " << maxVirtualBands
240 << ")";
241 throw IException(IException::Programmer, mess.str(), _FILEINFO_);
242 }
243
244 // Set up valid band access
245 Camera::SetBand(vband);
246 if ((vband > maxVirtualBands) && (vband <= Bands())) {
247 // probably switching to a band from phocube or similar
248 // instead of a different filter band, so just re-use the
249 // properties from the current band.
250 return;
251 }
252
253 PushFrameCameraDetectorMap *dmap = NULL;
255 dmap->SetBandFirstDetectorLine(p_detectorStartLines.at(vband - 1));
256 dmap->SetFrameletOffset(p_frameletOffsets.at(vband - 1));
257
258 SetFocalLength(p_focalLength.at(vband-1));
259
261 fplane->setBand(vband);
262 fplane->SetDetectorOrigin(p_boreSightSample.at(vband-1) + 1.0,
263 p_boreSightLine.at(vband-1) + 1.0);
264
266 distort->setBand(vband);
267 return;
268 }
269
270
271
276 int LroWideAngleCamera::PoolKeySize(const QString &key) const {
277 SpiceBoolean found;
278 SpiceInt n;
279 SpiceChar ctype[1];
280 dtpool_c(key.toLatin1().data(), &found, &n, ctype);
281 if (!found) n = 0;
282 return (n);
283 }
284
285
286
292 QVariant poolKeySize = getStoredResult(key + "_SIZE", SpiceIntType);
293
294 int nvals = poolKeySize.toInt();
295
296 if (nvals == 0) {
297 nvals = PoolKeySize(key);
298 storeResult(key + "_SIZE", SpiceIntType, nvals);
299 }
300
301 if (nvals <= 0) {
302 PvlObject NaifKeywords = getStoredNaifKeywords();
303 if (!NaifKeywords.hasKeyword(key)){
304 QString mess = "Kernel pool keyword " + key + " not found!";
305 throw IException(IException::Programmer, mess, _FILEINFO_);
306 }
307 PvlKeyword kw = NaifKeywords[key];
308 IntParameterList parms;
309 for (int i = 0; i<kw.size(); i++){
310 parms.push_back(toInt(kw[i]));
311 }
312 return parms;
313 }
314
315 IntParameterList parms;
316 for (int i = 0 ; i < nvals ; i++) {
317 parms.push_back(getInteger(key, i));
318 }
319
320 return (parms);
321 }
322
323
324
331 // only band independant if there is one filter
332 // band on the image
333 return p_frameletOffsets.size() == 1;
334 }
335
336
337
345 return (-85000);
346 }
347
348
349
357 return (1);
358 }
359
360
361
369 return (1);
370 }
371}
372
373
374// Plugin
385extern "C" Isis::Camera *LroWideAngleCameraPlugin(Isis::Cube &cube) {
386 return new Isis::LroWideAngleCamera(cube);
387}
void SetDetectorOrigin(const double sample, const double line)
Set the detector origin.
QString m_spacecraftNameLong
Full spacecraft name.
Definition Camera.h:499
int ParentLines() const
Returns the number of lines in the parent alphacube.
Definition Camera.cpp:2836
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:2584
void SetFocalLength()
Reads the focal length from the instrument kernel.
Definition Camera.cpp:1422
void SetPixelPitch()
Reads the Pixel Pitch from the instrument kernel.
Definition Camera.cpp:1429
void LoadCache()
This loads the spice cache big enough for this image.
Definition Camera.cpp:2450
QString m_instrumentNameShort
Shortened instrument name.
Definition Camera.h:498
CameraDistortionMap * DistortionMap()
Returns a pointer to the CameraDistortionMap object.
Definition Camera.cpp:2856
QString m_spacecraftNameShort
Shortened spacecraft name.
Definition Camera.h:500
CameraFocalPlaneMap * FocalPlaneMap()
Returns a pointer to the CameraFocalPlaneMap object.
Definition Camera.cpp:2866
virtual void SetBand(const int band)
Virtual method that sets the band number.
Definition Camera.cpp:2710
QString m_instrumentNameLong
Full instrument name.
Definition Camera.h:497
int Bands() const
Returns the number of bands in the image.
Definition Camera.cpp:2826
Convert between undistorted focal plane and ra/dec coordinates.
IO Handler for Isis Cubes.
Definition Cube.h:168
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition Cube.cpp:1707
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Distort/undistort focal plane coordinates.
Distort/undistort focal plane coordinates.
LRO Wide Angle Camera Model.
bool IsBandIndependent()
The camera model is band dependent, so this method returns false.
virtual int CkFrameId() const
CK frame ID - - Instrument Code from spacit run on CK.
IntParameterList GetVector(const QString &key)
double p_etStart
Ephemeris Start iTime.
int PoolKeySize(const QString &key) const
virtual int CkReferenceId() const
CK Reference ID - J2000.
void SetBand(const int band)
Sets the band in the camera model.
LroWideAngleCamera(Cube &cube)
Constructor for the LRO WAC Camera Model.
virtual int SpkReferenceId() const
SPK Reference ID - J2000.
double p_exposureDur
Exposure Duration value from labels.
int p_nframelets
Number of framelets in whole image.
~LroWideAngleCamera()
Destroys the LroWideAngleCamera object.
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Convert between parent image coordinates and detector coordinates.
void SetBandFirstDetectorLine(int firstLine)
Change the starting line in the detector based on band.
Convert between undistorted focal plane and ground coordinates.
Generic class for Push Frame Cameras.
PushFrameCameraDetectorMap * DetectorMap()
Returns a pointer to the PushFrameCameraDetectorMap object.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
A single keyword-value pair.
Definition PvlKeyword.h:87
int size() const
Returns the number of values stored in this keyword.
Definition PvlKeyword.h:133
Contains Pvl Groups and Pvl Objects.
Definition PvlObject.h:61
@ Traverse
Search child objects.
Definition PvlObject.h:158
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:1060
@ SpiceIntType
SpiceInt type.
Definition Spice.h:351
PvlObject getStoredNaifKeywords() const
This returns the PvlObject that stores all of the requested Naif data and can be a replacement for fu...
Definition Spice.cpp:1005
virtual SpiceRotation * instrumentRotation() const
Accessor method for the instrument rotation.
Definition Spice.cpp:1634
SpiceInt naifIkCode() const
This returns the NAIF IK code to use when reading from instrument kernels.
Definition Spice.cpp:975
SpiceDouble getDouble(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition Spice.cpp:1046
SpiceInt getInteger(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition Spice.cpp:1032
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition IString.cpp:93
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition IString.cpp:149
Namespace for the standard library.