File failed to load: https://isis.astrogeology.usgs.gov/6.0.0/Object/assets/jax/output/NativeMML/config.js
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 
26 using namespace std;
27 
28 namespace Isis {
37  VimsSkyMap::VimsSkyMap(Camera *parent, Pvl &lab) :
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 
150  p_camera->IgnoreProjection(true);
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  }
184  p_camera->IgnoreProjection(false);
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 
347  p_camera->IgnoreProjection(true);
348  p_camera->SetImage(inSamp, inLine);
349  p_camera->IgnoreProjection(false);
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 }
Isis::VimsSkyMap::p_maxDec
double p_maxDec
Maximum declination.
Definition: VimsSkyMap.h:92
Isis::VimsSkyMap::p_uz
double p_uz
Distorted focal plane z, in millimeters.
Definition: VimsSkyMap.h:71
Isis::Camera::IgnoreProjection
void IgnoreProjection(bool ignore)
Set whether or not the camera should ignore the Projection.
Definition: Camera.cpp:2925
Isis::HALFPI
const double HALFPI
The mathematical constant PI/2.
Definition: Constants.h:41
Isis::VimsSkyMap::p_etStart
SpiceDouble p_etStart
Start ephemeris time.
Definition: VimsSkyMap.h:65
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::CameraSkyMap::p_focalPlaneX
double p_focalPlaneX
Undistorted x value for the focal plane.
Definition: CameraSkyMap.h:59
Isis::VimsSkyMap::p_uy
double p_uy
Distorted focal plane y, in millimeters.
Definition: VimsSkyMap.h:70
Isis::LeastSquares::Solve
int Solve(Isis::LeastSquares::SolveMethod method=SVD)
After all the data has been registered through AddKnown, invoke this method to solve the system of eq...
Definition: LeastSquares.cpp:205
Isis::CameraSkyMap::p_camera
Camera * p_camera
The main camera to calculate distortions on.
Definition: CameraSkyMap.h:55
Isis::VimsSkyMap::p_interlineDelay
double p_interlineDelay
InterlineDelayDuration keyword value from the instrument group of the labels, divided by 1000.
Definition: VimsSkyMap.h:67
Isis::VimsSkyMap::p_decMap
double p_decMap[64][64]
Declination map.
Definition: VimsSkyMap.h:94
Isis::Camera::ParentLines
int ParentLines() const
Returns the number of lines in the parent alphacube.
Definition: Camera.cpp:2806
Isis::VimsSkyMap::p_minRa
double p_minRa
Minimum right ascension.
Definition: VimsSkyMap.h:89
Isis::Camera::SetImage
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:154
Isis::LeastSquares::Knowns
int Knowns() const
The number of knowns (or times AddKnown was invoked) linear combination of the variables.
Definition: LeastSquares.h:129
Isis::VimsSkyMap::SetSky
virtual bool SetSky(const double ra, const double dec)
Sets the sky position to the given ra and dec.
Definition: VimsSkyMap.cpp:247
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::Sensor::Declination
virtual double Declination()
Returns the declination angle (sky latitude).
Definition: Sensor.cpp:574
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::VimsSkyMap::SetFocalPlane
virtual bool SetFocalPlane(const double ux, const double uy, const double uz)
Compute ground position from focal plane coordinate.
Definition: VimsSkyMap.cpp:201
Isis::LeastSquares::Evaluate
double Evaluate(const std::vector< double > &input)
Invokes the BasisFunction Evaluate method.
Definition: LeastSquares.cpp:553
Isis::VimsSkyMap::p_yPixSize
double p_yPixSize
Y pixel size.
Definition: VimsSkyMap.h:74
Isis::Camera
Definition: Camera.h:236
Isis::Sensor::RightAscension
virtual double RightAscension()
Returns the right ascension angle (sky longitude).
Definition: Sensor.cpp:561
Isis::CameraSkyMap::p_focalPlaneY
double p_focalPlaneY
Undistorted y value for the focal plane.
Definition: CameraSkyMap.h:60
Isis::VimsSkyMap::p_xBore
double p_xBore
X boresight.
Definition: VimsSkyMap.h:75
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::VimsSkyMap::p_yBore
double p_yBore
Y boresight.
Definition: VimsSkyMap.h:76
Isis::Camera::ParentSamples
int ParentSamples() const
Returns the number of samples in the parent alphacube.
Definition: Camera.cpp:2816
Isis::VimsSkyMap::p_swathLength
int p_swathLength
SwathLength keyword value from the instrument group of the labels.
Definition: VimsSkyMap.h:84
Isis::Sensor::setTime
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:97
Isis::PolynomialBivariate
Nth degree Polynomial with two variables.
Definition: PolynomialBivariate.h:37
Isis::iTime::Et
double Et() const
Returns the ephemeris time (TDB) representation of the time as a double.
Definition: iTime.h:126
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::LeastSquares
Generic least square fitting class.
Definition: LeastSquares.h:99
Isis::VimsSkyMap::p_visExp
double p_visExp
VIS exposure duration, divided by 1000.
Definition: VimsSkyMap.h:80
Isis::VimsSkyMap::p_ux
double p_ux
Distorted focal plane x, in millimeters.
Definition: VimsSkyMap.h:69
Isis::VimsSkyMap::p_swathWidth
int p_swathWidth
SwathWidth keyword value from the instrument group of the labels.
Definition: VimsSkyMap.h:82
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::VimsSkyMap::p_maxRa
double p_maxRa
Maximum right ascension.
Definition: VimsSkyMap.h:90
Isis::VimsSkyMap::p_camSampOffset
int p_camSampOffset
Sample offset.
Definition: VimsSkyMap.h:86
Isis::VimsSkyMap::p_raMap
double p_raMap[64][64]
Right ascension map.
Definition: VimsSkyMap.h:93
Isis::VimsSkyMap::Init
void Init(Pvl &lab)
Initialize vims sky model.
Definition: VimsSkyMap.cpp:58
Isis::toDouble
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:149
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::Sensor::SetLookDirection
bool SetLookDirection(const double v[3])
Sets the look direction of the spacecraft.
Definition: Sensor.cpp:141
Isis::CameraSkyMap
Convert between undistorted focal plane and ra/dec coordinates.
Definition: CameraSkyMap.h:31
Isis::VimsSkyMap::p_xPixSize
double p_xPixSize
X pixel size.
Definition: VimsSkyMap.h:73
Isis::VimsSkyMap::p_minDec
double p_minDec
Minimum declination.
Definition: VimsSkyMap.h:91
Isis::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
Isis::VimsSkyMap::p_irExp
double p_irExp
IR exposure duration, divided by 1000.
Definition: VimsSkyMap.h:81
Isis::LeastSquares::AddKnown
void AddKnown(const std::vector< double > &input, double expected, double weight=1.0)
Invoke this method for each set of knowns.
Definition: LeastSquares.cpp:96
Isis::VimsSkyMap::p_channel
QString p_channel
Channel keyword value from the instrument group of the labels.
Definition: VimsSkyMap.h:78
Isis::VimsSkyMap::p_camLineOffset
int p_camLineOffset
Line offset.
Definition: VimsSkyMap.h:87
Isis::VimsSkyMap::LookDirection
void LookDirection(double v[3])
Determines the look direction in the camera coordinate system.
Definition: VimsSkyMap.cpp:372
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the USGS Astrogeology Discussion Board
To report a bug, or suggest a feature go to: ISIS Github
File Modified: 07/13/2023 15:17:27