8 #include "LineScanCameraGroundMap.h"
16 #include <QTextStream>
18 #include "IException.h"
21 #include "CameraDistortionMap.h"
22 #include "CameraFocalPlaneMap.h"
24 #include "LineScanCameraDetectorMap.h"
27 #include "Longitude.h"
28 #include "Statistics.h"
29 #include "SurfacePoint.h"
30 #include "FunctionTools.h"
44 public std::unary_function<double, double > {
49 m_surfacePoint = surPt;
65 double lookC[3] = {0.0, 0.0, 0.0};
72 double startTime = m_camera->cacheStartTime().Et();
73 double endTime = m_camera->cacheEndTime().Et();
74 if (et < startTime || et > endTime) {
75 IString msg =
"Ephemeris time passed to LineOffsetFunctor is not within the image "
77 throw IException(IException::Programmer, msg, _FILEINFO_);
80 m_camera->Sensor::setTime(et);
83 if (!m_camera->Sensor::SetGround(m_surfacePoint,
false)) {
84 IString msg =
"Sensor::SetGround failed for surface point in LineScanCameraGroundMap.cpp"
86 throw IException(IException::Programmer, msg, _FILEINFO_);
90 m_camera->Sensor::LookDirection(lookC);
91 ux = m_camera->FocalLength() * lookC[0] / lookC[2];
92 uy = m_camera->FocalLength() * lookC[1] / lookC[2];
115 if (m_camera->DistortionMap()->SetUndistortedFocalPlane(ux, uy)) {
117 dx = m_camera->DistortionMap()->FocalPlaneX();
118 dy = m_camera->DistortionMap()->FocalPlaneY();
125 if (!m_camera->FocalPlaneMap()->SetFocalPlane(dx, dy)) {
126 IString msg =
"FocalPlaneMap::SetFocalPlane failed for surface point in "
127 "LineScanCameraGroundMap.cpp LineOffsetFunctor";
128 throw IException(IException::Programmer, msg, _FILEINFO_);
132 return (m_camera->FocalPlaneMap()->DetectorLineOffset() -
133 m_camera->FocalPlaneMap()->DetectorLine());
149 public std::unary_function<double, double > {
154 surfacePoint = surPt;
161 double operator()(
double et) {
165 double startTime = m_camera->cacheStartTime().Et();
166 double endTime = m_camera->cacheEndTime().Et();
168 if (et < startTime || et > endTime) {
169 IString msg =
"Ephemeris time passed to SensorSurfacePointDistanceFunctor is not within the image "
171 throw IException(IException::Programmer, msg, _FILEINFO_);
173 m_camera->Sensor::setTime(et);
174 if (!m_camera->Sensor::SetGround(surfacePoint,
false)) {
175 IString msg =
"Sensor::SetGround failed for surface point in LineScanCameraGroundMap.cpp"
176 "SensorSurfacePointDistanceFunctor";
178 m_camera->instrumentPosition(s);
179 m_camera->Coordinate(p);
180 return sqrt((s[0] - p[0]) * (s[0] - p[0]) +
181 (s[1] - p[1]) * (s[1] - p[1]) +
182 (s[2] - p[2]) * (s[2] - p[2]) );
234 FindFocalPlaneStatus status = FindFocalPlane(approxLine, surfacePoint);
235 if (status == Success)
return true;
248 FindFocalPlaneStatus status = FindFocalPlane(-1, surfacePoint);
250 if (status == Success)
return true;
256 double LineScanCameraGroundMap::FindSpacecraftDistance(
int line,
261 if (!
p_camera->Sensor::SetGround(surfacePoint,
false)) {
269 LineScanCameraGroundMap::FindFocalPlaneStatus
270 LineScanCameraGroundMap::FindFocalPlane(
const int &approxLine,
276 double approxTime = 0;
277 double approxOffset = 0;
278 double lookC[3] = {0.0, 0.0, 0.0};
283 const double cacheStart =
p_camera->Spice::cacheStartTime().Et();
284 const double cacheEnd =
p_camera->Spice::cacheEndTime().Et();
288 if (lineRate == 0.0)
return Failure;
295 if (approxLine >= 0.5) {
301 approxOffset = offsetFunc(approxTime);
304 if (fabs(approxOffset) < 1e-2) {
305 p_camera->Sensor::setTime(approxTime);
307 if (!
p_camera->Sensor::SetGround(surfacePoint,
true)) {
310 p_camera->Sensor::LookDirection(lookC);
320 double fl, fh, xl, xh;
324 if (xh + lineRate < cacheEnd) {
336 for (
int j=0; j < 10; j++) {
340 double etGuess = xl + (xh - xl) * fl / (fl - fh);
342 if (etGuess < cacheStart) etGuess = cacheStart;
343 if (etGuess > cacheEnd) etGuess = cacheEnd;
345 double f = offsetFunc(etGuess);
349 if (fabs( xl- etGuess) > fabs( xh - etGuess)) {
359 if (fabs(f) < 1e-2) {
360 p_camera->Sensor::setTime(approxTime);
362 if (!
p_camera->Sensor::SetGround(surfacePoint,
true)) {
365 p_camera->Sensor::LookDirection(lookC);
385 double offsetNodes[3];
393 timeNodes[0] = cacheStart;
394 timeNodes[2] = cacheEnd;
395 timeNodes[1] = (cacheStart+cacheEnd) / 2.0;
400 for (
int i=0; i<3; i++) {
401 offsetNodes[i] = offsetFunc(timeNodes[i]);
405 timeAverage = (timeNodes[0] + timeNodes[1] + timeNodes[2]) / 3.0;
406 timeNodes[0] -= timeAverage;
407 timeNodes[1] -= timeAverage;
408 timeNodes[2] -= timeAverage;
410 scale = 1.0 / sqrt((timeNodes[0] - timeNodes[2]) *
411 (timeNodes[0] - timeNodes[2]) +
412 (offsetNodes[0] - offsetNodes[2]) *
413 (offsetNodes[0] - offsetNodes[2]));
415 timeNodes[0] *= scale;
416 timeNodes[1] *= scale;
417 timeNodes[2] *= scale;
419 offsetNodes[0] *= scale;
420 offsetNodes[1] *= scale;
421 offsetNodes[2] *= scale;
426 quadPoly[0] = quadPoly[1] = quadPoly[2] = 0.0;
428 temp = offsetNodes[0] / ((timeNodes[0] - timeNodes[1]) * (timeNodes[0] - timeNodes[2]));
430 quadPoly[1] += temp * (-timeNodes[1] - timeNodes[2]);
431 quadPoly[2] += temp * timeNodes[1] * timeNodes[2];
433 temp = offsetNodes[1] / ((timeNodes[1] - timeNodes[0]) * (timeNodes[1] - timeNodes[2]));
435 quadPoly[1] += temp * (-timeNodes[0] - timeNodes[2]);
436 quadPoly[2] += temp * timeNodes[0] * timeNodes[2];
438 temp = offsetNodes[2] / ((timeNodes[2] - timeNodes[0]) * (timeNodes[2] - timeNodes[1]));
440 quadPoly[1] += temp * (-timeNodes[0] - timeNodes[1]);
441 quadPoly[2] += temp * timeNodes[0] * timeNodes[1];
445 temp = quadPoly[1] * quadPoly[1] - 4.0 * quadPoly[0] * quadPoly[2];
452 if (quadPoly[1] >= 0.0) {
453 temp = -0.5 * (quadPoly[1] + sqrt(temp));
456 temp = -0.5 * (quadPoly[1] - sqrt(temp));
459 if (quadPoly[0] != 0.0) {
460 root.push_back(temp/quadPoly[0]);
463 if (quadPoly[2] != 0.0) {
464 root.push_back(quadPoly[2]/temp);
468 for (
int i=root.size()-1; i>=0; i--) {
469 if ( root[i] < timeNodes[0] || root[i] > timeNodes[2] ) {
475 for (
int i=0; i<root.size(); i++) {
476 root[i] = root[i]/scale + timeAverage;
480 if (root.size() == 0) {
490 for (
int i=0; i<root.size(); i++) {
491 dist << distanceFunc(root[i]);
492 offset << offsetFunc(root[i]);
498 for (
int i=1; i<root.size(); i++) {
499 if (dist[i] < dist[j]) j=i;
502 approxTime = root[j];
503 approxOffset = offset[j];
506 if (fabs(approxOffset) < 1.0e-2) {
507 p_camera->Sensor::setTime(approxTime);
510 if (!
p_camera->Sensor::SetGround(surfacePoint,
true)) {
514 p_camera->Sensor::LookDirection(lookC);
543 for (
int i=0; i<3; i++) {
545 pt << timeNodes[i] / scale + timeAverage;
546 pt << offsetNodes[i] / scale;
550 for (
int i=0; i<root.size(); i++) {
557 qSort(pts.begin(), pts.end(), ptXLessThan);
560 for (
int i=1; i<pts.size(); i++) {
562 if ( (pts[i-1][1] > 0) - (pts[i-1][1] < 0) != (pts[i][1] > 0) - (pts[i][1] < 0) ) {
564 if (FunctionTools::brentsRootFinder <LineOffsetFunctor> (offsetFunc, pts[i-1], pts[i],
565 1.0e-3, 200, temp)) {
572 for (
int i = root.size()-1; i>=0; i--) {
575 if (!
p_camera->Sensor::SetGround(surfacePoint,
true)) {
581 if (root.size() == 0) {
588 for (
int i=0; i<root.size(); i++) {
589 dist << distanceFunc(root[i]);
590 offset << offsetFunc(root[i]);
596 for (
int i=1; i<root.size(); i++) {
597 if (dist[i] < dist[j]) j=i;
604 p_camera->Sensor::LookDirection(lookC);
617 return l1[0] < l2[0];