Isis 3 Programmer Reference
VimsSkyMap.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "VimsSkyMap.h"
10
11#include <iostream>
12#include <iomanip>
13
14#include <QDebug>
15
16#include "Camera.h"
17#include "FileName.h"
18#include "IException.h"
19#include "IString.h"
20#include "iTime.h"
21#include "LeastSquares.h"
22#include "PolynomialBivariate.h"
23#include "Preference.h"
24#include "SpecialPixel.h"
25
26using namespace std;
27
28namespace Isis {
38 CameraSkyMap(parent) {
39 }
40
41
58 void VimsSkyMap::Init(Pvl &lab) {
59 PvlGroup inst = lab.findGroup("Instrument", Pvl::Traverse);
60
61 // Vis or IR
62 p_channel = (QString) inst ["Channel"];
63 // Get the start time in et
64 QString stime = (QString) inst ["NativeStartTime"];
65 QString intTime = stime.split(".").first();
66 stime = stime.split(".").last();
67
68 p_etStart = p_camera->getClockTime(intTime).Et();
69 p_etStart += toDouble(stime) / 15959.0;
70
71 //----------------------------------------------------------------------
72 // Because of inaccuracy with the 15 Mhz clock, the IR exposure and
73 // interline delay need to be adjusted.
74 //----------------------------------------------------------------------
75 p_irExp = (toDouble(inst ["ExposureDuration"][0]) * 1.01725) / 1000.;
76 p_visExp = toDouble(inst ["ExposureDuration"][1]) / 1000.;
77 p_interlineDelay = (toDouble(inst ["InterlineDelayDuration"]) * 1.01725) / 1000.;
78
79 // Get summation mode
80 QString sampMode = QString((QString)inst ["SamplingMode"]).toUpper();
81
82 // Get sample/line offsets
83 int sampOffset = inst ["XOffset"];
84 int lineOffset = inst ["ZOffset"];
85
86 // Get swath width/length which will be image size unless occultation image
87 p_swathWidth = inst ["SwathWidth"];
88 p_swathLength = inst ["SwathLength"];
89
90 if (p_channel == "VIS") {
91 if (sampMode == "NORMAL") {
92 p_xPixSize = p_yPixSize = 0.00051;
93 p_xBore = p_yBore = 31;
94 p_camSampOffset = sampOffset - 1;
95 p_camLineOffset = lineOffset - 1;
96
97 }
98 else if (sampMode == "HI-RES") {
99 p_xPixSize = p_yPixSize = 0.00051 / 3.0;
100 p_xBore = p_yBore = 94;
101 //New as of 2009-08-04 per Dyer Lytle's email
102 // Old Values:p_camSampOffset = 3 * (sampOffset - 1) + p_swathWidth;
103 // p_camLineOffset = 3 * (lineOffset - 1) + p_swathLength;
104 p_camSampOffset = (3 * (sampOffset + p_swathWidth / 2)) - p_swathWidth / 2;
105 p_camLineOffset = (3 * (lineOffset + p_swathLength / 2)) - p_swathLength / 2;
106 }
107 else {
108 string msg = "Unsupported SamplingMode [" + IString(sampMode) + "]";
109 throw IException(IException::Programmer, msg, _FILEINFO_);
110 }
111 }
112 else if (p_channel == "IR") {
113 if (sampMode == "NORMAL") {
114 p_xPixSize = p_yPixSize = 0.000495;
115 p_xBore = p_yBore = 31;
116 p_camSampOffset = sampOffset - 1;
117 p_camLineOffset = lineOffset - 1;
118 }
119 else if (sampMode == "HI-RES") {
120 p_xPixSize = 0.000495 / 2.0;
121 p_yPixSize = 0.000495;
122 p_xBore = 62.5;
123 p_yBore = 31;
124 p_camSampOffset = 2 * ((sampOffset - 1) + ((p_swathWidth - 1) / 4));
125 p_camLineOffset = lineOffset - 1;
126 }
127 else {
128 string msg = "Unsupported SamplingMode [" + IString(sampMode) + "]";
129 throw IException(IException::Programmer, msg, _FILEINFO_);
130 }
131 }
132
133 // Calculate ra/dec maps
134 for(int line = 0; line < p_camera->ParentLines(); line++) {
135 for(int samp = 0; samp < p_camera->ParentSamples(); samp++) {
136 p_raMap[line][samp] = Isis::NULL8;
137 p_decMap[line][samp] = Isis::NULL8;
138 }
139 }
140
141 //---------------------------------------------------------------------
142 // Loop for each pixel in cube, get pointing information and calculate
143 // control point (line,sample,lat,lon) for later use in latlon_to_linesamp.
144 //---------------------------------------------------------------------
145 p_minRa = 99999.;
146 p_minDec = 99999.;
147 p_maxRa = -99999.;
148 p_maxDec = -99999.;
149
151 for(int line = 0; line < p_camera->ParentLines(); line++) {
152
153 // VIS exposure is for a single line. According to SIS,
154 // NATIVE_START_TIME is for the first pixel of the IR exposure.
155 // "The offset from IR start to VIS start is calculated by
156 // IrExposMsec - VisExposMsec)/2".
157 // This needs to be moved to forward routine
158
159 if(p_channel == "VIS") {
160 double et = ((double)p_etStart + (((p_irExp * p_swathWidth) - p_visExp) / 2.)) +
161 ((line + 0.5) * p_visExp);
162 p_camera->setTime(et);
163 }
164
165 for(int samp = 0; samp < p_camera->ParentSamples(); samp++) {
166 if(p_channel == "IR") {
167 double et = (double)p_etStart +
168 (line * p_camera->ParentSamples() * p_irExp) +
169 (line * p_interlineDelay) + ((samp + 0.5) * p_irExp);
170 p_camera->setTime(et);
171 }
172
173 p_camera->SetImage((double) samp + 1, (double)line + 1);
174 double ra = p_camera->RightAscension();
175 double dec = p_camera->Declination();
176 if(ra < p_minRa) p_minRa = ra;
177 if(ra > p_maxRa) p_maxRa = ra;
178 if(dec < p_minDec) p_minDec = dec;
179 if(dec > p_maxDec) p_maxDec = dec;
180 p_raMap[line][samp] = ra;
181 p_decMap[line][samp] = dec;
182 }
183 }
185
186 }
187
188
201 bool VimsSkyMap::SetFocalPlane(const double ux, const double uy,
202 const double uz) {
203 p_ux = ux;
204 p_uy = uy;
205 p_uz = uz;
206
207 double imgSamp = ux;
208 double imgLine = uy;
209
210 if((imgLine < 0.5) || (imgLine > p_camera->ParentLines() + 0.5) ||
211 (imgSamp < 0.5) || (imgSamp > p_camera->ParentSamples() + 0.5)) {
212 return false;
213 }
214 imgLine--;
215 imgSamp--;
216
217 // does interline_delay & exposure-duration account for summing modes?
218 // if not, won't use p_parentLine/p_parentSample
219 double et = 0.;
220 if(p_channel == "VIS") {
221 et = (p_etStart + ((p_irExp * p_swathWidth) - p_visExp) / 2.) +
222 ((imgLine + 0.5) * p_visExp);
223 }
224 else if(p_channel == "IR") {
225 et = (double)p_etStart +
226 (imgLine * p_camera->ParentSamples() * p_irExp) +
227 (imgLine * p_interlineDelay) + ((imgSamp + 0.5) * p_irExp);
228 }
229 p_camera->setTime(et);
230
231 SpiceDouble lookC[3];
232 LookDirection(lookC);
233
234 SpiceDouble unitLookC[3];
235 vhat_c(lookC, unitLookC);
236 return p_camera->SetLookDirection(unitLookC);
237 }
238
247 bool VimsSkyMap::SetSky(const double ra, const double dec) {
248 if(ra < p_minRa || ra > p_maxRa ||
249 dec < p_minDec || dec > p_maxDec) {
250 return false;
251 }
252 // Find closest points ??? what tolerance ???
253 double minDist = 9999.;
254 int minSamp = -1;
255 int minLine = -1;
256
257 for(int line = 0; line < p_camera->ParentLines(); line++) {
258
259 for(int samp = 0; samp < p_camera->ParentSamples(); samp++) {
260 double mapRa = p_raMap[line][samp];
261 if(mapRa == Isis::NULL8) continue;
262 double mapDec = p_decMap[line][samp];
263 if(mapDec == Isis::NULL8) continue;
264 // If on boundary convert lons. If trying to find 360, convert
265 // lons on other side of meridian to values greater than 360. If
266 // trying to find 1.0, convert lons on other side to negative numbers.
267 if(abs(mapRa - ra) > 180) {
268 if((ra - mapRa) > 0) {
269 mapRa = 360. + mapRa;
270 }
271 else if((ra - mapRa) < 0) {
272 mapRa = mapRa - 360.;
273 }
274 }
275 double dist = ((ra - mapRa) * (ra - mapRa)) +
276 ((dec - mapDec) * (dec - mapDec));
277 if(dist < minDist) {
278 minDist = dist;
279 minSamp = samp;
280 minLine = line;
281 }
282 }
283 }
284
285 //-----------------------------------------------------------------
286 // If dist is less than some ??? tolerance ??? this is the
287 // closest point. Use this point and surrounding 8 pts as
288 // control pts.
289 //----------------------------------------------------------------
290 if(minDist >= 9999.) return false;
291
292 //-------------------------------------------------------------
293 // Set-up for LU decomposition (least2 fit).
294 // Assume we will have 9 control points, this may not be true
295 // and will need to be adjusted before the final solution.
296 //-------------------------------------------------------------
297 PolynomialBivariate sampBasis(1);
298 PolynomialBivariate lineBasis(1);
299 LeastSquares sampLsq(sampBasis);
300 LeastSquares lineLsq(lineBasis);
301 vector<double> known(2);
302
303 for(int line = minLine - 1; line < minLine + 2; line++) {
304 if(line < 0 || line > p_camera->ParentLines() - 1) continue;
305 for(int samp = minSamp - 1; samp < minSamp + 2; samp++) {
306 // Check for edges
307 if(samp < 0 || samp > p_camera->ParentSamples() - 1) continue;
308
309 double mapRa = p_raMap[line][samp];
310 double mapDec = p_decMap[line][samp];
311 if((mapRa == Isis::NULL8) || (mapDec == Isis::NULL8)) continue;
312
313 // If on boundary convert lons. If trying to find 360, convert
314 // lons on other side of meridian to values greater than 360. If
315 // trying to find 1.0, convert lons on other side to negative numbers.
316 if(abs(mapRa - ra) > 180) {
317 if((ra - mapRa) > 0) {
318 mapRa = 360. + mapRa;
319 }
320 else if((ra - mapRa) < 0) {
321 mapRa = mapRa - 360.;
322 }
323 }
324
325 known[0] = mapDec;
326 known[1] = mapRa;
327 sampLsq.AddKnown(known, samp + 1);
328 lineLsq.AddKnown(known, line + 1);
329 }
330 }
331 if(sampLsq.Knowns() < 3) return false;
332
333 sampLsq.Solve();
334 lineLsq.Solve();
335
336 // Solve for new sample position
337 known[0] = dec;
338 known[1] = ra;
339 double inSamp = sampLsq.Evaluate(known);
340 double inLine = lineLsq.Evaluate(known);
341
342 if(inSamp < 0 || inSamp > p_camera->ParentSamples() + 0.5 ||
343 inLine < 0 || inLine > p_camera->ParentLines() + 0.5) {
344 return false;
345 }
346
348 p_camera->SetImage(inSamp, inLine);
350 p_focalPlaneX = inSamp;
351 p_focalPlaneY = inLine;
352
353 return true;
354 }
355
356
372 void VimsSkyMap::LookDirection(double v[3]) {
373 double x = p_ux - 1. + p_camSampOffset;
374 double y = p_uy - 1. + p_camLineOffset;
375
376 // Compute pointing angles based on pixel size separation
377 double theta = Isis::HALFPI - (y - p_yBore) * p_yPixSize;
378 double phi = (-1. * Isis::HALFPI) + (x - p_xBore) * p_xPixSize;
379
380 v[0] = sin(theta) * cos(phi);
381 v[1] = cos(theta);
382 v[2] = sin(theta) * sin(phi) / -1.;
383 }
384}
int ParentLines() const
Returns the number of lines in the parent alphacube.
Definition Camera.cpp:2836
void IgnoreProjection(bool ignore)
Set whether or not the camera should ignore the Projection.
Definition Camera.cpp:2955
int ParentSamples() const
Returns the number of samples in the parent alphacube.
Definition Camera.cpp:2846
virtual bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
Definition Camera.cpp:156
Convert between undistorted focal plane and ra/dec coordinates.
Camera * p_camera
The main camera to calculate distortions on.
double p_focalPlaneY
Undistorted y value for the focal plane.
double p_focalPlaneX
Undistorted x value for the focal plane.
Isis exception class.
Definition IException.h:91
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Adds specific functionality to C++ strings.
Definition IString.h:165
Generic least square fitting class.
Nth degree Polynomial with two variables.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
@ Traverse
Search child objects.
Definition PvlObject.h:158
void setTime(const iTime &time)
By setting the time you essential set the position of the spacecraft and body as indicated in the cla...
Definition Sensor.cpp:99
virtual double RightAscension()
Returns the right ascension angle (sky longitude).
Definition Sensor.cpp:565
virtual double Declination()
Returns the declination angle (sky latitude).
Definition Sensor.cpp:578
bool SetLookDirection(const double v[3])
Sets the look direction of the spacecraft.
Definition Sensor.cpp:143
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
double p_decMap[64][64]
Declination map.
Definition VimsSkyMap.h:94
int p_camSampOffset
Sample offset.
Definition VimsSkyMap.h:86
double p_minRa
Minimum right ascension.
Definition VimsSkyMap.h:89
double p_maxDec
Maximum declination.
Definition VimsSkyMap.h:92
double p_xPixSize
X pixel size.
Definition VimsSkyMap.h:73
VimsSkyMap(Camera *parent, Pvl &lab)
Constructs the VimsSkyMap object.
void Init(Pvl &lab)
Initialize vims sky model.
double p_ux
Distorted focal plane x, in millimeters.
Definition VimsSkyMap.h:69
double p_yBore
Y boresight.
Definition VimsSkyMap.h:76
double p_interlineDelay
InterlineDelayDuration keyword value from the instrument group of the labels, divided by 1000.
Definition VimsSkyMap.h:67
void LookDirection(double v[3])
Determines the look direction in the camera coordinate system.
QString p_channel
Channel keyword value from the instrument group of the labels.
Definition VimsSkyMap.h:78
double p_uz
Distorted focal plane z, in millimeters.
Definition VimsSkyMap.h:71
double p_maxRa
Maximum right ascension.
Definition VimsSkyMap.h:90
double p_raMap[64][64]
Right ascension map.
Definition VimsSkyMap.h:93
double p_visExp
VIS exposure duration, divided by 1000.
Definition VimsSkyMap.h:80
double p_irExp
IR exposure duration, divided by 1000.
Definition VimsSkyMap.h:81
int p_swathLength
SwathLength keyword value from the instrument group of the labels.
Definition VimsSkyMap.h:84
double p_xBore
X boresight.
Definition VimsSkyMap.h:75
double p_minDec
Minimum declination.
Definition VimsSkyMap.h:91
double p_yPixSize
Y pixel size.
Definition VimsSkyMap.h:74
SpiceDouble p_etStart
Start ephemeris time.
Definition VimsSkyMap.h:65
virtual bool SetSky(const double ra, const double dec)
Sets the sky position to the given ra and dec.
virtual bool SetFocalPlane(const double ux, const double uy, const double uz)
Compute ground position from focal plane coordinate.
int p_swathWidth
SwathWidth keyword value from the instrument group of the labels.
Definition VimsSkyMap.h:82
double p_uy
Distorted focal plane y, in millimeters.
Definition VimsSkyMap.h:70
int p_camLineOffset
Line offset.
Definition VimsSkyMap.h:87
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
const double HALFPI
The mathematical constant PI/2.
Definition Constants.h:41
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition IString.cpp:149
Namespace for the standard library.