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
30
31namespace Isis {
32
39
40
49 initialize();
50 readSolveSettings(xmlReader);
51 }
52
53
55 initialize();
56
57 // group name must be instrument id
58 m_instrumentId = (QString)scParameterGroup.nameKeyword();
59
60 // If CKDEGREE is not specified, then a default of 2 is used
61 if (scParameterGroup.hasKeyword("CKDEGREE")) {
62 m_ckDegree = (int)(scParameterGroup.findKeyword("CKDEGREE"));
63 }
64
65 // If CKSOLVEDEGREE is not specified, then a default of 2 is used
66 if (scParameterGroup.hasKeyword("CKSOLVEDEGREE")) {
67 m_ckSolveDegree = (int) (scParameterGroup.findKeyword("CKSOLVEDEGREE"));
68 }
69
70 // do we solve for No pointing, ANGLES only, ANGLES+ANGULAR VELOCITY, ANGLES+ANGULAR VELOCITY+
71 // ANGULAR ACCELERATION, or a higher order polynomial
72 QString csolve = "NONE";
73 csolve = (QString)scParameterGroup.findKeyword("CAMSOLVE");
74 csolve = csolve.toUpper();
75 if (csolve == "NONE") {
78 }
79 else if (csolve == "ANGLES") {
82 }
83 else if (csolve == "VELOCITIES") {
86 }
87 else if (csolve == "ACCELERATIONS") {
90 }
91 else if (csolve == "ALL"){
94 }
95
96 // If OVEREXISTING is not specified, then a default of NO is used
97 if (scParameterGroup.hasKeyword("OVEREXISTING")) {
98 QString parval = (QString)scParameterGroup.findKeyword("OVEREXISTING");
99 parval = parval.toUpper();
100 if (parval == "TRUE" || parval == "YES") {
103 }
104 else if (parval == "FALSE" || parval == "NO") {
107 }
108 else {
109 QString msg = "The OVEREXISTING parameter must be set to TRUE or FALSE; YES or NO";
110 throw IException(IException::User, msg, _FILEINFO_);
111 }
112 }
113
114 // If SPKDEGREE is not specified, then a default of 2 is used
115 if (scParameterGroup.hasKeyword("SPKDEGREE"))
116 m_spkDegree = (int)(scParameterGroup.findKeyword("SPKDEGREE"));
117
118 // If SPKSOLVEDEGREE is not specified, then a default of 2 is used
119 if (scParameterGroup.hasKeyword("SPKSOLVEDEGREE"))
120 m_spkSolveDegree = (int)(scParameterGroup.findKeyword("SPKSOLVEDEGREE"));
121
122 // do we solve for No position, POSITION only, POSITION+VELOCITY, POSITION+VELOCITY+
123 // ACCELERATION, or a higher order polynomial
124 QString ssolve = "NONE";
125 ssolve = (QString)scParameterGroup.findKeyword("SPSOLVE");
126 ssolve = ssolve.toUpper();
127 if (ssolve == "NONE") {
130 }
131 else if (ssolve == "POSITION") {
134 }
135 else if (ssolve == "VELOCITIES") {
138 }
139 else if (ssolve == "ACCELERATIONS") {
142 }
143 else if (csolve == "ALL"){
146 }
147
148 // If TWIST is not specified, then a default of YES is used
149 if (scParameterGroup.hasKeyword("TWIST")) {
150 QString parval = (QString)scParameterGroup.findKeyword("TWIST");
151 parval = parval.toUpper();
152 if (parval == "TRUE" || parval == "YES") { // is this necessary ??? i think pvl and toString can handle it...
153 m_solveTwist = true;
154 }
155 else if (parval == "FALSE" || parval == "NO") {
156 m_solveTwist = false;
157 }
158 else {
159 QString msg = "The TWIST parameter must be set to TRUE or FALSE; YES or NO";
160 throw IException(IException::User, msg, _FILEINFO_);
161 }
162 }
163 // If OVERHERMITE is not specified, then a default of NO is used
164 if (scParameterGroup.hasKeyword("OVERHERMITE")) {
165 QString parval = (QString)scParameterGroup.findKeyword("OVERHERMITE");
166 parval = parval.toUpper();
167 if (parval == "TRUE" || parval == "YES") {
170 }
171 else if (parval == "FALSE" || parval == "NO") {
174 }
175 else {
176 QString msg = "The OVERHERMITE parameter must be set to TRUE or FALSE; YES or NO";
177 throw IException(IException::User, msg, _FILEINFO_);
178 }
179 }
180
182 if (scParameterGroup.hasKeyword("CAMERA_ANGLES_SIGMA")) {
183 m_anglesAprioriSigma.append((double)(scParameterGroup.findKeyword("CAMERA_ANGLES_SIGMA")));
184 }
185 else {
187 }
188 if (scParameterGroup.hasKeyword("CAMERA_ANGULAR_VELOCITY_SIGMA")){
190 (double)(scParameterGroup.findKeyword("CAMERA_ANGULAR_VELOCITY_SIGMA")));
191 }
192 else {
194 }
195 if (scParameterGroup.hasKeyword("CAMERA_ANGULAR_ACCELERATION_SIGMA")){
197 (double)(scParameterGroup.findKeyword("CAMERA_ANGULAR_ACCELERATION_SIGMA")));
198 }
199 else {
201 }
202 if (scParameterGroup.hasKeyword("ADDITIONAL_CAMERA_POINTING_SIGMAS")) {
203 PvlKeyword additionalSigmas = scParameterGroup.findKeyword("ADDITIONAL_CAMERA_POINTING_SIGMAS");
204 for (int i = 0; i < additionalSigmas.size(); i++ ) {
205 m_anglesAprioriSigma.append(toDouble(additionalSigmas[i]));
206 }
207 }
208 }
209
211 if (scParameterGroup.hasKeyword("SPACECRAFT_POSITION_SIGMA")) {
212 m_positionAprioriSigma.append((double)(scParameterGroup.findKeyword("SPACECRAFT_POSITION_SIGMA")));
213 }
214 else {
216 }
217 if (scParameterGroup.hasKeyword("SPACECRAFT_VELOCITY_SIGMA")){
218 m_positionAprioriSigma.append((double)(scParameterGroup.findKeyword("SPACECRAFT_VELOCITY_SIGMA")));
219 }
220 else {
222 }
223 if (scParameterGroup.hasKeyword("SPACECRAFT_ACCELERATION_SIGMA")) {
224 m_positionAprioriSigma.append((double)(scParameterGroup.findKeyword("SPACECRAFT_ACCELERATION_SIGMA")));
225 }
226 else {
228 }
229 if (scParameterGroup.hasKeyword("ADDITIONAL_SPACECRAFT_POSITION_SIGMAS")) {
230 PvlKeyword additionalSigmas = scParameterGroup.findKeyword("ADDITIONAL_SPACECRAFT_POSITION_SIGMAS");
231 for (int i = 0; i < additionalSigmas.size(); i++ ) {
232 m_positionAprioriSigma.append(toDouble(additionalSigmas[i]));
233 }
234 }
235 }
236
237 // CSM settings
238 if (scParameterGroup.hasKeyword("CSMSOLVESET")) {
239 setCSMSolveSet(stringToCSMSolveSet(scParameterGroup.findKeyword("CSMSOLVESET")));
240 }
241 else if (scParameterGroup.hasKeyword("CSMSOLVETYPE")) {
242 setCSMSolveType(stringToCSMSolveType(scParameterGroup.findKeyword("CSMSOLVETYPE")));
243 }
244 else if (scParameterGroup.hasKeyword("CSMSOLVELIST")) {
245 PvlKeyword csmSolveListKey = scParameterGroup.findKeyword("CSMSOLVELIST");
246 QStringList csmSolveList;
247 for (int i = 0; i < csmSolveListKey.size(); i++) {
248 csmSolveList.append(csmSolveListKey[i]);
249 }
250 setCSMSolveParameterList(csmSolveList);
251 }
252 }
253
254
261
262 m_id = NULL;
263 m_id = new QUuid(other.m_id->toString());
264 // TODO: add check to all copy constructors (verify other.xxx is not null) and operator= ???
265 // or intit all variables in all constructors
266
267 m_instrumentId = other.m_instrumentId;
268 m_csmSolveOption = other.m_csmSolveOption;
269 m_csmSolveSet = other.m_csmSolveSet;
270 m_csmSolveType = other.m_csmSolveType;
271 m_csmSolveList = other.m_csmSolveList;
272 m_instrumentPointingSolveOption = other.m_instrumentPointingSolveOption;
273 m_observationNumbers = other.m_observationNumbers;
274 m_numberCamAngleCoefSolved = other.m_numberCamAngleCoefSolved;
275 m_ckDegree = other.m_ckDegree;
276 m_ckSolveDegree = other.m_ckSolveDegree;
277 m_solveTwist = other.m_solveTwist;
278 m_solvePointingPolynomialOverExisting = other.m_solvePointingPolynomialOverExisting;
279 m_anglesAprioriSigma = other.m_anglesAprioriSigma;
280 m_pointingInterpolationType = other.m_pointingInterpolationType;
281 m_instrumentPositionSolveOption = other.m_instrumentPositionSolveOption;
282 m_numberCamPosCoefSolved = other.m_numberCamPosCoefSolved;
283 m_spkDegree = other.m_spkDegree;
284 m_spkSolveDegree = other.m_spkSolveDegree;
285 m_solvePositionOverHermiteSpline = other.m_solvePositionOverHermiteSpline;
286 m_positionAprioriSigma = other.m_positionAprioriSigma;
287 m_positionInterpolationType = other.m_positionInterpolationType;
288 }
289
290
300
301
312 if (&other != this) {
313 delete m_id;
314 m_id = NULL;
315 m_id = new QUuid(other.m_id->toString());
316
317 m_instrumentId = other.m_instrumentId;
318 m_observationNumbers = other.m_observationNumbers;
319
320 // CSM related
321 m_csmSolveOption = other.m_csmSolveOption;
322 m_csmSolveSet = other.m_csmSolveSet;
323 m_csmSolveType = other.m_csmSolveType;
324 m_csmSolveList = other.m_csmSolveList;
325
326 // pointing related
327 m_instrumentPointingSolveOption = other.m_instrumentPointingSolveOption;
328 m_numberCamAngleCoefSolved = other.m_numberCamAngleCoefSolved;
329 m_ckDegree = other.m_ckDegree;
330 m_ckSolveDegree = other.m_ckSolveDegree;
331 m_solveTwist = other.m_solveTwist;
332 m_solvePointingPolynomialOverExisting = other.m_solvePointingPolynomialOverExisting;
333 m_pointingInterpolationType = other.m_pointingInterpolationType;
334 m_anglesAprioriSigma = other.m_anglesAprioriSigma;
335
336 // position related
337 m_instrumentPositionSolveOption = other.m_instrumentPositionSolveOption;
338 m_numberCamPosCoefSolved = other.m_numberCamPosCoefSolved;
339 m_spkDegree = other.m_spkDegree;
340 m_spkSolveDegree = other.m_spkSolveDegree;
341 m_solvePositionOverHermiteSpline = other.m_solvePositionOverHermiteSpline;
342 m_positionInterpolationType = other.m_positionInterpolationType;
343 m_positionAprioriSigma = other.m_positionAprioriSigma;
344
345 }
346
347 return *this;
348
349 }
350
351
356 m_id = NULL;
357 m_id = new QUuid(QUuid::createUuid());
358
359 m_instrumentId = "";
360
361 // CSM solve options
363 m_csmSolveSet = csm::param::ADJUSTABLE;
364 m_csmSolveType = csm::param::REAL;
366
367 // Camera Pointing Options
368 // Defaults:
369 // m_instrumentPointingSolveOption = AnglesOnly;
370 // m_numberCamAngleCoefSolved = 1; // AnglesOnly;
371 // m_ckDegree = 2;
372 // m_ckSolveDegree = 2;
373 // m_solveTwist = true;
374 // m_solvePointingPolynomialOverExisting = false;
375 // m_pointingInterpolationType = SpiceRotation::PolyFunction;
376 // m_anglesAprioriSigma.append(Isis::Null); // num cam angle
377 // coef = 1
378 setInstrumentPointingSettings(AnglesOnly, true, 2, 2, false);
379
380 // Spacecraft Position Options
381 // Defaults:
382 // m_instrumentPositionSolveOption = NoPositionFactors;
383 // m_numberCamPosCoefSolved = 0; // NoPositionFactors;
384 // m_spkDegree = 2;
385 // m_spkSolveDegree = 2;
386 // m_solvePositionOverHermiteSpline = false;
387 // m_positionInterpolationType = SpicePosition::PolyFunction;
388 // m_positionAprioriSigma.clear();
390
391 }
392
393
394 // =============================================================================================//
395 // =============================================================================================//
396 // =============================================================================================//
397
406
407
416
417
426 m_observationNumbers.insert(observationNumber);
427 }
428
429
439 return m_observationNumbers.remove(observationNumber);
440 }
441
442
451
452
453 // =============================================================================================//
454 // ======================== CSM Options ========================================================//
455 // =============================================================================================//
456
457
467 if (option.compare("NoCSMParameters", Qt::CaseInsensitive) == 0) {
469 }
470 else if (option.compare("Set", Qt::CaseInsensitive) == 0) {
472 }
473 else if (option.compare("Type", Qt::CaseInsensitive) == 0) {
475 }
476 else if (option.compare("List", Qt::CaseInsensitive) == 0) {
478 }
479 else {
481 "Unknown bundle CSM solve option " + option + ".",
482 _FILEINFO_);
483 }
484 }
485
486
496 return "NoCSMParameters";
497 }
498 else if (option == BundleObservationSolveSettings::Set) {
499 return "Set";
500 }
501 else if (option == BundleObservationSolveSettings::Type) {
502 return "Type";
503 }
504 else if (option == BundleObservationSolveSettings::List) {
505 return "List";
506 }
507 else {
509 "Unknown CSM solve option enum [" + toString(option) + "].",
510 _FILEINFO_);
511 }
512 }
513
514
523 if (set.compare("VALID", Qt::CaseInsensitive) == 0) {
524 return csm::param::VALID;
525 }
526 else if (set.compare("ADJUSTABLE", Qt::CaseInsensitive) == 0) {
527 return csm::param::ADJUSTABLE;
528 }
529 else if (set.compare("NON_ADJUSTABLE", Qt::CaseInsensitive) == 0) {
530 return csm::param::NON_ADJUSTABLE;
531 }
532 else {
534 "Unknown bundle CSM parameter set " + set + ".",
535 _FILEINFO_);
536 }
537 }
538
539
548 if (set == csm::param::VALID) {
549 return "VALID";
550 }
551 else if (set == csm::param::ADJUSTABLE) {
552 return "ADJUSTABLE";
553 }
554 else if (set == csm::param::NON_ADJUSTABLE) {
555 return "NON_ADJUSTABLE";
556 }
557 else {
559 "Unknown CSM parameter set enum [" + toString(set) + "].",
560 _FILEINFO_);
561 }
562 }
563
564
573 if (type.compare("NONE", Qt::CaseInsensitive) == 0) {
574 return csm::param::NONE;
575 }
576 else if (type.compare("FICTITIOUS", Qt::CaseInsensitive) == 0) {
577 return csm::param::FICTITIOUS;
578 }
579 else if (type.compare("REAL", Qt::CaseInsensitive) == 0) {
580 return csm::param::REAL;
581 }
582 else if (type.compare("FIXED", Qt::CaseInsensitive) == 0) {
583 return csm::param::FIXED;
584 }
585 else {
587 "Unknown bundle CSM parameter type " + type + ".",
588 _FILEINFO_);
589 }
590 }
591
592
601 if (type == csm::param::NONE) {
602 return "NONE";
603 }
604 else if (type == csm::param::FICTITIOUS) {
605 return "FICTITIOUS";
606 }
607 else if (type == csm::param::REAL) {
608 return "REAL";
609 }
610 else if (type == csm::param::FIXED) {
611 return "FIXED";
612 }
613 else {
615 "Unknown CSM parameter type enum [" + toString(type) + "].",
616 _FILEINFO_);
617 }
618 }
619
620
631
632
642
643
653
654
664
665
672 return m_csmSolveSet;
673 }
674
675
682 return m_csmSolveType;
683 }
684
685
694
695
696 // =============================================================================================//
697 // ======================== Camera Pointing Options ============================================//
698 // =============================================================================================//
699
700
713 if (option.compare("NONE", Qt::CaseInsensitive) == 0) {
715 }
716 else if (option.compare("NoPointingFactors", Qt::CaseInsensitive) == 0) {
718 }
719 else if (option.compare("ANGLES", Qt::CaseInsensitive) == 0) {
721 }
722 else if (option.compare("AnglesOnly", Qt::CaseInsensitive) == 0) {
724 }
725 else if (option.compare("VELOCITIES", Qt::CaseInsensitive) == 0) {
727 }
728 else if (option.compare("AnglesAndVelocity", Qt::CaseInsensitive) == 0) {
730 }
731 else if (option.compare("ACCELERATIONS", Qt::CaseInsensitive) == 0) {
733 }
734 else if (option.compare("AnglesVelocityAndAcceleration", Qt::CaseInsensitive) == 0) {
736 }
737 else if (option.compare("ALL", Qt::CaseInsensitive) == 0) {
739 }
740 else if (option.compare("AllPolynomialCoefficients", Qt::CaseInsensitive) == 0) {
742 }
743 else {
745 "Unknown bundle instrument pointing solve option " + option + ".",
746 _FILEINFO_);
747 }
748 }
749
750
763 if (option == NoPointingFactors) return "None";
764 else if (option == AnglesOnly) return "AnglesOnly";
765 else if (option == AnglesVelocity) return "AnglesAndVelocity";
766 else if (option == AnglesVelocityAcceleration) return "AnglesVelocityAndAcceleration";
767 else if (option == AllPointingCoefficients) return "AllPolynomialCoefficients";
769 "Unknown pointing solve option enum [" + toString(option) + "].",
770 _FILEINFO_);
771 }
772
773
789 bool solveTwist,
790 int ckDegree,
791 int ckSolveDegree,
792 bool solvePolynomialOverExisting,
793 double anglesAprioriSigma,
794 double angularVelocityAprioriSigma,
795 double angularAccelerationAprioriSigma,QList<double> * additionalPointingSigmas) {
796
797 // automatically set the solve option and ck degree to the user entered values
799
800 // the ck solve degree entered is only used if we are solving for all coefficients
801 // otherwise it defaults to 2.
802 if (option == AllPointingCoefficients) {
803 // update spkDegree and spkSolveDegree
806
807 // we are solving for (solve degree + 1) coefficients
808 // this is the maximum number of apriori sigmas allowed
810 }
811 else {
812 // let spkDegree and spkSolveDegree default to 2, 2
813 m_ckDegree = 2;
814 m_ckSolveDegree = 2;
815
816 // solve for the appropriate number of coefficients, based on solve option enum
817 m_numberCamAngleCoefSolved = ((int) option);
818 }
819
820 m_anglesAprioriSigma.clear();
822 if (anglesAprioriSigma > 0.0) {
823 m_anglesAprioriSigma.append(anglesAprioriSigma);
824 }
825 else {
827 }
828
830 if (angularVelocityAprioriSigma > 0.0) {
831 m_anglesAprioriSigma.append(angularVelocityAprioriSigma);
832 }
833 else {
835 }
836
838 if (angularAccelerationAprioriSigma > 0.0) {
839 m_anglesAprioriSigma.append(angularAccelerationAprioriSigma);
840 }
841 else {
843 }
844 }
845 }
846 }
847
848 if (additionalPointingSigmas) {
849 for (int i=0;i < additionalPointingSigmas->count();i++) {
850 m_anglesAprioriSigma.append(additionalPointingSigmas->value(i));
851 }
852 }
853
854
855
856
857
858 m_solveTwist = solveTwist; // dependent on solve option???
859
860 // Set the SpiceRotation interpolation type enum appropriately
861 m_solvePointingPolynomialOverExisting = solvePolynomialOverExisting;
864 }
865 else {
867 }
868
869 }
870
871
882
883
892
893
902
903
913
914
923
924
934
935
944
945
954
955
956 // =============================================================================================//
957 // ======================== Spacecraft Position Options ========================================//
958 // =============================================================================================//
959
960
973 if (option.compare("NONE", Qt::CaseInsensitive) == 0) {
975 }
976 else if (option.compare("NoPositionFactors", Qt::CaseInsensitive) == 0) {
978 }
979 else if (option.compare("POSITIONS", Qt::CaseInsensitive) == 0) {
981 }
982 else if (option.compare("PositionOnly", Qt::CaseInsensitive) == 0) {
984 }
985 else if (option.compare("VELOCITIES", Qt::CaseInsensitive) == 0) {
987 }
988 else if (option.compare("PositionAndVelocity", Qt::CaseInsensitive) == 0) {
990 }
991 else if (option.compare("ACCELERATIONS", Qt::CaseInsensitive) == 0) {
993 }
994 else if (option.compare("PositionVelocityAndAcceleration", Qt::CaseInsensitive) == 0) {
996 }
997 else if (option.compare("ALL", Qt::CaseInsensitive) == 0) {
999 }
1000 else if (option.compare("AllPolynomialCoefficients", Qt::CaseInsensitive) == 0) {
1002 }
1003 else {
1005 "Unknown bundle instrument position solve option " + option + ".",
1006 _FILEINFO_);
1007 }
1008 }
1009
1010
1023 if (option == NoPositionFactors) return "None";
1024 else if (option == PositionOnly) return "PositionOnly";
1025 else if (option == PositionVelocity) return "PositionAndVelocity";
1026 else if (option == PositionVelocityAcceleration) return "PositionVelocityAndAcceleration";
1027 else if (option == AllPositionCoefficients) return "AllPolynomialCoefficients";
1029 "Unknown position solve option enum [" + toString(option) + "].",
1030 _FILEINFO_);
1031 }
1032
1033
1047 int spkDegree,
1048 int spkSolveDegree,
1049 bool positionOverHermite,
1050 double positionAprioriSigma,
1051 double velocityAprioriSigma,
1052 double accelerationAprioriSigma,
1053 QList<double> *additionalPositionSigmas) {
1054 // automatically set the solve option and spk degree to the user entered values
1056
1057 // the spk solve degree entered is only used if we are solving for all coefficients
1058 // otherwise it defaults to 2.
1059 if (option == AllPositionCoefficients) {
1060 // update spkDegree and spkSolveDegree
1063 // we are solving for (solve degree + 1) coefficients
1064 // this is the maximum number of apriori sigmas allowed
1066 }
1067 else {
1068 // let spkDegree and spkSolveDegree default to 2, 2
1069 m_spkDegree = 2;
1070 m_spkSolveDegree = 2;
1071
1072 // solve for the appropriate number of coefficients, based on solve option enum
1073 m_numberCamPosCoefSolved = ((int) option);
1074 }
1075
1076 m_positionAprioriSigma.clear();
1077 if (m_numberCamPosCoefSolved > 0) {
1078 if (positionAprioriSigma > 0.0) {
1079 m_positionAprioriSigma.append(positionAprioriSigma);
1080 }
1081 else {
1083 }
1084
1085 if (m_numberCamPosCoefSolved > 1) {
1086 if (velocityAprioriSigma > 0.0) {
1087 m_positionAprioriSigma.append(velocityAprioriSigma);
1088 }
1089 else {
1091 }
1092
1093 if (m_numberCamPosCoefSolved > 2) {
1094 if (accelerationAprioriSigma > 0.0) {
1095 m_positionAprioriSigma.append(accelerationAprioriSigma);
1096 }
1097 else {
1099 }
1100 }
1101 }
1102 }
1103
1104 if (additionalPositionSigmas) {
1105 for (int i=0;i < additionalPositionSigmas->count();i++) {
1106 m_positionAprioriSigma.append(additionalPositionSigmas->value(i));
1107 }
1108 }
1109
1110 // Set the SpicePosition interpolation type enum appropriately
1111 m_solvePositionOverHermiteSpline = positionOverHermite;
1114 }
1115 else {
1117 }
1118
1119 }
1120
1121
1132
1133
1142
1143
1153
1154
1163
1164
1174
1175
1184
1185
1194
1195
1196 // =============================================================================================//
1197 // =============================================================================================//
1198 // =============================================================================================//
1199
1200
1210 void BundleObservationSolveSettings::save(QXmlStreamWriter &stream,
1211 const Project *project) const {
1212
1213 stream.writeStartElement("bundleObservationSolveSettings");
1214 stream.writeTextElement("id", m_id->toString());
1215 stream.writeTextElement("instrumentId", instrumentId());
1216
1217 // pointing related
1218 stream.writeStartElement("instrumentPointingOptions");
1219 stream.writeAttribute("solveOption",
1221 stream.writeAttribute("numberCoefSolved", toString(m_numberCamAngleCoefSolved));
1222 stream.writeAttribute("degree", toString(m_ckDegree));
1223 stream.writeAttribute("solveDegree", toString(m_ckSolveDegree));
1224 stream.writeAttribute("solveTwist", toString(m_solveTwist));
1225 stream.writeAttribute("solveOverExisting", toString(m_solvePointingPolynomialOverExisting));
1226 stream.writeAttribute("interpolationType", toString(m_pointingInterpolationType));
1227
1228 stream.writeStartElement("aprioriPointingSigmas");
1229 for (int i = 0; i < m_anglesAprioriSigma.size(); i++) {
1231 stream.writeTextElement("sigma", "N/A");
1232 }
1233 else {
1234 stream.writeTextElement("sigma", toString(m_anglesAprioriSigma[i]));
1235 }
1236 }
1237 stream.writeEndElement();// end aprioriPointingSigmas
1238 stream.writeEndElement();// end instrumentPointingOptions
1239
1240 // position related
1241 stream.writeStartElement("instrumentPositionOptions");
1242 stream.writeAttribute("solveOption",
1244 stream.writeAttribute("numberCoefSolved", toString(m_numberCamPosCoefSolved));
1245 stream.writeAttribute("degree", toString(m_spkDegree));
1246 stream.writeAttribute("solveDegree", toString(m_spkSolveDegree));
1247 stream.writeAttribute("solveOverHermiteSpline", toString(m_solvePositionOverHermiteSpline));
1248 stream.writeAttribute("interpolationType", toString(m_positionInterpolationType));
1249
1250 stream.writeStartElement("aprioriPositionSigmas");
1251 for (int i = 0; i < m_positionAprioriSigma.size(); i++) {
1253 stream.writeTextElement("sigma", "N/A");
1254 }
1255 else {
1256 stream.writeTextElement("sigma", toString(m_positionAprioriSigma[i]));
1257 }
1258 }
1259 stream.writeEndElement();// end aprioriPositionSigmas
1260 stream.writeEndElement(); // end instrumentPositionOptions
1261
1262 stream.writeEndElement(); // end bundleObservationSolveSettings
1263
1264 }
1265
1266 void BundleObservationSolveSettings::readSolveSettings(QXmlStreamReader *xmlReader) {
1267 initialize();
1268 Q_ASSERT(xmlReader->name() == "bundleObservationSolveSettings");
1269 while (xmlReader->readNextStartElement()) {
1270 if (xmlReader->qualifiedName() == "instrumentId") {
1271 QString instrumentId = xmlReader->readElementText();
1272 if (!instrumentId.isEmpty()){
1274 }
1275 }
1276 else if (xmlReader->qualifiedName() == "instrumentPointingOptions") {
1277 QStringRef solveOption = xmlReader->attributes().value("solveOption");
1278 if (!solveOption.isEmpty()) {
1280 }
1281 QStringRef numberCoefSolved = xmlReader->attributes().value("numberCoefSolved");
1282 if (!numberCoefSolved.isEmpty()) {
1283 m_numberCamAngleCoefSolved = numberCoefSolved.toInt();
1284 }
1285 QStringRef degree = xmlReader->attributes().value("degree");
1286 if (!degree.isEmpty()) {
1287 m_ckDegree = degree.toInt();
1288 }
1289 QStringRef solveDegree = xmlReader->attributes().value("solveDegree");
1290 if (!solveDegree.isEmpty()) {
1291 m_ckSolveDegree = solveDegree.toInt();
1292 }
1293 QStringRef solveTwist = xmlReader->attributes().value("solveTwist");
1294 if (!solveTwist.isEmpty()) {
1295 m_solveTwist = toBool(solveTwist.toString());
1296 }
1297 QStringRef solveOverExisting = xmlReader->attributes().value("solveOverExisting");
1298 if (!solveOverExisting.isEmpty()) {
1299 m_solvePointingPolynomialOverExisting = toBool(solveOverExisting.toString());
1300 }
1301 QStringRef interpolationType = xmlReader->attributes().value("interpolationType");
1302 if (!interpolationType.isEmpty()) {
1303 if (interpolationType == "3") {
1305 }
1306 else if (interpolationType == "4") {
1308 }
1309 }
1310 while (xmlReader->readNextStartElement()) {
1311 if (xmlReader->qualifiedName() == "aprioriPointingSigmas") {
1312 m_anglesAprioriSigma.clear();
1313 while (xmlReader->readNextStartElement()) {
1314 if (xmlReader->qualifiedName() == "sigma") {
1315 QString sigma = xmlReader->readElementText();
1316 if (!sigma.isEmpty()){
1317 if (sigma == "N/A") {
1319 }
1320 else {
1321 m_anglesAprioriSigma.append(sigma.toDouble());
1322 }
1323 }
1324 }
1325 else {
1326 xmlReader->skipCurrentElement();
1327 }
1328 }
1329 }
1330 else {
1331 xmlReader->skipCurrentElement();
1332 }
1333 }
1334 }
1335 else if (xmlReader->qualifiedName() == "instrumentPositionOptions") {
1336 QStringRef solveOption = xmlReader->attributes().value("solveOption");
1337 if (!solveOption.isEmpty()) {
1339 }
1340 QStringRef numberCoefSolved = xmlReader->attributes().value("numberCoefSolved");
1341 if (!numberCoefSolved.isEmpty()) {
1342 m_numberCamPosCoefSolved = numberCoefSolved.toInt();
1343 }
1344 QStringRef degree = xmlReader->attributes().value("degree");
1345 if (!degree.isEmpty()) {
1346 m_spkDegree = degree.toInt();
1347 }
1348 QStringRef solveDegree = xmlReader->attributes().value("solveDegree");
1349 if (!solveDegree.isEmpty()) {
1350 m_spkSolveDegree = solveDegree.toInt();
1351 }
1352 QStringRef solveOverHermiteSpline = xmlReader->attributes().value("solveOverHermiteSpline");
1353 if (!solveOverHermiteSpline.isEmpty()) {
1354 m_solvePositionOverHermiteSpline = toBool(solveOverHermiteSpline.toString());
1355 }
1356 QStringRef interpolationType = xmlReader->attributes().value("interpolationType");
1357 if (!interpolationType.isEmpty()) {
1358 if (interpolationType == "3") {
1360 }
1361 else if (interpolationType == "4") {
1363 }
1364 }
1365 while (xmlReader->readNextStartElement()) {
1366 if (xmlReader->qualifiedName() == "aprioriPositionSigmas") {
1367 m_positionAprioriSigma.clear();
1368 while (xmlReader->readNextStartElement()) {
1369 if (xmlReader->qualifiedName() == "sigma") {
1370 QString sigma = xmlReader->readElementText();
1371 if (!sigma.isEmpty()){
1372 if (sigma == "N/A") {
1374
1375 }
1376 else {
1377 m_positionAprioriSigma.append(sigma.toDouble());
1378 }
1379 }
1380 }
1381 else {
1382 xmlReader->skipCurrentElement();
1383 }
1384 }
1385 }
1386 else {
1387 xmlReader->skipCurrentElement();
1388 }
1389 }
1390 }
1391 else {
1392 xmlReader->skipCurrentElement();
1393 }
1394 }
1395 }
1396}
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:287
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.
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 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