Isis 3 Programmer Reference
BundleSettings.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "BundleSettings.h"
10
11#include <QDataStream>
12#include <QDebug>
13#include <QList>
14#include <QString>
15#include <QtGlobal> // qMax()
16#include <QUuid>
17#include <QXmlStreamWriter>
18#include <QXmlInputSource>
19
20#include "BundleObservationSolveSettings.h"
21#include "IException.h"
22#include "IString.h"
23#include "Project.h" // currently used for xml handler
24#include "PvlKeyword.h"
25#include "PvlObject.h"
26#include "SpecialPixel.h"
27#include "XmlStackedHandlerReader.h"
28
29namespace Isis {
30
40 init();
41 BundleObservationSolveSettings defaultSolveSettings;
42 m_observationSolveSettings.append(defaultSolveSettings);
43 }
44
51 m_validateNetwork = true;
52
54 m_solveRadius = false;
55 m_updateCubeLabel = false;
56 m_errorPropagation = false;
58 m_cubeList = "";
59 m_outlierRejection = false;
61
62 // Parameter Uncertainties (Weighting)
63 // The units are meters for either coordinate type
67
68 // Convergence Criteria
72
73 // Maximum Likelihood Estimation Options no default in the constructor - must be set.
74 m_maximumLikelihood.clear();
75
76 // Self Calibration ??? (from ipce only)
77
78 // Target Body
79 m_solveTargetBody = false;
80// m_solveTargetBodyPolePosition = false;
81// m_solveTargetBodyZeroMeridian = false;
82// m_solveTargetBodyRotationRate = false;
83// m_solveTargetBodyRadiusMethod = None;
84
85 // Control Points
88
89 // Output Options
91 }
92
93
111 XmlStackedHandlerReader *xmlReader) {
112 init();
113 xmlReader->setErrorHandler(new XmlHandler(this, project));
114 xmlReader->pushContentHandler(new XmlHandler(this, project));
115 }
116
117
125 : m_validateNetwork(other.m_validateNetwork),
126 m_cubeList(other.m_cubeList),
127 m_solveObservationMode(other.m_solveObservationMode),
128 m_solveRadius(other.m_solveRadius),
129 m_updateCubeLabel(other.m_updateCubeLabel),
130 m_errorPropagation(other.m_errorPropagation),
131 m_createInverseMatrix(other.m_createInverseMatrix),
132 m_outlierRejection(other.m_outlierRejection),
133 m_outlierRejectionMultiplier(other.m_outlierRejectionMultiplier),
134 m_globalPointCoord1AprioriSigma(other.m_globalPointCoord1AprioriSigma),
135 m_globalPointCoord2AprioriSigma(other.m_globalPointCoord2AprioriSigma),
136 m_globalPointCoord3AprioriSigma(other.m_globalPointCoord3AprioriSigma),
137 m_observationSolveSettings(other.m_observationSolveSettings),
138 m_convergenceCriteria(other.m_convergenceCriteria),
139 m_convergenceCriteriaThreshold(other.m_convergenceCriteriaThreshold),
140 m_convergenceCriteriaMaximumIterations(other.m_convergenceCriteriaMaximumIterations),
141 m_maximumLikelihood(other.m_maximumLikelihood),
142 m_solveTargetBody(other.m_solveTargetBody),
143 m_bundleTargetBody(other.m_bundleTargetBody),
144 m_cpCoordTypeReports(other.m_cpCoordTypeReports),
145 m_cpCoordTypeBundle(other.m_cpCoordTypeBundle),
146 m_outputFilePrefix(other.m_outputFilePrefix){
147 }
148
149
155
156
170 if (&other != this) {
171 m_validateNetwork = other.m_validateNetwork;
172 m_cubeList = other.m_cubeList;
173 m_solveObservationMode = other.m_solveObservationMode;
174 m_solveRadius = other.m_solveRadius;
175 m_updateCubeLabel = other.m_updateCubeLabel;
176 m_errorPropagation = other.m_errorPropagation;
177 m_createInverseMatrix = other.m_createInverseMatrix;
178 m_outlierRejection = other.m_outlierRejection;
179 m_outlierRejectionMultiplier = other.m_outlierRejectionMultiplier;
180 m_globalPointCoord1AprioriSigma = other.m_globalPointCoord1AprioriSigma;
181 m_globalPointCoord2AprioriSigma = other.m_globalPointCoord2AprioriSigma;
182 m_globalPointCoord3AprioriSigma = other.m_globalPointCoord3AprioriSigma;
183 m_observationSolveSettings = other.m_observationSolveSettings;
184 m_convergenceCriteria = other.m_convergenceCriteria;
185 m_convergenceCriteriaThreshold = other.m_convergenceCriteriaThreshold;
186 m_convergenceCriteriaMaximumIterations = other.m_convergenceCriteriaMaximumIterations;
187 m_solveTargetBody = other.m_solveTargetBody;
188 m_bundleTargetBody = other.m_bundleTargetBody;
189 m_cpCoordTypeReports = other.m_cpCoordTypeReports;
190 m_cpCoordTypeBundle = other.m_cpCoordTypeBundle;
191 m_maximumLikelihood = other.m_maximumLikelihood;
192 m_outputFilePrefix = other.m_outputFilePrefix;
193 }
194 return *this;
195 }
196
197
211
212
224 return m_validateNetwork;
225 }
226
227
234 void BundleSettings::setCubeList(QString cubeList) {
235 m_cubeList = cubeList;
236 }
237
238
244 QString BundleSettings::cubeList() const {
245 return m_cubeList;
246 }
247
248
249 // =============================================================================================//
250 // ======================== Solve Options ======================================================//
251 // =============================================================================================//
252
269 void BundleSettings::setSolveOptions(bool solveObservationMode,
270 bool updateCubeLabel,
271 bool errorPropagation,
272 bool solveRadius,
273 SurfacePoint::CoordinateType coordTypeBundle,
274 SurfacePoint::CoordinateType coordTypeReports,
275 double globalPointCoord1AprioriSigma,
276 double globalPointCoord2AprioriSigma,
277 double globalPointCoord3AprioriSigma) {
282 m_cpCoordTypeReports = coordTypeReports;
283 m_cpCoordTypeBundle = coordTypeBundle;
284 // m_cpCoordTypeBundle = SurfacePoint::Latitudinal;
285
286 if (globalPointCoord1AprioriSigma > 0.0) { // otherwise, we leave as default Isis::Null
288 }
289 else {
291 }
292
295 }
296 else {
298 }
299
300 // This is ugly. *** TODO *** Revisit this section to try to find a cleaner solution.
301 // I think we will have to do similar checking other places.
302 // See pvlObject, save, (DAC 03-29-2017)
303 if (coordTypeBundle == SurfacePoint::Latitudinal) {
306 }
307 else {
309 }
310 }
311 else if (coordTypeBundle == SurfacePoint::Rectangular) {
314 }
315 else {
317 }
318 }
319 }
320
321
329 void BundleSettings::setOutlierRejection(bool outlierRejection, double multiplier) {
331 if (m_outlierRejection) {
332 m_outlierRejectionMultiplier = multiplier;
333 }
334 else {
336 }
337 }
338
339
348 QList<BundleObservationSolveSettings> obsSolveSettingsList) {
349 m_observationSolveSettings = obsSolveSettingsList;
350 }
351
352
364
365
378
379
394
395
404 return m_outlierRejection;
405 }
406
407
417
418
426 return m_solveRadius;
427 }
428
429
438 return m_updateCubeLabel;
439 }
440
441
449 return m_errorPropagation;
450 }
451
452
466 void BundleSettings::setCreateInverseMatrix(bool createMatrixFile) {
467 m_createInverseMatrix = createMatrixFile;
468 }
469
470
479
480
489
490
499
500
509
510
518 return m_observationSolveSettings.size();
519 }
520
521
534 BundleSettings::observationSolveSettings(QString observationNumber) const {
535
536 BundleObservationSolveSettings defaultSolveSettings;
537
538 for (int i = 0; i < numberSolveSettings(); i++) {
539 if (m_observationSolveSettings[i].observationNumbers().contains(observationNumber)) {
540 return m_observationSolveSettings[i];
541 }
542 }
543 return defaultSolveSettings;
544 }
545
546
560
561 if (n >= 0 && n < numberSolveSettings()) {
562 return m_observationSolveSettings[n];
563 }
564 QString msg = "Unable to find BundleObservationSolveSettings with index = ["
565 + toString(n) + "].";
566 throw IException(IException::Unknown, msg, _FILEINFO_);
567 }
568
569
576 QList<BundleObservationSolveSettings> BundleSettings::observationSolveSettings() const {
577 return m_observationSolveSettings;
578 }
579
580
581 // =============================================================================================//
582 // ======================== Convergence Criteria ===============================================//
583 // =============================================================================================//
584
602 if (criteria.compare("SIGMA0", Qt::CaseInsensitive) == 0) {
604 }
605 else if (criteria.compare("PARAMETERCORRECTIONS", Qt::CaseInsensitive) == 0) {
607 }
609 "Unknown bundle convergence criteria [" + criteria + "].",
610 _FILEINFO_);
611 }
612
613
627 if (criteria == Sigma0) return "Sigma0";
628 else if (criteria == ParameterCorrections) return "ParameterCorrections";
630 "Unknown convergence criteria enum [" + toString(criteria) + "].",
631 _FILEINFO_);
632 }
633
634
646 double threshold,
647 int maximumIterations) {
648 m_convergenceCriteria = criteria;
650 m_convergenceCriteriaMaximumIterations = maximumIterations;
651 }
652
653
663
664
674
675
687
688
689
690 // =============================================================================================//
691 // ======================== Parameter Uncertainties (Weighting) ================================//
692 // =============================================================================================//
693// void BundleSettings::setGlobalLatitudeAprioriSigma(double sigma) {
694// m_globalLatitudeAprioriSigma = sigma;
695// }
696//
697//
698//
699// void BundleSettings::setGlobalLongitudeAprioriSigma(double sigma) {
700// m_globalLongitudeAprioriSigma = sigma;
701// }
702//
703//
704//
705// void BundleSettings::setGlobalRadiiAprioriSigma(double sigma) {
706// m_globalRadiusAprioriSigma = sigma;
707// }
708
709
710 // =============================================================================================//
711 // ======================== Maximum Likelihood Estimation Options ==============================//
712 // =============================================================================================//
713
714
728 double maxModelCQuantile) {
729
731 QString msg = "For bundle adjustments with multiple maximum likelihood estimators, the first "
732 "model must be of type HUBER or HUBER_MODIFIED.";
733 throw IException(IException::Programmer, msg, _FILEINFO_);
734 }
735
736 m_maximumLikelihood.append(qMakePair(model, maxModelCQuantile));
737 }
738
739
748 QList< QPair< MaximumLikelihoodWFunctions::Model, double > >
752
753
754 // =============================================================================================//
755 // ======================== Self Calibration ??? (from ipce only) =========================//
756 // =============================================================================================//
757
758 // =============================================================================================//
759 // ======================== Target Body ??? (from ipce only) ==============================//
760 // =============================================================================================//
761
771
772
782
783
790// bool BundleSettings::solveTargetBodyPolePosition() const {
791// return m_solveTargetBodyPolePosition;
792// }
793
794
803 return 0;
804
805 return m_bundleTargetBody->numberParameters();
806 }
807
808
816 if (!m_bundleTargetBody) {
817 return false;
818 }
819 else {
820 return (m_bundleTargetBody->numberParameters() > 0);
821 }
822 }
823
824
834 if (!m_bundleTargetBody) {
835 return false;
836 }
837 return m_bundleTargetBody->solvePoleRA();
838 }
839
840
850 if (!m_bundleTargetBody) {
851 return false;
852 }
853 return m_bundleTargetBody->solvePoleRAVelocity();
854 }
855
856
866 if (!m_bundleTargetBody) {
867 return false;
868 }
869 return m_bundleTargetBody->solvePoleDec();
870 }
871
872
882 if (!m_bundleTargetBody) {
883 return false;
884 }
885 return m_bundleTargetBody->solvePoleDecVelocity();
886 }
887
888
898 if (!m_bundleTargetBody) {
899 return false;
900 }
901 return m_bundleTargetBody->solvePM();
902 }
903
904
914 if (!m_bundleTargetBody) {
915 return false;
916 }
917 return m_bundleTargetBody->solvePMVelocity();
918 }
919
920
930 if (!m_bundleTargetBody) {
931 return false;
932 }
933 return m_bundleTargetBody->solvePMAcceleration();
934 }
935
936
946 if (!m_bundleTargetBody) {
947 return false;
948 }
949 return m_bundleTargetBody->solveTriaxialRadii();
950 }
951
952
962 if (!m_bundleTargetBody) {
963 return false;
964 }
965 return m_bundleTargetBody->solveMeanRadius();
966 }
967
968
969// void BundleSettings::setTargetBodySolveOptions(bool solveTargetBodyPolePosition,
970// double aprioriRaPole, double sigmaRaPole,
971// double aprioriDecPole, double sigmaDecPole,
972// bool solveTargetBodyZeroMeridian,
973// double aprioriW0, double sigmaW0,
974// bool solveTargetBodyRotationRate,
975// double aprioriWDot, double sigmaWDot,
976// TargetRadiiSolveMethod solveRadiiMethod,
977// double aprioriRadiusA, double sigmaRadiusA,
978// double aprioriRadiusB, double sigmaRadiusB,
979// double aprioriRadiusC, double sigmaRadiusC,
980// double aprioriMeanRadius, double sigmaMeanRadius) {
981
982
983// m_solveTargetBody = true;
984// m_solveTargetBodyPolePosition = solveTargetBodyPolePosition;
985// m_aprioriRaPole = aprioriRaPole;
986// m_sigmaRaPole = sigmaRaPole;
987// m_aprioriDecPole = aprioriDecPole;
988// m_sigmaDecPole = sigmaDecPole;
989// m_solveTargetBodyZeroMeridian =solveTargetBodyZeroMeridian;
990// m_aprioriW0 = aprioriW0;
991// m_sigmaW0 = sigmaW0;
992// m_solveTargetBodyRotationRate = solveTargetBodyRotationRate;
993// m_aprioriWDot = aprioriWDot;
994// m_sigmaWDot = sigmaWDot;
995// m_solveTargetBodyRadiusMethod = solveRadiiMethod;
996// m_aprioriRadiusA = aprioriRadiusA;
997// m_sigmaRadiusA = sigmaRadiusA;
998// m_aprioriRadiusB = aprioriRadiusB;
999// m_sigmaRadiusB = sigmaRadiusB;
1000// m_aprioriRadiusC = aprioriRadiusC;
1001// m_sigmaRadiusC = sigmaRadiusC;
1002// m_aprioriMeanRadius = aprioriMeanRadius;
1003// m_sigmaMeanRadius = sigmaMeanRadius;
1004
1005// m_bundleTargetBody->setSolveSettings(solveTargetBodyPolePosition, aprioriRaPole, sigmaRaPole,
1006// aprioriDecPole, sigmaDecPole, solveTargetBodyZeroMeridian,
1007// aprioriW0, sigmaW0, solveTargetBodyRotationRate,
1008// aprioriWDot, sigmaWDot, solveRadiiMethod, aprioriRadiusA,
1009// sigmaRadiusA, aprioriRadiusB, sigmaRadiusB, aprioriRadiusC,
1010// sigmaRadiusC, aprioriMeanRadius, sigmaMeanRadius);
1011// }
1012
1013
1014 // =============================================================================================//
1015 // ========================= Output Options (from Jigsaw only) ================================//
1016 // =============================================================================================//
1022 void BundleSettings::setOutputFilePrefix(QString outputFilePrefix) {
1024 }
1025
1026
1037 return m_outputFilePrefix;
1038 }
1039
1040
1050 void BundleSettings::save(QXmlStreamWriter &stream, const Project *project) const {
1051 stream.writeStartElement("bundleSettings");
1052
1053 stream.writeStartElement("globalSettings");
1054
1055 stream.writeTextElement("validateNetwork", toString(validateNetwork()));
1056
1057 stream.writeStartElement("solveOptions");
1058 stream.writeAttribute("solveObservationMode", toString(solveObservationMode()));
1059 stream.writeAttribute("solveRadius", toString(solveRadius()));
1060 stream.writeAttribute("controlPointCoordTypeReports", toString(controlPointCoordTypeReports()));
1061 stream.writeAttribute("controlPointCoordTypeBundle", toString(controlPointCoordTypeBundle()));
1062 stream.writeAttribute("updateCubeLabel", toString(updateCubeLabel()));
1063 stream.writeAttribute("errorPropagation", toString(errorPropagation()));
1064 stream.writeAttribute("createInverseMatrix", toString(createInverseMatrix()));
1065 stream.writeEndElement();
1066
1067 stream.writeStartElement("aprioriSigmas");
1069 stream.writeAttribute("pointCoord1", "N/A");
1070 }
1071 else {
1072 stream.writeAttribute("pointCoord1", toString(globalPointCoord1AprioriSigma()));
1073 }
1075 stream.writeAttribute("pointCoord2", "N/A");
1076 }
1077 else {
1078 stream.writeAttribute("pointCoord2", toString(globalPointCoord2AprioriSigma()));
1079 }
1081 stream.writeAttribute("pointCoord3", "N/A");
1082 }
1083 else {
1084 stream.writeAttribute("pointCoord3", toString(globalPointCoord3AprioriSigma()));
1085 }
1086 stream.writeEndElement();
1087
1088 stream.writeStartElement("outlierRejectionOptions");
1089 stream.writeAttribute("rejection", toString(outlierRejection()));
1090 if (outlierRejection()) {
1091 stream.writeAttribute("multiplier", toString(outlierRejectionMultiplier()));
1092 }
1093 else {
1094 stream.writeAttribute("multiplier", "N/A");
1095 }
1096 stream.writeEndElement();
1097
1098 stream.writeStartElement("convergenceCriteriaOptions");
1099 stream.writeAttribute("convergenceCriteria",
1101 stream.writeAttribute("threshold",
1103 stream.writeAttribute("maximumIterations",
1105 stream.writeEndElement();
1106
1107 stream.writeStartElement("maximumLikelihoodEstimation");
1108 for (int i = 0; i < m_maximumLikelihood.size(); i++) {
1109 stream.writeStartElement("model");
1110 stream.writeAttribute("type",
1112 stream.writeAttribute("quantile", toString(m_maximumLikelihood[i].second));
1113 stream.writeEndElement();
1114 }
1115 stream.writeEndElement();
1116
1117 stream.writeStartElement("outputFileOptions");
1118 stream.writeAttribute("fileNamePrefix", outputFilePrefix());
1119 stream.writeEndElement();
1120
1121 stream.writeEndElement(); // end global settings
1122
1123 if (!m_observationSolveSettings.isEmpty()) {
1124 stream.writeStartElement("observationSolveSettingsList");
1125 for (int i = 0; i < m_observationSolveSettings.size(); i++) {
1126 m_observationSolveSettings[i].save(stream, project);
1127 }
1128 stream.writeEndElement();
1129 }
1130 else {
1131 // throw error??? should not write if no observation settings...
1132 }
1133 stream.writeEndElement();
1134 }
1135
1136
1146 m_xmlHandlerBundleSettings = bundleSettings;
1147 m_xmlHandlerProject = project;
1148 m_xmlHandlerCharacters = "";
1149 m_xmlHandlerObservationSettings.clear();
1150 }
1151
1152
1158
1159
1175 bool BundleSettings::XmlHandler::startElement(const QString &namespaceURI,
1176 const QString &localName,
1177 const QString &qName,
1178 const QXmlAttributes &attributes) {
1179 m_xmlHandlerCharacters = "";
1180
1181 if (XmlStackedHandler::startElement(namespaceURI, localName, qName, attributes)) {
1182
1183 if (localName == "solveOptions") {
1184
1185 QString solveObservationModeStr = attributes.value("solveObservationMode");
1186 if (!solveObservationModeStr.isEmpty()) {
1187 m_xmlHandlerBundleSettings->m_solveObservationMode = toBool(solveObservationModeStr);
1188 }
1189
1190 QString solveRadiusStr = attributes.value("solveRadius");
1191 if (!solveRadiusStr.isEmpty()) {
1192 m_xmlHandlerBundleSettings->m_solveRadius = toBool(solveRadiusStr);
1193 }
1194
1195 QString coordTypeReportsStr = attributes.value("controlPointCoordinateTypeReports");
1196 if (!coordTypeReportsStr.isEmpty()) {
1197 m_xmlHandlerBundleSettings->m_cpCoordTypeReports =
1198 SurfacePoint::stringToCoordinateType(coordTypeReportsStr);
1199 }
1200
1201 QString coordTypeBundleStr = attributes.value("controlPointCoordinateTypeBundle");
1202 if (!coordTypeBundleStr.isEmpty()) {
1203 m_xmlHandlerBundleSettings->m_cpCoordTypeBundle =
1204 SurfacePoint::stringToCoordinateType(coordTypeBundleStr);
1205 }
1206
1207 QString updateCubeLabelStr = attributes.value("updateCubeLabel");
1208 if (!updateCubeLabelStr.isEmpty()) {
1209 m_xmlHandlerBundleSettings->m_updateCubeLabel = toBool(updateCubeLabelStr);
1210 }
1211
1212 QString errorPropagationStr = attributes.value("errorPropagation");
1213 if (!errorPropagationStr.isEmpty()) {
1214 m_xmlHandlerBundleSettings->m_errorPropagation = toBool(errorPropagationStr);
1215 }
1216
1217 QString createInverseMatrixStr = attributes.value("createInverseMatrix");
1218 if (!createInverseMatrixStr.isEmpty()) {
1219 m_xmlHandlerBundleSettings->m_createInverseMatrix = toBool(createInverseMatrixStr);
1220 }
1221 }
1222 else if (localName == "aprioriSigmas") {
1223
1224 QString globalPointCoord1AprioriSigmaStr = attributes.value("pointCoord1");
1225 m_xmlHandlerBundleSettings->m_globalPointCoord1AprioriSigma = Isis::Null;
1226 // TODO: why do I need to init this one and not other sigmas???
1227 if (!globalPointCoord1AprioriSigmaStr.isEmpty()) {
1228 if (globalPointCoord1AprioriSigmaStr == "N/A") {
1229 m_xmlHandlerBundleSettings->m_globalPointCoord1AprioriSigma = Isis::Null;
1230 }
1231 else {
1232 m_xmlHandlerBundleSettings->m_globalPointCoord1AprioriSigma
1233 = toDouble(globalPointCoord1AprioriSigmaStr);
1234 }
1235 }
1236
1237 QString globalPointCoord2AprioriSigmaStr = attributes.value("pointCoord2");
1238 if (!globalPointCoord2AprioriSigmaStr.isEmpty()) {
1239 if (globalPointCoord2AprioriSigmaStr == "N/A") {
1240 m_xmlHandlerBundleSettings->m_globalPointCoord2AprioriSigma = Isis::Null;
1241 }
1242 else {
1243 m_xmlHandlerBundleSettings->m_globalPointCoord2AprioriSigma
1244 = toDouble(globalPointCoord2AprioriSigmaStr);
1245 }
1246 }
1247
1248 QString globalPointCoord3AprioriSigmaStr = attributes.value("radius");
1249 if (!globalPointCoord3AprioriSigmaStr.isEmpty()) {
1250 if (globalPointCoord3AprioriSigmaStr == "N/A") {
1251 m_xmlHandlerBundleSettings->m_globalPointCoord3AprioriSigma = Isis::Null;
1252 }
1253 else {
1254 m_xmlHandlerBundleSettings->m_globalPointCoord3AprioriSigma
1255 = toDouble(globalPointCoord3AprioriSigmaStr);
1256 }
1257 }
1258 }
1259 else if (localName == "outlierRejectionOptions") {
1260 QString outlierRejectionStr = attributes.value("rejection");
1261 if (!outlierRejectionStr.isEmpty()) {
1262 m_xmlHandlerBundleSettings->m_outlierRejection = toBool(outlierRejectionStr);
1263 }
1264
1265 QString outlierRejectionMultiplierStr = attributes.value("multiplier");
1266 if (!outlierRejectionMultiplierStr.isEmpty()) {
1267 if (outlierRejectionMultiplierStr != "N/A") {
1268 m_xmlHandlerBundleSettings->m_outlierRejectionMultiplier
1269 = toDouble(outlierRejectionMultiplierStr);
1270 }
1271 else {
1272 m_xmlHandlerBundleSettings->m_outlierRejectionMultiplier = 3.0;
1273 }
1274 }
1275 }
1276 else if (localName == "convergenceCriteriaOptions") {
1277
1278 QString convergenceCriteriaStr = attributes.value("convergenceCriteria");
1279 if (!convergenceCriteriaStr.isEmpty()) {
1280 m_xmlHandlerBundleSettings->m_convergenceCriteria
1281 = stringToConvergenceCriteria(convergenceCriteriaStr);
1282 }
1283
1284 QString convergenceCriteriaThresholdStr = attributes.value("threshold");
1285 if (!convergenceCriteriaThresholdStr.isEmpty()) {
1286 m_xmlHandlerBundleSettings->m_convergenceCriteriaThreshold
1287 = toDouble(convergenceCriteriaThresholdStr);
1288 }
1289
1290 QString convergenceCriteriaMaximumIterationsStr = attributes.value("maximumIterations");
1291 if (!convergenceCriteriaMaximumIterationsStr.isEmpty()) {
1292 m_xmlHandlerBundleSettings->m_convergenceCriteriaMaximumIterations
1293 = toInt(convergenceCriteriaMaximumIterationsStr);
1294 }
1295 }
1296 else if (localName == "model") {
1297 QString type = attributes.value("type");
1298 QString quantile = attributes.value("quantile");
1299 if (!type.isEmpty() && !quantile.isEmpty()) {
1300 m_xmlHandlerBundleSettings->m_maximumLikelihood.append(
1301 qMakePair(MaximumLikelihoodWFunctions::stringToModel(type),
1302 toDouble(quantile)));
1303 }
1304 }
1305 else if (localName == "outputFileOptions") {
1306 QString outputFilePrefixStr = attributes.value("fileNamePrefix");
1307 if (!outputFilePrefixStr.isEmpty()) {
1308 m_xmlHandlerBundleSettings->m_outputFilePrefix = outputFilePrefixStr;
1309 }
1310 }
1311 else if (localName == "bundleObservationSolveSettings") {
1312 m_xmlHandlerObservationSettings.append(
1313 new BundleObservationSolveSettings(m_xmlHandlerProject, reader()));
1314 }
1315 }
1316 return true;
1317 }
1318
1319
1327 m_xmlHandlerCharacters += ch;
1328 return XmlStackedHandler::characters(ch);
1329 }
1330
1331
1341 bool BundleSettings::XmlHandler::endElement(const QString &namespaceURI, const QString &localName,
1342 const QString &qName) {
1343 if (!m_xmlHandlerCharacters.isEmpty()) {
1344 if (localName == "validateNetwork") {
1345 m_xmlHandlerBundleSettings->m_validateNetwork = toBool(m_xmlHandlerCharacters);
1346 }
1347 else if (localName == "observationSolveSettingsList") {
1348 for (int i = 0; i < m_xmlHandlerObservationSettings.size(); i++) {
1349 m_xmlHandlerBundleSettings->m_observationSolveSettings.append(
1350 *m_xmlHandlerObservationSettings[i]);
1351 }
1352 m_xmlHandlerObservationSettings.clear();
1353 }
1354
1355 m_xmlHandlerCharacters = "";
1356 }
1357 return XmlStackedHandler::endElement(namespaceURI, localName, qName);
1358 }
1359
1360
1367 bool BundleSettings::XmlHandler::fatalError(const QXmlParseException &exception) {
1368 qDebug() << "Parse error with BundleSettings at line " << exception.lineNumber()
1369 << ", " << "column " << exception.columnNumber() << ": "
1370 << qPrintable(exception.message());
1371 return false;
1372 }
1373}
This class is used to modify and manage solve settings for 1 to many BundleObservations.
This class is needed to read/write BundleSettings from/to an XML formateed file.
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
Handle an XML start element.
XmlHandler(BundleSettings *bundleSettings, Project *project)
Create an XML Handler (reader) that can populate the BundleSettings class data.
~XmlHandler()
Destroys BundleSettings::XmlHandler object.
virtual bool characters(const QString &ch)
Add a character from an XML element to the content handler.
virtual bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName)
Handle end tags for the BundleSettings serialized XML.
bool fatalError(const QXmlParseException &exception)
Format an error message indicating a problem with BundleSettings.
Container class for BundleAdjustment settings.
bool m_createInverseMatrix
Indicates whether to create the inverse matrix file.
double globalPointCoord2AprioriSigma() const
Retrieves the global a priori sigma for 2nd coordinate of points for this bundle.
bool validateNetwork() const
This method is used to determine whether to validate the network before the bundle adjustment.
int convergenceCriteriaMaximumIterations() const
Retrieves the maximum number of iterations allowed to solve the bundle adjustment.
bool m_solveRadius
Indicates whether to solve for point radii.
BundleSettings & operator=(const BundleSettings &other)
Assignment operator to allow proper copying of the 'other' BundleSettings object to this one.
double globalPointCoord3AprioriSigma() const
Retrieves the global a priori sigma 3rd coordinate of points for this bundle.
void addMaximumLikelihoodEstimatorModel(MaximumLikelihoodWFunctions::Model model, double cQuantile)
Add a maximum likelihood estimator (MLE) model to the bundle adjustment.
BundleSettings()
Constructs a BundleSettings object.
QString m_outputFilePrefix
The prefix for all output files.
bool m_solveObservationMode
Indicates whether to solve for observation mode.
SurfacePoint::CoordinateType controlPointCoordTypeBundle() const
Indicates the control point coordinate type for the actual bundle adjust.
bool errorPropagation() const
This method is used to determine whether this bundle adjustment will perform error propagation.
void setConvergenceCriteria(ConvergenceCriteria criteria, double threshold, int maximumIterations)
Set the convergence criteria options for the bundle adjustment.
bool solvePMVelocity() const
This method is used to determine whether the bundle adjustment will solve for target body prime merid...
double m_globalPointCoord2AprioriSigma
The global a priori sigma for longitude or Y.
void save(QXmlStreamWriter &stream, const Project *project) const
This method is used to write a BundleSettings object in an XML format.
ConvergenceCriteria
This enum defines the options for the bundle adjustment's convergence.
@ Sigma0
The value of sigma0 will be used to determine that the bundle adjustment has converged.
@ ParameterCorrections
All parameter corrections will be used to determine that the bundle adjustment has converged.
BundleTargetBodyQsp bundleTargetBody() const
Retrieves a pointer to target body information for the bundle adjustment.
void setCreateInverseMatrix(bool createMatrix)
Turn the creation of the inverse correlation matrix file on or off.
bool solveMeanRadius() const
This method is used to determine whether the bundle adjustment will solve for target body mean radius...
bool solveRadius() const
This method is used to determine whether this bundle adjustment will solve for radius.
void init()
Set Default vales for a BundleSettings object.
bool solveTriaxialRadii() const
This method is used to determine whether the bundle adjustment will solve for target body triaxial ra...
BundleTargetBodyQsp m_bundleTargetBody
A pointer to the target body settings and information.
ConvergenceCriteria m_convergenceCriteria
Enumeration used to indicate what criteria to use to determine bundle adjustment convergence.
double m_globalPointCoord3AprioriSigma
The global a priori sigma for radius or Z.
bool solvePMAcceleration() const
This method is used to determine whether the bundle adjustment will solve for target body prime merid...
QList< BundleObservationSolveSettings > observationSolveSettings() const
Retrieves solve settings for the observation corresponding to the given index.
void setBundleTargetBody(BundleTargetBodyQsp bundleTargetBody)
Sets the target body for the bundle adjustment.
int numberTargetBodyParameters() const
This method is used to determine whether the bundle adjustment will solve for target body pole positi...
QString outputFilePrefix() const
Retrieve the output file prefix.
double globalPointCoord1AprioriSigma() const
Retrieves global a priori sigma for 1st coordinate of points for this bundle.
bool updateCubeLabel() const
This method is used to determine whether this bundle adjustment will update the cube labels.
double m_convergenceCriteriaThreshold
Tolerance value corresponding to the selected convergence criteria.
double m_outlierRejectionMultiplier
The multiplier value for outlier rejection.
bool outlierRejection() const
This method is used to determine whether outlier rejection will be performed on this bundle adjustmen...
void setOutputFilePrefix(QString outputFilePrefix)
Set the output file prefix for the bundle adjustment.
bool solvePoleRA() const
This method is used to determine whether the bundle adjustment will solve for target body pole right ...
bool solvePoleDecVelocity() const
This method is used to determine whether the bundle adjustment will solve for target body pole declin...
static QString convergenceCriteriaToString(ConvergenceCriteria criteria)
Converts the given BundleSettings::ConvergenceCriteria enumeration to a string.
void setValidateNetwork(bool validate)
Sets the internal flag to indicate whether to validate the network before the bundle adjustment.
~BundleSettings()
Destroys the BundleSettings object.
static ConvergenceCriteria stringToConvergenceCriteria(QString criteria)
Converts the given string value to a BundleSettings::ConvergenceCriteria enumeration.
SurfacePoint::CoordinateType m_cpCoordTypeReports
Indicates the coordinate type for outputting control points in reports.
bool m_outlierRejection
Indicates whether to perform automatic outlier detection/rejection.
bool m_errorPropagation
Indicates whether to perform error propagation.
bool createInverseMatrix() const
Indicates if the settings will allow the inverse correlation matrix to be created.
bool solvePoleRAVelocity() const
This method is used to determine whether the bundle adjustment will solve for target body pole right ...
QString cubeList() const
BundleSettings::cubeList.
QList< QPair< MaximumLikelihoodWFunctions::Model, double > > m_maximumLikelihood
Model and C-Quantile for each of the three maximum likelihood estimations.
void setOutlierRejection(bool outlierRejection, double multiplier=1.0)
Set the outlier rejection options for the bundle adjustment.
ConvergenceCriteria convergenceCriteria() const
Retrieves the convergence criteria to be used to solve the bundle adjustment.
QList< QPair< MaximumLikelihoodWFunctions::Model, double > > maximumLikelihoodEstimatorModels() const
Retrieves the list of maximum likelihood estimator (MLE) models with their corresponding C-Quantiles.
bool solvePoleDec() const
This method is used to determine whether the bundle adjustment will solve for target body pole declin...
bool m_validateNetwork
Indicates whether the network should be validated.
double m_globalPointCoord1AprioriSigma
The global a priori sigma for latitude or X.
int numberSolveSettings() const
Retrieves the number of observation solve settings.
void setSolveOptions(bool solveObservationMode=false, bool updateCubeLabel=false, bool errorPropagation=false, bool solveRadius=false, SurfacePoint::CoordinateType coordTypeBundle=SurfacePoint::Latitudinal, SurfacePoint::CoordinateType coordTypeReports=SurfacePoint::Latitudinal, double globalPointCoord1AprioriSigma=Isis::Null, double globalPointCoord2AprioriSigma=Isis::Null, double globalPointCoord3AprioriSigma=Isis::Null)
Set the solve options for the bundle adjustment.
SurfacePoint::CoordinateType controlPointCoordTypeReports() const
Indicates the control point coordinate type for reports.
bool solvePM() const
This method is used to determine whether the bundle adjustment will solve for target body prime merid...
void setCubeList(QString fileName)
BundleSettings::setCubeList.
bool m_updateCubeLabel
Indicates whether to update cubes.
double convergenceCriteriaThreshold() const
Retrieves the convergence threshold to be used to solve the bundle adjustment.
void setObservationSolveOptions(QList< BundleObservationSolveSettings > obsSolveSettingsList)
Add the list of solve options for each observation.
bool solveObservationMode() const
This method is used to determine whether this bundle adjustment will solve for observation mode.
int m_convergenceCriteriaMaximumIterations
Maximum number of iterations before quitting the bundle adjustment if it has not yet converged to the...
bool solveTargetBody() const
This method is used to determine whether the bundle adjustment will solve for target body.
double outlierRejectionMultiplier() const
Retrieves the outlier rejection multiplier for the bundle adjustment.
bool m_solveTargetBody
Indicates whether to solve for target body.
SurfacePoint::CoordinateType m_cpCoordTypeBundle
Indicates the coordinate type used for control points in the bundle adjustment.
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
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
static QString modelToString(Model model)
Static method to return a string represtentation for a given MaximumLikelihoodWFunctions::Model enum.
Model
The supported maximum likelihood estimation models.
@ HuberModified
A modification to Huber's method propsed by William J.J.
The main project for ipce.
Definition Project.h:289
CoordinateType
Defines the coordinate typ, units, and coordinate index for some of the output methods.
@ Latitudinal
Planetocentric latitudinal (lat/lon/rad) coordinates.
@ Rectangular
Body-fixed rectangular x/y/z coordinates.
static CoordinateType stringToCoordinateType(QString type)
This method converts the given string value to a SurfacePoint::CoordinateType enumeration.
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
bool validate(const NaifVertex &v)
Verifies that the given NaifVector or NaifVertex is 3 dimensional.