Isis 3 Programmer Reference
BundleSolutionInfo.cpp
1 #include "BundleSolutionInfo.h"
2 
3 #include <QDataStream>
4 #include <QDebug>
5 #include <QFile>
6 #include <QList>
7 #include <QString>
8 #include <QStringList>
9 #include <QUuid>
10 #include <QXmlStreamWriter>
11 
12 #include "BundleResults.h"
13 #include "Control.h"
14 #include "ControlList.h"
15 #include "ControlMeasure.h"
16 #include "ControlNet.h"
17 #include "ControlPoint.h"
18 #include "FileName.h"
19 #include "ImageList.h"
20 #include "IString.h"
21 #include "iTime.h"
22 #include "Project.h"
23 #include "PvlKeyword.h"
24 #include "PvlObject.h"
25 #include "StatCumProbDistDynCalc.h"
26 #include "Statistics.h"
27 #include "XmlStackedHandlerReader.h"
28 
29 namespace Isis {
30 
39  BundleSolutionInfo::BundleSolutionInfo(BundleSettingsQsp inputSettings,
40  FileName controlNetworkFileName,
41  BundleResults outputStatistics,
42  QList<ImageList *> imgList,
43  QObject *parent) : QObject(parent) {
44  m_id = new QUuid(QUuid::createUuid());
45  m_runTime = "";
46  m_name = m_runTime;
47  m_inputControlNetFileName = new FileName(controlNetworkFileName);
48  m_outputControl = NULL;
49  m_outputControlName="";
50  m_settings = inputSettings;
51  m_statisticsResults = new BundleResults(outputStatistics);
52  m_images = new QList<ImageList *>(imgList);
54  }
55 
56 
64  BundleSolutionInfo::BundleSolutionInfo(Project *project,
65  XmlStackedHandlerReader *xmlReader,
66  QObject *parent) : QObject(parent) {
67  //TODO does xml stuff need project???
68  m_id = new QUuid(QUuid::createUuid());
69  m_runTime = "";
70  m_name = m_runTime;
72  m_outputControl = NULL;
73  m_outputControlName="";
74  m_statisticsResults = NULL;
75  // what about the rest of the member data ? should we set defaults ??? CREATE INITIALIZE METHOD
78 
79  xmlReader->setErrorHandler(new XmlHandler(this, project));
80  xmlReader->pushContentHandler(new XmlHandler(this, project));
81  }
82 
83 
88  delete m_id;
89 
92 
93  delete m_outputControl;
94  m_outputControl = NULL;
95 
96  delete m_statisticsResults;
97  m_statisticsResults = NULL;
98 
99  if (m_images != NULL) {
100  delete m_images;
101  m_images = NULL;
102  }
103 
104  // if (m_adjustedImages != NULL) {
105  // qDeleteAll(*m_adjustedImages);
106  // m_adjustedImages->clear();
107  // delete m_adjustedImages;
108  // m_adjustedImages = NULL;
109  // }
110  }
111 
112 
119  return m_txtBundleOutputFilename;
120  }
121 
122 
129  return m_csvSavedImagesFilename;
130  }
131 
132 
139  return m_csvSavedPointsFilename;
140  }
141 
142 
149  return m_csvSavedResidualsFilename;
150  }
151 
152 
159  m_adjustedImages->append(images);
160  }
161 
162 
169  delete m_statisticsResults;
170  m_statisticsResults = NULL;
171  m_statisticsResults = new BundleResults(statisticsResults);
172  }
173 
174 
188 
189  //TODO do we need to close anything here?
190 
191  FileName oldInputFileName(*m_inputControlNetFileName);
192  FileName newInputFileName(project->cnetRoot() + "/" +
193  oldInputFileName.dir().dirName() + "/" + oldInputFileName.name());
194  *m_inputControlNetFileName = newInputFileName.expanded();
195 
196  FileName oldOutputFileName(m_outputControl->fileName());
197  FileName newOutputFileName(project->cnetRoot() + "/" +
198  oldOutputFileName.dir().dirName() + "/" + oldOutputFileName.name());
199 
200  if (m_outputControl) {
201  delete m_outputControl;
202  }
203  m_outputControl = new Control(newOutputFileName.expanded());
204  m_outputControlName = newOutputFileName.expanded();
205  }
206 
207 
215  return *m_adjustedImages;
216  }
217 
218 
224  QString BundleSolutionInfo::id() const {
225  return m_id->toString().remove(QRegExp("[{}]"));
226  }
227 
228 
234  void BundleSolutionInfo::setRunTime(QString runTime) {
235  // ??? validate that a valid time has been given???
236  // try {
237  // iTime time(runTime);
238  // }
239  // catch (...) {
240  // throw IException(IException::Unknown,
241  // "Invalid bundle adjustment run time [" + runTime + ].",
242  // _FILEINFO_);
243  // }
244  m_runTime = runTime;
245  if (m_name == m_runTime || m_name == "") {
246  m_name = runTime;
247  }
248  }
249 
250 
256  QString BundleSolutionInfo::runTime() const {
257  return m_runTime;
258  }
259 
260 
268  }
269 
270 
277 
278  if (m_outputControl)
279  return m_outputControl->fileName();
280  else
281  return m_outputControlName;
282  }
283 
284 
291  m_outputControl = outputControl;
292  }
293 
294 
301  m_outputControlName = name;
302  }
303 
304 
311  return m_outputControlName;
312  }
313 
320  return m_outputControl;
321  }
322 
323 
330  return m_settings;
331  }
332 
333 
342  if (m_statisticsResults) {
343  return *m_statisticsResults;
344  }
345  else {
347  "Results for this bundle is NULL.",
348  _FILEINFO_);
349  }
350  }
351 
352 
359  return *m_images;
360  }
361 
362 
368  void BundleSolutionInfo::setName(QString name) {
369  m_name = name;
370  }
371 
372 
379  QString BundleSolutionInfo::name() const {
380  return m_name;
381  }
382 
383 
394  bool BundleSolutionInfo::outputImagesCSVHeader(std::ofstream &fpOut) {
395 
396  if (!fpOut) {
397  return false;
398  }
399 
400  char buf[1056];
401 
402  // setup column headers
403  std::vector<QString> outputColumns;
404 
405  outputColumns.push_back("Image,");
406  outputColumns.push_back("rms,");
407  outputColumns.push_back("rms,");
408  outputColumns.push_back("rms,");
409 
410  BundleObservationSolveSettings obsSettings = m_settings->observationSolveSettings(0);
411 
412  int numberCamPosCoefSolved = obsSettings.numberCameraPositionCoefficientsSolved();
413  int numberCamAngleCoefSolved = obsSettings.numberCameraAngleCoefficientsSolved();
414 
415  int nCoeff = 1;
416  if (numberCamPosCoefSolved > 0)
417  nCoeff = numberCamPosCoefSolved;
418 
419  for (int i = 0; i < nCoeff; i++) {
420  for (int j = 0; j < 5; j++) {
421  if (nCoeff == 1)
422  outputColumns.push_back("X,");
423  else {
424  QString str = "X(t" + toString(i) + "),";
425  outputColumns.push_back(str);
426  }
427  }
428  }
429  for (int i = 0; i < nCoeff; i++) {
430  for (int j = 0; j < 5; j++) {
431  if (nCoeff == 1)
432  outputColumns.push_back("Y,");
433  else {
434  QString str = "Y(t" + toString(i) + "),";
435  outputColumns.push_back(str);
436  }
437  }
438  }
439  for (int i = 0; i < nCoeff; i++) {
440  for (int j = 0; j < 5; j++) {
441  if (nCoeff == 1) {
442  outputColumns.push_back("Z,");
443  }
444  else {
445  QString str = "Z(t" + toString(i) + "),";
446  outputColumns.push_back(str);
447  }
448  }
449  if (!i)
450  break;
451  }
452 
453  for (int i = 0; i < numberCamAngleCoefSolved; i++) {
454  for (int j = 0; j < 5; j++) {
455  if (numberCamAngleCoefSolved == 1)
456  outputColumns.push_back("RA,");
457  else {
458  QString str = "RA(t" + toString(i) + "),";
459  outputColumns.push_back(str);
460  }
461  }
462  }
463  for (int i = 0; i < numberCamAngleCoefSolved; i++) {
464  for (int j = 0; j < 5; j++) {
465  if (numberCamAngleCoefSolved == 1)
466  outputColumns.push_back("DEC,");
467  else {
468  QString str = "DEC(t" + toString(i) + "),";
469  outputColumns.push_back(str);
470  }
471  }
472  }
473  for (int i = 0; i < numberCamAngleCoefSolved; i++) {
474  for (int j = 0; j < 5; j++) {
475  if (numberCamAngleCoefSolved == 1) {
476  outputColumns.push_back("TWIST,");
477  }
478  else {
479  QString str = "TWIST(t" + toString(i) + "),";
480  outputColumns.push_back(str);
481  }
482  }
483  }
484 
485  // print first column header to buffer and output to file
486  int ncolumns = outputColumns.size();
487  for (int i = 0; i < ncolumns; i++) {
488  QString str = outputColumns.at(i);
489  sprintf(buf, "%s", (const char*)str.toLatin1().data());
490  fpOut << buf;
491  }
492  sprintf(buf, "\n");
493  fpOut << buf;
494 
495  outputColumns.clear();
496  outputColumns.push_back("Filename,");
497 
498  outputColumns.push_back("sample res,");
499  outputColumns.push_back("line res,");
500  outputColumns.push_back("total res,");
501 
502  // Initially account for X,Y,Z (3)
503  int nparams = 3;
504  // See how many position coeffients we solved for to make more headers (t0, t1, ...)
505  if (numberCamPosCoefSolved)
506  nparams = 3 * numberCamPosCoefSolved;
507 
508  // Initially account for RA,DEC,TWIST (3)
509  int numCameraAnglesSolved = 3;
510  // See how many angle coefficients we solved for to make more headers (t0, t1, ...)
511  nparams += numCameraAnglesSolved*numberCamAngleCoefSolved;
512  for (int i = 0; i < nparams; i++) {
513  outputColumns.push_back("Initial,");
514  outputColumns.push_back("Correction,");
515  outputColumns.push_back("Final,");
516  outputColumns.push_back("Apriori Sigma,");
517  outputColumns.push_back("Adj Sigma,");
518  }
519 
520  // print second column header to buffer and output to file
521  ncolumns = outputColumns.size();
522  for (int i = 0; i < ncolumns; i++) {
523  QString str = outputColumns.at(i);
524  sprintf(buf, "%s", (const char*)str.toLatin1().data());
525  fpOut << buf;
526  }
527  sprintf(buf, "\n");
528  fpOut << buf;
529 
530  return true;
531  }
532 
533 
534 
547  bool BundleSolutionInfo::outputHeader(std::ofstream &fpOut) {
548 
549  if (!fpOut) {
550  return false;
551  }
552 
553  char buf[1056];
554  int numObservations = m_statisticsResults->observations().size();
555  int numImages = 0;
556  for (int i = 0; i < numObservations; i++) {
557  numImages += m_statisticsResults->observations().at(i)->size();
558  }
559  int numValidPoints = m_statisticsResults->outputControlNet()->GetNumValidPoints();
560  int numInnerConstraints = 0;
561  int numDistanceConstraints = 0;
562  int numDegreesOfFreedom = m_statisticsResults->numberObservations()
567 
568  int convergenceCriteria = 1;
569 
570  sprintf(buf, "JIGSAW: BUNDLE ADJUSTMENT\n=========================\n");
571  fpOut << buf;
572  sprintf(buf, "\n Run Time: %s",
573  Isis::iTime::CurrentLocalTime().toLatin1().data());
574  fpOut << buf;
575  sprintf(buf, "\n Network Filename: %s",
576  m_inputControlNetFileName->expanded().toLatin1().data());
577  fpOut << buf;
578 
579  sprintf(buf,"\n Cube List: %s",
580  m_settings->cubeList().toStdString().c_str() );
581 
582  fpOut << buf;
583 
584  sprintf(buf, "\n Output Network Filename: %s",
585  outputControlName().toStdString().c_str() );
586  fpOut << buf;
587  sprintf(buf,"\n Output File Prefix: %s",
588  m_settings->outputFilePrefix().toStdString().c_str() );
589  fpOut <<buf;
590 
591  sprintf(buf, "\n Network Id: %s",
592  m_statisticsResults->outputControlNet()->GetNetworkId().toLatin1().data());
593  fpOut << buf;
594  sprintf(buf, "\n Network Description: %s",\
595  m_statisticsResults->outputControlNet()->Description().toLatin1().data());
596  fpOut << buf;
597  sprintf(buf, "\n Target: %s",
598  m_statisticsResults->outputControlNet()->GetTarget().toLatin1().data());
599  fpOut << buf;
600  sprintf(buf, "\n\n Linear Units: kilometers");
601  fpOut << buf;
602  sprintf(buf, "\n Angular Units: decimal degrees");
603  fpOut << buf;
604  sprintf(buf, "\n\nINPUT: SOLVE OPTIONS\n====================\n");
605  fpOut << buf;
606 
607  m_settings->solveObservationMode() ?
608  sprintf(buf, "\n OBSERVATIONS: ON"):
609  sprintf(buf, "\n OBSERVATIONS: OFF");
610  fpOut << buf;
611 
612  m_settings->solveRadius() ?
613  sprintf(buf, "\n RADIUS: ON"):
614  sprintf(buf, "\n RADIUS: OFF");
615  fpOut << buf;
616 
617  m_settings->solveTargetBody() ?
618  sprintf(buf, "\n TARGET BODY: ON"):
619  sprintf(buf, "\n TARGET BODY: OFF");
620  fpOut << buf;
621 
622  m_settings->updateCubeLabel() ?
623  sprintf(buf, "\n UPDATE: YES"):
624  sprintf(buf, "\n UPDATE: NO");
625  fpOut << buf;
626 
627  m_settings->errorPropagation() ?
628  sprintf(buf, "\n ERROR PROPAGATION: ON"):
629  sprintf(buf, "\n ERROR PROPAGATION: OFF");
630  fpOut << buf;
631 
632  (m_settings->controlPointCoordTypeReports() == SurfacePoint::Latitudinal) ?
633  sprintf(buf, "\n CONTROL POINT COORDINATE TYPE FOR REPORTS: LATITUDINAL"):
634  sprintf(buf, "\n CONTROL POINT COORDINATE TYPE FOR REPORTS: RECTANGULAR");
635  fpOut << buf;
636 
637  (m_settings->controlPointCoordTypeBundle() == SurfacePoint::Latitudinal) ?
638  sprintf(buf, "\n CONTROL POINT COORDINATE TYPE FOR BUNDLE: LATITUDINAL"):
639  sprintf(buf, "\n CONTROL POINT COORDINATE TYPE FOR BUNDLE: RECTANGULAR");
640  fpOut << buf;
641 
642  if (m_settings->outlierRejection()) {
643  sprintf(buf, "\n OUTLIER REJECTION: ON");
644  fpOut << buf;
645  sprintf(buf, "\n REJECTION MULTIPLIER: %lf",
646  m_settings->outlierRejectionMultiplier());
647  fpOut << buf;
648 
649  }
650  else {
651  sprintf(buf, "\n OUTLIER REJECTION: OFF");
652  fpOut << buf;
653  sprintf(buf, "\n REJECTION MULTIPLIER: N/A");
654  fpOut << buf;
655  }
656 
657  // Added April 5, 2017
658  sprintf(buf, "\n CONTROL POINT COORDINATE TYPE FOR REPORTS: %s",
659  SurfacePoint::coordinateTypeToString(m_settings->controlPointCoordTypeReports()).toLatin1().data());
660 
661  // Added July 4, 2017
662  sprintf(buf, "\n CONTROL POINT COORDINATE TYPE FOR BUNDLE: %s",
663  SurfacePoint::coordinateTypeToString(m_settings->controlPointCoordTypeBundle()).toLatin1().data());
664 
665  sprintf(buf, "\n\nMAXIMUM LIKELIHOOD ESTIMATION\n============================\n");
666  fpOut << buf;
667 
668  for (int tier = 0; tier < 3; tier++) {
669  if (tier < m_statisticsResults->numberMaximumLikelihoodModels()) {
670  sprintf(buf, "\n Tier %d Enabled: TRUE", tier);
671  fpOut << buf;
672  sprintf(buf, "\n Maximum Likelihood Model: %s",
675  maximumLikelihoodModelWFunc(tier).model()).toLatin1().data());
676  fpOut << buf;
677  sprintf(buf, "\n Quantile used for tweaking constant: %lf",
679  fpOut << buf;
680  sprintf(buf, "\n Quantile weighted R^2 Residual value: %lf",
682  fpOut << buf;
683  sprintf(buf, "\n Approx. weighted Residual cutoff: %s",
685  .weightedResidualCutoff().toLatin1().data());
686  fpOut << buf;
687  if (tier != 2) fpOut << "\n";
688  }
689  else {
690  sprintf(buf, "\n Tier %d Enabled: FALSE", tier);
691  fpOut << buf;
692  }
693  }
694 
695  sprintf(buf, "\n\nINPUT: CONVERGENCE CRITERIA\n===========================\n");
696  fpOut << buf;
697  sprintf(buf, "\n SIGMA0: %e",
698  m_settings->convergenceCriteriaThreshold());
699  fpOut << buf;
700  sprintf(buf, "\n MAXIMUM ITERATIONS: %d",
701  m_settings->convergenceCriteriaMaximumIterations());
702  fpOut << buf;
703 
704  //TODO Should it be checked that positionSigmas.size() == positionSolveDegree and
705  // pointingSigmas.size() == pointingSolveDegree somewhere? JAM
706 
707  //TODO How do we output this information when using multiple solve settings? JAM
708 
709  BundleObservationSolveSettings globalSettings = m_settings->observationSolveSettings(0);
710  int pointingSolveDegree = globalSettings.numberCameraAngleCoefficientsSolved();
711  QList<double> pointingSigmas = globalSettings.aprioriPointingSigmas();
712  int positionSolveDegree = globalSettings.numberCameraPositionCoefficientsSolved();
713  QList<double> positionSigmas = globalSettings.aprioriPositionSigmas();
714 
715  sprintf(buf, "\n\nINPUT: CAMERA POINTING OPTIONS\n==============================\n");
716  fpOut << buf;
717  switch (pointingSolveDegree) {
718  case 0:
719  sprintf(buf,"\n CAMSOLVE: NONE");
720  break;
721  case 1:
722  sprintf(buf,"\n CAMSOLVE: ANGLES");
723  break;
724  case 2:
725  sprintf(buf,"\n CAMSOLVE: ANGLES, VELOCITIES");
726  break;
727  case 3:
728  sprintf(buf,"\n CAMSOLVE: ANGLES, VELOCITIES, ACCELERATIONS");
729  break;
730  default:
731  sprintf(buf,"\n CAMSOLVE: ALL POLYNOMIAL COEFFICIENTS (%d)"
732  "\n CKDEGREE: %d"
733  "\n CKSOLVEDEGREE: %d",
734  pointingSolveDegree,
735  globalSettings.ckDegree(),
736  globalSettings.ckSolveDegree());
737  break;
738  }
739  fpOut << buf;
740  globalSettings.solveTwist() ?
741  sprintf(buf, "\n TWIST: ON"):
742  sprintf(buf, "\n TWIST: OFF");
743  fpOut << buf;
744  globalSettings.solvePolyOverPointing() ?
745  sprintf(buf, "\n POLYNOMIAL OVER EXISTING POINTING: ON"):
746  sprintf(buf, "\nPOLYNOMIAL OVER EXISTING POINTING : OFF");
747  fpOut << buf;
748 
749  sprintf(buf, "\n\nINPUT: SPACECRAFT OPTIONS\n=========================\n");
750  fpOut << buf;
751  switch (positionSolveDegree) {
752  case 0:
753  sprintf(buf,"\n SPSOLVE: NONE");
754  break;
755  case 1:
756  sprintf(buf,"\n SPSOLVE: POSITION");
757  break;
758  case 2:
759  sprintf(buf,"\n SPSOLVE: POSITION, VELOCITIES");
760  break;
761  case 3:
762  sprintf(buf,"\n SPSOLVE: POSITION, VELOCITIES, ACCELERATIONS");
763  break;
764  default:
765  sprintf(buf,"\n SPSOLVE: ALL POLYNOMIAL COEFFICIENTS (%d)"
766  "\n SPKDEGREE: %d"
767  "\n SPKSOLVEDEGREE: %d",
768  positionSolveDegree,
769  globalSettings.spkDegree(),
770  globalSettings.spkSolveDegree());
771  break;
772  }
773  fpOut << buf;
774  globalSettings.solvePositionOverHermite() ?
775  sprintf(buf, "\n POLYNOMIAL OVER HERMITE SPLINE: ON"):
776  sprintf(buf, "\nPOLYNOMIAL OVER HERMITE SPLINE : OFF");
777  fpOut << buf;
778 
779  sprintf(buf, "\n\nINPUT: GLOBAL IMAGE PARAMETER UNCERTAINTIES\n===========================================\n");
780  QString coord1Str;
781  QString coord2Str;
782  QString coord3Str;
783  switch (m_settings->controlPointCoordTypeReports()) {
785  coord1Str = "LATITUDE";
786  coord2Str = "LONGITUDE";
787  coord3Str = "RADIUS";
788  break;
790  coord1Str = " X";
791  coord2Str = " Y";
792  coord3Str = " Z";
793  break;
794  default:
795  IString msg ="Unknown surface point coordinate type enum ["
796  + toString(m_settings->controlPointCoordTypeReports()) + "]." ;
798  break;
799  }
800 
801  // Coordinate 1 (latitude or point X)
802  fpOut << buf;
803  (m_settings->globalPointCoord1AprioriSigma() == Isis::Null) ?
804  sprintf(buf,"\n POINT %s SIGMA: N/A", coord1Str.toLatin1().data()):
805  sprintf(buf,"\n POINT %s SIGMA: %lf (meters)", coord1Str.toLatin1().data(),
806  m_settings->globalPointCoord1AprioriSigma());
807  // Coordinate 2 (longitude or point Y)
808  fpOut << buf;
809  (m_settings->globalPointCoord2AprioriSigma() == Isis::Null) ?
810  sprintf(buf,"\n POINT %s SIGMA: N/A", coord2Str.toLatin1().data()):
811  sprintf(buf,"\n POINT %s SIGMA: %lf (meters)", coord2Str.toLatin1().data(),
812  m_settings->globalPointCoord2AprioriSigma());
813  // Coordinate 3 (radius or point Z)
814  fpOut << buf;
815  (m_settings->globalPointCoord3AprioriSigma() == Isis::Null) ?
816  sprintf(buf,"\n POINT %s SIGMA: N/A", coord3Str.toLatin1().data()):
817  sprintf(buf,"\n POINT %s SIGMA: %lf (meters)", coord3Str.toLatin1().data(),
818  m_settings->globalPointCoord3AprioriSigma());
819  fpOut << buf;
820  (positionSolveDegree < 1 || positionSigmas[0] == Isis::Null) ?
821  sprintf(buf,"\n SPACECRAFT POSITION SIGMA: N/A"):
822  sprintf(buf,"\n SPACECRAFT POSITION SIGMA: %lf (meters)",
823  positionSigmas[0]);
824  fpOut << buf;
825 
826  (positionSolveDegree < 2 || positionSigmas[1] == Isis::Null) ?
827  sprintf(buf,"\n SPACECRAFT VELOCITY SIGMA: N/A"):
828  sprintf(buf,"\n SPACECRAFT VELOCITY SIGMA: %lf (m/s)",
829  positionSigmas[1]);
830  fpOut << buf;
831 
832  (positionSolveDegree < 3 || positionSigmas[2] == Isis::Null) ?
833  sprintf(buf,"\n SPACECRAFT ACCELERATION SIGMA: N/A"):
834  sprintf(buf,"\n SPACECRAFT ACCELERATION SIGMA: %lf (m/s/s)",
835  positionSigmas[2]);
836  fpOut << buf;
837 
838  (pointingSolveDegree < 1 || pointingSigmas[0] == Isis::Null) ?
839  sprintf(buf,"\n CAMERA ANGLES SIGMA: N/A"):
840  sprintf(buf,"\n CAMERA ANGLES SIGMA: %lf (dd)",
841  pointingSigmas[0]);
842  fpOut << buf;
843 
844  (pointingSolveDegree < 2 || pointingSigmas[1] == Isis::Null) ?
845  sprintf(buf,"\n CAMERA ANGULAR VELOCITY SIGMA: N/A"):
846  sprintf(buf,"\n CAMERA ANGULAR VELOCITY SIGMA: %lf (dd/s)",
847  pointingSigmas[1]);
848  fpOut << buf;
849 
850  (pointingSolveDegree < 3 || pointingSigmas[2] == Isis::Null) ?
851  sprintf(buf,"\n CAMERA ANGULAR ACCELERATION SIGMA: N/A"):
852  sprintf(buf,"\n CAMERA ANGULAR ACCELERATION SIGMA: %lf (dd/s/s)",
853  pointingSigmas[2]);
854  fpOut << buf;
855 
856  if (m_settings->solveTargetBody()) {
857  sprintf(buf, "\n\nINPUT: TARGET BODY OPTIONS\n==============================\n");
858  fpOut << buf;
859 
860  if (m_settings->solvePoleRA() && m_settings->solvePoleDec()) {
861  sprintf(buf,"\n POLE: RIGHT ASCENSION");
862  fpOut << buf;
863  sprintf(buf,"\n : DECLINATION\n");
864  fpOut << buf;
865  }
866  else if (m_settings->solvePoleRA()) {
867  sprintf(buf,"\n POLE: RIGHT ASCENSION\n");
868  fpOut << buf;
869  }
870  else if (m_settings->solvePoleDec()) {
871  sprintf(buf,"\n POLE: DECLINATION\n");
872  fpOut << buf;
873  }
874 
875  if (m_settings->solvePM() || m_settings->solvePMVelocity()
876  || m_settings->solvePMAcceleration()) {
877  sprintf(buf,"\n PRIME MERIDIAN: W0 (OFFSET)");
878  fpOut << buf;
879 
880  if (m_settings->solvePMVelocity()) {
881  sprintf(buf,"\n : WDOT (SPIN RATE)");
882  fpOut << buf;
883  }
884  if (m_settings->solvePMAcceleration()) {
885  sprintf(buf,"\n :W ACCELERATION");
886  fpOut << buf;
887  }
888  }
889 
890  if (m_settings->solveTriaxialRadii() || m_settings->solveMeanRadius()) {
891  if (m_settings->solveMeanRadius()) {
892  sprintf(buf,"\n RADII: MEAN");
893  fpOut << buf;
894  }
895  else if (m_settings->solveTriaxialRadii()) {
896  sprintf(buf,"\n RADII: TRIAXIAL");
897  fpOut << buf;
898  }
899  }
900  }
901 
902  sprintf(buf, "\n\nJIGSAW: RESULTS\n===============\n");
903  fpOut << buf;
904  sprintf(buf, "\n Images: %6d",numImages);
905  fpOut << buf;
906  sprintf(buf, "\n Points: %6d",numValidPoints);
907  fpOut << buf;
908 
909  sprintf(buf, "\n Total Measures: %6d",
912  fpOut << buf;
913 
914  sprintf(buf, "\n Total Observations: %6d",
917  fpOut << buf;
918 
919  sprintf(buf, "\n Good Observations: %6d",
921  fpOut << buf;
922 
923  sprintf(buf, "\n Rejected Observations: %6d",
925  fpOut << buf;
926 
928  sprintf(buf, "\n Constrained Point Parameters: %6d",
930  fpOut << buf;
931  }
932 
934  sprintf(buf, "\n Constrained Image Parameters: %6d",
936  fpOut << buf;
937  }
938 
940  sprintf(buf, "\n Constrained Target Parameters: %6d",
942  fpOut << buf;
943  }
944 
945  sprintf(buf, "\n Unknowns: %6d",
947  fpOut << buf;
948 
949  if (numInnerConstraints > 0) {
950  sprintf(buf, "\n Inner Constraints: %6d", numInnerConstraints);
951  fpOut << buf;
952  }
953 
954  if (numDistanceConstraints > 0) {
955  sprintf(buf, "\n Distance Constraints: %d", numDistanceConstraints);
956  fpOut << buf;
957  }
958 
959  sprintf(buf, "\n Degrees of Freedom: %6d", numDegreesOfFreedom);
960  fpOut << buf;
961 
962  sprintf(buf, "\n Convergence Criteria: %6.3g",
963  m_settings->convergenceCriteriaThreshold());
964  fpOut << buf;
965 
966  if (convergenceCriteria == 1) {
967  sprintf(buf, "(Sigma0)");
968  fpOut << buf;
969  }
970 
971  sprintf(buf, "\n Iterations: %6d", m_statisticsResults->iterations());
972  fpOut << buf;
973 
974  if (m_statisticsResults->iterations() >= m_settings->convergenceCriteriaMaximumIterations()) {
975  sprintf(buf, "(Maximum reached)");
976  fpOut << buf;
977  }
978 
979  sprintf(buf, "\n Sigma0: %30.20lf\n", m_statisticsResults->sigma0());
980  fpOut << buf;
981  sprintf(buf, " Error Propagation Elapsed Time: %6.4lf (seconds)\n",
983  fpOut << buf;
984  sprintf(buf, " Total Elapsed Time: %6.4lf (seconds)\n",
986  fpOut << buf;
989  > 100) {
990  sprintf(buf, "\n Residual Percentiles:\n");
991  fpOut << buf;
992 
993  // residual prob distribution values are calculated/printed
994  // even if there is no maximum likelihood estimation
995  try {
996  for (int bin = 1;bin < 34;bin++) {
997  double cumProb = double(bin) / 100.0;
998  double resValue =
1000  residualsCumulativeProbabilityDistribution().value(cumProb);
1001  double resValue33 =
1003  residualsCumulativeProbabilityDistribution().value(cumProb + 0.33);
1004  double resValue66 =
1006  residualsCumulativeProbabilityDistribution().value(cumProb + 0.66);
1007  sprintf(buf, " Percentile %3d: %+8.3lf"
1008  " Percentile %3d: %+8.3lf"
1009  " Percentile %3d: %+8.3lf\n",
1010  bin, resValue,
1011  bin + 33, resValue33,
1012  bin + 66, resValue66);
1013  fpOut << buf;
1014  }
1015  }
1016  catch (IException &e) {
1017  QString msg = "Failed to output residual percentiles for bundleout";
1018  throw IException(e, IException::Io, msg, _FILEINFO_);
1019  }
1020  try {
1021  sprintf(buf, "\n Residual Box Plot:");
1022  fpOut << buf;
1023  sprintf(buf, "\n minimum: %+8.3lf",
1025  fpOut << buf;
1026  sprintf(buf, "\n Quartile 1: %+8.3lf",
1028  fpOut << buf;
1029  sprintf(buf, "\n Median: %+8.3lf",
1031  fpOut << buf;
1032  sprintf(buf, "\n Quartile 3: %+8.3lf",
1034  fpOut << buf;
1035  sprintf(buf, "\n maximum: %+8.3lf\n",
1037  fpOut << buf;
1038  }
1039  catch (IException &e) {
1040  QString msg = "Failed to output residual box plot for bundleout";
1041  throw IException(e, IException::Io, msg, _FILEINFO_);
1042  }
1043  }
1044 
1045  sprintf(buf, "\nIMAGE MEASURES SUMMARY\n==========================\n\n");
1046  fpOut << buf;
1047  sprintf(buf," Measures RMS(pixels)\n");
1048  fpOut << buf;
1049  sprintf(buf," ************************ "
1050  "**************************************\n");
1051  fpOut << buf;
1052 
1053  sprintf(buf," |Accepted | Total| |Samples | "
1054  "Lines | Total|\n");
1055  fpOut << buf;
1056 
1057  int numMeasures;
1058  int numRejectedMeasures;
1059  int numUsed;
1060  int imageIndex = 0;
1061  Statistics rmsSamplesTotal,rmsLinesTotal,rmsTotals;
1062 
1063  for (int i = 0; i < numObservations; i++) {
1064 
1065  int numImagesInObservation = m_statisticsResults->observations().at(i)->size();
1066 
1067  for (int j = 0; j < numImagesInObservation; j++) {
1068 
1069  BundleImageQsp bundleImage = m_statisticsResults->observations().at(i)->at(j);
1070 
1071  double rmsSampleResiduals = m_statisticsResults->
1072  rmsImageSampleResiduals()[imageIndex].Rms();
1073  double rmsLineResiduals = m_statisticsResults->
1074  rmsImageLineResiduals()[imageIndex].Rms();
1075  double rmsLandSResiduals = m_statisticsResults->
1076  rmsImageResiduals()[imageIndex].Rms();
1077  rmsSamplesTotal.AddData(rmsSampleResiduals);
1078  rmsLinesTotal.AddData(rmsLineResiduals);
1079  rmsTotals.AddData(rmsLandSResiduals);
1080 
1081  numMeasures = m_statisticsResults->outputControlNet()->GetNumberOfValidMeasuresInImage
1082  (bundleImage->serialNumber());
1083 
1084  numRejectedMeasures = m_statisticsResults->outputControlNet()->
1085  GetNumberOfJigsawRejectedMeasuresInImage(bundleImage->serialNumber());
1086 
1087  numUsed = numMeasures - numRejectedMeasures;
1088 
1089  sprintf(buf,"%30s" ,bundleImage->fileName().toLatin1().data());
1090  fpOut << buf;
1091 
1092  sprintf(buf,"%5d %5d ",numUsed,numMeasures);
1093  fpOut << buf;
1094 
1095  sprintf(buf,"%-15.4lf%-15.4lf%-15.4lf \n",
1096  rmsSampleResiduals,rmsLineResiduals,rmsLandSResiduals);
1097 
1098  fpOut << buf;
1099  imageIndex++;
1100  }
1101  }
1102 
1103  sprintf(buf,"\nTotal RMS:");
1104  fpOut << buf;
1105  sprintf(buf," ");
1106  fpOut << buf;
1107  sprintf(buf,"%-15.4lf%-15.4lf%-15.4lf\n",
1108  rmsSamplesTotal.Rms(),rmsLinesTotal.Rms(),rmsTotals.Rms());
1109  fpOut << buf;
1110 
1111  return true;
1112  }
1113 
1114 
1127 
1128  char buf[1056];
1129  int imgIndex = 0;
1130 
1131  QList<Statistics> rmsImageSampleResiduals = m_statisticsResults->rmsImageSampleResiduals();
1132  QList<Statistics> rmsImageLineResiduals = m_statisticsResults->rmsImageLineResiduals();
1134 
1135  QString ofname = "bundleout_images.csv";
1136  ofname = m_settings->outputFilePrefix() + ofname;
1137  m_csvSavedImagesFilename = ofname;
1138 
1139  std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1140  if (!fpOut) {
1141  return false;
1142  }
1143 
1144 
1145  BundleObservationQsp observation;
1146 
1147  int nObservations = m_statisticsResults->observations().size();
1148 
1149  outputImagesCSVHeader(fpOut);
1150 
1151  bool errorProp = false;
1152  if (m_statisticsResults->converged() && m_settings->errorPropagation()) {
1153  errorProp = true;
1154  }
1155 
1156  for (int i = 0; i < nObservations;i++ ) {
1157  observation = m_statisticsResults->observations().at(i);
1158 
1159  if(!observation) {
1160  continue;
1161  }
1162 
1163  int numImages = observation->size();
1164 
1165  for (int j = 0; j < numImages; j++) {
1166 
1167  BundleImageQsp image = observation->at(j);
1168 
1169 
1170  sprintf(buf, "%s", image->fileName().toLatin1().data());
1171  fpOut << buf;
1172  sprintf(buf,",");
1173  fpOut << buf;
1174 
1175  fpOut << toString(rmsImageSampleResiduals[imgIndex].Rms()).toLatin1().data();
1176  sprintf(buf,",");
1177  fpOut << buf;
1178 
1179  fpOut << toString(rmsImageLineResiduals[imgIndex].Rms()).toLatin1().data();
1180  sprintf(buf,",");
1181  fpOut << buf;
1182 
1183  fpOut << toString(rmsImageResiduals[imgIndex].Rms()).toLatin1().data();
1184  sprintf(buf,",");
1185  fpOut << buf;
1186 
1187  QString observationString =
1188  observation->bundleOutputCSV(errorProp);
1189 
1190  //Removes trailing commas
1191  if (observationString.right(1)==",") {
1192  observationString.truncate(observationString.length()-1);
1193  }
1194 
1195  fpOut << (const char*) observationString.toLatin1().data();
1196 
1197  sprintf(buf,"\n");
1198  fpOut << buf;
1199  imgIndex++;
1200 
1201  }
1202  }
1203 
1204  fpOut.close();
1205  return true;
1206  }
1207 
1208 
1215 
1216  QString ofname = "bundleout.txt";
1217  ofname = m_settings->outputFilePrefix() + ofname;
1218 
1219  std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1220  if (!fpOut) {
1221  return false;
1222  }
1223 
1224  m_txtBundleOutputFilename = ofname;
1225 
1226  char buf[4096];
1227  BundleObservationQsp observation;
1228 
1229  int nObservations = m_statisticsResults->observations().size();
1230 
1231  outputHeader(fpOut);
1232 
1233  bool berrorProp = false;
1234  if (m_statisticsResults->converged() && m_settings->errorPropagation()) {
1235  berrorProp = true;
1236  }
1237 
1238  // output target body header if solving for target
1239  if (m_settings->solveTargetBody()) {
1240  sprintf(buf, "\nTARGET BODY\n==========================\n");
1241  fpOut << buf;
1242 
1243  sprintf(buf, "\n Target Initial Total "
1244  "Final Initial Final\n"
1245  "Parameter Value Correction "
1246  "Value Accuracy Accuracy\n");
1247  fpOut << buf;
1248 
1249  QString targetString =
1250  m_settings->bundleTargetBody()->formatBundleOutputString(berrorProp);
1251  fpOut << (const char*)targetString.toLatin1().data();
1252  }
1253 
1254  // output image exterior orientation header
1255  sprintf(buf, "\nIMAGE EXTERIOR ORIENTATION\n==========================\n");
1256  fpOut << buf;
1257 
1258  QMap<QString, QStringList> imagesAndParameters;
1259 
1260  if (m_settings->solveTargetBody()) {
1261  imagesAndParameters.insert( "target", m_settings->bundleTargetBody()->parameterList() );
1262  }
1263 
1264  for (int i = 0; i < nObservations; i++) {
1265 
1266  observation = m_statisticsResults->observations().at(i);
1267  if (!observation) {
1268  continue;
1269  }
1270 
1271  int numImages = observation->size();
1272  for (int j = 0; j < numImages; j++) {
1273  BundleImageQsp image = observation->at(j);
1274  sprintf(buf, "\nImage Full File Name: %s\n", image->fileName().toLatin1().data());
1275  fpOut << buf;
1276  sprintf(buf, "\nImage Serial Number: %s\n", image->serialNumber().toLatin1().data());
1277  fpOut << buf;
1278 
1279  sprintf(buf,"Image Initial Total Final Accuracy\n");
1280  fpOut << buf;
1281  sprintf(buf,"Parameter Value Correction Value Initial Final Units\n");
1282  fpOut << buf;
1283 
1284  sprintf(buf," "
1285  "***************************************\n");
1286  fpOut << buf;
1287 
1288  observation->bundleOutputString(fpOut,berrorProp);
1289  // Build list of images and parameters for correlation matrix.
1290  foreach ( QString image, observation->imageNames() ) {
1291  imagesAndParameters.insert( image, observation->parameterList() );
1292  }
1293  }
1294  }
1295 
1296  // Save list of images and their associated parameters for CorrelationMatrix to use in ice.
1297  m_statisticsResults->setCorrMatImgsAndParams(imagesAndParameters);
1298 
1299  // Save list of images and their associated parameters for CorrelationMatrix to use in ice.
1300  m_statisticsResults->setCorrMatImgsAndParams(imagesAndParameters);
1301 
1302  // output point uncertainty statistics if error propagation is on
1303  if (berrorProp) {
1304  sprintf(buf, "\n\n\nPOINTS UNCERTAINTY SUMMARY\n==========================\n\n");
1305  fpOut << buf;
1306 
1307  // Coordinate 1 (latitude or point x) summary
1308  QString
1309  coordName = surfacePointCoordName(m_settings->controlPointCoordTypeReports(),
1310  SurfacePoint::One);
1311  sprintf(buf, "RMS Sigma %s(m)%20.8lf\n", coordName.toLatin1().data(),
1313  fpOut << buf;
1314  sprintf(buf, "MIN Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1316  m_statisticsResults->minSigmaCoord1PointId().toLatin1().data());
1317  fpOut << buf;
1318  sprintf(buf, "MAX Sigma %s(m)%20.8lf at %s\n\n", coordName.toLatin1().data(),
1320  m_statisticsResults->maxSigmaCoord1PointId().toLatin1().data());
1321  fpOut << buf;
1322 
1323  // Coordinate 2 (longitude or point y) summary
1324  coordName = surfacePointCoordName(m_settings->controlPointCoordTypeReports(),
1325  SurfacePoint::Two);
1326  sprintf(buf, "RMS Sigma %s(m)%20.8lf\n", coordName.toLatin1().data(),
1328  fpOut << buf;
1329  sprintf(buf, "MIN Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1331  m_statisticsResults->minSigmaCoord2PointId().toLatin1().data());
1332  fpOut << buf;
1333  sprintf(buf, "MAX Sigma %s(m)%20.8lf at %s\n\n", coordName.toLatin1().data(),
1335  m_statisticsResults->maxSigmaCoord2PointId().toLatin1().data());
1336  fpOut << buf;
1337 
1338  // Coordinate 3 (radius or point z) summary
1339  coordName = surfacePointCoordName(m_settings->controlPointCoordTypeReports(),
1340  SurfacePoint::Three);
1341  if ( m_settings->solveRadius() ) {
1342  sprintf(buf, "RMS Sigma %s(m)%20.8lf\n", coordName.toLatin1().data(),
1344  fpOut << buf;
1345  sprintf(buf, "MIN Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1347  m_statisticsResults->minSigmaCoord3PointId().toLatin1().data());
1348  fpOut << buf;
1349  sprintf(buf, "MAX Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1351  m_statisticsResults->maxSigmaCoord3PointId().toLatin1().data());
1352  fpOut << buf;
1353  }
1354  else {
1355  sprintf(buf, " RMS Sigma Radius(m) N/A\n");
1356  fpOut << buf;
1357  sprintf(buf, " MIN Sigma Radius(m) N/A\n");
1358  fpOut << buf;
1359  sprintf(buf, " MAX Sigma Radius(m) N/A\n");
1360  fpOut << buf;
1361  }
1362  }
1363 
1364  // output point summary data header
1365  if (m_settings->controlPointCoordTypeReports() == SurfacePoint::Latitudinal) {
1366  sprintf(buf, "\n\nPOINTS SUMMARY\n==============\n%103s"
1367  "Sigma Sigma Sigma\n"
1368  " Label Status Rays RMS"
1369  " Latitude Longitude Radius"
1370  " Latitude Longitude Radius\n", "");
1371  }
1372  else { // Must be Rectangular
1373  sprintf(buf, "\n\nPOINTS SUMMARY\n==============\n%103s"
1374  "Sigma Sigma Sigma\n"
1375  " Label Status Rays RMS"
1376  " Point X Point Y Point Z"
1377  " Point X Point Y Point Z\n", "");
1378  }
1379  fpOut << buf;
1380 
1381  int nPoints = m_statisticsResults->bundleControlPoints().size();
1382  for (int i = 0; i < nPoints; i++) {
1383  BundleControlPointQsp bundleControlPoint = m_statisticsResults->bundleControlPoints().at(i);
1384 
1385  QString pointSummaryString =
1386  bundleControlPoint->formatBundleOutputSummaryString(berrorProp);
1387  fpOut << (const char*)pointSummaryString.toLatin1().data();
1388  }
1389 
1390  // output point detail data header
1391  sprintf(buf, "\n\nPOINTS DETAIL\n=============\n\n");
1392  fpOut << buf;
1393 
1394  bool solveRadius = m_settings->solveRadius();
1395 
1396  for (int i = 0; i < nPoints; i++) {
1397  BundleControlPointQsp bundleControlPoint = m_statisticsResults->bundleControlPoints().at(i);
1398 
1399  // Removed radiansToMeters argument 9/18/2018 DAC
1400  QString pointDetailString =
1401  bundleControlPoint->formatBundleOutputDetailString(berrorProp,
1402  solveRadius);
1403  fpOut << (const char*)pointDetailString.toLatin1().data();
1404  }
1405 
1406  fpOut.close();
1407 
1408  return true;
1409  }
1410 
1411 
1418  char buf[1056];
1419 
1420  QString ofname = "bundleout_points.csv";
1421  ofname = m_settings->outputFilePrefix() + ofname;
1422  m_csvSavedPointsFilename = ofname;
1423 
1424  std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1425  if (!fpOut) {
1426  return false;
1427  }
1428 
1429  int numPoints = m_statisticsResults->bundleControlPoints().size();
1430 
1431  double dLat, dLon, dRadius;
1432  double dX, dY, dZ;
1433  double dSigmaLat, dSigmaLong, dSigmaRadius;
1434  QString strStatus;
1435  double cor_lat_m;
1436  double cor_lon_m;
1437  double cor_rad_m;
1438  int numMeasures, numRejectedMeasures;
1439  double dResidualRms;
1440 
1441  // print column headers
1442  if (m_settings->errorPropagation()) {
1443  sprintf(buf, ",,,,,3-d,3-d,3-d,Sigma,Sigma,Sigma,Correction,Correction,Correction,Coordinate,"
1444  "Coordinate,Coordinate\nPoint,Point,Accepted,Rejected,Residual,Latitude,Longitude,"
1445  "Radius,Latitude,Longitude,Radius,Latitude,Longitude,Radius,X,Y,Z\nLabel,Status,"
1446  "Measures,Measures,RMS,(dd),(dd),(km),(m),(m),(m),(m),(m),(m),(km),(km),(km)\n");
1447  }
1448  else {
1449  sprintf(buf, ",,,,,3-d,3-d,3-d,Correction,Correction,Correction,Coordinate,Coordinate,"
1450  "Coordinate\nPoint,Point,Accepted,Rejected,Residual,Latitude,Longitude,Radius,"
1451  "Latitude,Longitude,Radius,X,Y,Z\nLabel,Status,Measures,Measures,RMS,(dd),(dd),(km),"
1452  "(m),(m),(m),(km),(km),(km)\n");
1453  }
1454  fpOut << buf;
1455 
1456  for (int i = 0; i < numPoints; i++) {
1457  BundleControlPointQsp bundlecontrolpoint = m_statisticsResults->bundleControlPoints().at(i);
1458 
1459  if (!bundlecontrolpoint) {
1460  continue;
1461  }
1462 
1463  if (bundlecontrolpoint->isRejected()) {
1464  continue;
1465  }
1466 
1467  dLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatitude().degrees();
1468  dLon = bundlecontrolpoint->adjustedSurfacePoint().GetLongitude().degrees();
1469  dRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadius().kilometers();
1470  dX = bundlecontrolpoint->adjustedSurfacePoint().GetX().kilometers();
1471  dY = bundlecontrolpoint->adjustedSurfacePoint().GetY().kilometers();
1472  dZ = bundlecontrolpoint->adjustedSurfacePoint().GetZ().kilometers();
1473  numMeasures = bundlecontrolpoint->numberOfMeasures();
1474  numRejectedMeasures = bundlecontrolpoint->numberOfRejectedMeasures();
1475  dResidualRms = bundlecontrolpoint->residualRms();
1476 
1477  // point corrections and initial sigmas
1478  boost::numeric::ublas::bounded_vector< double, 3 > corrections = bundlecontrolpoint->
1479  corrections();
1480  // Now use the local radius to convert radians to meters instead of the target body equatorial radius
1481  cor_lat_m = bundlecontrolpoint->adjustedSurfacePoint().LatitudeToMeters(corrections[0]);
1482  cor_lon_m = bundlecontrolpoint->adjustedSurfacePoint().LongitudeToMeters(corrections[1]);
1483  cor_rad_m = corrections[2]*1000.0;
1484 
1485  if (bundlecontrolpoint->type() == ControlPoint::Fixed) {
1486  strStatus = "FIXED";
1487  }
1488  else if (bundlecontrolpoint->type() == ControlPoint::Constrained) {
1489  strStatus = "CONSTRAINED";
1490  }
1491  else if (bundlecontrolpoint->type() == ControlPoint::Free) {
1492  strStatus = "FREE";
1493  }
1494  else {
1495  strStatus = "UNKNOWN";
1496  }
1497 
1498  if (m_settings->errorPropagation()) {
1499  dSigmaLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatSigmaDistance().meters();
1500  dSigmaLong = bundlecontrolpoint->adjustedSurfacePoint().GetLonSigmaDistance().meters();
1501  dSigmaRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadiusSigma().meters();
1502 
1503  sprintf(buf, "%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
1504  "%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf\n",
1505  bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
1506  numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, dSigmaLat,
1507  dSigmaLong, dSigmaRadius, cor_lat_m, cor_lon_m, cor_rad_m, dX, dY, dZ);
1508  }
1509  else
1510  sprintf(buf, "%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
1511  "%16.8lf,%16.8lf\n",
1512  bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
1513  numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, cor_lat_m,
1514  cor_lon_m, cor_rad_m, dX, dY, dZ);
1515 
1516  fpOut << buf;
1517  }
1518 
1519  fpOut.close();
1520 
1521  return true;
1522  }
1523 
1524 
1531  char buf[1056];
1532 
1533  QString ofname = "residuals.csv";
1534  ofname = m_settings->outputFilePrefix() + ofname;
1535  m_csvSavedResidualsFilename = ofname;
1536 
1537  std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1538  if (!fpOut) {
1539  return false;
1540  }
1541 
1542  // output column headers
1543 
1544  sprintf(buf, ",,,x image,y image,Measured,Measured,sample,line,Residual Vector\n");
1545  fpOut << buf;
1546  sprintf(buf, "Point,Image,Image,coordinate,coordinate,"
1547  "Sample,Line,residual,residual,Magnitude\n");
1548  fpOut << buf;
1549  sprintf(buf, "Label,Filename,Serial Number,(mm),(mm),"
1550  "(pixels),(pixels),(pixels),(pixels),(pixels),Rejected\n");
1551  fpOut << buf;
1552 
1553  // Setup counts and pointers
1554 
1555  int numPoints = m_statisticsResults->bundleControlPoints().size();
1556  int numMeasures = 0;
1557 
1558  BundleControlPointQsp bundleControlPoint;
1559  BundleMeasureQsp bundleMeasure;
1560 
1561  for (int i = 0; i < numPoints; i++) {
1562  bundleControlPoint = m_statisticsResults->bundleControlPoints().at(i);
1563  numMeasures = bundleControlPoint->size();
1564 
1565  if (bundleControlPoint->rawControlPoint()->IsIgnored()) {
1566  continue;
1567  }
1568 
1569  for (int j = 0; j < numMeasures; j++) {
1570  bundleMeasure = bundleControlPoint->at(j);
1571 
1572  Camera *measureCamera = bundleMeasure->camera();
1573  if (!measureCamera) {
1574  continue;
1575  }
1576 
1577  if (bundleMeasure->isRejected()) {
1578  sprintf(buf, "%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,*\n",
1579  bundleControlPoint->id().toLatin1().data(),
1580  bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1581  bundleMeasure->cubeSerialNumber().toLatin1().data(),
1582  bundleMeasure->focalPlaneMeasuredX(),
1583  bundleMeasure->focalPlaneMeasuredY(),
1584  bundleMeasure->sample(),
1585  bundleMeasure->line(),
1586  bundleMeasure->sampleResidual(),
1587  bundleMeasure->lineResidual(),
1588  bundleMeasure->residualMagnitude());
1589  }
1590  else {
1591  sprintf(buf, "%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf\n",
1592  bundleControlPoint->id().toLatin1().data(),
1593  bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1594  bundleMeasure->cubeSerialNumber().toLatin1().data(),
1595  bundleMeasure->focalPlaneMeasuredX(),
1596  bundleMeasure->focalPlaneMeasuredY(),
1597  bundleMeasure->sample(),
1598  bundleMeasure->line(),
1599  bundleMeasure->sampleResidual(),
1600  bundleMeasure->lineResidual(),
1601  bundleMeasure->residualMagnitude());
1602  }
1603  fpOut << buf;
1604  }
1605  }
1606 
1607  fpOut.close();
1608 
1609  return true;
1610  }
1611 
1612 
1629  void BundleSolutionInfo::save(QXmlStreamWriter &stream, const Project *project,
1630  FileName newProjectRoot) const {
1631 
1632  // TODO: comment below not clear, why is this done?
1633  // This is done for unitTest which has no Project
1634  // SHOULD WE BE CREATING A SERIALIZED PROJECT AS INPUT TO THIS UNIT TEST?
1635  QString relativePath;
1636  QString relativeBundlePath;
1637  FileName bundleSolutionInfoRoot;
1638 
1639  if (project) {
1640  bundleSolutionInfoRoot = FileName(Project::bundleSolutionInfoRoot(newProjectRoot.expanded()) +
1641  "/" + runTime());
1642  QString oldPath = project->bundleSolutionInfoRoot(project->projectRoot()) + "/" + runTime();
1643  QString newPath = project->bundleSolutionInfoRoot(newProjectRoot.toString()) + "/" + runTime();
1644  // If project is being saved to new area, create directory and copy files
1645  if (oldPath != newPath) {
1646  // Create project folder for BundleSolutionInfo
1647  QDir bundleDir(newPath);
1648  if (!bundleDir.mkpath(bundleDir.path())) {
1649  throw IException(IException::Io,
1650  QString("Failed to create directory [%1]")
1651  .arg(bundleSolutionInfoRoot.path()),
1652  _FILEINFO_);
1653  }
1654  QString oldFile = oldPath + "/" + FileName(m_outputControl->fileName()).name();
1655  QString newFile = newPath + "/" + FileName(m_outputControl->fileName()).name();
1656  if (!QFile::copy(oldFile, newFile)) {
1657  throw IException(IException::Io,
1658  QString("Failed to copy file [%1] to new file [%2]")
1659  .arg(m_outputControl->fileName()).arg(newFile),
1660  _FILEINFO_);
1661  }
1662  newFile = newPath + "/" + FileName(m_txtBundleOutputFilename).name();
1663  if (!QFile::copy(m_txtBundleOutputFilename, newFile)) {
1664  throw IException(IException::Io,
1665  QString("Failed to copy file [%1] to new file [%2]")
1666  .arg(m_txtBundleOutputFilename).arg(newFile),
1667  _FILEINFO_);
1668  }
1669  newFile = newPath + "/" + FileName(m_csvSavedImagesFilename).name();
1670  if (!QFile::copy(m_csvSavedImagesFilename, newFile)) {
1671  throw IException(IException::Io,
1672  QString("Failed to copy file [%1] to new file [%2]")
1673  .arg(m_csvSavedImagesFilename).arg(newFile),
1674  _FILEINFO_);
1675  }
1676  newFile = newPath + "/" + FileName(m_csvSavedPointsFilename).name();
1677  if (!QFile::copy(m_csvSavedPointsFilename, newFile)) {
1678  throw IException(IException::Io,
1679  QString("Failed to copy file [%1] to new file [%2]")
1680  .arg(m_csvSavedPointsFilename).arg(newFile),
1681  _FILEINFO_);
1682  }
1683  newFile = newPath + "/" + FileName(m_csvSavedResidualsFilename).name();
1684  if (!QFile::copy(m_csvSavedResidualsFilename, newFile)) {
1685  throw IException(IException::Io,
1686  QString("Failed to copy file [%1] to new file [%2]")
1687  .arg(m_csvSavedResidualsFilename).arg(newFile),
1688  _FILEINFO_);
1689  }
1690  }
1691 
1692  // Create relativePath
1693  relativePath = m_inputControlNetFileName->expanded().remove(project->newProjectRoot());
1694  // Get rid of any preceding "/" , but add on ending "/"
1695  if (relativePath.startsWith("/")) {
1696  relativePath.remove(0,1);
1697  }
1698 
1699  // Create relativeBundlePath for bundleSolutionInfo
1700  relativeBundlePath = newPath.remove(project->newProjectRoot());
1701  // Get rid of any preceding "/" , but add on ending "/"
1702  if (relativeBundlePath.startsWith("/")) {
1703  relativeBundlePath.remove(0,1);
1704  }
1705  relativeBundlePath += "/";
1706  }
1707 
1708  // TODO: so, we can do the stuff below if project is NULL?
1709 
1710  stream.writeStartElement("bundleSolutionInfo");
1711  // save ID, cnet file name, and run time to stream
1712  stream.writeStartElement("generalAttributes");
1713  stream.writeTextElement("id", m_id->toString());
1714  stream.writeTextElement("name", m_name);
1715  stream.writeTextElement("runTime", runTime());
1716 
1717  stream.writeTextElement("inputFileName",
1718  relativePath);
1719  stream.writeTextElement("bundleOutTXT",
1720  relativeBundlePath + FileName(m_txtBundleOutputFilename).name());
1721  stream.writeTextElement("imagesCSV",
1722  relativeBundlePath + FileName(m_csvSavedImagesFilename).name());
1723  stream.writeTextElement("pointsCSV",
1724  relativeBundlePath + FileName(m_csvSavedPointsFilename).name());
1725  stream.writeTextElement("residualsCSV",
1726  relativeBundlePath + FileName(m_csvSavedResidualsFilename).name());
1727  stream.writeEndElement(); // end general attributes
1728 
1729  // save settings to stream
1730  m_settings->save(stream, project);
1731 
1732  // save statistics to stream
1733  m_statisticsResults->save(stream, project);
1734 
1735  if (project) {
1736  // save adjusted images lists to stream
1737  if (!m_adjustedImages->isEmpty()) {
1738  stream.writeStartElement("imageLists");
1739  for (int i = 0; i < m_adjustedImages->count(); i++) {
1740  m_adjustedImages->at(i)->save(stream, project, bundleSolutionInfoRoot);
1741  }
1742  stream.writeEndElement();
1743  }
1744 
1745  // save output control
1746  stream.writeStartElement("outputControl");
1747  m_outputControl->save(stream, project, relativeBundlePath);
1748  stream.writeEndElement();
1749  }
1750 
1751  stream.writeEndElement(); //end bundleSolutionInfo
1752  }
1753 
1754 
1763  Project *project) {
1764  m_xmlHandlerBundleSolutionInfo = bundleSolutionInfo;
1765  m_xmlHandlerProject = project;
1767  }
1768 
1769 
1774  }
1775 
1776 
1785  m_xmlHandlerCharacters += ch;
1786  return XmlStackedHandler::characters(ch);
1787  }
1788 
1789 
1800  bool BundleSolutionInfo::XmlHandler::startElement(const QString &namespaceURI,
1801  const QString &localName,
1802  const QString &qName,
1803  const QXmlAttributes &atts) {
1804  m_xmlHandlerCharacters = "";
1805 
1806  if (XmlStackedHandler::startElement(namespaceURI, localName, qName, atts)) {
1807 
1808  if (localName == "bundleSettings") {
1809  m_xmlHandlerBundleSolutionInfo->m_settings =
1810  BundleSettingsQsp(new BundleSettings(m_xmlHandlerProject, reader()));
1811  }
1812  else if (localName == "bundleResults") {
1813  m_xmlHandlerBundleSolutionInfo->m_statisticsResults = new BundleResults(m_xmlHandlerProject,
1814  reader());
1815  }
1816  else if (localName == "imageList") {
1817  m_xmlHandlerBundleSolutionInfo->m_adjustedImages->append(
1818  new ImageList(m_xmlHandlerProject, reader()));
1819  }
1820  else if (localName == "outputControl") {
1821  FileName outputControlPath = FileName(m_xmlHandlerProject->bundleSolutionInfoRoot() + "/"
1822  + m_xmlHandlerBundleSolutionInfo->runTime());
1823 
1824  m_xmlHandlerBundleSolutionInfo->m_outputControl = new Control(outputControlPath, reader());
1825  }
1826  }
1827  return true;
1828  }
1829 
1830 
1840  bool BundleSolutionInfo::XmlHandler::endElement(const QString &namespaceURI,
1841  const QString &localName,
1842  const QString &qName) {
1843  // This is done for unitTest which has no Project
1844  QString projectRoot;
1845  if (m_xmlHandlerProject) {
1846  projectRoot = m_xmlHandlerProject->projectRoot() + "/";
1847  }
1848 
1849  if (localName == "id") {
1850  // all constructors assign a Uuid - we need to give it a one from the XML
1851  assert(m_xmlHandlerBundleSolutionInfo->m_id);
1852  delete m_xmlHandlerBundleSolutionInfo->m_id;
1853  m_xmlHandlerBundleSolutionInfo->m_id = new QUuid(m_xmlHandlerCharacters);
1854  }
1855  else if (localName == "name") {
1856  m_xmlHandlerBundleSolutionInfo->m_name = m_xmlHandlerCharacters;
1857  }
1858  else if (localName == "runTime") {
1859  m_xmlHandlerBundleSolutionInfo->m_runTime = m_xmlHandlerCharacters;
1860  }
1861  else if (localName == "inputFileName") {
1862  assert(m_xmlHandlerBundleSolutionInfo->m_inputControlNetFileName == NULL);
1863  m_xmlHandlerBundleSolutionInfo->m_inputControlNetFileName = new FileName(
1864  projectRoot + m_xmlHandlerCharacters);
1865  }
1866  else if (localName == "bundleOutTXT") {
1867  m_xmlHandlerBundleSolutionInfo->m_txtBundleOutputFilename =
1868  projectRoot + m_xmlHandlerCharacters;
1869  }
1870  else if (localName == "imagesCSV") {
1871  m_xmlHandlerBundleSolutionInfo->m_csvSavedImagesFilename =
1872  projectRoot + m_xmlHandlerCharacters;
1873  }
1874  else if (localName == "pointsCSV") {
1875  m_xmlHandlerBundleSolutionInfo->m_csvSavedPointsFilename =
1876  projectRoot + m_xmlHandlerCharacters;
1877  }
1878  else if (localName == "residualsCSV") {
1879  m_xmlHandlerBundleSolutionInfo->m_csvSavedResidualsFilename =
1880  projectRoot + m_xmlHandlerCharacters;
1881  }
1882 
1883  m_xmlHandlerCharacters = "";
1884  return XmlStackedHandler::endElement(namespaceURI, localName, qName);
1885  }
1886 
1887 
1897  SurfacePoint::CoordIndex coordIdx) const {
1898  QString coordName;
1899  switch (m_settings->controlPointCoordTypeReports()) {
1901  switch (coordIdx) {
1902  case SurfacePoint::One:
1903  coordName = " Latitude";
1904  break;
1905  case SurfacePoint::Two:
1906  coordName = "Longitude";
1907  break;
1908  case SurfacePoint::Three:
1909  coordName = " Radius";
1910  break;
1911  default:
1912  IString msg = "Unknown surface point index enum ["
1913  + toString(coordIdx) + "].";
1915  break;
1916  }
1917  break;
1919  switch (coordIdx) {
1920  case SurfacePoint::One:
1921  coordName = "POINT X";
1922  break;
1923  case SurfacePoint::Two:
1924  coordName = "POINT Y";
1925  break;
1926  case SurfacePoint::Three:
1927  coordName = "POINT Z";
1928  break;
1929  default:
1930  IString msg = "Unknown surface point index enum ["
1931  + toString(coordIdx) + "].";
1933  break;
1934  }
1935  break;
1936  default:
1937  IString msg = "Unknown surface point coordinate type enum ["
1938  + toString(m_settings->controlPointCoordTypeReports()) + "].";
1940  break;
1941  }
1942  return coordName;
1943  }
1944 }
This represents an ISIS control net in a project-based GUI interface.
Definition: Control.h:79
Control * control() const
Returns bundle output Control object.
void setRunTime(QString runTime)
Sets the run time, and the name if a name is not already set.
QString path() const
Returns the path of the file name.
Definition: FileName.cpp:119
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
Handle an XML start element.
double meters() const
Get the distance in meters.
Definition: Distance.cpp:97
double max()
Returns the maximum observation so far included in the dynamic calculation.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
void updateFileName(Project *)
TODO: change description below to something more like english.
Distance minSigmaCoord2Distance() const
Returns the minimum sigma distance for coordinate 2.
Internalizes a list of images and allows for operations on the entire list.
Definition: ImageList.h:55
bool outputText()
Outputs a text file with the results of the BundleAdjust.
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:110
QString maxSigmaCoord3PointId() const
Returns the maximum sigma point id for coordinate 3.
The main project for ipce.
Definition: Project.h:289
QString outputControlName() const
Returns m_outputControlName.
int numberObservations() const
Returns the number of observations.
QList< ImageList * > imageList()
Returns the images used in the bundle.
const BundleObservationVector & observations() const
Returns a reference to the observations used by the BundleAdjust.
A Constrained point is a Control Point whose lat/lon/radius is somewhat established and should not be...
Definition: ControlPoint.h:391
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:503
A Fixed point is a Control Point whose lat/lon is well established and should not be changed...
Definition: ControlPoint.h:386
File name manipulation and expansion.
Definition: FileName.h:116
void save(QXmlStreamWriter &stream, const Project *project) const
Saves the BundleResults object to an XML file.
XmlHandler(BundleSolutionInfo *bundleSolutionInfo, Project *project)
Create an XML Handler (reader) that can populate the BundleSolutionInfo class data.
Container class for BundleAdjustment results.
BundleSettingsQsp m_settings
Bundle settings.
BundleSettingsQsp bundleSettings()
Returns bundle settings.
int numberCameraPositionCoefficientsSolved() const
Accesses the number of camera position coefficients in the solution.
QString savedResidualsFilename()
Returns filename of output bundle residuals csv file.
double sigmaCoord1StatisticsRms() const
Returns the RMS of the adjusted sigmas for coordinate 1.
double value(double cumProb)
Provides the value of the variable that has the given cumulative probility (according the current est...
QString weightedResidualCutoff()
Method to return a string represtentation of the weighted residual cutoff (if it exists) for the Maxi...
bool outputHeader(std::ofstream &fpOut)
Output header for bundle results file.
double sigmaCoord3StatisticsRms() const
Returns the RMS of the adjusted sigmas for coordinate 3.
QString minSigmaCoord1PointId() const
Returns the minimum sigma point id for coordinate 1.
QString m_name
Name of the bundle. Defaults to the id.
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:178
bool solvePositionOverHermite() const
Whether or not the polynomial for solving will be fit over an existing Hermite spline.
QList< ImageList * > * m_images
Input image list.
QString name() const
Returns the name of the bundle.
QString surfacePointCoordName(SurfacePoint::CoordinateType type, SurfacePoint::CoordIndex coordInx) const
Determine the control point coordinate name.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
QString savedPointsFilename()
Returns filename of output bundle points csv file.
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:162
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:171
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Method to write this Control object&#39;s member data to an XML stream.
Definition: Control.cpp:365
bool outputImagesCSV()
Outputs the bundleout_images.csv file which contains Jigsaw data about the images within each observa...
static QString cnetRoot(QString projectRoot)
Appends the root directory name &#39;cnets&#39; to the project.
Definition: Project.cpp:2019
QString maxSigmaCoord1PointId() const
Returns the maximum sigma point id for coordinate 1.
QString id() const
Get a unique, identifying string associated with this BundleSolutionInfo object.
Distance maxSigmaCoord3Distance() const
Returns the maximum sigma distance for coordinate 3.
ControlNetQsp outputControlNet() const
Returns a shared pointer to the output control network.
QList< ImageList * > adjustedImages() const
Returns the list of images that were adjusted after a bundle.
void setOutputStatistics(BundleResults statisticsResults)
Sets the stat results.
bool outputImagesCSVHeader(std::ofstream &fpOut)
Outputs the header for the bundleout_images.csv file.
A Free point is a Control Point that identifies common measurements between two or more cubes...
Definition: ControlPoint.h:399
QVector< BundleControlPointQsp > & bundleControlPoints()
Returns a reference to the BundleControlPoint vector.
Planetocentric latitudinal (lat/lon/rad) coordinates.
Definition: SurfacePoint.h:156
MaximumLikelihoodWFunctions maximumLikelihoodModelWFunc(int modelIndex) const
Returns the maximum likelihood model at the given index.
BundleResults * m_statisticsResults
Bundle statistical results.
BundleSolutionInfo * m_xmlHandlerBundleSolutionInfo
The bundleSolutionInfo object.
QString runTime() const
Returns the run time.
int ckDegree() const
Accesses the degree of polynomial fit to original camera angles (ckDegree).
This class is used to accumulate statistics on double arrays.
Definition: Statistics.h:107
double elapsedTime() const
Returns the elapsed time for the bundle adjustment.
QString outputControlNetFileName() const
Returns the name of the output control network.
void setName(QString name)
Sets the name of the bundle.
StatCumProbDistDynCalc residualsCumulativeProbabilityDistribution() const
Returns the cumulative probability distribution of the residuals used for reporting.
int numberConstrainedImageParameters() const
Returns the number of constrained image parameters.
int ckSolveDegree() const
Accesses the degree of the camera angles polynomial being fit to in the bundle adjustment (ckSolveDeg...
Distance minSigmaCoord3Distance() const
Returns the minimum sigma distance for coordinate 3.
int spkSolveDegree() const
Accesses the degree of thecamera position polynomial being fit to in the bundle adjustment (spkSolveD...
double sigmaCoord2StatisticsRms() const
Returns the RMS of the adjusted sigmas for coordinate 2.
static QString coordinateTypeToString(CoordinateType type)
Converts the given SurfacePoint::CoordinateType enumeration to a string.
double maximumLikelihoodModelQuantile(int modelIndex) const
Returns the quantile of the maximum likelihood model at the given index.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
QList< Statistics > rmsImageSampleResiduals() const
Returns the list of RMS image sample residuals statistics.
QUuid * m_id
A unique ID for this BundleSolutionInfo object (useful for others to reference this object when savin...
QSharedPointer< BundleSettings > BundleSettingsQsp
Definition for a BundleSettingsQsp, a shared pointer to a BundleSettings object.
virtual void pushContentHandler(XmlStackedHandler *newHandler)
Push a contentHandler and maybe continue parsing...
void setOutputControlName(QString name)
Sets m_outputControlName.
This class is used to read an images.xml file into an image list.
void addAdjustedImages(ImageList *images)
Adds a list of images that were adjusted (their labels were updated).
Container class for BundleAdjustment settings.
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:134
bool solvePolyOverPointing() const
Whether or not the solve polynomial will be fit over the existing pointing polynomial.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
double Rms() const
Computes and returns the rms.
Definition: Statistics.cpp:378
void setOutputControl(Control *outputControl)
Returns the name of the output control network.
QString minSigmaCoord2PointId() const
Returns the minimum sigma point id for coordinate 2.
QString projectRoot() const
Get the top-level folder of the project.
Definition: Project.cpp:1666
QDir dir() const
Returns the path of the file&#39;s parent directory as a QDir object.
Definition: FileName.cpp:481
FileName * m_inputControlNetFileName
Input control network file name.
QString m_xmlHandlerCharacters
List of characters that have been handled.
QList< Statistics > rmsImageResiduals() const
Returns the list of RMS image residuals statistics.
Distance minSigmaCoord1Distance() const
Returns the minimum sigma distance for coordinate 1.
bool converged() const
Returns whether or not the bundle adjustment converged.
double elapsedTimeErrorProp() const
Returns the elapsed time for error propagation.
QList< double > aprioriPositionSigmas() const
Accesses the a priori position sigmas.
QString newProjectRoot() const
Get the top-level folder of the new project.
Definition: Project.cpp:1675
Body-fixed rectangular x/y/z coordinates.
Definition: SurfacePoint.h:157
void setCorrMatImgsAndParams(QMap< QString, QStringList > imgsAndParams)
Set the images and their associated parameters of the correlation matrix.
CoordinateType
Defines the coordinate typ, units, and coordinate index for some of the output methods.
Definition: SurfacePoint.h:155
Control * m_outputControl
Output control.
This class is used to modify and manage solve settings for 1 to many BundleObservations.
int numberRejectedObservations() const
Returns the number of observation that were rejected.
QList< Statistics > rmsImageLineResiduals() const
Returns the list of RMS image line residuals statistics.
virtual bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName)
Handle an XML end element.
QString minSigmaCoord3PointId() const
Returns the minimum sigma point id for coordinate 3.
bool outputResiduals()
Outputs image coordinate residuals to a csv file.
QString toString() const
Returns a QString of the full file name including the file path, excluding the attributes with any Is...
Definition: FileName.cpp:531
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Saves the BundleSolutionInfo to the project.
QString m_runTime
Run time of the bundle adjustment.
QList< ImageList * > * m_adjustedImages
Adjusted image list.
int numberConstrainedTargetParameters() const
Return the number of constrained target parameters.
BundleResults bundleResults()
Returns the bundle results.
virtual bool characters(const QString &ch)
Adds characters to m_xmlHandlerCharacters.
int numberCameraAngleCoefficientsSolved() const
Accesses the number of camera angle coefficients in the solution.
Isis exception class.
Definition: IException.h:107
Adds specific functionality to C++ strings.
Definition: IString.h:181
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
double min()
Returns the maximum observation so far included in the dynamic calculation.
A container class for statistical results from a BundleAdjust solution.
Definition: BundleResults.h:96
Distance maxSigmaCoord2Distance() const
Returns the maximum sigma distance for coordinate 2.
QString savedBundleOutputFilename()
Returns bundleout text filename.
int numberConstrainedPointParameters() const
Returns the number of constrained point parameters.
int iterations() const
Returns the number of iterations taken by the BundleAdjust.
double tweakingConstant() const
Returns the current tweaking constant.
QString maxSigmaCoord2PointId() const
Returns the maximum sigma point id for coordinate 2.
QString bundleSolutionInfoRoot() const
Accessor for the root directory of the results data.
Definition: Project.cpp:2243
static QString modelToString(Model model)
Static method to return a string represtentation for a given MaximumLikelihoodWFunctions::Model enum...
static QString bundleSolutionInfoRoot(QString projectRoot)
Appends the root directory name &#39;bundle&#39; to the project results directory.
Definition: Project.cpp:2233
QString inputControlNetFileName() const
Returns the name of the input control network.
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
Definition: Statistics.cpp:154
QString savedImagesFilename()
Returns filename of output bundle images csv file.
Manage a stack of content handlers for reading XML files.
int spkDegree() const
Accesses the degree of the polynomial fit to the original camera position (spkDegree).
QString fileName() const
Access the name of the control network file associated with this Control.
Definition: Control.cpp:264
bool solveTwist() const
Accesses the flag for solving for twist.
double sigma0() const
Returns the Sigma0 of the bundle adjustment.
Distance maxSigmaCoord1Distance() const
Returns the maximum sigma distance for coordinate 1.
QList< double > aprioriPointingSigmas() const
Accesses the a priori pointing sigmas.
int numberUnknownParameters() const
Returns the number of unknown parameters.
bool outputPointsCSV()
Outputs point data to a csv file.