9#include "BundleAdjust.h"
17#include <QCoreApplication>
23#include <boost/lexical_cast.hpp>
24#include <boost/numeric/ublas/io.hpp>
25#include <boost/numeric/ublas/matrix_proxy.hpp>
26#include <boost/numeric/ublas/matrix_sparse.hpp>
27#include <boost/numeric/ublas/vector_proxy.hpp>
30#include "Application.h"
31#include "BundleLidarControlPoint.h"
32#include "BundleMeasure.h"
33#include "BundleObservation.h"
34#include "IsisBundleObservation.h"
35#include "BundleObservationSolveSettings.h"
36#include "BundleResults.h"
37#include "BundleSettings.h"
38#include "BundleSolutionInfo.h"
39#include "BundleTargetBody.h"
41#include "CameraDetectorMap.h"
42#include "CameraDistortionMap.h"
43#include "CameraFocalPlaneMap.h"
44#include "CameraGroundMap.h"
47#include "ControlPoint.h"
48#include "CorrelationMatrix.h"
55#include "MaximumLikelihoodWFunctions.h"
56#include "SpecialPixel.h"
57#include "StatCumProbDistDynCalc.h"
58#include "SurfacePoint.h"
61using namespace boost::numeric::ublas;
78 const char* message) {
92 errlog +=
". (See print.prt for details)";
108 const QString &cnetFile,
109 const QString &cubeList,
121 bundleSettings->controlPointCoordTypeReports()) );
129 m_bundleTargetBody = bundleSettings->bundleTargetBody();
146 const QString &cnetFile,
147 const QString &cubeList,
148 const QString &lidarDataFile,
179 m_bundleTargetBody = bundleSettings->bundleTargetBody();
216 m_bundleTargetBody = bundleSettings->bundleTargetBody();
253 m_bundleTargetBody = bundleSettings->bundleTargetBody();
289 m_bundleTargetBody = bundleSettings->bundleTargetBody();
305 const QString &cubeList,
320 m_bundleTargetBody = bundleSettings->bundleTargetBody();
337 QList<ImageList *> imgLists,
350 m_imageLists = imgLists;
358 foreach (
Image *image, *imgList) {
364 m_bundleTargetBody = bundleSettings->bundleTargetBody();
426 emit(statusUpdate(
"Initialization"));
435 m_iterationSummary =
"";
470 for (
int i = 0; i < numImages; i++) {
479 QString msg =
fileName +
" camera was initialized using CSMInit, so jigsaw must use CSM parameters." +
480 " Please refer to documentation for more information." +
"\n";
489 QString msg =
"In BundleAdjust::init(): image " +
fileName +
"is null." +
"\n";
497 QString msg =
"In BundleAdjust::init(): observation "
498 + observationNumber +
"is null." +
"\n";
505 for (
int i = 0; i < numControlPoints; i++) {
507 if (point->IsIgnored()) {
516 int numMeasures = bundleControlPoint->size();
517 for (
int j = 0; j < numMeasures; j++) {
519 QString cubeSerialNumber = measure->cubeSerialNumber();
523 BundleImageQsp image = observation->imageByCubeSerialNumber(cubeSerialNumber);
525 measure->setParentObservation(observation);
526 measure->setParentImage(image);
527 measure->setSigma(1.4);
534 int numLidarPoints = 0;
538 for (
int i = 0; i < numLidarPoints; i++) {
540 if (lidarPoint->IsIgnored()) {
549 int numMeasures = bundleLidarPoint->size();
550 for (
int j = 0; j < numMeasures; j++) {
552 QString cubeSerialNumber = measure->cubeSerialNumber();
556 BundleImageQsp image = observation->imageByCubeSerialNumber(cubeSerialNumber);
558 measure->setParentObservation(observation);
559 measure->setParentImage(image);
560 measure->setSigma(30.0);
572 lidarPoint->ComputeApriori();
575 bundleLidarPoint->initializeRangeConstraints();
612 if (m_bundleTargetBody->solveMeanRadius() || m_bundleTargetBody->solveTriaxialRadii()) {
614 "is NOT possible and likely increases error in the solve.\n");
617 if (m_bundleTargetBody->solveMeanRadius()){
619 bool isMeanRadiusValid =
true;
620 double localRadius, aprioriRadius;
624 SurfacePoint surfacepoint = point->adjustedSurfacePoint();
626 localRadius = surfacepoint.GetLocalRadius().meters();
627 aprioriRadius = m_bundleTargetBody->meanRadius().meters();
631 if (aprioriRadius >= 2 * localRadius || aprioriRadius <= localRadius / 2) {
632 isMeanRadiusValid =
false;
636 if (!isMeanRadiusValid) {
638 "This can cause a bundle failure.\n");
681 int imagesWithInsufficientMeasures = 0;
682 QString msg =
"Images with one or less measures:\n";
683 int numObservations = m_bundleObservations.size();
684 for (
int i = 0; i < numObservations; i++) {
685 int numImages = m_bundleObservations.at(i)->size();
686 for (
int j = 0; j < numImages; j++) {
689 GetNumberOfValidMeasuresInImage(bundleImage->serialNumber());
691 if (numMeasures > 1) {
695 imagesWithInsufficientMeasures++;
696 msg += bundleImage->fileName() +
": " +
toString(numMeasures) +
"\n";
700 if ( imagesWithInsufficientMeasures > 0 ) {
723 cholmod_l_start(&m_cholmodCommon);
729 m_cholmodCommon.nmethods = 1;
730 m_cholmodCommon.method[0].ordering = CHOLMOD_AMD;
748 cholmod_l_free_factor(&
m_L, &m_cholmodCommon);
750 cholmod_l_finish(&m_cholmodCommon);
768 int nBlockColumns = m_bundleObservations.size();
783 for (
int i = 2; i < nBlockColumns; i++) {
790 for (
int i = 0; i < nBlockColumns; i++) {
839 emit(statusBarUpdate(
"Solving"));
858 if (m_bundleTargetBody && m_bundleTargetBody->solveMeanRadius()) {
860 for (
int i = 0; i < numControlPoints; i++) {
862 SurfacePoint surfacepoint = point->adjustedSurfacePoint();
864 surfacepoint.ResetLocalRadius(m_bundleTargetBody->meanRadius());
866 point->setAdjustedSurfacePoint(surfacepoint);
871 if (m_bundleTargetBody && m_bundleTargetBody->solveTriaxialRadii()
874 for (
int i = 0; i < numControlPoints; i++) {
876 SurfacePoint surfacepoint = point->adjustedSurfacePoint();
878 Distance localRadius = m_bundleTargetBody->localRadius(surfacepoint.GetLatitude(),
879 surfacepoint.GetLongitude());
880 surfacepoint.ResetLocalRadius(localRadius);
882 point->setAdjustedSurfacePoint(surfacepoint);
889 double previousSigma0 = 0.0;
892 clock_t solveStartClock = clock();
901 emit statusUpdate(
"\n aborting...");
907 emit statusUpdate( QString(
"\nstarting iteration %1\n").arg(
m_iteration) );
909 clock_t iterationStartClock = clock();
925 emit statusUpdate(
"\n aborting...");
941 emit statusUpdate(
"\n aborting...");
953 emit statusUpdate(
"\n aborting...");
960 emit(statusBarUpdate(
"Computing Residuals"));
975 emit statusUpdate(
"\n aborting...");
991 emit statusUpdate(QString(
"Iteration: %1 \n")
993 emit statusUpdate(QString(
"Sigma0: %1 \n")
998 emit statusUpdate(QString(
"Observations: %1 \n")
1000 emit statusUpdate(QString(
"Constrained Parameters:%1 \n")
1002 emit statusUpdate(QString(
"Unknowns: %1 \n")
1004 emit statusUpdate(QString(
"Degrees of Freedom: %1 \n")
1031 emit statusUpdate(
"Bundle has converged\n");
1032 emit statusBarUpdate(
"Converged");
1034 clock_t iterationStopClock = clock();
1036 / (
double)CLOCKS_PER_SEC;
1043 int numConvergedParams = 0;
1045 for (
int ij = 0; ij < numImgParams; ij++) {
1050 numConvergedParams++;
1053 if ( numConvergedParams == numImgParams ) {
1055 emit statusUpdate(
"Bundle has converged\n");
1056 emit statusBarUpdate(
"Converged");
1062 clock_t iterationStopClock = clock();
1064 / (
double)CLOCKS_PER_SEC;
1065 emit statusUpdate( QString(
"End of Iteration %1 \n").arg(
m_iteration) );
1066 emit statusUpdate( QString(
"Elapsed Time: %1 \n").arg(
m_iterationTime,
1073 emit(statusBarUpdate(
"Max Iterations Reached"));
1086 cholmod_l_free_factor(&
m_L, &m_cholmodCommon);
1097 clock_t errorPropStartClock = clock();
1102 emit statusUpdate(
"\n\nError Propagation Complete\n");
1103 clock_t errorPropStopClock = clock();
1105 / (
double)CLOCKS_PER_SEC);
1108 clock_t solveStopClock = clock();
1110 / (
double)CLOCKS_PER_SEC);
1124 emit statusUpdate(
"\nBundle Complete\n");
1130 emit statusUpdate(
"\n aborting...");
1131 emit statusBarUpdate(
"Failed to Converge");
1133 QString msg =
"Could not solve bundle adjust.";
1134 throw IException(e, e.errorType(), msg, _FILEINFO_);
1148 emit(statusBarUpdate(
"Computing Measure Residuals"));
1155 emit(statusBarUpdate(
"Computing Lidar Measure Residuals"));
1178 return bundleSolutionInfo;
1194 emit(statusBarUpdate(
"Forming Normal Equations"));
1195 bool status =
false;
1212 int numTargetBodyParameters =
m_bundleSettings->numberTargetBodyParameters();
1214 coeffTarget.resize(2,numTargetBodyParameters);
1223 coeffPoint3D.clear();
1229 int numObservations = 0;
1230 int numGood3DPoints = 0;
1231 int numRejected3DPoints = 0;
1232 int numConstrainedCoordinates = 0;
1237 for (
int i = 0; i < num3DPoints; i++) {
1238 emit(pointUpdate(i+1));
1241 if (point->isRejected()) {
1242 numRejected3DPoints++;
1253 int numMeasures = point->size();
1254 for (
int j = 0; j < numMeasures; j++) {
1259 if (measure->isRejected()) {
1263 status =
computePartials(coeffTarget, coeffImage, coeffPoint3D, coeffRHS, *measure,
1273 numObservations += 2;
1275 formMeasureNormals(N22, N12, n1, n2, coeffTarget, coeffImage, coeffPoint3D, coeffRHS,
1276 measure->observationIndex());
1288 int numRejectedLidarPoints = 0.0;
1289 int numGoodLidarPoints = 0.0;
1290 numObservations = 0;
1291 numConstrainedCoordinates = 0;
1298 for (
int i = 0; i < numLidarPoints; i++) {
1299 emit(pointUpdate(i+1));
1302 if (point->isRejected()) {
1303 numRejectedLidarPoints++;
1312 int numMeasures = point->size();
1313 for (
int j = 0; j < numMeasures; j++) {
1316 if (measure->isRejected()) {
1320 status =
computePartials(coeffTarget, coeffImage, coeffPoint3D, coeffRHS, *measure,
1329 numObservations += 2;
1331 formMeasureNormals(N22, N12, n1, n2, coeffTarget, coeffImage, coeffPoint3D, coeffRHS,
1332 measure->observationIndex());
1340 numGoodLidarPoints++;
1384 int observationIndex) {
1386 int blockIndex = observationIndex;
1390 int numTargetPartials = coeffTarget.size2();
1400 numTargetPartials, coeffImage.size2());
1401 (*(*
m_sparseNormals[blockIndex])[0]) += prod(trans(coeffTarget),coeffImage);
1404 N12.insertMatrixBlock(0, numTargetPartials, 3);
1405 *N12[0] += prod(trans(coeffTarget), coeffPoint3D);
1408 vector_range<LinearAlgebra::VectorCompressed> n1_range(n1, range(0, numTargetPartials));
1410 n1_range += prod(trans(coeffTarget), coeffRHS);
1414 int numImagePartials = coeffImage.size2();
1418 numImagePartials, numImagePartials);
1420 (*(*
m_sparseNormals[blockIndex])[blockIndex]) += prod(trans(coeffImage), coeffImage);
1423 N12.insertMatrixBlock(blockIndex, numImagePartials, 3);
1424 *N12[blockIndex] += prod(trans(coeffImage), coeffPoint3D);
1427 vector_range<LinearAlgebra::VectorCompressed> vr(
1433 vr += prod(trans(coeffImage), coeffRHS);
1436 N22 += prod(trans(coeffPoint3D), coeffPoint3D);
1439 n2 += prod(trans(coeffPoint3D), coeffRHS);
1468 boost::numeric::ublas::bounded_vector<double, 3> &NIC = bundleControlPoint->nicVector();
1474 int numConstrainedCoordinates = 0;
1478 boost::numeric::ublas::bounded_vector<double, 3> &weights
1479 = bundleControlPoint->weights();
1480 boost::numeric::ublas::bounded_vector<double, 3> &corrections
1481 = bundleControlPoint->corrections();
1483 if (weights(0) > 0.0) {
1484 N22(0,0) += weights(0);
1485 n2(0) += (-weights(0) * corrections(0));
1486 numConstrainedCoordinates++;
1489 if (weights(1) > 0.0) {
1490 N22(1,1) += weights(1);
1491 n2(1) += (-weights(1) * corrections(1));
1492 numConstrainedCoordinates++;
1495 if (weights(2) > 0.0) {
1496 N22(2,2) += weights(2);
1497 n2(2) += (-weights(2) * corrections(2));
1498 numConstrainedCoordinates++;
1507 bundleControlPoint->setAdjustedSurfacePoint(
SurfacePoint);
1513 NIC = prod(N22, n2);
1521 return numConstrainedCoordinates;
1548 boost::numeric::ublas::bounded_vector<double, 3> &NIC = bundleLidarControlPoint->nicVector();
1554 int numConstrainedCoordinates = 0;
1558 boost::numeric::ublas::bounded_vector<double, 3> &weights
1559 = bundleLidarControlPoint->weights();
1560 boost::numeric::ublas::bounded_vector<double, 3> &corrections
1561 = bundleLidarControlPoint->corrections();
1563 if (weights(0) > 0.0) {
1564 N22(0,0) += weights(0);
1565 n2(0) += (-weights(0) * corrections(0));
1566 numConstrainedCoordinates++;
1569 if (weights(1) > 0.0) {
1570 N22(1,1) += weights(1);
1571 n2(1) += (-weights(1) * corrections(1));
1572 numConstrainedCoordinates++;
1575 if (weights(2) > 0.0) {
1576 N22(2,2) += weights(2);
1577 n2(2) += (-weights(2) * corrections(2));
1578 numConstrainedCoordinates++;
1587 bundleLidarControlPoint->setAdjustedSurfacePoint(
SurfacePoint);
1593 NIC = prod(N22, n2);
1601 return numConstrainedCoordinates;
1624 vector<double> &nj) {
1632 if ( !diagonalBlock )
1639 vector<double> weights = m_bundleTargetBody->parameterWeights();
1640 vector<double> corrections = m_bundleTargetBody->parameterCorrections();
1642 int blockSize = diagonalBlock->size1();
1643 for (
int j = 0; j < blockSize; j++) {
1644 if (weights[j] > 0.0) {
1645 (*diagonalBlock)(j,j) += weights[j];
1646 nj[n] -= weights[j] * corrections(j);
1656 observation = m_bundleObservations.at(i-1);
1659 observation = m_bundleObservations.at(i);
1666 int blockSize = diagonalBlock->size1();
1667 for (
int j = 0; j < blockSize; j++) {
1668 if (weights(j) > 0.0) {
1669 (*diagonalBlock)(j,j) += weights(j);
1670 nj[n] -= weights(j) * corrections(j);
1698 QMapIterator< int, LinearAlgebra::Matrix * > N12it(N12);
1700 while ( N12it.hasNext() ) {
1703 int rowIndex = N12it.key();
1706 Q.insertMatrixBlock(rowIndex, 3, N12it.value()->size1());
1708 *(Q[rowIndex]) = prod(N22,trans(*(N12it.value())));
1727 QMapIterator<int, LinearAlgebra::Matrix*> N12it(N12);
1728 QMapIterator<int, LinearAlgebra::Matrix*> Qit(Q);
1731 while ( N12it.hasNext() ) {
1734 int rowIndex = N12it.key();
1737 while ( Qit.hasNext() ) {
1740 int columnIndex = Qit.key();
1742 if ( rowIndex > columnIndex ) {
1750 N12block->size1(), Qblock->size2());
1752 (*(*
m_sparseNormals[columnIndex])[rowIndex]) -= prod(*N12block,*Qblock);
1772 vector<double> &nj) {
1780 QMapIterator<int, LinearAlgebra::Matrix*> Qit(Q);
1782 while ( Qit.hasNext() ) {
1785 int columnIndex = Qit.key();
1792 for (
unsigned i = 0; i < blockProduct.size(); i++) {
1793 nj(numParams+i) += alpha*blockProduct(i);
1812 QString msg =
"CHOLMOD: Failed to load Triplet matrix";
1830 if (m_cholmodCommon.status == CHOLMOD_NOT_POSDEF) {
1831 QString msg =
"Matrix NOT positive-definite: failure at column " +
toString((
int)
m_L->minor);
1839 cholmod_dense *x, *b;
1845 double *px = (
double*)b->x;
1846 for (
int i = 0; i <
m_rank; i++) {
1851 x = cholmod_l_solve(CHOLMOD_A,
m_L, b, &m_cholmodCommon);
1854 double *sx = (
double*)x->x;
1855 for (
int i = 0; i <
m_rank; i++) {
1861 cholmod_l_free_dense(&b, &m_cholmodCommon);
1862 cholmod_l_free_dense(&x, &m_cholmodCommon);
1884 -1, CHOLMOD_REAL, &m_cholmodCommon);
1899 long numEntries = 0;
1902 for (
int columnIndex = 0; columnIndex < numBlockcolumns; columnIndex++) {
1906 if ( !normalsColumn ) {
1907 QString status =
"\nSparseBlockColumnMatrix retrieval failure at column " +
1908 QString::number(columnIndex);
1913 int numLeadingColumns = normalsColumn->startColumn();
1915 QMapIterator< int, LinearAlgebra::Matrix * > it(*normalsColumn);
1917 while ( it.hasNext() ) {
1920 int rowIndex = it.key();
1927 if ( !normalsBlock ) {
1928 QString status =
"\nmatrix block retrieval failure at column ";
1929 status.append(columnIndex);
1930 status.append(
", row ");
1931 status.append(rowIndex);
1933 status =
"Total # of block columns: " + QString::number(numBlockcolumns);
1940 if ( columnIndex == rowIndex ) {
1941 for (
unsigned ii = 0; ii < normalsBlock->size1(); ii++) {
1942 for (
unsigned jj = ii; jj < normalsBlock->size2(); jj++) {
1943 entryValue = normalsBlock->at_element(ii,jj);
1944 int entryColumnIndex = jj + numLeadingColumns;
1945 int entryRowIndex = ii + numLeadingRows;
1948 tripletColumns[numEntries] = entryColumnIndex;
1949 tripletRows[numEntries] = entryRowIndex;
1953 tripletValues[numEntries] = entryValue;
1960 for (
unsigned ii = 0; ii < normalsBlock->size1(); ii++) {
1961 for (
unsigned jj = 0; jj < normalsBlock->size2(); jj++) {
1962 entryValue = normalsBlock->at_element(ii,jj);
1963 int entryColumnIndex = jj + numLeadingColumns;
1964 int entryRowIndex = ii + numLeadingRows;
1967 tripletColumns[numEntries] = entryRowIndex;
1968 tripletRows[numEntries] = entryColumnIndex;
1972 tripletValues[numEntries] = entryValue;
2001 boost::numeric::ublas::symmetric_matrix< double, upper > c = m;
2003 den = m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1))
2004 - m(0, 1) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0))
2005 + m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0));
2008 if (fabs(den) < 1.0e-100) {
2014 m(0, 0) = (c(1, 1) * c(2, 2) - c(1, 2) * c(2, 1)) * det;
2015 m(0, 1) = (c(0, 2) * c(2, 1) - c(0, 1) * c(2, 2)) * det;
2016 m(0, 2) = (c(0, 1) * c(1, 2) - c(0, 2) * c(1, 1)) * det;
2017 m(1, 1) = (c(0, 0) * c(2, 2) - c(0, 2) * c(2, 0)) * det;
2018 m(1, 2) = (c(0, 2) * c(1, 0) - c(0, 0) * c(1, 2)) * det;
2019 m(2, 2) = (c(0, 0) * c(1, 1) - c(0, 1) * c(1, 0)) * det;
2045 matrix<double> &coeffImage,
2046 matrix<double> &coeffPoint3D,
2047 vector<double> &coeffRHS,
2051 Camera *measureCamera = measure.camera();
2054 int numImagePartials = observation->numberParameters();
2060 coeffImage.resize(2,numImagePartials);
2070 measureCamera->SetImage(measure.sample(), measure.line());
2074 if (measureCamera->GetCameraType() !=
Camera::Csm) {
2078 double computedX, computedY;
2080 &computedX, &computedY,
false))) {
2081 QString msg =
"Unable to map apriori surface point for measure ";
2082 msg += measure.cubeSerialNumber() +
" on point " + point.
id() +
" into focal plane";
2088 observation->computeTargetPartials(coeffTarget, measure,
m_bundleSettings, m_bundleTargetBody);
2091 observation->computeImagePartials(coeffImage, measure);
2097 observation->computePoint3DPartials(coeffPoint3D, measure, coordType);
2100 observation->computeRHSPartials(coeffRHS, measure);
2102 double deltaX = coeffRHS(0);
2103 double deltaY = coeffRHS(1);
2111 double residualR2ZScore = sqrt(deltaX * deltaX + deltaY * deltaY) / sqrt(2.0);
2119 coeffImage *= observationWeight;
2120 coeffPoint3D *= observationWeight;
2121 coeffRHS *= observationWeight;
2124 coeffTarget *= observationWeight;
2136 emit(statusBarUpdate(
"Updating Parameters"));
2142 int numTargetBodyParameters = m_bundleTargetBody->numberParameters();
2144 m_bundleTargetBody->applyParameterCorrections(subrange(
m_imageSolution,0,
2145 numTargetBodyParameters));
2147 t += numTargetBodyParameters;
2151 int numObservations = m_bundleObservations.size();
2152 for (
int i = 0; i < numObservations; i++) {
2157 observation->applyParameterCorrections(subrange(
m_imageSolution,t,t+numParameters));
2162 QSharedPointer<IsisBundleObservation> isisObservation = qSharedPointerDynamicCast<IsisBundleObservation>(observation);
2163 isisObservation->updateBodyRotation();
2173 if (point->isRejected()) {
2178 m_bundleTargetBody);
2186 if (point->isRejected()) {
2191 m_bundleTargetBody);
2204 emit(statusBarUpdate(
"Computing Residuals"));
2226 for (
int i = 0; i < m_bundleObservations.size(); i++) {
2227 vtpv += m_bundleObservations.at(i)->vtpv();
2231 if ( m_bundleTargetBody) {
2232 vtpv += m_bundleTargetBody->vtpv();
2263 std::vector<double> residuals;
2265 residuals.resize(numResiduals);
2268 int residualIndex = 0;
2270 for (
int i = 0; i < numObjectPoints; i++) {
2274 if ( point->isRejected() ) {
2278 int numMeasures = point->numberOfMeasures();
2279 for (
int j = 0; j < numMeasures; j++) {
2283 if ( measure->isRejected() ) {
2287 vx = measure->sampleResidual();
2288 vy = measure->lineResidual();
2290 residuals[residualIndex] = sqrt(vx*vx + vy*vy);
2297 std::sort(residuals.begin(), residuals.end());
2303 int midpointIndex = numResiduals / 2;
2305 if ( numResiduals % 2 == 0 ) {
2306 median = (residuals[midpointIndex - 1] + residuals[midpointIndex]) / 2;
2309 median = residuals[midpointIndex];
2313 for (
int i = 0; i < numResiduals; i++) {
2314 residuals[i] = fabs(residuals[i] - median);
2317 std::sort(residuals.begin(), residuals.end());
2319 if ( numResiduals % 2 == 0 ) {
2320 medianDev = (residuals[midpointIndex - 1] + residuals[midpointIndex]) / 2;
2323 medianDev = residuals[midpointIndex];
2326 QString status =
"\nmedian deviation: ";
2327 status.append(QString(
"%1").arg(medianDev));
2328 status.append(
"\n");
2331 mad = 1.4826 * medianDev;
2334 status.append(QString(
"%1").arg(mad));
2335 status.append(
"\n");
2341 status =
"\nRejection Limit: ";
2343 status.append(
"\n");
2360 int totalNumRejected = 0;
2362 int maxResidualIndex;
2369 int numComingBack = 0;
2374 for (
int i = 0; i < numObjectPoints; i++) {
2377 point->zeroNumberOfRejectedMeasures();
2380 maxResidualIndex = -1;
2383 int numMeasures = point->numberOfMeasures();
2384 for (
int j = 0; j < numMeasures; j++) {
2388 vx = measure->sampleResidual();
2389 vy = measure->lineResidual();
2391 sumSquares = sqrt(vx*vx + vy*vy);
2394 if ( sumSquares <= usedRejectionLimit ) {
2397 if ( measure->isRejected() ) {
2398 QString status =
"Coming back in: ";
2399 status.append(QString(
"%1").arg(point->id().toLatin1().data()));
2400 status.append(
"\r");
2403 m_controlNet->DecrementNumberOfRejectedMeasuresInImage(measure->cubeSerialNumber());
2406 measure->setRejected(
false);
2411 if ( measure->isRejected() ) {
2417 if ( sumSquares > maxResidual ) {
2418 maxResidual = sumSquares;
2419 maxResidualIndex = j;
2424 if ( maxResidual == -1.0 || maxResidual <= usedRejectionLimit ) {
2425 point->setNumberOfRejectedMeasures(numRejected);
2431 if ((numMeasures - (numRejected + 1)) < 2) {
2432 point->setNumberOfRejectedMeasures(numRejected);
2441 rejected->setRejected(
true);
2443 point->setNumberOfRejectedMeasures(numRejected);
2444 m_controlNet->IncrementNumberOfRejectedMeasuresInImage(rejected->cubeSerialNumber());
2448 if ( ( numMeasures-numRejected ) < 2 ) {
2449 point->setRejected(
true);
2450 QString status =
"Rejecting Entire Point: ";
2451 status.append(QString(
"%1").arg(point->id().toLatin1().data()));
2452 status.append(
"\r");
2456 point->setRejected(
false);
2460 int numberRejectedObservations = 2*totalNumRejected;
2462 QString status =
"\nRejected Observations:";
2463 status.append(QString(
"%1").arg(numberRejectedObservations));
2464 status.append(
" (Rejection Limit:");
2465 status.append(QString(
"%1").arg(usedRejectionLimit));
2466 status.append(
")\n");
2471 status =
"\nMeasures that came back: ";
2472 status.append(QString(
"%1").arg(numComingBack));
2473 status.append(
"\n");
2489 if (m_imageLists.count() > 0) {
2490 return m_imageLists;
2497 imgList->append(image);
2500 m_imageLists.append(imgList);
2503 QString msg =
"Invalid image in serial number list\n";
2508 QString msg =
"No images used in bundle adjust\n";
2512 return m_imageLists;
2537 emit(statusBarUpdate(
"Error Propagation"));
2552 QString status =
" Time: ";
2553 status.append(currentTime.c_str());
2554 status.append(
"\n\n");
2558 std::vector< symmetric_matrix<double> > pointCovariances(numObjectPoints,
2559 symmetric_matrix<double>(3));
2560 for (
int d = 0; d < numObjectPoints; d++) {
2561 pointCovariances[d].clear();
2567 b = cholmod_l_zeros (
m_rank, 1, CHOLMOD_REAL, &m_cholmodCommon );
2568 double *pb = (
double*)b->x;
2579 QFile matrixOutput(matrixFile.expanded());
2584 matrixOutput.open(QIODevice::WriteOnly);
2586 QDataStream outStream(&matrixOutput);
2589 int columnIndex = 0;
2592 for (i = 0; i < numBlockColumns; i++) {
2597 numColumns = normalsColumn->numberOfColumns();
2598 int numRows = normalsColumn->numberOfRows();
2600 inverseMatrix.zeroBlocks();
2603 if (normalsColumn->numberOfColumns() == numColumns) {
2604 int numRows = normalsColumn->numberOfRows();
2605 inverseMatrix.insertMatrixBlock(i, numRows, numColumns);
2606 inverseMatrix.zeroBlocks();
2609 numColumns = normalsColumn->numberOfColumns();
2612 inverseMatrix.wipe();
2615 for (j = 0; j < (i+1); j++) {
2617 int numRows = normalsRow->numberOfRows();
2627 for (j = 0; j < numColumns; j++) {
2628 if ( columnIndex > 0 ) {
2629 pb[columnIndex - 1] = 0.0;
2631 pb[columnIndex] = 1.0;
2633 x = cholmod_l_solve ( CHOLMOD_A,
m_L, b, &m_cholmodCommon );
2638 for (k = 0; k < inverseMatrix.size(); k++) {
2641 int sz1 = matrix->size1();
2643 for (
int ii = 0; ii < sz1; ii++) {
2644 (*matrix)(ii,localCol) = px[ii + rp];
2646 rp += matrix->size1();
2652 cholmod_l_free_dense(&x,&m_cholmodCommon);
2657 vector< double > &adjustedSigmas = m_bundleTargetBody->adjustedSigmas();
2658 matrix< double > *targetCovMatrix = inverseMatrix.value(i);
2660 for (
int z = 0; z < numColumns; z++)
2667 observation = m_bundleObservations.at(i-1);
2670 observation = m_bundleObservations.at(i);
2672 vector< double > &adjustedSigmas = observation->adjustedSigmas();
2673 matrix< double > *imageCovMatrix = inverseMatrix.value(i);
2674 for (
int z = 0; z < numColumns; z++) {
2681 outStream << inverseMatrix;
2686 for (j = 0; j < numObjectPoints; j++) {
2687 emit(pointUpdate(j+1));
2689 if ( point->isRejected() ) {
2695 QString status =
"\rError Propagation: Inverse Block ";
2696 status.append(QString::number(i+1));
2697 status.append(
" of ");
2698 status.append(QString::number(numBlockColumns));
2699 status.append(
"; Point ");
2700 status.append(QString::number(j+1));
2701 status.append(
" of ");
2702 status.append(QString::number(numObjectPoints));
2714 boost::numeric::ublas::symmetric_matrix<double> &covariance = pointCovariances[pointIndex];
2725 QMapIterator< int, LinearAlgebra::Matrix * > it(Q);
2726 while ( it.hasNext() ) {
2729 int nKey = it.key();
2737 if ( !secondQBlock ) {
2743 if ( !inverseBlock ) {
2747 T = prod(*inverseBlock, trans(*firstQBlock));
2748 T = prod(*secondQBlock,T);
2758 catch (std::exception &e) {
2760 QString msg =
"Input data and settings are not sufficiently stable "
2761 "for error propagation.";
2771 matrixOutput.close();
2780 cholmod_l_free_dense(&b,&m_cholmodCommon);
2786 status =
"\rFilling point covariance matrices: Time ";
2787 status.append(currentTime.c_str());
2794 for (j = 0; j < numObjectPoints; j++) {
2798 if ( point->isRejected() ) {
2803 status =
"\rError Propagation: Filling point covariance matrices ";
2804 status.append(QString(
"%1").arg(j+1));
2805 status.append(
" of ");
2806 status.append(QString(
"%1").arg(numObjectPoints));
2807 status.append(
"\r");
2812 boost::numeric::ublas::symmetric_matrix<double> &covariance = pointCovariances[pointIndex];
2820 boost::numeric::ublas::symmetric_matrix <double,boost::numeric::ublas::upper> pCovar;
2823 pCovar =
SurfacePoint.GetSphericalMatrix(SurfacePoint::Kilometers);
2827 pCovar =
SurfacePoint.GetRectangularMatrix(SurfacePoint::Kilometers);
2829 pCovar += covariance;
2830 pCovar *= sigma0Squared;
2954 return m_controlNet->Camera(i)->instrumentRotation()->Cache(
"InstrumentPointing");
2969 return m_controlNet->Camera(i)->instrumentPosition()->Cache(
"InstrumentPosition");
2984 QString msg =
"Cannot get model state for image [" +
toString(i) +
2985 "] because it is not a CSM camera model.";
3003 QString iterationNumber;
3012 PvlGroup summaryGroup(iterationNumber);
3018 summaryGroup +=
PvlKeyword(
"Constrained_Point_Parameters",
3020 summaryGroup +=
PvlKeyword(
"Constrained_Image_Parameters",
3023 summaryGroup +=
PvlKeyword(
"Constrained_Target_Parameters",
3026 summaryGroup +=
PvlKeyword(
"Unknown_Parameters",
3028 summaryGroup +=
PvlKeyword(
"Degrees_of_Freedom",
3030 summaryGroup +=
PvlKeyword(
"Rejected_Measures",
3037 summaryGroup +=
PvlKeyword(
"Maximum_Likelihood_Tier: ",
3039 summaryGroup +=
PvlKeyword(
"Median_of_R^2_residuals: ",
3044 summaryGroup +=
PvlKeyword(
"Converged",
"TRUE");
3048 summaryGroup +=
PvlKeyword(
"ErrorPropagationElapsedTime",
3057 std::ostringstream ostr;
3058 ostr << summaryGroup << std::endl;
3059 m_iterationSummary += QString::fromStdString( ostr.str() );
3065 std::cout << summaryGroup << std::endl;
3098 return m_iterationSummary;
3113 printf(
"%s", status.toStdString().c_str());
3115 else if (QCoreApplication::applicationName() !=
"ipce") {
3116 printf(
"%s", status.toStdString().c_str());
3163 QVector<Statistics> rmsImageSampleResiduals(numberImages);
3164 QVector<Statistics> rmsImageLineResiduals(numberImages);
3165 QVector<Statistics> rmsImageResiduals(numberImages);
3168 for (
int i = 0; i < numObjectPoints; i++) {
3172 if (point->isRejected()) {
3176 int numMeasures = point->numberOfMeasures();
3177 for (
int j = 0; j < numMeasures; j++) {
3181 if (measure->isRejected()) {
3185 double sampleResidual = fabs(measure->sampleResidual());
3186 double lineResidual = fabs(measure->lineResidual());
3192 rmsImageSampleResiduals[imageIndex].AddData(sampleResidual);
3193 rmsImageLineResiduals[imageIndex].AddData(lineResidual);
3194 rmsImageResiduals[imageIndex].AddData(lineResidual);
3195 rmsImageResiduals[imageIndex].AddData(sampleResidual);
3199 QVector<Statistics> rmsLidarImageSampleResiduals(numberImages);
3200 QVector<Statistics> rmsLidarImageLineResiduals(numberImages);
3201 QVector<Statistics> rmsLidarImageResiduals(numberImages);
3205 for (
int i = 0; i < numLidarPoints; i++) {
3209 if (point->isRejected()) {
3213 int numMeasures = point->numberOfMeasures();
3214 for (
int j = 0; j < numMeasures; j++) {
3218 if (measure->isRejected()) {
3222 double sampleResidual = fabs(measure->sampleResidual());
3223 double lineResidual = fabs(measure->lineResidual());
3229 rmsLidarImageSampleResiduals[imageIndex].AddData(sampleResidual);
3230 rmsLidarImageLineResiduals[imageIndex].AddData(lineResidual);
3231 rmsLidarImageResiduals[imageIndex].AddData(lineResidual);
3232 rmsLidarImageResiduals[imageIndex].AddData(sampleResidual);
3242 QString minSigmaCoord1PointId =
"";
3245 QString maxSigmaCoord1PointId =
"";
3249 QString minSigmaCoord2PointId =
"";
3252 QString maxSigmaCoord2PointId =
"";
3256 QString minSigmaCoord3PointId =
"";
3259 QString maxSigmaCoord3PointId =
"";
3266 Distance sigmaCoord1Dist, sigmaCoord2Dist, sigmaCoord3Dist;
3271 for (
int i = 0; i < numPoints; i++) {
3275 maxSigmaCoord1Dist = point->adjustedSurfacePoint().GetSigmaDistance(type,
3277 minSigmaCoord1Dist = maxSigmaCoord1Dist;
3279 maxSigmaCoord2Dist = point->adjustedSurfacePoint().GetSigmaDistance(type,
3281 minSigmaCoord2Dist = maxSigmaCoord2Dist;
3283 maxSigmaCoord1PointId = point->id();
3284 maxSigmaCoord2PointId = maxSigmaCoord1PointId;
3285 minSigmaCoord1PointId = maxSigmaCoord1PointId;
3286 minSigmaCoord2PointId = maxSigmaCoord1PointId;
3290 maxSigmaCoord3Dist = point->adjustedSurfacePoint().GetSigmaDistance(type,
3291 SurfacePoint::Three);
3292 minSigmaCoord3Dist = maxSigmaCoord3Dist;
3294 maxSigmaCoord3PointId = maxSigmaCoord1PointId;
3295 minSigmaCoord3PointId = maxSigmaCoord1PointId;
3300 for (
int i = 0; i < numPoints; i++) {
3304 sigmaCoord1Dist = point->adjustedSurfacePoint().GetSigmaDistance(type,
3306 sigmaCoord2Dist = point->adjustedSurfacePoint().GetSigmaDistance(type,
3308 sigmaCoord3Dist = point->adjustedSurfacePoint().GetSigmaDistance(type,
3309 SurfacePoint::Three);
3311 sigmaCoord1Stats.AddData(sigmaCoord1Dist.meters());
3312 sigmaCoord2Stats.AddData(sigmaCoord2Dist.meters());
3313 sigmaCoord3Stats.AddData(sigmaCoord3Dist.meters());
3315 if (sigmaCoord1Dist > maxSigmaCoord1Dist) {
3316 maxSigmaCoord1Dist = sigmaCoord1Dist;
3317 maxSigmaCoord1PointId = point->id();
3319 if (sigmaCoord2Dist > maxSigmaCoord2Dist) {
3320 maxSigmaCoord2Dist = sigmaCoord2Dist;
3321 maxSigmaCoord2PointId = point->id();
3324 if (sigmaCoord3Dist > maxSigmaCoord3Dist) {
3325 maxSigmaCoord3Dist = sigmaCoord3Dist;
3326 maxSigmaCoord3PointId = point->id();
3329 if (sigmaCoord1Dist < minSigmaCoord1Dist) {
3330 minSigmaCoord1Dist = sigmaCoord1Dist;
3331 minSigmaCoord1PointId = point->id();
3333 if (sigmaCoord2Dist < minSigmaCoord2Dist) {
3334 minSigmaCoord2Dist = sigmaCoord2Dist;
3335 minSigmaCoord2PointId = point->id();
3338 if (sigmaCoord3Dist < minSigmaCoord3Dist) {
3339 minSigmaCoord3Dist = sigmaCoord3Dist;
3340 minSigmaCoord3PointId = point->id();
3349 minSigmaCoord1PointId, maxSigmaCoord1PointId);
3352 minSigmaCoord2PointId, maxSigmaCoord2PointId);
3355 minSigmaCoord3PointId, maxSigmaCoord3PointId);
3358 sigmaCoord2Stats.Rms(),
3359 sigmaCoord3Stats.Rms());
3362 rmsImageSampleResiduals.toList(),
3363 rmsImageResiduals.toList());
3366 rmsLidarImageSampleResiduals.toList(),
3367 rmsLidarImageResiduals.toList());
static void Log(PvlGroup &results)
Writes Pvl results to sessionlog and printfile.
QString modelState(int index)
Return the updated model state for the ith cube in the cube list given to the constructor.
bool m_cleanUp
!< If the iteration summaries should be output to the log file.
int m_rank
!< If the serial number lists need to be deleted by the destructor.
SparseBlockMatrix m_sparseNormals
!< The right hand side of the normal equations.
int numberOfImages() const
Returns the number of images.
void productAB(SparseBlockColumnMatrix &A, SparseBlockRowMatrix &B)
Perform the matrix multiplication C = N12 x Q.
bool solveCholesky()
Compute the least squares bundle adjustment solution using Cholesky decomposition.
bool computeBundleStatistics()
Compute Bundle statistics and store them in m_bundleResults.
double m_iterationTime
Time for last iteration.
int formLidarPointNormals(LinearAlgebra::MatrixUpperTriangular &N22, SparseBlockColumnMatrix &N12, LinearAlgebra::Vector &n2, LinearAlgebra::Vector &nj, BundleLidarControlPointQsp &point)
Compute the Q matrix and NIC vector for a control point.
bool formNormalEquations()
Form the least-squares normal equations matrix via cholmod.
SerialNumberList * serialNumberList()
Returns a pointer to the serial number list.
void init(Progress *progress=0)
Initialize all solution parameters.
bool computePartials(LinearAlgebra::Matrix &coeffTarget, LinearAlgebra::Matrix &coeffImage, LinearAlgebra::Matrix &coeffPoint3D, LinearAlgebra::Vector &coeffRHS, BundleMeasure &measure, BundleControlPoint &point)
Compute partial derivatives and weighted residuals for a measure.
bool isConverged()
Returns if the BundleAdjust converged.
QString fileName(int index)
Return the ith filename in the cube list file given to constructor.
void abortBundle()
Flag to abort when bundle is threaded.
QString m_lidarFileName
Input lidar point filename.
int m_previousNumberImagePartials
!< The image parameter solution vector.
double iteration() const
Returns what iteration the BundleAdjust is currently on.
void outputBundleStatus(QString status)
Slot for deltack and jigsaw to output the bundle status.
bool flagOutliers()
Flags outlier measures and control points.
QVector< BundleControlPointQsp > m_bundleControlPoints
Vector of control points.
LidarDataQsp lidarData()
Returns a pointer to the output lidar data file.
bool isAborted()
Returns if the BundleAdjust has been aborted.
BundleSettingsQsp m_bundleSettings
Contains the solve settings.
bool invert3x3(LinearAlgebra::MatrixUpperTriangular &m)
Dedicated quick inverse of 3x3 matrix.
int m_numLidarConstraints
TODO: temp.
Table cMatrix(int index)
Return the updated instrument pointing table for the ith cube in the cube list given to the construct...
double computeVtpv()
Computes vtpv, the weighted sum of squares of residuals.
QList< ImageList * > imageLists()
This method returns the image list used in the bundle adjust.
void applyParameterCorrections()
Apply parameter corrections for current iteration.
bool initializeCHOLMODLibraryVariables()
Initializations for CHOLMOD sparse matrix package.
boost::numeric::ublas::symmetric_matrix< double, boost::numeric::ublas::upper, boost::numeric::ublas::column_major > m_normalInverse
!< The lists of images used in the bundle.
LinearAlgebra::Vector m_imageSolution
!< The lower triangular L matrix from Cholesky decomposition.
cholmod_triplet * m_cholmodTriplet
!< The sparse block normal equations matrix.
ControlNetQsp m_controlNet
Output control net.
bool validateNetwork()
control network validation - on the very real chance that the net has not been checked before running...
SerialNumberList * m_serialNumberList
!< Vector of observations.
bool loadCholmodTriplet()
Load sparse normal equations matrix into CHOLMOD triplet.
LidarDataQsp m_lidarDataSet
Output lidar data.
cholmod_factor * m_L
!< The CHOLMOD sparse normal equations matrix used by cholmod_factorize to solve the system.
bool solveSystem()
Compute the solution to the normal equations using the CHOLMOD library.
BundleAdjust(BundleSettingsQsp bundleSettings, const QString &cnetFile, const QString &cubeList, bool printSummary=true)
Construct a BundleAdjust object from the given settings, control network file, and cube list.
void accumProductAlphaAB(double alpha, SparseBlockRowMatrix &A, LinearAlgebra::Vector &B, LinearAlgebra::Vector &C)
Performs the matrix multiplication nj = nj + alpha (Q x n2).
bool initializeNormalEquationsMatrix()
Initialize Normal Equations matrix (m_sparseNormals).
QString iterationSummaryGroup() const
Returns the iteration summary string.
LinearAlgebra::Vector m_RHS
!< Contains object parameters, statistics, and workspace used by the CHOLMOD library.
bool errorPropagation()
Error propagation for solution.
BundleResults m_bundleResults
Stores the results of the bundle adjust.
QString m_cnetFileName
The control net filename.
bool formMeasureNormals(LinearAlgebra::MatrixUpperTriangular &N22, SparseBlockColumnMatrix &N12, LinearAlgebra::VectorCompressed &n1, LinearAlgebra::Vector &n2, LinearAlgebra::Matrix &coeffTarget, LinearAlgebra::Matrix &coeffImage, LinearAlgebra::Matrix &coeffPoint3D, LinearAlgebra::Vector &coeffRHS, int observationIndex)
Form the auxilary normal equation matrices for a measure.
BundleSolutionInfo * bundleSolveInformation()
Create a BundleSolutionInfo containing the settings and results from the bundle adjustment.
int formPointNormals(LinearAlgebra::MatrixUpperTriangular &N22, SparseBlockColumnMatrix &N12, LinearAlgebra::Vector &n2, LinearAlgebra::Vector &nj, BundleControlPointQsp &point)
Compute the Q matrix and NIC vector for a control point.
bool m_abort
!< Contains information about the target body.
BundleLidarPointVector m_bundleLidarControlPoints
Vector of lidar points.
void computeResiduals()
Compute image measure residuals.
bool m_printSummary
!< Summary of the most recently completed iteration.
bool computeRejectionLimit()
Compute rejection limit.
bool productATransB(LinearAlgebra::MatrixUpperTriangular &N22, SparseBlockColumnMatrix &N12, SparseBlockRowMatrix &Q)
Perform the matrix multiplication Q = N22 x N12(transpose)
void iterationSummary()
Creates an iteration summary and an iteration group for the solution summary.
int m_iteration
The current iteration.
bool freeCHOLMODLibraryVariables()
Free CHOLMOD library variables.
bool formWeightedNormals(LinearAlgebra::VectorCompressed &n1, LinearAlgebra::Vector &nj)
Apply weighting for spacecraft position, velocity, acceleration and camera angles,...
BundleSolutionInfo * solveCholeskyBR()
Compute the least squares bundle adjustment solution using Cholesky decomposition.
ControlNetQsp controlNet()
Returns a pointer to the output control network.
cholmod_sparse * m_cholmodNormal
!< The CHOLMOD triplet representation of the sparse normal equations matrix.
~BundleAdjust()
Destroys BundleAdjust object, deallocates pointers (if we have ownership), and frees variables from c...
Table spVector(int index)
Return the updated instrument position table for the ith cube in the cube list given to the construct...
This class holds information about a control point that BundleAdjust needs to run correctly.
SurfacePoint adjustedSurfacePoint() const
Accesses the adjusted SurfacePoint associated with this BundleControlPoint.
QString id() const
Accesses the Point ID associated with this BundleControlPoint.
This class hold image information that BundleAdjust needs to run correctly.Definition for a BundleIma...
This class holds information about a lidar control point that BundleAdjust requires.
double vtpvRangeContribution()
Compute vtpv of lidar range constraints.
A container class for a ControlMeasure.
BundleObservationQsp addNew(BundleImageQsp image, QString observationNumber, QString instrumentId, BundleSettingsQsp bundleSettings)
Adds a new BundleObservation to this vector or fetches an existing BundleObservation if this vector a...
int numberParameters()
Returns the sum of the position parameters and pointing parameters for the contained BundleObservatio...
BundleObservationQsp observationByCubeSerialNumber(QString cubeSerialNumber)
Accesses a BundleObservation associated with the passed serial number.
void addProbabilityDistributionObservation(double obsValue)
Adds an observation to the cumulative probability distribution of |R^2 residuals|.
void incrementNumberConstrainedImageParameters(int incrementAmount)
Increase the number of constrained image parameters.
double elapsedTimeErrorProp() const
Returns the elapsed time for error propagation.
int numberRejectedObservations() const
Returns the number of observation that were rejected.
double rejectionLimit() const
Returns the rejection limit.
int numberObservations() const
Returns the number of observations.
void setElapsedTime(double time)
Sets the elapsed time for the bundle adjustment.
MaximumLikelihoodWFunctions maximumLikelihoodModelWFunc(int modelIndex) const
Returns the maximum likelihood model at the given index.
void setBundleControlPoints(QVector< BundleControlPointQsp > controlPoints)
Sets the bundle control point vector.
void setNumberConstrainedPointParameters(int numberParameters)
Set number of contrained point parameters.
void setBundleLidarPoints(QVector< BundleLidarControlPointQsp > lidarPoints)
Sets the bundle lidar point vector.
double sigma0() const
Returns the Sigma0 of the bundle adjustment.
void setIterations(int iterations)
Sets the number of iterations taken by the BundleAdjust.
bool converged() const
Returns whether or not the bundle adjustment converged.
void setSigmaCoord1Range(Distance minCoord1Dist, Distance maxCoord1Dist, QString minCoord1PointId, QString maxCoord1PointId)
Sets the min and max sigma distances and point ids for coordinate 1.
void incrementMaximumLikelihoodModelIndex()
Increases the value that indicates which stage the maximum likelihood adjustment is currently on.
void setOutputControlNet(ControlNetQsp outNet)
Sets the output ControlNet.
void setSigmaCoord2Range(Distance minCoord2Dist, Distance maxCoord2Dist, QString minCoord2PointId, QString maxCoord2PointId)
Sets the min and max sigma distances and point ids for coordinate 2.
int numberConstrainedPointParameters() const
Returns the number of constrained point parameters.
void resetNumberConstrainedImageParameters()
Resets the number of constrained image parameters to 0.
void setNumberRejectedObservations(int numberObservations)
Sets the number of rejected observations.
void maximumLikelihoodSetUp(QList< QPair< MaximumLikelihoodWFunctions::Model, double > > modelsWithQuantiles)
This method steps up the maximum likelihood estimation solution.
int numberUnknownParameters() const
Returns the number of unknown parameters.
void addResidualsProbabilityDistributionObservation(double obsValue)
Adds an observation to the cumulative probability distribution of residuals used for reporting.
int numberMaximumLikelihoodModels() const
Returns how many maximum likelihood models were used in the bundle adjustment.
void setNumberLidarRangeConstraints(int numberLidarRangeConstraints)
Sets the total number of lidar range constraints.
int maximumLikelihoodModelIndex() const
Returns which step the bundle adjustment is on.
void setRejectionLimit(double rejectionLimit)
Sets the rejection limit.
void incrementNumberConstrainedTargetParameters(int incrementAmount)
Increases the number of constrained target parameters.
void setOutputLidarData(LidarDataQsp outLidarData)
Sets the output LidarData object.
void setNumberImageObservations(int numberObservations)
Sets the number of photogrammetric image observations.
void setRmsImageResidualLists(QList< Statistics > rmsImageLineResiduals, QList< Statistics > rmsImageSampleResiduals, QList< Statistics > rmsImageResiduals)
Sets the root mean square image residual Statistics lists.
double maximumLikelihoodMedianR2Residuals() const
Returns the median of the |R^2 residuals|.
void setNumberLidarImageObservations(int numberLidarObservations)
Sets the number of lidar observations.
int numberConstrainedTargetParameters() const
Return the number of constrained target parameters.
double elapsedTime() const
Returns the elapsed time for the bundle adjustment.
void setNumberUnknownParameters(int numberParameters)
Sets the total number of parameters to solve for.
void setSigmaCoord3Range(Distance minCoord3Dist, Distance maxCoord3Dist, QString minCoord3PointId, QString maxCoord3PointId)
Sets the min and max sigma distances and point ids for coordinate 3.
void setNumberConstrainedLidarPointParameters(int numberParameters)
Set number of contrained point parameters.
void setObservations(BundleObservationVector observations)
Sets the vector of BundleObservations.
void initializeResidualsProbabilityDistribution(unsigned int nodes=20)
Initializes or resets the cumulative probability distribution of residuals used for reporting.
void setRmsFromSigmaStatistics(double rmsFromSigmaCoord1Stats, double rmsFromSigmaCoord2Stats, double rmsFromSigmaCoord3Stats)
Sets the root mean square values of the adjusted sigmas for all three coordinates.
void setRmsXYResiduals(double rx, double ry, double rxy)
Sets the root mean square of the x and y residuals.
void printMaximumLikelihoodTierInformation()
Prints out information about which tier the solution is in and the status of the residuals.
void resizeSigmaStatisticsVectors(int numberImages)
Resizes all image sigma vectors.
void setCorrMatCovFileName(FileName name)
Set the covariance file name for the matrix used to calculate the correlation matrix.
void setRmsLidarImageResidualLists(QList< Statistics > rmsLidarImageLineResiduals, QList< Statistics > rmsLidarImageSampleResiduals, QList< Statistics > rmsLidarImageResiduals)
Sets the root mean square lidar image residual Statistics lists.
void computeSigma0(double dvtpv, BundleSettings::ConvergenceCriteria criteria)
Computes the sigma0 and stores it internally.
int numberConstrainedImageParameters() const
Returns the number of constrained image parameters.
void setElapsedTimeErrorProp(double time)
Sets the elapsed time for error propegation.
void setConverged(bool converged)
Sets if the bundle adjustment converged.
void resetNumberConstrainedTargetParameters()
Resets the number of constrained target parameters to 0.
int degreesOfFreedom() const
Returns the degrees of freedom.
@ Sigma0
The value of sigma0 will be used to determine that the bundle adjustment has converged.
Container class for BundleAdjustment results.
void setRunTime(QString runTime)
Sets the run time, and the name if a name is not already set.
QString getModelState() const
Get the CSM Model state string to re-create the CSM Model.
@ Csm
Community Sensor Model Camera.
virtual CameraType GetCameraType() const =0
Returns the type of camera that was created.
This represents an ISIS control net in a project-based GUI interface.
QString fileName() const
Access the name of the control network file associated with this Control.
Status ComputeApriori()
Computes a priori lat/lon/radius point coordinates by determining the average lat/lon/radius of all m...
Distance measurement, usually in meters.
File name manipulation and expansion.
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
@ Programmer
This error is for when a programmer made an API call that was illegal.
This represents a cube in a project-based GUI interface.
void closeCube()
Cleans up the Cube pointer.
QString fileName() const
Get the file name of the cube that this image represents.
Internalizes a list of images and allows for operations on the entire list.
boost::numeric::ublas::compressed_vector< double > VectorCompressed
Definition for an Isis::LinearAlgebra::VectorCompressed of doubles.
boost::numeric::ublas::vector< double > Vector
Definition for an Isis::LinearAlgebra::Vector of doubles.
boost::numeric::ublas::matrix< double > Matrix
Definition for an Isis::LinearAlgebra::Matrix of doubles.
boost::numeric::ublas::symmetric_matrix< double, boost::numeric::ublas::upper > MatrixUpperTriangular
Definition for an Isis::LinearAlgebra::MatrixUpperTriangular of doubles with an upper configuration.
double sqrtWeightScaler(double residualZScore)
This provides the scaler to the sqrt of the weight, which is very useful for building normal equation...
Program progress reporter.
Contains multiple PvlContainers.
A single keyword-value pair.
Serial Number list generator.
QString observationNumber(int index)
Return a observation number given an index.
QString serialNumber(const QString &filename)
Return a serial number given a filename.
void add(const QString &filename, bool def2filename=false)
Adds a new filename / serial number pair to the SerialNumberList.
QString spacecraftInstrumentId(int index)
Return the spacecraftname/instrumentid at the given index.
int size() const
How many serial number / filename combos are in the list.
int serialNumberIndex(const QString &sn)
Return a list index given a serial number.
QString fileName(const QString &sn)
Return a filename given a serial number.
void zeroBlocks()
Sets all elements of all matrix blocks to zero.
int numberOfBlocks()
Returns total number of blocks in matrix.
void wipe()
Deletes all pointer elements and removes them from the list.
bool insertMatrixBlock(int nColumnBlock, int nRowBlock, int nRows, int nCols)
Inserts a "newed" boost LinearAlgebra::Matrix pointer of size (nRows, nCols) into the matrix at nColu...
LinearAlgebra::Matrix * getBlock(int column, int row)
Returns pointer to boost matrix at position (column, row).
bool setNumberOfColumns(int n)
Initializes number of columns (SparseBlockColumnMatrix).
int numberOfElements()
Returns number of matrix elements in matrix.
void zeroBlocks()
Sets all elements of all matrix blocks to zero.
This class is used to accumulate statistics on double arrays.
This class defines a body-fixed surface point.
CoordinateType
Defines the coordinate typ, units, and coordinate index for some of the output methods.
@ Latitudinal
Planetocentric latitudinal (lat/lon/rad) coordinates.
@ Rectangular
Body-fixed rectangular x/y/z coordinates.
void SetMatrix(CoordinateType type, const boost::numeric::ublas::symmetric_matrix< double, boost::numeric::ublas::upper > &covar)
Set the covariance matrix.
Class for storing Table blobs information.
static QString CurrentLocalTime()
Returns the current local time This time is taken directly from the system clock, so if the system cl...
This is free and unencumbered software released into the public domain.
QSharedPointer< LidarData > LidarDataQsp
Definition for a shared pointer to a LidarData object.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
static void cholmodErrorHandler(int nStatus, const char *file, int nLineNo, const char *message)
Custom error handler for CHOLMOD.
QSharedPointer< ControlNet > ControlNetQsp
Typedef for QSharedPointer to control network. This typedef is for future implementation of target bo...