Skip to content

Commit

Permalink
Added adjusted XYZ point coordinate sigmas to the points.csv jigsaw o…
Browse files Browse the repository at this point in the history
…utput file. Modified (#5711)

ctest FunctionalTestJigsawApollo to validate this output. Addresses #5710.
  • Loading branch information
kledmundson authored Feb 10, 2025
1 parent 16f8c50 commit 2347762
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 69 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ release.
## [Unreleased]

### Added
- Added adjusted XYZ point coordinate sigmas to the points.csv jigsaw output file. Modified
ctest FunctionalTestJigsawApollo to validate this output. [#5710](https://github.com/DOI-USGS/ISIS3/issues/5710)
- Added OFFBODY and OFFBODYTRIM parameters to cam2cam. Added tests and updated documentation. [#3602] (https://github.com/DOI-USGS/ISIS3/issues/3602)

### Changed
Expand Down
140 changes: 81 additions & 59 deletions isis/src/control/objs/BundleSolutionInfo/BundleSolutionInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1611,32 +1611,47 @@ namespace Isis {

double dLat, dLon, dRadius;
double dX, dY, dZ;
double dSigmaLat, dSigmaLong, dSigmaRadius;
QString strStatus;
double cor_lat_dd = 0.0; // lat correction, decimal degrees
double cor_lon_dd = 0.0; // lon correction, decimal degrees
double cor_rad_km = 0.0; // radius correction, kilometers

double cor_lat_m = 0.0; // lat correction, meters
double cor_lon_m = 0.0; // lon correction, meters
double cor_rad_m = 0.0; // radius correction, meters

double cor_x_km = 0.0; // x correction, kilometers
double cor_y_km = 0.0; // y correction, kilometers
double cor_z_km = 0.0; // z correction, kilometers

double latInit = Isis::Null;
double lonInit = Isis::Null;
double radInit = Isis::Null;

int numMeasures, numRejectedMeasures;
double dResidualRms;

// bundle coordinate type (Lat, Lon, Radius or XYZ)
bool bundleLatLonRadius = true;
if ( m_settings->controlPointCoordTypeBundle() == SurfacePoint::Rectangular ) {
bundleLatLonRadius = false;
}

// print column headers
if (m_settings->errorPropagation()) {
snprintf(buf, sizeof(buf), ",,,,,3-d,3-d,3-d,Sigma,Sigma,Sigma,Correction,Correction,Correction,Coordinate,"
"Coordinate,Coordinate\nPoint,Point,Accepted,Rejected,Residual,Latitude,Longitude,"
"Radius,Latitude,Longitude,Radius,Latitude,Longitude,Radius,X,Y,Z\nLabel,Status,"
"Measures,Measures,RMS,(dd),(dd),(km),(m),(m),(m),(m),(m),(m),(km),(km),(km)\n");
snprintf(buf, sizeof(buf), ",,,,,3-d,3-d,3-d,Sigma,Sigma,Sigma,Correction,Correction,Correction,"
"Coordinate,Coordinate,Coordinate,Sigma,Sigma,Sigma\n"
"Point,Point,Accepted,Rejected,Residual,Latitude,Longitude,Radius,Latitude,Longitude,"
"Radius,Latitude,Longitude,Radius,X,Y,Z,X,Y,Z\n"
"Label,Status,Measures,Measures,RMS,(dd),(dd),(km),(m),(m),(m),(m),(m),(m),(km),(km),(km),"
"(m),(m),(m)\n");
}
else {
snprintf(buf, sizeof(buf), ",,,,,3-d,3-d,3-d,Correction,Correction,Correction,Coordinate,Coordinate,"
"Coordinate\nPoint,Point,Accepted,Rejected,Residual,Latitude,Longitude,Radius,"
"Latitude,Longitude,Radius,X,Y,Z\nLabel,Status,Measures,Measures,RMS,(dd),(dd),(km),"
"(m),(m),(m),(km),(km),(km)\n");
snprintf(buf, sizeof(buf), ",,,,,3-d,3-d,3-d,Correction,Correction,Correction,Coordinate,"
"Coordinate,Coordinate\n"
"Point,Point,Accepted,Rejected,Residual,Latitude,Longitude,Radius,Latitude,Longitude,"
"Radius,X,Y,Z\n"
"Label,Status,Measures,Measures,RMS,(dd),(dd),(km),(m),(m),(m),(km),(km),(km)\n");
}
fpOut << buf;

Expand All @@ -1651,53 +1666,53 @@ namespace Isis {
continue;
}

dLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatitude().degrees();
dLon = bundlecontrolpoint->adjustedSurfacePoint().GetLongitude().degrees();
dRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadius().kilometers();
dX = bundlecontrolpoint->adjustedSurfacePoint().GetX().kilometers();
dY = bundlecontrolpoint->adjustedSurfacePoint().GetY().kilometers();
dZ = bundlecontrolpoint->adjustedSurfacePoint().GetZ().kilometers();
dLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatitude().degrees();
dLon = bundlecontrolpoint->adjustedSurfacePoint().GetLongitude().degrees();
dRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadius().kilometers();
dX = bundlecontrolpoint->adjustedSurfacePoint().GetX().kilometers();
dY = bundlecontrolpoint->adjustedSurfacePoint().GetY().kilometers();
dZ = bundlecontrolpoint->adjustedSurfacePoint().GetZ().kilometers();
numMeasures = bundlecontrolpoint->numberOfMeasures();
numRejectedMeasures = bundlecontrolpoint->numberOfRejectedMeasures();
dResidualRms = bundlecontrolpoint->residualRms();
dResidualRms = bundlecontrolpoint->residualRms();

// Use the local radius in meters, rad*1000., to convert radians to meters now instead of the
// target body equatorial radius (DAC 09/17/2018; from BundleControlPoint.cpp)
double rtm = dRadius * 1000.;

// point corrections and initial sigmas
// point corrections
// Latitude, Longitude corrections are decimal degrees;
// Radius correction is kilometers
boost::numeric::ublas::bounded_vector< double, 3 > corrections = bundlecontrolpoint->
corrections();

if (m_settings->controlPointCoordTypeBundle() == SurfacePoint::Rectangular) {
double xCor = corrections(0); // km
double yCor = corrections(1); // km
double zCor = corrections(2); // km
// solution is rectangular (point coordinates are X,Y,Z)
// must compute latitudinal initial coordinates and corrections
if (bundleLatLonRadius == false) {
cor_x_km = corrections(0);
cor_y_km = corrections(1);
cor_z_km = corrections(2);

if (!IsSpecial(dX) && !IsSpecial(dY) && !IsSpecial(dZ)) {
SurfacePoint rectPoint(Displacement(dX - xCor, Displacement::Kilometers),
Displacement(dY - yCor, Displacement::Kilometers),
Displacement(dZ - zCor, Displacement::Kilometers));
SurfacePoint rectInitPoint(Displacement(dX - cor_x_km, Displacement::Kilometers),
Displacement(dY - cor_y_km, Displacement::Kilometers),
Displacement(dZ - cor_z_km, Displacement::Kilometers));

latInit = rectPoint.GetLatitude().degrees();
lonInit = rectPoint.GetLongitude().degrees();
radInit = rectPoint.GetLocalRadius().kilometers();
latInit = rectInitPoint.GetLatitude().degrees();
lonInit = rectInitPoint.GetLongitude().degrees();
radInit = rectInitPoint.GetLocalRadius().kilometers();

if (!IsSpecial(dLat)) {
cor_lat_dd = (dLat - latInit); // degrees
cor_lat_m = cor_lat_dd * DEG2RAD * rtm;
}
if (!IsSpecial(dLon)) {
cor_lon_dd = (dLon - lonInit); // degrees
cor_lon_m = cor_lon_dd * DEG2RAD * rtm * cos(dLat*DEG2RAD); // lon corrections meters
}
if (!IsSpecial(dRadius)) {
cor_rad_km = dRadius - radInit;
cor_rad_m = cor_rad_km * 1000.;
}
cor_lat_dd = (dLat - latInit); // degrees
cor_lon_dd = (dLon - lonInit); // degrees
cor_rad_km = dRadius - radInit;

cor_lat_m = cor_lat_dd * DEG2RAD * rtm;
cor_lon_m = cor_lon_dd * DEG2RAD * rtm * cos(dLat*DEG2RAD); // lon corrections meters
cor_rad_m = cor_rad_km * 1000.;
}
}
else if (m_settings->controlPointCoordTypeBundle() == SurfacePoint::Latitudinal) {
// solution is latitudinal (point coordinates are Latitude, Longitude, Radius)
else if (bundleLatLonRadius == true) {
cor_lat_dd = corrections(0) * RAD2DEG; // lat correction, decimal degs
cor_lon_dd = corrections(1) * RAD2DEG; // lon correction, decimal degs
cor_rad_m = corrections(2) * 1000.0; // radius correction, meters
Expand All @@ -1706,16 +1721,14 @@ namespace Isis {
cor_lon_m = bundlecontrolpoint->adjustedSurfacePoint().LongitudeToMeters(corrections(1));
cor_rad_km = corrections(2);

if (!IsSpecial(dLat)) {
latInit = dLat - cor_lat_dd;
}

if (!IsSpecial(dLon)) {
lonInit = dLon - cor_lon_dd;
}
if (!IsSpecial(dLat) && !IsSpecial(dLon) && !IsSpecial(dRadius)) {
SurfacePoint latInitPoint(Latitude(dLat - cor_lat_dd, Angle::Degrees),
Longitude(dLon - cor_lon_dd, Angle::Degrees),
Distance(dRadius - corrections(2), Distance::Kilometers));

if (!IsSpecial(dRadius)) {
radInit = dRadius - corrections(2); // km
latInit = latInitPoint.GetLatitude().degrees();
lonInit = latInitPoint.GetLongitude().degrees();
radInit = latInitPoint.GetLocalRadius().kilometers();
}
}

Expand All @@ -1733,22 +1746,31 @@ namespace Isis {
}

if (m_settings->errorPropagation()) {
double dSigmaLat, dSigmaLong, dSigmaRadius;
double dSigmaX, dSigmaY, dSigmaZ;

dSigmaLat = bundlecontrolpoint->adjustedSurfacePoint().GetLatSigmaDistance().meters();
dSigmaLong = bundlecontrolpoint->adjustedSurfacePoint().GetLonSigmaDistance().meters();
dSigmaRadius = bundlecontrolpoint->adjustedSurfacePoint().GetLocalRadiusSigma().meters();

snprintf(buf, sizeof(buf), "%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
"%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf\n",
bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, dSigmaLat,
dSigmaLong, dSigmaRadius, cor_lat_m, cor_lon_m, cor_rad_m, dX, dY, dZ);
dSigmaX = bundlecontrolpoint->adjustedSurfacePoint().GetXSigma().meters();
dSigmaY = bundlecontrolpoint->adjustedSurfacePoint().GetYSigma().meters();
dSigmaZ = bundlecontrolpoint->adjustedSurfacePoint().GetZSigma().meters();

snprintf(buf, sizeof(buf), "%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
"%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
"%16.8lf\n",
bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, dSigmaLat,
dSigmaLong, dSigmaRadius, cor_lat_m, cor_lon_m, cor_rad_m, dX, dY, dZ,
dSigmaX,dSigmaY,dSigmaZ);
}
else
snprintf(buf, sizeof(buf), "%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
"%16.8lf,%16.8lf\n",
bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, cor_lat_m,
cor_lon_m, cor_rad_m, dX, dY, dZ);
snprintf(buf, sizeof(buf), "%s,%s,%d,%d,%6.2lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,%16.8lf,"
"%16.8lf,%16.8lf,%16.8lf\n",
bundlecontrolpoint->id().toLatin1().data(), strStatus.toLatin1().data(),
numMeasures, numRejectedMeasures, dResidualRms, dLat, dLon, dRadius, cor_lat_m,
cor_lon_m, cor_rad_m, dX, dY, dZ);

fpOut << buf;
}
Expand Down
2 changes: 2 additions & 0 deletions isis/src/control/objs/BundleSolutionInfo/BundleSolutionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ namespace Isis {
* bundle adjustment, the Lat/Lon/Radius point corrections written
* to the points.csv file are incorrect and do not match those written
* to the bundleout.txt file.
* @history 2025-01-19 Ken Edmundson - Added three columns to the end of each line in the
* points.csv file for the adjusted XYZ point sigmas.
*/
class BundleSolutionInfo : public QObject {
Q_OBJECT
Expand Down
20 changes: 10 additions & 10 deletions isis/tests/FunctionalTestsJigsaw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,18 @@ TEST_F(ApolloNetwork, FunctionalTestJigsawApollo) {
int numColumns = line.columns();
int numRows = line.rows();

ASSERT_EQ(numColumns, 12);
ASSERT_EQ(numColumns, 15);
ASSERT_EQ(numRows, 398);

// Validate the line information is correct
csvLine = line.getRow(0);
compareCsvLine(csvLine, "3-d,3-d,3-d,Sigma,Sigma,Sigma,Correction,Correction,Correction,Coordinate,Coordinate,Coordinate");
compareCsvLine(csvLine, "3-d,3-d,3-d,Sigma,Sigma,Sigma,Correction,Correction,Correction,Coordinate,Coordinate,Coordinate,Sigma,Sigma,Sigma");

csvLine = line.getRow(1);
compareCsvLine(csvLine, "Point,Point,Accepted,Rejected,Residual,Latitude,Longitude,Radius,Latitude,Longitude,Radius,Latitude,Longitude,Radius,X,Y,Z");
compareCsvLine(csvLine, "Point,Point,Accepted,Rejected,Residual,Latitude,Longitude,Radius,Latitude,Longitude,Radius,Latitude,Longitude,Radius,X,Y,Z,X,Y,Z");

csvLine = line.getRow(2);
compareCsvLine(csvLine, "Label,Status,Measures,Measures,RMS,(dd),(dd),(km),(m),(m),(m),(m),(m),(m),(km),(km),(km)");
compareCsvLine(csvLine, "Label,Status,Measures,Measures,RMS,(dd),(dd),(km),(m),(m),(m),(m),(m),(m),(km),(km),(km),(m),(m),(m)");

// Compare all of the values from the network against the values in the CSV
QList<ControlPoint*> points = outputNet.GetPoints();
Expand Down Expand Up @@ -115,14 +115,14 @@ TEST_F(ApolloNetwork, FunctionalTestJigsawApollo) {

// Spot check a few points for hard-coded values
// A few "Free" points:
compareCsvLine(line.getRow(30), "AS15_000031957,FREE,3,0,0.33,24.25013429,6.15097050,1735.93990543,270.68671676,265.71819251,500.96944842,860.25781493,-1823.63228489,-677.74533463,1573.65050943,169.59077243,712.98695596");
compareCsvLine(line.getRow(185), "AS15_000055107,FREE,2,0,2.22,24.26598395,6.75841991,1735.27498710,303.08885516,295.63588060,562.91712019,876.14367347,-1869.62276530,-708.50440630,1570.96622187,186.17020493,713.15150243");
compareCsvLine(line.getRow(396), "AS15_Tie14,FREE,4,0,0.76,23.34007344,4.52764905,1737.15233677,245.96412227,251.30260955,443.11518635,1022.08062058,-1897.32816475,-372.27330000,1590.02287614,125.90958874,688.23852695");
compareCsvLine(line.getRow(30), "AS15_000031957,FREE,3,0,0.33,24.25013429,6.15097050,1735.93990543,270.68671676,265.71819251,500.96944842,860.25781493,-1823.63228489,-677.74533463,1573.65050943,169.59077243,712.98695596, 465.66755434, 267.66330908, 326.12562996");
compareCsvLine(line.getRow(185), "AS15_000055107,FREE,2,0,2.22,24.26598395,6.75841991,1735.27498710,303.08885516,295.63588060,562.91712019,876.14367347,-1869.62276530,-708.50440630,1570.96622187,186.17020493,713.15150243, 522.79515846, 298.42172842, 365.74418181");
compareCsvLine(line.getRow(396), "AS15_Tie14,FREE,4,0,0.76,23.34007344,4.52764905,1737.15233677,245.96412227,251.30260955,443.11518635,1022.08062058,-1897.32816475,-372.27330000,1590.02287614,125.90958874,688.23852695, 414.98905206, 251.82613853, 290.46531976");

// A few "Constrained" points:
compareCsvLine(line.getRow(352), "AS15_SocetPAN_01,CONSTRAINED,3,0,0.27,27.61487917,2.18951566,1735.78407271,160.95596643,162.33483092,285.90375398,103.62041173,223.18286146,306.44770820,1536.92627520,58.76110229,804.58132250", 2);
compareCsvLine(line.getRow(360), "AS15_SocetPAN_10,CONSTRAINED,4,0,1.14,25.96587004,3.54262524,1735.72172102,113.85794037,113.34020561,189.03901900,-54.11385318,174.35206231,4.97102217,1557.52735013,96.42556502,759.96089165", 2);
compareCsvLine(line.getRow(380), "AS15_SocetPAN_40,CONSTRAINED,2,0,0.42,25.77498986,1.88090884,1735.56132012,133.81392881,132.83513465,230.53187100,23.85721304,82.06385794,171.57011514,1562.04594097,51.29735448,754.68811810", 2);
compareCsvLine(line.getRow(352), "AS15_SocetPAN_01,CONSTRAINED,3,0,0.27,27.61487917,2.18951566,1735.78407271,160.95596643,162.33483092,285.90375398,103.62041173,223.18286146,306.44770820,1536.92627520,58.76110229,804.58132250, 265.9686138, 162.53199952, 191.94901028", 2);
compareCsvLine(line.getRow(360), "AS15_SocetPAN_10,CONSTRAINED,4,0,1.14,25.96587004,3.54262524,1735.72172102,113.85794037,113.34020561,189.03901900,-54.11385318,174.35206231,4.97102217,1557.52735013,96.42556502,759.96089165, 176.89344204, 113.71419, 131.61753927", 2);
compareCsvLine(line.getRow(380), "AS15_SocetPAN_40,CONSTRAINED,2,0,0.42,25.77498986,1.88090884,1735.56132012,133.81392881,132.83513465,230.53187100,23.85721304,82.06385794,171.57011514,1562.04594097,51.29735448,754.68811810, 214.5688998, 133.00415652, 158.00748601", 2);

// Check for the correct line output format and csv file structure for the images.csv file
line = CSVReader(imagesOutput,
Expand Down

0 comments on commit 2347762

Please sign in to comment.