Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
CsmBundleObservation.cpp
1
6
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "CsmBundleObservation.h"
10
11#include <QDebug>
12#include <QString>
13#include <QStringList>
14#include <QVector>
15
16#include "BundleImage.h"
17#include "BundleControlPoint.h"
18#include "BundleObservationSolveSettings.h"
19#include "BundleTargetBody.h"
20#include "Camera.h"
21#include "CSMCamera.h"
22#include "LinearAlgebra.h"
23#include "SpicePosition.h"
24#include "SpiceRotation.h"
25
26using namespace std;
27
28namespace Isis {
29
35
36
46 CsmBundleObservation::CsmBundleObservation(BundleImageQsp image, QString observationNumber,
47 QString instrumentId, BundleTargetBodyQsp bundleTargetBody) : BundleObservation(image, observationNumber, instrumentId, bundleTargetBody) {
48 if (bundleTargetBody) {
49 QString msg = "Target body parameters cannot be solved for with CSM observations.";
50 throw IException(IException::User, msg, _FILEINFO_);
51 }
52 }
53
54
64
65
73
74
85 if (&src != this) {
88 }
89 return *this;
90 }
91
92
103
104 CSMCamera *csmCamera = dynamic_cast<CSMCamera*>(front()->camera());
105
106 m_paramIndices.clear();
107 m_weights.clear();
108 m_corrections.clear();
109 m_adjustedSigmas.clear();
110
111 if (m_solveSettings->csmSolveOption() == BundleObservationSolveSettings::Set) {
112 m_paramIndices = csmCamera->getParameterIndices(m_solveSettings->csmParameterSet());
113 }
114 else if (m_solveSettings->csmSolveOption() == BundleObservationSolveSettings::Type) {
115 m_paramIndices = csmCamera->getParameterIndices(m_solveSettings->csmParameterType());
116 }
117 else if (m_solveSettings->csmSolveOption() == BundleObservationSolveSettings::List) {
118 m_paramIndices = csmCamera->getParameterIndices(m_solveSettings->csmParameterList());
119 }
120 else {
121 return false;
122 }
123
124 int nParams = m_paramIndices.size();
125
126 m_weights.resize(nParams);
127 m_corrections.resize(nParams);
128 m_adjustedSigmas.resize(nParams);
129 m_aprioriSigmas.resize(nParams);
130
131 for (int i = 0; i < nParams; i++) {
133 }
134
135 return true;
136 }
137
138
148
149
164 // Check that the correction vector is the correct size
165 if (corrections.size() != m_paramIndices.size()) {
166 QString msg = "Invalid correction vector passed to observation.";
167 IException(IException::Programmer, msg, _FILEINFO_);
168 }
169
170 // Apply the corrections to the CSM camera
171 CSMCamera *csmCamera = dynamic_cast<CSMCamera*>(front()->camera());
172 for (size_t i = 0; i < corrections.size(); i++) {
173 csmCamera->applyParameterCorrection(m_paramIndices[i], corrections[i]);
174 }
175
176 // Accumulate the total corrections
177 m_corrections += corrections;
178
179 return true;
180 }
181
182
194
195
205 void CsmBundleObservation::bundleOutputString(std::ostream &fpOut, bool errorPropagation) {
206
207 char buf[4096];
208
209 QVector<double> finalParameterValues;
210 CSMCamera *csmCamera = dynamic_cast<CSMCamera*>(front()->camera());
211
212 int nParameters = numberParameters();
213
214 QStringList parameterNamesList;
215 QStringList parameterUnitList;
216
217 for (int i = 0; i < nParameters; i++) {
218 parameterNamesList.append(csmCamera->getParameterName(m_paramIndices[i]));
219 parameterUnitList.append(csmCamera->getParameterUnits(m_paramIndices[i]));
220 finalParameterValues.append(csmCamera->getParameterValue(m_paramIndices[i]));
221 }
222
223
224 // Set up default values when we are using default position
225 QString sigma;
226 QString adjustedSigma;
227 double correction;
228
229 for (int i = 0; i < nParameters; i++) {
230
231 correction = m_corrections(i);
232 adjustedSigma = QString::number(m_adjustedSigmas[i], 'f', 8);
233 sigma = (IsSpecial(m_aprioriSigmas[i]) ? "FREE" : toString(m_aprioriSigmas[i], 8));
234
235 snprintf(buf, sizeof(buf), "%.11s", parameterNamesList.at(i).toStdString().c_str());
236 fpOut << buf;
237 snprintf(buf, sizeof(buf), "%18.8lf ", finalParameterValues[i] - correction);
238 fpOut << buf;
239 snprintf(buf, sizeof(buf), "%20.8lf ", correction);
240 fpOut << buf;
241 snprintf(buf, sizeof(buf), "%23.8lf ", finalParameterValues[i]);
242 fpOut << buf;
243 snprintf(buf, sizeof(buf), " ");
244 fpOut << buf;
245 snprintf(buf, sizeof(buf), "%6s", sigma.toStdString().c_str());
246 fpOut << buf;
247 snprintf(buf, sizeof(buf), " ");
248 fpOut << buf;
249 if (errorPropagation) {
250 snprintf(buf, sizeof(buf), "%s", adjustedSigma.toStdString().c_str());
251 }
252 else {
253 snprintf(buf, sizeof(buf), "%s","N/A");
254 }
255 fpOut << buf;
256 snprintf(buf, sizeof(buf), " ");
257 fpOut << buf;
258 snprintf(buf, sizeof(buf), "%s\n", parameterUnitList.at(i).toStdString().c_str());
259 fpOut << buf;
260
261 }
262 }
263
274 QString CsmBundleObservation::bundleOutputCSV(bool errorPropagation) {
275 QString finalqStr = "";
276 CSMCamera *csmCamera = dynamic_cast<CSMCamera*>(front()->camera());
277
278 for (size_t i = 0; i < m_paramIndices.size(); i++) {
279 double finalValue = csmCamera->getParameterValue(m_paramIndices[i]);
280 finalqStr += toString(finalValue - m_corrections[i]) + ",";
281 finalqStr += toString(m_corrections[i]) + ",";
282 finalqStr += toString(finalValue) + ",";
283 finalqStr += toString(m_aprioriSigmas[i], 8) + ",";
284 if (errorPropagation) {
285 finalqStr += QString::number(m_adjustedSigmas[i], 'f', 8) + ",";
286 }
287 else {
288 finalqStr += "N/A,";
289 }
290 }
291
292 return finalqStr;
293 }
294
295
306 QStringList paramList;
307 CSMCamera *csmCamera = dynamic_cast<CSMCamera*>(front()->camera());
308
309 for (int paramIndex : m_paramIndices) {
310 paramList.push_back(csmCamera->getParameterName(paramIndex));
311 }
312
313 return paramList;
314 }
315
330 if (bundleTargetBody) {
331 QString msg = "Target body parameters cannot be solved for with CSM observations.";
332 throw IException(IException::User, msg, _FILEINFO_);
333 }
334 return false;
335 }
336
337
351 coeffImage.clear();
352
353 CSMCamera *csmCamera = dynamic_cast<CSMCamera*>(measure.camera());
354 SurfacePoint groundPoint = measure.parentControlPoint()->adjustedSurfacePoint();
355
356 // Loop over parameters and populate matrix
357 for (size_t i = 0; i < m_paramIndices.size(); i++) {
358 vector<double> partials = csmCamera->getSensorPartials(m_paramIndices[i], groundPoint);
359 coeffImage(0, i) = partials[1];
360 coeffImage(1, i) = partials[0];
361 }
362
363 return true;
364 }
365
366
382 coeffPoint3D.clear();
383
384 CSMCamera *measureCamera = dynamic_cast<CSMCamera*>(measure.camera());
385
386 // do ground partials
387 SurfacePoint groundPoint = measure.parentControlPoint()->adjustedSurfacePoint();
388 vector<double> groundPartials = measureCamera->GroundPartials(groundPoint);
389
390 if (coordType == SurfacePoint::Rectangular) {
391 // groundPartials is:
392 // line WRT x
393 // line WRT y
394 // line WRT z
395 // sample WRT x
396 // sample WRT y
397 // sample WRT z
398 // Scale from WRT m to WRT Km
399 coeffPoint3D(1,0) = groundPartials[0] * 1000;
400 coeffPoint3D(1,1) = groundPartials[1] * 1000;
401 coeffPoint3D(1,2) = groundPartials[2] * 1000;
402 coeffPoint3D(0,0) = groundPartials[3] * 1000;
403 coeffPoint3D(0,1) = groundPartials[4] * 1000;
404 coeffPoint3D(0,2) = groundPartials[5] * 1000;
405 }
406 else if (coordType == SurfacePoint::Latitudinal) {
407 std::vector<double> latDerivative = groundPoint.LatitudinalDerivative(SurfacePoint::One);
408 std::vector<double> lonDerivative = groundPoint.LatitudinalDerivative(SurfacePoint::Two);
409 std::vector<double> radDerivative = groundPoint.LatitudinalDerivative(SurfacePoint::Three);
410
411 // Line w.r.t (lat, lon, radius)
412 coeffPoint3D(1,0) = 1000 * (groundPartials[0]*latDerivative[0] + groundPartials[1]*latDerivative[1] + groundPartials[2]*latDerivative[2]);
413 coeffPoint3D(1,1) = 1000 * (groundPartials[0]*lonDerivative[0] + groundPartials[1]*lonDerivative[1] + groundPartials[2]*lonDerivative[2]);
414 coeffPoint3D(1,2) = 1000 * (groundPartials[0]*radDerivative[0] + groundPartials[1]*radDerivative[1] + groundPartials[2]*radDerivative[2]);
415
416 // Sample w.r.t (lat, lon, radius)
417 coeffPoint3D(0,0) = 1000 * (groundPartials[3]*latDerivative[0] + groundPartials[4]*latDerivative[1] + groundPartials[5]*latDerivative[2]);
418 coeffPoint3D(0,1) = 1000 * (groundPartials[3]*lonDerivative[0] + groundPartials[4]*lonDerivative[1] + groundPartials[5]*lonDerivative[2]);
419 coeffPoint3D(0,2) = 1000 * (groundPartials[3]*radDerivative[0] + groundPartials[4]*radDerivative[1] + groundPartials[5]*radDerivative[2]);
420 }
421 else {
422 IString msg ="Unknown surface point coordinate type enum [" + toString(coordType) + "]." ;
423 throw IException(IException::Programmer, msg, _FILEINFO_);
424 }
425 return true;
426 }
427
428
442 // Clear old values
443 coeffRHS.clear();
444
445 Camera *measureCamera = measure.camera();
446 BundleControlPoint* point = measure.parentControlPoint();
447
448 // Get ground-to-image computed coordinates for this point.
449 if (!(measureCamera->SetGround(point->adjustedSurfacePoint()))) {
450 QString msg = "Unable to map apriori surface point for measure ";
451 msg += measure.cubeSerialNumber() + " on point " + point->id() + " back into image.";
452 throw IException(IException::User, msg, _FILEINFO_);
453 }
454 double computedSample = measureCamera->Sample();
455 double computedLine = measureCamera->Line();
456
457 // The RHS is the difference between the measured coordinates on the image
458 // and the coordinates calculated by the ground to image call.
459 double deltaSample = measure.sample() - computedSample;
460 double deltaLine = measure.line() - computedLine;
461
462 coeffRHS(0) = deltaSample;
463 coeffRHS(1) = deltaLine;
464
465 return true;
466 }
467
468
482 return deltaVal;
483 }
484}
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.
A container class for a ControlMeasure.
double sample() const
Accesses the current sample measurement for this control measure.
double line() const
Accesses the current line measurement for this control measure.
QString cubeSerialNumber() const
Accesses the serial number of the cube containing this control measure.
BundleControlPoint * parentControlPoint()
Accesses the parent BundleControlPoint for this bundle measure.
Camera * camera() const
Accesses the associated camera for this bundle measure.
QString instrumentId()
Accesses the instrument id.
LinearAlgebra::Vector m_aprioriSigmas
A posteriori (adjusted) parameter sigmas.
LinearAlgebra::Vector m_adjustedSigmas
A posteriori (adjusted) parameter sigmas.
LinearAlgebra::Vector m_weights
Parameter weights. Cumulative parameter correction vector.
BundleObservation()
Constructs a BundleObservation initialized to a default state.
This class is used to modify and manage solve settings for 1 to many BundleObservations.
@ Set
Solve for all CSM parameters belonging to a specific set.
@ Type
Solve for all CSM parameters of a specific type.
@ List
Solve for an explicit list of CSM parameters.
std::vector< int > getParameterIndices(csm::param::Set paramSet) const
Get the indices of the parameters that belong to a set.
QString getParameterUnits(int index)
Get the units of the parameter at a particular index.
double getParameterCovariance(int index1, int index2)
Get the covariance between two parameters.
virtual std::vector< double > GroundPartials(SurfacePoint groundPoint)
Compute the partial derivatives of the sample, line with respect to the x, y, z coordinates of the gr...
double getParameterValue(int index)
Get the value of a parameter.
QString getParameterName(int index)
Get the name of the parameter.
void applyParameterCorrection(int index, double correction)
Adjust the value of a parameter.
virtual double Line() const
Returns the current line number.
Definition Camera.cpp:2740
virtual double Sample() const
Returns the current sample number.
Definition Camera.cpp:2720
virtual bool SetGround(Latitude latitude, Longitude longitude)
Sets the lat/lon values to get the sample/line values.
Definition Camera.cpp:403
bool computeRHSPartials(LinearAlgebra::Vector &coeffRHS, BundleMeasure &measure)
Calculates the sample, line residuals between the values measured in the image and the ground-to-imag...
CsmBundleObservation & operator=(const CsmBundleObservation &src)
Assignment operator.
int numberParameters()
Returns the number of total parameters there are for solving.
QString bundleOutputCSV(bool errorPropagation)
Creates and returns a formatted QString representing the bundle coefficients and parameters in csv fo...
bool computeTargetPartials(LinearAlgebra::Matrix &coeffTarget, BundleMeasure &measure, BundleSettingsQsp &bundleSettings, BundleTargetBodyQsp &bundleTargetBody)
Cannot compute target body parameters for a CSM observation, so always throws an exception.
bool computeImagePartials(LinearAlgebra::Matrix &coeffImage, BundleMeasure &measure)
Calculates the sensor partials with respect to the solve parameters and populates the coeffImage matr...
bool applyParameterCorrections(LinearAlgebra::Vector corrections)
Applies the parameter corrections.
const BundleObservationSolveSettingsQsp solveSettings()
Accesses the solve settings.
std::vector< int > m_paramIndices
The indices of the parameters the observation is solving for.
virtual QStringList parameterList()
Returns the list of observation parameter names.
void bundleOutputString(std::ostream &fpOut, bool errorPropagation)
Takes in an open std::ofstream and writes out information which goes into the bundleout....
bool computePoint3DPartials(LinearAlgebra::Matrix &coeffPoint3D, BundleMeasure &measure, SurfacePoint::CoordinateType coordType)
Calculates the ground partials for the line, sample currently set in the sensor model.
virtual bool setSolveSettings(BundleObservationSolveSettings solveSettings)
Set solve parameters.
CsmBundleObservation()
Constructs a CsmBundleObservation initialized to a default state.
double computeObservationValue(BundleMeasure &measure, double deltaVal)
Returns the observed value in (sample, line) coordinates.
BundleObservationSolveSettingsQsp m_solveSettings
Solve settings for this observation.
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Adds specific functionality to C++ strings.
Definition IString.h:165
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.
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.
std::vector< double > LatitudinalDerivative(CoordIndex index)
Compute partial derivative of the conversion of the latitudinal coordinates to body-fixed rectangular...
This is free and unencumbered software released into the public domain.
Definition Calculator.h:18
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
QSharedPointer< BundleSettings > BundleSettingsQsp
Definition for a BundleSettingsQsp, a shared pointer to a BundleSettings object.
QSharedPointer< BundleTargetBody > BundleTargetBodyQsp
Definition for BundleTargetBodyQsp, a QSharedPointer to a BundleTargetBody.
QSharedPointer< BundleObservationSolveSettings > BundleObservationSolveSettingsQsp
Definition for BundleObservationSolveSettingsQsp, a QSharedPointer to a BundleObservationSolveSetting...
bool IsSpecial(const double d)
Returns if the input pixel is special.
Namespace for the standard library.