Loading [MathJax]/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
BundleSolutionInfo.cpp
1
6
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
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);
65 }
66
67
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);
94 }
95
96
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
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){
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;
179 m_statisticsResults = new BundleResults();
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
327
328
334 QString BundleSolutionInfo::id() const {
335 return m_id->toString().remove(QRegExp("[{}]"));
336 }
337
338
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
377 return m_inputControlNetFileName->expanded();
378 }
379
380
387
388 if (m_outputControl)
389 return m_outputControl->fileName();
390 else
391 return m_outputControlName;
392 }
393
394
401 return m_inputLidarDataFileName->expanded();
402 }
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
481
482
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
597 LidarDataQsp lidarData = m_statisticsResults->outputLidarData();
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 if (m_settings->controlPointCoordTypeBundle() == SurfacePoint::Latitudinal) {
666 m_settings->solveRadius() ?
667 snprintf(buf, sizeof(buf), "\n RADIUS: ON"):
668 snprintf(buf, sizeof(buf), "\n RADIUS: OFF");
669 }
670 else { // Rectangular (XYZ) solution
671 snprintf(buf, sizeof(buf), "\n RADIUS: N/A");
672 }
673 fpOut << buf;
674
675 m_settings->solveTargetBody() ?
676 snprintf(buf, sizeof(buf), "\n TARGET BODY: ON"):
677 snprintf(buf, sizeof(buf), "\n TARGET BODY: OFF");
678 fpOut << buf;
679
680 m_settings->updateCubeLabel() ?
681 snprintf(buf, sizeof(buf), "\n UPDATE: YES"):
682 snprintf(buf, sizeof(buf), "\n UPDATE: NO");
683 fpOut << buf;
684
685 m_settings->errorPropagation() ?
686 snprintf(buf, sizeof(buf), "\n ERROR PROPAGATION: ON"):
687 snprintf(buf, sizeof(buf), "\n ERROR PROPAGATION: OFF");
688 fpOut << buf;
689
690 (m_settings->controlPointCoordTypeReports() == SurfacePoint::Latitudinal) ?
691 snprintf(buf, sizeof(buf), "\n CONTROL POINT COORDINATE TYPE FOR REPORTS: LATITUDINAL"):
692 snprintf(buf, sizeof(buf), "\n CONTROL POINT COORDINATE TYPE FOR REPORTS: RECTANGULAR");
693 fpOut << buf;
694
695 (m_settings->controlPointCoordTypeBundle() == SurfacePoint::Latitudinal) ?
696 snprintf(buf, sizeof(buf), "\n CONTROL POINT COORDINATE TYPE FOR BUNDLE: LATITUDINAL"):
697 snprintf(buf, sizeof(buf), "\n CONTROL POINT COORDINATE TYPE FOR BUNDLE: RECTANGULAR");
698 fpOut << buf;
699
700 if (m_settings->outlierRejection()) {
701 snprintf(buf, sizeof(buf), "\n OUTLIER REJECTION: ON");
702 fpOut << buf;
703 snprintf(buf, sizeof(buf), "\n REJECTION MULTIPLIER: %lf",
704 m_settings->outlierRejectionMultiplier());
705 fpOut << buf;
706
707 }
708 else {
709 snprintf(buf, sizeof(buf), "\n OUTLIER REJECTION: OFF");
710 fpOut << buf;
711 snprintf(buf, sizeof(buf), "\n REJECTION MULTIPLIER: N/A");
712 fpOut << buf;
713 }
714
715 // Added April 5, 2017
716 snprintf(buf, sizeof(buf), "\n CONTROL POINT COORDINATE TYPE FOR REPORTS: %s",
717 SurfacePoint::coordinateTypeToString(m_settings->controlPointCoordTypeReports()).toLatin1().data());
718
719 // Added July 4, 2017
720 snprintf(buf, sizeof(buf), "\n CONTROL POINT COORDINATE TYPE FOR BUNDLE: %s",
721 SurfacePoint::coordinateTypeToString(m_settings->controlPointCoordTypeBundle()).toLatin1().data());
722
723 snprintf(buf, sizeof(buf), "\n\nMAXIMUM LIKELIHOOD ESTIMATION\n============================\n");
724 fpOut << buf;
725
726 for (int tier = 0; tier < 3; tier++) {
727 if (tier < m_statisticsResults->numberMaximumLikelihoodModels()) {
728 snprintf(buf, sizeof(buf), "\n Tier %d Enabled: TRUE", tier);
729 fpOut << buf;
730 snprintf(buf, sizeof(buf), "\n Maximum Likelihood Model: %s",
733 maximumLikelihoodModelWFunc(tier).model()).toLatin1().data());
734 fpOut << buf;
735 snprintf(buf, sizeof(buf), "\n Quantile used for tweaking constant: %lf",
736 m_statisticsResults->maximumLikelihoodModelQuantile(tier));
737 fpOut << buf;
738 snprintf(buf, sizeof(buf), "\n Quantile weighted R^2 Residual value: %lf",
739 m_statisticsResults->maximumLikelihoodModelWFunc(tier).tweakingConstant());
740 fpOut << buf;
741 snprintf(buf, sizeof(buf), "\n Approx. weighted Residual cutoff: %s",
742 m_statisticsResults->maximumLikelihoodModelWFunc(tier)
743 .weightedResidualCutoff().toLatin1().data());
744 fpOut << buf;
745 if (tier != 2) fpOut << "\n";
746 }
747 else {
748 snprintf(buf, sizeof(buf), "\n Tier %d Enabled: FALSE", tier);
749 fpOut << buf;
750 }
751 }
752
753 snprintf(buf, sizeof(buf), "\n\nINPUT: CONVERGENCE CRITERIA\n===========================\n");
754 fpOut << buf;
755 snprintf(buf, sizeof(buf), "\n SIGMA0: %e",
756 m_settings->convergenceCriteriaThreshold());
757 fpOut << buf;
758 snprintf(buf, sizeof(buf), "\n MAXIMUM ITERATIONS: %d",
759 m_settings->convergenceCriteriaMaximumIterations());
760 fpOut << buf;
761
762 //TODO Should it be checked that positionSigmas.size() == positionSolveDegree and
763 // pointingSigmas.size() == pointingSolveDegree somewhere? JAM
764
765 //TODO How do we output this information when using multiple solve settings? JAM
766
767 BundleObservationSolveSettings globalSettings = m_settings->observationSolveSettings(0);
768 int pointingSolveDegree = globalSettings.numberCameraAngleCoefficientsSolved();
769 QList<double> pointingSigmas = globalSettings.aprioriPointingSigmas();
770 int positionSolveDegree = globalSettings.numberCameraPositionCoefficientsSolved();
771 QList<double> positionSigmas = globalSettings.aprioriPositionSigmas();
772
773 snprintf(buf, sizeof(buf), "\n\nINPUT: CAMERA POINTING OPTIONS\n==============================\n");
774 fpOut << buf;
775 switch (pointingSolveDegree) {
776 case 0:
777 snprintf(buf, sizeof(buf),"\n CAMSOLVE: NONE");
778 break;
779 case 1:
780 snprintf(buf, sizeof(buf),"\n CAMSOLVE: ANGLES");
781 break;
782 case 2:
783 snprintf(buf, sizeof(buf),"\n CAMSOLVE: ANGLES, VELOCITIES");
784 break;
785 case 3:
786 snprintf(buf, sizeof(buf),"\n CAMSOLVE: ANGLES, VELOCITIES, ACCELERATIONS");
787 break;
788 default:
789 snprintf(buf, sizeof(buf),"\n CAMSOLVE: ALL POLYNOMIAL COEFFICIENTS (%d)"
790 "\n CKDEGREE: %d"
791 "\n CKSOLVEDEGREE: %d",
792 pointingSolveDegree,
793 globalSettings.ckDegree(),
794 globalSettings.ckSolveDegree());
795 break;
796 }
797 fpOut << buf;
798 globalSettings.solveTwist() ?
799 snprintf(buf, sizeof(buf), "\n TWIST: ON"):
800 snprintf(buf, sizeof(buf), "\n TWIST: OFF");
801 fpOut << buf;
802 globalSettings.solvePolyOverPointing() ?
803 snprintf(buf, sizeof(buf), "\n POLYNOMIAL OVER EXISTING POINTING: ON"):
804 snprintf(buf, sizeof(buf), "\nPOLYNOMIAL OVER EXISTING POINTING : OFF");
805 fpOut << buf;
806
807 snprintf(buf, sizeof(buf), "\n\nINPUT: SPACECRAFT OPTIONS\n=========================\n");
808 fpOut << buf;
809 switch (positionSolveDegree) {
810 case 0:
811 snprintf(buf, sizeof(buf),"\n SPSOLVE: NONE");
812 break;
813 case 1:
814 snprintf(buf, sizeof(buf),"\n SPSOLVE: POSITION");
815 break;
816 case 2:
817 snprintf(buf, sizeof(buf),"\n SPSOLVE: POSITION, VELOCITIES");
818 break;
819 case 3:
820 snprintf(buf, sizeof(buf),"\n SPSOLVE: POSITION, VELOCITIES, ACCELERATIONS");
821 break;
822 default:
823 snprintf(buf, sizeof(buf),"\n SPSOLVE: ALL POLYNOMIAL COEFFICIENTS (%d)"
824 "\n SPKDEGREE: %d"
825 "\n SPKSOLVEDEGREE: %d",
826 positionSolveDegree,
827 globalSettings.spkDegree(),
828 globalSettings.spkSolveDegree());
829 break;
830 }
831 fpOut << buf;
832 globalSettings.solvePositionOverHermite() ?
833 snprintf(buf, sizeof(buf), "\n POLYNOMIAL OVER HERMITE SPLINE: ON"):
834 snprintf(buf, sizeof(buf), "\nPOLYNOMIAL OVER HERMITE SPLINE : OFF");
835 fpOut << buf;
836
837 snprintf(buf, sizeof(buf), "\n\nINPUT: GLOBAL IMAGE PARAMETER UNCERTAINTIES\n===========================================\n");
838 QString coord1Str;
839 QString coord2Str;
840 QString coord3Str;
841 switch (m_settings->controlPointCoordTypeBundle()) {
843 coord1Str = " POINT LATITUDE";
844 coord2Str = " POINT LONGITUDE";
845 coord3Str = " POINT RADIUS";
846 break;
848 coord1Str = " POINT X";
849 coord2Str = " POINT Y";
850 coord3Str = " POINT Z";
851 break;
852 default:
853 IString msg ="Unknown surface point coordinate type enum ["
854 + toString(m_settings->controlPointCoordTypeReports()) + "]." ;
855 throw IException(IException::Programmer, msg, _FILEINFO_);
856 break;
857 }
858
859 // Coordinate 1 (latitude or point X)
860 fpOut << buf;
861 (m_settings->globalPointCoord1AprioriSigma() == Isis::Null) ?
862 snprintf(buf, sizeof(buf),"\n%s SIGMA: N/A", coord1Str.toLatin1().data()):
863 snprintf(buf, sizeof(buf),"\n%s SIGMA: %lf (meters)", coord1Str.toLatin1().data(),
864 m_settings->globalPointCoord1AprioriSigma());
865 // Coordinate 2 (longitude or point Y)
866 fpOut << buf;
867 (m_settings->globalPointCoord2AprioriSigma() == Isis::Null) ?
868 snprintf(buf, sizeof(buf),"\n%s SIGMA: N/A", coord2Str.toLatin1().data()):
869 snprintf(buf, sizeof(buf),"\n%s SIGMA: %lf (meters)", coord2Str.toLatin1().data(),
870 m_settings->globalPointCoord2AprioriSigma());
871 // Coordinate 3 (radius or point Z)
872 fpOut << buf;
873 (m_settings->globalPointCoord3AprioriSigma() == Isis::Null) ?
874 snprintf(buf, sizeof(buf),"\n%s SIGMA: N/A", coord3Str.toLatin1().data()):
875 snprintf(buf, sizeof(buf),"\n%s SIGMA: %lf (meters)", coord3Str.toLatin1().data(),
876 m_settings->globalPointCoord3AprioriSigma());
877 fpOut << buf;
878 (positionSolveDegree < 1 || positionSigmas[0] == Isis::Null) ?
879 snprintf(buf, sizeof(buf),"\n SPACECRAFT POSITION SIGMA: N/A"):
880 snprintf(buf, sizeof(buf),"\n SPACECRAFT POSITION SIGMA: %lf (meters)",
881 positionSigmas[0]);
882 fpOut << buf;
883
884 (positionSolveDegree < 2 || positionSigmas[1] == Isis::Null) ?
885 snprintf(buf, sizeof(buf),"\n SPACECRAFT VELOCITY SIGMA: N/A"):
886 snprintf(buf, sizeof(buf),"\n SPACECRAFT VELOCITY SIGMA: %lf (m/s)",
887 positionSigmas[1]);
888 fpOut << buf;
889
890 (positionSolveDegree < 3 || positionSigmas[2] == Isis::Null) ?
891 snprintf(buf, sizeof(buf),"\n SPACECRAFT ACCELERATION SIGMA: N/A"):
892 snprintf(buf, sizeof(buf),"\n SPACECRAFT ACCELERATION SIGMA: %lf (m/s/s)",
893 positionSigmas[2]);
894 fpOut << buf;
895
896 (pointingSolveDegree < 1 || pointingSigmas[0] == Isis::Null) ?
897 snprintf(buf, sizeof(buf),"\n CAMERA ANGLES SIGMA: N/A"):
898 snprintf(buf, sizeof(buf),"\n CAMERA ANGLES SIGMA: %lf (dd)",
899 pointingSigmas[0]);
900 fpOut << buf;
901
902 (pointingSolveDegree < 2 || pointingSigmas[1] == Isis::Null) ?
903 snprintf(buf, sizeof(buf),"\n CAMERA ANGULAR VELOCITY SIGMA: N/A"):
904 snprintf(buf, sizeof(buf),"\n CAMERA ANGULAR VELOCITY SIGMA: %lf (dd/s)",
905 pointingSigmas[1]);
906 fpOut << buf;
907
908 (pointingSolveDegree < 3 || pointingSigmas[2] == Isis::Null) ?
909 snprintf(buf, sizeof(buf),"\n CAMERA ANGULAR ACCELERATION SIGMA: N/A"):
910 snprintf(buf, sizeof(buf),"\n CAMERA ANGULAR ACCELERATION SIGMA: %lf (dd/s/s)",
911 pointingSigmas[2]);
912 fpOut << buf;
913
914 if (m_settings->solveTargetBody()) {
915 snprintf(buf, sizeof(buf), "\n\nINPUT: TARGET BODY OPTIONS\n==============================\n");
916 fpOut << buf;
917
918 if (m_settings->solvePoleRA() && m_settings->solvePoleDec()) {
919 snprintf(buf, sizeof(buf),"\n POLE: RIGHT ASCENSION");
920 fpOut << buf;
921 snprintf(buf, sizeof(buf),"\n : DECLINATION\n");
922 fpOut << buf;
923 }
924 else if (m_settings->solvePoleRA()) {
925 snprintf(buf, sizeof(buf),"\n POLE: RIGHT ASCENSION\n");
926 fpOut << buf;
927 }
928 else if (m_settings->solvePoleDec()) {
929 snprintf(buf, sizeof(buf),"\n POLE: DECLINATION\n");
930 fpOut << buf;
931 }
932
933 if (m_settings->solvePM() || m_settings->solvePMVelocity()
934 || m_settings->solvePMAcceleration()) {
935 snprintf(buf, sizeof(buf),"\n PRIME MERIDIAN: W0 (OFFSET)");
936 fpOut << buf;
937
938 if (m_settings->solvePMVelocity()) {
939 snprintf(buf, sizeof(buf),"\n : WDOT (SPIN RATE)");
940 fpOut << buf;
941 }
942 if (m_settings->solvePMAcceleration()) {
943 snprintf(buf, sizeof(buf),"\n :W ACCELERATION");
944 fpOut << buf;
945 }
946 }
947
948 if (m_settings->solveTriaxialRadii() || m_settings->solveMeanRadius()) {
949 if (m_settings->solveMeanRadius()) {
950 snprintf(buf, sizeof(buf),"\n RADII: MEAN");
951 fpOut << buf;
952 }
953 else if (m_settings->solveTriaxialRadii()) {
954 snprintf(buf, sizeof(buf),"\n RADII: TRIAXIAL");
955 fpOut << buf;
956 }
957 }
958 }
959
960 snprintf(buf, sizeof(buf), "\n\nJIGSAW: RESULTS\n===============\n");
961 fpOut << buf;
962 snprintf(buf, sizeof(buf), "\n Images: %6d",numImages);
963 fpOut << buf;
964 snprintf(buf, sizeof(buf), "\n Points: %6d",numValidPoints);
965 fpOut << buf;
966
967 if (numValidLidarPoints > 0) {
968 snprintf(buf, sizeof(buf), "\n Lidar Points: %6d",numValidLidarPoints);
969 fpOut << buf;
970 }
971
972 snprintf(buf, sizeof(buf), "\n Total Measures: %6d",
973 (m_statisticsResults->numberObservations()
974 + m_statisticsResults->numberRejectedObservations()) / 2);
975 fpOut << buf;
976
977 snprintf(buf, sizeof(buf), "\n Total Observations: %6d",
978 m_statisticsResults->numberObservations()
979 + m_statisticsResults->numberRejectedObservations());
980 fpOut << buf;
981
982 snprintf(buf, sizeof(buf), "\n Good Observations: %6d",
983 m_statisticsResults->numberObservations());
984 fpOut << buf;
985
986 snprintf(buf, sizeof(buf), "\n Rejected Observations: %6d",
987 m_statisticsResults->numberRejectedObservations());
988 fpOut << buf;
989
990 if (m_statisticsResults->numberConstrainedPointParameters() > 0) {
991 snprintf(buf, sizeof(buf), "\n Constrained Point Parameters: %6d",
992 m_statisticsResults->numberConstrainedPointParameters());
993 fpOut << buf;
994 }
995
996 if (m_statisticsResults->numberConstrainedImageParameters() > 0) {
997 snprintf(buf, sizeof(buf), "\n Constrained Image Parameters: %6d",
998 m_statisticsResults->numberConstrainedImageParameters());
999 fpOut << buf;
1000 }
1001
1002 if (m_statisticsResults->numberConstrainedTargetParameters() > 0) {
1003 snprintf(buf, sizeof(buf), "\n Constrained Target Parameters: %6d",
1004 m_statisticsResults->numberConstrainedTargetParameters());
1005 fpOut << buf;
1006 }
1007
1008 if (m_statisticsResults->numberLidarRangeConstraintEquations() > 0) {
1009 snprintf(buf, sizeof(buf), "\n Lidar Range Constraints: %6d",
1010 m_statisticsResults->numberLidarRangeConstraintEquations());
1011 fpOut << buf;
1012 }
1013
1014 snprintf(buf, sizeof(buf), "\n Unknowns: %6d",
1015 m_statisticsResults->numberUnknownParameters());
1016 fpOut << buf;
1017
1018 if (numInnerConstraints > 0) {
1019 snprintf(buf, sizeof(buf), "\n Inner Constraints: %6d", numInnerConstraints);
1020 fpOut << buf;
1021 }
1022
1023 if (numDistanceConstraints > 0) {
1024 snprintf(buf, sizeof(buf), "\n Distance Constraints: %d", numDistanceConstraints);
1025 fpOut << buf;
1026 }
1027
1028 snprintf(buf, sizeof(buf), "\n Degrees of Freedom: %6d", numDegreesOfFreedom);
1029 fpOut << buf;
1030
1031 snprintf(buf, sizeof(buf), "\n Convergence Criteria: %6.3g",
1032 m_settings->convergenceCriteriaThreshold());
1033 fpOut << buf;
1034
1035 if (convergenceCriteria == 1) {
1036 snprintf(buf, sizeof(buf), "(Sigma0)");
1037 fpOut << buf;
1038 }
1039
1040 snprintf(buf, sizeof(buf), "\n Iterations: %6d", m_statisticsResults->iterations());
1041 fpOut << buf;
1042
1043 if (m_statisticsResults->iterations() >= m_settings->convergenceCriteriaMaximumIterations()) {
1044 snprintf(buf, sizeof(buf), "(Maximum reached)");
1045 fpOut << buf;
1046 }
1047
1048 snprintf(buf, sizeof(buf), "\n Sigma0: %30.20lf\n", m_statisticsResults->sigma0());
1049 fpOut << buf;
1050 snprintf(buf, sizeof(buf), " Error Propagation Elapsed Time: %6.4lf (seconds)\n",
1051 m_statisticsResults->elapsedTimeErrorProp());
1052 fpOut << buf;
1053 snprintf(buf, sizeof(buf), " Total Elapsed Time: %6.4lf (seconds)\n",
1054 m_statisticsResults->elapsedTime());
1055 fpOut << buf;
1056 if (m_statisticsResults->numberObservations()
1057 + m_statisticsResults->numberRejectedObservations()
1058 > 100) {
1059 snprintf(buf, sizeof(buf), "\n Residual Percentiles:\n");
1060 fpOut << buf;
1061
1062 // residual prob distribution values are calculated/printed
1063 // even if there is no maximum likelihood estimation
1064 try {
1065 for (int bin = 1;bin < 34;bin++) {
1066 double cumProb = double(bin) / 100.0;
1067 double resValue =
1069 residualsCumulativeProbabilityDistribution().value(cumProb);
1070 double resValue33 =
1072 residualsCumulativeProbabilityDistribution().value(cumProb + 0.33);
1073 double resValue66 =
1075 residualsCumulativeProbabilityDistribution().value(cumProb + 0.66);
1076 snprintf(buf, sizeof(buf), " Percentile %3d: %+8.3lf"
1077 " Percentile %3d: %+8.3lf"
1078 " Percentile %3d: %+8.3lf\n",
1079 bin, resValue,
1080 bin + 33, resValue33,
1081 bin + 66, resValue66);
1082 fpOut << buf;
1083 }
1084 }
1085 catch (IException &e) {
1086 QString msg = "Failed to output residual percentiles for bundleout";
1087 throw IException(e, IException::Io, msg, _FILEINFO_);
1088 }
1089 try {
1090 snprintf(buf, sizeof(buf), "\n Residual Box Plot:");
1091 fpOut << buf;
1092 snprintf(buf, sizeof(buf), "\n minimum: %+8.3lf",
1093 m_statisticsResults->residualsCumulativeProbabilityDistribution().min());
1094 fpOut << buf;
1095 snprintf(buf, sizeof(buf), "\n Quartile 1: %+8.3lf",
1096 m_statisticsResults->residualsCumulativeProbabilityDistribution().value(0.25));
1097 fpOut << buf;
1098 snprintf(buf, sizeof(buf), "\n Median: %+8.3lf",
1099 m_statisticsResults->residualsCumulativeProbabilityDistribution().value(0.50));
1100 fpOut << buf;
1101 snprintf(buf, sizeof(buf), "\n Quartile 3: %+8.3lf",
1102 m_statisticsResults->residualsCumulativeProbabilityDistribution().value(0.75));
1103 fpOut << buf;
1104 snprintf(buf, sizeof(buf), "\n maximum: %+8.3lf\n",
1105 m_statisticsResults->residualsCumulativeProbabilityDistribution().max());
1106 fpOut << buf;
1107 }
1108 catch (IException &e) {
1109 QString msg = "Failed to output residual box plot for bundleout";
1110 throw IException(e, IException::Io, msg, _FILEINFO_);
1111 }
1112 }
1113
1114 // Loop over the observations to find the longest file path/name in the
1115 // bunch
1116 int filePadding = 0;
1117
1118 for (int i = 0; i < numObservations; i++) {
1119
1120 int numImagesInObservation = m_statisticsResults->observations().at(i)->size();
1121
1122 for (int j = 0; j < numImagesInObservation; j++) {
1123 BundleImageQsp bundleImage = m_statisticsResults->observations().at(i)->at(j);
1124
1125 if (bundleImage->fileName().length() > filePadding) {
1126 filePadding = bundleImage->fileName().length();
1127 }
1128 }
1129 }
1130
1131 snprintf(buf, sizeof(buf), "\nIMAGE MEASURES SUMMARY\n==========================\n\n");
1132 fpOut << buf;
1133
1134 // Pad each element in the table with the space for the longest image
1135 // path/name then padd it the length of the element + 1
1136 QString header("Measures RMS(pixels)");
1137 if (m_statisticsResults->outputLidarData()) {
1138 header += " Lidar RMS(pixels)";
1139 }
1140 // This is padded by an extra 11 to move it center to the table
1141 snprintf(buf, sizeof(buf),"%*s\n", header.length() + 11 + filePadding, header.toLatin1().data());
1142 fpOut << buf;
1143
1144 QString dividers("*************************** *******************************************");
1145 if (m_statisticsResults->outputLidarData()) {
1146 dividers += " *******************************************";
1147 }
1148 snprintf(buf, sizeof(buf),"%*s\n", dividers.length() + 1 + filePadding, dividers.toLatin1().data());
1149 fpOut << buf;
1150
1151 QString fields("| Accepted | Total | | Samples | Lines | Total |");
1152 if (m_statisticsResults->outputLidarData()) {
1153 fields += " | Samples | Lines | Total |";
1154 }
1155 snprintf(buf, sizeof(buf),"%*s\n", fields.length() + 1 + filePadding, fields.toLatin1().data());
1156 fpOut << buf;
1157
1158 int numMeasures, numLidarMeasures;
1159 int numRejectedMeasures, numLidarRejectedMeasures;
1160 int numUsed, numLidarUsed;
1161 int imageIndex = 0;
1162 Statistics rmsSamplesTotal,rmsLinesTotal,rmsTotals;
1163
1164 for (int i = 0; i < numObservations; i++) {
1165
1166 int numImagesInObservation = m_statisticsResults->observations().at(i)->size();
1167
1168 for (int j = 0; j < numImagesInObservation; j++) {
1169
1170 BundleImageQsp bundleImage = m_statisticsResults->observations().at(i)->at(j);
1171
1172 double rmsSampleResiduals = m_statisticsResults->
1173 rmsImageSampleResiduals()[imageIndex].Rms();
1174 double rmsLineResiduals = m_statisticsResults->
1175 rmsImageLineResiduals()[imageIndex].Rms();
1176 double rmsLandSResiduals = m_statisticsResults->
1177 rmsImageResiduals()[imageIndex].Rms();
1178 rmsSamplesTotal.AddData(rmsSampleResiduals);
1179 rmsLinesTotal.AddData(rmsLineResiduals);
1180 rmsTotals.AddData(rmsLandSResiduals);
1181
1182 numMeasures = m_statisticsResults->outputControlNet()->GetNumberOfValidMeasuresInImage
1183 (bundleImage->serialNumber());
1184
1185 numRejectedMeasures = m_statisticsResults->outputControlNet()->
1186 GetNumberOfJigsawRejectedMeasuresInImage(bundleImage->serialNumber());
1187
1188 numUsed = numMeasures - numRejectedMeasures;
1189
1190 QString filename = bundleImage->fileName();
1191 QStringList List;
1192 List = filename.split("/");
1193
1194 snprintf(buf, sizeof(buf),"%-*s" ,filePadding + 1, bundleImage->fileName().toLatin1().data());
1195 fpOut << buf;
1196
1197 snprintf(buf, sizeof(buf), " %12d %12d ", numUsed, numMeasures);
1198 fpOut << buf;
1199
1200 snprintf(buf, sizeof(buf),"%13.4lf %13.4lf %13.4lf",
1201 rmsSampleResiduals,rmsLineResiduals,rmsLandSResiduals);
1202
1203 fpOut << buf;
1204
1205 if (m_statisticsResults->outputLidarData()) {
1206 double rmsLidarSampleResiduals = m_statisticsResults->
1207 rmsLidarImageSampleResiduals()[imageIndex].Rms();
1208 double rmsLidarLineResiduals = m_statisticsResults->
1209 rmsLidarImageLineResiduals()[imageIndex].Rms();
1210 double rmsLidarLandSResiduals = m_statisticsResults->
1211 rmsLidarImageResiduals()[imageIndex].Rms();
1212
1213 numLidarMeasures = m_statisticsResults->outputLidarData()->
1214 GetNumberOfValidMeasuresInImage(bundleImage->serialNumber());
1215
1216 numLidarRejectedMeasures = m_statisticsResults->outputLidarData()->
1217 GetNumberOfJigsawRejectedMeasuresInImage(bundleImage->serialNumber());
1218
1219 numLidarUsed = numLidarMeasures - numLidarRejectedMeasures;
1220
1221 snprintf(buf, sizeof(buf), " %12d %12d ", numLidarUsed, numLidarMeasures);
1222 fpOut << buf;
1223
1224 snprintf(buf, sizeof(buf),"%13.4lf %13.4lf %13.4lf",
1225 rmsLidarSampleResiduals,rmsLidarLineResiduals,rmsLidarLandSResiduals);
1226
1227 fpOut << buf;
1228 }
1229
1230 snprintf(buf, sizeof(buf), " \n");
1231 fpOut << buf;
1232 imageIndex++;
1233 }
1234 }
1235
1236 // Do something similar to above but left justify the string and add a 33
1237 // character buffer
1238 snprintf(buf, sizeof(buf),"%*s", -(filePadding + 33), "\nTotal RMS:");
1239 fpOut << buf;
1240 snprintf(buf, sizeof(buf),"%13.4lf %13.4lf %13.4lf\n",
1241 rmsSamplesTotal.Rms(),rmsLinesTotal.Rms(),rmsTotals.Rms());
1242 fpOut << buf;
1243
1244 return true;
1245 }
1246
1247
1260
1261 char buf[1056];
1262
1263 QList<Statistics> rmsImageSampleResiduals = m_statisticsResults->rmsImageSampleResiduals();
1264 QList<Statistics> rmsImageLineResiduals = m_statisticsResults->rmsImageLineResiduals();
1265 QList<Statistics> rmsImageResiduals = m_statisticsResults->rmsImageResiduals();
1266
1267 bool errorProp = false;
1268 if (m_statisticsResults->converged() && m_settings->errorPropagation()) {
1269 errorProp = true;
1270 }
1271
1272 QList<QString> outputCsvFileNames;
1273 QList<QString> instrumentIds = m_statisticsResults->observations().instrumentIds();
1274 // If there's just a single instrumentId just call it bundleout_images.csv
1275 if (instrumentIds.size() == 1) {
1276 QString ofname = "bundleout_images.csv";
1277 ofname = m_settings->outputFilePrefix() + ofname;
1278 m_csvSavedImagesFilename = ofname;
1279 outputCsvFileNames.push_back(ofname);
1280 }
1281 // Otherwise append the instrument IDs so it's bundleout_images_spacecraft_sensor.csv
1282 else {
1283 for (int i = 0; i < instrumentIds.size(); i++) {
1284 QString updatedInstrumentId = instrumentIds[i];
1285 // Replace and "/" or " " characters with "_" to make the filename safer
1286 // This line must be separate to avoid modifying the instrumentId in the list
1287 // we will iterate over later
1288 updatedInstrumentId.replace("/", "_").replace(" ", "_");
1289 QString ofname = "bundleout_images_" + updatedInstrumentId + ".csv";
1290 ofname = m_settings->outputFilePrefix() + ofname;
1291 m_csvSavedImagesFilename = ofname;
1292 outputCsvFileNames.push_back(ofname);
1293 }
1294 }
1295
1296 for (int i = 0; i < instrumentIds.size(); i++) {
1297
1298 std::ofstream fpOut(outputCsvFileNames[i].toLatin1().data(), std::ios::out);
1299 if (!fpOut) {
1300 return false;
1301 }
1302
1303 QList<BundleObservationQsp> observations =
1304 m_statisticsResults->observations().observationsByInstId(instrumentIds[i]);
1305
1306 int nObservations = observations.size();
1307
1308 outputImagesCSVHeader(fpOut, observations.front());
1309
1310 for (int j = 0; j < nObservations; j++ ) {
1311 BundleObservationQsp observation = observations[j];
1312
1313 // We need the image index, not the observation index,
1314 // so count all of the images prior to this observation
1315 int observationIndex = observation->index();
1316 int imgIndex = 0;
1317 for (int obsIndex = 0; obsIndex < observationIndex; obsIndex++) {
1318 imgIndex += m_statisticsResults->observations().at(obsIndex)->size();
1319 }
1320
1321 if(!observation) {
1322 continue;
1323 }
1324
1325 int numImages = observation->size();
1326
1327 for (int k = 0; k < numImages; k++) {
1328 BundleImageQsp image = observation->at(k);
1329
1330 snprintf(buf, sizeof(buf), "%s", image->fileName().toLatin1().data());
1331 fpOut << buf;
1332 snprintf(buf, sizeof(buf),",");
1333 fpOut << buf;
1334
1335 fpOut << toString(rmsImageSampleResiduals[imgIndex].Rms()).toLatin1().data();
1336 snprintf(buf, sizeof(buf),",");
1337 fpOut << buf;
1338
1339 fpOut << toString(rmsImageLineResiduals[imgIndex].Rms()).toLatin1().data();
1340 snprintf(buf, sizeof(buf),",");
1341 fpOut << buf;
1342
1343 fpOut << toString(rmsImageResiduals[imgIndex].Rms()).toLatin1().data();
1344 snprintf(buf, sizeof(buf),",");
1345 fpOut << buf;
1346
1347 QString observationString =
1348 observation->bundleOutputCSV(errorProp);
1349
1350 //Removes trailing commas
1351 if (observationString.right(1)==",") {
1352 observationString.truncate(observationString.length()-1);
1353 }
1354
1355 fpOut << (const char*) observationString.toLatin1().data();
1356
1357 snprintf(buf, sizeof(buf),"\n");
1358 fpOut << buf;
1359 imgIndex++;
1360
1361 }
1362 }
1363 fpOut.close();
1364 }
1365
1366 return true;
1367 }
1368
1369
1376
1377 QString ofname = "bundleout.txt";
1378 ofname = m_settings->outputFilePrefix() + ofname;
1379
1380 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1381 if (!fpOut) {
1382 return false;
1383 }
1384
1385 m_txtBundleOutputFilename = ofname;
1386
1387 char buf[4096];
1388 BundleObservationQsp observation;
1389
1390 int nObservations = m_statisticsResults->observations().size();
1391
1392 outputHeader(fpOut);
1393
1394 bool berrorProp = false;
1395 if (m_statisticsResults->converged() && m_settings->errorPropagation()) {
1396 berrorProp = true;
1397 }
1398
1399 // output target body header if solving for target
1400 if (m_settings->solveTargetBody()) {
1401 snprintf(buf, sizeof(buf), "\nTARGET BODY\n==========================\n");
1402 fpOut << buf;
1403
1404 snprintf(buf, sizeof(buf), "\n Target Initial Total "
1405 "Final Initial Final\n"
1406 "Parameter Value Correction "
1407 "Value Accuracy Accuracy\n");
1408 fpOut << buf;
1409
1410 QString targetString =
1411 m_settings->bundleTargetBody()->formatBundleOutputString(berrorProp);
1412 fpOut << (const char*)targetString.toLatin1().data();
1413 }
1414
1415 // output image exterior orientation header
1416 snprintf(buf, sizeof(buf), "\nIMAGE EXTERIOR ORIENTATION\n==========================\n");
1417 fpOut << buf;
1418
1419 QMap<QString, QStringList> imagesAndParameters;
1420
1421 if (m_settings->solveTargetBody()) {
1422 imagesAndParameters.insert( "target", m_settings->bundleTargetBody()->parameterList() );
1423 }
1424
1425 for (int i = 0; i < nObservations; i++) {
1426
1427 observation = m_statisticsResults->observations().at(i);
1428 if (!observation) {
1429 continue;
1430 }
1431
1432 int numImages = observation->size();
1433 for (int j = 0; j < numImages; j++) {
1434 BundleImageQsp image = observation->at(j);
1435 snprintf(buf, sizeof(buf), "\nImage Full File Name: %s\n", image->fileName().toLatin1().data());
1436 fpOut << buf;
1437 snprintf(buf, sizeof(buf), "\nImage Serial Number: %s\n", image->serialNumber().toLatin1().data());
1438 fpOut << buf;
1439
1440 snprintf(buf, sizeof(buf),"Image Initial Total Final Accuracy\n");
1441 fpOut << buf;
1442 snprintf(buf, sizeof(buf),"Parameter Value Correction Value Initial Final Units\n");
1443 fpOut << buf;
1444
1445 snprintf(buf, sizeof(buf)," "
1446 "***************************************\n");
1447 fpOut << buf;
1448
1449 observation->bundleOutputString(fpOut,berrorProp);
1450 // Build list of images and parameters for correlation matrix.
1451 foreach ( QString image, observation->imageNames() ) {
1452 imagesAndParameters.insert( image, observation->parameterList() );
1453 }
1454 }
1455 }
1456
1457 // Save list of images and their associated parameters for CorrelationMatrix to use in ice.
1458 m_statisticsResults->setCorrMatImgsAndParams(imagesAndParameters);
1459
1460 // Save list of images and their associated parameters for CorrelationMatrix to use in ice.
1461 m_statisticsResults->setCorrMatImgsAndParams(imagesAndParameters);
1462
1463 // output point uncertainty statistics if error propagation is on
1464 if (berrorProp) {
1465 snprintf(buf, sizeof(buf), "\n\n\nPOINTS UNCERTAINTY SUMMARY\n==========================\n\n");
1466 fpOut << buf;
1467
1468 // Coordinate 1 (latitude or point x) summary
1469 QString coordName = surfacePointCoordName(m_settings->controlPointCoordTypeReports(),
1470 SurfacePoint::One);
1471 snprintf(buf, sizeof(buf), "RMS Sigma %s(m)%20.8lf\n", coordName.toLatin1().data(),
1472 m_statisticsResults->sigmaCoord1StatisticsRms());
1473 fpOut << buf;
1474 snprintf(buf, sizeof(buf), "MIN Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1475 m_statisticsResults->minSigmaCoord1Distance().meters(),
1476 m_statisticsResults->minSigmaCoord1PointId().toLatin1().data());
1477 fpOut << buf;
1478 snprintf(buf, sizeof(buf), "MAX Sigma %s(m)%20.8lf at %s\n\n", coordName.toLatin1().data(),
1479 m_statisticsResults->maxSigmaCoord1Distance().meters(),
1480 m_statisticsResults->maxSigmaCoord1PointId().toLatin1().data());
1481 fpOut << buf;
1482
1483 // Coordinate 2 (longitude or point y) summary
1484 coordName = surfacePointCoordName(m_settings->controlPointCoordTypeReports(),
1485 SurfacePoint::Two);
1486 snprintf(buf, sizeof(buf), "RMS Sigma %s(m)%20.8lf\n", coordName.toLatin1().data(),
1487 m_statisticsResults->sigmaCoord2StatisticsRms());
1488 fpOut << buf;
1489 snprintf(buf, sizeof(buf), "MIN Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1490 m_statisticsResults->minSigmaCoord2Distance().meters(),
1491 m_statisticsResults->minSigmaCoord2PointId().toLatin1().data());
1492 fpOut << buf;
1493 snprintf(buf, sizeof(buf), "MAX Sigma %s(m)%20.8lf at %s\n\n", coordName.toLatin1().data(),
1494 m_statisticsResults->maxSigmaCoord2Distance().meters(),
1495 m_statisticsResults->maxSigmaCoord2PointId().toLatin1().data());
1496 fpOut << buf;
1497
1498 // Coordinate 3 (radius or point z) summary
1499 coordName = surfacePointCoordName(m_settings->controlPointCoordTypeReports(),
1500 SurfacePoint::Three);
1501
1502 if (m_settings->controlPointCoordTypeBundle() == SurfacePoint::Latitudinal &&
1503 m_settings->controlPointCoordTypeReports() == SurfacePoint::Latitudinal &&
1504 m_settings->solveRadius() == false ) {
1505 snprintf(buf, sizeof(buf), " RMS Sigma Radius(m) N/A\n");
1506 fpOut << buf;
1507 snprintf(buf, sizeof(buf), " MIN Sigma Radius(m) N/A\n");
1508 fpOut << buf;
1509 snprintf(buf, sizeof(buf), " MAX Sigma Radius(m) N/A\n");
1510 fpOut << buf;
1511 }
1512 else {
1513 snprintf(buf, sizeof(buf), "RMS Sigma %s(m)%20.8lf\n", coordName.toLatin1().data(),
1514 m_statisticsResults->sigmaCoord3StatisticsRms());
1515 fpOut << buf;
1516 snprintf(buf, sizeof(buf), "MIN Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1517 m_statisticsResults->minSigmaCoord3Distance().meters(),
1518 m_statisticsResults->minSigmaCoord3PointId().toLatin1().data());
1519 fpOut << buf;
1520 snprintf(buf, sizeof(buf), "MAX Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1521 m_statisticsResults->maxSigmaCoord3Distance().meters(),
1522 m_statisticsResults->maxSigmaCoord3PointId().toLatin1().data());
1523 fpOut << buf;
1524 }
1525 }
1526
1527 // output point summary data header
1528 if (m_settings->controlPointCoordTypeReports() == SurfacePoint::Latitudinal) {
1529 snprintf(buf, sizeof(buf), "\n\nPOINTS SUMMARY\n==============\n%103s"
1530 "Sigma Sigma Sigma\n"
1531 " Label Status Rays RMS"
1532 " Latitude Longitude Radius"
1533 " Latitude Longitude Radius\n", "");
1534 }
1535 else { // Must be Rectangular
1536 snprintf(buf, sizeof(buf), "\n\nPOINTS SUMMARY\n==============\n%103s"
1537 "Sigma Sigma Sigma\n"
1538 " Label Status Rays RMS"
1539 " Point X Point Y Point Z"
1540 " Point X Point Y Point Z\n", "");
1541 }
1542 fpOut << buf;
1543
1544 int nPoints = m_statisticsResults->bundleControlPoints().size();
1545 for (int i = 0; i < nPoints; i++) {
1546 BundleControlPointQsp bundleControlPoint = m_statisticsResults->bundleControlPoints().at(i);
1547
1548 QString pointSummaryString =
1549 bundleControlPoint->formatBundleOutputSummaryString(berrorProp);
1550 fpOut << (const char*)pointSummaryString.toLatin1().data();
1551 }
1552
1553 int nLidarPoints = m_statisticsResults->bundleLidarControlPoints().size();
1554 for (int i = 0; i < nLidarPoints; i++) {
1555 BundleLidarControlPointQsp lidarControlPoint
1556 = m_statisticsResults->bundleLidarControlPoints().at(i);
1557
1558 QString pointSummaryString =
1559 lidarControlPoint->formatBundleOutputSummaryString(berrorProp);
1560 fpOut << (const char*)pointSummaryString.toLatin1().data();
1561 }
1562
1563 // output point detail data header
1564 snprintf(buf, sizeof(buf), "\n\nPOINTS DETAIL\n=============\n\n");
1565 fpOut << buf;
1566
1567 bool solveRadius = m_settings->solveRadius();
1568
1569 for (int i = 0; i < nPoints; i++) {
1570 BundleControlPointQsp bundleControlPoint = m_statisticsResults->bundleControlPoints().at(i);
1571
1572 // Removed radiansToMeters argument 9/18/2018 DAC
1573 QString pointDetailString =
1574 bundleControlPoint->formatBundleOutputDetailString(berrorProp, solveRadius);
1575 fpOut << (const char*)pointDetailString.toLatin1().data();
1576 }
1577
1578 for (int i = 0; i < nLidarPoints; i++) {
1579 BundleLidarControlPointQsp bundleLidarControlPoint =
1580 m_statisticsResults->bundleLidarControlPoints().at(i);
1581
1582 QString pointDetailString =
1583 bundleLidarControlPoint->formatBundleOutputDetailString(berrorProp, solveRadius);
1584 fpOut << (const char*)pointDetailString.toLatin1().data();
1585 }
1586
1587 fpOut.close();
1588
1589 return true;
1590 }
1591
1592
1599 char buf[1056];
1600
1601 QString ofname = "bundleout_points.csv";
1602 ofname = m_settings->outputFilePrefix() + ofname;
1603 m_csvSavedPointsFilename = ofname;
1604
1605 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1606 if (!fpOut) {
1607 return false;
1608 }
1609
1610 int numPoints = m_statisticsResults->bundleControlPoints().size();
1611
1612 double dLat, dLon, dRadius;
1613 double dX, dY, dZ;
1614 double dSigmaLat, dSigmaLong, dSigmaRadius;
1615 QString strStatus;
1616 double cor_lat_dd = 0.0; // lat correction, decimal degrees
1617 double cor_lon_dd = 0.0; // lon correction, decimal degrees
1618 double cor_rad_km = 0.0; // radius correction, kilometers
1619 double cor_lat_m = 0.0; // lat correction, meters
1620 double cor_lon_m = 0.0; // lon correction, meters
1621 double cor_rad_m = 0.0; // radius correction, meters
1622 double latInit = Isis::Null;
1623 double lonInit = Isis::Null;
1624 double radInit = Isis::Null;
1625 int numMeasures, numRejectedMeasures;
1626 double dResidualRms;
1627
1628 // print column headers
1629 if (m_settings->errorPropagation()) {
1630 snprintf(buf, sizeof(buf), ",,,,,3-d,3-d,3-d,Sigma,Sigma,Sigma,Correction,Correction,Correction,Coordinate,"
1631 "Coordinate,Coordinate\nPoint,Point,Accepted,Rejected,Residual,Latitude,Longitude,"
1632 "Radius,Latitude,Longitude,Radius,Latitude,Longitude,Radius,X,Y,Z\nLabel,Status,"
1633 "Measures,Measures,RMS,(dd),(dd),(km),(m),(m),(m),(m),(m),(m),(km),(km),(km)\n");
1634 }
1635 else {
1636 snprintf(buf, sizeof(buf), ",,,,,3-d,3-d,3-d,Correction,Correction,Correction,Coordinate,Coordinate,"
1637 "Coordinate\nPoint,Point,Accepted,Rejected,Residual,Latitude,Longitude,Radius,"
1638 "Latitude,Longitude,Radius,X,Y,Z\nLabel,Status,Measures,Measures,RMS,(dd),(dd),(km),"
1639 "(m),(m),(m),(km),(km),(km)\n");
1640 }
1641 fpOut << buf;
1642
1643 for (int i = 0; i < numPoints; i++) {
1644 BundleControlPointQsp bundlecontrolpoint = m_statisticsResults->bundleControlPoints().at(i);
1645
1646 if (!bundlecontrolpoint) {
1647 continue;
1648 }
1649
1650 if (bundlecontrolpoint->isRejected()) {
1651 continue;
1652 }
1653
1654 dLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatitude().degrees();
1655 dLon = bundlecontrolpoint->adjustedSurfacePoint().GetLongitude().degrees();
1656 dRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadius().kilometers();
1657 dX = bundlecontrolpoint->adjustedSurfacePoint().GetX().kilometers();
1658 dY = bundlecontrolpoint->adjustedSurfacePoint().GetY().kilometers();
1659 dZ = bundlecontrolpoint->adjustedSurfacePoint().GetZ().kilometers();
1660 numMeasures = bundlecontrolpoint->numberOfMeasures();
1661 numRejectedMeasures = bundlecontrolpoint->numberOfRejectedMeasures();
1662 dResidualRms = bundlecontrolpoint->residualRms();
1663
1664 // Use the local radius in meters, rad*1000., to convert radians to meters now instead of the
1665 // target body equatorial radius (DAC 09/17/2018; from BundleControlPoint.cpp)
1666 double rtm = dRadius * 1000.;
1667
1668 // point corrections and initial sigmas
1669 boost::numeric::ublas::bounded_vector< double, 3 > corrections = bundlecontrolpoint->
1670 corrections();
1671
1672 if (m_settings->controlPointCoordTypeBundle() == SurfacePoint::Rectangular) {
1673 double xCor = corrections(0); // km
1674 double yCor = corrections(1); // km
1675 double zCor = corrections(2); // km
1676
1677 if (!IsSpecial(dX) && !IsSpecial(dY) && !IsSpecial(dZ)) {
1681
1682 latInit = rectPoint.GetLatitude().degrees();
1683 lonInit = rectPoint.GetLongitude().degrees();
1684 radInit = rectPoint.GetLocalRadius().kilometers();
1685
1686 if (!IsSpecial(dLat)) {
1687 cor_lat_dd = (dLat - latInit); // degrees
1688 cor_lat_m = cor_lat_dd * DEG2RAD * rtm;
1689 }
1690 if (!IsSpecial(dLon)) {
1691 cor_lon_dd = (dLon - lonInit); // degrees
1692 cor_lon_m = cor_lon_dd * DEG2RAD * rtm * cos(dLat*DEG2RAD); // lon corrections meters
1693 }
1694 if (!IsSpecial(dRadius)) {
1695 cor_rad_km = dRadius - radInit;
1696 cor_rad_m = cor_rad_km * 1000.;
1697 }
1698 }
1699 }
1700 else if (m_settings->controlPointCoordTypeBundle() == SurfacePoint::Latitudinal) {
1701 cor_lat_dd = corrections(0) * RAD2DEG; // lat correction, decimal degs
1702 cor_lon_dd = corrections(1) * RAD2DEG; // lon correction, decimal degs
1703 cor_rad_m = corrections(2) * 1000.0; // radius correction, meters
1704
1705 cor_lat_m = bundlecontrolpoint->adjustedSurfacePoint().LatitudeToMeters(corrections(0));
1706 cor_lon_m = bundlecontrolpoint->adjustedSurfacePoint().LongitudeToMeters(corrections(1));
1707 cor_rad_km = corrections(2);
1708
1709 if (!IsSpecial(dLat)) {
1710 latInit = dLat - cor_lat_dd;
1711 }
1712
1713 if (!IsSpecial(dLon)) {
1714 lonInit = dLon - cor_lon_dd;
1715 }
1716
1717 if (!IsSpecial(dRadius)) {
1718 radInit = dRadius - corrections(2); // km
1719 }
1720 }
1721
1722 if (bundlecontrolpoint->type() == ControlPoint::Fixed) {
1723 strStatus = "FIXED";
1724 }
1725 else if (bundlecontrolpoint->type() == ControlPoint::Constrained) {
1726 strStatus = "CONSTRAINED";
1727 }
1728 else if (bundlecontrolpoint->type() == ControlPoint::Free) {
1729 strStatus = "FREE";
1730 }
1731 else {
1732 strStatus = "UNKNOWN";
1733 }
1734
1735 if (m_settings->errorPropagation()) {
1736 dSigmaLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatSigmaDistance().meters();
1737 dSigmaLong = bundlecontrolpoint->adjustedSurfacePoint().GetLonSigmaDistance().meters();
1738 dSigmaRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadiusSigma().meters();
1739
1740 snprintf(buf, sizeof(buf), "%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
1741 "%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf\n",
1742 bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
1743 numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, dSigmaLat,
1744 dSigmaLong, dSigmaRadius, cor_lat_m, cor_lon_m, cor_rad_m, dX, dY, dZ);
1745 }
1746 else
1747 snprintf(buf, sizeof(buf), "%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
1748 "%16.8lf,%16.8lf\n",
1749 bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
1750 numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, cor_lat_m,
1751 cor_lon_m, cor_rad_m, dX, dY, dZ);
1752
1753 fpOut << buf;
1754 }
1755
1756 fpOut.close();
1757
1758 return true;
1759 }
1760
1761
1768 char buf[1056];
1769
1770 QString ofname = "bundleout_lidar.csv";
1771 ofname = m_settings->outputFilePrefix() + ofname;
1772 m_csvSavedPointsFilename = ofname;
1773
1774 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1775 if (!fpOut) {
1776 return false;
1777 }
1778
1779 int numPoints = m_statisticsResults->bundleLidarControlPoints().size();
1780
1781 // measured apriori adjusted adjusted
1782 // range sigma range residual sigma
1783 // point id image (km) (km) (km) (km) (km)
1784
1785 // print column headers
1786 if (m_settings->errorPropagation()) {
1787 snprintf(buf, sizeof(buf), ",,measured,a priori,adjusted,adjusted\n"
1788 "point,image,range,sigma,range,sigma,residual\n"
1789 "id,name,(km),(km),(km),(km),(km)\n");
1790 }
1791 else {
1792 snprintf(buf, sizeof(buf), ",,measured,a priori,adjusted\n"
1793 "point,image,range,sigma,range,residual\n"
1794 "id,name,(km),(km),(km),(km)\n");
1795 }
1796 fpOut << buf;
1797
1798 for (int i = 0; i < numPoints; i++) {
1799
1800 BundleLidarControlPointQsp point = m_statisticsResults->bundleLidarControlPoints().at(i);
1801 if (!point || point->isRejected()) {
1802 continue;
1803 }
1804
1805 int nRangeConstraints = point->numberRangeConstraints();
1806 for (int j = 0; j < nRangeConstraints; j++) {
1807 BundleLidarRangeConstraintQsp rangeConstraint = point->rangeConstraint(j);
1808
1809 QString str = rangeConstraint->formatBundleOutputString(m_settings->errorPropagation());
1810 fpOut << str;
1811 }
1812 }
1813
1814 fpOut.close();
1815
1816 return true;
1817 }
1818
1819
1826 char buf[1056];
1827
1828 QString ofname = "residuals.csv";
1829 ofname = m_settings->outputFilePrefix() + ofname;
1830 m_csvSavedResidualsFilename = ofname;
1831
1832 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1833 if (!fpOut) {
1834 return false;
1835 }
1836
1837 // output column headers
1838
1839 snprintf(buf, sizeof(buf), ",,,x image,y image,Measured,Measured,sample,line,Residual Vector\n");
1840 fpOut << buf;
1841 snprintf(buf, sizeof(buf), "Point,Image,Image,coordinate,coordinate,"
1842 "Sample,Line,residual,residual,Magnitude\n");
1843 fpOut << buf;
1844 snprintf(buf, sizeof(buf), "Label,Filename,Serial Number,(mm),(mm),"
1845 "(pixels),(pixels),(pixels),(pixels),(pixels),Rejected\n");
1846 fpOut << buf;
1847
1848 // Setup counts and pointers
1849
1850 int numPoints = m_statisticsResults->bundleControlPoints().size();
1851 int numMeasures = 0;
1852
1853 BundleControlPointQsp bundleControlPoint;
1854 BundleMeasureQsp bundleMeasure;
1855
1856 for (int i = 0; i < numPoints; i++) {
1857 bundleControlPoint = m_statisticsResults->bundleControlPoints().at(i);
1858 numMeasures = bundleControlPoint->size();
1859
1860 if (bundleControlPoint->rawControlPoint()->IsIgnored()) {
1861 continue;
1862 }
1863
1864 for (int j = 0; j < numMeasures; j++) {
1865 bundleMeasure = bundleControlPoint->at(j);
1866
1867 Camera *measureCamera = bundleMeasure->camera();
1868 if (!measureCamera) {
1869 continue;
1870 }
1871
1872 if (bundleMeasure->isRejected()) {
1873 snprintf(buf, sizeof(buf), "%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,*\n",
1874 bundleControlPoint->id().toLatin1().data(),
1875 bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1876 bundleMeasure->cubeSerialNumber().toLatin1().data(),
1877 bundleMeasure->focalPlaneMeasuredX(),
1878 bundleMeasure->focalPlaneMeasuredY(),
1879 bundleMeasure->sample(),
1880 bundleMeasure->line(),
1881 bundleMeasure->sampleResidual(),
1882 bundleMeasure->lineResidual(),
1883 bundleMeasure->residualMagnitude());
1884 }
1885 else {
1886 snprintf(buf, sizeof(buf), "%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf\n",
1887 bundleControlPoint->id().toLatin1().data(),
1888 bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1889 bundleMeasure->cubeSerialNumber().toLatin1().data(),
1890 bundleMeasure->focalPlaneMeasuredX(),
1891 bundleMeasure->focalPlaneMeasuredY(),
1892 bundleMeasure->sample(),
1893 bundleMeasure->line(),
1894 bundleMeasure->sampleResidual(),
1895 bundleMeasure->lineResidual(),
1896 bundleMeasure->residualMagnitude());
1897 }
1898 fpOut << buf;
1899 }
1900 }
1901
1902 numPoints = m_statisticsResults->bundleLidarControlPoints().size();
1903 numMeasures = 0;
1904
1905 BundleLidarControlPointQsp bundleLidarPoint;
1906
1907 for (int i = 0; i < numPoints; i++) {
1908 bundleLidarPoint = m_statisticsResults->bundleLidarControlPoints().at(i);
1909 numMeasures = bundleLidarPoint->size();
1910
1911 if (bundleLidarPoint->rawControlPoint()->IsIgnored()) {
1912 continue;
1913 }
1914
1915 for (int j = 0; j < numMeasures; j++) {
1916 bundleMeasure = bundleLidarPoint->at(j);
1917
1918 Camera *measureCamera = bundleMeasure->camera();
1919 if (!measureCamera) {
1920 continue;
1921 }
1922
1923 if (bundleMeasure->isRejected()) {
1924 snprintf(buf, sizeof(buf), "%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,*\n",
1925 bundleLidarPoint->id().toLatin1().data(),
1926 bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1927 bundleMeasure->cubeSerialNumber().toLatin1().data(),
1928 bundleMeasure->focalPlaneMeasuredX(),
1929 bundleMeasure->focalPlaneMeasuredY(),
1930 bundleMeasure->sample(),
1931 bundleMeasure->line(),
1932 bundleMeasure->sampleResidual(),
1933 bundleMeasure->lineResidual(),
1934 bundleMeasure->residualMagnitude());
1935 }
1936 else {
1937 snprintf(buf, sizeof(buf), "%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf\n",
1938 bundleLidarPoint->id().toLatin1().data(),
1939 bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1940 bundleMeasure->cubeSerialNumber().toLatin1().data(),
1941 bundleMeasure->focalPlaneMeasuredX(),
1942 bundleMeasure->focalPlaneMeasuredY(),
1943 bundleMeasure->sample(),
1944 bundleMeasure->line(),
1945 bundleMeasure->sampleResidual(),
1946 bundleMeasure->lineResidual(),
1947 bundleMeasure->residualMagnitude());
1948 }
1949 fpOut << buf;
1950 }
1951 }
1952
1953 fpOut.close();
1954
1955 return true;
1956 }
1957
1958
1975 void BundleSolutionInfo::save(QXmlStreamWriter &stream, const Project *project,
1976 FileName newProjectRoot) const {
1977
1978 // This is done for testing serialization without a Project
1979 QString relativePath;
1980 QString relativeBundlePath;
1981 FileName bundleSolutionInfoRoot;
1982
1983 if (project) {
1984 bundleSolutionInfoRoot = FileName(Project::bundleSolutionInfoRoot(newProjectRoot.expanded()) +
1985 "/" + runTime());
1986 QString oldPath = project->bundleSolutionInfoRoot(project->projectRoot()) + "/" + runTime();
1987 QString newPath = project->bundleSolutionInfoRoot(newProjectRoot.toString()) + "/" + runTime();
1988 // If project is being saved to new area, create directory and copy files
1989 if (oldPath != newPath) {
1990 // Create project folder for BundleSolutionInfo
1991 QDir bundleDir(newPath);
1992 if (!bundleDir.mkpath(bundleDir.path())) {
1994 QString("Failed to create directory [%1]")
1995 .arg(bundleSolutionInfoRoot.path()),
1996 _FILEINFO_);
1997 }
1998 QString oldFile = oldPath + "/" + FileName(m_outputControl->fileName()).name();
1999 QString newFile = newPath + "/" + FileName(m_outputControl->fileName()).name();
2000 if (!QFile::copy(oldFile, newFile)) {
2002 QString("Failed to copy file [%1] to new file [%2]")
2003 .arg(m_outputControl->fileName()).arg(newFile),
2004 _FILEINFO_);
2005 }
2006 newFile = newPath + "/" + FileName(m_txtBundleOutputFilename).name();
2007 if (!QFile::copy(m_txtBundleOutputFilename, newFile)) {
2009 QString("Failed to copy file [%1] to new file [%2]")
2010 .arg(m_txtBundleOutputFilename).arg(newFile),
2011 _FILEINFO_);
2012 }
2013 newFile = newPath + "/" + FileName(m_csvSavedImagesFilename).name();
2014 if (!QFile::copy(m_csvSavedImagesFilename, newFile)) {
2016 QString("Failed to copy file [%1] to new file [%2]")
2017 .arg(m_csvSavedImagesFilename).arg(newFile),
2018 _FILEINFO_);
2019 }
2020 newFile = newPath + "/" + FileName(m_csvSavedPointsFilename).name();
2021 if (!QFile::copy(m_csvSavedPointsFilename, newFile)) {
2023 QString("Failed to copy file [%1] to new file [%2]")
2024 .arg(m_csvSavedPointsFilename).arg(newFile),
2025 _FILEINFO_);
2026 }
2027 newFile = newPath + "/" + FileName(m_csvSavedResidualsFilename).name();
2028 if (!QFile::copy(m_csvSavedResidualsFilename, newFile)) {
2030 QString("Failed to copy file [%1] to new file [%2]")
2031 .arg(m_csvSavedResidualsFilename).arg(newFile),
2032 _FILEINFO_);
2033 }
2034 }
2035
2036 // Create relativePath
2037 relativePath = m_inputControlNetFileName->expanded().remove(project->newProjectRoot());
2038 // Get rid of any preceding "/" , but add on ending "/"
2039 if (relativePath.startsWith("/")) {
2040 relativePath.remove(0,1);
2041 }
2042
2043 // Create relativeBundlePath for bundleSolutionInfo
2044 relativeBundlePath = newPath.remove(project->newProjectRoot());
2045 // Get rid of any preceding "/" , but add on ending "/"
2046 if (relativeBundlePath.startsWith("/")) {
2047 relativeBundlePath.remove(0,1);
2048 }
2049 relativeBundlePath += "/";
2050 }
2051
2052 stream.writeStartElement("bundleSolutionInfo");
2053 // save ID, cnet file name, and run time to stream
2054 stream.writeStartElement("generalAttributes");
2055 stream.writeTextElement("id", m_id->toString());
2056 stream.writeTextElement("name", m_name);
2057 stream.writeTextElement("runTime", runTime());
2058
2059 stream.writeTextElement("inputFileName",
2060 relativePath);
2061 stream.writeTextElement("bundleOutTXT",
2062 relativeBundlePath + FileName(m_txtBundleOutputFilename).name());
2063 stream.writeTextElement("imagesCSV",
2064 relativeBundlePath + FileName(m_csvSavedImagesFilename).name());
2065 stream.writeTextElement("pointsCSV",
2066 relativeBundlePath + FileName(m_csvSavedPointsFilename).name());
2067 stream.writeTextElement("residualsCSV",
2068 relativeBundlePath + FileName(m_csvSavedResidualsFilename).name());
2069 stream.writeEndElement(); // end general attributes
2070
2071 // save settings to stream
2072 m_settings->save(stream, project);
2073
2074 // save statistics to stream
2075 m_statisticsResults->save(stream, project);
2076
2077 if (project) {
2078 // save adjusted images lists to stream
2079 if (!m_adjustedImages->isEmpty()) {
2080 stream.writeStartElement("imageLists");
2081 for (int i = 0; i < m_adjustedImages->count(); i++) {
2082 m_adjustedImages->at(i)->save(stream, project, bundleSolutionInfoRoot);
2083 }
2084 stream.writeEndElement();
2085 }
2086
2087 // save output control
2088 stream.writeStartElement("outputControl");
2089 m_outputControl->save(stream, project, relativeBundlePath);
2090 stream.writeEndElement();
2091 }
2092
2093 stream.writeEndElement(); //end bundleSolutionInfo
2094 }
2095
2096
2106 SurfacePoint::CoordIndex coordIdx) const {
2107 QString coordName;
2108 switch (m_settings->controlPointCoordTypeReports()) {
2110 switch (coordIdx) {
2111 case SurfacePoint::One:
2112 coordName = " Latitude";
2113 break;
2114 case SurfacePoint::Two:
2115 coordName = "Longitude";
2116 break;
2117 case SurfacePoint::Three:
2118 coordName = " Radius";
2119 break;
2120 default:
2121 IString msg = "Unknown surface point index enum ["
2122 + toString(coordIdx) + "].";
2123 throw IException(IException::Programmer, msg, _FILEINFO_);
2124 break;
2125 }
2126 break;
2128 switch (coordIdx) {
2129 case SurfacePoint::One:
2130 coordName = "POINT X";
2131 break;
2132 case SurfacePoint::Two:
2133 coordName = "POINT Y";
2134 break;
2135 case SurfacePoint::Three:
2136 coordName = "POINT Z";
2137 break;
2138 default:
2139 IString msg = "Unknown surface point index enum ["
2140 + toString(coordIdx) + "].";
2141 throw IException(IException::Programmer, msg, _FILEINFO_);
2142 break;
2143 }
2144 break;
2145 default:
2146 IString msg = "Unknown surface point coordinate type enum ["
2147 + toString(m_settings->controlPointCoordTypeReports()) + "].";
2148 throw IException(IException::Programmer, msg, _FILEINFO_);
2149 break;
2150 }
2151 return coordName;
2152 }
2153}
double degrees() const
Get the angle in units of Degrees.
Definition Angle.h:232
This class is used to modify and manage solve settings for 1 to many BundleObservations.
bool solveTwist() const
Accesses the flag for solving for twist.
bool solvePolyOverPointing() const
Whether or not the solve polynomial will be fit over the existing pointing polynomial.
int numberCameraPositionCoefficientsSolved() const
Accesses the number of camera position coefficients in the solution.
int ckDegree() const
Accesses the degree of polynomial fit to original camera angles (ckDegree).
QList< double > aprioriPositionSigmas() const
Accesses the a priori position sigmas.
QList< double > aprioriPointingSigmas() const
Accesses the a priori pointing sigmas.
int ckSolveDegree() const
Accesses the degree of the camera angles polynomial being fit to in the bundle adjustment (ckSolveDeg...
bool solvePositionOverHermite() const
Whether or not the polynomial for solving will be fit over an existing Hermite spline.
int numberCameraAngleCoefficientsSolved() const
Accesses the number of camera angle coefficients in the solution.
int spkSolveDegree() const
Accesses the degree of thecamera position polynomial being fit to in the bundle adjustment (spkSolveD...
int spkDegree() const
Accesses the degree of the polynomial fit to the original camera position (spkDegree).
A container class for statistical results from a BundleAdjust solution.
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.
BundleSolutionInfo(BundleSettingsQsp inputSettings, FileName controlNetworkFileName, BundleResults outputStatistics, QList< ImageList * > imgList, QObject *parent=0)
Constructor.
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
@ 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.
Displacement is a signed length, usually in meters.
@ Kilometers
The distance is being specified in kilometers.
double kilometers() const
Get the distance in kilometers.
Definition Distance.cpp:106
File name manipulation and expansion.
Definition FileName.h:100
QString path() const
Returns the path of the file name.
Definition FileName.cpp:103
QDir dir() const
Returns the path of the file's parent directory as a QDir object.
Definition FileName.cpp:465
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.
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
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
This class is used to accumulate statistics on double arrays.
Definition Statistics.h:93
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
double Rms() const
Computes and returns the rms.
This class defines a body-fixed surface point.
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.
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
Distance GetLocalRadius() const
Return the radius of the surface point.
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.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QSharedPointer< LidarData > LidarDataQsp
Definition for a shared pointer to a LidarData object.
Definition LidarData.h:100
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
QSharedPointer< BundleLidarControlPoint > BundleLidarControlPointQsp
QSharedPointer to a BundleLidarControlPoint.
QSharedPointer< BundleSettings > BundleSettingsQsp
Definition for a BundleSettingsQsp, a shared pointer to a BundleSettings object.
QSharedPointer< BundleLidarRangeConstraint > BundleLidarRangeConstraintQsp
Typdef for BundleLidarRangeConstraint QSharedPointer.
QSharedPointer< BundleObservation > BundleObservationQsp
Typdef for BundleObservation QSharedPointer.
const double DEG2RAD
Multiplier for converting from degrees to radians.
Definition Constants.h:43
const double Null
Value for an Isis Null pixel.
QSharedPointer< BundleControlPoint > BundleControlPointQsp
Definition for BundleControlPointQSP, a shared pointer to a BundleControlPoint.
bool IsSpecial(const double d)
Returns if the input pixel is special.
const double RAD2DEG
Multiplier for converting from radians to degrees.
Definition Constants.h:44
QSharedPointer< BundleMeasure > BundleMeasureQsp
Definition for BundleMeasureQsp, a shared pointer to a BundleMeasure.