Isis 3 Programmer Reference
IsisBundleObservation.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "IsisBundleObservation.h"
10
11#include <QDebug>
12#include <QString>
13#include <QStringList>
14#include <QVector>
15
16#include "BundleImage.h"
17#include "BundleControlPoint.h"
18#include "BundleObservationSolveSettings.h"
19#include "BundleTargetBody.h"
20#include "Camera.h"
21#include "LinearAlgebra.h"
22#include "SpicePosition.h"
23#include "SpiceRotation.h"
24#include "CameraGroundMap.h"
25
26using namespace std;
27using namespace boost::numeric::ublas;
28
29namespace Isis {
30
38
39
50 QString instrumentId, BundleTargetBodyQsp bundleTargetBody) :
51 BundleObservation(image, observationNumber, instrumentId, bundleTargetBody) {
52 m_bundleTargetBody = bundleTargetBody;
55
56 if (image) {
57 // set the observations spice position and rotation objects from the primary image in the
58 // observation (this is, by design at the moment, the first image added to the observation)
59 // if the image, camera, or instrument position/orientation is null, then set to null
60 m_instrumentPosition = (image->camera() ?
61 (image->camera()->instrumentPosition() ?
62 image->camera()->instrumentPosition() : NULL)
63 : NULL);
64 m_instrumentRotation = (image->camera() ?
65 (image->camera()->instrumentRotation() ?
66 image->camera()->instrumentRotation() : NULL)
67 : NULL);
68 }
69 }
70
71
78 m_instrumentPosition = src.m_instrumentPosition;
79 m_instrumentRotation = src.m_instrumentRotation;
80 m_solveSettings = src.m_solveSettings;
81 m_bundleTargetBody = src.m_bundleTargetBody;
82 }
83
84
92
93
104 if (&src != this) {
106 m_instrumentPosition = src.m_instrumentPosition;
107 m_instrumentRotation = src.m_instrumentRotation;
108 m_solveSettings = src.m_solveSettings;
109 m_bundleTargetBody = src.m_bundleTargetBody;
110 }
111 return *this;
112 }
113
114
125
126 // initialize solution parameters for this observation
127 int nCameraAngleCoefficients = m_solveSettings->numberCameraAngleCoefficientsSolved();
128 int nCameraPositionCoefficients = m_solveSettings->numberCameraPositionCoefficientsSolved();
129
130 int nParameters = 3*nCameraPositionCoefficients + 2*nCameraAngleCoefficients;
131 if (nCameraAngleCoefficients >= 1 && m_solveSettings->solveTwist()) {
132 nParameters += nCameraAngleCoefficients;
133 }
134 // size vectors and set to zero
135 m_weights.resize(nParameters);
136 m_weights.clear();
137 m_corrections.resize(nParameters);
138 m_corrections.clear();
139 m_adjustedSigmas.resize(nParameters);
140 m_adjustedSigmas.clear();
141 m_aprioriSigmas.resize(nParameters);
142 for ( int i = 0; i < nParameters; i++) {
144 }
145
146 if (!initParameterWeights()) {
147 return false;
148 }
149
150 return true;
151 }
152
153
162
163
172
173
183
184
191 if (m_solveSettings->instrumentPositionSolveOption() !=
193
194 double positionBaseTime = 0.0;
195 double positiontimeScale = 0.0;
196 std::vector<double> posPoly1, posPoly2, posPoly3;
197
198 for (int i = 0; i < size(); i++) {
199 BundleImageQsp image = at(i);
200 SpicePosition *spicePosition = image->camera()->instrumentPosition();
201
202 // If this image isn't the first, copy the position from the first
203 if (i > 0) {
205 spicePosition->SetOverrideBaseTime(positionBaseTime, positiontimeScale);
206 spicePosition->SetPolynomial(posPoly1, posPoly2, posPoly3,
207 m_solveSettings->positionInterpolationType());
208 }
209 // Otherwise we need to fit the initial position
210 else {
211 // first, set the degree of the spk polynomial to be fit for a priori values
213
214 // now, set what kind of interpolation to use (polynomial function or
215 // polynomial function over hermite spline)
216 spicePosition->SetPolynomial(m_solveSettings->positionInterpolationType());
217
218 // finally, set the degree of the position polynomial actually used in the bundle adjustment
220
222 positionBaseTime = m_instrumentPosition->GetBaseTime();
223 positiontimeScale = m_instrumentPosition->GetTimeScale();
224 m_instrumentPosition->GetPolynomial(posPoly1, posPoly2, posPoly3);
225 }
226 }
227 }
228 }
229
230 if (m_solveSettings->instrumentPointingSolveOption() !=
232
233 double rotationBaseTime = 0.0;
234 double rotationtimeScale = 0.0;
235 std::vector<double> anglePoly1, anglePoly2, anglePoly3;
236
237 for (int i = 0; i < size(); i++) {
238 BundleImageQsp image = at(i);
239 SpiceRotation *spicerotation = image->camera()->instrumentRotation();
240
241 // If this image isn't the first, copy the pointing from the first
242 if (i > 0) {
243 spicerotation->SetPolynomialDegree(m_solveSettings->ckSolveDegree());
244 spicerotation->SetOverrideBaseTime(rotationBaseTime, rotationtimeScale);
245 spicerotation->SetPolynomial(anglePoly1, anglePoly2, anglePoly3,
246 m_solveSettings->pointingInterpolationType());
247 }
248 // Otherwise we need to fit the initial pointing
249 else {
250 // first, set the degree of the polynomial to be fit for a priori values
251 spicerotation->SetPolynomialDegree(m_solveSettings->ckDegree());
252
253 // now, set what kind of interpolation to use (polynomial function or
254 // polynomial function over a pointing cache)
255 spicerotation->SetPolynomial(m_solveSettings->pointingInterpolationType());
256
257 // finally, set the degree of the pointing polynomial actually used in the bundle adjustment
258 spicerotation->SetPolynomialDegree(m_solveSettings->ckSolveDegree());
259
260 rotationBaseTime = spicerotation->GetBaseTime();
261 rotationtimeScale = spicerotation->GetTimeScale();
262 spicerotation->GetPolynomial(anglePoly1, anglePoly2, anglePoly3);
263 }
264 }
265 }
266 return true;
267 }
268
269
274 std::vector<Angle> raCoefs = m_bundleTargetBody->poleRaCoefs();
275 std::vector<Angle> decCoefs = m_bundleTargetBody->poleDecCoefs();
276 std::vector<Angle> pmCoefs = m_bundleTargetBody->pmCoefs();
277
278 for (int i = 0; i < size(); i++) {
279 BundleImageQsp image = at(i);
280 image->camera()->bodyRotation()->setPckPolynomial(raCoefs, decCoefs, pmCoefs);
281 }
282 }
283
284
289 std::vector<Angle> raCoefs = m_bundleTargetBody->poleRaCoefs();
290 std::vector<Angle> decCoefs = m_bundleTargetBody->poleDecCoefs();
291 std::vector<Angle> pmCoefs = m_bundleTargetBody->pmCoefs();
292
293 for (int i = 0; i < size(); i++) {
294 BundleImageQsp image = at(i);
295 image->camera()->bodyRotation()->setPckPolynomial(raCoefs, decCoefs, pmCoefs);
296 }
297 }
298
299
306
307 // weights for
308 double posWeight = 0.0; // position
309 double velWeight = 0.0; // velocity
310 double accWeight = 0.0; // acceleration
311 double angWeight = 0.0; // angles
312 double angVelWeight = 0.0; // angular velocity
313 double angAccWeight = 0.0; // angular acceleration
314
315 QList<double> aprioriPointingSigmas = m_solveSettings->aprioriPointingSigmas();
316 QList<double> aprioriPositionSigmas = m_solveSettings->aprioriPositionSigmas();
317
318 int nCamPosCoeffsSolved = 3 *m_solveSettings->numberCameraPositionCoefficientsSolved();
319
320 int nCamAngleCoeffsSolved;
321 if (m_solveSettings->solveTwist()) {
322 nCamAngleCoeffsSolved = 3 *m_solveSettings->numberCameraAngleCoefficientsSolved();
323 }
324 else {
325 nCamAngleCoeffsSolved = 2 *m_solveSettings->numberCameraAngleCoefficientsSolved();
326 }
327
328 if (aprioriPositionSigmas.size() >= 1 && aprioriPositionSigmas.at(0) > 0.0) {
329 posWeight = aprioriPositionSigmas.at(0);
330 posWeight = 1.0 / (posWeight *posWeight * 1.0e-6);
331 }
332 if (aprioriPositionSigmas.size() >= 2 && aprioriPositionSigmas.at(1) > 0.0) {
333 velWeight = aprioriPositionSigmas.at(1);
334 velWeight = 1.0 / (velWeight *velWeight * 1.0e-6);
335 }
336 if (aprioriPositionSigmas.size() >= 3 && aprioriPositionSigmas.at(2) > 0.0) {
337 accWeight = aprioriPositionSigmas.at(2);
338 accWeight = 1.0 / (accWeight *accWeight * 1.0e-6);
339 }
340
341 if (aprioriPointingSigmas.size() >= 1 && aprioriPointingSigmas.at(0) > 0.0) {
342 angWeight = aprioriPointingSigmas.at(0);
343 angWeight = 1.0 / (angWeight *angWeight * DEG2RAD * DEG2RAD);
344 }
345 if (aprioriPointingSigmas.size() >= 2 && aprioriPointingSigmas.at(1) > 0.0) {
346 angVelWeight = aprioriPointingSigmas.at(1);
347 angVelWeight = 1.0 / (angVelWeight * angVelWeight * DEG2RAD * DEG2RAD);
348 }
349 if (aprioriPointingSigmas.size() >= 3 && aprioriPointingSigmas.at(2) > 0.0) {
350 angAccWeight = aprioriPointingSigmas.at(2);
351 angAccWeight = 1.0 / (angAccWeight * angAccWeight * DEG2RAD * DEG2RAD);
352 }
353
354 int nSpkTerms = m_solveSettings->spkSolveDegree()+1;
355 nSpkTerms = m_solveSettings->numberCameraPositionCoefficientsSolved();
356 for ( int i = 0; i < nCamPosCoeffsSolved; i++) {
357 if (i % nSpkTerms == 0) {
358 m_aprioriSigmas[i] = aprioriPositionSigmas.at(0);
359 m_weights[i] = posWeight;
360 }
361 if (i % nSpkTerms == 1) {
362 m_aprioriSigmas[i] = aprioriPositionSigmas.at(1);
363 m_weights[i] = velWeight;
364 }
365 if (i % nSpkTerms == 2) {
366 m_aprioriSigmas[i] = aprioriPositionSigmas.at(2);
367 m_weights[i] = accWeight;
368 }
369 }
370
371 int nCkTerms = m_solveSettings->ckSolveDegree()+1;
372 nCkTerms = m_solveSettings->numberCameraAngleCoefficientsSolved();
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;
377 }
378 if (i % nCkTerms == 1) {
379 m_aprioriSigmas[nCamPosCoeffsSolved + i] = aprioriPointingSigmas.at(1);
380 m_weights[nCamPosCoeffsSolved + i] = angVelWeight;
381 }
382 if (i % nCkTerms == 2) {
383 m_aprioriSigmas[nCamPosCoeffsSolved + i] = aprioriPointingSigmas.at(2);
384 m_weights[nCamPosCoeffsSolved + i] = angAccWeight;
385 }
386 }
387
388 return true;
389 }
390
391
406
407 int index = 0;
408
409 try {
410 int nCameraAngleCoefficients = m_solveSettings->numberCameraAngleCoefficientsSolved();
411 int nCameraPositionCoefficients = m_solveSettings->numberCameraPositionCoefficientsSolved();
412
414 = m_solveSettings->instrumentPositionSolveOption();
416
418 QString msg = "Instrument position is NULL, but position solve option is ";
420 positionOption));
421 throw IException(IException::Unknown, msg, _FILEINFO_);
422 }
423
424 std::vector<double> coefX(nCameraPositionCoefficients);
425 std::vector<double> coefY(nCameraPositionCoefficients);
426 std::vector<double> coefZ(nCameraPositionCoefficients);
427
428 m_instrumentPosition->GetPolynomial(coefX, coefY, coefZ);
429
430 // update X coordinate coefficient(s) and sum parameter correction
431 for (int i = 0; i < nCameraPositionCoefficients; i++) {
432 coefX[i] += corrections(index);
433 index++;
434 }
435
436 // update Y coordinate coefficient(s) and sum parameter correction
437 for (int i = 0; i < nCameraPositionCoefficients; i++) {
438 coefY[i] += corrections(index);
439 index++;
440 }
441
442 // update Z coordinate coefficient(s) and sum parameter correction
443 for (int i = 0; i < nCameraPositionCoefficients; i++) {
444 coefZ[i] += corrections(index);
445 index++;
446 }
447
448 // apply updates to all images in observation
449 for (int i = 0; i < size(); i++) {
450 BundleImageQsp image = at(i);
451 SpicePosition *spiceposition = image->camera()->instrumentPosition();
452 spiceposition->SetPolynomial(coefX, coefY, coefZ,
453 m_solveSettings->positionInterpolationType());
454 }
455 }
456
458 = m_solveSettings->instrumentPointingSolveOption();
460
462 QString msg = "Instrument rotation is NULL, but pointing solve option is ";
464 pointingOption));
465 throw IException(IException::Unknown, msg, _FILEINFO_);
466 }
467
468 std::vector<double> coefRA(nCameraPositionCoefficients);
469 std::vector<double> coefDEC(nCameraPositionCoefficients);
470 std::vector<double> coefTWI(nCameraPositionCoefficients);
471
472 m_instrumentRotation->GetPolynomial(coefRA, coefDEC, coefTWI);
473
474 // update RA coefficient(s)
475 for (int i = 0; i < nCameraAngleCoefficients; i++) {
476 coefRA[i] += corrections(index);
477 index++;
478 }
479
480 // update DEC coefficient(s)
481 for (int i = 0; i < nCameraAngleCoefficients; i++) {
482 coefDEC[i] += corrections(index);
483 index++;
484 }
485
486 if (m_solveSettings->solveTwist()) {
487 // update TWIST coefficient(s)
488 for (int i = 0; i < nCameraAngleCoefficients; i++) {
489 coefTWI[i] += corrections(index);
490 index++;
491 }
492 }
493
494 // apply updates to all images in observation
495 for (int i = 0; i < size(); i++) {
496 BundleImageQsp image = at(i);
497 SpiceRotation *spiceRotation = image->camera()->instrumentRotation();
498 spiceRotation->SetPolynomial(coefRA, coefDEC, coefTWI,
499 m_solveSettings->pointingInterpolationType());
500 }
501 }
502
503 // update corrections
504 m_corrections += corrections;
505
506 }
507 catch (IException &e) {
508 QString msg = "Unable to apply parameter corrections to IsisBundleObservation.";
509 throw IException(e, IException::Unknown, msg, _FILEINFO_);
510 }
511 return true;
512 }
513
514
521 return 3.0 * m_solveSettings->numberCameraPositionCoefficientsSolved();
522 }
523
524
531 int angleCoefficients = m_solveSettings->numberCameraAngleCoefficientsSolved();
532
533 if (m_solveSettings->solveTwist()) {
534 return 3.0 * angleCoefficients;
535 }
536 return 2.0 * angleCoefficients;
537 }
538
539
551
552
563 QStringList paramList;
564
565 // We still want to output the center postion even if not solving for it
566 // so always do at least 1
567 int numberCamPosCoefSolved = std::max(
568 solveSettings()->numberCameraPositionCoefficientsSolved(),
569 1);
570 for (int i = 0; i < numberCamPosCoefSolved; i++) {
571 if (numberCamPosCoefSolved == 1) {
572 paramList.push_back("X");
573 }
574 else {
575 QString str = "X(t" + toString(i) + ")";
576 paramList.push_back(str);
577 }
578 }
579 for (int i = 0; i < numberCamPosCoefSolved; i++) {
580 if (numberCamPosCoefSolved == 1) {
581 paramList.push_back("Y");
582 }
583 else {
584 QString str = "Y(t" + toString(i) + ")";
585 paramList.push_back(str);
586 }
587 }
588 for (int i = 0; i < numberCamPosCoefSolved; i++) {
589 if (numberCamPosCoefSolved == 1) {
590 paramList.push_back("Z");
591 }
592 else {
593 QString str = "Z(t" + toString(i) + ")";
594 paramList.push_back(str);
595 }
596 }
597
598 // We still want to output the center pointing even if not solving for it
599 // so always do at least 1
600 int numberCamAngleCoefSolved = std::max(
601 solveSettings()->numberCameraAngleCoefficientsSolved(),
602 1);
603 for (int i = 0; i < numberCamAngleCoefSolved; i++) {
604 if (numberCamAngleCoefSolved == 1) {
605 paramList.push_back("RA");
606 }
607 else {
608 QString str = "RA(t" + toString(i) + ")";
609 paramList.push_back(str);
610 }
611 }
612 for (int i = 0; i < numberCamAngleCoefSolved; i++) {
613 if (numberCamAngleCoefSolved == 1) {
614 paramList.push_back("DEC");
615 }
616 else {
617 QString str = "DEC(t" + toString(i) + ")";
618 paramList.push_back(str);
619 }
620 }
621 for (int i = 0; i < numberCamAngleCoefSolved; i++) {
622 if (numberCamAngleCoefSolved == 1) {
623 paramList.push_back("TWIST");
624 }
625 else {
626 QString str = "TWIST(t" + toString(i) + ")";
627 paramList.push_back(str);
628 }
629 }
630
631 return paramList;
632}
633
634
646 void IsisBundleObservation::bundleOutputFetchData(QVector<double> &finalParameterValues,
647 int &nPositionCoefficients, int &nPointingCoefficients,
648 bool &useDefaultPosition,
649 bool &useDefaultPointing, bool &useDefaultTwist) {
650
651 std::vector<double> coefX,coefY,coefZ,coefRA,coefDEC,coefTWI;
652 nPositionCoefficients = m_solveSettings->numberCameraPositionCoefficientsSolved();
653 nPointingCoefficients = m_solveSettings->numberCameraAngleCoefficientsSolved();
654
655 // Indicate if we need to obtain default position or pointing values
656 useDefaultPosition = false;
657 useDefaultPointing = false;
658 // Indicate if we need to use default values when not solving twist
659 useDefaultTwist = !(m_solveSettings->solveTwist());
660
661 // If we aren't solving for position, set the number of coefficients to 1 so we
662 // can output the instrumentPosition's center coordinate values for X, Y, and Z
663 if (nPositionCoefficients == 0) {
664 nPositionCoefficients = 1;
665 useDefaultPosition = true;
666 }
667
668 // If we arent' solving for pointing, set the number of coefficients to 1 so we
669 // can output the instrumentPointing's center angles for RA, DEC, and TWI
670 if (nPointingCoefficients == 0) {
671 nPointingCoefficients = 1;
672 useDefaultPointing = true;
673 }
674
675 coefX.resize(nPositionCoefficients);
676 coefY.resize(nPositionCoefficients);
677 coefZ.resize(nPositionCoefficients);
678 coefRA.resize(nPointingCoefficients);
679 coefDEC.resize(nPointingCoefficients);
680 coefTWI.resize(nPointingCoefficients);
681
683 if (!useDefaultPosition) {
684 m_instrumentPosition->GetPolynomial(coefX,coefY,coefZ);
685 }
686 // Use the position's center coordinate if not solving for spacecraft position
687 else {
688 const std::vector<double> centerCoord = m_instrumentPosition->GetCenterCoordinate();
689 coefX[0] = centerCoord[0];
690 coefY[0] = centerCoord[1];
691 coefZ[0] = centerCoord[2];
692 }
693 }
694
696 if (!useDefaultPointing) {
697 m_instrumentRotation->GetPolynomial(coefRA,coefDEC,coefTWI);
698 }
699 // Use the pointing's center angles if not solving for pointing (rotation)
700 else {
701 const std::vector<double> centerAngles = m_instrumentRotation->GetCenterAngles();
702 coefRA[0] = centerAngles[0];
703 coefDEC[0] = centerAngles[1];
704 coefTWI[0] = centerAngles[2];
705 }
706 }
707
708 // Combine all vectors into one
709 if (nPositionCoefficients > 0) {
710 for (int i=0; i < nPositionCoefficients; i++) {
711 finalParameterValues.append(coefX[i]);
712 }
713 for (int i=0; i < nPositionCoefficients; i++) {
714 finalParameterValues.append(coefY[i]);
715 }
716 for (int i=0; i < nPositionCoefficients; i++) {
717 finalParameterValues.append(coefZ[i]);
718 }
719 }
720 if (nPointingCoefficients > 0) {
721 for (int i=0; i < nPointingCoefficients; i++) {
722 finalParameterValues.append(coefRA[i]);
723 }
724 for (int i=0; i < nPointingCoefficients; i++) {
725 finalParameterValues.append(coefDEC[i]);
726 }
727 for (int i=0; i < nPointingCoefficients; i++) {
728 finalParameterValues.append(coefTWI[i]);
729 }
730 }
731
732 }
733
734
744 void IsisBundleObservation::bundleOutputString(std::ostream &fpOut, bool errorPropagation) {
745
746 char buf[4096];
747
748 QVector<double> finalParameterValues;
749 int nPositionCoefficients, nPointingCoefficients;
750 bool useDefaultPosition, useDefaultPointing,useDefaultTwist;
751
752 bundleOutputFetchData(finalParameterValues,
753 nPositionCoefficients,nPointingCoefficients,
754 useDefaultPosition,useDefaultPointing,useDefaultTwist);
755
756 int nPositionParameters = 3 * nPositionCoefficients;
757 int nPointingParameters = 3 * nPointingCoefficients;
758 int nParameters = nPositionParameters + nPointingParameters;
759
760 // for convenience, create vectors of parameters names and values in the correct sequence
761 QStringList parameterNamesListX,parameterNamesListY,parameterNamesListZ,
762 parameterNamesListRA,parameterNamesListDEC,parameterNamesListTWI,
763 parameterNamesList;
764 QStringList correctionUnitListX,correctionUnitListY,correctionUnitListZ,
765 correctionUnitListRA,correctionUnitListDEC,correctionUnitListTWI,
766 correctionUnitList;
767
768 QString str("%1(%2) ");
769 QString str2("%1(%2) ");
770 QString strN("%1(%2)");
771
772
773 if (nPositionCoefficients > 0) {
774 for (int j = 0; j < nPositionCoefficients;j++) {
775 if (j == 0) {
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");
782 } //end inner-if
783
784 else if (j==1) {
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");
791 }
792 else {
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));
800 }
801 }//end for
802 }//end outer-if
803
804 if (nPointingCoefficients > 0) {
805 for (int j = 0; j < nPointingCoefficients;j++) {
806 if (j == 0) {
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");
813 } //end inner-if
814
815 else if (j==1) {
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");
822 }
823 else {
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));
830 }
831 }//end for
832 }// end outer-if
833
834 //Put all of the parameter names together into one QStringList
835 parameterNamesList.append(parameterNamesListX);
836 parameterNamesList.append(parameterNamesListY);
837 parameterNamesList.append(parameterNamesListZ);
838 parameterNamesList.append(parameterNamesListRA);
839 parameterNamesList.append(parameterNamesListDEC);
840 parameterNamesList.append(parameterNamesListTWI);
841
842 //Put all of the correction unit names together into one QStringList
843 correctionUnitList.append(correctionUnitListX);
844 correctionUnitList.append(correctionUnitListY);
845 correctionUnitList.append(correctionUnitListZ);
846 correctionUnitList.append(correctionUnitListDEC);
847 correctionUnitList.append(correctionUnitListRA);
848 correctionUnitList.append(correctionUnitListTWI);
849
850 // Set up default values when we are using default position
851 QString sigma = "N/A";
852 QString adjustedSigma = "N/A";
853 double correction = 0.0;
854
855 // position parameters
856 for (int i = 0; i < nPositionParameters; i++) {
857 // If not using the default position, we can correctly access sigmas and corrections
858 // members
859 if (!useDefaultPosition) {
860 correction = m_corrections(i);
861 adjustedSigma = QString::number(m_adjustedSigmas[i], 'f', 8);
862 sigma = ( IsSpecial(m_aprioriSigmas[i]) ? "FREE" : toString(m_aprioriSigmas[i], 8) );
863 }
864
865 snprintf(buf, sizeof(buf),"%s", parameterNamesList.at(i).toStdString().c_str() );
866 fpOut << buf;
867 snprintf(buf, sizeof(buf),"%18.8lf ", finalParameterValues[i] - correction);
868 fpOut << buf;
869 snprintf(buf, sizeof(buf),"%20.8lf ", correction);
870 fpOut << buf;
871 snprintf(buf, sizeof(buf),"%23.8lf ", finalParameterValues[i]);
872 fpOut << buf;
873 snprintf(buf, sizeof(buf)," ");
874 fpOut << buf;
875 snprintf(buf, sizeof(buf),"%6s", sigma.toStdString().c_str());
876 fpOut << buf;
877 snprintf(buf, sizeof(buf)," ");
878 fpOut << buf;
879 if (errorPropagation) {
880 snprintf(buf, sizeof(buf),"%s", adjustedSigma.toStdString().c_str());
881 }
882 else {
883 snprintf(buf, sizeof(buf),"%s", "N/A");
884 }
885 fpOut << buf;
886 snprintf(buf, sizeof(buf)," ");
887 fpOut << buf;
888 snprintf(buf, sizeof(buf),"%s\n", correctionUnitList.at(i).toStdString().c_str() );
889 fpOut << buf;
890
891 }
892
893 // We need to use an offset of -3 (1 coef; X,Y,Z) if we used the default center coordinate
894 // (i.e. we did not solve for position), as m_corrections and m_*sigmas are populated
895 // according to which parameters are solved
896 int offset = 0;
897 if (useDefaultPosition) {
898 offset = 3;
899 }
900
901 // pointing parameters
902 for (int i = nPositionParameters; i < nParameters; i++) {
903 if (!useDefaultPointing) {
904 // If solving camera and not solving for twist, provide default values for twist to
905 // prevent bad indexing into m_corrections and m_*sigmas
906 // TWIST is last parameter, which corresponds to nParameters - nPointingCoefficients
907 if ( (i >= nParameters - nPointingCoefficients) && useDefaultTwist) {
908 correction = 0.0;
909 adjustedSigma = "N/A";
910 sigma = "N/A";
911 }
912 else {
913 correction = m_corrections(i - offset);
914 adjustedSigma = QString::number(m_adjustedSigmas(i-offset) * RAD2DEG, 'f', 8);
915 sigma = ( IsSpecial(m_aprioriSigmas[i - offset]) ? "FREE" :
916 toString(m_aprioriSigmas[i-offset], 8) );
917 }
918 }
919 // We are using default pointing, so provide default correction and sigma values to output
920 else {
921 correction = 0.0;
922 adjustedSigma = "N/A";
923 sigma = "N/A";
924 }
925
926 snprintf(buf, sizeof(buf),"%s",parameterNamesList.at(i).toStdString().c_str() );
927 fpOut << buf;
928 snprintf(buf, sizeof(buf),"%18.8lf ",(finalParameterValues[i]*RAD2DEG - correction*RAD2DEG));
929 fpOut << buf;
930 snprintf(buf, sizeof(buf),"%20.8lf ",(correction*RAD2DEG));
931 fpOut << buf;
932 snprintf(buf, sizeof(buf),"%23.8lf ",(finalParameterValues[i]*RAD2DEG));
933 fpOut << buf;
934 snprintf(buf, sizeof(buf)," ");
935 fpOut << buf;
936 snprintf(buf, sizeof(buf),"%6s",sigma.toStdString().c_str());
937 fpOut << buf;
938 snprintf(buf, sizeof(buf)," ");
939 fpOut << buf;
940 if (errorPropagation) {
941 snprintf(buf, sizeof(buf),"%s",adjustedSigma.toStdString().c_str());
942 }
943 else {
944 snprintf(buf, sizeof(buf),"%s","N/A");
945 }
946 fpOut<<buf;
947 snprintf(buf, sizeof(buf)," ");
948 fpOut<<buf;
949 snprintf(buf, sizeof(buf),"%s\n",correctionUnitList.at(i).toStdString().c_str() );
950 fpOut<<buf;
951 }
952
953 }
954
965 QString IsisBundleObservation::bundleOutputCSV(bool errorPropagation) {
966
967 QVector<double> finalParameterValues;
968 int nPositionCoefficients, nPointingCoefficients;
969 bool useDefaultPosition, useDefaultPointing,useDefaultTwist;
970
971 bundleOutputFetchData(finalParameterValues,
972 nPositionCoefficients,nPointingCoefficients,
973 useDefaultPosition,useDefaultPointing,useDefaultTwist);
974
975 int nPositionParameters = 3 * nPositionCoefficients;
976 int nPointingParameters = 3 * nPointingCoefficients;
977 int nParameters = nPositionParameters + nPointingParameters;
978
979 QString finalqStr = "";
980
981 // Set up default values when we are using default position
982 QString sigma = "N/A";
983 QString adjustedSigma = "N/A";
984 double correction = 0.0;
985
986 // Position parameters
987 for (int i = 0; i < nPositionParameters; i++) {
988 if (!useDefaultPosition) {
989 correction = m_corrections(i);
990 adjustedSigma = QString::number(m_adjustedSigmas[i], 'f', 8);
991 sigma = ( IsSpecial(m_aprioriSigmas[i]) ? "FREE" : toString(m_aprioriSigmas[i], 8) );
992 }
993 // Provide default values for position if not solving position
994 else {
995 correction = 0.0;
996 adjustedSigma = "N/A";
997 sigma = "N/A";
998 }
999
1000 finalqStr += toString(finalParameterValues[i] - correction) + ",";
1001 finalqStr += toString(correction) + ",";
1002 finalqStr += toString(finalParameterValues[i]) + ",";
1003 finalqStr += sigma + ",";
1004 if (errorPropagation) {
1005 finalqStr += adjustedSigma + ",";
1006 }
1007 else {
1008 finalqStr += "N/A,";
1009 }
1010
1011 }
1012
1013 // If not solving position, we need to offset access to correction and sigma members by -3
1014 // (X,Y,Z) since m_corrections and m_*sigmas are populated according to which parameters are
1015 // solved
1016 int offset = 0;
1017 if (useDefaultPosition) {
1018 offset = 3;
1019 }
1020 // pointing parameters
1021 for (int i = nPositionParameters; i < nParameters; i++) {
1022 if (!useDefaultPointing) {
1023 // Use default values if solving camera but not solving for TWIST to prevent bad indexing
1024 // into m_corrections and m_*sigmas
1025 if ( (i >= nParameters - nPointingCoefficients) && useDefaultTwist) {
1026 correction = 0.0;
1027 adjustedSigma = "N/A";
1028 sigma = "N/A";
1029 }
1030 else {
1031 correction = m_corrections(i - offset);
1032 adjustedSigma = QString::number(m_adjustedSigmas(i-offset) * RAD2DEG, 'f', 8);
1033 sigma = ( IsSpecial(m_aprioriSigmas[i-offset]) ? "FREE" :
1034 toString(m_aprioriSigmas[i-offset], 8) );
1035 }
1036 }
1037 // Provide default values for pointing if not solving pointing
1038 else {
1039 correction = 0.0;
1040 adjustedSigma = "N/A";
1041 sigma = "N/A";
1042 }
1043
1044 finalqStr += toString(finalParameterValues[i]*RAD2DEG - correction * RAD2DEG) + ",";
1045 finalqStr += toString(correction * RAD2DEG) + ",";
1046 finalqStr += toString(finalParameterValues[i]*RAD2DEG) + ",";
1047 finalqStr += sigma + ",";
1048 if (errorPropagation) {
1049 finalqStr += adjustedSigma + ",";
1050 }
1051 else {
1052 finalqStr += "N/A,";
1053 }
1054
1055 }
1056
1057 return finalqStr;
1058 }
1059
1060
1073 bool IsisBundleObservation::computeTargetPartials(matrix<double> &coeffTarget, BundleMeasure &measure,
1074 BundleSettingsQsp &bundleSettings, BundleTargetBodyQsp &bundleTargetBody) {
1075 coeffTarget.clear();
1076
1077 Camera *measureCamera = measure.camera();
1078 BundleControlPoint *point = measure.parentControlPoint();
1079 SurfacePoint surfacePoint = point->adjustedSurfacePoint();
1080
1081 int index = 0;
1082
1083 if (bundleSettings->solvePoleRA()) {
1084 measureCamera->GroundMap()->GetdXYdTOrientation(SpiceRotation::WRT_RightAscension, 0,
1085 &coeffTarget(0, index),
1086 &coeffTarget(1, index));
1087 index++;
1088 }
1089
1090 if (bundleSettings->solvePoleRAVelocity()) {
1091 measureCamera->GroundMap()->GetdXYdTOrientation(SpiceRotation::WRT_RightAscension, 1,
1092 &coeffTarget(0, index),
1093 &coeffTarget(1, index));
1094 index++;
1095 }
1096
1097 if (bundleSettings->solvePoleDec()) {
1098 measureCamera->GroundMap()->GetdXYdTOrientation(SpiceRotation::WRT_Declination, 0,
1099 &coeffTarget(0, index),
1100 &coeffTarget(1, index));
1101 index++;
1102 }
1103
1104 if (bundleSettings->solvePoleDecVelocity()) {
1105 measureCamera->GroundMap()->GetdXYdTOrientation(SpiceRotation::WRT_Declination, 1,
1106 &coeffTarget(0, index),
1107 &coeffTarget(1, index));
1108 index++;
1109 }
1110
1111 if (bundleSettings->solvePM()) {
1112 measureCamera->GroundMap()->GetdXYdTOrientation(SpiceRotation::WRT_Twist, 0,
1113 &coeffTarget(0, index),
1114 &coeffTarget(1, index));
1115 index++;
1116 }
1117
1118 if (bundleSettings->solvePMVelocity()) {
1119 measureCamera->GroundMap()->GetdXYdTOrientation(SpiceRotation::WRT_Twist, 1,
1120 &coeffTarget(0, index),
1121 &coeffTarget(1, index));
1122 index++;
1123 }
1124
1125 if (bundleTargetBody->solveMeanRadius()) {
1126 std::vector<double> lookBWRTMeanRadius =
1127 measureCamera->GroundMap()->MeanRadiusPartial(surfacePoint,
1128 bundleTargetBody->meanRadius());
1129
1130 measureCamera->GroundMap()->GetdXYdPoint(lookBWRTMeanRadius, &coeffTarget(0, index),
1131 &coeffTarget(1, index));
1132 index++;
1133 }
1134
1135 if (bundleTargetBody->solveTriaxialRadii()) {
1136
1137 std::vector<double> lookBWRTRadiusA =
1138 measureCamera->GroundMap()->EllipsoidPartial(surfacePoint,
1139 CameraGroundMap::WRT_MajorAxis);
1140
1141 measureCamera->GroundMap()->GetdXYdPoint(lookBWRTRadiusA, &coeffTarget(0, index),
1142 &coeffTarget(1, index));
1143 index++;
1144
1145 std::vector<double> lookBWRTRadiusB =
1146 measureCamera->GroundMap()->EllipsoidPartial(surfacePoint,
1147 CameraGroundMap::WRT_MinorAxis);
1148
1149 measureCamera->GroundMap()->GetdXYdPoint(lookBWRTRadiusB, &coeffTarget(0, index),
1150 &coeffTarget(1, index));
1151 index++;
1152
1153 std::vector<double> lookBWRTRadiusC =
1154 measureCamera->GroundMap()->EllipsoidPartial(surfacePoint,
1155 CameraGroundMap::WRT_PolarAxis);
1156
1157 measureCamera->GroundMap()->GetdXYdPoint(lookBWRTRadiusC, &coeffTarget(0, index),
1158 &coeffTarget(1, index));
1159 index++;
1160 }
1161
1162 double observationSigma = 1.4 * measureCamera->PixelPitch();
1163 double observationWeight = 1.0 / observationSigma;
1164
1165 // Multiply coefficients by observation weight
1166 coeffTarget *= observationWeight;
1167
1168 return true;
1169 }
1170
1171
1184 bool IsisBundleObservation::computeImagePartials(matrix<double> &coeffImage, BundleMeasure &measure) {
1185 coeffImage.clear();
1186
1187 Camera *camera = measure.camera();
1188
1189 int index = 0;
1190
1191 // Parials for X, Y, Z position coordinates
1192 if (solveSettings()->instrumentPositionSolveOption() !=
1194
1195 int numCamPositionCoefficients =
1196 solveSettings()->numberCameraPositionCoefficientsSolved();
1197
1198 // Add the partial for the x coordinate of the position (differentiating
1199 // point(x,y,z) - spacecraftPosition(x,y,z) in J2000
1200 for (int cameraCoef = 0; cameraCoef < numCamPositionCoefficients; cameraCoef++) {
1201 camera->GroundMap()->GetdXYdPosition(SpicePosition::WRT_X, cameraCoef,
1202 &coeffImage(0, index),
1203 &coeffImage(1, index));
1204 index++;
1205 }
1206
1207 // Add the partial for the y coordinate of the position
1208 for (int cameraCoef = 0; cameraCoef < numCamPositionCoefficients; cameraCoef++) {
1209 camera->GroundMap()->GetdXYdPosition(SpicePosition::WRT_Y, cameraCoef,
1210 &coeffImage(0, index),
1211 &coeffImage(1, index));
1212 index++;
1213 }
1214
1215 // Add the partial for the z coordinate of the position
1216 for (int cameraCoef = 0; cameraCoef < numCamPositionCoefficients; cameraCoef++) {
1217 camera->GroundMap()->GetdXYdPosition(SpicePosition::WRT_Z, cameraCoef,
1218 &coeffImage(0, index),
1219 &coeffImage(1, index));
1220 index++;
1221 }
1222 }
1223
1224 // Partials for RA, DEC, twist
1225 if (solveSettings() ->instrumentPointingSolveOption() !=
1227
1228 int numCamAngleCoefficients =
1229 solveSettings()->numberCameraAngleCoefficientsSolved();
1230
1231 // Add the partials for ra
1232 for (int cameraCoef = 0; cameraCoef < numCamAngleCoefficients; cameraCoef++) {
1234 cameraCoef, &coeffImage(0, index),
1235 &coeffImage(1, index));
1236 index++;
1237 }
1238
1239 // Add the partials for dec
1240 for (int cameraCoef = 0; cameraCoef < numCamAngleCoefficients; cameraCoef++) {
1242 cameraCoef, &coeffImage(0, index),
1243 &coeffImage(1, index));
1244 index++;
1245 }
1246
1247 // Add the partial for twist if necessary
1248 if (solveSettings()->solveTwist()) {
1249 for (int cameraCoef = 0; cameraCoef < numCamAngleCoefficients; cameraCoef++) {
1251 cameraCoef, &coeffImage(0, index),
1252 &coeffImage(1, index));
1253 index++;
1254 }
1255 }
1256 }
1257
1258 // Multiply coefficients by observation weight
1259 double observationSigma = 1.4 * camera->PixelPitch();
1260 double observationWeight = 1.0 / observationSigma;
1261 coeffImage *= observationWeight;
1262
1263 return true;
1264 }
1265
1266
1281 bool IsisBundleObservation::computePoint3DPartials(matrix<double> &coeffPoint3D, BundleMeasure &measure, SurfacePoint::CoordinateType coordType) {
1282 coeffPoint3D.clear();
1283 Camera *measureCamera = measure.camera();
1284 BundleControlPoint* point = measure.parentControlPoint();
1285
1286 // These vectors are either body-fixed latitudinal (lat/lon/radius) or rectangular (x/y/z)
1287 // depending on the value of coordinate type in SurfacePoint
1288 std::vector<double> lookBWRTCoord1 = point->adjustedSurfacePoint().Partial(coordType, SurfacePoint::One);
1289 std::vector<double> lookBWRTCoord2 = point->adjustedSurfacePoint().Partial(coordType, SurfacePoint::Two);
1290 std::vector<double> lookBWRTCoord3 = point->adjustedSurfacePoint().Partial(coordType, SurfacePoint::Three);
1291
1292 measureCamera->GroundMap()->GetdXYdPoint(lookBWRTCoord1,
1293 &coeffPoint3D(0, 0),
1294 &coeffPoint3D(1, 0));
1295 measureCamera->GroundMap()->GetdXYdPoint(lookBWRTCoord2,
1296 &coeffPoint3D(0, 1),
1297 &coeffPoint3D(1, 1));
1298 measureCamera->GroundMap()->GetdXYdPoint(lookBWRTCoord3,
1299 &coeffPoint3D(0, 2),
1300 &coeffPoint3D(1, 2));
1301
1302 double observationSigma = 1.4 * measureCamera->PixelPitch();
1303 double observationWeight = 1.0 / observationSigma;
1304
1305 // Multiply coefficients by observation weight
1306 coeffPoint3D *= observationWeight;
1307
1308 return true;
1309 }
1310
1311
1324 bool IsisBundleObservation::computeRHSPartials(boost::numeric::ublas::vector<double> &coeffRHS, BundleMeasure &measure) {
1325 coeffRHS.clear();
1326 Camera *measureCamera = measure.camera();
1327 BundleControlPoint* point = measure.parentControlPoint();
1328 // Compute the look vector in instrument coordinates based on time of observation and apriori
1329 // lat/lon/radius. As of 05/15/2019, this call no longer does the back-of-planet test. An optional
1330 // bool argument was added CameraGroundMap::GetXY to turn off the test.
1331 double computedX, computedY;
1332 if (!(measureCamera->GroundMap()->GetXY(point->adjustedSurfacePoint(),
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";
1336 throw IException(IException::User, msg, _FILEINFO_);
1337 }
1338
1339 double measuredX = measure.focalPlaneMeasuredX();
1340 double measuredY = measure.focalPlaneMeasuredY();
1341
1342 double deltaX = measuredX - computedX;
1343 double deltaY = measuredY - computedY;
1344
1345 coeffRHS(0) = deltaX;
1346 coeffRHS(1) = deltaY;
1347
1348 // Multiply coefficients by observation weight
1349 double observationSigma = 1.4 * measureCamera->PixelPitch();
1350 double observationWeight = 1.0 / observationSigma;
1351
1352 coeffRHS *= observationWeight;
1353
1354 return true;
1355 }
1356
1357
1371 return deltaVal * 1.4;
1372 }
1373}
1374
This class holds information about a control point that BundleAdjust needs to run correctly.
SurfacePoint adjustedSurfacePoint() const
Accesses the adjusted SurfacePoint associated with this BundleControlPoint.
QString id() const
Accesses the Point ID associated with this BundleControlPoint.
A container class for a ControlMeasure.
Abstract base class for an observation in bundle adjustment.
int index()
Accesses the observation's index.
LinearAlgebra::Vector m_aprioriSigmas
A posteriori (adjusted) parameter sigmas.
LinearAlgebra::Vector m_adjustedSigmas
A posteriori (adjusted) parameter sigmas.
LinearAlgebra::Vector m_weights
Parameter weights. Cumulative parameter correction vector.
virtual BundleObservation & operator=(const BundleObservation &src)
Assignment operator.
This class is used to modify and manage solve settings for 1 to many BundleObservations.
InstrumentPositionSolveOption
Options for how to solve for instrument position.
@ NoPositionFactors
Solve for none of the position factors.
static QString instrumentPointingSolveOptionToString(InstrumentPointingSolveOption option)
Tranlsates an enumerated InstrumentPointingSolveOption value to its string representation.
static QString instrumentPositionSolveOptionToString(InstrumentPositionSolveOption option)
Translates an enumerated InstrumentPositionSolveOption to its string representation.
InstrumentPointingSolveOption
Options for how to solve for instrument pointing.
@ NoPointingFactors
Solve for none of the pointing factors.
virtual bool GetdXYdPosition(const SpicePosition::PartialType varType, int coefIndex, double *cudx, double *cudy)
Compute derivative w/r to position of focal plane coordinate from ground position using current Spice...
virtual bool GetdXYdOrientation(const SpiceRotation::PartialType varType, int coefIndex, double *cudx, double *cudy)
Compute derivative of focal plane coordinate w/r to instrument using current state from SetImage call...
double PixelPitch() const
Returns the pixel pitch.
Definition Camera.cpp:2772
CameraGroundMap * GroundMap()
Returns a pointer to the CameraGroundMap object.
Definition Camera.cpp:2886
Isis exception class.
Definition IException.h:91
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition IException.h:118
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
Class for observations that use ISIS camera models in bundle adjustment.
SpiceRotation * m_instrumentRotation
Instrument spice rotation (in primary image).
const BundleObservationSolveSettingsQsp solveSettings()
Accesses the solve settings.
int numberParameters()
Returns the number of total parameters there are for solving.
IsisBundleObservation()
Constructs a IsisBundleObservation initialized to a default state.
virtual QStringList parameterList()
Returns the list of observation parameter names.
bool initParameterWeights()
Initializes the paramater weights for solving.
QString bundleOutputCSV(bool errorPropagation)
Creates and returns a formatted QString representing the bundle coefficients and parameters in csv fo...
bool computeImagePartials(LinearAlgebra::Matrix &coeffImage, BundleMeasure &measure)
Calculates the sensor partials with respect to the selected solve parameters and populates the coeffI...
BundleObservationSolveSettingsQsp m_solveSettings
Solve settings for this observation.
SpiceRotation * spiceRotation()
Accesses the instrument's spice rotation.
void updateBodyRotation()
Updates the body rotation.
void bundleOutputFetchData(QVector< double > &finalParameterValues, int &nPositionCoefficients, int &nPointingCoefficients, bool &useDefaultPosition, bool &useDefaultPointing, bool &useDefaultTwist)
Fetches data for the log file output methods.
void initializeBodyRotation()
Intializes the body rotation.
double computeObservationValue(BundleMeasure &measure, double deltaVal)
Converts the observed value from a focal plane coordinate to an image sample or line.
bool computeRHSPartials(LinearAlgebra::Vector &coeffRHS, BundleMeasure &measure)
Calculates the sample, line residuals between the measured focal plane values and the focal plane coo...
bool initializeExteriorOrientation()
Initializes the exterior orientation.
bool applyParameterCorrections(LinearAlgebra::Vector corrections)
Applies the parameter corrections.
virtual bool setSolveSettings(BundleObservationSolveSettings solveSettings)
Set solve parameters.
int numberPointingParameters()
Returns the number of pointing parameters being solved for.
int numberPositionParameters()
Returns the number of position parameters there are.
IsisBundleObservation & operator=(const IsisBundleObservation &src)
Assignment operator.
void bundleOutputString(std::ostream &fpOut, bool errorPropagation)
Takes in an open std::ofstream and writes out information which goes into the bundleout....
bool computePoint3DPartials(LinearAlgebra::Matrix &coeffPoint3D, BundleMeasure &measure, SurfacePoint::CoordinateType coordType)
Calculates the ground partials for the ground point currently set in the sensor model.
SpicePosition * spicePosition()
Accesses the instrument's spice position.
SpicePosition * m_instrumentPosition
Instrument spice position (in primary image).
bool computeTargetPartials(LinearAlgebra::Matrix &coeffTarget, BundleMeasure &measure, BundleSettingsQsp &bundleSettings, BundleTargetBodyQsp &bundleTargetBody)
Computes any needed partials for the target body parameters.
BundleTargetBodyQsp m_bundleTargetBody
QShared pointer to BundleTargetBody.
boost::numeric::ublas::vector< double > Vector
Definition for an Isis::LinearAlgebra::Vector of doubles.
Obtain SPICE position information for a body.
double GetTimeScale()
Return the time scale for the position.
void SetOverrideBaseTime(double baseTime, double timeScale)
Set an override base time to be used with observations on scanners to allow all images in an observat...
void GetPolynomial(std::vector< double > &XC, std::vector< double > &YC, std::vector< double > &ZC)
Return the coefficients of a polynomial fit to each of the three coordinates of the position for the ...
double GetBaseTime()
Return the base time for the position.
void SetPolynomial(const Source type=PolyFunction)
Set the coefficients of a polynomial fit to each of the components (X, Y, Z) of the position vector f...
const std::vector< double > & GetCenterCoordinate()
Compute and return the coordinate at the center time.
void SetPolynomialDegree(int degree)
Set the polynomial degree.
Obtain SPICE rotation information for a body.
void SetPolynomial(const Source type=PolyFunction)
Set the coefficients of a polynomial fit to each of the three camera angles for the time period cover...
std::vector< double > GetCenterAngles()
Return the camera angles at the center time of the observation.
void GetPolynomial(std::vector< double > &abcAng1, std::vector< double > &abcAng2, std::vector< double > &abcAng3)
Return the coefficients of a polynomial fit to each of the three camera angles for the time period co...
@ WRT_RightAscension
With respect to Right Ascension.
@ WRT_Twist
With respect to Twist or Prime Meridian Rotation.
@ WRT_Declination
With respect to Declination.
This class defines a body-fixed surface point.
CoordinateType
Defines the coordinate typ, units, and coordinate index for some of the output methods.
std::vector< double > Partial(CoordinateType type, CoordIndex index)
Compute partial derivative of conversion from body-fixed coordinates to the specified.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
const double DEG2RAD
Multiplier for converting from degrees to radians.
Definition Constants.h:43
const double Null
Value for an Isis Null pixel.
QSharedPointer< BundleObservationSolveSettings > BundleObservationSolveSettingsQsp
Definition for BundleObservationSolveSettingsQsp, a QSharedPointer to a BundleObservationSolveSetting...
bool IsSpecial(const double d)
Returns if the input pixel is special.
const double RAD2DEG
Multiplier for converting from radians to degrees.
Definition Constants.h:44
Namespace for the standard library.