Commit 2072faae authored by Jeannie Backer's avatar Jeannie Backer
Browse files

improved xml writers.

git-svn-id: http://subversion.wr.usgs.gov/repos/prog/isis3/branches/ipce@5942 41f8697f-d340-4b68-9986-7bafba869bb8
parent 8d0497a4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@

#include <vector>


// TODO Don't include
#include "FileList.h"
// The following includes are needed since class enumerations are used as input
+182 −15
Original line number Diff line number Diff line
@@ -18,8 +18,13 @@
 *  http://www.usgs.gov/privacy.html.
 */

#include "StatCumProbDistDynCalc.h"

#include <QDataStream>
#include <QDebug>
#include <QList>
#include <QUuid>
#include <QXmlStreamWriter>

#include <float.h>
#include <math.h>
@@ -27,7 +32,8 @@

#include "IException.h"
#include "IString.h"
#include "StatCumProbDistDynCalc.h"
#include "Project.h"
#include "XmlStackedHandlerReader.h"

namespace Isis {

@@ -38,18 +44,62 @@ namespace Isis {
   * @param [in] unsigned int nodes -- this is the number of specific evenly spaced quantiles that
   *                 will be dynamically tracked
   */
  StatCumProbDistDynCalc::StatCumProbDistDynCalc(unsigned int nodes) {
  StatCumProbDistDynCalc::StatCumProbDistDynCalc(unsigned int nodes, QObject *parent) : QObject(parent) {

    initialize(nodes);
  }



  StatCumProbDistDynCalc::StatCumProbDistDynCalc(Project *project, XmlStackedHandlerReader *xmlReader, QObject *parent) {   // TODO: does xml stuff need project???
    m_id = NULL;
    // ??? initializations ???
    xmlReader->pushContentHandler(new XmlHandler(this, project));   // TODO: does xml stuff need project???
  }



  StatCumProbDistDynCalc::StatCumProbDistDynCalc(const StatCumProbDistDynCalc &other)
    : m_id(new QUuid(other.m_id->toString())),
      m_numberCells(other.m_numberCells),      
      m_numberQuantiles(other.m_numberQuantiles),  
      m_quantiles(other.m_quantiles),        
      m_idealNum(other.m_idealNum),         
      m_n(other.m_n),                
      m_quantileValues(other.m_quantileValues),   
      m_numberObservations(other.m_numberObservations) {
  }



  /** 
   * Destroys StatCumProbDistDynCalc object.
   */ 
  StatCumProbDistDynCalc::~StatCumProbDistDynCalc() { 
  } //empty destructor
    delete m_id;
    m_id = NULL;
  }



  StatCumProbDistDynCalc &StatCumProbDistDynCalc::operator=(const StatCumProbDistDynCalc &other) {

    if (&other != this) {
      delete m_id;
      m_id = NULL;
      m_id = new QUuid(m_id->toString());

      m_numberCells        = other.m_numberCells;
      m_numberQuantiles    = other.m_numberQuantiles;
      m_quantiles          = other.m_quantiles;
      m_idealNum           = other.m_idealNum;
      m_n                  = other.m_n;
      m_quantileValues     = other.m_quantileValues;
      m_numberObservations = other.m_numberObservations;
    }
    return *this;

  }



@@ -96,14 +146,15 @@ namespace Isis {
   * Returns the maximum observation so far included in the dynamic calculation
   *
   * @return double -- the maximum observation so far included in the dynamic calculation
   * @throw  IsisProgrammerError -- StatCumDistDynCalc will return no data until 
   *             the number of observations added matches the number of
   *             quantiles (i.e. number of nodes) selected.
   * @throw  IsisProgrammerError -- StatCumProbDistDynCalc will return 
   *             no data until the number of observations added matches
   *             the number of quantiles (i.e. number of nodes)
   *             selected.
   */
  double StatCumProbDistDynCalc::max() {
     //if there isn't even as much data as there are quantiles to track return DBL_MAX
     if (m_numberObservations < m_numberQuantiles) {
       IString msg = "StatCumDistDynCalc will return no data until the number of observations added"
       IString msg = "StatCumProbDistDynCalc will return no data until the number of observations added"
                     " [" + toString(m_numberObservations) + "] matches the number of quantiles"
                     " [" + toString(m_numberQuantiles) + "] (i.e. number of nodes) selected.";
       throw IException(IException::Programmer, msg, _FILEINFO_);
@@ -119,14 +170,15 @@ namespace Isis {
   * Returns the maximum observation so far included in the dynamic calculation
   *
   * @return double -- the maximum observation so far included in the dynamic calculation
   * @throw  IsisProgrammerError -- StatCumDistDynCalc will return no data until 
   *             the number of observations added matches the number of
   *             quantiles (i.e. number of nodes) selected.
   * @throw  IsisProgrammerError -- StatCumProbDistDynCalc will return 
   *             no data until the number of observations added matches
   *             the number of quantiles (i.e. number of nodes)
   *             selected.
   */
   double StatCumProbDistDynCalc::min() { 
     //if there isn't even as much data as there are quantiles to track return -DBL_MAX
     if (m_numberObservations < m_numberQuantiles) {
       IString msg = "StatCumDistDynCalc will return no data until the number of observations added"
       IString msg = "StatCumProbDistDynCalc will return no data until the number of observations added"
                     " [" + toString(m_numberObservations) + "] matches the number of quantiles"
                     " [" + toString(m_numberQuantiles) + "] (i.e. number of nodes) selected.";
       throw IException(IException::Programmer, msg, _FILEINFO_);
@@ -145,7 +197,7 @@ namespace Isis {
   * @param [in] double -- cumlative probability domain [0.1]
   * @return double -- the vaule of the variable that has the cumulative probility (according the 
   *             current estimate of cumulative probility function)
   * @throw  IsisProgrammerError -- StatCumDistDynCalc will return no data until 
   * @throw  IsisProgrammerError -- StatCumProbDistDynCalc will return no data until 
   *             the number of observations added matches the number of
   *             quantiles (i.e. number of nodes) selected.
   * @throw  IsisProgrammerError -- Invalid cumulative probability passed in to 
@@ -159,7 +211,7 @@ namespace Isis {

     //if there isn't even as much data as there are quantiles to track return DBL_MAX
     if (m_numberObservations < m_numberQuantiles) {
       IString msg = "StatCumDistDynCalc will return no data until the number of observations added"
       IString msg = "StatCumProbDistDynCalc will return no data until the number of observations added"
                     " [" + toString(m_numberObservations) + "] matches the number of quantiles"
                     " [" + toString(m_numberQuantiles) + "] (i.e. number of nodes) selected.";
       throw IException(IException::Programmer, msg, _FILEINFO_);
@@ -265,14 +317,14 @@ namespace Isis {
   * @return    double -- the cumulative probility, that is, the proportion of the distribution 
   *                that is less than or equal to the value given (according the current
   *                estimate of cumulative probility function).
   * @throw     IsisProgrammerError -- StatCumDistDynCalc will return no data until there has been 
   * @throw     IsisProgrammerError -- StatCumProbDistDynCalc will return no data until there has been 
   *                at least m_numberQuantiles observations added
   */
   double StatCumProbDistDynCalc::cumProb(double value) {
     //given a value return the cumulative probility

     if (m_numberObservations < m_numberQuantiles) {
       IString msg = "StatCumDistDynCalc will return no data until the number of observations added"
       IString msg = "StatCumProbDistDynCalc will return no data until the number of observations added"
                     " [" + toString(m_numberObservations) + "] matches the number of quantiles"
                     " [" + toString(m_numberQuantiles) + "] (i.e. number of nodes) selected.";
       throw IException(IException::Programmer, msg, _FILEINFO_);
@@ -441,6 +493,121 @@ namespace Isis {



  void StatCumProbDistDynCalc::save(QXmlStreamWriter &stream, const Project *project) const {   // TODO: does xml stuff need project???

    stream.writeStartElement("statCumProbDistDynCalc");
    stream.writeTextElement("id", m_id->toString());
    stream.writeTextElement("numberCells", toString(m_numberCells));
    stream.writeTextElement("numberObservations", toString(m_numberObservations));

    stream.writeStartElement("quantiles");
    for (int i = 0; i < m_quantiles.size(); i++) {
      stream.writeTextElement("value", toString(m_quantiles[i]));
    }
    stream.writeEndElement();

    stream.writeStartElement("idealNum");
    for (int i = 0; i < m_idealNum.size(); i++) {
      stream.writeTextElement("value", toString(m_idealNum[i]));
    }
    stream.writeEndElement();
    
    stream.writeStartElement("n");
    for (int i = 0; i < m_n.size(); i++) {
      stream.writeTextElement("value", toString(m_n[i]));
    }
    stream.writeEndElement();

    stream.writeStartElement("quantileValues");
    for (int i = 0; i < m_quantileValues.size(); i++) {
      stream.writeTextElement("value", toString(m_quantileValues[i]));
    }
    stream.writeEndElement();
    stream.writeEndElement();

  }



  StatCumProbDistDynCalc::XmlHandler::XmlHandler(StatCumProbDistDynCalc *probabilityCalc, Project *project) {   // TODO: does xml stuff need project???
    m_probabilityCalc = probabilityCalc;
    m_project = project;   // TODO: does xml stuff need project???
    m_characters = "";
  }



  StatCumProbDistDynCalc::XmlHandler::~XmlHandler() {
    // ??? compile error ??? delete m_project;    // TODO: does xml stuff need project???
    m_project = NULL;
  }



  bool StatCumProbDistDynCalc::XmlHandler::startElement(const QString &namespaceURI, 
                                                                const QString &localName,
                                                                const QString &qName,
                                                                const QXmlAttributes &atts) {
    m_characters = "";
    if (XmlStackedHandler::startElement(namespaceURI, localName, qName, atts)) {
      // no element attibutes to evaluate
    }
    return true;
  }



  bool StatCumProbDistDynCalc::XmlHandler::characters(const QString &ch) {
    m_characters += ch;
    return XmlStackedHandler::characters(ch);
  }



  bool StatCumProbDistDynCalc::XmlHandler::endElement(const QString &namespaceURI, const QString &localName,
                                     const QString &qName) {
    if (!m_characters.isEmpty()) {
      if (localName == "id") {
        delete m_probabilityCalc->m_id;
        m_probabilityCalc->m_id = NULL;
        m_probabilityCalc->m_id = new QUuid(m_characters);
      }
      if (localName == "numberCells") {
        m_probabilityCalc->m_numberCells = toInt(m_characters);
      }
      if (localName == "numberObservations") {
        m_probabilityCalc->m_numberObservations = toInt(m_characters);
      }
//
//    stream.writeStartElement("quantileValue");
//    for (int i = 0; i < m_quantiles.size(); i++) {
//      stream.writeTextElement("value", toString(m_quantiles[i]));
//    }
//    stream.writeEndElement();
//
//    stream.writeStartElement("idealNum");
//    for (int i = 0; i < m_idealNum.size(); i++) {
//      stream.writeTextElement("value", toString(m_idealNum[i]));
//    }
//    stream.writeEndElement();
//    
//    stream.writeStartElement("n");
//    for (int i = 0; i < m_n.size(); i++) {
//      stream.writeTextElement("value", toString(m_n[i]));
//    }
//    stream.writeEndElement();
//
//    stream.writeStartElement("quantileValues");
//    for (int i = 0; i < m_quantileValues.size(); i++) {
//      stream.writeTextElement("value", toString(m_quantileValues[i]));

      m_characters = "";
    }
    return XmlStackedHandler::endElement(namespaceURI, localName, qName);
  }



  QDataStream &StatCumProbDistDynCalc::write(QDataStream &stream) const {
    stream << (qint32)m_numberCells
           << (qint32)m_numberQuantiles 
+64 −40
Original line number Diff line number Diff line
@@ -22,9 +22,19 @@
 */

#include <QList>
#include <QObject>
#include <QVector>

#include "XmlStackedHandler.h"

class QDataStream;
class QUuid;
class QXmlStreamWriter;

namespace Isis {
  class Project;// ??? does xml stuff need project???
  class XmlStackedHandlerReader;

 /**
  * @brief This class is used to approximate cumulative probibility distributions of a stream of
  *        observations without storing the observations or having any apriori knowlege of the range
@@ -61,14 +71,18 @@ namespace Isis {
  *                           methods.
  *
  */
  class StatCumProbDistDynCalc {
  class StatCumProbDistDynCalc : public QObject {
    Q_OBJECT
    // class uses the P^2 Algorithim to calculate equiprobability cell histograms from a stream of 
    // data without storing the data 
    //  see "The p^2 Algorithim for Dynamic Calculations of Quantiles and Histograms Without Storing
    //  Observations"
    public:
    StatCumProbDistDynCalc(unsigned int nodes=20);  //individual qunatile value to be calculated
    ~StatCumProbDistDynCalc(); //empty destructor
      StatCumProbDistDynCalc(unsigned int nodes=20, QObject *parent = 0);  //individual qunatile value to be calculated
      StatCumProbDistDynCalc(Project *project, XmlStackedHandlerReader *xmlReader, QObject *parent = 0);   // TODO: does xml stuff need project???
      StatCumProbDistDynCalc(const StatCumProbDistDynCalc &other);
      ~StatCumProbDistDynCalc();
      StatCumProbDistDynCalc &operator=(const StatCumProbDistDynCalc &other);
    
      void addObs(double obs);
      void set(int numberCells, 
@@ -84,56 +98,66 @@ namespace Isis {
      double max(); //return the largest value so far
      double min(); //return the smallest values so far
      void initialize(unsigned int nodes=20); //resets the class to start a new dynamic calculation
    
      void save(QXmlStreamWriter &stream, const Project *project) const;   // TODO: does xml stuff need project???
    
      QDataStream &write(QDataStream &stream) const;
      QDataStream &read(QDataStream &stream);

    private:

      /**
     * The number of cells or bins that being used to model the probility 
     * density function 
       *
       * @author 2014-07-28 Jeannie Backer
       *
       * @internal
       */
    unsigned int m_numberCells;     //the number of cells in the histogram
      class XmlHandler : public XmlStackedHandler {
        public:
          XmlHandler(StatCumProbDistDynCalc *probabilityCalc, Project *project);   // TODO: does xml stuff need project???
          ~XmlHandler();
   
    /** 
     * The number of quantiles being used to model the probility density 
     * function This is one more than the number of cells.
     */
    unsigned int m_numberQuantiles;     //the number of quantiles being calculated (m_cells+1)
          virtual bool startElement(const QString &namespaceURI, const QString &localName,
                                    const QString &qName, const QXmlAttributes &atts);
          virtual bool characters(const QString &ch);
          virtual bool endElement(const QString &namespaceURI, const QString &localName,
                                    const QString &qName);
   
    /** 
     * The quantiles being modeled begining at 0 and going to 1
     */
    QList<double> m_quantiles;        //the target quantile
        private:
          Q_DISABLE_COPY(XmlHandler);
   
    /** 
     * The ideal number of observations that should be less than or equal to the 
     * value of the corresponding quantiles, note this is dynamically changing 
     * as observations are added 
     */
    QList<double> m_idealNum;      //ideal positions of quantiles
          StatCumProbDistDynCalc *m_probabilityCalc;
          Project *m_project;   // TODO: does xml stuff need project???
          QString m_characters;
      };

    /** 
     * The actual number of observations that are less than or equal to the 
     * value of the corresponding quantiles, note this is dynamically changing 
     * as observations are added 
     */
    QList<int> m_n;
      QUuid *m_id; /**< A unique ID for this object (useful for others to reference
                        this object when saving to disk).*/
      unsigned int m_numberCells; /**< The number of cells or histogram bins that are being used to
                                       model the probility density function.*/
      
    /** 
     * The calculated values of the quantiles, note this is dynamically changing 
     * as observations are added 
     */
    QVector<double> m_quantileValues; // TODO: figure out how to change this to QList... 
      unsigned int m_numberQuantiles; /**< The number of quantiles being used to model the probility
                                           density function. This value is one more than the number of
                                           cells, (i.e. m_numberQuantiles=m_cells+1).*/
      
      QList<double> m_quantiles; /**< The target quantiles being modeled, between 0 and 1.*/
      
      QList<double> m_idealNum; /**< The ideal number of observations that should be less than or
                                     equal to the value of the corresponding quantiles, note this is
                                     dynamically changing as observations are added.*/
      
      QList<int> m_n; /**< The actual number of observations that are less than or equal to the value
                           of the corresponding quantiles, note this is dynamically changing as
                           observations are added.*/
      
      QVector<double> m_quantileValues; /**< The calculated values of the quantiles, note this is
                                             dynamically changing as observations are added.*/
      // TODO: figure out how to change this to QList... 
      //       Problem: resized in constructor, but not initialized.
                         // Values are set in addObs() using operator=, not  append() method.
                         // So size must already be set
      //       Values are set in addObs() using operator=, not  append()
      //       method. So size must already be set
      
    /** 
     * The number of observations, note this is dynamically changing as 
     * observations are added 
     */
    unsigned int m_numberObservations;  //the number of observations
      unsigned int m_numberObservations; /**< The number of observations, note this is dynamically
                                            changing as observations are added.*/
  };

  // operators to read/write StatCumProbDistDynCalc to/from binary data
+199 −29

File changed.

Preview size limit exceeded, changes collapsed.

+44 −7
Original line number Diff line number Diff line
@@ -20,11 +20,19 @@
 *  http://www.usgs.gov/privacy.html.
 */

#include <QObject>

#include "SpecialPixel.h"
#include "Constants.h"
#include "SpecialPixel.h"
#include "XmlStackedHandler.h"

class QDataStream;
class QUuid;
class QXmlStreamWriter;

namespace Isis {
  class Project;// ??? does xml stuff need project???
  class XmlStackedHandlerReader;
  /**
  * @brief This class is used to accumulate statistics on double arrays.
  *
@@ -73,16 +81,16 @@ namespace Isis {
  *   @todo 2005-02-07 Deborah Lee Soltesz - add example using cube data to the class documentation
  *
  */
  class Statistics {
  class Statistics : public QObject {
    Q_OBJECT
    public:
      Statistics();
      Statistics(QObject *parent = 0);
      Statistics(Project *project, XmlStackedHandlerReader *xmlReader, QObject *parent = 0);   // TODO: does xml stuff need project???
      Statistics(const Statistics &other);
      ~Statistics();
      Statistics &operator=(const Statistics &other);

      void Reset();
      void set(int validPixels, int nullPixels, int lrsPixels, int lisPixels,
               int hrsPixels, int hisPixels, int underRangePixels, int overRangePixels,
               double sum,  double minimum,  double maximum, double validMinimum,
               double validMaximum, bool removedData);

      void AddData(const double *data, const unsigned int count);
      void AddData(const double data);
@@ -152,10 +160,39 @@ namespace Isis {
        return m_sumsum;
      };

      void save(QXmlStreamWriter &stream, const Project *project) const;   // TODO: does xml stuff need project???
    
      QDataStream &write(QDataStream &stream) const;
      QDataStream &read(QDataStream &stream);

    private:
      /**
       *
       * @author 2014-07-28 Jeannie Backer
       *
       * @internal
       */
      class XmlHandler : public XmlStackedHandler {
        public:
          XmlHandler(Statistics *statistics, Project *project);   // TODO: does xml stuff need project???
          ~XmlHandler();
   
          virtual bool startElement(const QString &namespaceURI, const QString &localName,
                                    const QString &qName, const QXmlAttributes &atts);
          virtual bool characters(const QString &ch);
          virtual bool endElement(const QString &namespaceURI, const QString &localName,
                                    const QString &qName);
   
        private:
          Q_DISABLE_COPY(XmlHandler);
   
          Statistics *m_statistics;
          Project *m_project;   // TODO: does xml stuff need project???
          QString m_characters;
      };

      QUuid *m_id; /**< A unique ID for this object (useful for others to reference
                        this object when saving to disk).*/
      double m_sum;              //!< Sum accumulator.
      double m_sumsum;           //!< Sum-squared accumulator.
      double m_minimum;          //!< Minimum double value encountered.
Loading