Commit 399f5783 authored by Kristin Berry's avatar Kristin Berry Committed by Jesse Mapel
Browse files

Initial work toward a working AbstractBundleObservation class

parent 051f94bd
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ find files of those names at the top level of this repository. **/

// Isis lib
#include "Application.h"
#include "AbstractBundleObservation.h"
#include "BundleObservation.h"
#include "BundleObservationSolveSettings.h"
#include "BundleResults.h"
@@ -424,7 +425,7 @@ namespace Isis {
          throw IException(IException::Programmer, msg, _FILEINFO_);
        }

        BundleObservationQsp observation =
        AbstractBundleObservationQsp observation =
            m_bundleObservations.addNew(image, observationNumber, instrumentId, m_bundleSettings);

        if (!observation) {
@@ -461,7 +462,7 @@ namespace Isis {
          BundleMeasureQsp measure = bundleControlPoint->at(j);
          QString cubeSerialNumber = measure->cubeSerialNumber();

          BundleObservationQsp observation =
          AbstractBundleObservationQsp observation =
              m_bundleObservations.observationByCubeSerialNumber(cubeSerialNumber);
          BundleImageQsp image = observation->imageByCubeSerialNumber(cubeSerialNumber);

@@ -975,7 +976,6 @@ namespace Isis {
          cholmod_free_factor(&m_L, &m_cholmodCommon);
        }


        iterationSummary();

        m_iteration++;
@@ -1421,7 +1421,7 @@ namespace Isis {
        }
      }
      else {
        BundleObservationQsp observation;
        AbstractBundleObservationQsp observation;

        // get parameter weights for this observation
        if (m_bundleSettings->solveTargetBody()) {
@@ -1658,7 +1658,6 @@ namespace Isis {
        outputBundleStatus("\nTriplet allocation failure\n");
        return false;
      }

      m_cholmodTriplet->nnz = 0;
    }

@@ -1882,7 +1881,7 @@ namespace Isis {

    const BundleObservationSolveSettingsQsp observationSolveSettings =
        measure.observationSolveSettings();
    BundleObservationQsp observation = measure.parentBundleObservation();
    AbstractBundleObservationQsp observation = measure.parentBundleObservation();

    int numImagePartials = observation->numberParameters();

@@ -2158,14 +2157,15 @@ namespace Isis {
    // Update spice for each BundleObservation
    int numObservations = m_bundleObservations.size();
    for (int i = 0; i < numObservations; i++) {
      BundleObservationQsp observation = m_bundleObservations.at(i);
      AbstractBundleObservationQsp observation = m_bundleObservations.at(i);

      int numParameters = observation->numberParameters();

      observation->applyParameterCorrections(subrange(m_imageSolution,t,t+numParameters));

      if (m_bundleSettings->solveTargetBody()) {
        observation->updateBodyRotation();
        // TODO: needs to be updated for ISIS vs. CSM CSM has no updateBodyRotation
//        observation->updateBodyRotation();
      }

      t += numParameters;
@@ -2275,7 +2275,7 @@ namespace Isis {

    // add vtpv from constrained image parameters
    for (int i = 0; i < m_bundleObservations.size(); i++) {
      BundleObservationQsp observation = m_bundleObservations.at(i);
      AbstractBundleObservationQsp observation = m_bundleObservations.at(i);

      // get weight and correction vector for this observation
      const LinearAlgebra::Vector &weights = observation->parameterWeights();
@@ -2747,7 +2747,7 @@ namespace Isis {
      }
      // save adjusted image sigmas
      else {
        BundleObservationQsp observation;
        AbstractBundleObservationQsp observation;
        if (m_bundleSettings->solveTargetBody()) {
          observation = m_bundleObservations.at(i-1);
        }
+2 −2
Original line number Diff line number Diff line
@@ -1177,7 +1177,7 @@ namespace Isis {
    }


    BundleObservationQsp observation;
    AbstractBundleObservationQsp observation;

    int nObservations = m_statisticsResults->observations().size();

@@ -1259,7 +1259,7 @@ namespace Isis {
    m_txtBundleOutputFilename = ofname;

    char buf[4096];
    BundleObservationQsp observation;
    AbstractBundleObservationQsp observation;

    int nObservations = m_statisticsResults->observations().size();

+427 −0
Original line number Diff line number Diff line
/** This is free and unencumbered software released into the public domain.

The authors of ISIS do not claim copyright on the contents of this file.
For more details about the LICENSE terms and the AUTHORS, you will
find files of those names at the top level of this repository. **/

/* SPDX-License-Identifier: CC0-1.0 */

#include "AbstractBundleObservation.h"

#include <QDebug>
#include <QString>
#include <QStringList>
#include <QVector>

#include "BundleImage.h"
#include "BundleObservationSolveSettings.h"
#include "BundleTargetBody.h"
#include "Camera.h"
#include "LinearAlgebra.h"
#include "SpicePosition.h"
#include "SpiceRotation.h"

using namespace std;

namespace Isis {

  /**
   * Constructs a AbstractBundleObservation initialized to a default state.
   */
  AbstractBundleObservation::AbstractBundleObservation() {
    m_serialNumbers.clear();
    m_imageNames.clear();
    m_parameterNamesList.clear();
    m_observationNumber = "";
    m_instrumentId = "";
    m_instrumentRotation = NULL;
    m_instrumentPosition = NULL;
    m_index = 0;
    m_weights.clear();
    m_corrections.clear();
//    m_solution.clear();
    m_aprioriSigmas.clear();
    m_adjustedSigmas.clear();
  }


  /**
   * Constructs a AbstractBundleObservation from an BundleImage, an instrument id, an observation
   * number to assign to this AbstractBundleObservation, and a target body.
   *
   * @param image QSharedPointer to the primary image in the observation
   * @param observationNumber Observation number of the observation
   * @param instrumentId Id of the instrument for the observation
   * @param bundleTargetBody QSharedPointer to the target body of the observation
   */
  AbstractBundleObservation::AbstractBundleObservation(BundleImageQsp image, QString observationNumber,
                                       QString instrumentId, BundleTargetBodyQsp bundleTargetBody) {
    m_serialNumbers.clear();
    m_imageNames.clear();
    m_parameterNamesList.clear();
    m_observationNumber = "";
    m_instrumentId = "";
    m_instrumentRotation = NULL;
    m_instrumentPosition = NULL;
    m_index = 0;
    m_weights.clear();
    m_corrections.clear();
//    m_solution.clear();
    m_aprioriSigmas.clear();
    m_adjustedSigmas.clear();

    m_observationNumber = observationNumber;
    m_instrumentId = instrumentId;

    m_bundleTargetBody = bundleTargetBody;

    if (image) {
      append(image);
      m_serialNumbers.append(image->serialNumber());
      m_imageNames.append(image->fileName());
      m_cubeSerialNumberToBundleImageMap.insert(image->serialNumber(), image);

      // set the observations spice position and rotation objects from the primary image in the
      // observation (this is, by design at the moment, the first image added to the observation)
      // if the image, camera, or instrument position/orientation is null, then set to null
      m_instrumentPosition = (image->camera() ?
                               (image->camera()->instrumentPosition() ?
                                 image->camera()->instrumentPosition() : NULL)
                               : NULL);
      m_instrumentRotation = (image->camera() ?
                               (image->camera()->instrumentRotation() ?
                                  image->camera()->instrumentRotation() : NULL)
                               : NULL);

      // set the observations target body spice rotation object from the primary image in the
      // observation (this is, by design at the moment, the first image added to the observation)
      // if the image, camera, or instrument position/orientation is null, then set to null
//      m_bodyRotation = (image->camera() ?
//                           (image->camera()->bodyRotation() ?
//                             image->camera()->bodyRotation() : NULL)
//                           : NULL);
    }
  }


  /**
   * Creates a copy of another AbstractBundleObservation.
   *
   * @param src Reference to the AbstractBundleObservation to copy
   */
  AbstractBundleObservation::AbstractBundleObservation(const AbstractBundleObservation &src) {
    m_serialNumbers = src.m_serialNumbers;
    m_cubeSerialNumberToBundleImageMap = src.m_cubeSerialNumberToBundleImageMap;

    m_observationNumber = src.m_observationNumber;
    m_instrumentId = src.m_instrumentId;

    m_instrumentPosition = src.m_instrumentPosition;
    m_instrumentRotation = src.m_instrumentRotation;

    m_solveSettings = src.m_solveSettings;

    m_index = src.m_index;
  }


  /**
   * Destructor.
   *
   * Contained BundleImages will remain until all shared pointers are deleted.
   */
  AbstractBundleObservation::~AbstractBundleObservation() {
    clear();
  }


  /**
   * Assignment operator
   *
   * Assigns the state of the source AbstractBundleObservation to this AbstractBundleObservation
   *
   * @param AbstractBundleObservation Reference to the source AbstractBundleObservation to assign from
   *
   * @return @b AbstractBundleObservation& Reference to this AbstractBundleObservation
   */
  AbstractBundleObservation &AbstractBundleObservation::operator=(const AbstractBundleObservation &src) {
    if (&src != this) {
      m_serialNumbers = src.m_serialNumbers;
      m_cubeSerialNumberToBundleImageMap = src.m_cubeSerialNumberToBundleImageMap;

      m_observationNumber = src.m_observationNumber;
      m_instrumentId = src.m_instrumentId;

      m_instrumentPosition = src.m_instrumentPosition;
      m_instrumentRotation = src.m_instrumentRotation;

      m_solveSettings = src.m_solveSettings;
    }
    return *this;
  }


  /**
   * Appends a BundleImage shared pointer to the AbstractBundleObservation.
   * If the pointer is valid, then the BundleImage and its serial number will be inserted into
   * the serial number to BundleImage map.
   *
   * @param value The BundleImage to be appended.
   *
   * @see QVector::append()
   */
  void AbstractBundleObservation::append(const BundleImageQsp &value) {
    if (value) {
      m_cubeSerialNumberToBundleImageMap.insert(value->serialNumber(), value);
    }
    QVector<BundleImageQsp>::append(value);
  }


  /**
   * Returns the BundleImage shared pointer associated with the given serial number.
   * If no BundleImage with that serial number is contained a NULL pointer is returned.
   *
   * @param cubeSerialNumber The serial number of the cube to be returned.
   *
   * @return @b BundleImageQsp A shared pointer to the BundleImage (NULL if not found).
   */
  BundleImageQsp AbstractBundleObservation::imageByCubeSerialNumber(QString cubeSerialNumber) {
    BundleImageQsp bundleImage;

    if (m_cubeSerialNumberToBundleImageMap.contains(cubeSerialNumber)) {
      bundleImage = m_cubeSerialNumberToBundleImageMap.value(cubeSerialNumber);
    }

    return bundleImage;
  }


  // Need something that provides this functionality in child classes, but not here -- function signatures will be different. 
  /**
   * Set solve parameters
   *
   * @param solveSettings The solve settings to use
   *
   * @return @b bool Returns true if settings were successfully set
   *
   * @internal
   *   @todo initParameterWeights() doesn't return false, so this methods always
   *         returns true.
   */
//  bool AbstractBundleObservation::setSolveSettings(BundleObservationSolveSettings solveSettings) {
    // different for both 
//  }


  /**
   * Accesses the instrument id
   *
   * @return @b QString Returns the instrument id of the observation
   */
  QString AbstractBundleObservation::instrumentId() {
    return m_instrumentId;
  }


  /**
   * Accesses the solve parameter weights
   *
   * @return @b LinearAlgebra::Vector Returns the parameter weights for solving
   */
  LinearAlgebra::Vector &AbstractBundleObservation::parameterWeights() {
    return m_weights;
  }


  /**
   * Accesses the parameter corrections
   *
   * @return @b LinearAlgebra::Vector Returns the parameter corrections
   */
  LinearAlgebra::Vector &AbstractBundleObservation::parameterCorrections() {
    return m_corrections;
  }


  /**
   * Accesses the a priori sigmas
   *
   * @return @b LinearAlgebra::Vector Returns the a priori sigmas
   */
  LinearAlgebra::Vector &AbstractBundleObservation::aprioriSigmas() {
    return m_aprioriSigmas;
  }


  /**
   * Accesses the adjusted sigmas
   *
   * @return @b LinearAlgebra::Vector Returns the adjusted sigmas
   */
  LinearAlgebra::Vector &AbstractBundleObservation::adjustedSigmas() {
    return m_adjustedSigmas;
  }


  /**
   * Accesses the solve settings
   *
   * @return @b const AbstractBundleObservationSolveSettingsQsp Returns a pointer to the solve
   *                                                    settings for this AbstractBundleObservation
   */
  const AbstractBundleObservationSolveSettingsQsp AbstractBundleObservation::solveSettings() {
    return m_solveSettings;
  }


  /**
   * Initializes the paramater weights for solving
   *
   * @return @b bool Returns true upon successful intialization
   *
   * @internal
   *   @todo Don't like this, don't like this, don't like this, don't like this, don't like this.
   *         By the way, this seems klunky to me, would like to come up with a better way.
   *         Also, apriori sigmas are in two places, the AbstractBundleObservationSolveSettings AND in the
   *         the AbstractBundleObservation class too - this is unnecessary should only be in the
   *         AbstractBundleObservationSolveSettings. But, they are split into position and pointing.
   *
   *   @todo always returns true?
   */
  bool AbstractBundleObservation::initParameterWeights() {
    // will be different for ISIS and CSM
  }


  /**
   * Applies the parameter corrections
   *
   * @param corrections Vector of corrections to apply
   *
   * @throws IException::Unknown "Instrument position is NULL, but position solve option is
   *                              [not NoPositionFactors]"
   * @throws IException::Unknown "Instrument position is NULL, but pointing solve option is
   *                              [not NoPointingFactors]"
   * @throws IException::Unknown "Unable to apply parameter corrections to AbstractBundleObservation."
   *
   * @return @b bool Returns true upon successful application of corrections
   *
   * @internal
   *   @todo always returns true?
   */
  bool AbstractBundleObservation::applyParameterCorrections(LinearAlgebra::Vector corrections) {
    // Will be different for ISIS and CSM
    return false;
  }


  /**
   * Returns the number of total parameters there are for solving
   *
   * The total number of parameters is equal to the number of position parameters and number of
   * pointing parameters
   *
   * @return @b int Returns the number of parameters there are
   */
  int AbstractBundleObservation::numberParameters() {
    // different
    return 0;
  }


  /**
   * Sets the index for the observation
   *
   * @param n Value to set the index of the observation to
   */
  void AbstractBundleObservation::setIndex(int n) {
    m_index = n;
  }


  /**
   * Accesses the observation's index
   *
   * @return @b int Returns the observation's index
   */
  int AbstractBundleObservation::index() {
    return m_index;
  }

  /**
 * @brief Creates and returns a formatted QString representing the bundle coefficients and
 * parameters
 *
 * @depricated The function formatBundleOutputString is depricated as of ISIS 3.9
 * and will be removed in ISIS 4.0
 *
 * @param errorPropagation Boolean indicating whether or not to attach more information
 *     (corrections, sigmas, adjusted sigmas...) to the output QString
 * @param imageCSV Boolean which is set to true if the function is being
 *     called from BundleSolutionInfo::outputImagesCSV().  It is set to false by default
 *     for backwards compatibility.
 *
 * @return @b QString Returns a formatted QString representing the AbstractBundleObservation
 *
 * @internal
 *   @history 2016-10-26 Ian Humphrey - Default values are now provided for parameters that are
 *                           not being solved. Fixes #4464.
 */
QString AbstractBundleObservation::formatBundleOutputString(bool errorPropagation, bool imageCSV) {
  // different for both
}


// FIXME: if this is going to stay, needs to not take position and pointing
  void AbstractBundleObservation::bundleOutputFetchData(QVector<double> &finalParameterValues,
                          int &nPositionCoefficients, int &nPointingCoefficients,
                          bool &useDefaultPosition,
                          bool &useDefaultPointing, bool &useDefaultTwist) {
    // different for both, solve settings is a problem.
  }


  /**
   * @brief Takes in an open std::ofstream and writes out information which goes into the
   * bundleout.txt file.
   *
   * @param fpOut The open std::ofstream object which is passed in from
   * BundleSolutionInfo::outputText()
   * @param errorPropagation Boolean indicating whether or not to attach more information
   *     (corrections, sigmas, adjusted sigmas...) to the output.
   */
  void AbstractBundleObservation::bundleOutputString(std::ostream &fpOut, bool errorPropagation) {
    // different in both
  }

  /**
   * @brief Creates and returns a formatted QString representing the bundle coefficients and
   * parameters in csv format.
   *
   * @param errorPropagation Boolean indicating whether or not to attach more information
   *     (corrections, sigmas, adjusted sigmas...) to the output QString
   *
   * @return @b QString Returns a formatted QString representing the AbstractBundleObservation in
   * csv format
   */
  QString AbstractBundleObservation::bundleOutputCSV(bool errorPropagation) {
    // different in both
  }


// FIXME: will this work for both? CSM can list parameters, right? 
  QStringList AbstractBundleObservation::parameterList() {
    return m_parameterNamesList;
  }


  /**
   * Access to image names for CorrelationMatrix to use.
   *
   * @return @b QStringList Returns a QStringList of the image names
   */
  QStringList AbstractBundleObservation::imageNames() {
    return m_imageNames;
  }
}
+116 −0
Original line number Diff line number Diff line
#ifndef AbstractBundleObservation_h
#define AbstractBundleObservation_h

/** This is free and unencumbered software released into the public domain.

The authors of ISIS do not claim copyright on the contents of this file.
For more details about the LICENSE terms and the AUTHORS, you will
find files of those names at the top level of this repository. **/

/* SPDX-License-Identifier: CC0-1.0 */

#include <QStringList>
#include <QVector>

#include "BundleImage.h"
#include "BundleObservationSolveSettings.h"
#include "BundleTargetBody.h"
#include "LinearAlgebra.h"

namespace Isis {
  class BundleObservationSolveSettings;

  /**
   * @brief Class for bundle observations
   */
  class AbstractBundleObservation : public QVector<BundleImageQsp> {

    public:
      // default constructor
      AbstractBundleObservation();

      // constructor
      AbstractBundleObservation(BundleImageQsp image, QString observationNumber, QString instrumentId,
                        BundleTargetBodyQsp bundleTargetBody); // target body and CSM question

      // copy constructor
      AbstractBundleObservation(const AbstractBundleObservation &src);

      // destructor
      ~AbstractBundleObservation();

      // equals operator
      AbstractBundleObservation &operator=(const AbstractBundleObservation &src);

      // copy method
      void copy(const AbstractBundleObservation &src);

      void append(const BundleImageQsp &value);

      BundleImageQsp imageByCubeSerialNumber(QString cubeSerialNumber);

      bool setSolveSettings(BundleObservationSolveSettings solveSettings);

      void setIndex(int n);
      int index();

      QString instrumentId();

      LinearAlgebra::Vector &parameterWeights();
      LinearAlgebra::Vector &parameterCorrections();
      LinearAlgebra::Vector &aprioriSigmas();
      LinearAlgebra::Vector &adjustedSigmas();

      const BundleObservationSolveSettingsQsp solveSettings();
      int numberParameters();
      bool applyParameterCorrections(LinearAlgebra::Vector corrections);


      // FIXME: if this stays, needs to not use position/pointing
      void bundleOutputFetchData(QVector<double> &finalParameterValues,
                            int &nPositionCoefficients, int &nPointingCoefficients,
                            bool &useDefaultPosition, bool &useDefaultPointing,
                            bool &useDefaultTwist);


      void bundleOutputString(std::ostream &fpOut,bool errorPropagation);
      QString bundleOutputCSV(bool errorPropagation);

      QString formatBundleOutputString(bool errorPropagation, bool imageCSV=false);

      // CAN we have this for both? 
      QStringList parameterList();
      QStringList imageNames();

    private:
      QString m_observationNumber; /**< This is typically equivalent to serial number
                                        except in the case of "observation mode" (e.g.
                                        Lunar Orbiter) where for each image in the
                                        observation, the observation number is the serial number
                                        augmented with an additional integer. **/
      int m_index; //!< Index of this observation.
      //! Map between cube serial number and BundleImage pointers.
      QMap<QString, BundleImageQsp> m_cubeSerialNumberToBundleImageMap;
      QStringList m_serialNumbers;      //!< List of all cube serial numbers in observation.
      QStringList m_parameterNamesList; //!< List of all cube parameters.
      QStringList m_imageNames;         //!< List of all cube names.
      QString m_instrumentId;      //!< Spacecraft instrument id.

      BundleObservationSolveSettingsQsp m_solveSettings; //!< Solve settings for this observation.

      // TODO??? change these to LinearAlgebra vectors...
      LinearAlgebra::Vector m_weights;     //!< Parameter weights.
      //! Cumulative parameter correction vector.
      LinearAlgebra::Vector m_corrections;
      //LinearAlgebra::Vector m_solution;  //!< parameter solution vector.
      //! A posteriori (adjusted) parameter sigmas.
      LinearAlgebra::Vector m_aprioriSigmas;
      //! A posteriori (adjusted) parameter sigmas.
      LinearAlgebra::Vector m_adjustedSigmas;
  };

  //! Typdef for AbstractBundleObservation QSharedPointer.
  typedef QSharedPointer<AbstractBundleObservation> AbstractBundleObservationQsp; // change name or no?
}

#endif // AbstractBundleObservation_h
+3 −3
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ find files of those names at the top level of this repository. **/

#include "BundleImage.h"

#include "BundleObservation.h"
#include "AbstractBundleObservation.h"
#include "Camera.h"

namespace Isis {
@@ -72,7 +72,7 @@ namespace Isis {
   *
   * @param parentObservation The parent BundleObservation.
   */
  void BundleImage::setParentObservation(QSharedPointer<BundleObservation> parentObservation) {
  void BundleImage::setParentObservation(QSharedPointer<AbstractBundleObservation> parentObservation) {


    // TODO: BundleImage's setParentObservation should take a QSharedPointer. JAM
@@ -96,7 +96,7 @@ namespace Isis {
   *
   * @return @b QSharedPointer<BundleObservation> A pointer to the parent BundleObservation.
   */
  QSharedPointer<BundleObservation> BundleImage::parentObservation() {
  QSharedPointer<AbstractBundleObservation> BundleImage::parentObservation() {
    return m_parentObservation;
  }

Loading