9 #include "BundleSolutionInfo.h"
11 #include <QDataStream>
16 #include <QStringList>
18 #include <QXmlStreamWriter>
20 #include "BundleResults.h"
22 #include "ControlList.h"
23 #include "ControlMeasure.h"
24 #include "ControlNet.h"
25 #include "ControlPoint.h"
27 #include "ImageList.h"
31 #include "PvlKeyword.h"
32 #include "PvlObject.h"
33 #include "StatCumProbDistDynCalc.h"
34 #include "Statistics.h"
35 #include "XmlStackedHandlerReader.h"
52 m_id =
new QUuid(QUuid::createUuid());
57 m_outputControlName=
"";
72 BundleSolutionInfo::BundleSolutionInfo(
Project *project,
76 m_id =
new QUuid(QUuid::createUuid());
81 m_outputControlName=
"";
87 xmlReader->setErrorHandler(
new XmlHandler(
this, project));
127 return m_txtBundleOutputFilename;
137 return m_csvSavedImagesFilename;
147 return m_csvSavedPointsFilename;
157 return m_csvSavedResidualsFilename;
201 oldInputFileName.
dir().dirName() +
"/" + oldInputFileName.
name());
206 oldOutputFileName.
dir().dirName() +
"/" + oldOutputFileName.
name());
212 m_outputControlName = newOutputFileName.
expanded();
233 return m_id->toString().remove(QRegExp(
"[{}]"));
289 return m_outputControlName;
309 m_outputControlName =
name;
319 return m_outputControlName;
355 "Results for this bundle is NULL.",
412 std::vector<QString> outputColumns;
414 outputColumns.push_back(
"Image,");
415 outputColumns.push_back(
"rms,");
416 outputColumns.push_back(
"rms,");
417 outputColumns.push_back(
"rms,");
419 QStringList observationParameters = observation->parameterList();
421 for (
int i = 0; i < observationParameters.size(); i++) {
422 for (
int j = 0; j < 5; j++) {
423 outputColumns.push_back(observationParameters[i] +
",");
428 int ncolumns = outputColumns.size();
429 for (
int i = 0; i < ncolumns; i++) {
430 QString str = outputColumns.at(i);
431 sprintf(buf,
"%s", (
const char*)str.toLatin1().data());
437 outputColumns.clear();
439 outputColumns.push_back(
"Filename,");
440 outputColumns.push_back(
"sample res,");
441 outputColumns.push_back(
"line res,");
442 outputColumns.push_back(
"total res,");
444 for (
int i = 0; i < observationParameters.size(); i++) {
445 outputColumns.push_back(
"Initial,");
446 outputColumns.push_back(
"Correction,");
447 outputColumns.push_back(
"Final,");
448 outputColumns.push_back(
"Apriori Sigma,");
449 outputColumns.push_back(
"Adj Sigma,");
453 ncolumns = outputColumns.size();
454 for (
int i = 0; i < ncolumns; i++) {
455 QString str = outputColumns.at(i);
456 sprintf(buf,
"%s", (
const char*)str.toLatin1().data());
488 for (
int i = 0; i < numObservations; i++) {
492 int numInnerConstraints = 0;
493 int numDistanceConstraints = 0;
500 int convergenceCriteria = 1;
502 sprintf(buf,
"JIGSAW: BUNDLE ADJUSTMENT\n=========================\n");
504 sprintf(buf,
"\n Run Time: %s",
507 sprintf(buf,
"\n Network Filename: %s",
511 sprintf(buf,
"\n Cube List: %s",
512 m_settings->cubeList().toStdString().c_str() );
516 sprintf(buf,
"\n Output Network Filename: %s",
519 sprintf(buf,
"\n Output File Prefix: %s",
520 m_settings->outputFilePrefix().toStdString().c_str() );
523 sprintf(buf,
"\n Network Id: %s",
526 sprintf(buf,
"\n Network Description: %s",\
529 sprintf(buf,
"\n Target: %s",
532 sprintf(buf,
"\n\n Linear Units: kilometers");
534 sprintf(buf,
"\n Angular Units: decimal degrees");
536 sprintf(buf,
"\n\nINPUT: SOLVE OPTIONS\n====================\n");
540 sprintf(buf,
"\n OBSERVATIONS: ON"):
541 sprintf(buf,
"\n OBSERVATIONS: OFF");
545 sprintf(buf,
"\n RADIUS: ON"):
546 sprintf(buf,
"\n RADIUS: OFF");
550 sprintf(buf,
"\n TARGET BODY: ON"):
551 sprintf(buf,
"\n TARGET BODY: OFF");
555 sprintf(buf,
"\n UPDATE: YES"):
556 sprintf(buf,
"\n UPDATE: NO");
560 sprintf(buf,
"\n ERROR PROPAGATION: ON"):
561 sprintf(buf,
"\n ERROR PROPAGATION: OFF");
565 sprintf(buf,
"\n CONTROL POINT COORDINATE TYPE FOR REPORTS: LATITUDINAL"):
566 sprintf(buf,
"\n CONTROL POINT COORDINATE TYPE FOR REPORTS: RECTANGULAR");
570 sprintf(buf,
"\n CONTROL POINT COORDINATE TYPE FOR BUNDLE: LATITUDINAL"):
571 sprintf(buf,
"\n CONTROL POINT COORDINATE TYPE FOR BUNDLE: RECTANGULAR");
575 sprintf(buf,
"\n OUTLIER REJECTION: ON");
577 sprintf(buf,
"\n REJECTION MULTIPLIER: %lf",
583 sprintf(buf,
"\n OUTLIER REJECTION: OFF");
585 sprintf(buf,
"\n REJECTION MULTIPLIER: N/A");
590 sprintf(buf,
"\n CONTROL POINT COORDINATE TYPE FOR REPORTS: %s",
594 sprintf(buf,
"\n CONTROL POINT COORDINATE TYPE FOR BUNDLE: %s",
597 sprintf(buf,
"\n\nMAXIMUM LIKELIHOOD ESTIMATION\n============================\n");
600 for (
int tier = 0; tier < 3; tier++) {
601 if (tier < m_statisticsResults->numberMaximumLikelihoodModels()) {
602 sprintf(buf,
"\n Tier %d Enabled: TRUE", tier);
604 sprintf(buf,
"\n Maximum Likelihood Model: %s",
607 maximumLikelihoodModelWFunc(tier).model()).toLatin1().data());
609 sprintf(buf,
"\n Quantile used for tweaking constant: %lf",
612 sprintf(buf,
"\n Quantile weighted R^2 Residual value: %lf",
615 sprintf(buf,
"\n Approx. weighted Residual cutoff: %s",
619 if (tier != 2) fpOut <<
"\n";
622 sprintf(buf,
"\n Tier %d Enabled: FALSE", tier);
627 sprintf(buf,
"\n\nINPUT: CONVERGENCE CRITERIA\n===========================\n");
629 sprintf(buf,
"\n SIGMA0: %e",
632 sprintf(buf,
"\n MAXIMUM ITERATIONS: %d",
633 m_settings->convergenceCriteriaMaximumIterations());
647 sprintf(buf,
"\n\nINPUT: CAMERA POINTING OPTIONS\n==============================\n");
649 switch (pointingSolveDegree) {
651 sprintf(buf,
"\n CAMSOLVE: NONE");
654 sprintf(buf,
"\n CAMSOLVE: ANGLES");
657 sprintf(buf,
"\n CAMSOLVE: ANGLES, VELOCITIES");
660 sprintf(buf,
"\n CAMSOLVE: ANGLES, VELOCITIES, ACCELERATIONS");
663 sprintf(buf,
"\n CAMSOLVE: ALL POLYNOMIAL COEFFICIENTS (%d)"
665 "\n CKSOLVEDEGREE: %d",
673 sprintf(buf,
"\n TWIST: ON"):
674 sprintf(buf,
"\n TWIST: OFF");
677 sprintf(buf,
"\n POLYNOMIAL OVER EXISTING POINTING: ON"):
678 sprintf(buf,
"\nPOLYNOMIAL OVER EXISTING POINTING : OFF");
681 sprintf(buf,
"\n\nINPUT: SPACECRAFT OPTIONS\n=========================\n");
683 switch (positionSolveDegree) {
685 sprintf(buf,
"\n SPSOLVE: NONE");
688 sprintf(buf,
"\n SPSOLVE: POSITION");
691 sprintf(buf,
"\n SPSOLVE: POSITION, VELOCITIES");
694 sprintf(buf,
"\n SPSOLVE: POSITION, VELOCITIES, ACCELERATIONS");
697 sprintf(buf,
"\n SPSOLVE: ALL POLYNOMIAL COEFFICIENTS (%d)"
699 "\n SPKSOLVEDEGREE: %d",
707 sprintf(buf,
"\n POLYNOMIAL OVER HERMITE SPLINE: ON"):
708 sprintf(buf,
"\nPOLYNOMIAL OVER HERMITE SPLINE : OFF");
711 sprintf(buf,
"\n\nINPUT: GLOBAL IMAGE PARAMETER UNCERTAINTIES\n===========================================\n");
715 switch (
m_settings->controlPointCoordTypeReports()) {
717 coord1Str =
"LATITUDE";
718 coord2Str =
"LONGITUDE";
719 coord3Str =
"RADIUS";
727 IString msg =
"Unknown surface point coordinate type enum ["
736 sprintf(buf,
"\n POINT %s SIGMA: N/A", coord1Str.toLatin1().data()):
737 sprintf(buf,
"\n POINT %s SIGMA: %lf (meters)", coord1Str.toLatin1().data(),
742 sprintf(buf,
"\n POINT %s SIGMA: N/A", coord2Str.toLatin1().data()):
743 sprintf(buf,
"\n POINT %s SIGMA: %lf (meters)", coord2Str.toLatin1().data(),
748 sprintf(buf,
"\n POINT %s SIGMA: N/A", coord3Str.toLatin1().data()):
749 sprintf(buf,
"\n POINT %s SIGMA: %lf (meters)", coord3Str.toLatin1().data(),
752 (positionSolveDegree < 1 || positionSigmas[0] ==
Isis::Null) ?
753 sprintf(buf,
"\n SPACECRAFT POSITION SIGMA: N/A"):
754 sprintf(buf,
"\n SPACECRAFT POSITION SIGMA: %lf (meters)",
758 (positionSolveDegree < 2 || positionSigmas[1] ==
Isis::Null) ?
759 sprintf(buf,
"\n SPACECRAFT VELOCITY SIGMA: N/A"):
760 sprintf(buf,
"\n SPACECRAFT VELOCITY SIGMA: %lf (m/s)",
764 (positionSolveDegree < 3 || positionSigmas[2] ==
Isis::Null) ?
765 sprintf(buf,
"\n SPACECRAFT ACCELERATION SIGMA: N/A"):
766 sprintf(buf,
"\n SPACECRAFT ACCELERATION SIGMA: %lf (m/s/s)",
770 (pointingSolveDegree < 1 || pointingSigmas[0] ==
Isis::Null) ?
771 sprintf(buf,
"\n CAMERA ANGLES SIGMA: N/A"):
772 sprintf(buf,
"\n CAMERA ANGLES SIGMA: %lf (dd)",
776 (pointingSolveDegree < 2 || pointingSigmas[1] ==
Isis::Null) ?
777 sprintf(buf,
"\n CAMERA ANGULAR VELOCITY SIGMA: N/A"):
778 sprintf(buf,
"\n CAMERA ANGULAR VELOCITY SIGMA: %lf (dd/s)",
782 (pointingSolveDegree < 3 || pointingSigmas[2] ==
Isis::Null) ?
783 sprintf(buf,
"\n CAMERA ANGULAR ACCELERATION SIGMA: N/A"):
784 sprintf(buf,
"\n CAMERA ANGULAR ACCELERATION SIGMA: %lf (dd/s/s)",
789 sprintf(buf,
"\n\nINPUT: TARGET BODY OPTIONS\n==============================\n");
793 sprintf(buf,
"\n POLE: RIGHT ASCENSION");
795 sprintf(buf,
"\n : DECLINATION\n");
799 sprintf(buf,
"\n POLE: RIGHT ASCENSION\n");
803 sprintf(buf,
"\n POLE: DECLINATION\n");
809 sprintf(buf,
"\n PRIME MERIDIAN: W0 (OFFSET)");
813 sprintf(buf,
"\n : WDOT (SPIN RATE)");
817 sprintf(buf,
"\n :W ACCELERATION");
824 sprintf(buf,
"\n RADII: MEAN");
828 sprintf(buf,
"\n RADII: TRIAXIAL");
834 sprintf(buf,
"\n\nJIGSAW: RESULTS\n===============\n");
836 sprintf(buf,
"\n Images: %6d",numImages);
838 sprintf(buf,
"\n Points: %6d",numValidPoints);
841 sprintf(buf,
"\n Total Measures: %6d",
846 sprintf(buf,
"\n Total Observations: %6d",
851 sprintf(buf,
"\n Good Observations: %6d",
855 sprintf(buf,
"\n Rejected Observations: %6d",
860 sprintf(buf,
"\n Constrained Point Parameters: %6d",
866 sprintf(buf,
"\n Constrained Image Parameters: %6d",
872 sprintf(buf,
"\n Constrained Target Parameters: %6d",
877 sprintf(buf,
"\n Unknowns: %6d",
881 if (numInnerConstraints > 0) {
882 sprintf(buf,
"\n Inner Constraints: %6d", numInnerConstraints);
886 if (numDistanceConstraints > 0) {
887 sprintf(buf,
"\n Distance Constraints: %d", numDistanceConstraints);
891 sprintf(buf,
"\n Degrees of Freedom: %6d", numDegreesOfFreedom);
894 sprintf(buf,
"\n Convergence Criteria: %6.3g",
898 if (convergenceCriteria == 1) {
899 sprintf(buf,
"(Sigma0)");
907 sprintf(buf,
"(Maximum reached)");
913 sprintf(buf,
" Error Propagation Elapsed Time: %6.4lf (seconds)\n",
916 sprintf(buf,
" Total Elapsed Time: %6.4lf (seconds)\n",
922 sprintf(buf,
"\n Residual Percentiles:\n");
928 for (
int bin = 1;bin < 34;bin++) {
929 double cumProb = double(bin) / 100.0;
932 residualsCumulativeProbabilityDistribution().value(cumProb);
935 residualsCumulativeProbabilityDistribution().value(cumProb + 0.33);
938 residualsCumulativeProbabilityDistribution().value(cumProb + 0.66);
939 sprintf(buf,
" Percentile %3d: %+8.3lf"
940 " Percentile %3d: %+8.3lf"
941 " Percentile %3d: %+8.3lf\n",
943 bin + 33, resValue33,
944 bin + 66, resValue66);
949 QString msg =
"Failed to output residual percentiles for bundleout";
953 sprintf(buf,
"\n Residual Box Plot:");
955 sprintf(buf,
"\n minimum: %+8.3lf",
958 sprintf(buf,
"\n Quartile 1: %+8.3lf",
961 sprintf(buf,
"\n Median: %+8.3lf",
964 sprintf(buf,
"\n Quartile 3: %+8.3lf",
967 sprintf(buf,
"\n maximum: %+8.3lf\n",
972 QString msg =
"Failed to output residual box plot for bundleout";
981 for (
int i = 0; i < numObservations; i++) {
985 for (
int j = 0; j < numImagesInObservation; j++) {
988 if (bundleImage->fileName().length() > filePadding) {
989 filePadding = bundleImage->fileName().length();
994 sprintf(buf,
"\nIMAGE MEASURES SUMMARY\n==========================\n\n");
999 QString header(
"Measures RMS(pixels)");
1001 sprintf(buf,
"%*s\n", header.length() + 11 + filePadding, header.toLatin1().data());
1004 QString dividers(
"*************************** *******************************************");
1005 sprintf(buf,
"%*s\n", dividers.length() + 1 + filePadding, dividers.toLatin1().data());
1008 QString fields(
"| Accepted | Total | | Samples | Lines | Total |");
1009 sprintf(buf,
"%*s\n", fields.length() + 1 + filePadding, fields.toLatin1().data());
1013 int numRejectedMeasures;
1016 Statistics rmsSamplesTotal,rmsLinesTotal,rmsTotals;
1018 for (
int i = 0; i < numObservations; i++) {
1022 for (
int j = 0; j < numImagesInObservation; j++) {
1027 rmsImageSampleResiduals()[imageIndex].Rms();
1029 rmsImageLineResiduals()[imageIndex].Rms();
1031 rmsImageResiduals()[imageIndex].Rms();
1032 rmsSamplesTotal.
AddData(rmsSampleResiduals);
1033 rmsLinesTotal.
AddData(rmsLineResiduals);
1034 rmsTotals.
AddData(rmsLandSResiduals);
1037 (bundleImage->serialNumber());
1040 GetNumberOfJigsawRejectedMeasuresInImage(bundleImage->serialNumber());
1042 numUsed = numMeasures - numRejectedMeasures;
1044 QString filename = bundleImage->fileName();
1046 List = filename.split(
"/");
1048 sprintf(buf,
"%-*s" ,filePadding + 1, bundleImage->fileName().toLatin1().data());
1051 sprintf(buf,
" %12d %12d ", numUsed, numMeasures);
1054 sprintf(buf,
"%13.4lf %13.4lf %13.4lf \n",
1055 rmsSampleResiduals,rmsLineResiduals,rmsLandSResiduals);
1064 sprintf(buf,
"%*s", -(filePadding + 33),
"\nTotal RMS:");
1066 sprintf(buf,
"%13.4lf %13.4lf %13.4lf\n",
1067 rmsSamplesTotal.
Rms(),rmsLinesTotal.
Rms(),rmsTotals.
Rms());
1093 bool errorProp =
false;
1101 if (instrumentIds.size() == 1) {
1102 QString ofname =
"bundleout_images.csv";
1103 ofname =
m_settings->outputFilePrefix() + ofname;
1104 m_csvSavedImagesFilename = ofname;
1105 outputCsvFileNames.push_back(ofname);
1109 for (
int i = 0; i < instrumentIds.size(); i++) {
1110 QString updatedInstrumentId = instrumentIds[i];
1114 updatedInstrumentId.replace(
"/",
"_").replace(
" ",
"_");
1115 QString ofname =
"bundleout_images_" + updatedInstrumentId +
".csv";
1116 ofname =
m_settings->outputFilePrefix() + ofname;
1117 m_csvSavedImagesFilename = ofname;
1118 outputCsvFileNames.push_back(ofname);
1122 for (
int i = 0; i < instrumentIds.size(); i++) {
1124 std::ofstream fpOut(outputCsvFileNames[i].toLatin1().data(), std::ios::out);
1132 int nObservations = observations.size();
1136 for (
int j = 0; j < nObservations; j++ ) {
1141 int observationIndex = observation->index();
1143 for (
int obsIndex = 0; obsIndex < observationIndex; obsIndex++) {
1151 int numImages = observation->size();
1153 for (
int k = 0; k < numImages; k++) {
1156 sprintf(buf,
"%s", image->fileName().toLatin1().data());
1161 fpOut <<
toString(rmsImageSampleResiduals[imgIndex].Rms()).toLatin1().data();
1165 fpOut <<
toString(rmsImageLineResiduals[imgIndex].Rms()).toLatin1().data();
1169 fpOut <<
toString(rmsImageResiduals[imgIndex].Rms()).toLatin1().data();
1173 QString observationString =
1174 observation->bundleOutputCSV(errorProp);
1177 if (observationString.right(1)==
",") {
1178 observationString.truncate(observationString.length()-1);
1181 fpOut << (
const char*) observationString.toLatin1().data();
1203 QString ofname =
"bundleout.txt";
1204 ofname =
m_settings->outputFilePrefix() + ofname;
1206 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1211 m_txtBundleOutputFilename = ofname;
1220 bool berrorProp =
false;
1227 sprintf(buf,
"\nTARGET BODY\n==========================\n");
1230 sprintf(buf,
"\n Target Initial Total "
1231 "Final Initial Final\n"
1232 "Parameter Value Correction "
1233 "Value Accuracy Accuracy\n");
1236 QString targetString =
1237 m_settings->bundleTargetBody()->formatBundleOutputString(berrorProp);
1238 fpOut << (
const char*)targetString.toLatin1().data();
1242 sprintf(buf,
"\nIMAGE EXTERIOR ORIENTATION\n==========================\n");
1248 imagesAndParameters.insert(
"target",
m_settings->bundleTargetBody()->parameterList() );
1251 for (
int i = 0; i < nObservations; i++) {
1258 int numImages = observation->size();
1259 for (
int j = 0; j < numImages; j++) {
1261 sprintf(buf,
"\nImage Full File Name: %s\n", image->fileName().toLatin1().data());
1263 sprintf(buf,
"\nImage Serial Number: %s\n", image->serialNumber().toLatin1().data());
1266 sprintf(buf,
"Image Initial Total Final Accuracy\n");
1268 sprintf(buf,
"Parameter Value Correction Value Initial Final Units\n");
1272 "***************************************\n");
1275 observation->bundleOutputString(fpOut,berrorProp);
1277 foreach ( QString image, observation->imageNames() ) {
1278 imagesAndParameters.insert( image, observation->parameterList() );
1291 sprintf(buf,
"\n\n\nPOINTS UNCERTAINTY SUMMARY\n==========================\n\n");
1298 sprintf(buf,
"RMS Sigma %s(m)%20.8lf\n", coordName.toLatin1().data(),
1301 sprintf(buf,
"MIN Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1305 sprintf(buf,
"MAX Sigma %s(m)%20.8lf at %s\n\n", coordName.toLatin1().data(),
1313 sprintf(buf,
"RMS Sigma %s(m)%20.8lf\n", coordName.toLatin1().data(),
1316 sprintf(buf,
"MIN Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1320 sprintf(buf,
"MAX Sigma %s(m)%20.8lf at %s\n\n", coordName.toLatin1().data(),
1327 SurfacePoint::Three);
1329 sprintf(buf,
"RMS Sigma %s(m)%20.8lf\n", coordName.toLatin1().data(),
1332 sprintf(buf,
"MIN Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1336 sprintf(buf,
"MAX Sigma %s(m)%20.8lf at %s\n", coordName.toLatin1().data(),
1342 sprintf(buf,
" RMS Sigma Radius(m) N/A\n");
1344 sprintf(buf,
" MIN Sigma Radius(m) N/A\n");
1346 sprintf(buf,
" MAX Sigma Radius(m) N/A\n");
1353 sprintf(buf,
"\n\nPOINTS SUMMARY\n==============\n%103s"
1354 "Sigma Sigma Sigma\n"
1355 " Label Status Rays RMS"
1356 " Latitude Longitude Radius"
1357 " Latitude Longitude Radius\n",
"");
1360 sprintf(buf,
"\n\nPOINTS SUMMARY\n==============\n%103s"
1361 "Sigma Sigma Sigma\n"
1362 " Label Status Rays RMS"
1363 " Point X Point Y Point Z"
1364 " Point X Point Y Point Z\n",
"");
1369 for (
int i = 0; i < nPoints; i++) {
1372 QString pointSummaryString =
1373 bundleControlPoint->formatBundleOutputSummaryString(berrorProp);
1374 fpOut << (
const char*)pointSummaryString.toLatin1().data();
1378 sprintf(buf,
"\n\nPOINTS DETAIL\n=============\n\n");
1381 bool solveRadius =
m_settings->solveRadius();
1383 for (
int i = 0; i < nPoints; i++) {
1387 QString pointDetailString =
1388 bundleControlPoint->formatBundleOutputDetailString(berrorProp,
1390 fpOut << (
const char*)pointDetailString.toLatin1().data();
1407 QString ofname =
"bundleout_points.csv";
1408 ofname =
m_settings->outputFilePrefix() + ofname;
1409 m_csvSavedPointsFilename = ofname;
1411 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1418 double dLat, dLon, dRadius;
1420 double dSigmaLat, dSigmaLong, dSigmaRadius;
1425 int numMeasures, numRejectedMeasures;
1426 double dResidualRms;
1430 sprintf(buf,
",,,,,3-d,3-d,3-d,Sigma,Sigma,Sigma,Correction,Correction,Correction,Coordinate,"
1431 "Coordinate,Coordinate\nPoint,Point,Accepted,Rejected,Residual,Latitude,Longitude,"
1432 "Radius,Latitude,Longitude,Radius,Latitude,Longitude,Radius,X,Y,Z\nLabel,Status,"
1433 "Measures,Measures,RMS,(dd),(dd),(km),(m),(m),(m),(m),(m),(m),(km),(km),(km)\n");
1436 sprintf(buf,
",,,,,3-d,3-d,3-d,Correction,Correction,Correction,Coordinate,Coordinate,"
1437 "Coordinate\nPoint,Point,Accepted,Rejected,Residual,Latitude,Longitude,Radius,"
1438 "Latitude,Longitude,Radius,X,Y,Z\nLabel,Status,Measures,Measures,RMS,(dd),(dd),(km),"
1439 "(m),(m),(m),(km),(km),(km)\n");
1443 for (
int i = 0; i < numPoints; i++) {
1446 if (!bundlecontrolpoint) {
1450 if (bundlecontrolpoint->isRejected()) {
1454 dLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatitude().degrees();
1455 dLon = bundlecontrolpoint->adjustedSurfacePoint().GetLongitude().degrees();
1456 dRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadius().kilometers();
1457 dX = bundlecontrolpoint->adjustedSurfacePoint().GetX().kilometers();
1458 dY = bundlecontrolpoint->adjustedSurfacePoint().GetY().kilometers();
1459 dZ = bundlecontrolpoint->adjustedSurfacePoint().GetZ().kilometers();
1460 numMeasures = bundlecontrolpoint->numberOfMeasures();
1461 numRejectedMeasures = bundlecontrolpoint->numberOfRejectedMeasures();
1462 dResidualRms = bundlecontrolpoint->residualRms();
1465 boost::numeric::ublas::bounded_vector< double, 3 > corrections = bundlecontrolpoint->
1468 cor_lat_m = bundlecontrolpoint->adjustedSurfacePoint().LatitudeToMeters(corrections[0]);
1469 cor_lon_m = bundlecontrolpoint->adjustedSurfacePoint().LongitudeToMeters(corrections[1]);
1470 cor_rad_m = corrections[2]*1000.0;
1473 strStatus =
"FIXED";
1476 strStatus =
"CONSTRAINED";
1482 strStatus =
"UNKNOWN";
1486 dSigmaLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatSigmaDistance().meters();
1487 dSigmaLong = bundlecontrolpoint->adjustedSurfacePoint().GetLonSigmaDistance().meters();
1488 dSigmaRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadiusSigma().meters();
1490 sprintf(buf,
"%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
1491 "%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf\n",
1492 bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
1493 numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, dSigmaLat,
1494 dSigmaLong, dSigmaRadius, cor_lat_m, cor_lon_m, cor_rad_m, dX, dY, dZ);
1497 sprintf(buf,
"%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
1498 "%16.8lf,%16.8lf\n",
1499 bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
1500 numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, cor_lat_m,
1501 cor_lon_m, cor_rad_m, dX, dY, dZ);
1520 QString ofname =
"residuals.csv";
1521 ofname =
m_settings->outputFilePrefix() + ofname;
1522 m_csvSavedResidualsFilename = ofname;
1524 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1531 sprintf(buf,
",,,x image,y image,Measured,Measured,sample,line,Residual Vector\n");
1533 sprintf(buf,
"Point,Image,Image,coordinate,coordinate,"
1534 "Sample,Line,residual,residual,Magnitude\n");
1536 sprintf(buf,
"Label,Filename,Serial Number,(mm),(mm),"
1537 "(pixels),(pixels),(pixels),(pixels),(pixels),Rejected\n");
1543 int numMeasures = 0;
1548 for (
int i = 0; i < numPoints; i++) {
1550 numMeasures = bundleControlPoint->size();
1552 if (bundleControlPoint->rawControlPoint()->IsIgnored()) {
1556 for (
int j = 0; j < numMeasures; j++) {
1557 bundleMeasure = bundleControlPoint->at(j);
1559 Camera *measureCamera = bundleMeasure->camera();
1560 if (!measureCamera) {
1564 if (bundleMeasure->isRejected()) {
1565 sprintf(buf,
"%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,*\n",
1566 bundleControlPoint->id().toLatin1().data(),
1567 bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1568 bundleMeasure->cubeSerialNumber().toLatin1().data(),
1569 bundleMeasure->focalPlaneMeasuredX(),
1570 bundleMeasure->focalPlaneMeasuredY(),
1571 bundleMeasure->sample(),
1572 bundleMeasure->line(),
1573 bundleMeasure->sampleResidual(),
1574 bundleMeasure->lineResidual(),
1575 bundleMeasure->residualMagnitude());
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());
1622 QString relativePath;
1623 QString relativeBundlePath;
1632 if (oldPath != newPath) {
1634 QDir bundleDir(newPath);
1635 if (!bundleDir.mkpath(bundleDir.path())) {
1637 QString(
"Failed to create directory [%1]")
1638 .arg(bundleSolutionInfoRoot.
path()),
1643 if (!QFile::copy(oldFile, newFile)) {
1645 QString(
"Failed to copy file [%1] to new file [%2]")
1649 newFile = newPath +
"/" +
FileName(m_txtBundleOutputFilename).
name();
1650 if (!QFile::copy(m_txtBundleOutputFilename, newFile)) {
1652 QString(
"Failed to copy file [%1] to new file [%2]")
1653 .arg(m_txtBundleOutputFilename).arg(newFile),
1656 newFile = newPath +
"/" +
FileName(m_csvSavedImagesFilename).
name();
1657 if (!QFile::copy(m_csvSavedImagesFilename, newFile)) {
1659 QString(
"Failed to copy file [%1] to new file [%2]")
1660 .arg(m_csvSavedImagesFilename).arg(newFile),
1663 newFile = newPath +
"/" +
FileName(m_csvSavedPointsFilename).
name();
1664 if (!QFile::copy(m_csvSavedPointsFilename, newFile)) {
1666 QString(
"Failed to copy file [%1] to new file [%2]")
1667 .arg(m_csvSavedPointsFilename).arg(newFile),
1670 newFile = newPath +
"/" +
FileName(m_csvSavedResidualsFilename).
name();
1671 if (!QFile::copy(m_csvSavedResidualsFilename, newFile)) {
1673 QString(
"Failed to copy file [%1] to new file [%2]")
1674 .arg(m_csvSavedResidualsFilename).arg(newFile),
1682 if (relativePath.startsWith(
"/")) {
1683 relativePath.remove(0,1);
1689 if (relativeBundlePath.startsWith(
"/")) {
1690 relativeBundlePath.remove(0,1);
1692 relativeBundlePath +=
"/";
1697 stream.writeStartElement(
"bundleSolutionInfo");
1699 stream.writeStartElement(
"generalAttributes");
1700 stream.writeTextElement(
"id",
m_id->toString());
1701 stream.writeTextElement(
"name",
m_name);
1702 stream.writeTextElement(
"runTime",
runTime());
1704 stream.writeTextElement(
"inputFileName",
1706 stream.writeTextElement(
"bundleOutTXT",
1707 relativeBundlePath +
FileName(m_txtBundleOutputFilename).
name());
1708 stream.writeTextElement(
"imagesCSV",
1709 relativeBundlePath +
FileName(m_csvSavedImagesFilename).
name());
1710 stream.writeTextElement(
"pointsCSV",
1711 relativeBundlePath +
FileName(m_csvSavedPointsFilename).
name());
1712 stream.writeTextElement(
"residualsCSV",
1713 relativeBundlePath +
FileName(m_csvSavedResidualsFilename).
name());
1714 stream.writeEndElement();
1725 stream.writeStartElement(
"imageLists");
1729 stream.writeEndElement();
1733 stream.writeStartElement(
"outputControl");
1735 stream.writeEndElement();
1738 stream.writeEndElement();
1752 m_xmlHandlerProject = project;
1772 m_xmlHandlerCharacters += ch;
1773 return XmlStackedHandler::characters(ch);
1788 const QString &localName,
1789 const QString &qName,
1790 const QXmlAttributes &atts) {
1791 m_xmlHandlerCharacters =
"";
1793 if (XmlStackedHandler::startElement(namespaceURI, localName, qName, atts)) {
1795 if (localName ==
"bundleSettings") {
1796 m_xmlHandlerBundleSolutionInfo->m_settings =
1799 else if (localName ==
"bundleResults") {
1800 m_xmlHandlerBundleSolutionInfo->m_statisticsResults =
new BundleResults(m_xmlHandlerProject,
1803 else if (localName ==
"imageList") {
1804 m_xmlHandlerBundleSolutionInfo->m_adjustedImages->append(
1805 new ImageList(m_xmlHandlerProject, reader()));
1807 else if (localName ==
"outputControl") {
1808 FileName outputControlPath =
FileName(m_xmlHandlerProject->bundleSolutionInfoRoot() +
"/"
1809 + m_xmlHandlerBundleSolutionInfo->runTime());
1811 m_xmlHandlerBundleSolutionInfo->m_outputControl =
new Control(outputControlPath, reader());
1828 const QString &localName,
1829 const QString &qName) {
1831 QString projectRoot;
1832 if (m_xmlHandlerProject) {
1833 projectRoot = m_xmlHandlerProject->projectRoot() +
"/";
1836 if (localName ==
"id") {
1838 assert(m_xmlHandlerBundleSolutionInfo->m_id);
1839 delete m_xmlHandlerBundleSolutionInfo->m_id;
1840 m_xmlHandlerBundleSolutionInfo->m_id =
new QUuid(m_xmlHandlerCharacters);
1842 else if (localName ==
"name") {
1843 m_xmlHandlerBundleSolutionInfo->m_name = m_xmlHandlerCharacters;
1845 else if (localName ==
"runTime") {
1846 m_xmlHandlerBundleSolutionInfo->m_runTime = m_xmlHandlerCharacters;
1848 else if (localName ==
"inputFileName") {
1849 assert(m_xmlHandlerBundleSolutionInfo->m_inputControlNetFileName == NULL);
1850 m_xmlHandlerBundleSolutionInfo->m_inputControlNetFileName =
new FileName(
1851 projectRoot + m_xmlHandlerCharacters);
1853 else if (localName ==
"bundleOutTXT") {
1854 m_xmlHandlerBundleSolutionInfo->m_txtBundleOutputFilename =
1855 projectRoot + m_xmlHandlerCharacters;
1857 else if (localName ==
"imagesCSV") {
1858 m_xmlHandlerBundleSolutionInfo->m_csvSavedImagesFilename =
1859 projectRoot + m_xmlHandlerCharacters;
1861 else if (localName ==
"pointsCSV") {
1862 m_xmlHandlerBundleSolutionInfo->m_csvSavedPointsFilename =
1863 projectRoot + m_xmlHandlerCharacters;
1865 else if (localName ==
"residualsCSV") {
1866 m_xmlHandlerBundleSolutionInfo->m_csvSavedResidualsFilename =
1867 projectRoot + m_xmlHandlerCharacters;
1870 m_xmlHandlerCharacters =
"";
1871 return XmlStackedHandler::endElement(namespaceURI, localName, qName);
1884 SurfacePoint::CoordIndex coordIdx)
const {
1886 switch (
m_settings->controlPointCoordTypeReports()) {
1889 case SurfacePoint::One:
1890 coordName =
" Latitude";
1892 case SurfacePoint::Two:
1893 coordName =
"Longitude";
1895 case SurfacePoint::Three:
1896 coordName =
" Radius";
1899 IString msg =
"Unknown surface point index enum ["
1907 case SurfacePoint::One:
1908 coordName =
"POINT X";
1910 case SurfacePoint::Two:
1911 coordName =
"POINT Y";
1913 case SurfacePoint::Three:
1914 coordName =
"POINT Z";
1917 IString msg =
"Unknown surface point index enum ["
1924 IString msg =
"Unknown surface point coordinate type enum ["