Isis 3 Programmer Reference
BundleTargetBody.cpp
1 #include "BundleTargetBody.h"
2 
3 #include <QDebug>
4 #include <QObject>
5 
6 #include "BundleSettings.h"
7 #include "IException.h"
8 #include "PvlGroup.h"
9 #include "PvlKeyword.h"
10 #include "PvlObject.h"
11 #include "Target.h"
12 
13 namespace Isis {
14 
20  m_parameterNamesList.clear();
21  m_parameterSolveCodes.clear();
22 
23  m_weights.clear();
24  m_corrections.clear();
25  m_solution.clear();
26  m_aprioriSigmas.clear();
27  m_adjustedSigmas.clear();
28 
29  m_radii.resize(3);
30  m_raPole.resize(3);
31  m_decPole.resize(3);
32  m_pm.resize(3);
33  }
34 
35 
43  m_parameterNamesList.clear();
44  //TODO This should probably be set to something based on the target. JAM
45  m_parameterSolveCodes.clear();
46 
47  m_weights.clear();
48  m_corrections.clear();
49  m_solution.clear();
50  m_aprioriSigmas.clear();
51  m_adjustedSigmas.clear();
52 
53  // initialize radii and coefficients from target
54  m_radii.resize(3);
55  m_radii[0] = target->radii().at(0);
56  m_radii[1] = target->radii().at(1);
57  m_radii[2] = target->radii().at(2);
58 
59  m_raPole.resize(3);
60  m_decPole.resize(3);
61  m_pm.resize(3);
62 
63  m_raPole = target->poleRaCoefs();
64  m_decPole = target->poleDecCoefs();
65  m_pm = target->pmCoefs();
66  }
67 
68 
76 
85 
86  m_radii = src.m_radii;
88 
89  m_raPole = src.m_raPole;
90  m_decPole = src.m_decPole;
91  m_pm = src.m_pm;
92 
94 
96 
97  m_weights = src.m_weights;
99  m_solution = src.m_solution;
102  }
103 
104 
109  }
110 
111 
118  if (this != &src) {
120 
129 
130  m_radii = src.m_radii;
132 
133  m_raPole = src.m_raPole;
134  m_decPole = src.m_decPole;
135  m_pm = src.m_pm;
136 
138 
140 
141  m_weights = src.m_weights;
143  m_solution = src.m_solution;
146  }
147 
148  return *this;
149  }
150 
151 
207  void BundleTargetBody::setSolveSettings(std::set<int> targetParameterSolveCodes,
208  Angle aprioriPoleRA, Angle sigmaPoleRA,
209  Angle aprioriVelocityPoleRA,
210  Angle sigmaVelocityPoleRA,
211  Angle aprioriPoleDec, Angle sigmaPoleDec,
212  Angle aprioriVelocityPoleDec,
213  Angle sigmaVelocityPoleDec,
214  Angle aprioriPM, Angle sigmaPM,
215  Angle aprioriVelocityPM,
216  Angle sigmaVelocityPM,
217  TargetRadiiSolveMethod solveRadiiMethod,
218  Distance aprioriRadiusA, Distance sigmaRadiusA,
219  Distance aprioriRadiusB, Distance sigmaRadiusB,
220  Distance aprioriRadiusC, Distance sigmaRadiusC,
221  Distance aprioriMeanRadius, Distance sigmaMeanRadius) {
222 
223  m_solveTargetBodyRadiusMethod = solveRadiiMethod;
224 
225  m_parameterSolveCodes = targetParameterSolveCodes;
226 
227  // size corrections and adjusted sigma vectors and set to zero
228  m_aprioriSigmas.resize(m_parameterSolveCodes.size());
229  m_aprioriSigmas.clear();
231  m_adjustedSigmas.clear();
232  m_weights.resize(m_parameterSolveCodes.size());
233  m_weights.clear();
234  m_corrections.resize(m_parameterSolveCodes.size());
235  m_corrections.clear();
236 
237 // ken testing
238  m_raPole[0] = aprioriPoleRA;
239  m_raPole[1] = aprioriVelocityPoleRA;
240  m_raPole[2] = Angle(0.0,Angle::Radians);
241  m_decPole[0] = aprioriPoleDec;
242  m_decPole[1] = aprioriVelocityPoleDec;
243  m_decPole[2] = Angle(0.0,Angle::Radians);
244  m_pm[0] = aprioriPM;
245  m_pm[1] = aprioriVelocityPM;
246  m_pm[2] = Angle(0.0,Angle::Radians);
247 // ken testing
248 
249 
250  int n = 0;
251  if (solvePoleRA()) {
252  m_parameterSolveCodes.insert(PoleRA);
253  m_raPole[0] = aprioriPoleRA;
254 
255  if (sigmaPoleRA.degrees() > 0.0) {
256  m_aprioriSigmas(n) = sigmaPoleRA.degrees();
257  m_weights(n) = 1.0/(sigmaPoleRA.radians()*sigmaPoleRA.radians());
258  }
259  else {
260  m_aprioriSigmas(n) = -1.0;
261  m_weights(n) = -1.0;
262  }
263  n++;
264  }
265 
266  if (solvePoleRAVelocity()) {
267  m_parameterSolveCodes.insert(VelocityPoleRA);
268  m_raPole[1] = aprioriVelocityPoleRA;
269 
270  if (sigmaVelocityPoleRA.degrees() > 0.0) {
271  m_aprioriSigmas(n) = sigmaVelocityPoleRA.degrees();
272  m_weights(n) = 1.0/(sigmaVelocityPoleRA.radians()*sigmaVelocityPoleRA.radians());
273  }
274  else {
275  m_aprioriSigmas(n) = -1.0;
276  m_weights(n) = -1.0;
277  }
278  n++;
279  }
280 // if (solvePoleRAAcceleration()) {
281 // m_parameterSolveCodes.insert(AccelerationPoleRA);
282 // m_raPole[2].setDegrees(aprioriAccelerationPoleRA);
283 // m_aprioriSigmas.insert_element(m_aprioriSigmas.size(), sigmaAccelerationPoleRA);
284 // }
285  if (solvePoleDec()) {
286  m_parameterSolveCodes.insert(PoleDec);
287  m_decPole[0] = aprioriPoleDec;
288 
289  if (sigmaPoleDec.degrees() > 0.0) {
290  m_aprioriSigmas(n) = sigmaPoleDec.degrees();
291  m_weights(n) = 1.0/(sigmaPoleDec.radians()*sigmaPoleDec.radians());
292  }
293  else {
294  m_aprioriSigmas(n) = -1.0;
295  m_weights(n) = -1.0;
296  }
297  n++;
298  }
299  if (solvePoleDecVelocity()) {
300  m_parameterSolveCodes.insert(VelocityPoleDec);
301  m_decPole[1] = aprioriVelocityPoleDec;
302 
303  if (sigmaVelocityPoleDec.degrees() > 0.0) {
304  m_aprioriSigmas(n) = sigmaVelocityPoleDec.degrees();
305  m_weights(n) = 1.0/(sigmaVelocityPoleDec.radians()*sigmaVelocityPoleDec.radians());
306  }
307  else {
308  m_aprioriSigmas(n) = -1.0;
309  m_weights(n) = -1.0;
310  }
311  n++;
312  }
313 
314 // bool solveAccelerationPoleDec = false;
315 // if (solvePoleDecAcceleration()) {
316 // m_parameterSolveCodes.insert(AccelerationPoleDec);
317 // }
318 
319  if (solvePM()) {
320  m_parameterSolveCodes.insert(PM);
321  m_pm[0] = aprioriPM;
322 
323  if (sigmaPM.degrees() > 0.0) {
324  m_aprioriSigmas(n) = sigmaPM.degrees();
325  m_weights(n) = 1.0/(sigmaPM.radians()*sigmaPM.radians());
326  }
327  else {
328  m_aprioriSigmas(n) = -1.0;
329  m_weights(n) = -1.0;
330  }
331  n++;
332  }
333 
334  if (solvePMVelocity()) { // programmer's note: also referred to as "spin rate"
335  m_parameterSolveCodes.insert(VelocityPM);
336  m_pm[1] = aprioriVelocityPM;
337 
338  if (sigmaVelocityPM.degrees() > 0.0) {
339  m_aprioriSigmas(n) = sigmaVelocityPM.degrees();
340  m_weights(n) = 1.0/(sigmaVelocityPM.radians()*sigmaVelocityPM.radians());
341  }
342  else {
343  m_aprioriSigmas(n) = -1.0;
344  m_weights(n) = -1.0;
345  }
346  n++;
347  }
348 
349 // bool solveAccelerationPM = false;
350 // if (solvePMAcceleration()) {
351 // m_parameterSolveCodes.insert(AccelerationPM);
352 // }
353 
355  m_parameterSolveCodes.insert(TriaxialRadiusA);
356  m_radii[0] = aprioriRadiusA;
357 
358  if (sigmaRadiusA.kilometers() > 0.0) {
359  m_aprioriSigmas(n) = sigmaRadiusA.kilometers();
360  m_weights(n) = 1.0/(sigmaRadiusA.kilometers()*sigmaRadiusA.kilometers());
361  }
362  else {
363  m_aprioriSigmas(n) = -1.0;
364  m_weights(n) = -1.0;
365  }
366  n++;
367 
368  m_parameterSolveCodes.insert(TriaxialRadiusB);
369  m_radii[1] = aprioriRadiusB;
370 
371  if (sigmaRadiusB.kilometers() > 0.0) {
372  m_aprioriSigmas(n) = sigmaRadiusB.kilometers();
373  m_weights(n) = 1.0/(sigmaRadiusB.kilometers()*sigmaRadiusB.kilometers());
374  }
375  else {
376  m_aprioriSigmas(n) = -1.0;
377  m_weights(n) = -1.0;
378  }
379  n++;
380 
381  m_parameterSolveCodes.insert(TriaxialRadiusC);
382  m_radii[2] = aprioriRadiusC;
383 
384  if (sigmaRadiusC.kilometers() > 0.0) {
385  m_aprioriSigmas(n) = sigmaRadiusC.kilometers();
386  m_weights(n) = 1.0/(sigmaRadiusC.kilometers()*sigmaRadiusC.kilometers());
387  }
388  else {
389  m_aprioriSigmas(n) = -1.0;
390  m_weights(n) = -1.0;
391  }
392  n++;
393  }
394 
395  else if (m_solveTargetBodyRadiusMethod == Mean) {
396  m_parameterSolveCodes.insert(MeanRadius);
397  m_meanRadius = aprioriMeanRadius;
398 
399  if (sigmaMeanRadius.kilometers() > 0.0) {
400  m_aprioriSigmas(n) = sigmaMeanRadius.kilometers();
401  m_weights(n) = 1.0/(sigmaMeanRadius.kilometers()*sigmaMeanRadius.kilometers());
402  }
403  else {
404  m_aprioriSigmas(n) = -1.0;
405  m_weights(n) = -1.0;
406  }
407  n++;
408  }
409 
410 // for (int i = 0; i < nParameters; i++) {
411 // std::cout << m_solution[i] << " " << m_aprioriSigmas[i] << " " << m_weights[i] << std::endl;
412 // }
413 // std::cout << "parameters: " << numberParameters() << std::endl;
414 // std::cout << " pole: " << numberPoleParameters() << std::endl;
415 // std::cout << " w0: " << numberW0Parameters() << std::endl;
416 // std::cout << " WDot: " << numberWDotParameters() << std::endl;
417 // std::cout << " Radius: " << numberRadiusParameters() << std::endl;
418 // int fred=1;
419  }
420 
421 
428  if (m_parameterSolveCodes.find(PoleRA) != m_parameterSolveCodes.end())
429  return true;
430  return false;
431  }
432 
433 
440  if (m_parameterSolveCodes.find(VelocityPoleRA) != m_parameterSolveCodes.end())
441  return true;
442  return false;
443  }
444 
445 
452  if (m_parameterSolveCodes.find(AccelerationPoleRA) != m_parameterSolveCodes.end())
453  return true;
454  return false;
455  }
456 
457 
464  if (m_parameterSolveCodes.find(PoleDec) != m_parameterSolveCodes.end())
465  return true;
466  return false;
467  }
468 
469 
476  if (m_parameterSolveCodes.find(VelocityPoleDec) != m_parameterSolveCodes.end())
477  return true;
478  return false;
479  }
480 
481 
488  if (m_parameterSolveCodes.find(AccelerationPoleDec) != m_parameterSolveCodes.end())
489  return true;
490  return false;
491  }
492 
493 
500  if (m_parameterSolveCodes.find(PM) != m_parameterSolveCodes.end())
501  return true;
502  return false;
503  }
504 
505 
512  if (m_parameterSolveCodes.find(VelocityPM) != m_parameterSolveCodes.end())
513  return true;
514  return false;
515  }
516 
517 
524  if (m_parameterSolveCodes.find(AccelerationPM) != m_parameterSolveCodes.end())
525  return true;
526  return false;
527  }
528 
529 
536  if (m_parameterSolveCodes.find(TriaxialRadiusA) != m_parameterSolveCodes.end() &&
537  m_parameterSolveCodes.find(TriaxialRadiusB) != m_parameterSolveCodes.end() &&
538  m_parameterSolveCodes.find(TriaxialRadiusC) != m_parameterSolveCodes.end())
539  return true;
540  return false;
541  }
542 
543 
550  if (m_parameterSolveCodes.find(MeanRadius) != m_parameterSolveCodes.end())
551  return true;
552  return false;
553  }
554 
555 
573  LinearAlgebra::Vector corrections) {
574  if (corrections.size() != m_parameterSolveCodes.size()) {
575  QString msg = "In BundleTargetBody::applyParameterCorrections: "
576  "correction and m_targetParameter vectors sizes don't match.\n";
578  }
579 
580 // for (int i = 0; i < corrections.size(); i++ )
581 // printf("%lf\n",corrections(i));
582 // std::cout << std::endl;
583 
584  try {
585  int n = 0;
586  for (std::set<int>::iterator it=m_parameterSolveCodes.begin();
587  it!=m_parameterSolveCodes.end(); ++it) {
588  switch (*it) {
589  case PoleRA:
590  m_raPole[0] += Angle(corrections[n], Angle::Radians);
591  break;
592  case VelocityPoleRA:
593  m_raPole[1] += Angle(corrections[n], Angle::Radians);
594  break;
595  case AccelerationPoleRA:
596  m_raPole[2] += Angle(corrections[n], Angle::Radians);
597  break;
598  case PoleDec:
599  m_decPole[0] += Angle(corrections[n], Angle::Radians);
600  break;
601  case VelocityPoleDec:
602  m_decPole[1] += Angle(corrections[n], Angle::Radians);
603  break;
604  case AccelerationPoleDec:
605  m_decPole[2] += Angle(corrections[n], Angle::Radians);
606  break;
607  case PM:
608  m_pm[0] += Angle(corrections[n], Angle::Radians);
609  break;
610  case VelocityPM:
611  m_pm[1] += Angle(corrections[n], Angle::Radians);
612  break;
613  case AccelerationPM:
614  m_pm[2] += Angle(corrections[n], Angle::Radians);
615  break;
616  case TriaxialRadiusA:
617  {
618  double c = m_radii[0].kilometers();
619  double d = c + corrections[n];
621 // m_radii[0] += Distance(corrections[n], Distance::Kilometers);
622  }
623  break;
624  case TriaxialRadiusB:
625  {
626  double c = m_radii[1].kilometers();
627  double d = c + corrections[n];
629 // m_radii[1] += Distance(corrections[n], Distance::Kilometers);
630  }
631  break;
632  case TriaxialRadiusC:
633  {
634  double c = m_radii[2].kilometers();
635  double d = c + corrections[n];
637 // m_radii[2] += Distance(corrections[n], Distance::Kilometers);
638  }
639  break;
640  case MeanRadius:
641  {
642  double c = m_meanRadius.kilometers();
643  double d = c + corrections[n];
645 // m_meanRadius += Distance(corrections[n], Distance::Kilometers);
646  }
647  break;
648  default:
649  break;
650  } // end switch
651 
652  m_corrections[n] += corrections[n];
653  n++;
654  } // end loop over m_parameterSolveCodes
655  } // end try
656 
657  catch (IException &e) {
658  QString msg = "Unable to apply parameter corrections to BundleTargetBody.";
659  throw IException(e, IException::Unknown, msg, _FILEINFO_);
660  }
661  }
662 
663 
674  QString method) {
675  if (method.compare("NONE", Qt::CaseInsensitive) == 0) {
676  return None;
677  }
678  else if (method.compare("MEAN", Qt::CaseInsensitive) == 0) {
679  return Mean;
680  }
681  else if (method.compare("ALL", Qt::CaseInsensitive) == 0) {
682  return All;
683  }
684  else {
686  "Unknown target body radius solution method [" + method + "].",
687  _FILEINFO_);
688  }
689  }
690 
691 
702  if (method == None)
703  return "None";
704  else if (method == Mean)
705  return "MeanRadius";
706  else if (method == All)
707  return "Radii";
709  "Unknown target body radius solve method enum [" + toString(method) + "].",
710  _FILEINFO_);
711  }
712 
713 
723  return m_weights;
724  }
725 
726 
736  return m_corrections;
737  }
738 
739 
749  return m_solution;
750  }
751 
752 
762  return m_aprioriSigmas;
763  }
764 
765 
775  return m_adjustedSigmas;
776  }
777 
778 // int BundleTargetBody::numberPoleParameters() {
779 // int nPoleParameters = 0;
780 // if (m_solveTargetBodyRaPole)
781 // nPoleParameters++;
782 // if (m_solveTargetBodyDecPole)
783 // nPoleParameters++;
784 // return nPoleParameters;
785 // }
786 
787 
788 // int BundleTargetBody::numberW0Parameters() {
789 // if (m_solveTargetBodyZeroMeridian)
790 // return 1;
791 // return 0;
792 // }
793 
794 
795 // int BundleTargetBody::numberWDotParameters() {
796 // if (m_solveTargetBodyRotationRate)
797 // return 1;
798 // return 0;
799 // }
800 
801 
817  return 3;
819  return 1;
820  return 0;
821  }
822 
823 
830  return m_parameterSolveCodes.size();
831  }
832 
833 
847  std::vector<Angle> BundleTargetBody::poleRaCoefs() {
848  return m_raPole;
849  }
850 
851 
865  std::vector<Angle> BundleTargetBody::poleDecCoefs() {
866  return m_decPole;
867  }
868 
869 
883  std::vector<Angle> BundleTargetBody::pmCoefs() {
884  return m_pm;
885  }
886 
887 
898  std::vector<Distance> BundleTargetBody::radii() {
899  if (!solveTriaxialRadii()) {
900  QString msg = "The triaxial radii can only be accessed when solving for triaxial radii.";
902  }
903  return m_radii;
904  }
905 
906 
916  if (!solveMeanRadius()) {
917  QString msg = "The mean radius can only be accessed when solving for mean radius.";
919  }
920  return m_meanRadius;
921  }
922 
923 
936  double vtpv = 0.0;
937  double v;
938 
939  int nParameters = m_parameterSolveCodes.size();
940  for (int i = 0; i < nParameters; i++) {
941  v = m_corrections(i);
942 
943  if (m_weights(i) > 0.0)
944  vtpv += v * v * m_weights(i);
945  }
946 
947  return vtpv;
948  }
949 
950 
958  QString BundleTargetBody::formatBundleOutputString(bool errorPropagation) {
959 
960  // for convenience, create vectors of parameters names and values in the correct sequence
961  std::vector<double> finalParameterValues;
962  QStringList parameterNamesList;
963  QString str("%1");
964  int nAngleParameters = 0;
965  int nRadiusParameters = 0;
966  if (solvePoleRA()) {
967  finalParameterValues.push_back(m_raPole[0].degrees());
968  parameterNamesList.append( str.arg("POLE RA ") );
969  nAngleParameters++;
970  }
971  if (solvePoleRAVelocity()) {
972  finalParameterValues.push_back(m_raPole[1].degrees());
973  parameterNamesList.append( str.arg("POLE RAv ") );
974  nAngleParameters++;
975  }
976  if (solvePoleRAAcceleration()) {
977  finalParameterValues.push_back(m_raPole[2].degrees());
978  parameterNamesList.append( str.arg("POLE RAa ") );
979  nAngleParameters++;
980  }
981  if (solvePoleDec()) {
982  finalParameterValues.push_back(m_decPole[0].degrees());
983  parameterNamesList.append( str.arg("POLE DEC ") );
984  nAngleParameters++;
985  }
986  if (solvePoleDecVelocity()) {
987  finalParameterValues.push_back(m_decPole[1].degrees());
988  parameterNamesList.append( str.arg("POLE DECv ") );
989  nAngleParameters++;
990  }
991  if (solvePoleDecAcceleration()) {
992  finalParameterValues.push_back(m_decPole[2].degrees());
993  parameterNamesList.append( str.arg("POLE DECa ") );
994  nAngleParameters++;
995  }
996  if (solvePM()) {
997  finalParameterValues.push_back(m_pm[0].degrees());
998  parameterNamesList.append( str.arg(" PM ") );
999  nAngleParameters++;
1000  }
1001  if (solvePMVelocity()) {
1002  finalParameterValues.push_back(m_pm[1].degrees());
1003  parameterNamesList.append( str.arg(" PMv ") );
1004  nAngleParameters++;
1005  }
1006  if (solvePoleDecAcceleration()) {
1007  finalParameterValues.push_back(m_pm[2].degrees());
1008  parameterNamesList.append( str.arg(" PMa ") );
1009  nAngleParameters++;
1010  }
1011  if (solveTriaxialRadii()) {
1012  finalParameterValues.push_back(m_radii[0].kilometers());
1013  finalParameterValues.push_back(m_radii[1].kilometers());
1014  finalParameterValues.push_back(m_radii[2].kilometers());
1015  parameterNamesList.append( str.arg(" RadiusA ") );
1016  parameterNamesList.append( str.arg(" RadiusB ") );
1017  parameterNamesList.append( str.arg(" RadiusC ") );
1018  nRadiusParameters += 3;
1019  }
1020  if (solveMeanRadius()) {
1021  finalParameterValues.push_back(m_meanRadius.kilometers());
1022  parameterNamesList.append( str.arg("MeanRadius ") );
1023  nRadiusParameters++;
1024  }
1025 
1026  int nParameters = nAngleParameters + nRadiusParameters;
1027 
1028  m_parameterNamesList = parameterNamesList;
1029  QString finalqStr = "";
1030  QString qStr = "";
1031  QString sigma = "";
1032 
1033 // for (std::set<int>::iterator it=m_parameterSolveCodes.begin(); it!=m_parameterSolveCodes.end(); ++it) {
1034  for (int i = 0; i < nAngleParameters; i++) {
1035 
1036  if (m_aprioriSigmas[i] <= 0.0)
1037  sigma = "FREE";
1038  else
1039  sigma = toString(m_aprioriSigmas[i], 8);
1040 
1041  if (errorPropagation) {
1042  Angle corr_temp = Angle(m_corrections(i),Angle::Radians);
1043  qStr = QString("%1%2%3%4%5%6\n").
1044  arg( parameterNamesList.at(i) ).
1045  arg(finalParameterValues[i] - corr_temp.degrees(), 17, 'f', 8).
1046  arg(corr_temp.degrees(), 21, 'f', 8).
1047  arg(finalParameterValues[i], 20, 'f', 8).
1048  arg(sigma, 18).
1049  arg(m_adjustedSigmas[i], 18, 'f', 8);
1050  }
1051  else {
1052  Angle corr_temp = Angle(m_corrections(i),Angle::Radians);
1053  qStr = QString("%1%2%3%4%5%6\n").
1054  arg( parameterNamesList.at(i) ).
1055  arg(finalParameterValues[i] - corr_temp.degrees(), 17, 'f', 8).
1056  arg(corr_temp.degrees(), 21, 'f', 8).
1057  arg(finalParameterValues[i], 20, 'f', 8).
1058  arg(sigma, 18).
1059  arg("N/A", 18);
1060  }
1061  finalqStr += qStr;
1062  }
1063 
1064  for (int i = nAngleParameters; i < nParameters; i++) {
1065 
1066  if (m_aprioriSigmas[i] <= 0.0)
1067  sigma = "FREE";
1068  else
1069  sigma = toString(m_aprioriSigmas[i], 8);
1070 
1071  if (errorPropagation) {
1072  double d1 = finalParameterValues[i];
1073  double d2 = m_corrections(i);
1074  qStr = QString("%1%2%3%4%5%6\n").
1075  arg( parameterNamesList.at(i) ).
1076  arg(d1 - d2, 17, 'f', 8).
1077  arg(d2, 21, 'f', 8).
1078  arg(d1, 20, 'f', 8).
1079  arg(sigma, 18).
1080  arg(m_adjustedSigmas[i], 18, 'f', 8);
1081  }
1082  else {
1083  double d1 = finalParameterValues[i];
1084  double d2 = m_corrections(i);
1085  qStr = QString("%1%2%3%4%5%6\n").
1086  arg( parameterNamesList.at(i) ).
1087  arg(d1 - d2, 17, 'f', 8).
1088  arg(d2, 21, 'f', 8).
1089  arg(d1, 20, 'f', 8).
1090  arg(sigma, 18).
1091  arg("N/A", 18);
1092  }
1093  finalqStr += qStr;
1094  }
1095 
1096  return finalqStr;
1097  }
1098 
1099 
1109  return m_parameterNamesList;
1110  }
1111 
1112 
1173  // reset defaults
1174  //initialize();
1175 
1176  double d = -1.0;
1177  QString str;
1178  TargetRadiiSolveMethod solveRadiiMethod = None;
1179 
1180  //TODO Solve method keywords need to be checked for validity. JAM
1181 
1182  // determine which parameters we're solving for
1183  std::set<int> targetParameterSolveCodes;
1185  for (g = tbObject.beginGroup(); g != tbObject.endGroup(); ++g) {
1186  if (g->hasKeyword("Ra")) {
1187  try {
1188  str = g->findKeyword("Ra")[0];
1189  }
1190  catch (IException &e) {
1191  QString msg = "Ra must be given as none, position, velocity, or acceleration";
1192  throw IException(IException::User, msg, _FILEINFO_);
1193  }
1194  if (str == "position") {
1195  targetParameterSolveCodes.insert(BundleTargetBody::PoleRA);
1196  }
1197  else if (str == "velocity") {
1198  targetParameterSolveCodes.insert(BundleTargetBody::PoleRA);
1199  targetParameterSolveCodes.insert(BundleTargetBody::VelocityPoleRA);
1200  }
1201  else if (str == "acceleration") {
1202  targetParameterSolveCodes.insert(BundleTargetBody::PoleRA);
1203  targetParameterSolveCodes.insert(BundleTargetBody::VelocityPoleRA);
1204  targetParameterSolveCodes.insert(BundleTargetBody::AccelerationPoleRA);
1205  }
1206  }
1207 
1208  if (g->hasKeyword("Dec")) {
1209  try {
1210  str = g->findKeyword("Dec")[0];
1211  }
1212  catch (IException &e) {
1213  QString msg = "Dec must be given as none, position, velocity, or acceleration";
1214  throw IException(IException::User, msg, _FILEINFO_);
1215  }
1216  if (str == "position") {
1217  targetParameterSolveCodes.insert(BundleTargetBody::PoleDec);
1218  }
1219  else if (str == "velocity") {
1220  targetParameterSolveCodes.insert(BundleTargetBody::PoleDec);
1221  targetParameterSolveCodes.insert(BundleTargetBody::VelocityPoleDec);
1222  }
1223  else if (str == "acceleration") {
1224  targetParameterSolveCodes.insert(BundleTargetBody::PoleDec);
1225  targetParameterSolveCodes.insert(BundleTargetBody::VelocityPoleDec);
1226  targetParameterSolveCodes.insert(BundleTargetBody::AccelerationPoleDec);
1227  }
1228  }
1229 
1230  if (g->hasKeyword("Pm")) {
1231  try {
1232  str = g->findKeyword("Pm")[0];
1233  }
1234  catch (IException &e) {
1235  QString msg = "Pm must be given as none, position, velocity, or acceleration";
1236  throw IException(IException::User, msg, _FILEINFO_);
1237  }
1238  if (str == "position") {
1239  targetParameterSolveCodes.insert(BundleTargetBody::PM);
1240  }
1241  else if (str == "velocity") {
1242  targetParameterSolveCodes.insert(BundleTargetBody::PM);
1243  targetParameterSolveCodes.insert(BundleTargetBody::VelocityPM);
1244  }
1245  else if (str == "acceleration") {
1246  targetParameterSolveCodes.insert(BundleTargetBody::PM);
1247  targetParameterSolveCodes.insert(BundleTargetBody::VelocityPM);
1248  targetParameterSolveCodes.insert(BundleTargetBody::AccelerationPM);
1249  }
1250  }
1251 
1252  if (g->hasKeyword("RadiiSolveOption")) {
1253  try {
1254  str = g->findKeyword("RadiiSolveOption")[0];
1255  }
1256  catch (IException &e) {
1257  QString msg = "RadiiSolveOption must be given as none, triaxial, or mean";
1258  throw IException(IException::User, msg, _FILEINFO_);
1259  }
1260  if (str == "triaxial") {
1261  targetParameterSolveCodes.insert(BundleTargetBody::TriaxialRadiusA);
1262  targetParameterSolveCodes.insert(BundleTargetBody::TriaxialRadiusB);
1263  targetParameterSolveCodes.insert(BundleTargetBody::TriaxialRadiusC);
1264  solveRadiiMethod = All;
1265  }
1266  else if (str == "mean") {
1267  targetParameterSolveCodes.insert(BundleTargetBody::MeanRadius);
1268  solveRadiiMethod = Mean;
1269  }
1270  else
1271  solveRadiiMethod = None;
1272  }
1273  }
1274 
1275  Angle aprioriPoleRA;
1276  Angle poleRASigma;
1277  Angle aprioriVelocityPoleRA;
1278  Angle poleRAVelocitySigma;
1279  Angle aprioriAccelerationPoleRA;
1280  Angle poleRAAccelerationSigma;
1281  Angle aprioriPoleDec;
1282  Angle poleDecSigma;
1283  Angle aprioriVelocityPoleDec;
1284  Angle sigmaVelocityPoleDec;
1285  Angle aprioriAccelerationPoleDec;
1286  Angle sigmaAccelerationPoleDec;
1287  Angle aprioriPM;
1288  Angle sigmaPM;
1289  Angle aprioriVelocityPM;
1290  Angle sigmaVelocityPM;
1291  Angle aprioriAccelerationPM;
1292  Angle pmAccelerationSigma;
1293  Distance aprioriRadiusA;
1294  Distance sigmaRadiusA;
1295  Distance aprioriRadiusB;
1296  Distance sigmaRadiusB;
1297  Distance aprioriRadiusC;
1298  Distance sigmaRadiusC;
1299  Distance aprioriMeanRadius;
1300  Distance sigmaMeanRadius;
1301 
1302  //TODO Determine which need to be non-negative. JAM
1303 
1304  for (g = tbObject.beginGroup(); g != tbObject.endGroup(); ++g) {
1305  if (g->hasKeyword("RaValue")) {
1306  try {
1307  d = (double)(g->findKeyword("RaValue"));
1308  }
1309  catch (IException &e) {
1310  QString msg = "RaValue must be a valid double (>= 0; blank defaults to 0).";
1311  throw IException(IException::User, msg, _FILEINFO_);
1312  }
1313  aprioriPoleRA = Angle(d, Angle::Degrees);
1314  }
1315 
1316  if (g->hasKeyword("RaSigma")) {
1317  try {
1318  d = (double)(g->findKeyword("RaSigma"));
1319  }
1320  catch (IException &e) {
1321  QString msg = "RaSigma must be a valid double (>= 0; blank defaults to 0).";
1322  throw IException(IException::User, msg, _FILEINFO_);
1323  }
1324  poleRASigma = Angle(d, Angle::Degrees);
1325  }
1326 
1327  if (g->hasKeyword("RaVelocityValue")) {
1328  try {
1329  d = (double)(g->findKeyword("RaVelocityValue"));
1330  }
1331  catch (IException &e) {
1332  QString msg = "RaVelocityValue must be a valid double (>= 0; blank defaults to 0).";
1333  throw IException(IException::User, msg, _FILEINFO_);
1334  }
1335  aprioriVelocityPoleRA = Angle(d, Angle::Degrees);
1336  }
1337 
1338  if (g->hasKeyword("RaVelocitySigma")) {
1339  try {
1340  d = (double)(g->findKeyword("RaVelocitySigma"));
1341  }
1342  catch (IException &e) {
1343  QString msg = "RaVelocitySigma must be a valid double (>= 0; blank defaults to 0).";
1344  throw IException(IException::User, msg, _FILEINFO_);
1345  }
1346  poleRAVelocitySigma = Angle(d, Angle::Degrees);
1347  }
1348 
1349  if (g->hasKeyword("RaAccelerationValue")) {
1350  try {
1351  d = (double)(g->findKeyword("RaAccelerationValue"));
1352  }
1353  catch (IException &e) {
1354  QString msg = "RaAccelerationValue must be a valid double (>= 0; blank defaults to 0).";
1355  throw IException(IException::User, msg, _FILEINFO_);
1356  }
1357  aprioriAccelerationPoleRA = Angle(d, Angle::Degrees);
1358  }
1359 
1360  if (g->hasKeyword("RaAccelerationSigma")) {
1361  try {
1362  d = (double)(g->findKeyword("RaAccelerationSigma"));
1363  }
1364  catch (IException &e) {
1365  QString msg = "RaAccelerationSigma must be a valid double (>= 0; blank defaults to 0).";
1366  throw IException(IException::User, msg, _FILEINFO_);
1367  }
1368  poleRAAccelerationSigma = Angle(d, Angle::Degrees);
1369  }
1370 
1371  if (g->hasKeyword("DecValue")) {
1372  try {
1373  d = (double)(g->findKeyword("DecValue"));
1374  }
1375  catch (IException &e) {
1376  QString msg = "DecValue must be a valid double (>= 0; blank defaults to 0).";
1377  throw IException(IException::User, msg, _FILEINFO_);
1378  }
1379  aprioriPoleDec = Angle(d, Angle::Degrees);
1380  }
1381 
1382  if (g->hasKeyword("DecSigma")) {
1383  try {
1384  d = (double)(g->findKeyword("DecSigma"));
1385  }
1386  catch (IException &e) {
1387  QString msg = "DecSigma must be a valid double (>= 0; blank defaults to 0).";
1388  throw IException(IException::User, msg, _FILEINFO_);
1389  }
1390  poleDecSigma = Angle(d, Angle::Degrees);
1391  }
1392 
1393  if (g->hasKeyword("DecVelocityValue")) {
1394  try {
1395  d = (double)(g->findKeyword("DecVelocityValue"));
1396  }
1397  catch (IException &e) {
1398  QString msg = "DecVelocityValue must be a valid double (>= 0; blank defaults to 0).";
1399  throw IException(IException::User, msg, _FILEINFO_);
1400  }
1401  aprioriVelocityPoleDec = Angle(d, Angle::Degrees);
1402  }
1403 
1404  if (g->hasKeyword("DecVelocitySigma")) {
1405  try {
1406  d = (double)(g->findKeyword("DecVelocitySigma"));
1407  }
1408  catch (IException &e) {
1409  QString msg = "DecVelocitySigma must be a valid double (>= 0; blank defaults to 0).";
1410  throw IException(IException::User, msg, _FILEINFO_);
1411  }
1412  sigmaVelocityPoleDec = Angle(d, Angle::Degrees);
1413  }
1414 
1415  if (g->hasKeyword("DecAccelerationValue")) {
1416  try {
1417  d = (double)(g->findKeyword("DecAccelerationValue"));
1418  }
1419  catch (IException &e) {
1420  QString msg = "DecAccelerationValue must be a valid double (>= 0; blank defaults to 0).";
1421  throw IException(IException::User, msg, _FILEINFO_);
1422  }
1423  aprioriAccelerationPoleDec = Angle(d, Angle::Degrees);
1424  }
1425 
1426  if (g->hasKeyword("DecAccelerationSigma")) {
1427  try {
1428  d = (double)(g->findKeyword("DecAccelerationSigma"));
1429  }
1430  catch (IException &e) {
1431  QString msg = "DecAccelerationSigma must be a valid double (>= 0; blank defaults to 0).";
1432  throw IException(IException::User, msg, _FILEINFO_);
1433  }
1434  sigmaAccelerationPoleDec = Angle(d, Angle::Degrees);
1435  }
1436 
1437  if (g->hasKeyword("PmValue")) {
1438  try {
1439  d = (double)(g->findKeyword("PmValue"));
1440  }
1441  catch (IException &e) {
1442  QString msg = "PmValue must be a valid double (>= 0; blank defaults to 0).";
1443  throw IException(IException::User, msg, _FILEINFO_);
1444  }
1445  aprioriPM = Angle(d, Angle::Degrees);
1446  }
1447 
1448  if (g->hasKeyword("PmSigma")) {
1449  try {
1450  d = (double)(g->findKeyword("PmSigma"));
1451  }
1452  catch (IException &e) {
1453  QString msg = "PmSigma must be a valid double (>= 0; blank defaults to 0).";
1454  throw IException(IException::User, msg, _FILEINFO_);
1455  }
1456  sigmaPM = Angle(d, Angle::Degrees);
1457  }
1458 
1459 
1460  if (g->hasKeyword("PmVelocityValue")) {
1461  try {
1462  d = (double)(g->findKeyword("PmVelocityValue"));
1463  }
1464  catch (IException &e) {
1465  QString msg = "PmVelocityValue must be a valid double (>= 0; blank defaults to 0).";
1466  throw IException(IException::User, msg, _FILEINFO_);
1467  }
1468  aprioriVelocityPM = Angle(d, Angle::Degrees);
1469  }
1470 
1471  if (g->hasKeyword("PmVelocitySigma")) {
1472  try {
1473  d = (double)(g->findKeyword("PmVelocitySigma"));
1474  }
1475  catch (IException &e) {
1476  QString msg = "PmVelocitySigma must be a valid double (>= 0; blank defaults to 0).";
1477  throw IException(IException::User, msg, _FILEINFO_);
1478  }
1479  sigmaVelocityPM = Angle(d, Angle::Degrees);
1480  }
1481 
1482  if (g->hasKeyword("PmAccelerationValue")) {
1483  try {
1484  d = (double)(g->findKeyword("PmAccelerationValue"));
1485  }
1486  catch (IException &e) {
1487  QString msg = "PmAccelerationValue must be a valid double (>= 0; blank defaults to 0).";
1488  throw IException(IException::User, msg, _FILEINFO_);
1489  }
1490  aprioriAccelerationPM = Angle(d, Angle::Degrees);
1491  }
1492 
1493  if (g->hasKeyword("PmAccelerationSigma")) {
1494  try {
1495  d = (double)(g->findKeyword("PmAccelerationSigma"));
1496  }
1497  catch (IException &e) {
1498  QString msg = "PmAccelerationSigma must be a valid double (>= 0; blank defaults to 0).";
1499  throw IException(IException::User, msg, _FILEINFO_);
1500  }
1501  pmAccelerationSigma = Angle(d, Angle::Degrees);
1502  }
1503 
1504  if (g->hasKeyword("RadiusAValue")) {
1505  try {
1506  d = (double)(g->findKeyword("RadiusAValue"));
1507  }
1508  catch (IException &e) {
1509  QString msg = "RadiusAValue must be a valid double (blank defaults to 0).";
1510  throw IException(IException::User, msg, _FILEINFO_);
1511  }
1512  try {
1513  aprioriRadiusA = Distance(d, Distance::Meters);
1514  }
1515  catch (IException &e) {
1516  QString msg = "RadiusAValue must be >= 0.";
1517  throw IException(IException::User, msg, _FILEINFO_);
1518  }
1519  }
1520 
1521  if (g->hasKeyword("RadiusASigma")) {
1522  try {
1523  d = (double)(g->findKeyword("RadiusASigma"));
1524  }
1525  catch (IException &e) {
1526  QString msg = "RadiusASigma must be a valid double (blank defaults to 0).";
1527  throw IException(IException::User, msg, _FILEINFO_);
1528  }
1529  try {
1530  sigmaRadiusA = Distance(d, Distance::Meters);
1531  }
1532  catch (IException &e) {
1533  QString msg = "RadiusASigma must be >= 0.";
1534  throw IException(IException::User, msg, _FILEINFO_);
1535  }
1536  }
1537 
1538  if (g->hasKeyword("RadiusBValue")) {
1539  try {
1540  d = (double)(g->findKeyword("RadiusBValue"));
1541  }
1542  catch (IException &e) {
1543  QString msg = "RadiusBValue must be a valid double (blank defaults to 0).";
1544  throw IException(IException::User, msg, _FILEINFO_);
1545  }
1546  try {
1547  aprioriRadiusB = Distance(d, Distance::Meters);
1548  }
1549  catch (IException &e) {
1550  QString msg = "RadiusBValue must be >= 0.";
1551  throw IException(IException::User, msg, _FILEINFO_);
1552  }
1553  }
1554 
1555  if (g->hasKeyword("RadiusBSigma")) {
1556  try {
1557  d = (double)(g->findKeyword("RadiusBSigma"));
1558  }
1559  catch (IException &e) {
1560  QString msg = "RadiusBSigma must be a valid double (blank defaults to 0).";
1561  throw IException(IException::User, msg, _FILEINFO_);
1562  }
1563  try {
1564  sigmaRadiusB = Distance(d, Distance::Meters);
1565  }
1566  catch (IException &e) {
1567  QString msg = "RadiusBSigma must be >= 0.";
1568  throw IException(IException::User, msg, _FILEINFO_);
1569  }
1570  }
1571 
1572  if (g->hasKeyword("RadiusCValue")) {
1573  try {
1574  d = (double)(g->findKeyword("RadiusCValue"));
1575  }
1576  catch (IException &e) {
1577  QString msg = "RadiusCValue must be a valid double (blank defaults to 0).";
1578  throw IException(IException::User, msg, _FILEINFO_);
1579  }
1580  try {
1581  aprioriRadiusC = Distance(d, Distance::Meters);
1582  }
1583  catch (IException &e) {
1584  QString msg = "RadiusCValue must be >= 0.";
1585  throw IException(IException::User, msg, _FILEINFO_);
1586  }
1587  }
1588 
1589  if (g->hasKeyword("RadiusCSigma")) {
1590  try {
1591  d = (double)(g->findKeyword("RadiusCSigma"));
1592  }
1593  catch (IException &e) {
1594  QString msg = "RadiusCSigma must be a valid double (blank defaults to 0).";
1595  throw IException(IException::User, msg, _FILEINFO_);
1596  }
1597  try {
1598  sigmaRadiusC = Distance(d, Distance::Meters);
1599  }
1600  catch (IException &e) {
1601  QString msg = "RadiusCSigma must be >= 0.";
1602  throw IException(IException::User, msg, _FILEINFO_);
1603  }
1604  }
1605 
1606  if (g->hasKeyword("MeanRadiusValue")) {
1607  try {
1608  d = (double)(g->findKeyword("MeanRadiusValue"));
1609  }
1610  catch (IException &e) {
1611  QString msg = "MeanRadiusValue must be a valid double (blank defaults to 0).";
1612  throw IException(IException::User, msg, _FILEINFO_);
1613  }
1614  try {
1615  aprioriMeanRadius = Distance(d, Distance::Meters);
1616  }
1617  catch (IException &e) {
1618  QString msg = "MeanRadiusValue must be >= 0.";
1619  throw IException(IException::User, msg, _FILEINFO_);
1620  }
1621  }
1622 
1623  if (g->hasKeyword("MeanRadiusSigma")) {
1624  try {
1625  d = (double)(g->findKeyword("MeanRadiusSigma"));
1626  }
1627  catch (IException &e) {
1628  QString msg = "MeanRadiusSigma must be a valid double (blank defaults to 0).";
1629  throw IException(IException::User, msg, _FILEINFO_);
1630  }
1631  try {
1632  sigmaMeanRadius = Distance(d, Distance::Meters);
1633  }
1634  catch (IException &e) {
1635  QString msg = "MeanRadiusSigma must be >= 0.";
1636  throw IException(IException::User, msg, _FILEINFO_);
1637  }
1638  }
1639  }
1640 
1641 /*
1642  try {
1643  // set target id
1644 // setInstrumentId((QString)tbParameterGroup.nameKeyword());
1645 
1646  }
1647  catch (IException &e) {
1648  QString msg = "Unable to set target body solve options from the given PVL.";
1649  throw IException(e, IException::User, msg, _FILEINFO_);
1650  }
1651 */
1652 
1653  setSolveSettings(targetParameterSolveCodes,
1654  aprioriPoleRA, poleRASigma,
1655  aprioriVelocityPoleRA, poleRAVelocitySigma,
1656  aprioriPoleDec, poleDecSigma,
1657  aprioriVelocityPoleDec, sigmaVelocityPoleDec,
1658  aprioriPM, sigmaPM,
1659  aprioriVelocityPM, sigmaVelocityPM,
1660  solveRadiiMethod,
1661  aprioriRadiusA, sigmaRadiusA,
1662  aprioriRadiusB, sigmaRadiusB,
1663  aprioriRadiusC, sigmaRadiusC,
1664  aprioriMeanRadius, sigmaMeanRadius);
1665 
1666  return true;
1667  }
1668 
1669 
1683 
1684  if (!solveTriaxialRadii()) {
1685  QString msg = "Local radius can only be found if triaxial radii were solved for.";
1687  }
1688 
1689  double a = m_radii[0].kilometers();
1690  double b = m_radii[1].kilometers();
1691  double c = m_radii[2].kilometers();
1692 
1693  double rlat = lat.radians();
1694  double rlon = lon.radians();
1695 
1696  double xyradius = a * b / sqrt(pow(b * cos(rlon), 2) +
1697  pow(a * sin(rlon), 2));
1698  const double &radius = xyradius * c / sqrt(pow(c * cos(rlat), 2) +
1699  pow(xyradius * sin(rlat), 2));
1700 
1701  return Distance(radius, Distance::Kilometers);
1702  }
1703 
1704 
1708 /*
1709  bool BundleTargetBody::readFromPvl(PvlGroup &tbParameterGroup) {
1710  // reset defaults
1711  //initialize();
1712 
1713  bool b = false;
1714  double d = -1.0;
1715 
1716  try {
1717  // set target id
1718 // setInstrumentId((QString)tbParameterGroup.nameKeyword());
1719 
1720  // pole right ascension settings
1721  if (tbParameterGroup.hasKeyword("Ra")) {
1722  try {
1723  b = toBool(tbParameterGroup.findKeyword("Ra")[0]);
1724  }
1725  catch (IException &e) {
1726  QString msg = "Ra must be a valid boolean (yes/no; true/false).";
1727  throw IException(IException::User, msg, _FILEINFO_);
1728  }
1729  if (b)
1730  m_parameterSolveCodes.insert(BundleTargetBody::PoleRA);
1731  }
1732 
1733  if (tbParameterGroup.hasKeyword("RaValue")) {
1734  try {
1735  d = (double)(tbParameterGroup.findKeyword("RaValue"));
1736  }
1737  catch (IException &e) {
1738  QString msg = "RaValue must be a valid double (>= 0; blank defaults to 0).";
1739  throw IException(IException::User, msg, _FILEINFO_);
1740  }
1741  m_raPole[0] = Angle(d, Angle::Degrees);
1742  }
1743 
1744  if (tbParameterGroup.hasKeyword("RaSigma")) {
1745  try {
1746  d = (double)(tbParameterGroup.findKeyword("RaSigma"));
1747  }
1748  catch (IException &e) {
1749  QString msg = "RaSigma must be a valid double (>= 0; blank defaults to 0).";
1750  throw IException(IException::User, msg, _FILEINFO_);
1751  }
1752  //m_raPole[1] = Angle(d, Angle::Degrees);
1753  }
1754 
1755  if (tbParameterGroup.hasKeyword("RaVelocity")) {
1756  try {
1757  b = toBool(tbParameterGroup.findKeyword("RaVelocity")[0]);
1758  }
1759  catch (IException &e) {
1760  QString msg = "RaVelocity must be a valid boolean (yes/no; true/false).";
1761  throw IException(IException::User, msg, _FILEINFO_);
1762  }
1763  if (b)
1764  m_parameterSolveCodes.insert(BundleTargetBody::VelocityPoleRA);
1765  }
1766 
1767  if (tbParameterGroup.hasKeyword("RaVelocityValue")) {
1768  try {
1769  d = (double)(tbParameterGroup.findKeyword("RaVelocityValue"));
1770  }
1771  catch (IException &e) {
1772  QString msg = "RaVelocityValue must be a valid double (>= 0; blank defaults to 0).";
1773  throw IException(IException::User, msg, _FILEINFO_);
1774  }
1775  m_raPole[1] = Angle(d, Angle::Degrees);
1776  }
1777 
1778  if (tbParameterGroup.hasKeyword("RaVelocitySigma")) {
1779  try {
1780  d = (double)(tbParameterGroup.findKeyword("RaVelocitySigma"));
1781  }
1782  catch (IException &e) {
1783  QString msg = "RaVelocitySigma must be a valid double (>= 0; blank defaults to 0).";
1784  throw IException(IException::User, msg, _FILEINFO_);
1785  }
1786  //m_raPole[1] = Angle(d, Angle::Degrees);
1787  }
1788 
1789  if (tbParameterGroup.hasKeyword("RaAcceleration")) {
1790  try {
1791  b = toBool(tbParameterGroup.findKeyword("RaAcceleration")[0]);
1792  }
1793  catch (IException &e) {
1794  QString msg = "RaAcceleration must be a valid boolean (yes/no; true/false).";
1795  throw IException(IException::User, msg, _FILEINFO_);
1796  }
1797  if (b)
1798  m_parameterSolveCodes.insert(BundleTargetBody::VelocityPoleRA);
1799  }
1800 
1801  if (tbParameterGroup.hasKeyword("RaAccelerationValue")) {
1802  try {
1803  d = (double)(tbParameterGroup.findKeyword("RaAccelerationValue"));
1804  }
1805  catch (IException &e) {
1806  QString msg = "RaAccelerationValue must be a valid double (>= 0; blank defaults to 0).";
1807  throw IException(IException::User, msg, _FILEINFO_);
1808  }
1809  m_raPole[2] = Angle(d, Angle::Degrees);
1810  }
1811 
1812  if (tbParameterGroup.hasKeyword("RaAccelerationSigma")) {
1813  try {
1814  d = (double)(tbParameterGroup.findKeyword("RaAccelerationSigma"));
1815  }
1816  catch (IException &e) {
1817  QString msg = "RaAccelerationSigma must be a valid double (>= 0; blank defaults to 0).";
1818  throw IException(IException::User, msg, _FILEINFO_);
1819  }
1820  //m_raPole[1] = Angle(d, Angle::Degrees);
1821  }
1822 
1823  // pole declination settings
1824  if (tbParameterGroup.hasKeyword("Dec")) {
1825  try {
1826  b = toBool(tbParameterGroup.findKeyword("Dec")[0]);
1827  }
1828  catch (IException &e) {
1829  QString msg = "Dec parameter must be a valid boolean (yes/no; true/false).";
1830  throw IException(IException::User, msg, _FILEINFO_);
1831  }
1832  if (b)
1833  m_parameterSolveCodes.insert(BundleTargetBody::PoleDec);
1834  }
1835 
1836  if (tbParameterGroup.hasKeyword("DecValue")) {
1837  try {
1838  d = (double)(tbParameterGroup.findKeyword("DecValue"));
1839  }
1840  catch (IException &e) {
1841  QString msg = "DecValue must be a valid double (>= 0; blank defaults to 0).";
1842  throw IException(IException::User, msg, _FILEINFO_);
1843  }
1844  m_decPole[0] = Angle(d, Angle::Degrees);
1845  }
1846 
1847  if (tbParameterGroup.hasKeyword("DecSigma")) {
1848  try {
1849  d = (double)(tbParameterGroup.findKeyword("DecSigma"));
1850  }
1851  catch (IException &e) {
1852  QString msg = "DecSigma must be a valid double (>= 0; blank defaults to 0).";
1853  throw IException(IException::User, msg, _FILEINFO_);
1854  }
1855  //m_raPole[1] = Angle(d, Angle::Degrees);
1856  }
1857 
1858  if (tbParameterGroup.hasKeyword("DecVelocity")) {
1859  try {
1860  b = toBool(tbParameterGroup.findKeyword("DecVelocity")[0]);
1861  }
1862  catch (IException &e) {
1863  QString msg = "DecVelocity must be a valid boolean (yes/no; true/false).";
1864  throw IException(IException::User, msg, _FILEINFO_);
1865  }
1866  if (b)
1867  m_parameterSolveCodes.insert(BundleTargetBody::VelocityPoleDec);
1868  }
1869 
1870  if (tbParameterGroup.hasKeyword("DecVelocityValue")) {
1871  try {
1872  d = (double)(tbParameterGroup.findKeyword("DecVelocityValue"));
1873  }
1874  catch (IException &e) {
1875  QString msg = "DecVelocityValue must be a valid double (>= 0; blank defaults to 0).";
1876  throw IException(IException::User, msg, _FILEINFO_);
1877  }
1878  m_decPole[1] = Angle(d, Angle::Degrees);
1879  }
1880 
1881  if (tbParameterGroup.hasKeyword("DecVelocitySigma")) {
1882  try {
1883  d = (double)(tbParameterGroup.findKeyword("DecVelocitySigma"));
1884  }
1885  catch (IException &e) {
1886  QString msg = "DecVelocitySigma must be a valid double (>= 0; blank defaults to 0).";
1887  throw IException(IException::User, msg, _FILEINFO_);
1888  }
1889  //m_raPole[1] = Angle(d, Angle::Degrees);
1890  }
1891 
1892  if (tbParameterGroup.hasKeyword("DecAcceleration")) {
1893  try {
1894  b = toBool(tbParameterGroup.findKeyword("DecAcceleration")[0]);
1895  }
1896  catch (IException &e) {
1897  QString msg = "DecAcceleration must be a valid boolean (yes/no; true/false).";
1898  throw IException(IException::User, msg, _FILEINFO_);
1899  }
1900  if (b)
1901  m_parameterSolveCodes.insert(BundleTargetBody::AccelerationPoleDec);
1902  }
1903 
1904  if (tbParameterGroup.hasKeyword("DecAccelerationValue")) {
1905  try {
1906  d = (double)(tbParameterGroup.findKeyword("DecAccelerationValue"));
1907  }
1908  catch (IException &e) {
1909  QString msg = "DecAccelerationValue must be a valid double (>= 0; blank defaults to 0).";
1910  throw IException(IException::User, msg, _FILEINFO_);
1911  }
1912  m_decPole[2] = Angle(d, Angle::Degrees);
1913  }
1914 
1915  if (tbParameterGroup.hasKeyword("DecAccelerationSigma")) {
1916  try {
1917  d = (double)(tbParameterGroup.findKeyword("DecAccelerationSigma"));
1918  }
1919  catch (IException &e) {
1920  QString msg = "DecAccelerationSigma must be a valid double (>= 0; blank defaults to 0).";
1921  throw IException(IException::User, msg, _FILEINFO_);
1922  }
1923  //m_raPole[1] = Angle(d, Angle::Degrees);
1924  }
1925 
1926  // prime meridian settings
1927  if (tbParameterGroup.hasKeyword("Pm")) {
1928  try {
1929  b = toBool(tbParameterGroup.findKeyword("Pm")[0]);
1930  }
1931  catch (IException &e) {
1932  QString msg = "Pm parameter must be a valid boolean (yes/no; true/false).";
1933  throw IException(IException::User, msg, _FILEINFO_);
1934  }
1935  if (b)
1936  m_parameterSolveCodes.insert(BundleTargetBody::PM);
1937  }
1938 
1939  if (tbParameterGroup.hasKeyword("PmValue")) {
1940  try {
1941  d = (double)(tbParameterGroup.findKeyword("PmValue"));
1942  }
1943  catch (IException &e) {
1944  QString msg = "PmValue must be a valid double (>= 0; blank defaults to 0).";
1945  throw IException(IException::User, msg, _FILEINFO_);
1946  }
1947  m_pm[0] = Angle(d, Angle::Degrees);
1948  }
1949 
1950  if (tbParameterGroup.hasKeyword("PmSigma")) {
1951  try {
1952  d = (double)(tbParameterGroup.findKeyword("PmSigma"));
1953  }
1954  catch (IException &e) {
1955  QString msg = "PmSigma must be a valid double (>= 0; blank defaults to 0).";
1956  throw IException(IException::User, msg, _FILEINFO_);
1957  }
1958  //m_raPole[1] = Angle(d, Angle::Degrees);
1959  }
1960 
1961  if (tbParameterGroup.hasKeyword("PmVelocity")) {
1962  try {
1963  b = toBool(tbParameterGroup.findKeyword("PmVelocity")[0]);
1964  }
1965  catch (IException &e) {
1966  QString msg = "PmVelocity must be a valid boolean (yes/no; true/false).";
1967  throw IException(IException::User, msg, _FILEINFO_);
1968  }
1969  if (b)
1970  m_parameterSolveCodes.insert(BundleTargetBody::VelocityPM);
1971  }
1972 
1973  if (tbParameterGroup.hasKeyword("PmVelocityValue")) {
1974  try {
1975  d = (double)(tbParameterGroup.findKeyword("PmVelocityValue"));
1976  }
1977  catch (IException &e) {
1978  QString msg = "PmVelocityValue must be a valid double (>= 0; blank defaults to 0).";
1979  throw IException(IException::User, msg, _FILEINFO_);
1980  }
1981  m_pm[1] = Angle(d, Angle::Degrees);
1982  }
1983 
1984  if (tbParameterGroup.hasKeyword("PmVelocitySigma")) {
1985  try {
1986  d = (double)(tbParameterGroup.findKeyword("PmVelocitySigma"));
1987  }
1988  catch (IException &e) {
1989  QString msg = "PmVelocitySigma must be a valid double (>= 0; blank defaults to 0).";
1990  throw IException(IException::User, msg, _FILEINFO_);
1991  }
1992  //m_raPole[1] = Angle(d, Angle::Degrees);
1993  }
1994 
1995  if (tbParameterGroup.hasKeyword("PmAcceleration")) {
1996  try {
1997  b = toBool(tbParameterGroup.findKeyword("PmAcceleration")[0]);
1998  }
1999  catch (IException &e) {
2000  QString msg = "PmAcceleration must be a valid boolean (yes/no; true/false).";
2001  throw IException(IException::User, msg, _FILEINFO_);
2002  }
2003  if (b)
2004  m_parameterSolveCodes.insert(BundleTargetBody::AccelerationPM);
2005  }
2006 
2007  if (tbParameterGroup.hasKeyword("PmAccelerationValue")) {
2008  try {
2009  d = (double)(tbParameterGroup.findKeyword("PmAccelerationValue"));
2010  }
2011  catch (IException &e) {
2012  QString msg = "PmAccelerationValue must be a valid double (>= 0; blank defaults to 0).";
2013  throw IException(IException::User, msg, _FILEINFO_);
2014  }
2015  m_decPole[2] = Angle(d, Angle::Degrees);
2016  }
2017 
2018  if (tbParameterGroup.hasKeyword("PmAccelerationSigma")) {
2019  try {
2020  d = (double)(tbParameterGroup.findKeyword("PmAccelerationSigma"));
2021  }
2022  catch (IException &e) {
2023  QString msg = "PmAccelerationSigma must be a valid double (>= 0; blank defaults to 0).";
2024  throw IException(IException::User, msg, _FILEINFO_);
2025  }
2026  //m_raPole[1] = Angle(d, Angle::Degrees);
2027  }
2028 
2029  // radii settings
2030  if (tbParameterGroup.hasKeyword("AllRadii")) {
2031  try {
2032  b = toBool(tbParameterGroup.findKeyword("AllRadii")[0]);
2033  }
2034  catch (IException &e) {
2035  QString msg = "AllRadii parameter must be a valid boolean (yes/no; true/false).";
2036  throw IException(IException::User, msg, _FILEINFO_);
2037  }
2038  if (b) {
2039  m_parameterSolveCodes.insert(BundleTargetBody::TriaxialRadiusA);
2040  m_parameterSolveCodes.insert(BundleTargetBody::TriaxialRadiusB);
2041  m_parameterSolveCodes.insert(BundleTargetBody::TriaxialRadiusC);
2042 
2043  if (tbParameterGroup.hasKeyword("RadiusAValue")) {
2044  try {
2045  d = (double)(tbParameterGroup.findKeyword("RadiusAValue"));
2046  }
2047  catch (IException &e) {
2048  QString msg = "RadiusAValue must be a valid double (>= 0; blank defaults to 0).";
2049  throw IException(IException::User, msg, _FILEINFO_);
2050  }
2051  m_radii[0].setKilometers(d);
2052  }
2053 
2054  if (tbParameterGroup.hasKeyword("RadiusASigma")) {
2055  try {
2056  d = (double)(tbParameterGroup.findKeyword("RadiusASigma"));
2057  }
2058  catch (IException &e) {
2059  QString msg = "RadiusASigma must be a valid double (>= 0; blank defaults to 0).";
2060  throw IException(IException::User, msg, _FILEINFO_);
2061  }
2062  //m_raPole[1] = Angle(d, Angle::Degrees);
2063  }
2064 
2065  if (tbParameterGroup.hasKeyword("RadiusBValue")) {
2066  try {
2067  d = (double)(tbParameterGroup.findKeyword("RadiusBValue"));
2068  }
2069  catch (IException &e) {
2070  QString msg = "RadiusBValue must be a valid double (>= 0; blank defaults to 0).";
2071  throw IException(IException::User, msg, _FILEINFO_);
2072  }
2073  m_radii[1].setKilometers(d);
2074  }
2075 
2076  if (tbParameterGroup.hasKeyword("RadiusBSigma")) {
2077  try {
2078  d = (double)(tbParameterGroup.findKeyword("RadiusBSigma"));
2079  }
2080  catch (IException &e) {
2081  QString msg = "RadiusBSigma must be a valid double (>= 0; blank defaults to 0).";
2082  throw IException(IException::User, msg, _FILEINFO_);
2083  }
2084  //m_raPole[1] = Angle(d, Angle::Degrees);
2085  }
2086 
2087  if (tbParameterGroup.hasKeyword("RadiusCValue")) {
2088  try {
2089  d = (double)(tbParameterGroup.findKeyword("RadiusCValue"));
2090  }
2091  catch (IException &e) {
2092  QString msg = "RadiusCValue must be a valid double (>= 0; blank defaults to 0).";
2093  throw IException(IException::User, msg, _FILEINFO_);
2094  }
2095  m_radii[2].setKilometers(d);
2096  }
2097 
2098  if (tbParameterGroup.hasKeyword("RadiusCSigma")) {
2099  try {
2100  d = (double)(tbParameterGroup.findKeyword("RadiusCSigma"));
2101  }
2102  catch (IException &e) {
2103  QString msg = "RadiusCSigma must be a valid double (>= 0; blank defaults to 0).";
2104  throw IException(IException::User, msg, _FILEINFO_);
2105  }
2106  //m_raPole[1] = Angle(d, Angle::Degrees);
2107  }
2108  }
2109  }
2110  else if (tbParameterGroup.hasKeyword("MeanRadius")) {
2111  try {
2112  b = toBool(tbParameterGroup.findKeyword("MeanRadius")[0]);
2113  }
2114  catch (IException &e) {
2115  QString msg = "MeanRadius parameter must be a valid boolean (yes/no; true/false).";
2116  throw IException(IException::User, msg, _FILEINFO_);
2117  }
2118  if (b) {
2119  m_parameterSolveCodes.insert(BundleTargetBody::MeanRadius);
2120 
2121  if (tbParameterGroup.hasKeyword("MeanRadiusValue")) {
2122  try {
2123  d = (double)(tbParameterGroup.findKeyword("MeanRadiusValue"));
2124  }
2125  catch (IException &e) {
2126  QString msg = "MeanRadiusValue must be a valid double (>= 0; blank defaults to 0).";
2127  throw IException(IException::User, msg, _FILEINFO_);
2128  }
2129  m_radii[2].setKilometers(d);
2130  }
2131 
2132  if (tbParameterGroup.hasKeyword("MeanRadiusSigma")) {
2133  try {
2134  d = (double)(tbParameterGroup.findKeyword("MeanRadiusSigma"));
2135  }
2136  catch (IException &e) {
2137  QString msg = "MeanRadiusSigma must be a valid double (>= 0; blank defaults to 0).";
2138  throw IException(IException::User, msg, _FILEINFO_);
2139  }
2140  //m_raPole[1] = Angle(d, Angle::Degrees);
2141  }
2142  }
2143  }
2144  }
2145 
2146  catch (IException &e) {
2147  QString msg = "Unable to set target body solve options from the given PVL.";
2148  throw IException(e, IException::User, msg, _FILEINFO_);
2149  }
2150 
2151  return true;
2152  }
2153 */
2154 }
This class is used to represent a target body in a bundle and how to solve for it.
virtual bool solvePoleRAVelocity()
If the pole right ascension velocity will be solved for with this target body.
LinearAlgebra::Vector & aprioriSigmas()
Returns the vector of apriori parameters sigmas.
Distance m_aprioriRadiusC
Apriori Radius C.
Distance m_sigmaRadiusA
Apriori Radius A Sigma.
std::vector< Angle > m_decPole
pole dec quadratic polynomial coefficients
static QString targetRadiiOptionToString(TargetRadiiSolveMethod targetRadiiSolveMethod)
Converts a TargetRadiiSolveMethod to a QString.
Distance m_sigmaRadiusB
Apriori Radius B Sigma.
Distance m_aprioriRadiusB
Apriori Radius B.
Distance localRadius(const Latitude &lat, const Longitude &lon)
Gets the local radius for the given latitude/longitude coordinate.
QString formatBundleOutputString(bool errorPropagation)
Formats and returns the parameter values as a QString.
Distance m_aprioriMeanRadius
Apriori Mean Radius.
double radians() const
Convert an angle to a double.
Definition: Angle.h:243
PvlGroupIterator endGroup()
Returns the ending group index.
Definition: PvlObject.h:121
virtual bool solvePM()
If the prime meridian angle will be solved for with this target body.
Distance m_aprioriRadiusA
Apriori Radius A.
QStringList parameterList()
Returns a list of all the parameters being solved for as QStrings.
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:63
Distance meanRadius()
Returns the mean radius.
The distance is being specified in kilometers.
Definition: Distance.h:58
virtual bool solvePoleRA()
If the pole right ascension angle will be solved for with this target body.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
static TargetRadiiSolveMethod stringToTargetRadiiOption(QString option)
Converts a QString to a TargetRadiiSolveMethod.
Distance m_meanRadius
Adjusted mean radius value.
LinearAlgebra::Vector m_adjustedSigmas
Adjusted parameter sigmas.
bool readFromPvl(PvlObject &tbPvlObject)
Set bundle solve parameters for target body from a pvl file.
Solve for all radii.
int numberRadiusParameters()
Returns the number of radius parameters being solved for.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
LinearAlgebra::Vector m_corrections
Cumulative parameter corrections.
LinearAlgebra::Vector & parameterWeights()
Returns the vector of parameter weights.
virtual bool solvePoleDec()
If the pole declination angle will be solved for with this target body.
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:162
double kilometers() const
Get the distance in kilometers.
Definition: Distance.cpp:118
Distance measurement, usually in meters.
Definition: Distance.h:47
double degrees() const
Get the angle in units of Degrees.
Definition: Angle.h:249
std::vector< Angle > m_raPole
pole ra quadratic polynomial coefficients
LinearAlgebra::Vector & adjustedSigmas()
Returns the vector of adjusted parameters sigmas.
LinearAlgebra::Vector & parameterSolution()
Returns the vector of parameters solution.
Distance m_sigmaRadiusC
Apriori Radius C Sigma.
This class is designed to encapsulate the concept of a Longitude.
Definition: Longitude.h:52
void applyParameterCorrections(LinearAlgebra::Vector corrections)
Applies a vector of corrections to the parameters for the target body.
boost::numeric::ublas::vector< double > Vector
Definition for an Isis::LinearAlgebra::Vector of doubles.
std::vector< Distance > m_radii
Adjusted triaxial radii values.
std::vector< Angle > m_pm
pole pm quadratic polynomial coefficients
virtual bool solvePMVelocity()
If the prime meridian velocity will be solved for with this target body.
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:73
Distance m_sigmaMeanRadius
Apriori Mean Radius Sigma.
std::vector< Angle > pmCoefs()
Returns the coefficients of the prime meridian polynomial.
Solve for mean radius.
BundleTargetBody()
Creates an empty BundleTargetBody object.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
TargetRadiiSolveMethod
Enumeration that defines how to solve for target radii.
LinearAlgebra::Vector m_solution
Parameter solution vector.
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:134
virtual bool solvePoleRAAcceleration()
If the pole right ascension acceleration will be solved for with this target body.
BundleTargetBody & operator=(const BundleTargetBody &src)
Assignment operator.
void setSolveSettings(std::set< int > targetParameterSolveCodes, Angle aprioriPoleRA, Angle sigmaPoleRA, Angle aprioriVelocityPoleRA, Angle sigmaVelocityPoleRA, Angle aprioriPoleDec, Angle sigmaPoleDec, Angle aprioriVelocityPoleDec, Angle sigmaVelocityPoleDec, Angle aprioriPM, Angle sigmaPM, Angle aprioriVelocityPM, Angle sigmaVelocityPM, TargetRadiiSolveMethod solveRadiiMethod, Distance aprioriRadiusA, Distance sigmaRadiusA, Distance aprioriRadiusB, Distance sigmaRadiusB, Distance aprioriRadiusC, Distance sigmaRadiusC, Distance aprioriMeanRadius, Distance sigmaMeanRadius)
Sets the solve settings for the target body.
double vtpv()
Calculates and returns the weighted sum of the squares of the corrections.
This class is used to create and store valid Isis3 targets.
Definition: Target.h:76
QStringList m_parameterNamesList
List of all target parameters.
Defines an angle and provides unit conversions.
Definition: Angle.h:62
QList< Isis::PvlGroup >::iterator PvlGroupIterator
The counter for groups.
Definition: PvlObject.h:95
LinearAlgebra::Vector m_aprioriSigmas
A priori parameter sigmas.
virtual bool solvePMAcceleration()
If the prime meridian acceleration will be solved for with this target body.
TargetRadiiSolveMethod m_solveTargetBodyRadiusMethod
Which radii will be solved for.
Isis exception class.
Definition: IException.h:107
std::set< int > m_parameterSolveCodes
Target parameter solve codes.
virtual bool solvePoleDecVelocity()
If the pole declination velocity will be solved for with this target body.
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
virtual int numberParameters()
Returns the total number of parameters being solved for.
virtual bool solveMeanRadius()
If the mean radius will be solved for with this target body.
virtual bool solveTriaxialRadii()
If the triaxial radii will be solved for with this target body.
LinearAlgebra::Vector m_weights
Parameter weights.
The distance is being specified in meters.
Definition: Distance.h:56
virtual ~BundleTargetBody()
Destructor.
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
Definition: Angle.h:80
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:74
virtual bool solvePoleDecAcceleration()
If the pole declination acceleration will be solved for with this target body.
std::vector< Angle > poleRaCoefs()
Returns the coefficients of the right ascension polynomial.
LinearAlgebra::Vector & parameterCorrections()
Returns the vector of corrections applied to the parameters.
std::vector< Distance > radii()
Returns the radius values.
PvlGroupIterator beginGroup()
Returns the beginning group index.
Definition: PvlObject.h:103
std::vector< Distance > radii() const
Returns the radii of the body in km.
Definition: Target.cpp:522
std::vector< Angle > poleDecCoefs()
Returns the coefficients of the declination polynomial.