Isis 3 Programmer Reference
BundleSolutionInfo.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "BundleSolutionInfo.h"
10
11#include <QDataStream>
12#include <QDebug>
13#include <QFile>
14#include <QList>
15#include <QString>
16#include <QStringList>
17#include <QUuid>
18#include <QXmlStreamWriter>
19#include <QXmlStreamReader>
20
21#include "BundleLidarRangeConstraint.h"
22#include "BundleResults.h"
23#include "Control.h"
24#include "ControlList.h"
25#include "ControlMeasure.h"
26#include "ControlNet.h"
27#include "ControlPoint.h"
28#include "FileName.h"
29#include "ImageList.h"
30#include "IString.h"
31#include "iTime.h"
32#include "Project.h"
33#include "PvlKeyword.h"
34#include "PvlObject.h"
35#include "StatCumProbDistDynCalc.h"
36#include "Statistics.h"
37
38namespace Isis {
39
48 BundleSolutionInfo::BundleSolutionInfo(BundleSettingsQsp inputSettings,
49 FileName controlNetworkFileName,
50 BundleResults outputStatistics,
51 QList<ImageList *> imgList,
52 QObject *parent) : QObject(parent) {
53 m_id = new QUuid(QUuid::createUuid());
54 m_runTime = "";
56 m_inputControlNetFileName = new FileName(controlNetworkFileName);
57 m_outputControl = NULL;
58 m_outputControlName="";
61 m_settings = inputSettings;
62 m_statisticsResults = new BundleResults(outputStatistics);
63 m_images = new QList<ImageList *>(imgList);
64 m_adjustedImages = new QList<ImageList *>;
65 }
66
67
76 BundleSolutionInfo::BundleSolutionInfo(BundleSettingsQsp inputSettings,
77 FileName controlNetworkFileName,
78 FileName lidarDataFileName,
79 BundleResults outputStatistics,
80 QList<ImageList *> imgList,
81 QObject *parent) : QObject(parent) {
82 m_id = new QUuid(QUuid::createUuid());
83 m_runTime = "";
85 m_inputControlNetFileName = new FileName(controlNetworkFileName);
86 m_outputControl = NULL;
87 m_outputControlName="";
88 m_inputLidarDataFileName = new FileName(lidarDataFileName);
90 m_settings = inputSettings;
91 m_statisticsResults = new BundleResults(outputStatistics);
92 m_images = new QList<ImageList *>(imgList);
93 m_adjustedImages = new QList<ImageList *>;
94 }
95
96
107 BundleSolutionInfo::BundleSolutionInfo(Project *project,
108 QXmlStreamReader *xmlReader,
109 QObject *parent) : QObject(parent)
110 {
111 m_id = new QUuid(QUuid::createUuid());
112 m_runTime = "";
115 m_outputControl = NULL;
116 m_outputControlName = "";
119 m_statisticsResults = NULL;
120 // what about the rest of the member data ? should we set defaults ??? CREATE INITIALIZE METHOD
121 m_images = new QList<ImageList *>;
122 m_adjustedImages = new QList<ImageList *>;
123
124 m_xmlHandlerProject = project;
126
127 readBundleSolutionInfo(xmlReader);
128 }
129
130 void BundleSolutionInfo::readBundleSolutionInfo(QXmlStreamReader *xmlReader) {
131 QString projectRoot;
132 if (m_xmlHandlerProject) {
133 projectRoot = m_xmlHandlerProject->projectRoot() + "/";
134 }
135 if (!m_adjustedImages){
136 m_adjustedImages = new QList<ImageList *>;
137 }
138 Q_ASSERT(xmlReader->name() == "bundleSolutionInfo");
139 while(xmlReader->readNextStartElement()) {
140 if (xmlReader->qualifiedName() == "generalAttributes") {
141 while (xmlReader->readNextStartElement()) {
142 if (xmlReader->qualifiedName() == "id") {
143 m_id = new QUuid(xmlReader->readElementText());
144 }
145 else if (xmlReader->qualifiedName() == "name") {
146 m_name = xmlReader->readElementText();
147 }
148 else if (xmlReader->qualifiedName() == "runTime") {
149 m_runTime = xmlReader->readElementText();
150 }
151 else if (xmlReader->qualifiedName() == "inputFileName") {
152 m_inputControlNetFileName = new FileName(projectRoot + xmlReader->readElementText());
153 }
154 else if (xmlReader->qualifiedName() == "bundleOutTXT") {
155 m_txtBundleOutputFilename = projectRoot + xmlReader->readElementText();
156 }
157 else if (xmlReader->qualifiedName() == "imagesCSV") {
158 m_csvSavedImagesFilename = projectRoot + xmlReader->readElementText();
159 }
160 else if (xmlReader->qualifiedName() == "pointsCSV") {
161 m_csvSavedPointsFilename = projectRoot + xmlReader->readElementText();
162 }
163 else if (xmlReader->qualifiedName() == "residualsCSV") {
164 m_csvSavedResidualsFilename = projectRoot + xmlReader->readElementText();
165 }
166 else {
167 xmlReader->skipCurrentElement();
168 }
169 }
170 }
171 else if (xmlReader->name() == "bundleSettings") {
172 m_settings = NULL;
173 BundleSettings *settings = new BundleSettings();
174 settings->readBundleSettings(xmlReader);
175 m_settings = BundleSettingsQsp(settings);
176 }
177 else if (xmlReader->name() == "bundleResults") {
178 m_statisticsResults = NULL;
180 m_statisticsResults->readBundleResults(xmlReader);
181 }
182 else {
183 xmlReader->skipCurrentElement();
184 }
185 }
186 }
187
192 delete m_id;
193
196
197 delete m_outputControl;
198 m_outputControl = NULL;
199
202
205
206 delete m_statisticsResults;
207 m_statisticsResults = NULL;
208
209 if (m_images != NULL) {
210 delete m_images;
211 m_images = NULL;
212 }
213
214 // if (m_adjustedImages != NULL) {
215 // qDeleteAll(*m_adjustedImages);
216 // m_adjustedImages->clear();
217 // delete m_adjustedImages;
218 // m_adjustedImages = NULL;
219 // }
220 }
221
222
229 return m_txtBundleOutputFilename;
230 }
231
232
239 return m_csvSavedImagesFilename;
240 }
241
242
249 return m_csvSavedPointsFilename;
250 }
251
252
259 return m_csvSavedResidualsFilename;
260 }
261
262
269 m_adjustedImages->append(images);
270 }
271
272
279 delete m_statisticsResults;
280 m_statisticsResults = NULL;
281 m_statisticsResults = new BundleResults(statisticsResults);
282 }
283
284
298
299 //TODO do we need to close anything here?
300
301 FileName oldInputFileName(*m_inputControlNetFileName);
302 FileName newInputFileName(project->cnetRoot() + "/" +
303 oldInputFileName.dir().dirName() + "/" + oldInputFileName.name());
304 *m_inputControlNetFileName = newInputFileName.expanded();
305
306 FileName oldOutputFileName(m_outputControl->fileName());
307 FileName newOutputFileName(project->cnetRoot() + "/" +
308 oldOutputFileName.dir().dirName() + "/" + oldOutputFileName.name());
309
310 if (m_outputControl) {
311 delete m_outputControl;
312 }
313 m_outputControl = new Control(newOutputFileName.expanded());
314 m_outputControlName = newOutputFileName.expanded();
315 }
316
317
324 QList<ImageList *> BundleSolutionInfo::adjustedImages() const {
325 return *m_adjustedImages;
326 }
327
328
334 QString BundleSolutionInfo::id() const {
335 return m_id->toString().remove(QRegExp("[{}]"));
336 }
337
338
344 void BundleSolutionInfo::setRunTime(QString runTime) {
345 // ??? validate that a valid time has been given???
346 // try {
347 // iTime time(runTime);
348 // }
349 // catch (...) {
350 // throw IException(IException::Unknown,
351 // "Invalid bundle adjustment run time [" + runTime + ].",
352 // _FILEINFO_);
353 // }
355 if (m_name == m_runTime || m_name == "") {
356 m_name = runTime;
357 }
358 }
359
360
367 return m_runTime;
368 }
369
370
379
380
387
388 if (m_outputControl)
389 return m_outputControl->fileName();
390 else
391 return m_outputControlName;
392 }
393
394
403
404
411 m_outputControl = outputControl;
412 }
413
414
421 m_outputControlName = name;
422 }
423
424
431 return m_outputControlName;
432 }
433
442
443
452
453
463 return *m_statisticsResults;
464 }
465 else {
467 "Results for this bundle is NULL.",
468 _FILEINFO_);
469 }
470 }
471
472
478 QList<ImageList *> BundleSolutionInfo::imageList() {
479 return *m_images;
480 }
481
482
488 void BundleSolutionInfo::setName(QString name) {
489 m_name = name;
490 }
491
492
499 QString BundleSolutionInfo::name() const {
500 return m_name;
501 }
502
503
515 bool BundleSolutionInfo::outputImagesCSVHeader(std::ofstream &fpOut, BundleObservationQsp observation) {
516
517 if (!fpOut) {
518 return false;
519 }
520
521 char buf[1056];
522
523 // setup column headers
524 std::vector<QString> outputColumns;
525
526 outputColumns.push_back("Image,");
527 outputColumns.push_back("rms,");
528 outputColumns.push_back("rms,");
529 outputColumns.push_back("rms,");
530
531 QStringList observationParameters = observation->parameterList();
532
533 for (int i = 0; i < observationParameters.size(); i++) {
534 for (int j = 0; j < 5; j++) {
535 outputColumns.push_back(observationParameters[i] + ",");
536 }
537 }
538
539 // print first column header to buffer and output to file
540 int ncolumns = outputColumns.size();
541 for (int i = 0; i < ncolumns; i++) {
542 QString str = outputColumns.at(i);
543 snprintf(buf, sizeof(buf), "%s", (const char*)str.toLatin1().data());
544 fpOut << buf;
545 }
546 snprintf(buf, sizeof(buf), "\n");
547 fpOut << buf;
548
549 outputColumns.clear();
550
551 outputColumns.push_back("Filename,");
552 outputColumns.push_back("sample res,");
553 outputColumns.push_back("line res,");
554 outputColumns.push_back("total res,");
555
556 for (int i = 0; i < observationParameters.size(); i++) {
557 outputColumns.push_back("Initial,");
558 outputColumns.push_back("Correction,");
559 outputColumns.push_back("Final,");
560 outputColumns.push_back("Apriori Sigma,");
561 outputColumns.push_back("Adj Sigma,");
562 }
563
564 // print second column header to buffer and output to file
565 ncolumns = outputColumns.size();
566 for (int i = 0; i < ncolumns; i++) {
567 QString str = outputColumns.at(i);
568 snprintf(buf, sizeof(buf), "%s", (const char*)str.toLatin1().data());
569 fpOut << buf;
570 }
571 snprintf(buf, sizeof(buf), "\n");
572 fpOut << buf;
573
574 return true;
575 }
576
577
578
591 bool BundleSolutionInfo::outputHeader(std::ofstream &fpOut) {
592
593 if (!fpOut) {
594 return false;
595 }
596
598
599 char buf[1056];
600 int numObservations = m_statisticsResults->observations().size();
601 int numImages = 0;
602 for (int i = 0; i < numObservations; i++) {
603 numImages += m_statisticsResults->observations().at(i)->size();
604 }
605 int numValidPoints = m_statisticsResults->outputControlNet()->GetNumValidPoints();
606
607 int numValidLidarPoints = 0;
608 if (lidarData) {
609 numValidLidarPoints = lidarData->numberLidarPoints();
610 }
611
612 int numInnerConstraints = 0;
613 int numDistanceConstraints = 0;
614 int numDegreesOfFreedom = m_statisticsResults->degreesOfFreedom();
615
616 int convergenceCriteria = 1;
617
618 snprintf(buf, sizeof(buf), "JIGSAW: BUNDLE ADJUSTMENT\n=========================\n");
619 fpOut << buf;
620 snprintf(buf, sizeof(buf), "\n Run Time: %s",
621 Isis::iTime::CurrentLocalTime().toLatin1().data());
622 fpOut << buf;
623 snprintf(buf, sizeof(buf), "\n Network Filename: %s",
624 m_inputControlNetFileName->expanded().toLatin1().data());
625 fpOut << buf;
626
627 snprintf(buf, sizeof(buf),"\n Cube List: %s",
628 m_settings->cubeList().toStdString().c_str() );
629
630 fpOut << buf;
631
632 snprintf(buf, sizeof(buf), "\n Output Network Filename: %s",
633 outputControlName().toStdString().c_str() );
634 fpOut << buf;
635 snprintf(buf, sizeof(buf),"\n Output File Prefix: %s",
636 m_settings->outputFilePrefix().toStdString().c_str() );
637 fpOut <<buf;
638
639 snprintf(buf, sizeof(buf), "\n Network Id: %s",
640 m_statisticsResults->outputControlNet()->GetNetworkId().toLatin1().data());
641 fpOut << buf;
642 snprintf(buf, sizeof(buf), "\n Network Description: %s",\
643 m_statisticsResults->outputControlNet()->Description().toLatin1().data());
644 fpOut << buf;
646 snprintf(buf, sizeof(buf), "\n Lidar Data Filename: %s",
647 m_inputLidarDataFileName->expanded().toLatin1().data());
648 fpOut << buf;
649 }
650 snprintf(buf, sizeof(buf), "\n Target: %s",
651 m_statisticsResults->outputControlNet()->GetTarget().toLatin1().data());
652 fpOut << buf;
653 snprintf(buf, sizeof(buf), "\n\n Linear Units: kilometers");
654 fpOut << buf;
655 snprintf(buf, sizeof(buf), "\n Angular Units: decimal degrees");
656 fpOut << buf;
657 snprintf(buf, sizeof(buf), "\n\nINPUT: SOLVE OPTIONS\n====================\n");
658 fpOut << buf;
659
660 m_settings->solveObservationMode() ?
661 snprintf(buf, sizeof(buf), "\n OBSERVATIONS: ON"):
662 snprintf(buf, sizeof(buf), "\n OBSERVATIONS: OFF");
663 fpOut << buf;
664
665 m_settings->solveRadius() ?
666 snprintf(buf, sizeof(buf), "\n RADIUS: ON"):
667 snprintf(buf, sizeof(buf), "\n RADIUS: OFF");
668 fpOut << buf;
669
670 m_settings->solveTargetBody() ?
671 snprintf(buf, sizeof(buf), "\n TARGET BODY: ON"):
672 snprintf(buf, sizeof(buf), "\n TARGET BODY: OFF");
673 fpOut << buf;
674
675 m_settings->updateCubeLabel() ?
676 snprintf(buf, sizeof(buf), "\n UPDATE: YES"):
677 snprintf(buf, sizeof(buf), "\n UPDATE: NO");
678 fpOut << buf;
679
680 m_settings->errorPropagation() ?
681 snprintf(buf, sizeof(buf), "\n ERROR PROPAGATION: ON"):
682 snprintf(buf, sizeof(buf), "\n ERROR PROPAGATION: OFF");
683 fpOut << buf;
684
685 (m_settings->controlPointCoordTypeReports() == SurfacePoint::Latitudinal) ?
686 snprintf(buf, sizeof(buf), "\n CONTROL POINT COORDINATE TYPE FOR REPORTS: LATITUDINAL"):
687 snprintf(buf, sizeof(buf), "\n CONTROL POINT COORDINATE TYPE FOR REPORTS: RECTANGULAR");
688 fpOut << buf;
689
690 (m_settings->controlPointCoordTypeBundle() == SurfacePoint::Latitudinal) ?
691 snprintf(buf, sizeof(buf), "\n CONTROL POINT COORDINATE TYPE FOR BUNDLE: LATITUDINAL"):
692 snprintf(buf, sizeof(buf), "\n CONTROL POINT COORDINATE TYPE FOR BUNDLE: RECTANGULAR");
693 fpOut << buf;
694
695 if (m_settings->outlierRejection()) {
696 snprintf(buf, sizeof(buf), "\n OUTLIER REJECTION: ON");
697 fpOut << buf;
698 snprintf(buf, sizeof(buf), "\n REJECTION MULTIPLIER: %lf",
699 m_settings->outlierRejectionMultiplier());
700 fpOut << buf;
701
702 }
703 else {
704 snprintf(buf, sizeof(buf), "\n OUTLIER REJECTION: OFF");
705 fpOut << buf;
706 snprintf(buf, sizeof(buf), "\n REJECTION MULTIPLIER: N/A");
707 fpOut << buf;
708 }
709
710 // Added April 5, 2017
711 snprintf(buf, sizeof(buf), "\n CONTROL POINT COORDINATE TYPE FOR REPORTS: %s",
712 SurfacePoint::coordinateTypeToString(m_settings->controlPointCoordTypeReports()).toLatin1().data());
713
714 // Added July 4, 2017
715 snprintf(buf, sizeof(buf), "\n CONTROL POINT COORDINATE TYPE FOR BUNDLE: %s",
716 SurfacePoint::coordinateTypeToString(m_settings->controlPointCoordTypeBundle()).toLatin1().data());
717
718 snprintf(buf, sizeof(buf), "\n\nMAXIMUM LIKELIHOOD ESTIMATION\n============================\n");
719 fpOut << buf;
720
721 for (int tier = 0; tier < 3; tier++) {
722 if (tier < m_statisticsResults->numberMaximumLikelihoodModels()) {
723 snprintf(buf, sizeof(buf), "\n Tier %d Enabled: TRUE", tier);
724 fpOut << buf;
725 snprintf(buf, sizeof(buf), "\n Maximum Likelihood Model: %s",
728 maximumLikelihoodModelWFunc(tier).model()).toLatin1().data());
729 fpOut << buf;
730 snprintf(buf, sizeof(buf), "\n Quantile used for tweaking constant: %lf",
732 fpOut << buf;
733 snprintf(buf, sizeof(buf), "\n Quantile weighted R^2 Residual value: %lf",
735 fpOut << buf;
736 snprintf(buf, sizeof(buf), "\n Approx. weighted Residual cutoff: %s",
738 .weightedResidualCutoff().toLatin1().data());
739 fpOut << buf;
740 if (tier != 2) fpOut << "\n";
741 }
742 else {
743 snprintf(buf, sizeof(buf), "\n Tier %d Enabled: FALSE", tier);
744 fpOut << buf;
745 }
746 }
747
748 snprintf(buf, sizeof(buf), "\n\nINPUT: CONVERGENCE CRITERIA\n===========================\n");
749 fpOut << buf;
750 snprintf(buf, sizeof(buf), "\n SIGMA0: %e",
751 m_settings->convergenceCriteriaThreshold());
752 fpOut << buf;
753 snprintf(buf, sizeof(buf), "\n MAXIMUM ITERATIONS: %d",
754 m_settings->convergenceCriteriaMaximumIterations());
755 fpOut << buf;
756
757 //TODO Should it be checked that positionSigmas.size() == positionSolveDegree and
758 // pointingSigmas.size() == pointingSolveDegree somewhere? JAM
759
760 //TODO How do we output this information when using multiple solve settings? JAM
761
762 BundleObservationSolveSettings globalSettings = m_settings->observationSolveSettings(0);
763 int pointingSolveDegree = globalSettings.numberCameraAngleCoefficientsSolved();
764 QList<double> pointingSigmas = globalSettings.aprioriPointingSigmas();
765 int positionSolveDegree = globalSettings.numberCameraPositionCoefficientsSolved();
766 QList<double> positionSigmas = globalSettings.aprioriPositionSigmas();
767
768 snprintf(buf, sizeof(buf), "\n\nINPUT: CAMERA POINTING OPTIONS\n==============================\n");
769 fpOut << buf;
770 switch (pointingSolveDegree) {
771 case 0:
772 snprintf(buf, sizeof(buf),"\n CAMSOLVE: NONE");
773 break;
774 case 1:
775 snprintf(buf, sizeof(buf),"\n CAMSOLVE: ANGLES");
776 break;
777 case 2:
778 snprintf(buf, sizeof(buf),"\n CAMSOLVE: ANGLES, VELOCITIES");
779 break;
780 case 3:
781 snprintf(buf, sizeof(buf),"\n CAMSOLVE: ANGLES, VELOCITIES, ACCELERATIONS");
782 break;
783 default:
784 snprintf(buf, sizeof(buf),"\n CAMSOLVE: ALL POLYNOMIAL COEFFICIENTS (%d)"
785 "\n CKDEGREE: %d"
786 "\n CKSOLVEDEGREE: %d",
787 pointingSolveDegree,
788 globalSettings.ckDegree(),
789 globalSettings.ckSolveDegree());
790 break;
791 }
792 fpOut << buf;
793 globalSettings.solveTwist() ?
794 snprintf(buf, sizeof(buf), "\n TWIST: ON"):
795 snprintf(buf, sizeof(buf), "\n TWIST: OFF");
796 fpOut << buf;
797 globalSettings.solvePolyOverPointing() ?
798 snprintf(buf, sizeof(buf), "\n POLYNOMIAL OVER EXISTING POINTING: ON"):
799 snprintf(buf, sizeof(buf), "\nPOLYNOMIAL OVER EXISTING POINTING : OFF");
800 fpOut << buf;
801
802 snprintf(buf, sizeof(buf), "\n\nINPUT: SPACECRAFT OPTIONS\n=========================\n");
803 fpOut << buf;
804 switch (positionSolveDegree) {
805 case 0:
806 snprintf(buf, sizeof(buf),"\n SPSOLVE: NONE");
807 break;
808 case 1:
809 snprintf(buf, sizeof(buf),"\n SPSOLVE: POSITION");
810 break;
811 case 2:
812 snprintf(buf, sizeof(buf),"\n SPSOLVE: POSITION, VELOCITIES");
813 break;
814 case 3:
815 snprintf(buf, sizeof(buf),"\n SPSOLVE: POSITION, VELOCITIES, ACCELERATIONS");
816 break;
817 default:
818 snprintf(buf, sizeof(buf),"\n SPSOLVE: ALL POLYNOMIAL COEFFICIENTS (%d)"
819 "\n SPKDEGREE: %d"
820 "\n SPKSOLVEDEGREE: %d",
821 positionSolveDegree,
822 globalSettings.spkDegree(),
823 globalSettings.spkSolveDegree());
824 break;
825 }
826 fpOut << buf;
827 globalSettings.solvePositionOverHermite() ?
828 snprintf(buf, sizeof(buf), "\n POLYNOMIAL OVER HERMITE SPLINE: ON"):
829 snprintf(buf, sizeof(buf), "\nPOLYNOMIAL OVER HERMITE SPLINE : OFF");
830 fpOut << buf;
831
832 snprintf(buf, sizeof(buf), "\n\nINPUT: GLOBAL IMAGE PARAMETER UNCERTAINTIES\n===========================================\n");
833 QString coord1Str;
834 QString coord2Str;
835 QString coord3Str;
836 switch (m_settings->controlPointCoordTypeReports()) {
838 coord1Str = "LATITUDE";
839 coord2Str = "LONGITUDE";
840 coord3Str = "RADIUS";
841 break;
843 coord1Str = " X";
844 coord2Str = " Y";
845 coord3Str = " Z";
846 break;
847 default:
848 IString msg ="Unknown surface point coordinate type enum ["
849 + toString(m_settings->controlPointCoordTypeReports()) + "]." ;
850 throw IException(IException::Programmer, msg, _FILEINFO_);
851 break;
852 }
853
854 // Coordinate 1 (latitude or point X)
855 fpOut << buf;
856 (m_settings->globalPointCoord1AprioriSigma() == Isis::Null) ?
857 snprintf(buf, sizeof(buf),"\n POINT %s SIGMA: N/A", coord1Str.toLatin1().data()):
858 snprintf(buf, sizeof(buf),"\n POINT %s SIGMA: %lf (meters)", coord1Str.toLatin1().data(),
859 m_settings->globalPointCoord1AprioriSigma());
860 // Coordinate 2 (longitude or point Y)
861 fpOut << buf;
862 (m_settings->globalPointCoord2AprioriSigma() == Isis::Null) ?
863 snprintf(buf, sizeof(buf),"\n POINT %s SIGMA: N/A", coord2Str.toLatin1().data()):
864 snprintf(buf, sizeof(buf),"\n POINT %s SIGMA: %lf (meters)", coord2Str.toLatin1().data(),
865 m_settings->globalPointCoord2AprioriSigma());
866 // Coordinate 3 (radius or point Z)
867 fpOut << buf;
868 (m_settings->globalPointCoord3AprioriSigma() == Isis::Null) ?
869 snprintf(buf, sizeof(buf),"\n POINT %s SIGMA: N/A", coord3Str.toLatin1().data()):
870 snprintf(buf, sizeof(buf),"\n POINT %s SIGMA: %lf (meters)", coord3Str.toLatin1().data(),
871 m_settings->globalPointCoord3AprioriSigma());
872 fpOut << buf;
873 (positionSolveDegree < 1 || positionSigmas[0] == Isis::Null) ?
874 snprintf(buf, sizeof(buf),"\n SPACECRAFT POSITION SIGMA: N/A"):
875 snprintf(buf, sizeof(buf),"\n SPACECRAFT POSITION SIGMA: %lf (meters)",
876 positionSigmas[0]);
877 fpOut << buf;
878
879 (positionSolveDegree < 2 || positionSigmas[1] == Isis::Null) ?
880 snprintf(buf, sizeof(buf),"\n SPACECRAFT VELOCITY SIGMA: N/A"):
881 snprintf(buf, sizeof(buf),"\n SPACECRAFT VELOCITY SIGMA: %lf (m/s)",
882 positionSigmas[1]);
883 fpOut << buf;
884
885 (positionSolveDegree < 3 || positionSigmas[2] == Isis::Null) ?
886 snprintf(buf, sizeof(buf),"\n SPACECRAFT ACCELERATION SIGMA: N/A"):
887 snprintf(buf, sizeof(buf),"\n SPACECRAFT ACCELERATION SIGMA: %lf (m/s/s)",
888 positionSigmas[2]);
889 fpOut << buf;
890
891 (pointingSolveDegree < 1 || pointingSigmas[0] == Isis::Null) ?
892 snprintf(buf, sizeof(buf),"\n CAMERA ANGLES SIGMA: N/A"):
893 snprintf(buf, sizeof(buf),"\n CAMERA ANGLES SIGMA: %lf (dd)",
894 pointingSigmas[0]);
895 fpOut << buf;
896
897 (pointingSolveDegree < 2 || pointingSigmas[1] == Isis::Null) ?
898 snprintf(buf, sizeof(buf),"\n CAMERA ANGULAR VELOCITY SIGMA: N/A"):
899 snprintf(buf, sizeof(buf),"\n CAMERA ANGULAR VELOCITY SIGMA: %lf (dd/s)",
900 pointingSigmas[1]);
901 fpOut << buf;
902
903 (pointingSolveDegree < 3 || pointingSigmas[2] == Isis::Null) ?
904 snprintf(buf, sizeof(buf),"\n CAMERA ANGULAR ACCELERATION SIGMA: N/A"):
905 snprintf(buf, sizeof(buf),"\n CAMERA ANGULAR ACCELERATION SIGMA: %lf (dd/s/s)",
906 pointingSigmas[2]);
907 fpOut << buf;
908
909 if (m_settings->solveTargetBody()) {
910 snprintf(buf, sizeof(buf), "\n\nINPUT: TARGET BODY OPTIONS\n==============================\n");
911 fpOut << buf;
912
913 if (m_settings->solvePoleRA() && m_settings->solvePoleDec()) {
914 snprintf(buf, sizeof(buf),"\n POLE: RIGHT ASCENSION");
915 fpOut << buf;
916 snprintf(buf, sizeof(buf),"\n : DECLINATION\n");
917 fpOut << buf;
918 }
919 else if (m_settings->solvePoleRA()) {
920 snprintf(buf, sizeof(buf),"\n POLE: RIGHT ASCENSION\n");
921 fpOut << buf;
922 }
923 else if (m_settings->solvePoleDec()) {
924 snprintf(buf, sizeof(buf),"\n POLE: DECLINATION\n");
925 fpOut << buf;
926 }
927
928 if (m_settings->solvePM() || m_settings->solvePMVelocity()
929 || m_settings->solvePMAcceleration()) {
930 snprintf(buf, sizeof(buf),"\n PRIME MERIDIAN: W0 (OFFSET)");
931 fpOut << buf;
932
933 if (m_settings->solvePMVelocity()) {
934 snprintf(buf, sizeof(buf),"\n : WDOT (SPIN RATE)");
935 fpOut << buf;
936 }
937 if (m_settings->solvePMAcceleration()) {
938 snprintf(buf, sizeof(buf),"\n :W ACCELERATION");
939 fpOut << buf;
940 }
941 }
942
943 if (m_settings->solveTriaxialRadii() || m_settings->solveMeanRadius()) {
944 if (m_settings->solveMeanRadius()) {
945 snprintf(buf, sizeof(buf),"\n RADII: MEAN");
946 fpOut << buf;
947 }
948 else if (m_settings->solveTriaxialRadii()) {
949 snprintf(buf, sizeof(buf),"\n RADII: TRIAXIAL");
950 fpOut << buf;
951 }
952 }
953 }
954
955 snprintf(buf, sizeof(buf), "\n\nJIGSAW: RESULTS\n===============\n");
956 fpOut << buf;
957 snprintf(buf, sizeof(buf), "\n Images: %6d",numImages);
958 fpOut << buf;
959 snprintf(buf, sizeof(buf), "\n Points: %6d",numValidPoints);
960 fpOut << buf;
961
962 if (numValidLidarPoints > 0) {
963 snprintf(buf, sizeof(buf), "\n Lidar Points: %6d",numValidLidarPoints);
964 fpOut << buf;
965 }
966
967 snprintf(buf, sizeof(buf), "\n Total Measures: %6d",
970 fpOut << buf;
971
972 snprintf(buf, sizeof(buf), "\n Total Observations: %6d",
975 fpOut << buf;
976
977 snprintf(buf, sizeof(buf), "\n Good Observations: %6d",
979 fpOut << buf;
980
981 snprintf(buf, sizeof(buf), "\n Rejected Observations: %6d",
983 fpOut << buf;
984
986 snprintf(buf, sizeof(buf), "\n Constrained Point Parameters: %6d",
988 fpOut << buf;
989 }
990
992 snprintf(buf, sizeof(buf), "\n Constrained Image Parameters: %6d",
994 fpOut << buf;
995 }
996
998 snprintf(buf, sizeof(buf), "\n Constrained Target Parameters: %6d",
1000 fpOut << buf;
1001 }
1002
1004 snprintf(buf, sizeof(buf), "\n Lidar Range Constraints: %6d",
1006 fpOut << buf;
1007 }
1008
1009 snprintf(buf, sizeof(buf), "\n Unknowns: %6d",
1011 fpOut << buf;
1012
1013 if (numInnerConstraints > 0) {
1014 snprintf(buf, sizeof(buf), "\n Inner Constraints: %6d", numInnerConstraints);
1015 fpOut << buf;
1016 }
1017
1018 if (numDistanceConstraints > 0) {
1019 snprintf(buf, sizeof(buf), "\n Distance Constraints: %d", numDistanceConstraints);
1020 fpOut << buf;
1021 }
1022
1023 snprintf(buf, sizeof(buf), "\n Degrees of Freedom: %6d", numDegreesOfFreedom);
1024 fpOut << buf;
1025
1026 snprintf(buf, sizeof(buf), "\n Convergence Criteria: %6.3g",
1027 m_settings->convergenceCriteriaThreshold());
1028 fpOut << buf;
1029
1030 if (convergenceCriteria == 1) {
1031 snprintf(buf, sizeof(buf), "(Sigma0)");
1032 fpOut << buf;
1033 }
1034
1035 snprintf(buf, sizeof(buf), "\n Iterations: %6d", m_statisticsResults->iterations());
1036 fpOut << buf;
1037
1038 if (m_statisticsResults->iterations() >= m_settings->convergenceCriteriaMaximumIterations()) {
1039 snprintf(buf, sizeof(buf), "(Maximum reached)");
1040 fpOut << buf;
1041 }
1042
1043 snprintf(buf, sizeof(buf), "\n Sigma0: %30.20lf\n", m_statisticsResults->sigma0());
1044 fpOut << buf;
1045 snprintf(buf, sizeof(buf), " Error Propagation Elapsed Time: %6.4lf (seconds)\n",
1047 fpOut << buf;
1048 snprintf(buf, sizeof(buf), " Total Elapsed Time: %6.4lf (seconds)\n",
1050 fpOut << buf;
1053 > 100) {
1054 snprintf(buf, sizeof(buf), "\n Residual Percentiles:\n");
1055 fpOut << buf;
1056
1057 // residual prob distribution values are calculated/printed
1058 // even if there is no maximum likelihood estimation
1059 try {
1060 for (int bin = 1;bin < 34;bin++) {
1061 double cumProb = double(bin) / 100.0;
1062 double resValue =
1064 residualsCumulativeProbabilityDistribution().value(cumProb);
1065 double resValue33 =
1067 residualsCumulativeProbabilityDistribution().value(cumProb + 0.33);
1068 double resValue66 =
1070 residualsCumulativeProbabilityDistribution().value(cumProb + 0.66);
1071 snprintf(buf, sizeof(buf), " Percentile %3d: %+8.3lf"
1072 " Percentile %3d: %+8.3lf"
1073 " Percentile %3d: %+8.3lf\n",
1074 bin, resValue,
1075 bin + 33, resValue33,
1076 bin + 66, resValue66);
1077 fpOut << buf;
1078 }
1079 }
1080 catch (IException &e) {
1081 QString msg = "Failed to output residual percentiles for bundleout";
1082 throw IException(e, IException::Io, msg, _FILEINFO_);
1083 }
1084 try {
1085 snprintf(buf, sizeof(buf), "\n Residual Box Plot:");
1086 fpOut << buf;
1087 snprintf(buf, sizeof(buf), "\n minimum: %+8.3lf",
1089 fpOut << buf;
1090 snprintf(buf, sizeof(buf), "\n Quartile 1: %+8.3lf",
1092 fpOut << buf;
1093 snprintf(buf, sizeof(buf), "\n Median: %+8.3lf",
1095 fpOut << buf;
1096 snprintf(buf, sizeof(buf), "\n Quartile 3: %+8.3lf",
1098 fpOut << buf;
1099 snprintf(buf, sizeof(buf), "\n maximum: %+8.3lf\n",
1101 fpOut << buf;
1102 }
1103 catch (IException &e) {
1104 QString msg = "Failed to output residual box plot for bundleout";
1105 throw IException(e, IException::Io, msg, _FILEINFO_);
1106 }
1107 }
1108
1109 // Loop over the observations to find the longest file path/name in the
1110 // bunch
1111 int filePadding = 0;
1112
1113 for (int i = 0; i < numObservations; i++) {
1114
1115 int numImagesInObservation = m_statisticsResults->observations().at(i)->size();
1116
1117 for (int j = 0; j < numImagesInObservation; j++) {
1118 BundleImageQsp bundleImage = m_statisticsResults->observations().at(i)->at(j);
1119
1120 if (bundleImage->fileName().length() > filePadding) {
1121 filePadding = bundleImage->fileName().length();
1122 }
1123 }
1124 }
1125
1126 snprintf(buf, sizeof(buf), "\nIMAGE MEASURES SUMMARY\n==========================\n\n");
1127 fpOut << buf;
1128
1129 // Pad each element in the table with the space for the longest image
1130 // path/name then padd it the length of the element + 1
1131 QString header("Measures RMS(pixels)");
1133 header += " Lidar RMS(pixels)";
1134 }
1135 // This is padded by an extra 11 to move it center to the table
1136 snprintf(buf, sizeof(buf),"%*s\n", header.length() + 11 + filePadding, header.toLatin1().data());
1137 fpOut << buf;
1138
1139 QString dividers("*************************** *******************************************");
1141 dividers += " *******************************************";
1142 }
1143 snprintf(buf, sizeof(buf),"%*s\n", dividers.length() + 1 + filePadding, dividers.toLatin1().data());
1144 fpOut << buf;
1145
1146 QString fields("| Accepted | Total | | Samples | Lines | Total |");
1148 fields += " | Samples | Lines | Total |";
1149 }
1150 snprintf(buf, sizeof(buf),"%*s\n", fields.length() + 1 + filePadding, fields.toLatin1().data());
1151 fpOut << buf;
1152
1153 int numMeasures, numLidarMeasures;
1154 int numRejectedMeasures, numLidarRejectedMeasures;
1155 int numUsed, numLidarUsed;
1156 int imageIndex = 0;
1157 Statistics rmsSamplesTotal,rmsLinesTotal,rmsTotals;
1158
1159 for (int i = 0; i < numObservations; i++) {
1160
1161 int numImagesInObservation = m_statisticsResults->observations().at(i)->size();
1162
1163 for (int j = 0; j < numImagesInObservation; j++) {
1164
1165 BundleImageQsp bundleImage = m_statisticsResults->observations().at(i)->at(j);
1166
1167 double rmsSampleResiduals = m_statisticsResults->
1168 rmsImageSampleResiduals()[imageIndex].Rms();
1169 double rmsLineResiduals = m_statisticsResults->
1170 rmsImageLineResiduals()[imageIndex].Rms();
1171 double rmsLandSResiduals = m_statisticsResults->
1172 rmsImageResiduals()[imageIndex].Rms();
1173 rmsSamplesTotal.AddData(rmsSampleResiduals);
1174 rmsLinesTotal.AddData(rmsLineResiduals);
1175 rmsTotals.AddData(rmsLandSResiduals);
1176
1177 numMeasures = m_statisticsResults->outputControlNet()->GetNumberOfValidMeasuresInImage
1178 (bundleImage->serialNumber());
1179
1180 numRejectedMeasures = m_statisticsResults->outputControlNet()->
1181 GetNumberOfJigsawRejectedMeasuresInImage(bundleImage->serialNumber());
1182
1183 numUsed = numMeasures - numRejectedMeasures;
1184
1185 QString filename = bundleImage->fileName();
1186 QStringList List;
1187 List = filename.split("/");
1188
1189 snprintf(buf, sizeof(buf),"%-*s" ,filePadding + 1, bundleImage->fileName().toLatin1().data());
1190 fpOut << buf;
1191
1192 snprintf(buf, sizeof(buf), " %12d %12d ", numUsed, numMeasures);
1193 fpOut << buf;
1194
1195 snprintf(buf, sizeof(buf),"%13.4lf %13.4lf %13.4lf",
1196 rmsSampleResiduals,rmsLineResiduals,rmsLandSResiduals);
1197
1198 fpOut << buf;
1199
1201 double rmsLidarSampleResiduals = m_statisticsResults->
1202 rmsLidarImageSampleResiduals()[imageIndex].Rms();
1203 double rmsLidarLineResiduals = m_statisticsResults->
1204 rmsLidarImageLineResiduals()[imageIndex].Rms();
1205 double rmsLidarLandSResiduals = m_statisticsResults->
1206 rmsLidarImageResiduals()[imageIndex].Rms();
1207
1208 numLidarMeasures = m_statisticsResults->outputLidarData()->
1209 GetNumberOfValidMeasuresInImage(bundleImage->serialNumber());
1210
1211 numLidarRejectedMeasures = m_statisticsResults->outputLidarData()->
1212 GetNumberOfJigsawRejectedMeasuresInImage(bundleImage->serialNumber());
1213
1214 numLidarUsed = numLidarMeasures - numLidarRejectedMeasures;
1215
1216 snprintf(buf, sizeof(buf), " %12d %12d ", numLidarUsed, numLidarMeasures);
1217 fpOut << buf;
1218
1219 snprintf(buf, sizeof(buf),"%13.4lf %13.4lf %13.4lf",
1220 rmsLidarSampleResiduals,rmsLidarLineResiduals,rmsLidarLandSResiduals);
1221
1222 fpOut << buf;
1223 }
1224
1225 snprintf(buf, sizeof(buf), " \n");
1226 fpOut << buf;
1227 imageIndex++;
1228 }
1229 }
1230
1231 // Do something similar to above but left justify the string and add a 33
1232 // character buffer
1233 snprintf(buf, sizeof(buf),"%*s", -(filePadding + 33), "\nTotal RMS:");
1234 fpOut << buf;
1235 snprintf(buf, sizeof(buf),"%13.4lf %13.4lf %13.4lf\n",
1236 rmsSamplesTotal.Rms(),rmsLinesTotal.Rms(),rmsTotals.Rms());
1237 fpOut << buf;
1238
1239 return true;
1240 }
1241
1242
1255
1256 char buf[1056];
1257
1258 QList<Statistics> rmsImageSampleResiduals = m_statisticsResults->rmsImageSampleResiduals();
1259 QList<Statistics> rmsImageLineResiduals = m_statisticsResults->rmsImageLineResiduals();
1260 QList<Statistics> rmsImageResiduals = m_statisticsResults->rmsImageResiduals();
1261
1262 bool errorProp = false;
1263 if (m_statisticsResults->converged() && m_settings->errorPropagation()) {
1264 errorProp = true;
1265 }
1266
1267 QList<QString> outputCsvFileNames;
1268 QList<QString> instrumentIds = m_statisticsResults->observations().instrumentIds();
1269 // If there's just a single instrumentId just call it bundleout_images.csv
1270 if (instrumentIds.size() == 1) {
1271 QString ofname = "bundleout_images.csv";
1272 ofname = m_settings->outputFilePrefix() + ofname;
1273 m_csvSavedImagesFilename = ofname;
1274 outputCsvFileNames.push_back(ofname);
1275 }
1276 // Otherwise append the instrument IDs so it's bundleout_images_spacecraft_sensor.csv
1277 else {
1278 for (int i = 0; i < instrumentIds.size(); i++) {
1279 QString updatedInstrumentId = instrumentIds[i];
1280 // Replace and "/" or " " characters with "_" to make the filename safer
1281 // This line must be separate to avoid modifying the instrumentId in the list
1282 // we will iterate over later
1283 updatedInstrumentId.replace("/", "_").replace(" ", "_");
1284 QString ofname = "bundleout_images_" + updatedInstrumentId + ".csv";
1285 ofname = m_settings->outputFilePrefix() + ofname;
1286 m_csvSavedImagesFilename = ofname;
1287 outputCsvFileNames.push_back(ofname);
1288 }
1289 }
1290
1291 for (int i = 0; i < instrumentIds.size(); i++) {
1292
1293 std::ofstream fpOut(outputCsvFileNames[i].toLatin1().data(), std::ios::out);
1294 if (!fpOut) {
1295 return false;
1296 }
1297
1298 QList<BundleObservationQsp> observations =
1299 m_statisticsResults->observations().observationsByInstId(instrumentIds[i]);
1300
1301 int nObservations = observations.size();
1302
1303 outputImagesCSVHeader(fpOut, observations.front());
1304
1305 for (int j = 0; j < nObservations; j++ ) {
1306 BundleObservationQsp observation = observations[j];
1307
1308 // We need the image index, not the observation index,
1309 // so count all of the images prior to this observation
1310 int observationIndex = observation->index();
1311 int imgIndex = 0;
1312 for (int obsIndex = 0; obsIndex < observationIndex; obsIndex++) {
1313 imgIndex += m_statisticsResults->observations().at(obsIndex)->size();
1314 }
1315
1316 if(!observation) {
1317 continue;
1318 }
1319
1320 int numImages = observation->size();
1321
1322 for (int k = 0; k < numImages; k++) {
1323 BundleImageQsp image = observation->at(k);
1324
1325 snprintf(buf, sizeof(buf), "%s", image->fileName().toLatin1().data());
1326 fpOut << buf;
1327 snprintf(buf, sizeof(buf),",");
1328 fpOut << buf;
1329
1330 fpOut << toString(rmsImageSampleResiduals[imgIndex].Rms()).toLatin1().data();
1331 snprintf(buf, sizeof(buf),",");
1332 fpOut << buf;
1333
1334 fpOut << toString(rmsImageLineResiduals[imgIndex].Rms()).toLatin1().data();
1335 snprintf(buf, sizeof(buf),",");
1336 fpOut << buf;
1337
1338 fpOut << toString(rmsImageResiduals[imgIndex].Rms()).toLatin1().data();
1339 snprintf(buf, sizeof(buf),",");
1340 fpOut << buf;
1341
1342 QString observationString =
1343 observation->bundleOutputCSV(errorProp);
1344
1345 //Removes trailing commas
1346 if (observationString.right(1)==",") {
1347 observationString.truncate(observationString.length()-1);
1348 }
1349
1350 fpOut << (const char*) observationString.toLatin1().data();
1351
1352 snprintf(buf, sizeof(buf),"\n");
1353 fpOut << buf;
1354 imgIndex++;
1355
1356 }
1357 }
1358 fpOut.close();
1359 }
1360
1361 return true;
1362 }
1363
1364
1371
1372 QString ofname = "bundleout.txt";
1373 ofname = m_settings->outputFilePrefix() + ofname;
1374
1375 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1376 if (!fpOut) {
1377 return false;
1378 }
1379
1380 m_txtBundleOutputFilename = ofname;
1381
1382 char buf[4096];
1383 BundleObservationQsp observation;
1384
1385 int nObservations = m_statisticsResults->observations().size();
1386
1387 outputHeader(fpOut);
1388
1389 bool berrorProp = false;
1390 if (m_statisticsResults->converged() && m_settings->errorPropagation()) {
1391 berrorProp = true;
1392 }
1393
1394 // output target body header if solving for target
1395 if (m_settings->solveTargetBody()) {
1396 snprintf(buf, sizeof(buf), "\nTARGET BODY\n==========================\n");
1397 fpOut << buf;
1398
1399 snprintf(buf, sizeof(buf), "\n Target Initial Total "
1400 "Final Initial Final\n"
1401 "Parameter Value Correction "
1402 "Value Accuracy Accuracy\n");
1403 fpOut << buf;
1404
1405 QString targetString =
1406 m_settings->bundleTargetBody()->formatBundleOutputString(berrorProp);
1407 fpOut << (const char*)targetString.toLatin1().data();
1408 }
1409
1410 // output image exterior orientation header
1411 snprintf(buf, sizeof(buf), "\nIMAGE EXTERIOR ORIENTATION\n==========================\n");
1412 fpOut << buf;
1413
1414 QMap<QString, QStringList> imagesAndParameters;
1415
1416 if (m_settings->solveTargetBody()) {
1417 imagesAndParameters.insert( "target", m_settings->bundleTargetBody()->parameterList() );
1418 }
1419
1420 for (int i = 0; i < nObservations; i++) {
1421
1422 observation = m_statisticsResults->observations().at(i);
1423 if (!observation) {
1424 continue;
1425 }
1426
1427 int numImages = observation->size();
1428 for (int j = 0; j < numImages; j++) {
1429 BundleImageQsp image = observation->at(j);
1430 snprintf(buf, sizeof(buf), "\nImage Full File Name: %s\n", image->fileName().toLatin1().data());
1431 fpOut << buf;
1432 snprintf(buf, sizeof(buf), "\nImage Serial Number: %s\n", image->serialNumber().toLatin1().data());
1433 fpOut << buf;
1434
1435 snprintf(buf, sizeof(buf),"Image Initial Total Final Accuracy\n");
1436 fpOut << buf;
1437 snprintf(buf, sizeof(buf),"Parameter Value Correction Value Initial Final Units\n");
1438 fpOut << buf;
1439
1440 snprintf(buf, sizeof(buf)," "
1441 "***************************************\n");
1442 fpOut << buf;
1443
1444 observation->bundleOutputString(fpOut,berrorProp);
1445 // Build list of images and parameters for correlation matrix.
1446 foreach ( QString image, observation->imageNames() ) {
1447 imagesAndParameters.insert( image, observation->parameterList() );
1448 }
1449 }
1450 }
1451
1452 // Save list of images and their associated parameters for CorrelationMatrix to use in ice.
1453 m_statisticsResults->setCorrMatImgsAndParams(imagesAndParameters);
1454
1455 // Save list of images and their associated parameters for CorrelationMatrix to use in ice.
1456 m_statisticsResults->setCorrMatImgsAndParams(imagesAndParameters);
1457
1458 // output point uncertainty statistics if error propagation is on
1459 if (berrorProp) {
1460 snprintf(buf, sizeof(buf), "\n\n\nPOINTS UNCERTAINTY SUMMARY\n==========================\n\n");
1461 fpOut << buf;
1462
1463 // Coordinate 1 (latitude or point x) summary
1464 QString
1465 coordName = surfacePointCoordName(m_settings->controlPointCoordTypeReports(),
1466 SurfacePoint::One);
1467 snprintf(buf, sizeof(buf), "RMS Sigma %s(m)%20.8lf\n", coordName.toLatin1().data(),
1469 fpOut << buf;
1470 snprintf(buf, sizeof(buf), "MIN Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1472 m_statisticsResults->minSigmaCoord1PointId().toLatin1().data());
1473 fpOut << buf;
1474 snprintf(buf, sizeof(buf), "MAX Sigma %s(m)%20.8lf at %s\n\n", coordName.toLatin1().data(),
1476 m_statisticsResults->maxSigmaCoord1PointId().toLatin1().data());
1477 fpOut << buf;
1478
1479 // Coordinate 2 (longitude or point y) summary
1480 coordName = surfacePointCoordName(m_settings->controlPointCoordTypeReports(),
1481 SurfacePoint::Two);
1482 snprintf(buf, sizeof(buf), "RMS Sigma %s(m)%20.8lf\n", coordName.toLatin1().data(),
1484 fpOut << buf;
1485 snprintf(buf, sizeof(buf), "MIN Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1487 m_statisticsResults->minSigmaCoord2PointId().toLatin1().data());
1488 fpOut << buf;
1489 snprintf(buf, sizeof(buf), "MAX Sigma %s(m)%20.8lf at %s\n\n", coordName.toLatin1().data(),
1491 m_statisticsResults->maxSigmaCoord2PointId().toLatin1().data());
1492 fpOut << buf;
1493
1494 // Coordinate 3 (radius or point z) summary
1495 coordName = surfacePointCoordName(m_settings->controlPointCoordTypeReports(),
1496 SurfacePoint::Three);
1497 if ( m_settings->solveRadius() ) {
1498 snprintf(buf, sizeof(buf), "RMS Sigma %s(m)%20.8lf\n", coordName.toLatin1().data(),
1500 fpOut << buf;
1501 snprintf(buf, sizeof(buf), "MIN Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1503 m_statisticsResults->minSigmaCoord3PointId().toLatin1().data());
1504 fpOut << buf;
1505 snprintf(buf, sizeof(buf), "MAX Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1507 m_statisticsResults->maxSigmaCoord3PointId().toLatin1().data());
1508 fpOut << buf;
1509 }
1510 else {
1511 snprintf(buf, sizeof(buf), " RMS Sigma Radius(m) N/A\n");
1512 fpOut << buf;
1513 snprintf(buf, sizeof(buf), " MIN Sigma Radius(m) N/A\n");
1514 fpOut << buf;
1515 snprintf(buf, sizeof(buf), " MAX Sigma Radius(m) N/A\n");
1516 fpOut << buf;
1517 }
1518 }
1519
1520 // output point summary data header
1521 if (m_settings->controlPointCoordTypeReports() == SurfacePoint::Latitudinal) {
1522 snprintf(buf, sizeof(buf), "\n\nPOINTS SUMMARY\n==============\n%103s"
1523 "Sigma Sigma Sigma\n"
1524 " Label Status Rays RMS"
1525 " Latitude Longitude Radius"
1526 " Latitude Longitude Radius\n", "");
1527 }
1528 else { // Must be Rectangular
1529 snprintf(buf, sizeof(buf), "\n\nPOINTS SUMMARY\n==============\n%103s"
1530 "Sigma Sigma Sigma\n"
1531 " Label Status Rays RMS"
1532 " Point X Point Y Point Z"
1533 " Point X Point Y Point Z\n", "");
1534 }
1535 fpOut << buf;
1536
1537 int nPoints = m_statisticsResults->bundleControlPoints().size();
1538 for (int i = 0; i < nPoints; i++) {
1540
1541 QString pointSummaryString =
1542 bundleControlPoint->formatBundleOutputSummaryString(berrorProp);
1543 fpOut << (const char*)pointSummaryString.toLatin1().data();
1544 }
1545
1546 int nLidarPoints = m_statisticsResults->bundleLidarControlPoints().size();
1547 for (int i = 0; i < nLidarPoints; i++) {
1548 BundleLidarControlPointQsp lidarControlPoint
1550
1551 QString pointSummaryString =
1552 lidarControlPoint->formatBundleOutputSummaryString(berrorProp);
1553 fpOut << (const char*)pointSummaryString.toLatin1().data();
1554 }
1555
1556 // output point detail data header
1557 snprintf(buf, sizeof(buf), "\n\nPOINTS DETAIL\n=============\n\n");
1558 fpOut << buf;
1559
1560 bool solveRadius = m_settings->solveRadius();
1561
1562 for (int i = 0; i < nPoints; i++) {
1564
1565 // Removed radiansToMeters argument 9/18/2018 DAC
1566 QString pointDetailString =
1567 bundleControlPoint->formatBundleOutputDetailString(berrorProp, solveRadius);
1568 fpOut << (const char*)pointDetailString.toLatin1().data();
1569 }
1570
1571 for (int i = 0; i < nLidarPoints; i++) {
1572 BundleLidarControlPointQsp bundleLidarControlPoint =
1574
1575 QString pointDetailString =
1576 bundleLidarControlPoint->formatBundleOutputDetailString(berrorProp, solveRadius);
1577 fpOut << (const char*)pointDetailString.toLatin1().data();
1578 }
1579
1580 fpOut.close();
1581
1582 return true;
1583 }
1584
1585
1592 char buf[1056];
1593
1594 QString ofname = "bundleout_points.csv";
1595 ofname = m_settings->outputFilePrefix() + ofname;
1596 m_csvSavedPointsFilename = ofname;
1597
1598 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1599 if (!fpOut) {
1600 return false;
1601 }
1602
1603 int numPoints = m_statisticsResults->bundleControlPoints().size();
1604
1605 double dLat, dLon, dRadius;
1606 double dX, dY, dZ;
1607 double dSigmaLat, dSigmaLong, dSigmaRadius;
1608 QString strStatus;
1609 double cor_lat_m;
1610 double cor_lon_m;
1611 double cor_rad_m;
1612 int numMeasures, numRejectedMeasures;
1613 double dResidualRms;
1614
1615 // print column headers
1616 if (m_settings->errorPropagation()) {
1617 snprintf(buf, sizeof(buf), ",,,,,3-d,3-d,3-d,Sigma,Sigma,Sigma,Correction,Correction,Correction,Coordinate,"
1618 "Coordinate,Coordinate\nPoint,Point,Accepted,Rejected,Residual,Latitude,Longitude,"
1619 "Radius,Latitude,Longitude,Radius,Latitude,Longitude,Radius,X,Y,Z\nLabel,Status,"
1620 "Measures,Measures,RMS,(dd),(dd),(km),(m),(m),(m),(m),(m),(m),(km),(km),(km)\n");
1621 }
1622 else {
1623 snprintf(buf, sizeof(buf), ",,,,,3-d,3-d,3-d,Correction,Correction,Correction,Coordinate,Coordinate,"
1624 "Coordinate\nPoint,Point,Accepted,Rejected,Residual,Latitude,Longitude,Radius,"
1625 "Latitude,Longitude,Radius,X,Y,Z\nLabel,Status,Measures,Measures,RMS,(dd),(dd),(km),"
1626 "(m),(m),(m),(km),(km),(km)\n");
1627 }
1628 fpOut << buf;
1629
1630 for (int i = 0; i < numPoints; i++) {
1632
1633 if (!bundlecontrolpoint) {
1634 continue;
1635 }
1636
1637 if (bundlecontrolpoint->isRejected()) {
1638 continue;
1639 }
1640
1641 dLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatitude().degrees();
1642 dLon = bundlecontrolpoint->adjustedSurfacePoint().GetLongitude().degrees();
1643 dRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadius().kilometers();
1644 dX = bundlecontrolpoint->adjustedSurfacePoint().GetX().kilometers();
1645 dY = bundlecontrolpoint->adjustedSurfacePoint().GetY().kilometers();
1646 dZ = bundlecontrolpoint->adjustedSurfacePoint().GetZ().kilometers();
1647 numMeasures = bundlecontrolpoint->numberOfMeasures();
1648 numRejectedMeasures = bundlecontrolpoint->numberOfRejectedMeasures();
1649 dResidualRms = bundlecontrolpoint->residualRms();
1650
1651 // point corrections and initial sigmas
1652 boost::numeric::ublas::bounded_vector< double, 3 > corrections = bundlecontrolpoint->
1653 corrections();
1654 // Now use the local radius to convert radians to meters instead of the target body equatorial radius
1655 cor_lat_m = bundlecontrolpoint->adjustedSurfacePoint().LatitudeToMeters(corrections[0]);
1656 cor_lon_m = bundlecontrolpoint->adjustedSurfacePoint().LongitudeToMeters(corrections[1]);
1657 cor_rad_m = corrections[2]*1000.0;
1658
1659 if (bundlecontrolpoint->type() == ControlPoint::Fixed) {
1660 strStatus = "FIXED";
1661 }
1662 else if (bundlecontrolpoint->type() == ControlPoint::Constrained) {
1663 strStatus = "CONSTRAINED";
1664 }
1665 else if (bundlecontrolpoint->type() == ControlPoint::Free) {
1666 strStatus = "FREE";
1667 }
1668 else {
1669 strStatus = "UNKNOWN";
1670 }
1671
1672 if (m_settings->errorPropagation()) {
1673 dSigmaLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatSigmaDistance().meters();
1674 dSigmaLong = bundlecontrolpoint->adjustedSurfacePoint().GetLonSigmaDistance().meters();
1675 dSigmaRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadiusSigma().meters();
1676
1677 snprintf(buf, sizeof(buf), "%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
1678 "%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf\n",
1679 bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
1680 numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, dSigmaLat,
1681 dSigmaLong, dSigmaRadius, cor_lat_m, cor_lon_m, cor_rad_m, dX, dY, dZ);
1682 }
1683 else
1684 snprintf(buf, sizeof(buf), "%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
1685 "%16.8lf,%16.8lf\n",
1686 bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
1687 numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, cor_lat_m,
1688 cor_lon_m, cor_rad_m, dX, dY, dZ);
1689
1690 fpOut << buf;
1691 }
1692
1693 fpOut.close();
1694
1695 return true;
1696 }
1697
1698
1705 char buf[1056];
1706
1707 QString ofname = "bundleout_lidar.csv";
1708 ofname = m_settings->outputFilePrefix() + ofname;
1709 m_csvSavedPointsFilename = ofname;
1710
1711 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1712 if (!fpOut) {
1713 return false;
1714 }
1715
1716 int numPoints = m_statisticsResults->bundleLidarControlPoints().size();
1717
1718 // measured apriori adjusted adjusted
1719 // range sigma range residual sigma
1720 // point id image (km) (km) (km) (km) (km)
1721
1722 // print column headers
1723 if (m_settings->errorPropagation()) {
1724 snprintf(buf, sizeof(buf), ",,measured,a priori,adjusted,adjusted\n"
1725 "point,image,range,sigma,range,sigma,residual\n"
1726 "id,name,(km),(km),(km),(km),(km)\n");
1727 }
1728 else {
1729 snprintf(buf, sizeof(buf), ",,measured,a priori,adjusted\n"
1730 "point,image,range,sigma,range,residual\n"
1731 "id,name,(km),(km),(km),(km)\n");
1732 }
1733 fpOut << buf;
1734
1735 for (int i = 0; i < numPoints; i++) {
1736
1738 if (!point || point->isRejected()) {
1739 continue;
1740 }
1741
1742 int nRangeConstraints = point->numberRangeConstraints();
1743 for (int j = 0; j < nRangeConstraints; j++) {
1744 BundleLidarRangeConstraintQsp rangeConstraint = point->rangeConstraint(j);
1745
1746 QString str = rangeConstraint->formatBundleOutputString(m_settings->errorPropagation());
1747 fpOut << str;
1748 }
1749 }
1750
1751 fpOut.close();
1752
1753 return true;
1754 }
1755
1756
1763 char buf[1056];
1764
1765 QString ofname = "residuals.csv";
1766 ofname = m_settings->outputFilePrefix() + ofname;
1767 m_csvSavedResidualsFilename = ofname;
1768
1769 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1770 if (!fpOut) {
1771 return false;
1772 }
1773
1774 // output column headers
1775
1776 snprintf(buf, sizeof(buf), ",,,x image,y image,Measured,Measured,sample,line,Residual Vector\n");
1777 fpOut << buf;
1778 snprintf(buf, sizeof(buf), "Point,Image,Image,coordinate,coordinate,"
1779 "Sample,Line,residual,residual,Magnitude\n");
1780 fpOut << buf;
1781 snprintf(buf, sizeof(buf), "Label,Filename,Serial Number,(mm),(mm),"
1782 "(pixels),(pixels),(pixels),(pixels),(pixels),Rejected\n");
1783 fpOut << buf;
1784
1785 // Setup counts and pointers
1786
1787 int numPoints = m_statisticsResults->bundleControlPoints().size();
1788 int numMeasures = 0;
1789
1790 BundleControlPointQsp bundleControlPoint;
1791 BundleMeasureQsp bundleMeasure;
1792
1793 for (int i = 0; i < numPoints; i++) {
1794 bundleControlPoint = m_statisticsResults->bundleControlPoints().at(i);
1795 numMeasures = bundleControlPoint->size();
1796
1797 if (bundleControlPoint->rawControlPoint()->IsIgnored()) {
1798 continue;
1799 }
1800
1801 for (int j = 0; j < numMeasures; j++) {
1802 bundleMeasure = bundleControlPoint->at(j);
1803
1804 Camera *measureCamera = bundleMeasure->camera();
1805 if (!measureCamera) {
1806 continue;
1807 }
1808
1809 if (bundleMeasure->isRejected()) {
1810 snprintf(buf, sizeof(buf), "%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,*\n",
1811 bundleControlPoint->id().toLatin1().data(),
1812 bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1813 bundleMeasure->cubeSerialNumber().toLatin1().data(),
1814 bundleMeasure->focalPlaneMeasuredX(),
1815 bundleMeasure->focalPlaneMeasuredY(),
1816 bundleMeasure->sample(),
1817 bundleMeasure->line(),
1818 bundleMeasure->sampleResidual(),
1819 bundleMeasure->lineResidual(),
1820 bundleMeasure->residualMagnitude());
1821 }
1822 else {
1823 snprintf(buf, sizeof(buf), "%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf\n",
1824 bundleControlPoint->id().toLatin1().data(),
1825 bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1826 bundleMeasure->cubeSerialNumber().toLatin1().data(),
1827 bundleMeasure->focalPlaneMeasuredX(),
1828 bundleMeasure->focalPlaneMeasuredY(),
1829 bundleMeasure->sample(),
1830 bundleMeasure->line(),
1831 bundleMeasure->sampleResidual(),
1832 bundleMeasure->lineResidual(),
1833 bundleMeasure->residualMagnitude());
1834 }
1835 fpOut << buf;
1836 }
1837 }
1838
1839 numPoints = m_statisticsResults->bundleLidarControlPoints().size();
1840 numMeasures = 0;
1841
1842 BundleLidarControlPointQsp bundleLidarPoint;
1843
1844 for (int i = 0; i < numPoints; i++) {
1845 bundleLidarPoint = m_statisticsResults->bundleLidarControlPoints().at(i);
1846 numMeasures = bundleLidarPoint->size();
1847
1848 if (bundleLidarPoint->rawControlPoint()->IsIgnored()) {
1849 continue;
1850 }
1851
1852 for (int j = 0; j < numMeasures; j++) {
1853 bundleMeasure = bundleLidarPoint->at(j);
1854
1855 Camera *measureCamera = bundleMeasure->camera();
1856 if (!measureCamera) {
1857 continue;
1858 }
1859
1860 if (bundleMeasure->isRejected()) {
1861 snprintf(buf, sizeof(buf), "%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,*\n",
1862 bundleLidarPoint->id().toLatin1().data(),
1863 bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1864 bundleMeasure->cubeSerialNumber().toLatin1().data(),
1865 bundleMeasure->focalPlaneMeasuredX(),
1866 bundleMeasure->focalPlaneMeasuredY(),
1867 bundleMeasure->sample(),
1868 bundleMeasure->line(),
1869 bundleMeasure->sampleResidual(),
1870 bundleMeasure->lineResidual(),
1871 bundleMeasure->residualMagnitude());
1872 }
1873 else {
1874 snprintf(buf, sizeof(buf), "%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf\n",
1875 bundleLidarPoint->id().toLatin1().data(),
1876 bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1877 bundleMeasure->cubeSerialNumber().toLatin1().data(),
1878 bundleMeasure->focalPlaneMeasuredX(),
1879 bundleMeasure->focalPlaneMeasuredY(),
1880 bundleMeasure->sample(),
1881 bundleMeasure->line(),
1882 bundleMeasure->sampleResidual(),
1883 bundleMeasure->lineResidual(),
1884 bundleMeasure->residualMagnitude());
1885 }
1886 fpOut << buf;
1887 }
1888 }
1889
1890 fpOut.close();
1891
1892 return true;
1893 }
1894
1895
1912 void BundleSolutionInfo::save(QXmlStreamWriter &stream, const Project *project,
1913 FileName newProjectRoot) const {
1914
1915 // This is done for testing serialization without a Project
1916 QString relativePath;
1917 QString relativeBundlePath;
1918 FileName bundleSolutionInfoRoot;
1919
1920 if (project) {
1921 bundleSolutionInfoRoot = FileName(Project::bundleSolutionInfoRoot(newProjectRoot.expanded()) +
1922 "/" + runTime());
1923 QString oldPath = project->bundleSolutionInfoRoot(project->projectRoot()) + "/" + runTime();
1924 QString newPath = project->bundleSolutionInfoRoot(newProjectRoot.toString()) + "/" + runTime();
1925 // If project is being saved to new area, create directory and copy files
1926 if (oldPath != newPath) {
1927 // Create project folder for BundleSolutionInfo
1928 QDir bundleDir(newPath);
1929 if (!bundleDir.mkpath(bundleDir.path())) {
1931 QString("Failed to create directory [%1]")
1932 .arg(bundleSolutionInfoRoot.path()),
1933 _FILEINFO_);
1934 }
1935 QString oldFile = oldPath + "/" + FileName(m_outputControl->fileName()).name();
1936 QString newFile = newPath + "/" + FileName(m_outputControl->fileName()).name();
1937 if (!QFile::copy(oldFile, newFile)) {
1939 QString("Failed to copy file [%1] to new file [%2]")
1940 .arg(m_outputControl->fileName()).arg(newFile),
1941 _FILEINFO_);
1942 }
1943 newFile = newPath + "/" + FileName(m_txtBundleOutputFilename).name();
1944 if (!QFile::copy(m_txtBundleOutputFilename, newFile)) {
1946 QString("Failed to copy file [%1] to new file [%2]")
1947 .arg(m_txtBundleOutputFilename).arg(newFile),
1948 _FILEINFO_);
1949 }
1950 newFile = newPath + "/" + FileName(m_csvSavedImagesFilename).name();
1951 if (!QFile::copy(m_csvSavedImagesFilename, newFile)) {
1953 QString("Failed to copy file [%1] to new file [%2]")
1954 .arg(m_csvSavedImagesFilename).arg(newFile),
1955 _FILEINFO_);
1956 }
1957 newFile = newPath + "/" + FileName(m_csvSavedPointsFilename).name();
1958 if (!QFile::copy(m_csvSavedPointsFilename, newFile)) {
1960 QString("Failed to copy file [%1] to new file [%2]")
1961 .arg(m_csvSavedPointsFilename).arg(newFile),
1962 _FILEINFO_);
1963 }
1964 newFile = newPath + "/" + FileName(m_csvSavedResidualsFilename).name();
1965 if (!QFile::copy(m_csvSavedResidualsFilename, newFile)) {
1967 QString("Failed to copy file [%1] to new file [%2]")
1968 .arg(m_csvSavedResidualsFilename).arg(newFile),
1969 _FILEINFO_);
1970 }
1971 }
1972
1973 // Create relativePath
1974 relativePath = m_inputControlNetFileName->expanded().remove(project->newProjectRoot());
1975 // Get rid of any preceding "/" , but add on ending "/"
1976 if (relativePath.startsWith("/")) {
1977 relativePath.remove(0,1);
1978 }
1979
1980 // Create relativeBundlePath for bundleSolutionInfo
1981 relativeBundlePath = newPath.remove(project->newProjectRoot());
1982 // Get rid of any preceding "/" , but add on ending "/"
1983 if (relativeBundlePath.startsWith("/")) {
1984 relativeBundlePath.remove(0,1);
1985 }
1986 relativeBundlePath += "/";
1987 }
1988
1989 stream.writeStartElement("bundleSolutionInfo");
1990 // save ID, cnet file name, and run time to stream
1991 stream.writeStartElement("generalAttributes");
1992 stream.writeTextElement("id", m_id->toString());
1993 stream.writeTextElement("name", m_name);
1994 stream.writeTextElement("runTime", runTime());
1995
1996 stream.writeTextElement("inputFileName",
1997 relativePath);
1998 stream.writeTextElement("bundleOutTXT",
1999 relativeBundlePath + FileName(m_txtBundleOutputFilename).name());
2000 stream.writeTextElement("imagesCSV",
2001 relativeBundlePath + FileName(m_csvSavedImagesFilename).name());
2002 stream.writeTextElement("pointsCSV",
2003 relativeBundlePath + FileName(m_csvSavedPointsFilename).name());
2004 stream.writeTextElement("residualsCSV",
2005 relativeBundlePath + FileName(m_csvSavedResidualsFilename).name());
2006 stream.writeEndElement(); // end general attributes
2007
2008 // save settings to stream
2009 m_settings->save(stream, project);
2010
2011 // save statistics to stream
2012 m_statisticsResults->save(stream, project);
2013
2014 if (project) {
2015 // save adjusted images lists to stream
2016 if (!m_adjustedImages->isEmpty()) {
2017 stream.writeStartElement("imageLists");
2018 for (int i = 0; i < m_adjustedImages->count(); i++) {
2019 m_adjustedImages->at(i)->save(stream, project, bundleSolutionInfoRoot);
2020 }
2021 stream.writeEndElement();
2022 }
2023
2024 // save output control
2025 stream.writeStartElement("outputControl");
2026 m_outputControl->save(stream, project, relativeBundlePath);
2027 stream.writeEndElement();
2028 }
2029
2030 stream.writeEndElement(); //end bundleSolutionInfo
2031 }
2032
2033
2043 SurfacePoint::CoordIndex coordIdx) const {
2044 QString coordName;
2045 switch (m_settings->controlPointCoordTypeReports()) {
2047 switch (coordIdx) {
2048 case SurfacePoint::One:
2049 coordName = " Latitude";
2050 break;
2051 case SurfacePoint::Two:
2052 coordName = "Longitude";
2053 break;
2054 case SurfacePoint::Three:
2055 coordName = " Radius";
2056 break;
2057 default:
2058 IString msg = "Unknown surface point index enum ["
2059 + toString(coordIdx) + "].";
2060 throw IException(IException::Programmer, msg, _FILEINFO_);
2061 break;
2062 }
2063 break;
2065 switch (coordIdx) {
2066 case SurfacePoint::One:
2067 coordName = "POINT X";
2068 break;
2069 case SurfacePoint::Two:
2070 coordName = "POINT Y";
2071 break;
2072 case SurfacePoint::Three:
2073 coordName = "POINT Z";
2074 break;
2075 default:
2076 IString msg = "Unknown surface point index enum ["
2077 + toString(coordIdx) + "].";
2078 throw IException(IException::Programmer, msg, _FILEINFO_);
2079 break;
2080 }
2081 break;
2082 default:
2083 IString msg = "Unknown surface point coordinate type enum ["
2084 + toString(m_settings->controlPointCoordTypeReports()) + "].";
2085 throw IException(IException::Programmer, msg, _FILEINFO_);
2086 break;
2087 }
2088 return coordName;
2089 }
2090}
This class is used to modify and manage solve settings for 1 to many BundleObservations.
A container class for statistical results from a BundleAdjust solution.
double elapsedTimeErrorProp() const
Returns the elapsed time for error propagation.
int numberRejectedObservations() const
Returns the number of observation that were rejected.
QString minSigmaCoord2PointId() const
Returns the minimum sigma point id for coordinate 2.
QList< Statistics > rmsImageSampleResiduals() const
Returns the list of RMS image sample residuals statistics.
ControlNetQsp outputControlNet() const
Returns a shared pointer to the output control network.
int numberObservations() const
Returns the number of observations.
MaximumLikelihoodWFunctions maximumLikelihoodModelWFunc(int modelIndex) const
Returns the maximum likelihood model at the given index.
double sigmaCoord3StatisticsRms() const
Returns the RMS of the adjusted sigmas for coordinate 3.
double sigma0() const
Returns the Sigma0 of the bundle adjustment.
bool converged() const
Returns whether or not the bundle adjustment converged.
double maximumLikelihoodModelQuantile(int modelIndex) const
Returns the quantile of the maximum likelihood model at the given index.
int numberConstrainedPointParameters() const
Returns the number of constrained point parameters.
int iterations() const
Returns the number of iterations taken by the BundleAdjust.
QString minSigmaCoord1PointId() const
Returns the minimum sigma point id for coordinate 1.
void save(QXmlStreamWriter &stream, const Project *project) const
Saves the BundleResults object to an XML file.
QVector< BundleControlPointQsp > & bundleControlPoints()
Returns a reference to the BundleControlPoint vector.
void setCorrMatImgsAndParams(QMap< QString, QStringList > imgsAndParams)
Set the images and their associated parameters of the correlation matrix.
Distance maxSigmaCoord2Distance() const
Returns the maximum sigma distance for coordinate 2.
int numberUnknownParameters() const
Returns the number of unknown parameters.
QVector< BundleLidarControlPointQsp > & bundleLidarControlPoints()
Returns a reference to the BundleLidarControlPoint vector.
LidarDataQsp outputLidarData() const
Returns a shared pointer to the output LidarData object.
double sigmaCoord2StatisticsRms() const
Returns the RMS of the adjusted sigmas for coordinate 2.
Distance minSigmaCoord3Distance() const
Returns the minimum sigma distance for coordinate 3.
QString maxSigmaCoord1PointId() const
Returns the maximum sigma point id for coordinate 1.
int numberConstrainedTargetParameters() const
Return the number of constrained target parameters.
StatCumProbDistDynCalc residualsCumulativeProbabilityDistribution() const
Returns the cumulative probability distribution of the residuals used for reporting.
double elapsedTime() const
Returns the elapsed time for the bundle adjustment.
QList< Statistics > rmsImageResiduals() const
Returns the list of RMS image residuals statistics.
const BundleObservationVector & observations() const
Returns a reference to the observations used by the BundleAdjust.
Distance minSigmaCoord1Distance() const
Returns the minimum sigma distance for coordinate 1.
QString minSigmaCoord3PointId() const
Returns the minimum sigma point id for coordinate 3.
QList< Statistics > rmsImageLineResiduals() const
Returns the list of RMS image line residuals statistics.
int numberLidarRangeConstraintEquations() const
Return the number of lidar range constraint equations.
Distance maxSigmaCoord3Distance() const
Returns the maximum sigma distance for coordinate 3.
Distance maxSigmaCoord1Distance() const
Returns the maximum sigma distance for coordinate 1.
QString maxSigmaCoord3PointId() const
Returns the maximum sigma point id for coordinate 3.
QString maxSigmaCoord2PointId() const
Returns the maximum sigma point id for coordinate 2.
int numberConstrainedImageParameters() const
Returns the number of constrained image parameters.
double sigmaCoord1StatisticsRms() const
Returns the RMS of the adjusted sigmas for coordinate 1.
Distance minSigmaCoord2Distance() const
Returns the minimum sigma distance for coordinate 2.
int degreesOfFreedom() const
Returns the degrees of freedom.
Container class for BundleAdjustment settings.
bool outputResiduals()
Outputs image coordinate residuals to a csv file.
bool outputImagesCSV()
Outputs the bundleout_images.csv file which contains Jigsaw data about the images within each observa...
BundleSettingsQsp m_settings
Bundle settings.
QString inputControlNetFileName() const
Returns the name of the input control network.
QString m_runTime
Run time of the bundle adjustment.
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Saves the BundleSolutionInfo to the project.
QString inputLidarDataFileName() const
Returns name of input lidar data file (if any).
void addAdjustedImages(ImageList *images)
Adds a list of images that were adjusted (their labels were updated).
QString savedPointsFilename()
Returns filename of output bundle points csv file.
QUuid * m_id
A unique ID for this BundleSolutionInfo object (useful for others to reference this object when savin...
BundleSettingsQsp bundleSettings()
Returns bundle settings.
void setName(QString name)
Sets the name of the bundle.
QList< ImageList * > * m_adjustedImages
Adjusted image list.
FileName * m_inputControlNetFileName
Input control network file name.
QString m_xmlHandlerCharacters
List of characters that have been handled.
void setOutputControl(Control *outputControl)
Returns the name of the output control network.
QList< ImageList * > adjustedImages() const
Returns the list of images that were adjusted after a bundle.
QList< ImageList * > * m_images
Input image list.
FileName * m_inputLidarDataFileName
Input lidar data file name.
QString surfacePointCoordName(SurfacePoint::CoordinateType type, SurfacePoint::CoordIndex coordInx) const
Determine the control point coordinate name.
QString savedResidualsFilename()
Returns filename of output bundle residuals csv file.
void setOutputControlName(QString name)
Sets m_outputControlName.
BundleResults bundleResults()
Returns the bundle results.
QString id() const
Get a unique, identifying string associated with this BundleSolutionInfo object.
void setRunTime(QString runTime)
Sets the run time, and the name if a name is not already set.
bool outputPointsCSV()
Outputs point data to a csv file.
QString outputControlName() const
Returns m_outputControlName.
void updateFileName(Project *)
TODO: change description below to something more like english.
QString outputControlNetFileName() const
Returns the name of the output control network.
BundleResults * m_statisticsResults
Bundle statistical results.
QString runTime() const
Returns the run time.
bool outputHeader(std::ofstream &fpOut)
Output header for bundle results file.
LidarData * m_outputLidarDataSet
QList of adjusted lidar points.
QString name() const
Returns the name of the bundle.
QString savedBundleOutputFilename()
Returns bundleout text filename.
bool outputText()
Outputs a text file with the results of the BundleAdjust.
Control * m_outputControl
Output control.
QString savedImagesFilename()
Returns filename of output bundle images csv file.
QList< ImageList * > imageList()
Returns the images used in the bundle.
void setOutputStatistics(BundleResults statisticsResults)
Sets the stat results.
QString m_name
Name of the bundle. Defaults to the id.
bool outputImagesCSVHeader(std::ofstream &fpOut, BundleObservationQsp observations)
Outputs the header for the bundleout_images.csv file.
Control * control() const
Returns bundle output Control object.
bool outputLidarCSV()
Outputs lidar data to a csv file.
This represents an ISIS control net in a project-based GUI interface.
Definition Control.h:65
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Method to write this Control object's member data to an XML stream.
Definition Control.cpp:353
QString fileName() const
Access the name of the control network file associated with this Control.
Definition Control.cpp:252
@ Constrained
A Constrained point is a Control Point whose lat/lon/radius is somewhat established and should not be...
@ Free
A Free point is a Control Point that identifies common measurements between two or more cubes.
@ Fixed
A Fixed point is a Control Point whose lat/lon is well established and should not be changed.
double meters() const
Get the distance in meters.
Definition Distance.cpp:85
File name manipulation and expansion.
Definition FileName.h:100
QString path() const
Returns the path of the file name.
Definition FileName.cpp:103
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition FileName.cpp:162
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition FileName.cpp:196
QString toString() const
Returns a QString of the full file name including the file path, excluding the attributes with any Is...
Definition FileName.cpp:515
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
@ Io
A type of error that occurred when performing an actual I/O operation.
Definition IException.h:155
Adds specific functionality to C++ strings.
Definition IString.h:165
Internalizes a list of images and allows for operations on the entire list.
Definition ImageList.h:53
static QString modelToString(Model model)
Static method to return a string represtentation for a given MaximumLikelihoodWFunctions::Model enum.
QString weightedResidualCutoff()
Method to return a string represtentation of the weighted residual cutoff (if it exists) for the Maxi...
double tweakingConstant() const
Returns the current tweaking constant.
The main project for ipce.
Definition Project.h:287
static QString cnetRoot(QString projectRoot)
Appends the root directory name 'cnets' to the project.
Definition Project.cpp:2080
QString bundleSolutionInfoRoot() const
Accessor for the root directory of the results data.
Definition Project.cpp:2304
static QString bundleSolutionInfoRoot(QString projectRoot)
Appends the root directory name 'bundle' to the project results directory.
Definition Project.cpp:2294
QString newProjectRoot() const
Get the top-level folder of the new project.
Definition Project.cpp:1736
QString projectRoot() const
Get the top-level folder of the project.
Definition Project.cpp:1727
double min()
Returns the maximum observation so far included in the dynamic calculation.
double value(double cumProb)
Provides the value of the variable that has the given cumulative probility (according the current est...
double max()
Returns the maximum observation so far included in the dynamic calculation.
This class is used to accumulate statistics on double arrays.
Definition Statistics.h:93
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 QString coordinateTypeToString(CoordinateType type)
Converts the given SurfacePoint::CoordinateType enumeration to a string.
static QString CurrentLocalTime()
Returns the current local time This time is taken directly from the system clock, so if the system cl...
Definition iTime.cpp:520
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
QSharedPointer< BundleSettings > BundleSettingsQsp
Definition for a BundleSettingsQsp, a shared pointer to a BundleSettings object.
QSharedPointer< BundleLidarRangeConstraint > BundleLidarRangeConstraintQsp
Typdef for BundleLidarRangeConstraint QSharedPointer.
const double Null
Value for an Isis Null pixel.