Commit de186899 authored by Jesse Mapel's avatar Jesse Mapel
Browse files

Improved documentation and testing for PiecewisePolynomial and Ephemeris plot too.

parent e5354458
Loading
Loading
Loading
Loading
+37 −12
Original line number Diff line number Diff line
@@ -171,27 +171,49 @@ namespace Isis {
   */
  void PiecewisePolynomial::refitPolynomials(int segments, int samples) {

    if (segments < 1) {
      QString msg = "Cannot refit polynomials over less than one segment.";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }

    // Generate sample data.
    std::vector<double> sampleValues;
    std::vector< std::vector<double> > sampleData;
    double firstSample = m_knots.front();
    double lastSample = m_knots.back();

    // If fitting over the zero polynomial, just take two samples
    // If the knots are set to -DBL_MAX and DBL_MAX, then convert to
    // values that we can do math with
    if (firstSample == -DBL_MAX) {
      firstSample = -100;
    }
    // If the knots are set to -DBL_MAX and DBL_MAX, then convert to
    // values that we can do math with
    if (lastSample == DBL_MAX) {
      lastSample = 100;
    }

    // If fitting over the zero polynomial, spread out the knots and
    // reinitialize the zero polynomials
    if ( isZero() ) {
      sampleValues.push_back(firstSample);
      sampleData.push_back(evaluate(firstSample));
      sampleValues.push_back(lastSample);
      sampleData.push_back(evaluate(lastSample));
      std::vector<double> zeroKnots;
      double knotRate = ( lastSample - firstSample ) / segments;
      for (int i = 0; i < segments + 1; i++) {
        zeroKnots.push_back(firstSample + knotRate * i);
      }
      setKnots(zeroKnots);
      return;
    }

    // Otherwise sample as normal
    else {
      double sampleRate = (lastSample - firstSample) / samples;
      for (int i = 0; i < samples; i++) {
        double currentValue = firstSample + sampleRate * i;
        sampleValues.push_back(currentValue);
        sampleData.push_back(evaluate(currentValue));
      }
    }

    // Fit over the sample data.
    try {
@@ -592,7 +614,8 @@ namespace Isis {
  void PiecewisePolynomial::computePolynomials(const std::vector<double> &values,
                                               const std::vector< std::vector<double> > &data) {

    /** Create the LeastSquares object to find the coefficients
    /** 
    Create the LeastSquares object to find the coefficients
    The coefficients are ordered based on the following:

    All of the coefficients for each segment are adjacent
@@ -847,8 +870,10 @@ namespace Isis {

    //Reinitialize the polynomials
    std::vector<PolynomialUnivariate> coordinateVector;
    PolynomialUnivariate zeroPoly(degree);
    zeroPoly.SetCoefficients( std::vector<double>(degree + 1, 0.0) );
    for (int i = 0; i < dimensions(); i++) {
      coordinateVector.push_back( PolynomialUnivariate(degree) );
      coordinateVector.push_back( zeroPoly );
    }
    m_polynomials.clear();
    for (int i = 0; i < segments(); i++) {
+285 −1
Original line number Diff line number Diff line
Unit test for PiecewisePolynomial

Test default constructor

Number of segments: 1
Space curve dimensions: 3
Polynomial degree: 0
Polynomial knots:
  -1.797693e+308
  1.797693e+308

Segment 1 polynomial:
Dimension 1 coefficients:
  0.0
Dimension 2 coefficients:
  0.0
Dimension 3 coefficients:
  0.0
Create 1D PiecewisePolynomial:

Number of segments: 1
@@ -173,6 +189,272 @@ Calculating residuals for 1 points.
  -5.0  0.0
RMS Error: 0.0

Test copy constructor
Number of segments: 1
Space curve dimensions: 3
Polynomial degree: 0
Polynomial knots:
  -1.797693e+308
  1.797693e+308

Segment 1 polynomial:
Dimension 1 coefficients:
  -2.5
Dimension 2 coefficients:
  -1.66667
Dimension 3 coefficients:
  3.0

Test assignment operator
Number of segments: 3
Space curve dimensions: 3
Polynomial degree: 2
Polynomial knots:
  -5.0
  -2.20163
  -0.143386
  3.0

Segment 1 polynomial:
Dimension 1 coefficients:
  0.326338
  -1.81105
  -0.474491
Dimension 2 coefficients:
  0.217688
  0.459387
  0.0170194
Dimension 3 coefficients:
  2.78236
  -0.126021
  -0.0170146

Segment 2 polynomial:
Dimension 1 coefficients:
  -0.143298
  -2.23768
  -0.571379
Dimension 2 coefficients:
  -0.0955277
  0.174856
  -0.0475988
Dimension 3 coefficients:
  3.09553
  0.158469
  0.0475944

Segment 3 polynomial:
Dimension 1 coefficients:
  -0.112189
  -1.80376
  0.941727
Dimension 2 coefficients:
  -0.074788
  0.46414
  0.961159
Dimension 3 coefficients:
  3.07479
  -0.130813
  -0.961156

Test derivatives
Derivatives at 0.0:
  -1.8037600276729
  0.4641399784535
  -0.130813441323

Test segment index accessor
Segment index for time -10.0: 0
Segment index for time -1.0: 1
Segment index for time 3.0: 2

Test refitting polynomials
Refit 3 segment, 3d polynomial to 5 segments.
Number of segments: 5
Space curve dimensions: 3
Polynomial degree: 2
Polynomial knots:
  -5.0
  -2.17857
  -1.83508
  -0.30547
  0.385805
  2.92

Segment 1 polynomial:
Dimension 1 coefficients:
  0.26892
  -1.84221
  -0.478559
Dimension 2 coefficients:
  0.179245
  0.438519
  0.0142943
Dimension 3 coefficients:
  2.82043
  -0.105368
  -0.0143185

Segment 2 polynomial:
Dimension 1 coefficients:
  0.317452
  -1.79766
  -0.468333
Dimension 2 coefficients:
  0.212113
  0.468693
  0.0212195
Dimension 3 coefficients:
  2.78921
  -0.13403
  -0.0208967

Segment 3 polynomial:
Dimension 1 coefficients:
  -0.229802
  -2.39409
  -0.630843
Dimension 2 coefficients:
  -0.153199
  0.0705491
  -0.0872622
Dimension 3 coefficients:
  3.15318
  0.262651
  0.0871864

Segment 4 polynomial:
Dimension 1 coefficients:
  -0.111414
  -1.61897
  0.637892
Dimension 2 coefficients:
  -0.0742696
  0.587325
  0.758609
Dimension 3 coefficients:
  3.07426
  -0.254033
  -0.758534

Segment 5 polynomial:
Dimension 1 coefficients:
  -0.0636046
  -1.86681
  0.959091
Dimension 2 coefficients:
  -0.0423979
  0.422103
  0.972735
Dimension 3 coefficients:
  3.04238
  -0.0887493
  -0.97274

Refit 3d zero polynomial to 3 segments.
Number of segments: 3
Space curve dimensions: 3
Polynomial degree: 0
Polynomial knots:
  -100.0
  -33.3333
  33.3333
  100.0

Segment 1 polynomial:
Dimension 1 coefficients:
  0.0
Dimension 2 coefficients:
  0.0
Dimension 3 coefficients:
  0.0

Segment 2 polynomial:
Dimension 1 coefficients:
  0.0
Dimension 2 coefficients:
  0.0
Dimension 3 coefficients:
  0.0

Segment 3 polynomial:
Dimension 1 coefficients:
  0.0
Dimension 2 coefficients:
  0.0
Dimension 3 coefficients:
  0.0

Test changing the polynomials degree
Number of segments: 3
Space curve dimensions: 3
Polynomial degree: 4
Polynomial knots:
  -100.0
  -33.3333
  33.3333
  100.0

Segment 1 polynomial:
Dimension 1 coefficients:
  0.0
  0.0
  0.0
  0.0
  0.0
Dimension 2 coefficients:
  0.0
  0.0
  0.0
  0.0
  0.0
Dimension 3 coefficients:
  0.0
  0.0
  0.0
  0.0
  0.0

Segment 2 polynomial:
Dimension 1 coefficients:
  0.0
  0.0
  0.0
  0.0
  0.0
Dimension 2 coefficients:
  0.0
  0.0
  0.0
  0.0
  0.0
Dimension 3 coefficients:
  0.0
  0.0
  0.0
  0.0
  0.0

Segment 3 polynomial:
Dimension 1 coefficients:
  0.0
  0.0
  0.0
  0.0
  0.0
Dimension 2 coefficients:
  0.0
  0.0
  0.0
  0.0
  0.0
Dimension 3 coefficients:
  0.0
  0.0
  0.0
  0.0
  0.0

Test error throws


@@ -181,7 +463,9 @@ Polynomial fit errors:
**PROGRAMMER ERROR** The number of data points [2] is insufficient to fit polynomials. at least [5] data points are required.
**PROGRAMMER ERROR** Input values are not sorted in ascending order.
**PROGRAMMER ERROR** Data point number [7] has the incorrect number of dimensions [2]. Expected [1] dimensions.
**PROGRAMMER ERROR** Cannot compute curvature. The triangle between points is degenerate.

Polynomial refitting errors:
**PROGRAMMER ERROR** Cannot refit polynomials over less than one segment.

Attempt to set to negative degree:
**PROGRAMMER ERROR** Input degree [-1] must be greater than or equal to 0.
+46 −0
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@ int main(int argc, char *argv[]) {

  cout << "Unit test for PiecewisePolynomial" << endl << endl;

  cout << "Test default constructor" << endl << endl;
  PiecewisePolynomial defaultPoly;
  outputPolynomial(defaultPoly);

  cout << "Create 1D PiecewisePolynomial:" << endl << endl;
  PiecewisePolynomial testPoly(-5, 5, 2, 1);
  outputPolynomial(testPoly);
@@ -69,6 +73,39 @@ int main(int argc, char *argv[]) {
  cout << endl;
  output3DResiduals(times3D, pointPoly);

  cout << endl << "Test copy constructor" << endl;
  PiecewisePolynomial copyPoly(pointPoly);
  outputPolynomial(copyPoly);

  cout << endl << "Test assignment operator" << endl;
  copyPoly = test3dPoly;
  outputPolynomial(copyPoly);

  cout << endl << "Test derivatives" << endl;
  std::vector<double> test3dDerivatives = test3dPoly.derivativeVariable(0.0);
  cout << "Derivatives at 0.0:" << endl;
  cout << "  " << toString(test3dDerivatives[0]) << endl;
  cout << "  " << toString(test3dDerivatives[1]) << endl;
  cout << "  " << toString(test3dDerivatives[2]) << endl;

  cout << endl << "Test segment index accessor" << endl;
  cout << "Segment index for time -10.0: " << toString(test3dPoly.segmentIndex(-10.0)) << endl;
  cout << "Segment index for time -1.0: " << toString(test3dPoly.segmentIndex(-1.0)) << endl;
  cout << "Segment index for time 3.0: " << toString(test3dPoly.segmentIndex(3.0)) << endl;

  cout << endl << "Test refitting polynomials" << endl;
  cout << "Refit 3 segment, 3d polynomial to 5 segments." << endl;
  copyPoly.refitPolynomials(5);
  outputPolynomial(copyPoly);

  cout << endl << "Refit 3d zero polynomial to 3 segments." << endl;
  defaultPoly.refitPolynomials(3);
  outputPolynomial(defaultPoly);

  cout << endl << "Test changing the polynomials degree" << endl;
  defaultPoly.setDegree(4);
  outputPolynomial(defaultPoly);

  cout << endl << "Test error throws" << endl << endl;

  cout << endl << "Polynomial fit errors:" << endl;
@@ -141,6 +178,15 @@ int main(int argc, char *argv[]) {
    e.print();
  }

  cout << endl << "Polynomial refitting errors:" << endl;

  try {
    copyPoly.refitPolynomials(-3);
  }
  catch(IException &e) {
    e.print();
  }

  cout << endl << "Attempt to set to negative degree:" << endl;
  try {
    testPoly.setDegree(-1);
+10 −14
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ namespace Isis {
  /**
   * Constructor creates a new EphemeridesPlotTool object.
   *
   * @param parent
   * @param parent The parent widget for the tool
   */
  EphemeridesPlotTool::EphemeridesPlotTool(QWidget *parent) : AbstractPlotTool(parent) {
    m_action = new QAction(this);
@@ -38,9 +38,8 @@ namespace Isis {

  /**
   * This method is called when the tool is activated by the
   *   parent, or when the plot mode is changed. It's used to
   *   activate or change the rubber banding mode to be either
   *   rectangle or line, depending on the current plot type.
   * parent. It enables the rubber band tool which is used to select the cube
   * to view data from.
   */
  void EphemeridesPlotTool::enableRubberBandTool() {
    rubberBandTool()->setDrawActiveViewportOnly(true);
@@ -48,11 +47,11 @@ namespace Isis {


  /**
   * This method adds the histogram tool to the tool pad.
   * This method adds the ephemerides tool to the tool pad.
   *
   * @param toolpad
   * @param toolpad The tool pad to add this tool to
   *
   * @return QAction*
   * @return QAction* The action that activates the tool
   */
  QAction *EphemeridesPlotTool::toolPadAction(ToolPad *toolpad) {
    QAction *action = new QAction(toolpad);
@@ -81,8 +80,9 @@ namespace Isis {


  /**
   * This method creates the default histogram plot window.
   * This method creates the default plot window.
   * 
   * @return @b PlotWindow* A pointer to the created window.
   */
  PlotWindow *EphemeridesPlotTool::createWindow() {
    PlotWindow *window = new EphemeridesPlotWindow(
@@ -96,7 +96,6 @@ namespace Isis {
   * Called when the user has finished drawing with the rubber
   * band.  ChangePlot is called to plot the data within the
   * rubber band.
   *
   */
  void EphemeridesPlotTool::rubberBandComplete() {
    if (selectedWindow()) {
@@ -162,10 +161,7 @@ namespace Isis {

  /**
   * This method sets up the names, line style, and color  of the
   * all the plot items that will be used in this class. This
   * method also fills the p_colors QList with the colors that
   * will be used when the user copies and pastes (special) into
   * another plot window.
   * all the plot items that will be used in this class.
   */
  void EphemeridesPlotTool::validatePlotCurves() {
      EphemeridesPlotWindow *targetWindow = qobject_cast<EphemeridesPlotWindow *>(
+7 −18
Original line number Diff line number Diff line
@@ -16,27 +16,17 @@ namespace Isis {
  class MdiCubeViewport;

  /**
  * @brief Tool for histograms
  * Tool for visualizing cube ephemerides, instrument position and orientation.
  * This tool plots the ephemeris data associated with the cube. The
  * ephemerides may come from SPICE, cached values, bundle adjusted values, or
  * other sources.
  *
  * @ingroup Visualization Tools
  *
  * @author ????-??-?? Noah Hilt
  * @author 2017-07-17 Jesse Mapel
  *
  * @internal
  *  @history 2008-08-18 Christopher Austin - Upgraded to geos3.0.0
  *  @history 2012-01-18 Steven Lambright and Jai Rideout - Fixed issue where
  *                          histograms were not created correctly for any bands
  *                          but band 1. Added check for RGB mode. Fixes #668.
  *  @history 2012-01-20 Steven Lambright - Completed documentation.
  *  @history 2013-12-11 Janet Barrett - Fixed refreshPlot method so that it 
  *                          checks the start sample and end sample for the
  *                          plot and starts the plot at the minimum of the 
  *                          2 samples. Fixes #1760.
  *  @history 2016-04-28 Tracie Sucharski - Removed qwt refernces to merge with
  *                          Qt5 library changes.
  *  @history 2016-07-06 Adam Paquette - Fixed the histogram tool to analyze the
  *                          appropriate pixels selected when using box banding
  *                          
  *  @history 2017-07-17 Jesse Mapel - Original Version
  */
  class EphemeridesPlotTool : public AbstractPlotTool {
      Q_OBJECT
@@ -74,8 +64,7 @@ namespace Isis {
      QPointer<CubePlotCurve> m_raCurve; /**! Plot curve for right ascension data. */
      QPointer<CubePlotCurve> m_decCurve; /**! Plot curve for declination data. */
      QPointer<CubePlotCurve> m_twiCurve; /**! Plot curve for twist data. */
      //! This is the action that activates this tool
      QAction *m_action;
      QAction *m_action; /**! The action that activates this tool. */
  };
};

Loading