Isis 3 Programmer Reference
SpicePosition.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "SpicePosition.h"
8 
9 #include <algorithm>
10 #include <cfloat>
11 #include <iomanip>
12 
13 #include <QString>
14 #include <QStringList>
15 #include <QChar>
16 
17 #include "BasisFunction.h"
18 #include "IException.h"
19 #include "LeastSquares.h"
20 #include "LineEquation.h"
21 #include "NaifStatus.h"
22 #include "NumericalApproximation.h"
23 #include "PolynomialUnivariate.h"
24 #include "TableField.h"
25 
26 using json = nlohmann::json;
27 
28 namespace Isis {
37  SpicePosition::SpicePosition(int targetCode, int observerCode) {
38  init(targetCode, observerCode, false);
39  }
40 
70  SpicePosition::SpicePosition(int targetCode, int observerCode,
71  bool swapObserverTarget) {
72  init(targetCode, observerCode, swapObserverTarget);
73  }
74 
87  void SpicePosition::init(int targetCode, int observerCode,
88  const bool &swapObserverTarget) {
89 
90  p_aberrationCorrection = "LT+S";
91  p_baseTime = 0.;
92  p_coefficients[0].clear();
93  p_coefficients[1].clear();
94  p_coefficients[2].clear();
95  p_coordinate.resize(3);
96  p_degree = 2;
97  p_degreeApplied = false;
98  p_et = -DBL_MAX;
100  p_fullCacheEndTime = 0;
101  p_fullCacheSize = 0;
102  p_hasVelocity = false;
103 
104  p_override = NoOverrides;
105  p_source = Spice;
106 
107  p_timeBias = 0.0;
108  p_timeScale = 1.;
109  p_velocity.resize(3);
110 
111 
112  m_swapObserverTarget = swapObserverTarget;
113  m_lt = 0.0;
114  m_state = NULL;
115 
116  // Determine observer/target ordering
117  if ( m_swapObserverTarget ) {
118  // New/improved settings.. Results in vector negation in SetEphemerisTimeSpice
119  p_targetCode = observerCode;
120  p_observerCode = targetCode;
121  }
122  else {
123  // Traditional settings
124  p_targetCode = targetCode;
125  p_observerCode = observerCode;
126  }
127  }
128 
129 
134  ClearCache();
135  }
136 
137 
150  void SpicePosition::SetTimeBias(double timeBias) {
151  p_timeBias = timeBias;
152  }
153 
161  double SpicePosition::GetTimeBias() const {
162  return (p_timeBias);
163  }
164 
186  void SpicePosition::SetAberrationCorrection(const QString &correction) {
187  QString abcorr(correction);
188  abcorr.remove(QChar(' '));
189  abcorr = abcorr.toUpper();
190  QStringList validAbcorr;
191  validAbcorr << "NONE" << "LT" << "LT+S" << "CN" << "CN+S"
192  << "XLT" << "XLT+S" << "XCN" << "XCN+S";
193 
194  if (validAbcorr.indexOf(abcorr) >= 0) {
195  p_aberrationCorrection = abcorr;
196  }
197  else {
198  QString msg = "Invalid abberation correction [" + correction + "]";
199  throw IException(IException::Programmer, msg, _FILEINFO_);
200  }
201  }
202 
214  return (p_aberrationCorrection);
215  }
216 
231  return (m_lt);
232  }
233 
249  const std::vector<double> &SpicePosition::SetEphemerisTime(double et) {
251 
252  // Save the time
253  if(et == p_et) {
254  return p_coordinate;
255  }
256 
257  p_et = et;
258 
259  // Read from the cache
260  if(p_source == Memcache) {
262  }
263  else if(p_source == HermiteCache) {
265  }
266  else if(p_source == PolyFunction) {
268  }
271  }
272  else { // Read from the kernel
274  }
275 
277 
278  // Return the coordinate
279  return p_coordinate;
280  }
281 
282 
297  void SpicePosition::LoadCache(double startTime, double endTime, int size) {
298  // Make sure cache isn't already loaded
299  if(p_source == Memcache || p_source == HermiteCache) {
300  QString msg = "A SpicePosition cache has already been created";
301  throw IException(IException::Programmer, msg, _FILEINFO_);
302  }
303 
304  if(startTime > endTime) {
305  QString msg = "Argument startTime must be less than or equal to endTime";
306  throw IException(IException::Programmer, msg, _FILEINFO_);
307  }
308 
309  if((startTime != endTime) && (size == 1)) {
310  QString msg = "Cache size must be more than 1 if startTime endTime differ";
311  throw IException(IException::Programmer, msg, _FILEINFO_);
312  }
313 
314  // Save full cache parameters
315  p_fullCacheStartTime = startTime;
316  p_fullCacheEndTime = endTime;
317  p_fullCacheSize = size;
318  LoadTimeCache();
319 
320  // Loop and load the cache
321  std::vector<ale::State> stateCache;
322  for(int i = 0; i < size; i++) {
323  double et = p_cacheTime[i];
324  SetEphemerisTime(et);
325  ale::State currentState = ale::State(ale::Vec3d(p_coordinate));
326  if (p_hasVelocity) {
327  currentState.velocity = ale::Vec3d(p_velocity);
328  }
329  stateCache.push_back(currentState);
330  }
331 
332  if (m_state != NULL) {
333  delete m_state;
334  }
335 
336  m_state = new ale::States(p_cacheTime, stateCache);
337  p_source = Memcache;
338  }
339 
340 
354  void SpicePosition::LoadCache(double time) {
355  LoadCache(time, time, 1);
356  }
357 
358 
368  void SpicePosition::LoadCache(json &isdPos) {
369  if (p_source != Spice) {
370  throw IException(IException::Programmer, "SpicePosition::LoadCache(json) only supports Spice source", _FILEINFO_);
371  }
372 
373  // Load the full cache time information from the label if available
374  p_fullCacheStartTime = isdPos["spk_table_start_time"].get<double>();
375  p_fullCacheEndTime = isdPos["spk_table_end_time"].get<double>();
376  p_fullCacheSize = isdPos["spk_table_original_size"].get<double>();
377  p_cacheTime = isdPos["ephemeris_times"].get<std::vector<double>>();
378 
379  p_hasVelocity = isdPos.find("velocities") != isdPos.end();
380 
381  std::vector<ale::State> stateCache;
382  if (p_hasVelocity) {
383  for (auto it = isdPos["positions"].begin(); it != isdPos["positions"].end(); it++) {
384  int index = it - isdPos["positions"].begin();
385  std::vector<double> pos = it->get<std::vector<double>>();
386  std::vector<double> vel = isdPos["velocities"][index];
387  stateCache.push_back(ale::State(ale::Vec3d(pos), ale::Vec3d(vel)));
388  }
389  }
390  else {
391  for (auto it = isdPos["positions"].begin(); it != isdPos["positions"].end(); it++) {
392  std::vector<double> pos = {it->at(0).get<double>(), it->at(1).get<double>(), it->at(2).get<double>()};
393  stateCache.push_back(ale::State(ale::Vec3d(pos)));
394  }
395  }
396 
397  if (m_state != NULL) {
398  delete m_state;
399  }
400 
401  m_state = new ale::States(p_cacheTime, stateCache);
402 
403  p_source = Memcache;
405  }
406 
430 
431  // Make sure cache isn't alread loaded
432  if(p_source == Memcache || p_source == HermiteCache) {
433  QString msg = "A SpicePosition cache has already been created";
434  throw IException(IException::Programmer, msg, _FILEINFO_);
435  }
436 
437  // Load the full cache time information from the label if available
438  if(table.Label().hasKeyword("SpkTableStartTime")) {
439  p_fullCacheStartTime = toDouble(table.Label().findKeyword("SpkTableStartTime")[0]);
440  }
441  if(table.Label().hasKeyword("SpkTableEndTime")) {
442  p_fullCacheEndTime = toDouble(table.Label().findKeyword("SpkTableEndTime")[0]);
443  }
444  if(table.Label().hasKeyword("SpkTableOriginalSize")) {
445  p_fullCacheSize = toDouble(table.Label().findKeyword("SpkTableOriginalSize")[0]);
446  }
447 
448 
449  // set source type by table's label keyword
450  if(!table.Label().hasKeyword("CacheType")) {
451  p_source = Memcache;
452  }
453  else if(table.Label().findKeyword("CacheType")[0] == "Linear") {
454  p_source = Memcache;
455  }
456  else if(table.Label().findKeyword("CacheType")[0] == "HermiteSpline") {
458  p_overrideTimeScale = 1.;
459  p_override = ScaleOnly;
460  }
461  else if(table.Label().findKeyword("CacheType")[0] == "PolyFunction") {
463  }
464  else {
466  "Invalid value for CacheType keyword in the table "
467  + table.Name(),
468  _FILEINFO_);
469  }
470 
471  std::vector<ale::State> stateCache;
472  // Loop through and move the table to the cache
473  if (p_source != PolyFunction) {
474  for (int r = 0; r < table.Records(); r++) {
475  TableRecord &rec = table[r];
476  if (rec.Fields() == 7) {
477  p_hasVelocity = true;
478  }
479  else if (rec.Fields() == 4) {
480  p_hasVelocity = false;
481  }
482  else {
483  QString msg = "Expecting four or seven fields in the SpicePosition table";
484  throw IException(IException::Programmer, msg, _FILEINFO_);
485  }
486 
487  ale::State currentState(ale::Vec3d((double)rec[0],
488  (double)rec[1],
489  (double)rec[2]));
490 
491  int inext = 3;
492 
493  if (p_hasVelocity) {
494  currentState.velocity = ale::Vec3d((double)rec[3],
495  (double)rec[4],
496  (double)rec[5]);
497  inext = 6;
498  }
499  stateCache.push_back(currentState);
500  p_cacheTime.push_back((double)rec[inext]);
501  }
502 
503  if (m_state != NULL) {
504  delete m_state;
505  }
506  m_state = new ale::States(p_cacheTime, stateCache);
507  }
508  else {
509  // Coefficient table for postion coordinates x, y, and z
510  std::vector<double> coeffX, coeffY, coeffZ;
511 
512  for (int r = 0; r < table.Records() - 1; r++) {
513  TableRecord &rec = table[r];
514 
515  if(rec.Fields() != 3) {
516  // throw an error
517  }
518  coeffX.push_back((double)rec[0]);
519  coeffY.push_back((double)rec[1]);
520  coeffZ.push_back((double)rec[2]);
521  }
522  // Take care of function time parameters
523  TableRecord &rec = table[table.Records()-1];
524  double baseTime = (double)rec[0];
525  double timeScale = (double)rec[1];
526  double degree = (double)rec[2];
527  SetPolynomialDegree((int) degree);
528  SetOverrideBaseTime(baseTime, timeScale);
529  SetPolynomial(coeffX, coeffY, coeffZ);
530  if (degree > 0) p_hasVelocity = true;
531  if(degree == 0 && m_state->hasVelocity()) p_hasVelocity = true;
532  }
533  }
534 
535 
549  Table SpicePosition::Cache(const QString &tableName) {
551  LineCache(tableName);
552  // TODO Figure out how to get the tolerance -- for now hard code .01
553  Memcache2HermiteCache(0.01);
554  }
555 
556  // record to be added to table
557  TableRecord record;
558 
559  if (p_source != PolyFunction) {
560  // add x,y,z position labels to record
561  TableField x("J2000X", TableField::Double);
562  TableField y("J2000Y", TableField::Double);
563  TableField z("J2000Z", TableField::Double);
564  record += x;
565  record += y;
566  record += z;
567 
568  if (p_hasVelocity) {
569  // add x,y,z velocity labels to record
570  TableField vx("J2000XV", TableField::Double);
571  TableField vy("J2000YV", TableField::Double);
572  TableField vz("J2000ZV", TableField::Double);
573  record += vx;
574  record += vy;
575  record += vz;
576  }
577  // add time label to record
579  record += t;
580 
581  // create output table
582  Table table(tableName, record);
583 
584  int inext = 0;
585 
586  std::vector<ale::State> stateCache = m_state->getStates();
587  for (int i = 0; i < (int)stateCache.size(); i++) {
588  record[inext++] = stateCache[i].position.x; // record[0]
589  record[inext++] = stateCache[i].position.y; // record[1]
590  record[inext++] = stateCache[i].position.z; // record[2]
591  if (p_hasVelocity) {
592  record[inext++] = stateCache[i].velocity.x; // record[3]
593  record[inext++] = stateCache[i].velocity.y; // record[4]
594  record[inext++] = stateCache[i].velocity.z; // record[5]
595  }
596  record[inext] = p_cacheTime[i]; // record[6]
597  table += record;
598 
599  inext = 0;
600  }
601 
602  CacheLabel(table);
603  return table;
604  }
605 
606  else if(p_source == PolyFunction && p_degree == 0 && p_fullCacheSize == 1){
607  // Just load the position for the single epoch
608  return LineCache(tableName);
609  }
610  // Load the coefficients for the curves fit to the 3 camera angles
611  else if (p_source == PolyFunction) {
612  // PolyFunction case
613  TableField spacecraftX("J2000SVX", TableField::Double);
614  TableField spacecraftY("J2000SVY", TableField::Double);
615  TableField spacecraftZ("J2000SVZ", TableField::Double);
616 
617  TableRecord record;
618  record += spacecraftX;
619  record += spacecraftY;
620  record += spacecraftZ;
621 
622  Table table(tableName, record);
623 
624  for(int cindex = 0; cindex < p_degree + 1; cindex++) {
625  record[0] = p_coefficients[0][cindex];
626  record[1] = p_coefficients[1][cindex];
627  record[2] = p_coefficients[2][cindex];
628  table += record;
629  }
630 
631  // Load one more table entry with the time adjustments for the fit equation
632  // t = (et - baseTime)/ timeScale
633  record[0] = p_baseTime;
634  record[1] = p_timeScale;
635  record[2] = (double) p_degree;
636 
637  CacheLabel(table);
638  table += record;
639  return table;
640  }
641 
642  else {
644  "Cannot create Table, no Cache is loaded.",
645  _FILEINFO_);
646  }
647 
648  }
649 
650 
651 
659  // determine type of table to return
660  QString tabletype = "";
661 
662  if(p_source == Memcache) {
663  tabletype = "Linear";
664  }
665  else if(p_source == HermiteCache) {
666  tabletype = "HermiteSpline";
667  }
668  else {
669  tabletype = "PolyFunction";
670  }
671 
672  table.Label() += PvlKeyword("CacheType", tabletype);
673 
674  // Write original time coverage
675  if(p_fullCacheStartTime != 0) {
676  table.Label() += PvlKeyword("SpkTableStartTime");
677  table.Label()["SpkTableStartTime"].addValue(toString(p_fullCacheStartTime));
678  }
679  if(p_fullCacheEndTime != 0) {
680  table.Label() += PvlKeyword("SpkTableEndTime");
681  table.Label()["SpkTableEndTime"].addValue(toString(p_fullCacheEndTime));
682  }
683  if(p_fullCacheSize != 0) {
684  table.Label() += PvlKeyword("SpkTableOriginalSize");
685  table.Label()["SpkTableOriginalSize"].addValue(toString(p_fullCacheSize));
686  }
687  }
688 
689 
690 
704  Table SpicePosition::LineCache(const QString &tableName) {
705 
706  // Apply the function and fill the caches
708 
709  if(p_source != Memcache) {
710  QString msg = "Only cached positions can be returned as a line cache of positions and time";
711  throw IException(IException::Programmer, msg, _FILEINFO_);
712  }
713  // Load the table and return it to caller
714  return Cache(tableName);
715  }
716 
717 
718 
731 
732  // Save current et
733  double et = p_et;
734 
735  // Make sure source is a function
736  if(p_source < HermiteCache) {
737  QString msg = "The SpicePosition has not yet been fit to a function";
738  throw IException(IException::Programmer, msg, _FILEINFO_);
739  }
740 
741  // Clear existing positions from thecache
742  p_cacheTime.clear();
743 
744  // Load the time cache first
745  LoadTimeCache();
746 
747  if (p_fullCacheSize > 1) {
748  // Load the positions and velocity caches
749  p_et = -DBL_MAX; // Forces recalculation in SetEphemerisTime
750  std::vector<ale::State> stateCache;
751  for (std::vector<double>::size_type pos = 0; pos < p_cacheTime.size(); pos++) {
752  SetEphemerisTime(p_cacheTime.at(pos));
753  stateCache.push_back(ale::State(ale::Vec3d(p_coordinate), ale::Vec3d(p_velocity)));
754  }
755  if (m_state != NULL) {
756  delete m_state;
757  }
758  m_state = new ale::States(p_cacheTime, stateCache);
759  }
760  else {
761  // Load the position for the single updated time instance
762  p_et = p_cacheTime[0];
764  std::vector<ale::State> stateCache;
765  stateCache.push_back(ale::Vec3d(p_coordinate));
766  std::vector<double> timeCache;
767  timeCache.push_back(p_cacheTime[0]);
768  if (m_state != NULL) {
769  delete m_state;
770  }
771  m_state = new ale::States(timeCache, stateCache);
772  }
773 
774  // Set source to cache and reset current et
775  p_source = Memcache;
776  p_et = -DBL_MAX;
777  SetEphemerisTime(et);
778 
780  }
781 
782 
793  Table SpicePosition::LoadHermiteCache(const QString &tableName) {
794  // find the first and last time values
795  double firstTime = p_fullCacheStartTime;
796  double lastTime = p_fullCacheEndTime;
797  int cacheTimeSize = (int) p_fullCacheSize;
798 
799  // Framing cameras are already cached and don't need to be reduced.
800  if(cacheTimeSize == 1) return Cache(tableName);
801 
802  //If it's already a hermite cache, just return it.
803  if (p_source == HermiteCache) {
804  return Cache(tableName);
805  }
806 
807  // Make sure a polynomial function is already loaded
808  if(p_source != PolyFunction) {
809  QString msg = "A SpicePosition polynomial function has not been created yet";
810  throw IException(IException::Programmer, msg, _FILEINFO_);
811  }
812 
813  // Load the polynomial functions
817  function1.SetCoefficients(p_coefficients[0]);
818  function2.SetCoefficients(p_coefficients[1]);
819  function3.SetCoefficients(p_coefficients[2]);
820 
821  // Clear existing coordinates from cache
822  ClearCache();
823 
824  // Set velocity vector to true since it is calculated
825  p_hasVelocity = true;
826 
827  // Calculate new postition coordinates from polynomials fit to coordinates &
828  // fill cache
829 // std::cout << "Before" << std::endl;
830 // double savetime = p_cacheTime.at(0);
831 // SetEphemerisTime(savetime);
832 // std::cout << " at time " << savetime << std::endl;
833 // for (int i=0; i<3; i++) {
834 // std::cout << p_coordinate[i] << std::endl;
835 // }
836 
837 
838  // find time for the extremum of each polynomial
839  // since this is only a 2nd degree polynomial,
840  // finding these extrema is simple
841  double b1 = function1.Coefficient(1);
842  double c1 = function1.Coefficient(2);
843  double extremumXtime = -b1 / (2.*c1) + p_baseTime; // extremum is time value for root of 1st derivative
844  // make sure we are in the domain
845  if(extremumXtime < firstTime) {
846  extremumXtime = firstTime;
847  }
848  if(extremumXtime > lastTime) {
849  extremumXtime = lastTime;
850  }
851 
852  double b2 = function2.Coefficient(1);
853  double c2 = function2.Coefficient(2);
854  double extremumYtime = -b2 / (2.*c2) + p_baseTime;
855  // make sure we are in the domain
856  if(extremumYtime < firstTime) {
857  extremumYtime = firstTime;
858  }
859  if(extremumYtime > lastTime) {
860  extremumYtime = lastTime;
861  }
862 
863  double b3 = function3.Coefficient(1);
864  double c3 = function3.Coefficient(2);
865  double extremumZtime = -b3 / (2.*c3) + p_baseTime;
866  // make sure we are in the domain
867  if(extremumZtime < firstTime) {
868  extremumZtime = firstTime;
869  }
870  if(extremumZtime > lastTime) {
871  extremumZtime = lastTime;
872  }
873 
874  // refill the time vector
875  p_cacheTime.clear();
876  p_cacheTime.push_back(firstTime);
877  p_cacheTime.push_back(extremumXtime);
878  p_cacheTime.push_back(extremumYtime);
879  p_cacheTime.push_back(extremumZtime);
880  p_cacheTime.push_back(lastTime);
881  // we don't know order of extrema, so sort
882  sort(p_cacheTime.begin(), p_cacheTime.end());
883  // in case an extremum is an endpoint
884  std::vector <double>::iterator it = unique(p_cacheTime.begin(), p_cacheTime.end());
885  p_cacheTime.resize(it - p_cacheTime.begin());
886 
887  if(p_cacheTime.size() == 2) {
888  p_cacheTime.clear();
889  p_cacheTime.push_back(firstTime);
890  p_cacheTime.push_back((firstTime + lastTime) / 2);
891  p_cacheTime.push_back(lastTime);
892  }
893 
894  // add positions and velocities for these times
895  std::vector<ale::State> stateCache;
896  for(int i = 0; i < (int) p_cacheTime.size(); i++) {
897  // x,y,z positions
898  double time;
899  time = p_cacheTime[i] - p_baseTime;
900  p_coordinate[0] = function1.Evaluate(time);
901  p_coordinate[1] = function2.Evaluate(time);
902  p_coordinate[2] = function3.Evaluate(time);
903 
904  // x,y,z velocities
905  p_velocity[0] = b1 + 2 * c1 * (p_cacheTime[i] - p_baseTime);
906  p_velocity[1] = b2 + 2 * c2 * (p_cacheTime[i] - p_baseTime);
907  p_velocity[2] = b3 + 2 * c3 * (p_cacheTime[i] - p_baseTime);
908  stateCache.push_back(ale::State(p_coordinate, p_velocity));
909  }
910  if (m_state != NULL) {
911  delete m_state;
912  }
913  m_state = new ale::States(p_cacheTime, stateCache);
914 
916  double et = p_et;
917  p_et = -DBL_MAX;
918  SetEphemerisTime(et);
919 
920  return Cache(tableName);
921  }
922 
923 
931  std::vector<double> XC, YC, ZC;
932 
933  // Check to see if the position is already a Polynomial Function
934  if (p_source == PolyFunction)
935  return;
936 
937  // Adjust the degree of the polynomial to the available data
938  int size = m_state->getStates().size();
939  if (size == 1) {
940  p_degree = 0;
941  }
942  else if (size == 2) {
943  p_degree = 1;
944  }
945 
946  // Check for polynomial over Hermite constant and initialize coefficients
947  if (type == PolyFunctionOverHermiteConstant) {
948  XC.assign(p_degree + 1, 0.);
949  YC.assign(p_degree + 1, 0.);
950  ZC.assign(p_degree + 1, 0.);
951  SetPolynomial(XC, YC, ZC, type);
952  return;
953  }
954 
958 
959  // Compute the base time
960  ComputeBaseTime();
961  std::vector<double> time;
962 
963  if(size == 1) {
964  double t = p_cacheTime.at(0);
965  SetEphemerisTime(t);
966  XC.push_back(p_coordinate[0]);
967  YC.push_back(p_coordinate[1]);
968  ZC.push_back(p_coordinate[2]);
969  }
970  else if(size == 2) {
971  // Load the times and get the corresponding coordinates
972  double t1 = p_cacheTime.at(0);
973  SetEphemerisTime(t1);
974  std::vector<double> coord1 = p_coordinate;
975  t1 = (t1 - p_baseTime) / p_timeScale;
976  double t2 = p_cacheTime.at(1);
977  SetEphemerisTime(t2);
978  std::vector<double> coord2 = p_coordinate;
979  t2 = (t2 - p_baseTime) / p_timeScale;
980  double slope[3];
981  double intercept[3];
982 
983  // Compute the linear equation for each coordinate and save them
984  for(int cIndex = 0; cIndex < 3; cIndex++) {
985  Isis::LineEquation posline(t1, coord1[cIndex], t2, coord2[cIndex]);
986  slope[cIndex] = posline.Slope();
987  intercept[cIndex] = posline.Intercept();
988  }
989  XC.push_back(intercept[0]);
990  XC.push_back(slope[0]);
991  YC.push_back(intercept[1]);
992  YC.push_back(slope[1]);
993  ZC.push_back(intercept[2]);
994  ZC.push_back(slope[2]);
995  }
996  else {
997  LeastSquares *fitX = new LeastSquares(function1);
998  LeastSquares *fitY = new LeastSquares(function2);
999  LeastSquares *fitZ = new LeastSquares(function3);
1000 
1001  // Load the known values to compute the fit equation
1002  for(std::vector<double>::size_type pos = 0; pos < p_cacheTime.size(); pos++) {
1003  double t = p_cacheTime.at(pos);
1004  time.push_back( (t - p_baseTime) / p_timeScale);
1005  SetEphemerisTime(t);
1006  std::vector<double> coord = p_coordinate;
1007 
1008  fitX->AddKnown(time, coord[0]);
1009  fitY->AddKnown(time, coord[1]);
1010  fitZ->AddKnown(time, coord[2]);
1011  time.clear();
1012  }
1013  // Solve the equations for the coefficients
1014  fitX->Solve();
1015  fitY->Solve();
1016  fitZ->Solve();
1017 
1018  // Delete the least squares objects now that we have all the coefficients
1019  delete fitX;
1020  delete fitY;
1021  delete fitZ;
1022 
1023  // For now assume all three coordinates are fit to a polynomial function.
1024  // Later they may each be fit to a unique basis function.
1025  // Fill the coefficient vectors
1026 
1027  for(int i = 0; i < function1.Coefficients(); i++) {
1028  XC.push_back(function1.Coefficient(i));
1029  YC.push_back(function2.Coefficient(i));
1030  ZC.push_back(function3.Coefficient(i));
1031  }
1032 
1033  }
1034 
1035  // Now that the coefficients have been calculated set the polynomial with them
1036  SetPolynomial(XC, YC, ZC);
1037  return;
1038  }
1039 
1040 
1041 
1054  void SpicePosition::SetPolynomial(const std::vector<double>& XC,
1055  const std::vector<double>& YC,
1056  const std::vector<double>& ZC,
1057  const Source type) {
1058 
1062 
1063  // Load the functions with the coefficients
1064  function1.SetCoefficients(XC);
1065  function2.SetCoefficients(YC);
1066  function3.SetCoefficients(ZC);
1067 
1068  // Compute the base time
1069  ComputeBaseTime();
1070 
1071  // Save the current coefficients
1072  p_coefficients[0] = XC;
1073  p_coefficients[1] = YC;
1074  p_coefficients[2] = ZC;
1075 
1076  // Set the flag indicating p_degree has been applied to the spacecraft
1077  // positions and the coefficients of the polynomials have been saved.
1078  p_degreeApplied = true;
1079 
1080  // Reset the interpolation source
1081  p_source = type;
1082 
1083  // Update the current position
1084  double et = p_et;
1085  p_et = -DBL_MAX;
1086  SetEphemerisTime(et);
1087 
1088  return;
1089  }
1090 
1091 
1092 
1103  void SpicePosition::GetPolynomial(std::vector<double>& XC,
1104  std::vector<double>& YC,
1105  std::vector<double>& ZC) {
1106  XC = p_coefficients[0];
1107  YC = p_coefficients[1];
1108  ZC = p_coefficients[2];
1109 
1110  return;
1111  }
1112 
1113 
1114 
1117  if(p_override == NoOverrides) {
1118  p_baseTime = (p_cacheTime.at(0) + p_cacheTime.at(p_cacheTime.size() - 1)) / 2.;
1120  }
1121  else if (p_override == ScaleOnly) {
1122  p_baseTime = (p_cacheTime.at(0) + p_cacheTime.at(p_cacheTime.size() - 1)) / 2.;
1124  }
1125  else {
1128  }
1129 
1130  // Take care of case where 1st and last times are the same
1131  if(p_timeScale == 0) p_timeScale = 1.0;
1132  return;
1133  }
1134 
1135 
1147  void SpicePosition::SetOverrideBaseTime(double baseTime, double timeScale) {
1148  p_overrideBaseTime = baseTime;
1149  p_overrideTimeScale = timeScale;
1150  p_override = BaseAndScale;
1151  return;
1152  }
1153 
1154 
1155 
1168  SpicePosition::PartialType partialVar, int coeffIndex) {
1169  // Start with a zero vector since the derivative of the other coordinates
1170  // with respect to the partial var will be 0.
1171  std::vector<double> coordinate(3, 0);
1172 
1173  // Get the index of the coordinate to update with the partial derivative
1174  int coordIndex = partialVar;
1175 
1176 // if(coeffIndex > 2) {
1177 // QString msg = "SpicePosition only supports up to a 2nd order fit for the spacecraft position";
1178 // throw IException(IException::Programmer, msg, _FILEINFO_);
1179 // }
1180 //
1181  // Reset the coordinate to its derivative
1182  coordinate[coordIndex] = DPolynomial(coeffIndex);
1183  return coordinate;
1184  }
1185 
1186 
1187 
1208  std::vector<double> SpicePosition::VelocityPartial(
1209  SpicePosition::PartialType partialVar, int coeffIndex) {
1210  // Start with a zero vector since the derivative of the other coordinates with
1211  // respect to the partial var will be 0.
1212  std::vector<double> dvelocity(3, 0);
1213 
1214  // Get the index of the coordinate to update with the partial derivative
1215  int coordIndex = partialVar;
1216 
1217  double time = (p_et - p_baseTime) / p_timeScale;
1218  double derivative = 0.;
1219 
1220  // Handle arithmetic failures
1221  double Epsilon = 1.0e-15;
1222  if (fabs(time) <= Epsilon) time = 0.0;
1223 
1224  // Only compute for coefficient index > 0 to avoid problems like 0 ** -1
1225  if (coeffIndex > 0)
1226  derivative = coeffIndex * pow(time, coeffIndex-1) / p_timeScale;
1227 
1228  // Reset the velocity coordinate to its derivative
1229  dvelocity[coordIndex] = derivative;
1230  return dvelocity;
1231  }
1232 
1233 
1244  double SpicePosition::DPolynomial(const int coeffIndex) {
1245  double derivative = 1.;
1246  double time = (p_et - p_baseTime) / p_timeScale;
1247 
1248  if(coeffIndex > 0 && coeffIndex <= p_degree) {
1249  derivative = pow(time, coeffIndex);
1250  }
1251  else if(coeffIndex == 0) {
1252  derivative = 1;
1253  }
1254  else {
1255  QString msg = "Unable to evaluate the derivative of the SPICE position fit polynomial for "
1256  "the given coefficient index [" + toString(coeffIndex) + "]. "
1257  "Index is negative or exceeds degree of polynomial ["
1258  + toString(p_degree) + "]";
1259  throw IException(IException::Programmer, msg, _FILEINFO_);
1260  }
1261 
1262  return derivative;
1263  }
1264 
1269  const std::vector<double> &SpicePosition::Velocity() {
1270  if(p_hasVelocity) {
1271  return p_velocity;
1272  }
1273  else {
1274  QString msg = "No velocity vector available";
1275  throw IException(IException::Programmer, msg, _FILEINFO_);
1276  }
1277  }
1278 
1279 
1280 
1295  ale::State state;
1296  if (p_cacheTime.size() == 1) {
1297  state = m_state->getStates().front();
1298  }
1299  else {
1300  state = m_state->getState(p_et, ale::LINEAR);
1301  }
1302  p_coordinate[0] = state.position.x;
1303  p_coordinate[1] = state.position.y;
1304  p_coordinate[2] = state.position.z;
1305  if (p_hasVelocity){
1306  p_velocity[0] = state.velocity.x;
1307  p_velocity[1] = state.velocity.y;
1308  p_velocity[2] = state.velocity.z;
1309  }
1310  }
1311 
1312 
1325  if (p_hasVelocity) {
1326  ale::State state = m_state->getState(p_et, ale::SPLINE);
1327 
1328  p_coordinate[0] = state.position.x;
1329  p_coordinate[1] = state.position.y;
1330  p_coordinate[2] = state.position.z;
1331 
1332  p_velocity[0] = state.velocity.x;
1333  p_velocity[1] = state.velocity.y;
1334  p_velocity[2] = state.velocity.z;
1335  }
1336  else {
1337  throw IException(IException::Io, "No velocities available. Cannot calculate Hermite Cache.",
1338  _FILEINFO_);
1339  }
1340  }
1341 
1342 
1343 
1356  // Create the empty functions
1360 
1361  // Load the coefficients to define the functions
1362  functionX.SetCoefficients(p_coefficients[0]);
1363  functionY.SetCoefficients(p_coefficients[1]);
1364  functionZ.SetCoefficients(p_coefficients[2]);
1365 
1366  // Normalize the time
1367  double rtime;
1368  rtime = (p_et - p_baseTime) / p_timeScale;
1369 
1370  // Evaluate the polynomials at current et to get position;
1371  p_coordinate[0] = functionX.Evaluate(rtime);
1372  p_coordinate[1] = functionY.Evaluate(rtime);
1373  p_coordinate[2] = functionZ.Evaluate(rtime);
1374 
1375  if(p_hasVelocity) {
1376 
1377  if( p_degree == 0) {
1378  ale::Vec3d velocity = m_state->getVelocities()[0];
1379  p_velocity[0] = velocity.x;
1380  p_velocity[1] = velocity.y;
1381  p_velocity[2] = velocity.z;
1382  }
1383  else {
1384  p_velocity[0] = ComputeVelocityInTime(WRT_X);
1385  p_velocity[1] = ComputeVelocityInTime(WRT_Y);
1386  p_velocity[2] = ComputeVelocityInTime(WRT_Z);
1387  }
1388  }
1389  }
1390 
1391 
1405  std::vector<double> hermiteCoordinate = p_coordinate;
1406 
1407  std::vector<double> hermiteVelocity = p_velocity;
1409 
1410  for (int index = 0; index < 3; index++) {
1411  p_coordinate[index] += hermiteCoordinate[index];
1412  p_velocity[index] += hermiteVelocity[index];
1413  }
1414  }
1415 
1416 
1433 
1434  double state[6];
1435  bool hasVelocity;
1436  double lt;
1437 
1438  // NOTE: Prefer method getter access as some are virtualized and portray
1439  // the appropriate internal representation!!!
1441  "J2000", GetAberrationCorrection(), state, hasVelocity,
1442  lt);
1443 
1444  // Set the internal state
1445  setStateVector(state, hasVelocity);
1446  setLightTime(lt);
1447  return;
1448  }
1449 
1450 
1463  void SpicePosition::Memcache2HermiteCache(double tolerance) {
1464  if(p_source == HermiteCache) {
1465  return;
1466  }
1467  else if(p_source != Memcache) {
1469  "Source type is not Memcache, cannot convert.",
1470  _FILEINFO_);
1471  }
1472 
1473  ale::States *tempStates = new ale::States(m_state->minimizeCache(tolerance));
1474  delete m_state;
1475  m_state = tempStates;
1476  p_cacheTime = m_state->getTimes();
1478  }
1479 
1480 
1485  if (m_state) {
1486  delete m_state;
1487  m_state = NULL;
1488  }
1489 
1490  p_cacheTime.clear();
1491  }
1492 
1493 
1503  // Adjust the degree for the data
1504  if(p_fullCacheSize == 1) {
1505  degree = 0;
1506  }
1507  else if(p_fullCacheSize == 2) {
1508  degree = 1;
1509  }
1510  // If polynomials have not been applied yet simply set the degree and return
1511  if(!p_degreeApplied) {
1512  p_degree = degree;
1513  }
1514 
1515  // Otherwise the existing polynomials need to be either expanded ...
1516  else if(p_degree < degree) { // (increase the number of terms)
1517  std::vector<double> coefX(p_coefficients[0]),
1518  coefY(p_coefficients[1]),
1519  coefZ(p_coefficients[2]);
1520 
1521  for(int icoef = p_degree + 1; icoef <= degree; icoef++) {
1522  coefX.push_back(0.);
1523  coefY.push_back(0.);
1524  coefZ.push_back(0.);
1525  }
1526  p_degree = degree;
1527  SetPolynomial(coefX, coefY, coefZ);
1528  }
1529  // ... or reduced (decrease the number of terms)
1530  else if(p_degree > degree) {
1531  std::vector<double> coefX(degree + 1),
1532  coefY(degree + 1),
1533  coefZ(degree + 1);
1534 
1535  for(int icoef = 0; icoef <= degree; icoef++) {
1536  coefX.push_back(p_coefficients[0][icoef]);
1537  coefY.push_back(p_coefficients[1][icoef]);
1538  coefZ.push_back(p_coefficients[2][icoef]);
1539  }
1540  p_degree = degree;
1541  SetPolynomial(coefX, coefY, coefZ);
1542  }
1543  }
1544 
1545 
1546 
1559  p_source = Spice;
1560  ClearCache();
1561  LoadCache(table);
1562  }
1563 
1569  // Loop and load the time cache
1570  double cacheSlope = 0.0;
1571 
1572  if(p_fullCacheSize > 1)
1573  cacheSlope = (p_fullCacheEndTime - p_fullCacheStartTime) /
1574  (double)(p_fullCacheSize - 1);
1575 
1576  for(int i = 0; i < p_fullCacheSize; i++) {
1577  double et = p_fullCacheStartTime + (double) i * cacheSlope;
1578  p_cacheTime.push_back(et);
1579  }
1580 
1581  }
1582 
1586  const std::vector<double> &SpicePosition::GetCenterCoordinate() {
1587  // Compute the center time
1588  double etCenter = (p_fullCacheEndTime + p_fullCacheStartTime) / 2.;
1589  SetEphemerisTime(etCenter);
1590 
1591  return Coordinate();
1592  }
1593 
1594 
1603  double SpicePosition::ComputeVelocityInTime(PartialType var) {
1604  double velocity = 0.;
1605 
1606  for (int icoef=1; icoef <= p_degree; icoef++) {
1607  velocity += icoef*p_coefficients[var][icoef]*pow((p_et - p_baseTime), (icoef - 1))
1608  / pow(p_timeScale, icoef);
1609  }
1610 
1611  return velocity;
1612  }
1613 
1614 
1626  std::vector<double> SpicePosition::Extrapolate(double timeEt) {
1627  if (!p_hasVelocity) return p_coordinate;
1628 
1629  double diffTime = timeEt - p_et;
1630  std::vector<double> extrapPos(3, 0.);
1631  extrapPos[0] = p_coordinate[0] + diffTime*p_velocity[0];
1632  extrapPos[1] = p_coordinate[1] + diffTime*p_velocity[1];
1633  extrapPos[2] = p_coordinate[2] + diffTime*p_velocity[2];
1634 
1635  return extrapPos;
1636  }
1637 
1638 
1646  std::vector<double> SpicePosition::HermiteCoordinate() {
1649  "Hermite coordinates only available for PolyFunctionOverHermiteConstant",
1650  _FILEINFO_);
1651  }
1652 
1653  // Save the current coordinate so it can be reset
1654  std::vector<double> coordinate = p_coordinate;
1656  std::vector<double> hermiteCoordinate = p_coordinate;
1657  p_coordinate = coordinate;
1658  return hermiteCoordinate;
1659  }
1660 
1661  //=========================================================================
1662  // Observer/Target swap and light time correction methods
1663  //=========================================================================
1664 
1676  return (p_observerCode);
1677  }
1678 
1690  return (p_targetCode);
1691  }
1692 
1693 
1706  return (EphemerisTime() + GetTimeBias());
1707  }
1708 
1709 
1742  void SpicePosition::computeStateVector(double et, int target, int observer,
1743  const QString &refFrame,
1744  const QString &abcorr,
1745  double state[6], bool &hasVelocity,
1746  double &lightTime) const {
1747 
1748  // First try getting the entire state (including the velocity vector)
1750  hasVelocity = true;
1751  lightTime = 0.0;
1752  spkez_c((SpiceInt) target, (SpiceDouble) et, refFrame.toLatin1().data(),
1753  abcorr.toLatin1().data(), (SpiceInt) observer, state, &lightTime);
1754 
1755  // If Naif fails attempting to get the entire state, assume the velocity vector is
1756  // not available and just get the position. First turn off Naif error reporting and
1757  // return any error without printing them.
1758  SpiceBoolean spfailure = failed_c();
1759  reset_c(); // Reset Naif error system to allow caller to recover
1760  if ( spfailure ) {
1761  hasVelocity = false;
1762  lightTime = 0.0;
1763  spkezp_c((SpiceInt) target, (SpiceDouble) et, refFrame.toLatin1().data(),
1764  abcorr.toLatin1().data(), (SpiceInt) observer, state, &lightTime);
1765  }
1767  return;
1768  }
1769 
1794  void SpicePosition::setStateVector(const double state[6],
1795  const bool &hasVelocity) {
1796 
1797  p_coordinate[0] = state[0];
1798  p_coordinate[1] = state[1];
1799  p_coordinate[2] = state[2];
1800 
1801  if ( hasVelocity ) {
1802  p_velocity[0] = state[3];
1803  p_velocity[1] = state[4];
1804  p_velocity[2] = state[5];
1805  }
1806  else {
1807  p_velocity[0] = 0.0;
1808  p_velocity[1] = 0.0;
1809  p_velocity[2] = 0.0;
1810  }
1811  p_hasVelocity = hasVelocity;
1812 
1813  // Negate vectors if swap of observer target is requested so interface
1814  // remains consistent
1815  if (m_swapObserverTarget) {
1816  vminus_c(&p_velocity[0], &p_velocity[0]);
1817  vminus_c(&p_coordinate[0], &p_coordinate[0]);
1818  }
1819 
1820  return;
1821  }
1822 
1824  void SpicePosition::setLightTime(const double &lightTime) {
1825  m_lt = lightTime;
1826  return;
1827  }
1828 
1829  // /** Resets the source interpolation of the position.
1830  // *
1831  // * @param [in] source The interpolation to use for calculating position
1832  // *
1833  // */
1834  // void SetSource(Source source) {
1835  // p_source = source;
1836  // return;
1837  // }
1838 }
Isis::SpicePosition::p_degreeApplied
bool p_degreeApplied
Flag indicating whether or not a polynomial.
Definition: SpicePosition.h:337
Isis::SpicePosition::HermiteCache
@ HermiteCache
Object is reading from splined table.
Definition: SpicePosition.h:182
Isis::SpicePosition::GetPolynomial
void GetPolynomial(std::vector< double > &XC, std::vector< double > &YC, std::vector< double > &ZC)
Return the coefficients of a polynomial fit to each of the three coordinates of the position for the ...
Definition: SpicePosition.cpp:1103
Isis::SpicePosition::p_aberrationCorrection
QString p_aberrationCorrection
Light time correction to apply.
Definition: SpicePosition.h:325
Isis::SpicePosition::p_coordinate
std::vector< double > p_coordinate
J2000 position at time et.
Definition: SpicePosition.h:328
Isis::IException::Io
@ Io
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:155
Isis::SpicePosition::SetEphemerisTimePolyFunction
void SetEphemerisTimePolyFunction()
This is a protected method that is called by SetEphemerisTime() when Source type is PolyFunction.
Definition: SpicePosition.cpp:1355
Isis::LeastSquares::Solve
int Solve(Isis::LeastSquares::SolveMethod method=SVD)
After all the data has been registered through AddKnown, invoke this method to solve the system of eq...
Definition: LeastSquares.cpp:205
Isis::SpicePosition::ClearCache
void ClearCache()
Removes the entire cache from memory.
Definition: SpicePosition.cpp:1484
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::SpicePosition::p_overrideBaseTime
double p_overrideBaseTime
Value set by caller to override computed base time.
Definition: SpicePosition.h:346
Isis::SpicePosition::p_targetCode
int p_targetCode
target body code
Definition: SpicePosition.h:321
Isis::SpicePosition::SetEphemerisTimeSpice
virtual void SetEphemerisTimeSpice()
This is a protected method that is called by SetEphemerisTime() when Source type is Spice.
Definition: SpicePosition.cpp:1432
Isis::SpicePosition::computeStateVector
void computeStateVector(double et, int target, int observer, const QString &refFrame, const QString &abcorr, double state[6], bool &hasVelocity, double &lightTime) const
Computes the state vector of the target w.r.t observer.
Definition: SpicePosition.cpp:1742
Isis::SpicePosition::GetAberrationCorrection
virtual QString GetAberrationCorrection() const
Returns current state of stellar aberration correction.
Definition: SpicePosition.cpp:213
Isis::LineEquation::Intercept
double Intercept()
Compute the intercept of the line.
Definition: LineEquation.cpp:87
Isis::SpicePosition::SetAberrationCorrection
virtual void SetAberrationCorrection(const QString &correction)
Set the aberration correction (light time)
Definition: SpicePosition.cpp:186
Isis::SpicePosition::SetPolynomial
void SetPolynomial(const Source type=PolyFunction)
Set the coefficients of a polynomial fit to each of the components (X, Y, Z) of the position vector f...
Definition: SpicePosition.cpp:930
Isis::SpicePosition::~SpicePosition
virtual ~SpicePosition()
Destructor.
Definition: SpicePosition.cpp:133
Isis::BasisFunction::SetCoefficients
void SetCoefficients(const std::vector< double > &coefs)
Set the coefficients for the equation.
Definition: BasisFunction.cpp:42
Isis::Table::Label
PvlObject & Label()
The Table's label.
Definition: Table.cpp:260
Isis::SpicePosition::HermiteCoordinate
std::vector< double > HermiteCoordinate()
This method returns the Hermite coordinate for the current time for PolyFunctionOverHermiteConstant f...
Definition: SpicePosition.cpp:1646
Isis::SpicePosition::CoordinatePartial
std::vector< double > CoordinatePartial(SpicePosition::PartialType partialVar, int coeffIndex)
Set the coefficients of a polynomial fit to each of the three coordinates of the position vector for ...
Definition: SpicePosition.cpp:1167
Isis::SpicePosition::p_velocity
std::vector< double > p_velocity
J2000 velocity at time et.
Definition: SpicePosition.h:329
Isis::SpicePosition::p_hasVelocity
bool p_hasVelocity
Flag to indicate velocity is available.
Definition: SpicePosition.h:344
Isis::SpicePosition::getAdjustedEphemerisTime
double getAdjustedEphemerisTime() const
Returns adjusted ephemeris time.
Definition: SpicePosition.cpp:1705
Isis::PolynomialUnivariate
Nth degree Polynomial with one variable.
Definition: PolynomialUnivariate.h:37
Isis::SpicePosition::Coordinate
const std::vector< double > & Coordinate()
Return the current J2000 position.
Definition: SpicePosition.h:211
Isis::TableRecord::Fields
int Fields() const
Returns the number of fields that are currently in the record.
Definition: TableRecord.cpp:78
Isis::SpicePosition::SetTimeBias
void SetTimeBias(double timeBias)
Apply a time bias when invoking SetEphemerisTime method.
Definition: SpicePosition.cpp:150
Isis::SpicePosition::getTargetCode
int getTargetCode() const
Returns target code.
Definition: SpicePosition.cpp:1689
Isis::SpicePosition::ComputeBaseTime
void ComputeBaseTime()
Compute the base time using cached times.
Definition: SpicePosition.cpp:1116
Isis::SpicePosition::GetTimeBias
double GetTimeBias() const
Returns the value of the time bias added to ET.
Definition: SpicePosition.cpp:161
Isis::LineEquation
Utility class for creating and using cartesean line equations.
Definition: LineEquation.h:29
Isis::SpicePosition::p_et
double p_et
Current ephemeris time.
Definition: SpicePosition.h:327
Isis::SpicePosition::setStateVector
void setStateVector(const double state[6], const bool &hasVelocity)
Sets the state of target relative to observer.
Definition: SpicePosition.cpp:1794
Isis::SpicePosition::SetEphemerisTimeMemcache
void SetEphemerisTimeMemcache()
This is a protected method that is called by SetEphemerisTime() when Source type is Memcache.
Definition: SpicePosition.cpp:1294
Isis::SpicePosition::SpicePosition
SpicePosition(int targetCode, int observerCode)
Construct an empty SpicePosition class using valid body codes.
Definition: SpicePosition.cpp:37
Isis::SpicePosition::p_timeBias
double p_timeBias
iTime bias when reading kernels
Definition: SpicePosition.h:324
Isis::NaifStatus::CheckErrors
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:28
Isis::SpicePosition::LineCache
Table LineCache(const QString &tableName)
Return a table with J2000 to reference positions.
Definition: SpicePosition.cpp:704
Isis::SpicePosition::SetEphemerisTime
const std::vector< double > & SetEphemerisTime(double et)
Return J2000 coordinate at given time.
Definition: SpicePosition.cpp:249
Isis::TableRecord
Definition: TableRecord.h:38
QStringList
Isis::SpicePosition::SetEphemerisTimePolyFunctionOverHermiteConstant
void SetEphemerisTimePolyFunctionOverHermiteConstant()
This is a protected method that is called by SetEphemerisTime() when Source type is PolyFunctionOverH...
Definition: SpicePosition.cpp:1403
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::SpicePosition::SetEphemerisTimeHermiteCache
void SetEphemerisTimeHermiteCache()
This is a protected method that is called by SetEphemerisTime() when Source type is HermiteCache.
Definition: SpicePosition.cpp:1324
Isis::SpicePosition::Spice
@ Spice
Object is reading directly from the kernels.
Definition: SpicePosition.h:180
Isis::SpicePosition::p_baseTime
double p_baseTime
Base time used in fit equations.
Definition: SpicePosition.h:335
Isis::SpicePosition::GetCenterCoordinate
const std::vector< double > & GetCenterCoordinate()
Compute and return the coordinate at the center time.
Definition: SpicePosition.cpp:1586
Isis::SpicePosition::p_source
Source p_source
Enumerated value for the location of the SPK information used.
Definition: SpicePosition.h:331
Isis::SpicePosition::PolyFunctionOverHermiteConstant
@ PolyFunctionOverHermiteConstant
Object is reading from splined.
Definition: SpicePosition.h:184
Isis::SpicePosition::getObserverCode
int getObserverCode() const
Returns observer code.
Definition: SpicePosition.cpp:1675
Isis::SpicePosition::p_degree
int p_degree
Degree of polynomial function fit to the coordinates of the position.
Definition: SpicePosition.h:340
Isis::SpicePosition::LoadHermiteCache
Table LoadHermiteCache(const QString &tableName)
Cache J2000 position over existing cached time range using polynomials stored as Hermite cubic spline...
Definition: SpicePosition.cpp:793
Isis::SpicePosition::p_overrideTimeScale
double p_overrideTimeScale
Value set by caller to override computed time scale.
Definition: SpicePosition.h:347
Isis::SpicePosition::PolyFunction
@ PolyFunction
Object is calculated from nth degree polynomial.
Definition: SpicePosition.h:183
Isis::SpicePosition::LoadCache
void LoadCache(double startTime, double endTime, int size)
Cache J2000 position over a time range.
Definition: SpicePosition.cpp:297
Isis::LeastSquares
Generic least square fitting class.
Definition: LeastSquares.h:99
Isis::SpicePosition::GetLightTime
double GetLightTime() const
Return the light time coorection value.
Definition: SpicePosition.cpp:230
Isis::SpicePosition::p_timeScale
double p_timeScale
Time scale used in fit equations.
Definition: SpicePosition.h:336
Isis::PvlObject::hasKeyword
bool hasKeyword(const QString &kname, FindOptions opts) const
See if a keyword is in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within ...
Definition: PvlObject.cpp:236
Isis::TableField::Double
@ Double
The values in the field are 8 byte doubles.
Definition: TableField.h:54
Isis::Table
Class for storing Table blobs information.
Definition: Table.h:61
Isis::Table::Name
QString Name() const
The Table's name.
Definition: Table.cpp:247
Isis::SpicePosition::p_observerCode
int p_observerCode
observer body code
Definition: SpicePosition.h:322
Isis::SpicePosition::Source
Source
This enum indicates the status of the object.
Definition: SpicePosition.h:180
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::SpicePosition::setLightTime
void setLightTime(const double &lightTime)
Inheritors can set the light time if indicated.
Definition: SpicePosition.cpp:1824
Isis::Spice
Obtain SPICE information for a spacecraft.
Definition: Spice.h:283
Isis::SpicePosition::Extrapolate
std::vector< double > Extrapolate(double timeEt)
Extrapolate position for a given time assuming a constant velocity.
Definition: SpicePosition.cpp:1626
Isis::SpicePosition::EphemerisTime
double EphemerisTime() const
Return the current ephemeris time.
Definition: SpicePosition.h:204
Isis::SpicePosition::CacheLabel
void CacheLabel(Table &table)
Add labels to a SpicePosition table.
Definition: SpicePosition.cpp:658
Isis::SpicePosition::LoadTimeCache
void LoadTimeCache()
Load the time cache.
Definition: SpicePosition.cpp:1568
Isis::SpicePosition::Memcache2HermiteCache
void Memcache2HermiteCache(double tolerance)
This method reduces the cache for position, time and velocity to the minimum number of values needed ...
Definition: SpicePosition.cpp:1463
Isis::toDouble
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:149
Isis::IException::Programmer
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:146
Isis::SpicePosition::p_coefficients
std::vector< double > p_coefficients[3]
Coefficients of polynomials fit to 3 coordinates.
Definition: SpicePosition.h:333
Isis::SpicePosition::m_lt
double m_lt
!< Swap traditional order
Definition: SpicePosition.h:351
Isis::SpicePosition::p_fullCacheSize
double p_fullCacheSize
Orignial size of the complete cache after spiceinit.
Definition: SpicePosition.h:343
Isis::SpicePosition::p_fullCacheStartTime
double p_fullCacheStartTime
Original start time of the complete cache after spiceinit.
Definition: SpicePosition.h:341
Isis::SpicePosition::SetOverrideBaseTime
void SetOverrideBaseTime(double baseTime, double timeScale)
Set an override base time to be used with observations on scanners to allow all images in an observat...
Definition: SpicePosition.cpp:1147
Isis::SpicePosition::Velocity
const std::vector< double > & Velocity()
Return the current J2000 velocity.
Definition: SpicePosition.cpp:1269
Isis::SpicePosition::p_override
OverrideType p_override
Time base and scale override options;.
Definition: SpicePosition.h:345
Isis::SpicePosition::p_fullCacheEndTime
double p_fullCacheEndTime
Original end time of the complete cache after spiceinit.
Definition: SpicePosition.h:342
Isis::PvlObject::findKeyword
PvlKeyword & findKeyword(const QString &kname, FindOptions opts)
Finds a keyword in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within this...
Definition: PvlObject.cpp:177
Isis::LineEquation::Slope
double Slope()
Compute the slope of the line.
Definition: LineEquation.cpp:66
Isis::LeastSquares::AddKnown
void AddKnown(const std::vector< double > &input, double expected, double weight=1.0)
Invoke this method for each set of knowns.
Definition: LeastSquares.cpp:96
Isis::SpicePosition::Cache
Table Cache(const QString &tableName)
Return a table with J2000 positions.
Definition: SpicePosition.cpp:549
Isis::SpicePosition::Memcache
@ Memcache
Object is reading from cached table.
Definition: SpicePosition.h:181
Isis::SpicePosition::ComputeVelocityInTime
double ComputeVelocityInTime(PartialType var)
Compute the velocity with respect to time instead of scaled time.
Definition: SpicePosition.cpp:1603
Isis::Table::Records
int Records() const
Returns the number of records.
Definition: Table.cpp:313
Isis::SpicePosition::ReloadCache
void ReloadCache()
Cache J2000 positions over existing cached time range using polynomials.
Definition: SpicePosition.cpp:729
Isis::BasisFunction::Evaluate
double Evaluate(const std::vector< double > &vars)
Compute the equation using the input variables.
Definition: BasisFunction.cpp:64
Isis::SpicePosition::p_cacheTime
std::vector< double > p_cacheTime
iTime for corresponding position
Definition: SpicePosition.h:332
Isis::SpicePosition::DPolynomial
double DPolynomial(const int coeffIndex)
Evaluate the derivative of the fit polynomial (parabola) defined by the given coefficients with respe...
Definition: SpicePosition.cpp:1244
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::SpicePosition::m_state
ale::States * m_state
!< Light time correction
Definition: SpicePosition.h:353
Isis::BasisFunction::Coefficients
int Coefficients() const
Returns the number of coefficients for the equation.
Definition: BasisFunction.h:64
Isis::SpicePosition::init
void init(int targetCode, int observerCode, const bool &swapObserverTarget=false)
Internal initialization of the object support observer/target swap.
Definition: SpicePosition.cpp:87
Isis::BasisFunction::Coefficient
double Coefficient(int i) const
Returns the ith coefficient.
Definition: BasisFunction.h:107
Isis::SpicePosition::VelocityPartial
std::vector< double > VelocityPartial(SpicePosition::PartialType partialVar, int coeffIndex)
Compute the derivative of the velocity with respect to the specified variable.
Definition: SpicePosition.cpp:1208
Isis::TableField
Class for storing an Isis::Table's field information.
Definition: TableField.h:47
Isis::SpicePosition::SetPolynomialDegree
void SetPolynomialDegree(int degree)
Set the polynomial degree.
Definition: SpicePosition.cpp:1502