Isis 3 Programmer Reference
BundleObservationSolveSettings.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "BundleObservationSolveSettings.h"
10
11#include <QDataStream>
12#include <QDebug>
13#include <QFile>
14#include <QList>
15#include <QSet>
16#include <QString>
17#include <QUuid>
18#include <QXmlInputSource>
19#include <QXmlStreamWriter>
20
21#include "BundleImage.h"
22#include "Camera.h"
23#include "FileName.h"
24#include "IException.h"
25#include "IString.h"
26#include "Project.h"
27#include "PvlKeyword.h"
28#include "PvlObject.h"
29#include "XmlStackedHandlerReader.h"
30
31
32namespace Isis {
33
40
41
50 Project *project,
51 XmlStackedHandlerReader *xmlReader) {
52 initialize();
53 xmlReader->pushContentHandler(new XmlHandler(this, project));
54 xmlReader->setErrorHandler(new XmlHandler(this, project));
55 }
56
57
59 initialize();
60
61 // group name must be instrument id
62 m_instrumentId = (QString)scParameterGroup.nameKeyword();
63
64 // If CKDEGREE is not specified, then a default of 2 is used
65 if (scParameterGroup.hasKeyword("CKDEGREE")) {
66 m_ckDegree = (int)(scParameterGroup.findKeyword("CKDEGREE"));
67 }
68
69 // If CKSOLVEDEGREE is not specified, then a default of 2 is used
70 if (scParameterGroup.hasKeyword("CKSOLVEDEGREE")) {
71 m_ckSolveDegree = (int) (scParameterGroup.findKeyword("CKSOLVEDEGREE"));
72 }
73
74 // do we solve for No pointing, ANGLES only, ANGLES+ANGULAR VELOCITY, ANGLES+ANGULAR VELOCITY+
75 // ANGULAR ACCELERATION, or a higher order polynomial
76 QString csolve = "NONE";
77 csolve = (QString)scParameterGroup.findKeyword("CAMSOLVE");
78 csolve = csolve.toUpper();
79 if (csolve == "NONE") {
82 }
83 else if (csolve == "ANGLES") {
86 }
87 else if (csolve == "VELOCITIES") {
90 }
91 else if (csolve == "ACCELERATIONS") {
94 }
95 else if (csolve == "ALL"){
98 }
99
100 // If OVEREXISTING is not specified, then a default of NO is used
101 if (scParameterGroup.hasKeyword("OVEREXISTING")) {
102 QString parval = (QString)scParameterGroup.findKeyword("OVEREXISTING");
103 parval = parval.toUpper();
104 if (parval == "TRUE" || parval == "YES") {
107 }
108 else if (parval == "FALSE" || parval == "NO") {
111 }
112 else {
113 QString msg = "The OVEREXISTING parameter must be set to TRUE or FALSE; YES or NO";
114 throw IException(IException::User, msg, _FILEINFO_);
115 }
116 }
117
118 // If SPKDEGREE is not specified, then a default of 2 is used
119 if (scParameterGroup.hasKeyword("SPKDEGREE"))
120 m_spkDegree = (int)(scParameterGroup.findKeyword("SPKDEGREE"));
121
122 // If SPKSOLVEDEGREE is not specified, then a default of 2 is used
123 if (scParameterGroup.hasKeyword("SPKSOLVEDEGREE"))
124 m_spkSolveDegree = (int)(scParameterGroup.findKeyword("SPKSOLVEDEGREE"));
125
126 // do we solve for No position, POSITION only, POSITION+VELOCITY, POSITION+VELOCITY+
127 // ACCELERATION, or a higher order polynomial
128 QString ssolve = "NONE";
129 ssolve = (QString)scParameterGroup.findKeyword("SPSOLVE");
130 ssolve = ssolve.toUpper();
131 if (ssolve == "NONE") {
134 }
135 else if (ssolve == "POSITION") {
138 }
139 else if (ssolve == "VELOCITIES") {
142 }
143 else if (ssolve == "ACCELERATIONS") {
146 }
147 else if (csolve == "ALL"){
150 }
151
152 // If TWIST is not specified, then a default of YES is used
153 if (scParameterGroup.hasKeyword("TWIST")) {
154 QString parval = (QString)scParameterGroup.findKeyword("TWIST");
155 parval = parval.toUpper();
156 if (parval == "TRUE" || parval == "YES") { // is this necessary ??? i think pvl and toString can handle it...
157 m_solveTwist = true;
158 }
159 else if (parval == "FALSE" || parval == "NO") {
160 m_solveTwist = false;
161 }
162 else {
163 QString msg = "The TWIST parameter must be set to TRUE or FALSE; YES or NO";
164 throw IException(IException::User, msg, _FILEINFO_);
165 }
166 }
167 // If OVERHERMITE is not specified, then a default of NO is used
168 if (scParameterGroup.hasKeyword("OVERHERMITE")) {
169 QString parval = (QString)scParameterGroup.findKeyword("OVERHERMITE");
170 parval = parval.toUpper();
171 if (parval == "TRUE" || parval == "YES") {
174 }
175 else if (parval == "FALSE" || parval == "NO") {
178 }
179 else {
180 QString msg = "The OVERHERMITE parameter must be set to TRUE or FALSE; YES or NO";
181 throw IException(IException::User, msg, _FILEINFO_);
182 }
183 }
184
186 if (scParameterGroup.hasKeyword("CAMERA_ANGLES_SIGMA")) {
187 m_anglesAprioriSigma.append((double)(scParameterGroup.findKeyword("CAMERA_ANGLES_SIGMA")));
188 }
189 else {
191 }
192 if (scParameterGroup.hasKeyword("CAMERA_ANGULAR_VELOCITY_SIGMA")){
194 (double)(scParameterGroup.findKeyword("CAMERA_ANGULAR_VELOCITY_SIGMA")));
195 }
196 else {
198 }
199 if (scParameterGroup.hasKeyword("CAMERA_ANGULAR_ACCELERATION_SIGMA")){
201 (double)(scParameterGroup.findKeyword("CAMERA_ANGULAR_ACCELERATION_SIGMA")));
202 }
203 else {
205 }
206 if (scParameterGroup.hasKeyword("ADDITIONAL_CAMERA_POINTING_SIGMAS")) {
207 PvlKeyword additionalSigmas = scParameterGroup.findKeyword("ADDITIONAL_CAMERA_POINTING_SIGMAS");
208 for (int i = 0; i < additionalSigmas.size(); i++ ) {
209 m_anglesAprioriSigma.append(toDouble(additionalSigmas[i]));
210 }
211 }
212 }
213
215 if (scParameterGroup.hasKeyword("SPACECRAFT_POSITION_SIGMA")) {
216 m_positionAprioriSigma.append((double)(scParameterGroup.findKeyword("SPACECRAFT_POSITION_SIGMA")));
217 }
218 else {
220 }
221 if (scParameterGroup.hasKeyword("SPACECRAFT_VELOCITY_SIGMA")){
222 m_positionAprioriSigma.append((double)(scParameterGroup.findKeyword("SPACECRAFT_VELOCITY_SIGMA")));
223 }
224 else {
226 }
227 if (scParameterGroup.hasKeyword("SPACECRAFT_ACCELERATION_SIGMA")) {
228 m_positionAprioriSigma.append((double)(scParameterGroup.findKeyword("SPACECRAFT_ACCELERATION_SIGMA")));
229 }
230 else {
232 }
233 if (scParameterGroup.hasKeyword("ADDITIONAL_SPACECRAFT_POSITION_SIGMAS")) {
234 PvlKeyword additionalSigmas = scParameterGroup.findKeyword("ADDITIONAL_SPACECRAFT_POSITION_SIGMAS");
235 for (int i = 0; i < additionalSigmas.size(); i++ ) {
236 m_positionAprioriSigma.append(toDouble(additionalSigmas[i]));
237 }
238 }
239 }
240
241 // CSM settings
242 if (scParameterGroup.hasKeyword("CSMSOLVESET")) {
243 setCSMSolveSet(stringToCSMSolveSet(scParameterGroup.findKeyword("CSMSOLVESET")));
244 }
245 else if (scParameterGroup.hasKeyword("CSMSOLVETYPE")) {
246 setCSMSolveType(stringToCSMSolveType(scParameterGroup.findKeyword("CSMSOLVETYPE")));
247 }
248 else if (scParameterGroup.hasKeyword("CSMSOLVELIST")) {
249 PvlKeyword csmSolveListKey = scParameterGroup.findKeyword("CSMSOLVELIST");
250 QStringList csmSolveList;
251 for (int i = 0; i < csmSolveListKey.size(); i++) {
252 csmSolveList.append(csmSolveListKey[i]);
253 }
254 setCSMSolveParameterList(csmSolveList);
255 }
256 }
257
258
265
266 m_id = NULL;
267 m_id = new QUuid(other.m_id->toString());
268 // TODO: add check to all copy constructors (verify other.xxx is not null) and operator= ???
269 // or intit all variables in all constructors
270
271 m_instrumentId = other.m_instrumentId;
272 m_csmSolveOption = other.m_csmSolveOption;
273 m_csmSolveSet = other.m_csmSolveSet;
274 m_csmSolveType = other.m_csmSolveType;
275 m_csmSolveList = other.m_csmSolveList;
276 m_instrumentPointingSolveOption = other.m_instrumentPointingSolveOption;
277 m_observationNumbers = other.m_observationNumbers;
278 m_numberCamAngleCoefSolved = other.m_numberCamAngleCoefSolved;
279 m_ckDegree = other.m_ckDegree;
280 m_ckSolveDegree = other.m_ckSolveDegree;
281 m_solveTwist = other.m_solveTwist;
282 m_solvePointingPolynomialOverExisting = other.m_solvePointingPolynomialOverExisting;
283 m_anglesAprioriSigma = other.m_anglesAprioriSigma;
284 m_pointingInterpolationType = other.m_pointingInterpolationType;
285 m_instrumentPositionSolveOption = other.m_instrumentPositionSolveOption;
286 m_numberCamPosCoefSolved = other.m_numberCamPosCoefSolved;
287 m_spkDegree = other.m_spkDegree;
288 m_spkSolveDegree = other.m_spkSolveDegree;
289 m_solvePositionOverHermiteSpline = other.m_solvePositionOverHermiteSpline;
290 m_positionAprioriSigma = other.m_positionAprioriSigma;
291 m_positionInterpolationType = other.m_positionInterpolationType;
292 }
293
294
304
305
316 if (&other != this) {
317 delete m_id;
318 m_id = NULL;
319 m_id = new QUuid(other.m_id->toString());
320
321 m_instrumentId = other.m_instrumentId;
322 m_observationNumbers = other.m_observationNumbers;
323
324 // CSM related
325 m_csmSolveOption = other.m_csmSolveOption;
326 m_csmSolveSet = other.m_csmSolveSet;
327 m_csmSolveType = other.m_csmSolveType;
328 m_csmSolveList = other.m_csmSolveList;
329
330 // pointing related
331 m_instrumentPointingSolveOption = other.m_instrumentPointingSolveOption;
332 m_numberCamAngleCoefSolved = other.m_numberCamAngleCoefSolved;
333 m_ckDegree = other.m_ckDegree;
334 m_ckSolveDegree = other.m_ckSolveDegree;
335 m_solveTwist = other.m_solveTwist;
336 m_solvePointingPolynomialOverExisting = other.m_solvePointingPolynomialOverExisting;
337 m_pointingInterpolationType = other.m_pointingInterpolationType;
338 m_anglesAprioriSigma = other.m_anglesAprioriSigma;
339
340 // position related
341 m_instrumentPositionSolveOption = other.m_instrumentPositionSolveOption;
342 m_numberCamPosCoefSolved = other.m_numberCamPosCoefSolved;
343 m_spkDegree = other.m_spkDegree;
344 m_spkSolveDegree = other.m_spkSolveDegree;
345 m_solvePositionOverHermiteSpline = other.m_solvePositionOverHermiteSpline;
346 m_positionInterpolationType = other.m_positionInterpolationType;
347 m_positionAprioriSigma = other.m_positionAprioriSigma;
348
349 }
350
351 return *this;
352
353 }
354
355
360 m_id = NULL;
361 m_id = new QUuid(QUuid::createUuid());
362
363 m_instrumentId = "";
364
365 // CSM solve options
367 m_csmSolveSet = csm::param::ADJUSTABLE;
368 m_csmSolveType = csm::param::REAL;
370
371 // Camera Pointing Options
372 // Defaults:
373 // m_instrumentPointingSolveOption = AnglesOnly;
374 // m_numberCamAngleCoefSolved = 1; // AnglesOnly;
375 // m_ckDegree = 2;
376 // m_ckSolveDegree = 2;
377 // m_solveTwist = true;
378 // m_solvePointingPolynomialOverExisting = false;
379 // m_pointingInterpolationType = SpiceRotation::PolyFunction;
380 // m_anglesAprioriSigma.append(Isis::Null); // num cam angle
381 // coef = 1
382 setInstrumentPointingSettings(AnglesOnly, true, 2, 2, false);
383
384 // Spacecraft Position Options
385 // Defaults:
386 // m_instrumentPositionSolveOption = NoPositionFactors;
387 // m_numberCamPosCoefSolved = 0; // NoPositionFactors;
388 // m_spkDegree = 2;
389 // m_spkSolveDegree = 2;
390 // m_solvePositionOverHermiteSpline = false;
391 // m_positionInterpolationType = SpicePosition::PolyFunction;
392 // m_positionAprioriSigma.clear();
394
395 }
396
397
398 // =============================================================================================//
399 // =============================================================================================//
400 // =============================================================================================//
401
410
411
420
421
430 m_observationNumbers.insert(observationNumber);
431 }
432
433
443 return m_observationNumbers.remove(observationNumber);
444 }
445
446
455
456
457 // =============================================================================================//
458 // ======================== CSM Options ========================================================//
459 // =============================================================================================//
460
461
471 if (option.compare("NoCSMParameters", Qt::CaseInsensitive) == 0) {
473 }
474 else if (option.compare("Set", Qt::CaseInsensitive) == 0) {
476 }
477 else if (option.compare("Type", Qt::CaseInsensitive) == 0) {
479 }
480 else if (option.compare("List", Qt::CaseInsensitive) == 0) {
482 }
483 else {
485 "Unknown bundle CSM solve option " + option + ".",
486 _FILEINFO_);
487 }
488 }
489
490
500 return "NoCSMParameters";
501 }
502 else if (option == BundleObservationSolveSettings::Set) {
503 return "Set";
504 }
505 else if (option == BundleObservationSolveSettings::Type) {
506 return "Type";
507 }
508 else if (option == BundleObservationSolveSettings::List) {
509 return "List";
510 }
511 else {
513 "Unknown CSM solve option enum [" + toString(option) + "].",
514 _FILEINFO_);
515 }
516 }
517
518
527 if (set.compare("VALID", Qt::CaseInsensitive) == 0) {
528 return csm::param::VALID;
529 }
530 else if (set.compare("ADJUSTABLE", Qt::CaseInsensitive) == 0) {
531 return csm::param::ADJUSTABLE;
532 }
533 else if (set.compare("NON_ADJUSTABLE", Qt::CaseInsensitive) == 0) {
534 return csm::param::NON_ADJUSTABLE;
535 }
536 else {
538 "Unknown bundle CSM parameter set " + set + ".",
539 _FILEINFO_);
540 }
541 }
542
543
552 if (set == csm::param::VALID) {
553 return "VALID";
554 }
555 else if (set == csm::param::ADJUSTABLE) {
556 return "ADJUSTABLE";
557 }
558 else if (set == csm::param::NON_ADJUSTABLE) {
559 return "NON_ADJUSTABLE";
560 }
561 else {
563 "Unknown CSM parameter set enum [" + toString(set) + "].",
564 _FILEINFO_);
565 }
566 }
567
568
577 if (type.compare("NONE", Qt::CaseInsensitive) == 0) {
578 return csm::param::NONE;
579 }
580 else if (type.compare("FICTITIOUS", Qt::CaseInsensitive) == 0) {
581 return csm::param::FICTITIOUS;
582 }
583 else if (type.compare("REAL", Qt::CaseInsensitive) == 0) {
584 return csm::param::REAL;
585 }
586 else if (type.compare("FIXED", Qt::CaseInsensitive) == 0) {
587 return csm::param::FIXED;
588 }
589 else {
591 "Unknown bundle CSM parameter type " + type + ".",
592 _FILEINFO_);
593 }
594 }
595
596
605 if (type == csm::param::NONE) {
606 return "NONE";
607 }
608 else if (type == csm::param::FICTITIOUS) {
609 return "FICTITIOUS";
610 }
611 else if (type == csm::param::REAL) {
612 return "REAL";
613 }
614 else if (type == csm::param::FIXED) {
615 return "FIXED";
616 }
617 else {
619 "Unknown CSM parameter type enum [" + toString(type) + "].",
620 _FILEINFO_);
621 }
622 }
623
624
635
636
646
647
657
658
668
669
676 return m_csmSolveSet;
677 }
678
679
686 return m_csmSolveType;
687 }
688
689
698
699
700 // =============================================================================================//
701 // ======================== Camera Pointing Options ============================================//
702 // =============================================================================================//
703
704
717 if (option.compare("NONE", Qt::CaseInsensitive) == 0) {
719 }
720 else if (option.compare("NoPointingFactors", Qt::CaseInsensitive) == 0) {
722 }
723 else if (option.compare("ANGLES", Qt::CaseInsensitive) == 0) {
725 }
726 else if (option.compare("AnglesOnly", Qt::CaseInsensitive) == 0) {
728 }
729 else if (option.compare("VELOCITIES", Qt::CaseInsensitive) == 0) {
731 }
732 else if (option.compare("AnglesAndVelocity", Qt::CaseInsensitive) == 0) {
734 }
735 else if (option.compare("ACCELERATIONS", Qt::CaseInsensitive) == 0) {
737 }
738 else if (option.compare("AnglesVelocityAndAcceleration", Qt::CaseInsensitive) == 0) {
740 }
741 else if (option.compare("ALL", Qt::CaseInsensitive) == 0) {
743 }
744 else if (option.compare("AllPolynomialCoefficients", Qt::CaseInsensitive) == 0) {
746 }
747 else {
749 "Unknown bundle instrument pointing solve option " + option + ".",
750 _FILEINFO_);
751 }
752 }
753
754
767 if (option == NoPointingFactors) return "None";
768 else if (option == AnglesOnly) return "AnglesOnly";
769 else if (option == AnglesVelocity) return "AnglesAndVelocity";
770 else if (option == AnglesVelocityAcceleration) return "AnglesVelocityAndAcceleration";
771 else if (option == AllPointingCoefficients) return "AllPolynomialCoefficients";
773 "Unknown pointing solve option enum [" + toString(option) + "].",
774 _FILEINFO_);
775 }
776
777
793 bool solveTwist,
794 int ckDegree,
795 int ckSolveDegree,
796 bool solvePolynomialOverExisting,
797 double anglesAprioriSigma,
798 double angularVelocityAprioriSigma,
799 double angularAccelerationAprioriSigma,QList<double> * additionalPointingSigmas) {
800
801 // automatically set the solve option and ck degree to the user entered values
803
804 // the ck solve degree entered is only used if we are solving for all coefficients
805 // otherwise it defaults to 2.
806 if (option == AllPointingCoefficients) {
807 // update spkDegree and spkSolveDegree
810
811 // we are solving for (solve degree + 1) coefficients
812 // this is the maximum number of apriori sigmas allowed
814 }
815 else {
816 // let spkDegree and spkSolveDegree default to 2, 2
817 m_ckDegree = 2;
818 m_ckSolveDegree = 2;
819
820 // solve for the appropriate number of coefficients, based on solve option enum
821 m_numberCamAngleCoefSolved = ((int) option);
822 }
823
824 m_anglesAprioriSigma.clear();
826 if (anglesAprioriSigma > 0.0) {
827 m_anglesAprioriSigma.append(anglesAprioriSigma);
828 }
829 else {
831 }
832
834 if (angularVelocityAprioriSigma > 0.0) {
835 m_anglesAprioriSigma.append(angularVelocityAprioriSigma);
836 }
837 else {
839 }
840
842 if (angularAccelerationAprioriSigma > 0.0) {
843 m_anglesAprioriSigma.append(angularAccelerationAprioriSigma);
844 }
845 else {
847 }
848 }
849 }
850 }
851
852 if (additionalPointingSigmas) {
853 for (int i=0;i < additionalPointingSigmas->count();i++) {
854 m_anglesAprioriSigma.append(additionalPointingSigmas->value(i));
855 }
856 }
857
858
859
860
861
862 m_solveTwist = solveTwist; // dependent on solve option???
863
864 // Set the SpiceRotation interpolation type enum appropriately
865 m_solvePointingPolynomialOverExisting = solvePolynomialOverExisting;
868 }
869 else {
871 }
872
873 }
874
875
886
887
896
897
906
907
917
918
927
928
938
939
948
949
958
959
960 // =============================================================================================//
961 // ======================== Spacecraft Position Options ========================================//
962 // =============================================================================================//
963
964
977 if (option.compare("NONE", Qt::CaseInsensitive) == 0) {
979 }
980 else if (option.compare("NoPositionFactors", Qt::CaseInsensitive) == 0) {
982 }
983 else if (option.compare("POSITIONS", Qt::CaseInsensitive) == 0) {
985 }
986 else if (option.compare("PositionOnly", Qt::CaseInsensitive) == 0) {
988 }
989 else if (option.compare("VELOCITIES", Qt::CaseInsensitive) == 0) {
991 }
992 else if (option.compare("PositionAndVelocity", Qt::CaseInsensitive) == 0) {
994 }
995 else if (option.compare("ACCELERATIONS", Qt::CaseInsensitive) == 0) {
997 }
998 else if (option.compare("PositionVelocityAndAcceleration", Qt::CaseInsensitive) == 0) {
1000 }
1001 else if (option.compare("ALL", Qt::CaseInsensitive) == 0) {
1003 }
1004 else if (option.compare("AllPolynomialCoefficients", Qt::CaseInsensitive) == 0) {
1006 }
1007 else {
1009 "Unknown bundle instrument position solve option " + option + ".",
1010 _FILEINFO_);
1011 }
1012 }
1013
1014
1027 if (option == NoPositionFactors) return "None";
1028 else if (option == PositionOnly) return "PositionOnly";
1029 else if (option == PositionVelocity) return "PositionAndVelocity";
1030 else if (option == PositionVelocityAcceleration) return "PositionVelocityAndAcceleration";
1031 else if (option == AllPositionCoefficients) return "AllPolynomialCoefficients";
1033 "Unknown position solve option enum [" + toString(option) + "].",
1034 _FILEINFO_);
1035 }
1036
1037
1051 int spkDegree,
1052 int spkSolveDegree,
1053 bool positionOverHermite,
1054 double positionAprioriSigma,
1055 double velocityAprioriSigma,
1056 double accelerationAprioriSigma,
1057 QList<double> *additionalPositionSigmas) {
1058 // automatically set the solve option and spk degree to the user entered values
1060
1061 // the spk solve degree entered is only used if we are solving for all coefficients
1062 // otherwise it defaults to 2.
1063 if (option == AllPositionCoefficients) {
1064 // update spkDegree and spkSolveDegree
1067 // we are solving for (solve degree + 1) coefficients
1068 // this is the maximum number of apriori sigmas allowed
1070 }
1071 else {
1072 // let spkDegree and spkSolveDegree default to 2, 2
1073 m_spkDegree = 2;
1074 m_spkSolveDegree = 2;
1075
1076 // solve for the appropriate number of coefficients, based on solve option enum
1077 m_numberCamPosCoefSolved = ((int) option);
1078 }
1079
1080 m_positionAprioriSigma.clear();
1081 if (m_numberCamPosCoefSolved > 0) {
1082 if (positionAprioriSigma > 0.0) {
1083 m_positionAprioriSigma.append(positionAprioriSigma);
1084 }
1085 else {
1087 }
1088
1089 if (m_numberCamPosCoefSolved > 1) {
1090 if (velocityAprioriSigma > 0.0) {
1091 m_positionAprioriSigma.append(velocityAprioriSigma);
1092 }
1093 else {
1095 }
1096
1097 if (m_numberCamPosCoefSolved > 2) {
1098 if (accelerationAprioriSigma > 0.0) {
1099 m_positionAprioriSigma.append(accelerationAprioriSigma);
1100 }
1101 else {
1103 }
1104 }
1105 }
1106 }
1107
1108 if (additionalPositionSigmas) {
1109 for (int i=0;i < additionalPositionSigmas->count();i++) {
1110 m_positionAprioriSigma.append(additionalPositionSigmas->value(i));
1111 }
1112 }
1113
1114 // Set the SpicePosition interpolation type enum appropriately
1115 m_solvePositionOverHermiteSpline = positionOverHermite;
1118 }
1119 else {
1121 }
1122
1123 }
1124
1125
1136
1137
1146
1147
1157
1158
1167
1168
1178
1179
1188
1189
1198
1199
1200 // =============================================================================================//
1201 // =============================================================================================//
1202 // =============================================================================================//
1203
1204
1214 void BundleObservationSolveSettings::save(QXmlStreamWriter &stream,
1215 const Project *project) const {
1216
1217 stream.writeStartElement("bundleObservationSolveSettings");
1218 stream.writeTextElement("id", m_id->toString());
1219 stream.writeTextElement("instrumentId", instrumentId());
1220
1221 // pointing related
1222 stream.writeStartElement("instrumentPointingOptions");
1223 stream.writeAttribute("solveOption",
1225 stream.writeAttribute("numberCoefSolved", toString(m_numberCamAngleCoefSolved));
1226 stream.writeAttribute("degree", toString(m_ckDegree));
1227 stream.writeAttribute("solveDegree", toString(m_ckSolveDegree));
1228 stream.writeAttribute("solveTwist", toString(m_solveTwist));
1229 stream.writeAttribute("solveOverExisting", toString(m_solvePointingPolynomialOverExisting));
1230 stream.writeAttribute("interpolationType", toString(m_pointingInterpolationType));
1231
1232 stream.writeStartElement("aprioriPointingSigmas");
1233 for (int i = 0; i < m_anglesAprioriSigma.size(); i++) {
1235 stream.writeTextElement("sigma", "N/A");
1236 }
1237 else {
1238 stream.writeTextElement("sigma", toString(m_anglesAprioriSigma[i]));
1239 }
1240 }
1241 stream.writeEndElement();// end aprioriPointingSigmas
1242 stream.writeEndElement();// end instrumentPointingOptions
1243
1244 // position related
1245 stream.writeStartElement("instrumentPositionOptions");
1246 stream.writeAttribute("solveOption",
1248 stream.writeAttribute("numberCoefSolved", toString(m_numberCamPosCoefSolved));
1249 stream.writeAttribute("degree", toString(m_spkDegree));
1250 stream.writeAttribute("solveDegree", toString(m_spkSolveDegree));
1251 stream.writeAttribute("solveOverHermiteSpline", toString(m_solvePositionOverHermiteSpline));
1252 stream.writeAttribute("interpolationType", toString(m_positionInterpolationType));
1253
1254 stream.writeStartElement("aprioriPositionSigmas");
1255 for (int i = 0; i < m_positionAprioriSigma.size(); i++) {
1257 stream.writeTextElement("sigma", "N/A");
1258 }
1259 else {
1260 stream.writeTextElement("sigma", toString(m_positionAprioriSigma[i]));
1261 }
1262 }
1263 stream.writeEndElement();// end aprioriPositionSigmas
1264 stream.writeEndElement(); // end instrumentPositionOptions
1265
1266 stream.writeEndElement(); // end bundleObservationSolveSettings
1267
1268 }
1269
1270
1281 Project *project) {
1282 m_xmlHandlerObservationSettings = settings;
1283 m_xmlHandlerProject = project; // TODO: does xml stuff need project???
1284 m_xmlHandlerCharacters = "";
1285 }
1286
1287
1292 // do not delete this pointer... we don't own it, do we???
1293 // passed into StatCumProbDistDynCalc constructor as pointer
1294 // delete m_xmlHandlerProject; // TODO: does xml stuff need project???
1295 m_xmlHandlerProject = NULL;
1296 }
1297
1298
1311 const QString &localName,
1312 const QString &qName,
1313 const QXmlAttributes &atts) {
1314 m_xmlHandlerCharacters = "";
1315 if (XmlStackedHandler::startElement(namespaceURI, localName, qName, atts)) {
1316 if (localName == "instrumentPointingOptions") {
1317
1318 QString pointingSolveOption = atts.value("solveOption");
1319 if (!pointingSolveOption.isEmpty()) {
1320 m_xmlHandlerObservationSettings->m_instrumentPointingSolveOption
1321 = stringToInstrumentPointingSolveOption(pointingSolveOption);
1322 }
1323
1324 QString numberCoefSolved = atts.value("numberCoefSolved");
1325 if (!numberCoefSolved.isEmpty()) {
1326 m_xmlHandlerObservationSettings->m_numberCamAngleCoefSolved = toInt(numberCoefSolved);
1327 }
1328
1329 QString ckDegree = atts.value("degree");
1330 if (!ckDegree.isEmpty()) {
1331 m_xmlHandlerObservationSettings->m_ckDegree = toInt(ckDegree);
1332 }
1333
1334 QString ckSolveDegree = atts.value("solveDegree");
1335 if (!ckSolveDegree.isEmpty()) {
1336 m_xmlHandlerObservationSettings->m_ckSolveDegree = toInt(ckSolveDegree);
1337 }
1338
1339 QString solveTwist = atts.value("solveTwist");
1340 if (!solveTwist.isEmpty()) {
1341 m_xmlHandlerObservationSettings->m_solveTwist = toBool(solveTwist);
1342 }
1343
1344 QString solveOverExisting = atts.value("solveOverExisting");
1345 if (!solveOverExisting.isEmpty()) {
1346 m_xmlHandlerObservationSettings->m_solvePointingPolynomialOverExisting =
1347 toBool(solveOverExisting);
1348 }
1349
1350 QString interpolationType = atts.value("interpolationType");
1351 if (!interpolationType.isEmpty()) {
1352 m_xmlHandlerObservationSettings->m_pointingInterpolationType =
1353 SpiceRotation::Source(toInt(interpolationType));
1354 }
1355
1356 }
1357 else if (localName == "aprioriPointingSigmas") {
1358 m_xmlHandlerAprioriSigmas.clear();
1359 }
1360 else if (localName == "instrumentPositionOptions") {
1361
1362 QString positionSolveOption = atts.value("solveOption");
1363 if (!positionSolveOption.isEmpty()) {
1364 m_xmlHandlerObservationSettings->m_instrumentPositionSolveOption
1365 = stringToInstrumentPositionSolveOption(positionSolveOption);
1366 }
1367
1368 QString numberCoefSolved = atts.value("numberCoefSolved");
1369 if (!numberCoefSolved.isEmpty()) {
1370 m_xmlHandlerObservationSettings->m_numberCamPosCoefSolved = toInt(numberCoefSolved);
1371 }
1372
1373 QString spkDegree = atts.value("degree");
1374 if (!spkDegree.isEmpty()) {
1375 m_xmlHandlerObservationSettings->m_spkDegree = toInt(spkDegree);
1376 }
1377
1378 QString spkSolveDegree = atts.value("solveDegree");
1379 if (!spkSolveDegree.isEmpty()) {
1380 m_xmlHandlerObservationSettings->m_spkSolveDegree = toInt(spkSolveDegree);
1381 }
1382
1383 QString solveOverHermiteSpline = atts.value("solveOverHermiteSpline");
1384 if (!solveOverHermiteSpline.isEmpty()) {
1385 m_xmlHandlerObservationSettings->m_solvePositionOverHermiteSpline =
1386 toBool(solveOverHermiteSpline);
1387 }
1388
1389 QString interpolationType = atts.value("interpolationType");
1390 if (!interpolationType.isEmpty()) {
1391 m_xmlHandlerObservationSettings->m_positionInterpolationType =
1392 SpicePosition::Source(toInt(interpolationType));
1393 }
1394 }
1395 else if (localName == "aprioriPositionSigmas") {
1396 m_xmlHandlerAprioriSigmas.clear();
1397 }
1398 }
1399 return true;
1400 }
1401
1402
1412 m_xmlHandlerCharacters += ch;
1413 return XmlStackedHandler::characters(ch);
1414 }
1415
1416
1428 const QString &localName,
1429 const QString &qName) {
1430 if (!m_xmlHandlerCharacters.isEmpty()) {
1431 if (localName == "id") {
1432 m_xmlHandlerObservationSettings->m_id = NULL;
1433 m_xmlHandlerObservationSettings->m_id = new QUuid(m_xmlHandlerCharacters);
1434 }
1435 else if (localName == "instrumentId") {
1436 m_xmlHandlerObservationSettings->setInstrumentId(m_xmlHandlerCharacters);
1437 }
1438// else if (localName == "bundleObservationSolveSettings") {
1439// // end tag for this entire class... how to get out???
1440// // call parse, as in Control List???
1441// }
1442 else if (localName == "sigma") {
1443 m_xmlHandlerAprioriSigmas.append(m_xmlHandlerCharacters);
1444 }
1445 else if (localName == "aprioriPointingSigmas") {
1446 m_xmlHandlerObservationSettings->m_anglesAprioriSigma.clear();
1447 for (int i = 0; i < m_xmlHandlerAprioriSigmas.size(); i++) {
1448 if (m_xmlHandlerAprioriSigmas[i] == "N/A") {
1449 m_xmlHandlerObservationSettings->m_anglesAprioriSigma.append(Isis::Null);
1450 }
1451 else {
1452 m_xmlHandlerObservationSettings->m_anglesAprioriSigma.append(
1453 toDouble(m_xmlHandlerAprioriSigmas[i]));
1454 }
1455 }
1456 }
1457 else if (localName == "aprioriPositionSigmas") {
1458 m_xmlHandlerObservationSettings->m_positionAprioriSigma.clear();
1459 for (int i = 0; i < m_xmlHandlerAprioriSigmas.size(); i++) {
1460 if (m_xmlHandlerAprioriSigmas[i] == "N/A") {
1461 m_xmlHandlerObservationSettings->m_positionAprioriSigma.append(Isis::Null);
1462 }
1463 else {
1464 m_xmlHandlerObservationSettings->m_positionAprioriSigma.append(
1465 toDouble(m_xmlHandlerAprioriSigmas[i]));
1466 }
1467 }
1468 }
1469 m_xmlHandlerCharacters = "";
1470 }
1471 return XmlStackedHandler::endElement(namespaceURI, localName, qName);
1472 }
1473}
XmlHandler(BundleObservationSolveSettings *settings, Project *project)
Constructs an XmlHandler for serialization.
virtual bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName)
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
This class is used to modify and manage solve settings for 1 to many BundleObservations.
CSMSolveOption
Options for how to solve for CSM parameters.
@ NoCSMParameters
Do not solve for CSM parameters.
@ Set
Solve for all CSM parameters belonging to a specific set.
@ Type
Solve for all CSM parameters of a specific type.
@ List
Solve for an explicit list of CSM parameters.
static InstrumentPointingSolveOption stringToInstrumentPointingSolveOption(QString option)
Translates a QString InstrumentPointingSolveOption to its enumerated value.
InstrumentPositionSolveOption
Options for how to solve for instrument position.
@ PositionVelocity
Solve for instrument positions and velocities.
@ PositionVelocityAcceleration
Solve for instrument positions, velocities, and accelerations.
@ AllPositionCoefficients
Solve for all coefficients in the polynomials fit to the instrument positions.
@ PositionOnly
Solve for instrument positions only.
@ NoPositionFactors
Solve for none of the position factors.
static QString csmSolveTypeToString(csm::param::Type type)
Convert a CSM parameter type enumeration value to a string.
csm::param::Type m_csmSolveType
The CSM parameter type to solve for.
SpicePosition::Source m_positionInterpolationType
SpicePosition interpolation types.
CSMSolveOption csmSolveOption() const
Get how the CSM parameters to solve for are specified for this observation.
CSMSolveOption m_csmSolveOption
How the CSM solution is specified.
void addObservationNumber(QString observationNumber)
Associates an observation number with these solve settings.
InstrumentPositionSolveOption instrumentPositionSolveOption() const
Accesses the instrument position solve option.
int m_numberCamAngleCoefSolved
The number of camera angle coefficients in solution.
void initialize()
Initializes the default state of this BundleObservationSolveSettings.
bool solveTwist() const
Accesses the flag for solving for twist.
void setCSMSolveType(csm::param::Type type)
Set the type of CSM parameters to solve for.
static QString csmSolveOptionToString(CSMSolveOption option)
Convert a CSM solve option enumeration value to a string.
int m_numberCamPosCoefSolved
The number of camera position coefficients in the solution.
BundleObservationSolveSettings & operator=(const BundleObservationSolveSettings &src)
Assigns the state of another BundleObservationSolveSettings to this one.
static csm::param::Set stringToCSMSolveSet(QString set)
Convert a string to its CSM parameter set enumeration value.
csm::param::Set csmParameterSet() const
Get the set of CSM parameters to solve for.
bool m_solvePositionOverHermiteSpline
The polynomial will be fit over an existing Hermite spline.
void setCSMSolveSet(csm::param::Set set)
Set the set of CSM parameters to solve for.
SpiceRotation::Source m_pointingInterpolationType
SpiceRotation interpolation type.
QSet< QString > m_observationNumbers
Associated observation numbers for these settings.
bool solvePolyOverPointing() const
Whether or not the solve polynomial will be fit over the existing pointing polynomial.
void setInstrumentPositionSettings(InstrumentPositionSolveOption option, int spkDegree=2, int spkSolveDegree=2, bool positionOverHermite=false, double positionAprioriSigma=-1.0, double velocityAprioriSigma=-1.0, double accelerationAprioriSigma=-1.0, QList< double > *additionalPositionSigmas=nullptr)
Sets the instrument pointing settings.
int m_spkDegree
Degree of the polynomial fit to the original camera position.
int numberCameraPositionCoefficientsSolved() const
Accesses the number of camera position coefficients in the solution.
void setInstrumentId(QString instrumentId)
Sets the instrument id for this observation.
QString m_instrumentId
The spacecraft instrument id for this observation.
void save(QXmlStreamWriter &stream, const Project *project) const
Saves this BundleObservationSolveSettings to an xml stream.
BundleObservationSolveSettings()
Constructor with default parameter initializations.
int ckDegree() const
Accesses the degree of polynomial fit to original camera angles (ckDegree).
QString instrumentId() const
Accesses the instrument id for this observation.
csm::param::Type csmParameterType() const
Get the type of CSM parameters to solve for.
QList< double > aprioriPositionSigmas() const
Accesses the a priori position sigmas.
QList< double > m_anglesAprioriSigma
The image position a priori sigmas.The size of the list is equal to the number of coefficients in the...
InstrumentPointingSolveOption m_instrumentPointingSolveOption
Option for how to solve for instrument pointing.
int m_spkSolveDegree
Degree of the camera position polynomial being fit to in the bundle adjustment.
static QString instrumentPointingSolveOptionToString(InstrumentPointingSolveOption option)
Tranlsates an enumerated InstrumentPointingSolveOption value to its string representation.
QList< double > aprioriPointingSigmas() const
Accesses the a priori pointing sigmas.
static InstrumentPositionSolveOption stringToInstrumentPositionSolveOption(QString option)
Translates a QString InstrumentPositionSolveOption to its enumerated value.
SpiceRotation::Source pointingInterpolationType() const
Accesses the SpiceRotation interpolation type for the instrument pointing.
static QString csmSolveSetToString(csm::param::Set set)
Convert a CSM parameter set enumeration value to a string.
int ckSolveDegree() const
Accesses the degree of the camera angles polynomial being fit to in the bundle adjustment (ckSolveDeg...
bool m_solvePointingPolynomialOverExisting
The polynomial will be fit over the existing pointing polynomial.
static CSMSolveOption stringToCSMSolveOption(QString option)
Convert a string to a CSM solve option enumeration value.
csm::param::Set m_csmSolveSet
The CSM parameter set to solve for.
void setInstrumentPointingSettings(InstrumentPointingSolveOption option, bool solveTwist, int ckDegree=2, int ckSolveDegree=2, bool solvePolynomialOverExisting=false, double anglesAprioriSigma=-1.0, double angularVelocityAprioriSigma=-1.0, double angularAccelerationAprioriSigma=-1.0, QList< double > *additionalPointingSigmas=nullptr)
Sets the instrument pointing settings.
bool solvePositionOverHermite() const
Whether or not the polynomial for solving will be fit over an existing Hermite spline.
InstrumentPositionSolveOption m_instrumentPositionSolveOption
Option for how to solve for instrument position.
QList< double > m_positionAprioriSigma
The instrument pointing a priori sigmas.
QStringList csmParameterList() const
Get the list of CSM parameters to solve for.
int m_ckSolveDegree
Degree of the camera angles polynomial being fit to in the bundle adjustment.
SpicePosition::Source positionInterpolationType() const
Accesses the SpicePosition interpolation type for the spacecraft position.
QSet< QString > observationNumbers() const
Returns a list of observation numbers associated with these solve settings.
static QString instrumentPositionSolveOptionToString(InstrumentPositionSolveOption option)
Translates an enumerated InstrumentPositionSolveOption to its string representation.
int numberCameraAngleCoefficientsSolved() const
Accesses the number of camera angle coefficients in the solution.
bool removeObservationNumber(QString observationNumber)
Removes an observation number from this solve settings.
int spkSolveDegree() const
Accesses the degree of thecamera position polynomial being fit to in the bundle adjustment (spkSolveD...
QUuid * m_id
A unique ID for this object (useful for others to reference this object when saving to disk).
InstrumentPointingSolveOption instrumentPointingSolveOption() const
Accesses the instrument pointing solve option.
void setCSMSolveParameterList(QStringList list)
Set an explicit list of CSM parameters to solve for.
QStringList m_csmSolveList
The names of the CSM parameters to solve for.
int m_ckDegree
Degree of the polynomial fit to the original camera angles.
InstrumentPointingSolveOption
Options for how to solve for instrument pointing.
@ AnglesVelocity
Solve for pointing angles and their angular velocities.
@ AnglesVelocityAcceleration
Solve for pointing angles, their velocities and their accelerations.
@ AllPointingCoefficients
Solve for all coefficients in the polynomials fit to the pointing angles.
@ AnglesOnly
Solve for pointing angles: right ascension, declination and, optionally, twist.
@ NoPointingFactors
Solve for none of the pointing factors.
int spkDegree() const
Accesses the degree of the polynomial fit to the original camera position (spkDegree).
static csm::param::Type stringToCSMSolveType(QString type)
Convert a string to its CSM parameter type enumeration value.
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
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
The main project for ipce.
Definition Project.h:289
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Source
This enum indicates the status of the object.
@ PolyFunction
Object is calculated from nth degree polynomial.
@ PolyFunctionOverHermiteConstant
Object is reading from splined.
Source
The rotation can come from one of 3 places for an Isis cube.
@ PolyFunction
From nth degree polynomial.
@ PolyFunctionOverSpice
Kernels plus nth degree polynomial.
Manage a stack of content handlers for reading XML files.
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
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition IString.cpp:93
const double Null
Value for an Isis Null pixel.
bool toBool(const QString &string)
Global function to convert from a string to a boolean.
Definition IString.cpp:38
bool IsSpecial(const double d)
Returns if the input pixel is special.
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition IString.cpp:149