9 #include "IsisBundleObservation.h"
13 #include <QStringList>
16 #include "BundleImage.h"
17 #include "BundleControlPoint.h"
18 #include "BundleObservationSolveSettings.h"
19 #include "BundleTargetBody.h"
21 #include "LinearAlgebra.h"
22 #include "SpicePosition.h"
23 #include "SpiceRotation.h"
24 #include "CameraGroundMap.h"
27 using namespace boost::numeric::ublas;
34 IsisBundleObservation::IsisBundleObservation() {
35 m_instrumentPosition = NULL;
36 m_instrumentRotation = NULL;
49 IsisBundleObservation::IsisBundleObservation(
BundleImageQsp image, QString observationNumber,
61 (image->camera()->instrumentPosition() ?
62 image->camera()->instrumentPosition() : NULL)
65 (image->camera()->instrumentRotation() ?
66 image->camera()->instrumentRotation() : NULL)
127 int nCameraAngleCoefficients =
m_solveSettings->numberCameraAngleCoefficientsSolved();
128 int nCameraPositionCoefficients =
m_solveSettings->numberCameraPositionCoefficientsSolved();
130 int nParameters = 3*nCameraPositionCoefficients + 2*nCameraAngleCoefficients;
132 nParameters += nCameraAngleCoefficients;
137 m_corrections.resize(nParameters);
138 m_corrections.clear();
142 for (
int i = 0; i < nParameters; i++) {
194 double positionBaseTime = 0.0;
195 double positiontimeScale = 0.0;
196 std::vector<double> posPoly1, posPoly2, posPoly3;
198 for (
int i = 0; i < size(); i++) {
233 double rotationBaseTime = 0.0;
234 double rotationtimeScale = 0.0;
235 std::vector<double> anglePoly1, anglePoly2, anglePoly3;
237 for (
int i = 0; i < size(); i++) {
239 SpiceRotation *spicerotation = image->camera()->instrumentRotation();
245 spicerotation->
SetPolynomial(anglePoly1, anglePoly2, anglePoly3,
262 spicerotation->
GetPolynomial(anglePoly1, anglePoly2, anglePoly3);
278 for (
int i = 0; i < size(); i++) {
280 image->camera()->bodyRotation()->setPckPolynomial(raCoefs, decCoefs, pmCoefs);
293 for (
int i = 0; i < size(); i++) {
295 image->camera()->bodyRotation()->setPckPolynomial(raCoefs, decCoefs, pmCoefs);
308 double posWeight = 0.0;
309 double velWeight = 0.0;
310 double accWeight = 0.0;
311 double angWeight = 0.0;
312 double angVelWeight = 0.0;
313 double angAccWeight = 0.0;
318 int nCamPosCoeffsSolved = 3 *
m_solveSettings->numberCameraPositionCoefficientsSolved();
320 int nCamAngleCoeffsSolved;
322 nCamAngleCoeffsSolved = 3 *
m_solveSettings->numberCameraAngleCoefficientsSolved();
325 nCamAngleCoeffsSolved = 2 *
m_solveSettings->numberCameraAngleCoefficientsSolved();
328 if (aprioriPositionSigmas.size() >= 1 && aprioriPositionSigmas.at(0) > 0.0) {
329 posWeight = aprioriPositionSigmas.at(0);
330 posWeight = 1.0 / (posWeight *posWeight * 1.0e-6);
332 if (aprioriPositionSigmas.size() >= 2 && aprioriPositionSigmas.at(1) > 0.0) {
333 velWeight = aprioriPositionSigmas.at(1);
334 velWeight = 1.0 / (velWeight *velWeight * 1.0e-6);
336 if (aprioriPositionSigmas.size() >= 3 && aprioriPositionSigmas.at(2) > 0.0) {
337 accWeight = aprioriPositionSigmas.at(2);
338 accWeight = 1.0 / (accWeight *accWeight * 1.0e-6);
341 if (aprioriPointingSigmas.size() >= 1 && aprioriPointingSigmas.at(0) > 0.0) {
342 angWeight = aprioriPointingSigmas.at(0);
345 if (aprioriPointingSigmas.size() >= 2 && aprioriPointingSigmas.at(1) > 0.0) {
346 angVelWeight = aprioriPointingSigmas.at(1);
347 angVelWeight = 1.0 / (angVelWeight * angVelWeight *
DEG2RAD *
DEG2RAD);
349 if (aprioriPointingSigmas.size() >= 3 && aprioriPointingSigmas.at(2) > 0.0) {
350 angAccWeight = aprioriPointingSigmas.at(2);
351 angAccWeight = 1.0 / (angAccWeight * angAccWeight *
DEG2RAD *
DEG2RAD);
356 for (
int i = 0; i < nCamPosCoeffsSolved; i++) {
357 if (i % nSpkTerms == 0) {
361 if (i % nSpkTerms == 1) {
365 if (i % nSpkTerms == 2) {
373 for (
int i = 0; i < nCamAngleCoeffsSolved; i++) {
374 if (i % nCkTerms == 0) {
375 m_aprioriSigmas[nCamPosCoeffsSolved + i] = aprioriPointingSigmas.at(0);
376 m_weights[nCamPosCoeffsSolved + i] = angWeight;
378 if (i % nCkTerms == 1) {
379 m_aprioriSigmas[nCamPosCoeffsSolved + i] = aprioriPointingSigmas.at(1);
380 m_weights[nCamPosCoeffsSolved + i] = angVelWeight;
382 if (i % nCkTerms == 2) {
383 m_aprioriSigmas[nCamPosCoeffsSolved + i] = aprioriPointingSigmas.at(2);
384 m_weights[nCamPosCoeffsSolved + i] = angAccWeight;
410 int nCameraAngleCoefficients =
m_solveSettings->numberCameraAngleCoefficientsSolved();
411 int nCameraPositionCoefficients =
m_solveSettings->numberCameraPositionCoefficientsSolved();
418 QString msg =
"Instrument position is NULL, but position solve option is ";
424 std::vector<double> coefX(nCameraPositionCoefficients);
425 std::vector<double> coefY(nCameraPositionCoefficients);
426 std::vector<double> coefZ(nCameraPositionCoefficients);
431 for (
int i = 0; i < nCameraPositionCoefficients; i++) {
432 coefX[i] += corrections(
index);
437 for (
int i = 0; i < nCameraPositionCoefficients; i++) {
438 coefY[i] += corrections(
index);
443 for (
int i = 0; i < nCameraPositionCoefficients; i++) {
444 coefZ[i] += corrections(
index);
449 for (
int i = 0; i < size(); i++) {
451 SpicePosition *spiceposition = image->camera()->instrumentPosition();
462 QString msg =
"Instrument rotation is NULL, but pointing solve option is ";
468 std::vector<double> coefRA(nCameraPositionCoefficients);
469 std::vector<double> coefDEC(nCameraPositionCoefficients);
470 std::vector<double> coefTWI(nCameraPositionCoefficients);
475 for (
int i = 0; i < nCameraAngleCoefficients; i++) {
476 coefRA[i] += corrections(
index);
481 for (
int i = 0; i < nCameraAngleCoefficients; i++) {
482 coefDEC[i] += corrections(
index);
488 for (
int i = 0; i < nCameraAngleCoefficients; i++) {
489 coefTWI[i] += corrections(
index);
495 for (
int i = 0; i < size(); i++) {
504 m_corrections += corrections;
508 QString msg =
"Unable to apply parameter corrections to IsisBundleObservation.";
521 return 3.0 *
m_solveSettings->numberCameraPositionCoefficientsSolved();
531 int angleCoefficients =
m_solveSettings->numberCameraAngleCoefficientsSolved();
534 return 3.0 * angleCoefficients;
536 return 2.0 * angleCoefficients;
567 int numberCamPosCoefSolved = std::max(
570 for (
int i = 0; i < numberCamPosCoefSolved; i++) {
571 if (numberCamPosCoefSolved == 1) {
572 paramList.push_back(
"X");
575 QString str =
"X(t" +
toString(i) +
")";
576 paramList.push_back(str);
579 for (
int i = 0; i < numberCamPosCoefSolved; i++) {
580 if (numberCamPosCoefSolved == 1) {
581 paramList.push_back(
"Y");
584 QString str =
"Y(t" +
toString(i) +
")";
585 paramList.push_back(str);
588 for (
int i = 0; i < numberCamPosCoefSolved; i++) {
589 if (numberCamPosCoefSolved == 1) {
590 paramList.push_back(
"Z");
593 QString str =
"Z(t" +
toString(i) +
")";
594 paramList.push_back(str);
600 int numberCamAngleCoefSolved = std::max(
603 for (
int i = 0; i < numberCamAngleCoefSolved; i++) {
604 if (numberCamAngleCoefSolved == 1) {
605 paramList.push_back(
"RA");
608 QString str =
"RA(t" +
toString(i) +
")";
609 paramList.push_back(str);
612 for (
int i = 0; i < numberCamAngleCoefSolved; i++) {
613 if (numberCamAngleCoefSolved == 1) {
614 paramList.push_back(
"DEC");
617 QString str =
"DEC(t" +
toString(i) +
")";
618 paramList.push_back(str);
621 for (
int i = 0; i < numberCamAngleCoefSolved; i++) {
622 if (numberCamAngleCoefSolved == 1) {
623 paramList.push_back(
"TWIST");
626 QString str =
"TWIST(t" +
toString(i) +
")";
627 paramList.push_back(str);
647 int &nPositionCoefficients,
int &nPointingCoefficients,
648 bool &useDefaultPosition,
649 bool &useDefaultPointing,
bool &useDefaultTwist) {
651 std::vector<double> coefX,coefY,coefZ,coefRA,coefDEC,coefTWI;
652 nPositionCoefficients =
m_solveSettings->numberCameraPositionCoefficientsSolved();
653 nPointingCoefficients =
m_solveSettings->numberCameraAngleCoefficientsSolved();
656 useDefaultPosition =
false;
657 useDefaultPointing =
false;
663 if (nPositionCoefficients == 0) {
664 nPositionCoefficients = 1;
665 useDefaultPosition =
true;
670 if (nPointingCoefficients == 0) {
671 nPointingCoefficients = 1;
672 useDefaultPointing =
true;
675 coefX.resize(nPositionCoefficients);
676 coefY.resize(nPositionCoefficients);
677 coefZ.resize(nPositionCoefficients);
678 coefRA.resize(nPointingCoefficients);
679 coefDEC.resize(nPointingCoefficients);
680 coefTWI.resize(nPointingCoefficients);
683 if (!useDefaultPosition) {
689 coefX[0] = centerCoord[0];
690 coefY[0] = centerCoord[1];
691 coefZ[0] = centerCoord[2];
696 if (!useDefaultPointing) {
702 coefRA[0] = centerAngles[0];
703 coefDEC[0] = centerAngles[1];
704 coefTWI[0] = centerAngles[2];
709 if (nPositionCoefficients > 0) {
710 for (
int i=0; i < nPositionCoefficients; i++) {
711 finalParameterValues.append(coefX[i]);
713 for (
int i=0; i < nPositionCoefficients; i++) {
714 finalParameterValues.append(coefY[i]);
716 for (
int i=0; i < nPositionCoefficients; i++) {
717 finalParameterValues.append(coefZ[i]);
720 if (nPointingCoefficients > 0) {
721 for (
int i=0; i < nPointingCoefficients; i++) {
722 finalParameterValues.append(coefRA[i]);
724 for (
int i=0; i < nPointingCoefficients; i++) {
725 finalParameterValues.append(coefDEC[i]);
727 for (
int i=0; i < nPointingCoefficients; i++) {
728 finalParameterValues.append(coefTWI[i]);
749 int nPositionCoefficients, nPointingCoefficients;
750 bool useDefaultPosition, useDefaultPointing,useDefaultTwist;
753 nPositionCoefficients,nPointingCoefficients,
754 useDefaultPosition,useDefaultPointing,useDefaultTwist);
756 int nPositionParameters = 3 * nPositionCoefficients;
757 int nPointingParameters = 3 * nPointingCoefficients;
758 int nParameters = nPositionParameters + nPointingParameters;
761 QStringList parameterNamesListX,parameterNamesListY,parameterNamesListZ,
762 parameterNamesListRA,parameterNamesListDEC,parameterNamesListTWI,
764 QStringList correctionUnitListX,correctionUnitListY,correctionUnitListZ,
765 correctionUnitListRA,correctionUnitListDEC,correctionUnitListTWI,
768 QString str(
"%1(%2) ");
769 QString str2(
"%1(%2) ");
770 QString strN(
"%1(%2)");
773 if (nPositionCoefficients > 0) {
774 for (
int j = 0; j < nPositionCoefficients;j++) {
776 parameterNamesListX.append(str.arg(
" X ").arg(
"km"));
777 parameterNamesListY.append(str.arg(
" Y ").arg(
"km"));
778 parameterNamesListZ.append(str.arg(
" Z ").arg(
"km"));
779 correctionUnitListX.append(
"m");
780 correctionUnitListY.append(
"m");
781 correctionUnitListZ.append(
"m");
785 parameterNamesListX.append( str2.arg(
" ").arg(
"km/s") );
786 parameterNamesListY.append( str2.arg(
" ").arg(
"km/s") );
787 parameterNamesListZ.append( str2.arg(
" ").arg(
"km/s") );
788 correctionUnitListX.append(
"m/s");
789 correctionUnitListY.append(
"m/s");
790 correctionUnitListZ.append(
"m/s");
793 QString str(
"%1(%2)");
794 parameterNamesListX.append(strN.arg(
" ").arg(
"km/s^"+
toString(j) ) );
795 parameterNamesListY.append(strN.arg(
" ").arg(
"km/s^"+
toString(j) ) );
796 parameterNamesListZ.append(strN.arg(
" ").arg(
"km/s^"+
toString(j) ) );
797 correctionUnitListX.append(
"m/s^"+
toString(j));
798 correctionUnitListY.append(
"m/s^"+
toString(j));
799 correctionUnitListZ.append(
"m/s^"+
toString(j));
804 if (nPointingCoefficients > 0) {
805 for (
int j = 0; j < nPointingCoefficients;j++) {
807 parameterNamesListRA.append(str.arg(
" RA ").arg(
"dd"));
808 parameterNamesListDEC.append(str.arg(
"DEC ").arg(
"dd"));
809 parameterNamesListTWI.append(str.arg(
"TWI ").arg(
"dd"));
810 correctionUnitListRA.append(
"dd");
811 correctionUnitListDEC.append(
"dd");
812 correctionUnitListTWI.append(
"dd");
816 parameterNamesListRA.append( str2.arg(
" ").arg(
"dd/s") );
817 parameterNamesListDEC.append( str2.arg(
" ").arg(
"dd/s") );
818 parameterNamesListTWI.append( str2.arg(
" ").arg(
"dd/s") );
819 correctionUnitListRA.append(
"dd/s");
820 correctionUnitListDEC.append(
"dd/s");
821 correctionUnitListTWI.append(
"dd/s");
824 parameterNamesListRA.append(strN.arg(
" ").arg(
"dd/s^"+
toString(j) ) );
825 parameterNamesListDEC.append(strN.arg(
" ").arg(
"dd/s^"+
toString(j) ) );
826 parameterNamesListTWI.append(strN.arg(
" ").arg(
"dd/s^"+
toString(j) ) );
827 correctionUnitListRA.append(
"dd/s^"+
toString(j));
828 correctionUnitListDEC.append(
"dd/s^"+
toString(j));
829 correctionUnitListTWI.append(
"dd/s^"+
toString(j));
835 parameterNamesList.append(parameterNamesListX);
836 parameterNamesList.append(parameterNamesListY);
837 parameterNamesList.append(parameterNamesListZ);
838 parameterNamesList.append(parameterNamesListRA);
839 parameterNamesList.append(parameterNamesListDEC);
840 parameterNamesList.append(parameterNamesListTWI);
843 correctionUnitList.append(correctionUnitListX);
844 correctionUnitList.append(correctionUnitListY);
845 correctionUnitList.append(correctionUnitListZ);
846 correctionUnitList.append(correctionUnitListDEC);
847 correctionUnitList.append(correctionUnitListRA);
848 correctionUnitList.append(correctionUnitListTWI);
851 QString sigma =
"N/A";
852 QString adjustedSigma =
"N/A";
853 double correction = 0.0;
856 for (
int i = 0; i < nPositionParameters; i++) {
859 if (!useDefaultPosition) {
860 correction = m_corrections(i);
865 sprintf(buf,
"%s", parameterNamesList.at(i).toStdString().c_str() );
867 sprintf(buf,
"%18.8lf ", finalParameterValues[i] - correction);
869 sprintf(buf,
"%20.8lf ", correction);
871 sprintf(buf,
"%23.8lf ", finalParameterValues[i]);
875 sprintf(buf,
"%6s", sigma.toStdString().c_str());
879 if (errorPropagation) {
880 sprintf(buf,
"%s", adjustedSigma.toStdString().c_str());
883 sprintf(buf,
"%s",
"N/A");
888 sprintf(buf,
"%s\n", correctionUnitList.at(i).toStdString().c_str() );
897 if (useDefaultPosition) {
902 for (
int i = nPositionParameters; i < nParameters; i++) {
903 if (!useDefaultPointing) {
907 if ( (i >= nParameters - nPointingCoefficients) && useDefaultTwist) {
909 adjustedSigma =
"N/A";
913 correction = m_corrections(i - offset);
922 adjustedSigma =
"N/A";
926 sprintf(buf,
"%s",parameterNamesList.at(i).toStdString().c_str() );
928 sprintf(buf,
"%18.8lf ",(finalParameterValues[i]*
RAD2DEG - correction*
RAD2DEG));
930 sprintf(buf,
"%20.8lf ",(correction*
RAD2DEG));
932 sprintf(buf,
"%23.8lf ",(finalParameterValues[i]*
RAD2DEG));
936 sprintf(buf,
"%6s",sigma.toStdString().c_str());
940 if (errorPropagation) {
941 sprintf(buf,
"%s",adjustedSigma.toStdString().c_str());
944 sprintf(buf,
"%s",
"N/A");
949 sprintf(buf,
"%s\n",correctionUnitList.at(i).toStdString().c_str() );
968 int nPositionCoefficients, nPointingCoefficients;
969 bool useDefaultPosition, useDefaultPointing,useDefaultTwist;
972 nPositionCoefficients,nPointingCoefficients,
973 useDefaultPosition,useDefaultPointing,useDefaultTwist);
975 int nPositionParameters = 3 * nPositionCoefficients;
976 int nPointingParameters = 3 * nPointingCoefficients;
977 int nParameters = nPositionParameters + nPointingParameters;
979 QString finalqStr =
"";
982 QString sigma =
"N/A";
983 QString adjustedSigma =
"N/A";
984 double correction = 0.0;
987 for (
int i = 0; i < nPositionParameters; i++) {
988 if (!useDefaultPosition) {
989 correction = m_corrections(i);
996 adjustedSigma =
"N/A";
1000 finalqStr +=
toString(finalParameterValues[i] - correction) +
",";
1001 finalqStr +=
toString(correction) +
",";
1002 finalqStr +=
toString(finalParameterValues[i]) +
",";
1003 finalqStr += sigma +
",";
1004 if (errorPropagation) {
1005 finalqStr += adjustedSigma +
",";
1008 finalqStr +=
"N/A,";
1017 if (useDefaultPosition) {
1021 for (
int i = nPositionParameters; i < nParameters; i++) {
1022 if (!useDefaultPointing) {
1025 if ( (i >= nParameters - nPointingCoefficients) && useDefaultTwist) {
1027 adjustedSigma =
"N/A";
1031 correction = m_corrections(i - offset);
1040 adjustedSigma =
"N/A";
1047 finalqStr += sigma +
",";
1048 if (errorPropagation) {
1049 finalqStr += adjustedSigma +
",";
1052 finalqStr +=
"N/A,";
1075 coeffTarget.clear();
1083 if (bundleSettings->solvePoleRA()) {
1085 &coeffTarget(0,
index),
1086 &coeffTarget(1,
index));
1090 if (bundleSettings->solvePoleRAVelocity()) {
1092 &coeffTarget(0,
index),
1093 &coeffTarget(1,
index));
1097 if (bundleSettings->solvePoleDec()) {
1099 &coeffTarget(0,
index),
1100 &coeffTarget(1,
index));
1104 if (bundleSettings->solvePoleDecVelocity()) {
1106 &coeffTarget(0,
index),
1107 &coeffTarget(1,
index));
1111 if (bundleSettings->solvePM()) {
1113 &coeffTarget(0,
index),
1114 &coeffTarget(1,
index));
1118 if (bundleSettings->solvePMVelocity()) {
1120 &coeffTarget(0,
index),
1121 &coeffTarget(1,
index));
1125 if (bundleTargetBody->solveMeanRadius()) {
1126 std::vector<double> lookBWRTMeanRadius =
1128 bundleTargetBody->meanRadius());
1131 &coeffTarget(1,
index));
1135 if (bundleTargetBody->solveTriaxialRadii()) {
1137 std::vector<double> lookBWRTRadiusA =
1139 CameraGroundMap::WRT_MajorAxis);
1142 &coeffTarget(1,
index));
1145 std::vector<double> lookBWRTRadiusB =
1147 CameraGroundMap::WRT_MinorAxis);
1150 &coeffTarget(1,
index));
1153 std::vector<double> lookBWRTRadiusC =
1155 CameraGroundMap::WRT_PolarAxis);
1158 &coeffTarget(1,
index));
1162 double observationSigma = 1.4 * measureCamera->
PixelPitch();
1163 double observationWeight = 1.0 / observationSigma;
1166 coeffTarget *= observationWeight;
1195 int numCamPositionCoefficients =
1200 for (
int cameraCoef = 0; cameraCoef < numCamPositionCoefficients; cameraCoef++) {
1202 &coeffImage(0,
index),
1203 &coeffImage(1,
index));
1208 for (
int cameraCoef = 0; cameraCoef < numCamPositionCoefficients; cameraCoef++) {
1210 &coeffImage(0,
index),
1211 &coeffImage(1,
index));
1216 for (
int cameraCoef = 0; cameraCoef < numCamPositionCoefficients; cameraCoef++) {
1218 &coeffImage(0,
index),
1219 &coeffImage(1,
index));
1228 int numCamAngleCoefficients =
1232 for (
int cameraCoef = 0; cameraCoef < numCamAngleCoefficients; cameraCoef++) {
1234 cameraCoef, &coeffImage(0,
index),
1235 &coeffImage(1,
index));
1240 for (
int cameraCoef = 0; cameraCoef < numCamAngleCoefficients; cameraCoef++) {
1242 cameraCoef, &coeffImage(0,
index),
1243 &coeffImage(1,
index));
1249 for (
int cameraCoef = 0; cameraCoef < numCamAngleCoefficients; cameraCoef++) {
1251 cameraCoef, &coeffImage(0,
index),
1252 &coeffImage(1,
index));
1259 double observationSigma = 1.4 * camera->
PixelPitch();
1260 double observationWeight = 1.0 / observationSigma;
1261 coeffImage *= observationWeight;
1282 coeffPoint3D.clear();
1293 &coeffPoint3D(0, 0),
1294 &coeffPoint3D(1, 0));
1296 &coeffPoint3D(0, 1),
1297 &coeffPoint3D(1, 1));
1299 &coeffPoint3D(0, 2),
1300 &coeffPoint3D(1, 2));
1302 double observationSigma = 1.4 * measureCamera->
PixelPitch();
1303 double observationWeight = 1.0 / observationSigma;
1306 coeffPoint3D *= observationWeight;
1331 double computedX, computedY;
1333 &computedX, &computedY,
false))) {
1334 QString msg =
"Unable to map apriori surface point for measure ";
1335 msg += measure.
cubeSerialNumber() +
" on point " + point->
id() +
" into focal plane";
1342 double deltaX = measuredX - computedX;
1343 double deltaY = measuredY - computedY;
1345 coeffRHS(0) = deltaX;
1346 coeffRHS(1) = deltaY;
1349 double observationSigma = 1.4 * measureCamera->
PixelPitch();
1350 double observationWeight = 1.0 / observationSigma;
1352 coeffRHS *= observationWeight;
1372 return deltaVal / measureCamera->
PixelPitch();