8 #include <QXmlStreamWriter>
19 #include "ImageList.h"
26 #include "XmlStackedHandlerReader.h"
43 m_id =
new QUuid(QUuid::createUuid());
67 BundleSolutionInfo::BundleSolutionInfo(
Project *project,
74 xmlReader->pushContentHandler(
new XmlHandler(
this, project));
75 xmlReader->setErrorHandler(
new XmlHandler(
this, project));
84 BundleSolutionInfo::BundleSolutionInfo(
FileName bundleSolutionInfoFile) {
86 m_id =
new QUuid(QUuid::createUuid());
105 : m_id(new QUuid(src.m_id->
toString())),
106 m_runTime(src.m_runTime),
107 m_controlNetworkFileName(new
FileName(src.m_controlNetworkFileName->expanded())),
109 m_statisticsResults(new
BundleResults(*src.m_statisticsResults)),
152 m_id =
new QUuid(src.
m_id->toString());
195 QString statisticsName) {
229 stream.writeStartElement(
"bundleSolutionInfo");
231 stream.writeStartElement(
"generalAttributes");
232 stream.writeTextElement(
"id",
m_id->toString());
233 stream.writeTextElement(
"runTime",
runTime());
235 stream.writeEndElement();
245 stream.writeStartElement(
"imageLists");
247 for (
int i = 0; i <
m_images->count(); i++) {
248 m_images->at(i)->save(stream, project,
"");
251 stream.writeEndElement();
253 stream.writeEndElement();
265 stream.writeStartElement(
"bundleSolutionInfo");
267 stream.writeStartElement(
"generalAttributes");
268 stream.writeTextElement(
"id",
m_id->toString());
269 stream.writeTextElement(
"runTime",
runTime());
271 stream.writeEndElement();
281 stream.writeStartElement(
"imageLists");
283 for (
int i = 0; i <
m_images->count(); i++) {
284 m_images->at(i)->save(stream, project,
"");
287 stream.writeEndElement();
289 stream.writeEndElement();
308 oldFileName.dir().dirName() +
"/" + oldFileName.name());
324 m_xmlHandlerProject = NULL;
325 m_xmlHandlerProject = project;
343 m_xmlHandlerProject = NULL;
345 delete m_xmlHandlerImages;
346 m_xmlHandlerImages = NULL;
348 delete m_xmlHandlerBundleResults;
349 m_xmlHandlerBundleResults = NULL;
364 const QString &localName,
365 const QString &qName,
366 const QXmlAttributes &atts) {
367 m_xmlHandlerCharacters =
"";
369 if (XmlStackedHandler::startElement(namespaceURI, localName, qName, atts)) {
371 if (localName ==
"bundleSettings") {
372 m_xmlHandlerBundleSettings =
375 else if (localName ==
"bundleResults") {
376 delete m_xmlHandlerBundleResults;
377 m_xmlHandlerBundleResults = NULL;
380 m_xmlHandlerBundleResults =
new BundleResults(m_xmlHandlerProject, reader());
382 else if (localName ==
"imageList") {
383 m_xmlHandlerImages->append(
new ImageList(m_xmlHandlerProject, reader()));
398 m_xmlHandlerCharacters += ch;
399 return XmlStackedHandler::characters(ch);
413 const QString &localName,
414 const QString &qName) {
415 if (localName ==
"id") {
416 m_xmlHandlerBundleSolutionInfo->m_id = NULL;
417 m_xmlHandlerBundleSolutionInfo->m_id =
new QUuid(m_xmlHandlerCharacters);
419 else if (localName ==
"runTime") {
420 m_xmlHandlerBundleSolutionInfo->m_runTime = m_xmlHandlerCharacters;
422 else if (localName ==
"fileName") {
423 m_xmlHandlerBundleSolutionInfo->m_controlNetworkFileName = NULL;
424 m_xmlHandlerBundleSolutionInfo->m_controlNetworkFileName =
new FileName(m_xmlHandlerCharacters);
426 else if (localName ==
"bundleSettings") {
427 m_xmlHandlerBundleSolutionInfo->m_settings =
430 else if (localName ==
"bundleResults") {
431 m_xmlHandlerBundleSolutionInfo->m_statisticsResults =
new BundleResults(*m_xmlHandlerBundleResults);
432 delete m_xmlHandlerBundleResults;
433 m_xmlHandlerBundleResults = NULL;
435 if (localName ==
"imageLists") {
436 for (
int i = 0; i < m_xmlHandlerImages->size(); i++) {
437 m_xmlHandlerBundleSolutionInfo->m_images->append(m_xmlHandlerImages->at(i));
439 m_xmlHandlerImages->clear();
441 m_xmlHandlerCharacters =
"";
442 return XmlStackedHandler::endElement(namespaceURI, localName, qName);
452 return m_id->toString().remove(QRegExp(
"[{}]"));
518 "Results for this bundle is NULL.",
547 std::vector<QString> outputColumns;
549 outputColumns.push_back(
"Image,");
550 outputColumns.push_back(
"rms,");
551 outputColumns.push_back(
"rms,");
552 outputColumns.push_back(
"rms,");
560 if (numberCamPosCoefSolved > 0)
561 nCoeff = numberCamPosCoefSolved;
563 for (
int i = 0; i < nCoeff; i++) {
564 for (
int j = 0; j < 5; j++) {
566 outputColumns.push_back(
"X,");
568 QString str =
"X(t" +
toString(i) +
"),";
569 outputColumns.push_back(str);
573 for (
int i = 0; i < nCoeff; i++) {
574 for (
int j = 0; j < 5; j++) {
576 outputColumns.push_back(
"Y,");
578 QString str =
"Y(t" +
toString(i) +
"),";
579 outputColumns.push_back(str);
583 for (
int i = 0; i < nCoeff; i++) {
584 for (
int j = 0; j < 5; j++) {
586 outputColumns.push_back(
"Z,");
589 QString str =
"Z(t" +
toString(i) +
"),";
590 outputColumns.push_back(str);
597 for (
int i = 0; i < numberCamAngleCoefSolved; i++) {
598 for (
int j = 0; j < 5; j++) {
599 if (numberCamAngleCoefSolved == 1)
600 outputColumns.push_back(
"RA,");
602 QString str =
"RA(t" +
toString(i) +
"),";
603 outputColumns.push_back(str);
607 for (
int i = 0; i < numberCamAngleCoefSolved; i++) {
608 for (
int j = 0; j < 5; j++) {
609 if (numberCamAngleCoefSolved == 1)
610 outputColumns.push_back(
"DEC,");
612 QString str =
"DEC(t" +
toString(i) +
"),";
613 outputColumns.push_back(str);
617 for (
int i = 0; i < numberCamAngleCoefSolved; i++) {
618 for (
int j = 0; j < 5; j++) {
619 if (numberCamAngleCoefSolved == 1) {
620 outputColumns.push_back(
"TWIST,");
623 QString str =
"TWIST(t" +
toString(i) +
"),";
624 outputColumns.push_back(str);
630 int ncolumns = outputColumns.size();
631 for (
int i = 0; i < ncolumns; i++) {
632 QString str = outputColumns.at(i);
633 sprintf(buf,
"%s", (
const char*)str.toLatin1().data());
639 outputColumns.clear();
640 outputColumns.push_back(
"Filename,");
642 outputColumns.push_back(
"sample res,");
643 outputColumns.push_back(
"line res,");
644 outputColumns.push_back(
"total res,");
649 if (numberCamPosCoefSolved)
650 nparams = 3 * numberCamPosCoefSolved;
653 int numCameraAnglesSolved = 3;
655 nparams += numCameraAnglesSolved*numberCamAngleCoefSolved;
656 for (
int i = 0; i < nparams; i++) {
657 outputColumns.push_back(
"Initial,");
658 outputColumns.push_back(
"Correction,");
659 outputColumns.push_back(
"Final,");
660 outputColumns.push_back(
"Apriori Sigma,");
661 outputColumns.push_back(
"Adj Sigma,");
665 ncolumns = outputColumns.size();
666 for (
int i = 0; i < ncolumns; i++) {
667 QString str = outputColumns.at(i);
668 sprintf(buf,
"%s", (
const char*)str.toLatin1().data());
700 for (
int i = 0; i < numObservations; i++) {
704 int numInnerConstraints = 0;
705 int numDistanceConstraints = 0;
712 int convergenceCriteria = 1;
714 sprintf(buf,
"JIGSAW: BUNDLE ADJUSTMENT\n=========================\n");
716 sprintf(buf,
"\n Run Time: %s",
719 sprintf(buf,
"\n Network Filename: %s",
722 sprintf(buf,
"\n Network Id: %s",
725 sprintf(buf,
"\n Network Description: %s",\
728 sprintf(buf,
"\n Target: %s",
731 sprintf(buf,
"\n\n Linear Units: kilometers");
733 sprintf(buf,
"\n Angular Units: decimal degrees");
735 sprintf(buf,
"\n\nINPUT: SOLVE OPTIONS\n====================\n");
739 sprintf(buf,
"\n OBSERVATIONS: ON"):
740 sprintf(buf,
"\n OBSERVATIONS: OFF");
744 sprintf(buf,
"\n RADIUS: ON"):
745 sprintf(buf,
"\n RADIUS: OFF");
749 sprintf(buf,
"\n TARGET BODY: ON"):
750 sprintf(buf,
"\n TARGET BODY: OFF");
754 sprintf(buf,
"\n UPDATE: YES"):
755 sprintf(buf,
"\n UPDATE: NO");
759 sprintf(buf,
"\n ERROR PROPAGATION: ON"):
760 sprintf(buf,
"\n ERROR PROPAGATION: OFF");
764 sprintf(buf,
"\n OUTLIER REJECTION: ON");
766 sprintf(buf,
"\n REJECTION MULTIPLIER: %lf",
772 sprintf(buf,
"\n OUTLIER REJECTION: OFF");
774 sprintf(buf,
"\n REJECTION MULTIPLIER: N/A");
778 sprintf(buf,
"\n\nMAXIMUM LIKELIHOOD ESTIMATION\n============================\n");
781 for (
int tier = 0; tier < 3; tier++) {
782 if (tier < m_statisticsResults->numberMaximumLikelihoodModels()) {
783 sprintf(buf,
"\n Tier %d Enabled: TRUE", tier);
785 sprintf(buf,
"\n Maximum Likelihood Model: %s",
788 maximumLikelihoodModelWFunc(tier).model()).toLatin1().data());
790 sprintf(buf,
"\n Quantile used for tweaking constant: %lf",
793 sprintf(buf,
"\n Quantile weighted R^2 Residual value: %lf",
796 sprintf(buf,
"\n Approx. weighted Residual cutoff: %s",
800 if (tier != 2) fpOut <<
"\n";
803 sprintf(buf,
"\n Tier %d Enabled: FALSE", tier);
808 sprintf(buf,
"\n\nINPUT: CONVERGENCE CRITERIA\n===========================\n");
810 sprintf(buf,
"\n SIGMA0: %e",
813 sprintf(buf,
"\n MAXIMUM ITERATIONS: %d",
814 m_settings->convergenceCriteriaMaximumIterations());
828 sprintf(buf,
"\n\nINPUT: CAMERA POINTING OPTIONS\n==============================\n");
830 switch (pointingSolveDegree) {
832 sprintf(buf,
"\n CAMSOLVE: NONE");
835 sprintf(buf,
"\n CAMSOLVE: ANGLES");
838 sprintf(buf,
"\n CAMSOLVE: ANGLES, VELOCITIES");
841 sprintf(buf,
"\n CAMSOLVE: ANGLES, VELOCITIES, ACCELERATIONS");
844 sprintf(buf,
"\n CAMSOLVE: ALL POLYNOMIAL COEFFICIENTS (%d)"
846 "\n CKSOLVEDEGREE: %d",
854 sprintf(buf,
"\n TWIST: ON"):
855 sprintf(buf,
"\n TWIST: OFF");
858 sprintf(buf,
"\n POLYNOMIAL OVER EXISTING POINTING: ON"):
859 sprintf(buf,
"\nPOLYNOMIAL OVER EXISTING POINTING : OFF");
862 sprintf(buf,
"\n\nINPUT: SPACECRAFT OPTIONS\n=========================\n");
864 switch (positionSolveDegree) {
866 sprintf(buf,
"\n SPSOLVE: NONE");
869 sprintf(buf,
"\n SPSOLVE: POSITION");
872 sprintf(buf,
"\n SPSOLVE: POSITION, VELOCITIES");
875 sprintf(buf,
"\n SPSOLVE: POSITION, VELOCITIES, ACCELERATIONS");
878 sprintf(buf,
"\n SPSOLVE: ALL POLYNOMIAL COEFFICIENTS (%d)"
880 "\n SPKSOLVEDEGREE: %d",
888 sprintf(buf,
"\n POLYNOMIAL OVER HERMITE SPLINE: ON"):
889 sprintf(buf,
"\nPOLYNOMIAL OVER HERMITE SPLINE : OFF");
892 sprintf(buf,
"\n\nINPUT: GLOBAL IMAGE PARAMETER UNCERTAINTIES\n===========================================\n");
895 sprintf(buf,
"\n POINT LATITUDE SIGMA: N/A"):
896 sprintf(buf,
"\n POINT LATITUDE SIGMA: %lf (meters)",
900 sprintf(buf,
"\n POINT LONGITUDE SIGMA: N/A"):
901 sprintf(buf,
"\n POINT LONGITUDE SIGMA: %lf (meters)",
905 sprintf(buf,
"\n POINT RADIUS SIGMA: N/A"):
906 sprintf(buf,
"\n POINT RADIUS SIGMA: %lf (meters)",
909 (positionSolveDegree < 1 || positionSigmas[0] ==
Isis::Null) ?
910 sprintf(buf,
"\n SPACECRAFT POSITION SIGMA: N/A"):
911 sprintf(buf,
"\n SPACECRAFT POSITION SIGMA: %lf (meters)",
915 (positionSolveDegree < 2 || positionSigmas[1] ==
Isis::Null) ?
916 sprintf(buf,
"\n SPACECRAFT VELOCITY SIGMA: N/A"):
917 sprintf(buf,
"\n SPACECRAFT VELOCITY SIGMA: %lf (m/s)",
921 (positionSolveDegree < 3 || positionSigmas[2] ==
Isis::Null) ?
922 sprintf(buf,
"\n SPACECRAFT ACCELERATION SIGMA: N/A"):
923 sprintf(buf,
"\n SPACECRAFT ACCELERATION SIGMA: %lf (m/s/s)",
927 (pointingSolveDegree < 1 || pointingSigmas[0] ==
Isis::Null) ?
928 sprintf(buf,
"\n CAMERA ANGLES SIGMA: N/A"):
929 sprintf(buf,
"\n CAMERA ANGLES SIGMA: %lf (dd)",
933 (pointingSolveDegree < 2 || pointingSigmas[1] ==
Isis::Null) ?
934 sprintf(buf,
"\n CAMERA ANGULAR VELOCITY SIGMA: N/A"):
935 sprintf(buf,
"\n CAMERA ANGULAR VELOCITY SIGMA: %lf (dd/s)",
939 (pointingSolveDegree < 3 || pointingSigmas[2] ==
Isis::Null) ?
940 sprintf(buf,
"\n CAMERA ANGULAR ACCELERATION SIGMA: N/A"):
941 sprintf(buf,
"\n CAMERA ANGULAR ACCELERATION SIGMA: %lf (dd/s/s)",
946 sprintf(buf,
"\n\nINPUT: TARGET BODY OPTIONS\n==============================\n");
950 sprintf(buf,
"\n POLE: RIGHT ASCENSION");
952 sprintf(buf,
"\n : DECLINATION\n");
956 sprintf(buf,
"\n POLE: RIGHT ASCENSION\n");
960 sprintf(buf,
"\n POLE: DECLINATION\n");
966 sprintf(buf,
"\n PRIME MERIDIAN: W0 (OFFSET)");
970 sprintf(buf,
"\n : WDOT (SPIN RATE)");
974 sprintf(buf,
"\n :W ACCELERATION");
981 sprintf(buf,
"\n RADII: MEAN");
985 sprintf(buf,
"\n RADII: TRIAXIAL");
991 sprintf(buf,
"\n\nJIGSAW: RESULTS\n===============\n");
993 sprintf(buf,
"\n Images: %6d",numImages);
995 sprintf(buf,
"\n Points: %6d",numValidPoints);
998 sprintf(buf,
"\n Total Measures: %6d",
1003 sprintf(buf,
"\n Total Observations: %6d",
1008 sprintf(buf,
"\n Good Observations: %6d",
1012 sprintf(buf,
"\n Rejected Observations: %6d",
1017 sprintf(buf,
"\n Constrained Point Parameters: %6d",
1023 sprintf(buf,
"\n Constrained Image Parameters: %6d",
1029 sprintf(buf,
"\n Constrained Target Parameters: %6d",
1034 sprintf(buf,
"\n Unknowns: %6d",
1038 if (numInnerConstraints > 0) {
1039 sprintf(buf,
"\n Inner Constraints: %6d", numInnerConstraints);
1043 if (numDistanceConstraints > 0) {
1044 sprintf(buf,
"\n Distance Constraints: %d", numDistanceConstraints);
1048 sprintf(buf,
"\n Degrees of Freedom: %6d", numDegreesOfFreedom);
1051 sprintf(buf,
"\n Convergence Criteria: %6.3g",
1055 if (convergenceCriteria == 1) {
1056 sprintf(buf,
"(Sigma0)");
1064 sprintf(buf,
"(Maximum reached)");
1070 sprintf(buf,
" Error Propagation Elapsed Time: %6.4lf (seconds)\n",
1073 sprintf(buf,
" Total Elapsed Time: %6.4lf (seconds)\n",
1079 sprintf(buf,
"\n Residual Percentiles:\n");
1085 for (
int bin = 1;bin < 34;bin++) {
1086 double cumProb = double(bin) / 100.0;
1089 residualsCumulativeProbabilityDistribution().value(cumProb);
1092 residualsCumulativeProbabilityDistribution().value(cumProb + 0.33);
1095 residualsCumulativeProbabilityDistribution().value(cumProb + 0.66);
1096 sprintf(buf,
" Percentile %3d: %+8.3lf"
1097 " Percentile %3d: %+8.3lf"
1098 " Percentile %3d: %+8.3lf\n",
1100 bin + 33, resValue33,
1101 bin + 66, resValue66);
1106 QString msg =
"Failed to output residual percentiles for bundleout";
1110 sprintf(buf,
"\n Residual Box Plot:");
1112 sprintf(buf,
"\n minimum: %+8.3lf",
1115 sprintf(buf,
"\n Quartile 1: %+8.3lf",
1118 sprintf(buf,
"\n Median: %+8.3lf",
1121 sprintf(buf,
"\n Quartile 3: %+8.3lf",
1124 sprintf(buf,
"\n maximum: %+8.3lf\n",
1129 QString msg =
"Failed to output residual box plot for bundleout";
1134 sprintf(buf,
"\nIMAGE MEASURES SUMMARY\n==========================\n\n");
1138 int numRejectedMeasures;
1142 for (
int i = 0; i < numObservations; i++) {
1146 for (
int j = 0; j < numImagesInObservation; j++) {
1151 rmsImageSampleResiduals()[imageIndex].Rms();
1153 rmsImageLineResiduals()[imageIndex].Rms();
1155 rmsImageResiduals()[imageIndex].Rms();
1158 GetNumberOfValidMeasuresInImage(
1159 bundleImage->serialNumber());
1162 GetNumberOfJigsawRejectedMeasuresInImage(
1163 bundleImage->serialNumber());
1165 numUsed = numMeasures - numRejectedMeasures;
1167 if (numUsed == numMeasures) {
1168 sprintf(buf,
"%s %5d of %5d %6.3lf %6.3lf %6.3lf\n",
1169 bundleImage->fileName().toLatin1().data(),
1170 (numMeasures-numRejectedMeasures), numMeasures,
1171 rmsSampleResiduals, rmsLineResiduals, rmsLandSResiduals);
1174 sprintf(buf,
"%s %5d of %5d* %6.3lf %6.3lf %6.3lf\n",
1175 bundleImage->fileName().toLatin1().data(),
1176 (numMeasures-numRejectedMeasures), numMeasures,
1177 rmsSampleResiduals, rmsLineResiduals, rmsLandSResiduals);
1208 QString ofname =
"bundleout_images.csv";
1209 ofname =
m_settings->outputFilePrefix() + ofname;
1211 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1223 bool errorProp =
false;
1228 for (
int i = 0; i < nObservations;i++ ) {
1235 int numImages = observation->size();
1237 for (
int j = 0; j < numImages; j++) {
1239 BundleImageQsp image = observation->at(j);
1242 sprintf(buf,
"%s", image->fileName().toLatin1().data());
1247 fpOut <<
toString(rmsImageSampleResiduals[imgIndex].Rms()).toLatin1().data();
1251 fpOut <<
toString(rmsImageLineResiduals[imgIndex].Rms()).toLatin1().data();
1255 fpOut <<
toString(rmsImageResiduals[imgIndex].Rms()).toLatin1().data();
1260 QString observationString =
1261 observation->formatBundleOutputString(errorProp,
true);
1264 if (observationString.right(1)==
",") {
1265 observationString.truncate(observationString.length()-1);
1268 fpOut << (
const char*) observationString.toLatin1().data();
1289 QString ofname =
"bundleout.txt";
1290 ofname =
m_settings->outputFilePrefix() + ofname;
1292 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1304 bool berrorProp =
false;
1311 sprintf(buf,
"\nTARGET BODY\n==========================\n");
1314 sprintf(buf,
"\n Target Initial Total "
1315 "Final Initial Final\n"
1316 "Parameter Value Correction "
1317 "Value Accuracy Accuracy\n");
1320 QString targetString =
1321 m_settings->bundleTargetBody()->formatBundleOutputString(berrorProp);
1322 fpOut << (
const char*)targetString.toLatin1().data();
1326 sprintf(buf,
"\nIMAGE EXTERIOR ORIENTATION\n==========================\n");
1332 imagesAndParameters.insert(
"target",
m_settings->bundleTargetBody()->parameterList() );
1335 for (
int i = 0; i < nObservations; i++) {
1342 int numImages = observation->size();
1343 for (
int j = 0; j < numImages; j++) {
1344 BundleImageQsp image = observation->at(j);
1345 sprintf(buf,
"\nImage Full File Name: %s\n", image->fileName().toLatin1().data());
1347 sprintf(buf,
"\nImage Serial Number: %s\n", image->serialNumber().toLatin1().data());
1350 sprintf(buf,
"\n Image Initial Total "
1351 "Final Initial Final\n"
1352 "Parameter Value Correction "
1353 "Value Accuracy Accuracy\n");
1356 QString observationString =
1357 observation->formatBundleOutputString(berrorProp);
1358 fpOut << (
const char*)observationString.toLatin1().data();
1361 foreach ( QString image, observation->imageNames() ) {
1362 imagesAndParameters.insert( image, observation->parameterList() );
1375 sprintf(buf,
"\n\n\nPOINTS UNCERTAINTY SUMMARY\n==========================\n\n");
1377 sprintf(buf,
" RMS Sigma Latitude(m)%20.8lf\n",
1380 sprintf(buf,
" MIN Sigma Latitude(m)%20.8lf at %s\n",
1384 sprintf(buf,
" MAX Sigma Latitude(m)%20.8lf at %s\n\n",
1388 sprintf(buf,
"RMS Sigma Longitude(m)%20.8lf\n",
1391 sprintf(buf,
"MIN Sigma Longitude(m)%20.8lf at %s\n",
1395 sprintf(buf,
"MAX Sigma Longitude(m)%20.8lf at %s\n\n",
1400 sprintf(buf,
" RMS Sigma Radius(m)%20.8lf\n",
1403 sprintf(buf,
" MIN Sigma Radius(m)%20.8lf at %s\n",
1407 sprintf(buf,
" MAX Sigma Radius(m)%20.8lf at %s\n",
1413 sprintf(buf,
" RMS Sigma Radius(m) N/A\n");
1415 sprintf(buf,
" MIN Sigma Radius(m) N/A\n");
1417 sprintf(buf,
" MAX Sigma Radius(m) N/A\n");
1423 sprintf(buf,
"\n\nPOINTS SUMMARY\n==============\n%103s"
1424 "Sigma Sigma Sigma\n"
1425 " Label Status Rays RMS"
1426 " Latitude Longitude Radius"
1427 " Latitude Longitude Radius\n",
"");
1431 for (
int i = 0; i < nPoints; i++) {
1434 QString pointSummaryString =
1435 bundleControlPoint->formatBundleOutputSummaryString(berrorProp);
1436 fpOut << (
const char*)pointSummaryString.toLatin1().data();
1440 sprintf(buf,
"\n\nPOINTS DETAIL\n=============\n\n");
1443 bool solveRadius =
m_settings->solveRadius();
1445 for (
int i = 0; i < nPoints; i++) {
1448 QString pointDetailString =
1449 bundleControlPoint->formatBundleOutputDetailString(berrorProp,
1452 fpOut << (
const char*)pointDetailString.toLatin1().data();
1469 QString ofname =
"bundleout_points.csv";
1470 ofname =
m_settings->outputFilePrefix() + ofname;
1472 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1479 double dLat, dLon, dRadius;
1481 double dSigmaLat, dSigmaLong, dSigmaRadius;
1486 int numMeasures, numRejectedMeasures;
1487 double dResidualRms;
1491 sprintf(buf,
"Point,Point,Accepted,Rejected,Residual,3-d,3-d,3-d,Sigma,"
1492 "Sigma,Sigma,Correction,Correction,Correction,Coordinate,"
1493 "Coordinate,Coordinate\nID,,,,,Latitude,Longitude,Radius,"
1494 "Latitude,Longitude,Radius,Latitude,Longitude,Radius,X,Y,Z\n"
1495 "Label,Status,Measures,Measures,RMS,(dd),(dd),(km),(m),(m),(m),"
1496 "(m),(m),(m),(km),(km),(km)\n");
1499 sprintf(buf,
"Point,Point,Accepted,Rejected,Residual,3-d,3-d,3-d,"
1500 "Correction,Correction,Correction,Coordinate,Coordinate,"
1501 "Coordinate\n,,,,,Latitude,Longitude,Radius,Latitude,"
1502 "Longitude,Radius,X,Y,Z\nLabel,Status,Measures,Measures,"
1503 "RMS,(dd),(dd),(km),(m),(m),(m),(km),(km),(km)\n");
1507 for (
int i = 0; i < numPoints; i++) {
1510 if (!bundlecontrolpoint) {
1514 if (bundlecontrolpoint->isRejected()) {
1518 dLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatitude().degrees();
1519 dLon = bundlecontrolpoint->adjustedSurfacePoint().GetLongitude().degrees();
1520 dRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadius().kilometers();
1521 dX = bundlecontrolpoint->adjustedSurfacePoint().GetX().kilometers();
1522 dY = bundlecontrolpoint->adjustedSurfacePoint().GetY().kilometers();
1523 dZ = bundlecontrolpoint->adjustedSurfacePoint().GetZ().kilometers();
1524 numMeasures = bundlecontrolpoint->numberOfMeasures();
1525 numRejectedMeasures = bundlecontrolpoint->numberOfRejectedMeasures();
1526 dResidualRms = bundlecontrolpoint->residualRms();
1529 boost::numeric::ublas::bounded_vector< double, 3 > corrections = bundlecontrolpoint->
1533 cor_rad_m = corrections[2]*1000.0;
1536 strStatus =
"FIXED";
1539 strStatus =
"CONSTRAINED";
1545 strStatus =
"UNKNOWN";
1549 dSigmaLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatSigmaDistance().meters();
1550 dSigmaLong = bundlecontrolpoint->adjustedSurfacePoint().GetLonSigmaDistance().meters();
1551 dSigmaRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadiusSigma().meters();
1553 sprintf(buf,
"%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
1554 "%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf\n",
1555 bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
1556 numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, dSigmaLat,
1557 dSigmaLong, dSigmaRadius, cor_lat_m, cor_lon_m, cor_rad_m, dX, dY, dZ);
1560 sprintf(buf,
"%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
1561 "%16.8lf,%16.8lf\n",
1562 bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
1563 numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, cor_lat_m,
1564 cor_lon_m, cor_rad_m, dX, dY, dZ);
1583 QString ofname =
"residuals.csv";
1584 ofname =
m_settings->outputFilePrefix() + ofname;
1586 std::ofstream fpOut(ofname.toLatin1().data(), std::ios::out);
1593 sprintf(buf,
",,,x image,y image,Measured,Measured,sample,line,Residual Vector\n");
1595 sprintf(buf,
"Point,Image,Image,coordinate,coordinate,"
1596 "Sample,Line,residual,residual,Magnitude\n");
1598 sprintf(buf,
"Label,Filename,Serial Number,(mm),(mm),"
1599 "(pixels),(pixels),(pixels),(pixels),(pixels),Rejected\n");
1605 int numMeasures = 0;
1610 for (
int i = 0; i < numPoints; i++) {
1612 numMeasures = bundleControlPoint->size();
1614 if (bundleControlPoint->rawControlPoint()->IsIgnored()) {
1618 for (
int j = 0; j < numMeasures; j++) {
1619 bundleMeasure = bundleControlPoint->at(j);
1621 Camera *measureCamera = bundleMeasure->camera();
1622 if (!measureCamera) {
1626 if (bundleMeasure->isRejected()) {
1627 sprintf(buf,
"%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,*\n",
1628 bundleControlPoint->id().toLatin1().data(),
1629 bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1630 bundleMeasure->cubeSerialNumber().toLatin1().data(),
1631 bundleMeasure->focalPlaneMeasuredX(),
1632 bundleMeasure->focalPlaneMeasuredY(),
1633 bundleMeasure->sample(),
1634 bundleMeasure->line(),
1635 bundleMeasure->sampleResidual(),
1636 bundleMeasure->lineResidual(),
1637 bundleMeasure->residualMagnitude());
1640 sprintf(buf,
"%s,%s,%s,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf\n",
1641 bundleControlPoint->id().toLatin1().data(),
1642 bundleMeasure->parentBundleImage()->fileName().toLatin1().data(),
1643 bundleMeasure->cubeSerialNumber().toLatin1().data(),
1644 bundleMeasure->focalPlaneMeasuredX(),
1645 bundleMeasure->focalPlaneMeasuredY(),
1646 bundleMeasure->sample(),
1647 bundleMeasure->line(),
1648 bundleMeasure->sampleResidual(),
1649 bundleMeasure->lineResidual(),
1650 bundleMeasure->residualMagnitude());
1670 stream <<
m_id->toString()
1694 m_id =
new QUuid(
id);
1709 stream >> statisticsResults;
1734 return bundleSolutionInfo.
write(stream);
1747 return bundleSolutionInfo.
read(stream);
1767 if (!bundleSolutionInfoFile.fileExists()) {
1768 QString msg =
"No file with the given name was found.";
1772 if (QString::compare(bundleSolutionInfoFile.extension(),
"hdf", Qt::CaseInsensitive) != 0) {
1773 QString msg =
"The given file is unsupported for constructing BundleSolutionInfo objects. "
1774 "Supported file types include [hdf].";
1795 const H5std_string hdfFileName(bundleSolutionInfoFile.expanded().toStdString());
1796 H5::H5File hdfFile( hdfFileName, H5F_ACC_RDONLY );
1800 QString bundleRunGroupName = root +
"BundleSolutionInfo";
1801 H5::Group bundleRunGroup = hdfFile.openGroup(bundleRunGroupName.toLatin1());
1806 H5std_string attValue;
1808 Attribute att = bundleRunGroup.openAttribute(
"runTime");
1809 H5::StrType strDataType(H5::PredType::C_S1, att.getStorageSize());
1810 att.read(strDataType, attValue);
1811 m_runTime = QString::fromStdString(attValue);
1813 att = bundleRunGroup.openAttribute(
"controlNetworkFileName");
1814 strDataType = H5::StrType(H5::PredType::C_S1, att.getStorageSize());
1815 att.read(strDataType, attValue);
1818 m_settings->openH5Group(bundleRunGroup, bundleRunGroupName);
1822 QString imagesGroupName = bundleRunGroupName +
"/imageLists";
1823 H5::Group imagesGroup = bundleRunGroup.openGroup(imagesGroupName.toLatin1());
1824 int imagesGroupSize = (int)imagesGroup.getNumObjs();
1826 for (
int i = 0; i < imagesGroupSize; i++) {
1827 H5std_string listGroupName = imagesGroup.getObjnameByIdx(i);
1828 H5::Group listGroup = imagesGroup.openGroup(listGroupName);
1830 H5std_string attValue;
1831 att = listGroup.openAttribute(
"path");
1832 strDataType = H5::StrType(H5::PredType::C_S1, att.getStorageSize());
1833 att.read(strDataType, attValue);
1834 QString listPath = QString::fromStdString(attValue);
1835 QString listName = QString::fromStdString(listGroupName).remove(imagesGroupName +
"/");
1839 att = listGroup.openAttribute(
"fileNames");
1840 strDataType = H5::StrType(H5::PredType::C_S1, att.getStorageSize());
1841 att.read(strDataType, attValue);
1842 QStringList fileList = QString::fromStdString(attValue).split(
",");
1843 for (
int j = 0; j < fileList.size();j++) {
1852 QString imagesGroupName = bundleRunGroupName +
"/imageLists";
1853 H5::Group imagesGroup = bundleRunGroup.openGroup(imagesGroupName.toLatin1());
1854 int imagesGroupSize = (int)imagesGroup.getNumObjs();
1856 for (
int i = 0; i < imagesGroupSize; i++) {
1857 H5std_string listGroupName = imagesGroup.getObjnameByIdx(i);
1858 H5::Group listGroup = imagesGroup.openGroup(listGroupName);
1860 H5std_string attValue;
1861 att = listGroup.openAttribute(
"path");
1862 strDataType = H5::StrType(H5::PredType::C_S1, att.getStorageSize());
1863 att.read(strDataType, attValue);
1864 QString listPath = QString::fromStdString(attValue);
1865 QString listName = QString::fromStdString(listGroupName).remove(imagesGroupName +
"/");
1868 imageList->openH5Group(bundleRunGroup, bundleRunGroupName);
1874 catch (H5::Exception error) {
1875 QString msg =
"H5 Exception Message: " + QString::fromStdString(error.getDetailMsg());
1877 msg =
"H5 exception handler has detected an error when invoking the function "
1878 + QString::fromStdString(error.getFuncName()) +
".";
1883 QString msg =
"Unable to read bundle solution information from the given HDF5 file ["
1884 + bundleSolutionInfoFile.expanded() +
"].";
1903 if (outputFileName.fileExists()) {
1904 QString msg =
"A file already exists with the given name ["
1905 + outputFileName.expanded() +
"].";
1922 const H5std_string hdfFileName(outputFileName.expanded().toStdString());
1924 H5::H5File hdfFile(hdfFileName, H5F_ACC_EXCL);
1928 QString bundleRunGroupName = root +
"BundleSolutionInfo";
1929 H5::Group bundleRunGroup = hdfFile.createGroup(bundleRunGroupName.toLatin1());
1935 H5::DataSpace spc(H5S_SCALAR);
1936 QString attValue =
"";
1938 H5::StrType strDataType(H5::PredType::C_S1,
m_runTime.length());
1939 att = bundleRunGroup.createAttribute(
"runTime", strDataType, spc);
1940 att.write(strDataType,
m_runTime.toStdString());
1943 strDataType = H5::StrType(H5::PredType::C_S1, attValue.length());
1944 att = bundleRunGroup.createAttribute(
"controlNetworkFileName", strDataType, spc);
1945 att.write(strDataType, attValue.toStdString());
1947 m_settings->createH5Group(bundleRunGroup, bundleRunGroupName);
1951 QString imagesGroupName = bundleRunGroupName +
"/imageLists";
1952 H5::Group imagesGroup = bundleRunGroup.createGroup(imagesGroupName.toLatin1());
1954 QString listGroupName =
"";
1957 for (
int i = 0; i <
m_images->size(); i++) {
1958 listGroupName = imagesGroupName +
"/" + (*m_images)[i]->name();
1960 H5::Group listGroup = imagesGroup.createGroup(listGroupName.toLatin1());
1962 attValue = (*m_images)[i]->path();
1963 strDataType = H5::StrType(H5::PredType::C_S1, attValue.length());
1964 att = listGroup.createAttribute(
"path", strDataType, spc);
1965 att.write(strDataType, attValue.toStdString());
1968 for (
int j = 0; j < (*m_images)[i]->size(); j++) {
1969 fileList += (*(*m_images)[i])[j]->fileName();
1972 QString fileNames = fileList.join(
",");
1973 stringSize = qMax(fileNames.length(), 1);
1974 strDataType = H5::StrType(H5::PredType::C_S1, stringSize);
1975 att = listGroup.createAttribute(
"fileNames", strDataType, spc);
1976 att.write(strDataType, fileNames.toStdString());
1980 catch (H5::Exception error) {
1981 QString msg =
"H5 Exception Message: " + QString::fromStdString(error.getDetailMsg());
1983 msg =
"H5 exception handler has detected an error when invoking the function "
1984 + QString::fromStdString(error.getFuncName()) +
".";
1991 "Unable to save bundle solution information to an HDF5 file.",
void save(QXmlStreamWriter &stream, const Project *project) const
Saves the BundleResults object to an XML file.
double sigmaLongitudeStatisticsRms() const
Returns the RMS of the adjusted longitude sigmas.
void setRunTime(QString runTime)
Sets the run time.
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
Handle an XML start element.
double max()
Returns the maximum observation so far included in the dynamic calculation.
void updateFileName(Project *)
Change the on-disk file name for the control network used to be where the control network ought to be...
double tweakingConstant() const
Returns the current tweaking constant.
Internalizes a list of images and allows for operations on the entire list.
QString minSigmaRadiusPointId() const
Returns the minimum sigma radius point id.
bool outputText()
Outputs a text file with the results of the BundleAdjust.
const double Null
Value for an Isis Null pixel.
QSharedPointer< BundleSettings > BundleSettingsQsp
Definition for a BundleSettingsQsp, a shared pointer to a BundleSettings object.
The main project for cnetsuite.
QList< double > aprioriPointingSigmas() const
Accesses the a priori pointing sigmas.
int iterations() const
Returns the number of iterations taken by the BundleAdjust.
int spkSolveDegree() const
Accesses the degree of thecamera position polynomial being fit to in the bundle adjustment (spkSolveD...
A Constrained point is a Control Point whose lat/lon/radius is somewhat established and should not be...
static QString CurrentLocalTime()
Returns the current local time This time is taken directly from the system clock, so if the system cl...
A Fixed point is a Control Point whose lat/lon is well established and should not be changed...
File name manipulation and expansion.
QString minSigmaLongitudePointId() const
Returns the minimum sigma longitude point id.
XmlHandler(BundleSolutionInfo *bundleSolutionInfo, Project *project)
Create an XML Handler (reader) that can populate the BundleSolutionInfo class data.
const BundleObservationVector & observations() const
Returns a reference to the observations used by the BundleAdjust.
Container class for BundleAdjustment results.
QString maxSigmaRadiusPointId() const
Returns the maximum sigma radius point id.
BundleSettingsQsp m_settings
The settings from the bundle adjust.
BundleSettingsQsp bundleSettings()
Returns the bundle settings.
QString maxSigmaLongitudePointId() const
Returns the maximum sigma longitude point id.
double value(double cumProb)
Provides the value of the variable that has the given cumulative probility (according the current est...
int numberConstrainedTargetParameters() const
Return the number of constrained target parameters.
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.
QString id() const
Get a unique, identifying string associated with this BundleSolutionInfo object.
int numberCameraAngleCoefficientsSolved() const
Accesses the number of camera angle coefficients in the solution.
Distance minSigmaLatitudeDistance() const
Returns the minimum sigma latitude distance.
const double DEG2RAD(0.017453292519943295769237)
Multiplier for converting from degrees to radians.
bool solvePositionOverHermite() const
Whether or not the polynomial for solving will be fit over an existing Hermite spline.
double sigma0() const
Returns the Sigma0 of the bundle adjustment.
QString runTime() const
Returns the run time.
QList< ImageList * > * m_images
The list of images that were adjusted.
BundleSolutionInfo & operator=(const BundleSolutionInfo &src)
Creates an equal operator for BundleSolutionInfos.
QList< ImageList * > * m_xmlHandlerImages
List of pointers to images.
double sigmaLatitudeStatisticsRms() const
Returns the RMS of the adjusted latitude sigmas.
int numberCameraPositionCoefficientsSolved() const
Accesses the number of camera position coefficients in the solution.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
A type of error that occurred when performing an actual I/O operation.
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 'cnets' to the project.
bool solveTwist() const
Accesses the flag for solving for twist.
QSharedPointer< BundleObservation > BundleObservationQsp
Typdef for BundleObservation QSharedPointer.
ControlNetQsp outputControlNet() const
Returns a shared pointer to the output control network.
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...
double elapsedTimeErrorProp() const
Returns the elapsed time for error propagation.
QVector< BundleControlPointQsp > & bundleControlPoints()
Returns a reference to the BundleControlPoint vector.
BundleResults * m_statisticsResults
The results of the bundle adjust.
BundleSolutionInfo * m_xmlHandlerBundleSolutionInfo
The bundleSolutionInfo object.
double meters() const
Get the distance in meters.
int numberRejectedObservations() const
Returns the number of observation that were rejected.
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Saves the BundleSolutionInfo to the project.
StatCumProbDistDynCalc residualsCumulativeProbabilityDistribution() const
Returns the cumulative probability distribution of the residuals used for reporting.
void createH5File(FileName outputFileName) const
Creates a new file using H5F_ACC_EXCL.
PvlObject pvlObject(QString resultsName="BundleSolutionInfo", QString settingsName="InputSettings", QString statisticsName="StatisticsResults")
Writes the results from BundleAdjust to a Pvl.
BundleResults * m_xmlHandlerBundleResults
Results from the bundle adjust.
#define _FILEINFO_
Macro for the filename and line number.
std::istream & operator>>(std::istream &is, CSVReader &csv)
Input read operator for input stream sources.
QList< Statistics > rmsImageResiduals() const
Returns the list of RMS image residuals statistics.
QUuid * m_id
A unique ID for this BundleSolutionInfo object (useful for others to reference this object when savin...
A single keyword-value pair.
This class is used to read an images.xml file into an image list.
Container class for BundleAdjustment settings.
A type of error that cannot be classified as any of the other error types.
QString maxSigmaLatitudePointId() const
Returns the maximum sigma latitude point id.
int ckSolveDegree() const
Accesses the degree of the camera angles polynomial being fit to in the bundle adjustment (ckSolveDeg...
double sigmaRadiusStatisticsRms() const
Returns the RMS of the adjusted raidus sigmas.
This represents a cube in a project-based GUI interface.
QString m_xmlHandlerCharacters
List of characters that have been handled.
QDataStream & read(QDataStream &stream)
Reads the data from the stream.
Distance minSigmaRadiusDistance() const
Returns the minimum sigma redius distance.
QList< double > aprioriPositionSigmas() const
Accesses the a priori position sigmas.
void append(Image *const &value)
Appends an image to the image list.
void openH5Group(H5::CommonFG &locationObject, QString locationName)
Reads from an hdf5 group.
void setCorrMatImgsAndParams(QMap< QString, QStringList > imgsAndParams)
Set the images and their associated parameters of the correlation matrix.
QString minSigmaLatitudePointId() const
Returns the minimum sigma latitude point id.
This class is used to modify and manage solve settings for 1 to many BundleObservations.
bool converged() const
Returns whether or not the bundle adjustment converged.
int numberObservations() const
Returns the number of observations.
virtual bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName)
Handle an XML end element.
QString controlNetworkFileName() const
Returns the name of the control network.
Distance maxSigmaLongitudeDistance() const
Returns the maximum sigma longitude distance.
int numberConstrainedImageParameters() const
Returns the number of constrained image parameters.
bool outputResiduals()
Outputs image coordinate residuals to a csv file.
~BundleSolutionInfo()
Destructor.
QString m_runTime
The run time of the bundle adjust.
Distance maxSigmaLatitudeDistance() const
Returns the maximum sigma latitude distance.
QSharedPointer< BundleMeasure > BundleMeasureQsp
Definition for BundleMeasureQsp, a shared pointer to a BundleMeasure.
BundleResults bundleResults()
Returns the bundle results.
virtual bool characters(const QString &ch)
Adds characters to m_xmlHandlerCharacters.
int numberUnknownParameters() const
Returns the number of unknown parameters.
QList< Statistics > rmsImageSampleResiduals() const
Returns the list of RMS image sample residuals statistics.
FileName * m_controlNetworkFileName
The name of the control network.
double min()
Returns the maximum observation so far included in the dynamic calculation.
A container class for statistical results from a BundleAdjust solution.
Distance maxSigmaRadiusDistance() const
Returns the maximum sigma redius distance.
PvlObject pvlObject(QString name="BundleResults") const
Saves the BundleResults object as a PvlObject.
double elapsedTime() const
Returns the elapsed time for the bundle adjustment.
QList< Statistics > rmsImageLineResiduals() const
Returns the list of RMS image line residuals statistics.
static QString modelToString(Model model)
Static method to return a string represtentation for a given MaximumLikelihoodWFunctions::Model enum...
Distance minSigmaLongitudeDistance() const
Returns the minimum sigma longitude distance.
void openH5File(FileName outputFileName)
Reads the settings and results from another BundleSolutionInfo.
QDebug operator<<(QDebug debug, const Hillshade &hillshade)
Print this class out to a QDebug object.
QDataStream & write(QDataStream &stream) const
Writes the data to the stream.
QSharedPointer< BundleControlPoint > BundleControlPointQsp
Definition for BundleControlPointQSP, a shared pointer to a BundleControlPoint.
Contains Pvl Groups and Pvl Objects.
bool solvePolyOverPointing() const
Whether or not the solve polynomial will be fit over the existing pointing polynomial.
int numberConstrainedPointParameters() const
Returns the number of constrained point parameters.
double radiansToMeters() const
Returns the radians to meters conversion factor for the target body.
his enables stack-based XML parsing of XML files.
int spkDegree() const
Accesses the degree of the polynomial fit to the original camera position (spkDegree).
MaximumLikelihoodWFunctions maximumLikelihoodModelWFunc(int modelIndex) const
Returns the maximum likelihood model at the given index.
int ckDegree() const
Accesses the degree of polynomial fit to original camera angles (ckDegree).
bool outputPointsCSV()
Outputs point data to a csv file.
double maximumLikelihoodModelQuantile(int modelIndex) const
Returns the quantile of the maximum likelihood model at the given index.