<commit_before>
/**
 * @file SimpleKalmanFilter.hpp
 * Class to compute the solution using a Kalman filter.
 */

#ifndef SIMPLE_KALMAN_FILTER_HPP
#define SIMPLE_KALMAN_FILTER_HPP

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Dagoberto Salazar - gAGE ( http://www.gage.es ). 2007
//
//============================================================================

#include "Exception.hpp"
#include "Matrix.hpp"
#include "Vector.hpp"
#include "SolverBase.hpp"

namespace gpstk
{
    /** @addtogroup GPSsolutions */
    /// @ingroup math
      //@{

      /** This class computes the solution using a Kalman filter.
       *
       * A typical way to use this class follows:
       *
       * @code
       *    // Declarations and initializations here...
       *
       *    SimpleKalmanFilter kalman(xhat0, pmatrix);
       *
       *    while(cin >> x >> y) {
       *
       *        try {
       *
       *            meas(0) = x;
       *            meas(1) = y;
       *
       *            kalman.Compute(phimatrix, qmatrix, meas, hmatrix, rmatrix);
       *
       *            cout << kalman.xhat(0) << " " << kalman.xhat(1) << endl;
       *        }
       *        catch (Exception e)
       *        {
       *            cout << e;
       *        }
       * @endcode
       *
       * More information about the Kalman filter may be found in the excellent and
       * easy introduction by Welch, G. and G. Bishop. "An Introduction to the
       * Kalman Filter" (http://www.cs.unc.edu/~welch/kalman/kalmanIntro.html).
       *
       * However, be aware that the algorithm used here is the modified version
       * presented in G. J. Bierman. "Factorization Methods for Discrete Sequential
       * Estimation". Mathematics in Science and Engineering, Vol. 128. Academic
       * Press, New York, 1977. This version enjoys better numerical stability.
       *
       */
    class SimpleKalmanFilter
    {
    public:

        /// Default constructor.
        SimpleKalmanFilter() : xhat(1,0.0), P(1,1,0.0), xhatminus(1,0.0), Pminus(1,1,0.0) {};

        /** Common constructor.
         *
         * @param initialState      Vector setting the initial state of the system.
         * @param initialErrorCovariance    Matrix setting the initial values of the a posteriori error covariance.
         */
        SimpleKalmanFilter(const Vector<double>& initialState, const Matrix<double>& initialErrorCovariance) : xhat(initialState), P(initialErrorCovariance), xhatminus(initialState.size(), 0.0), Pminus(initialErrorCovariance.rows(), initialErrorCovariance.cols(), 0.0) {};

        /** Common constructor. This is meant to be used with one-dimensional systems.
         *
         * @param initialValue      Initial value of system state.
         * @param initialErrorVariance  Initial value of the a posteriori error variance.
         */
        SimpleKalmanFilter(const double& initialValue, const double& initialErrorVariance) : xhat(1,initialValue), P(1,1,initialErrorVariance), xhatminus(1,0.0), Pminus(1,1,0.0) {};

        /** Reset method.
         *
         * This method will reset the filter, setting new values for initial system
         * state vector and the a posteriori error covariance matrix.
         *
         * @param initialState      Vector setting the initial state of the system.
         * @param initialErrorCovariance    Matrix setting the initial values of the a posteriori error covariance.
         */
        virtual void Reset(const Vector<double>& initialState, const Matrix<double>& initialErrorCovariance)
        {
            xhat = initialState;
            P = initialErrorCovariance;
            xhatminus.resize(initialState.size(), 0.0);
            Pminus.resize(initialErrorCovariance.rows(), initialErrorCovariance.cols(), 0.0);
        }

        /** Reset method.
         *
         * This method will reset the filter, setting new values for initial system
         * state and the a posteriori error variance. Used for one-dimensional
         * systems.
         *
         * @param initialValue      Initial value of system state.
         * @param initialErrorVariance  Initial value of the a posteriori error variance.
         */
        virtual void Reset(const double& initialValue, const double& initialErrorVariance)
        {
            xhat.resize(1, initialValue);
            P.resize(1,1, initialErrorVariance);
            xhatminus.resize(1, 0.0);
            Pminus.resize(1, 1, 0.0);
        }

        /** Compute the a posteriori estimate of the system state, as well as the
         * a posteriori estimate error covariance matrix.
         *
         * @param phiMatrix         State transition matrix.
         * @param controlMatrix     Control matrix.
         * @param controlInput      Control input vector.
         * @param processNoiseCovariance    Process noise covariance matrix.
         * @param measurements      Measurements vector.
         * @param measurementsMatrix    Measurements matrix. Called geometry matrix in GNSS.
         * @param measurementsNoiseCovariance   Measurements noise covariance matrix.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Compute(const Matrix<double>& phiMatrix, const Matrix<double>& controlMatrix, const Vector<double>& controlInput, const Matrix<double>& processNoiseCovariance, const Vector<double>& measurements, const Matrix<double>& measurementsMatrix, const Matrix<double>& measurementsNoiseCovariance) throw(InvalidSolver);

        /** Compute the a posteriori estimate of the system state, as well as the
         * a posteriori estimate error covariance matrix. This version assumes that
         * no control inputs act on the system.
         *
         * @param phiMatrix         State transition matrix.
         * @param processNoiseCovariance    Process noise covariance matrix.
         * @param measurements      Measurements vector.
         * @param measurementsMatrix    Measurements matrix. Called geometry matrix in GNSS.
         * @param measurementsNoiseCovariance   Measurements noise covariance matrix.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Compute(const Matrix<double>& phiMatrix, const Matrix<double>& processNoiseCovariance, const Vector<double>& measurements, const Matrix<double>& measurementsMatrix, const Matrix<double>& measurementsNoiseCovariance) throw(InvalidSolver);

        /** Compute the a posteriori estimate of the system state, as well as the
         * a posteriori estimate error variance. Version for one-dimensional systems.
         *
         * @param phiValue          State transition gain.
         * @param controlGain       Control gain.
         * @param controlInput      Control input value.
         * @param processNoiseVariance    Process noise variance.
         * @param measurement       Measurement value.
         * @param measurementsGain  Measurements gain.
         * @param measurementsNoiseVariance   Measurements noise variance.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Compute(const double& phiValue, const double& controlGain, const double& controlInput, const double& processNoiseVariance, const double& measurement, const double& measurementsGain, const double& measurementsNoiseVariance) throw(InvalidSolver);

        /** Compute the a posteriori estimate of the system state, as well as the
         * a posteriori estimate error variance. Version for one-dimensional systems
         * without control input on the system.
         *
         * @param phiValue          State transition gain.
         * @param processNoiseVariance    Process noise variance.
         * @param measurement       Measurement value.
         * @param measurementsGain  Measurements gain.
         * @param measurementsNoiseVariance   Measurements noise variance.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Compute(const double& phiValue, const double& processNoiseVariance, const double& measurement, const double& measurementsGain, const double& measurementsNoiseVariance) throw(InvalidSolver);

        /// Destructor.
        virtual ~SimpleKalmanFilter() {};

        /// A posteriori state estimation. This is usually your target.
        Vector<double> xhat;

        /// A posteriori error covariance.
        Matrix<double> P;

        /// A priori state estimation.
        Vector<double> xhatminus;

        /// A priori error covariance.
        Matrix<double> Pminus;

    private:

        /** Predicts (or "time updates") the a priori estimate of the system state,
         * as well as the a priori estimate error covariance matrix.
         *
         * @param phiMatrix         State transition matrix.
         * @param previousState     Previous system state vector. It is the last computed xhat.
         * @param controlMatrix     Control matrix.
         * @param controlInput      Control input vector.
         * @param processNoiseCovariance    Process noise covariance matrix.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Predict(const Matrix<double>& phiMatrix, const Vector<double>& previousState, const Matrix<double>& controlMatrix, const Vector<double>& controlInput, const Matrix<double>& processNoiseCovariance) throw(InvalidSolver);

        /** Predicts (or "time updates") the a priori estimate of the system state,
         * as well as the a priori estimate error variance. Version for
         * one-dimensional systems.
         *
         * @param phiValue          State transition gain.
         * @param previousState     Previous system state. It is the last computed xhat.
         * @param controlGain       Control gain.
         * @param controlInput      Control input value.
         * @param processNoiseVariance    Process noise variance.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Predict(const double& phiValue, const double& previousState, const double& controlGain, const double& controlInput, const double& processNoiseVariance) throw(InvalidSolver)
        {

            // Create dummy matrices and vectors and call the full Predict() method
            Matrix<double> dummyPhiMatrix(1,1,phiValue);
            Vector<double> dummyPreviousState(1,previousState);
            Matrix<double> dummyControMatrix(1,1,controlGain);
            Vector<double> dummyControlInput(1,controlInput);
            Matrix<double> dummyProcessNoiseCovariance(1,1,processNoiseVariance);

            return ( (*this).Predict(dummyPhiMatrix, dummyPreviousState, dummyControMatrix, dummyControlInput, dummyProcessNoiseCovariance) );

        };

        /** Predicts (or "time updates") the a priori estimate of the system state,
         * as well as the a priori estimate error covariance matrix. This version
         * assumes that no control inputs act on the system.
         *
         * @param phiMatrix         State transition matrix.
         * @param previousState     Previous system state vector. It is the last computed xhat.
         * @param processNoiseCovariance    Process noise covariance matrix.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Predict(const Matrix<double>& phiMatrix, const Vector<double>& previousState, const Matrix<double>& processNoiseCovariance) throw(InvalidSolver)
        {

            // Create dummy matrices and vectors and call the full Predict() method
            int stateRow(previousState.size());

            Matrix<double> dummyControMatrix(stateRow,1,0.0);
            Vector<double> dummyControlInput(1,0.0);

            return ( (*this).Predict(phiMatrix, previousState, dummyControMatrix, dummyControlInput, processNoiseCovariance) );

        };

        /** Predicts (or "time updates") the a priori estimate of the system state,
         * as well as the a priori estimate error variance. Version for
         * one-dimensional systems and no control input acting on the system.
         *
         * @param phiValue          State transition gain.
         * @param previousState     Previous system state. It is the last computed xhat.
         * @param processNoiseVariance    Process noise variance.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Predict(const double& phiValue, const double& previousState, const double& processNoiseVariance) throw(InvalidSolver)
        {

            // Create dummy matrices and vectors and call the full Predict() method
            Matrix<double> dummyPhiMatrix(1,1,phiValue);
            Vector<double> dummyPreviousState(1,previousState);
            Matrix<double> dummyControMatrix(1,1,0.0);
            Vector<double> dummyControlInput(1,0.0);
            Matrix<double> dummyProcessNoiseCovariance(1,1,processNoiseVariance);

            return ( (*this).Predict(dummyPhiMatrix, dummyPreviousState, dummyControMatrix, dummyControlInput, dummyProcessNoiseCovariance) );

        };

        /** Corrects (or "measurement updates") the a posteriori estimate of the
         * system state vector, as well as the a posteriori estimate error covariance
         * matrix, using as input the predicted a priori state vector and error
         * covariance matrix, plus measurements and associated matrices.
         *
         * @param measurements      Measurements vector.
         * @param measurementsMatrix    Measurements matrix. Called geometry matrix in GNSS.
         * @param measurementsNoiseCovariance   Measurements noise covariance matrix.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Correct(const Vector<double>& measurements, const Matrix<double>& measurementsMatrix, const Matrix<double>& measurementsNoiseCovariance) throw(InvalidSolver);

        /** Corrects (or "measurement updates") the a posteriori estimate of the
         * system state value, as well as the a posteriori estimate error variance,
         * using as input the predicted a priori state and error variance values,
         * plus measurement and associated gain and variance. Version for
         * one-dimensional systems.
         *
         * @param measurement       Measurement value.
         * @param measurementsGain  Measurements gain.
         * @param measurementsNoiseVariance   Measurements noise variance.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Correct(const double& measurement, const double& measurementsGain, const double& measurementsNoiseVariance) throw(InvalidSolver)
        {

            // Create dummy matrices and vectors and call the full Correct() method
            Vector<double> dummyMeasurements(1,measurement);
            Matrix<double> dummyMeasurementsMatrix(1,1,measurementsGain);
            Matrix<double> dummyMeasurementsNoise(1,1,measurementsNoiseVariance);

            return ( (*this).Correct(dummyMeasurements, dummyMeasurementsMatrix, dummyMeasurementsNoise) );

        };

    }; // class SimpleKalmanFilter

   //@}

} // namespace

#endif
<commit_msg>Simple change in documentation.<commit_after>
/**
 * @file SimpleKalmanFilter.hpp
 * Class to compute the solution using a Kalman filter.
 */

#ifndef SIMPLE_KALMAN_FILTER_HPP
#define SIMPLE_KALMAN_FILTER_HPP

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Dagoberto Salazar - gAGE ( http://www.gage.es ). 2007
//
//============================================================================

#include "Exception.hpp"
#include "Matrix.hpp"
#include "Vector.hpp"
#include "SolverBase.hpp"

namespace gpstk
{
    /** @addtogroup GPSsolutions */
    /// @ingroup math
      //@{

      /** This class computes the solution using a Kalman filter.
       *
       * A typical way to use this class follows:
       *
       * @code
       *    // Declarations and initializations here...
       *
       *    SimpleKalmanFilter kalman(xhat0, pmatrix);
       *
       *    while(cin >> x >> y) {
       *
       *        try {
       *
       *            meas(0) = x;
       *            meas(1) = y;
       *
       *            kalman.Compute(phimatrix, qmatrix, meas, hmatrix, rmatrix);
       *
       *            cout << kalman.xhat(0) << " " << kalman.xhat(1) << endl;
       *        }
       *        catch (Exception e)
       *        {
       *            cout << e;
       *        }
       *    }
       * @endcode
       *
       * More information about the Kalman filter may be found in the excellent and
       * easy introduction by Welch, G. and G. Bishop. "An Introduction to the
       * Kalman Filter" (http://www.cs.unc.edu/~welch/kalman/kalmanIntro.html).
       *
       * However, be aware that the algorithm used here is the modified version
       * presented in G. J. Bierman. "Factorization Methods for Discrete Sequential
       * Estimation". Mathematics in Science and Engineering, Vol. 128. Academic
       * Press, New York, 1977. This version enjoys better numerical stability.
       *
       */
    class SimpleKalmanFilter
    {
    public:

        /// Default constructor.
        SimpleKalmanFilter() : xhat(1,0.0), P(1,1,0.0), xhatminus(1,0.0), Pminus(1,1,0.0) {};

        /** Common constructor.
         *
         * @param initialState      Vector setting the initial state of the system.
         * @param initialErrorCovariance    Matrix setting the initial values of the a posteriori error covariance.
         */
        SimpleKalmanFilter(const Vector<double>& initialState, const Matrix<double>& initialErrorCovariance) : xhat(initialState), P(initialErrorCovariance), xhatminus(initialState.size(), 0.0), Pminus(initialErrorCovariance.rows(), initialErrorCovariance.cols(), 0.0) {};

        /** Common constructor. This is meant to be used with one-dimensional systems.
         *
         * @param initialValue      Initial value of system state.
         * @param initialErrorVariance  Initial value of the a posteriori error variance.
         */
        SimpleKalmanFilter(const double& initialValue, const double& initialErrorVariance) : xhat(1,initialValue), P(1,1,initialErrorVariance), xhatminus(1,0.0), Pminus(1,1,0.0) {};

        /** Reset method.
         *
         * This method will reset the filter, setting new values for initial system
         * state vector and the a posteriori error covariance matrix.
         *
         * @param initialState      Vector setting the initial state of the system.
         * @param initialErrorCovariance    Matrix setting the initial values of the a posteriori error covariance.
         */
        virtual void Reset(const Vector<double>& initialState, const Matrix<double>& initialErrorCovariance)
        {
            xhat = initialState;
            P = initialErrorCovariance;
            xhatminus.resize(initialState.size(), 0.0);
            Pminus.resize(initialErrorCovariance.rows(), initialErrorCovariance.cols(), 0.0);
        }

        /** Reset method.
         *
         * This method will reset the filter, setting new values for initial system
         * state and the a posteriori error variance. Used for one-dimensional
         * systems.
         *
         * @param initialValue      Initial value of system state.
         * @param initialErrorVariance  Initial value of the a posteriori error variance.
         */
        virtual void Reset(const double& initialValue, const double& initialErrorVariance)
        {
            xhat.resize(1, initialValue);
            P.resize(1,1, initialErrorVariance);
            xhatminus.resize(1, 0.0);
            Pminus.resize(1, 1, 0.0);
        }

        /** Compute the a posteriori estimate of the system state, as well as the
         * a posteriori estimate error covariance matrix.
         *
         * @param phiMatrix         State transition matrix.
         * @param controlMatrix     Control matrix.
         * @param controlInput      Control input vector.
         * @param processNoiseCovariance    Process noise covariance matrix.
         * @param measurements      Measurements vector.
         * @param measurementsMatrix    Measurements matrix. Called geometry matrix in GNSS.
         * @param measurementsNoiseCovariance   Measurements noise covariance matrix.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Compute(const Matrix<double>& phiMatrix, const Matrix<double>& controlMatrix, const Vector<double>& controlInput, const Matrix<double>& processNoiseCovariance, const Vector<double>& measurements, const Matrix<double>& measurementsMatrix, const Matrix<double>& measurementsNoiseCovariance) throw(InvalidSolver);

        /** Compute the a posteriori estimate of the system state, as well as the
         * a posteriori estimate error covariance matrix. This version assumes that
         * no control inputs act on the system.
         *
         * @param phiMatrix         State transition matrix.
         * @param processNoiseCovariance    Process noise covariance matrix.
         * @param measurements      Measurements vector.
         * @param measurementsMatrix    Measurements matrix. Called geometry matrix in GNSS.
         * @param measurementsNoiseCovariance   Measurements noise covariance matrix.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Compute(const Matrix<double>& phiMatrix, const Matrix<double>& processNoiseCovariance, const Vector<double>& measurements, const Matrix<double>& measurementsMatrix, const Matrix<double>& measurementsNoiseCovariance) throw(InvalidSolver);

        /** Compute the a posteriori estimate of the system state, as well as the
         * a posteriori estimate error variance. Version for one-dimensional systems.
         *
         * @param phiValue          State transition gain.
         * @param controlGain       Control gain.
         * @param controlInput      Control input value.
         * @param processNoiseVariance    Process noise variance.
         * @param measurement       Measurement value.
         * @param measurementsGain  Measurements gain.
         * @param measurementsNoiseVariance   Measurements noise variance.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Compute(const double& phiValue, const double& controlGain, const double& controlInput, const double& processNoiseVariance, const double& measurement, const double& measurementsGain, const double& measurementsNoiseVariance) throw(InvalidSolver);

        /** Compute the a posteriori estimate of the system state, as well as the
         * a posteriori estimate error variance. Version for one-dimensional systems
         * without control input on the system.
         *
         * @param phiValue          State transition gain.
         * @param processNoiseVariance    Process noise variance.
         * @param measurement       Measurement value.
         * @param measurementsGain  Measurements gain.
         * @param measurementsNoiseVariance   Measurements noise variance.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Compute(const double& phiValue, const double& processNoiseVariance, const double& measurement, const double& measurementsGain, const double& measurementsNoiseVariance) throw(InvalidSolver);

        /// Destructor.
        virtual ~SimpleKalmanFilter() {};

        /// A posteriori state estimation. This is usually your target.
        Vector<double> xhat;

        /// A posteriori error covariance.
        Matrix<double> P;

        /// A priori state estimation.
        Vector<double> xhatminus;

        /// A priori error covariance.
        Matrix<double> Pminus;

    private:

        /** Predicts (or "time updates") the a priori estimate of the system state,
         * as well as the a priori estimate error covariance matrix.
         *
         * @param phiMatrix         State transition matrix.
         * @param previousState     Previous system state vector. It is the last computed xhat.
         * @param controlMatrix     Control matrix.
         * @param controlInput      Control input vector.
         * @param processNoiseCovariance    Process noise covariance matrix.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Predict(const Matrix<double>& phiMatrix, const Vector<double>& previousState, const Matrix<double>& controlMatrix, const Vector<double>& controlInput, const Matrix<double>& processNoiseCovariance) throw(InvalidSolver);

        /** Predicts (or "time updates") the a priori estimate of the system state,
         * as well as the a priori estimate error variance. Version for
         * one-dimensional systems.
         *
         * @param phiValue          State transition gain.
         * @param previousState     Previous system state. It is the last computed xhat.
         * @param controlGain       Control gain.
         * @param controlInput      Control input value.
         * @param processNoiseVariance    Process noise variance.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Predict(const double& phiValue, const double& previousState, const double& controlGain, const double& controlInput, const double& processNoiseVariance) throw(InvalidSolver)
        {

            // Create dummy matrices and vectors and call the full Predict() method
            Matrix<double> dummyPhiMatrix(1,1,phiValue);
            Vector<double> dummyPreviousState(1,previousState);
            Matrix<double> dummyControMatrix(1,1,controlGain);
            Vector<double> dummyControlInput(1,controlInput);
            Matrix<double> dummyProcessNoiseCovariance(1,1,processNoiseVariance);

            return ( (*this).Predict(dummyPhiMatrix, dummyPreviousState, dummyControMatrix, dummyControlInput, dummyProcessNoiseCovariance) );

        };

        /** Predicts (or "time updates") the a priori estimate of the system state,
         * as well as the a priori estimate error covariance matrix. This version
         * assumes that no control inputs act on the system.
         *
         * @param phiMatrix         State transition matrix.
         * @param previousState     Previous system state vector. It is the last computed xhat.
         * @param processNoiseCovariance    Process noise covariance matrix.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Predict(const Matrix<double>& phiMatrix, const Vector<double>& previousState, const Matrix<double>& processNoiseCovariance) throw(InvalidSolver)
        {

            // Create dummy matrices and vectors and call the full Predict() method
            int stateRow(previousState.size());

            Matrix<double> dummyControMatrix(stateRow,1,0.0);
            Vector<double> dummyControlInput(1,0.0);

            return ( (*this).Predict(phiMatrix, previousState, dummyControMatrix, dummyControlInput, processNoiseCovariance) );

        };

        /** Predicts (or "time updates") the a priori estimate of the system state,
         * as well as the a priori estimate error variance. Version for
         * one-dimensional systems and no control input acting on the system.
         *
         * @param phiValue          State transition gain.
         * @param previousState     Previous system state. It is the last computed xhat.
         * @param processNoiseVariance    Process noise variance.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Predict(const double& phiValue, const double& previousState, const double& processNoiseVariance) throw(InvalidSolver)
        {

            // Create dummy matrices and vectors and call the full Predict() method
            Matrix<double> dummyPhiMatrix(1,1,phiValue);
            Vector<double> dummyPreviousState(1,previousState);
            Matrix<double> dummyControMatrix(1,1,0.0);
            Vector<double> dummyControlInput(1,0.0);
            Matrix<double> dummyProcessNoiseCovariance(1,1,processNoiseVariance);

            return ( (*this).Predict(dummyPhiMatrix, dummyPreviousState, dummyControMatrix, dummyControlInput, dummyProcessNoiseCovariance) );

        };

        /** Corrects (or "measurement updates") the a posteriori estimate of the
         * system state vector, as well as the a posteriori estimate error covariance
         * matrix, using as input the predicted a priori state vector and error
         * covariance matrix, plus measurements and associated matrices.
         *
         * @param measurements      Measurements vector.
         * @param measurementsMatrix    Measurements matrix. Called geometry matrix in GNSS.
         * @param measurementsNoiseCovariance   Measurements noise covariance matrix.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Correct(const Vector<double>& measurements, const Matrix<double>& measurementsMatrix, const Matrix<double>& measurementsNoiseCovariance) throw(InvalidSolver);

        /** Corrects (or "measurement updates") the a posteriori estimate of the
         * system state value, as well as the a posteriori estimate error variance,
         * using as input the predicted a priori state and error variance values,
         * plus measurement and associated gain and variance. Version for
         * one-dimensional systems.
         *
         * @param measurement       Measurement value.
         * @param measurementsGain  Measurements gain.
         * @param measurementsNoiseVariance   Measurements noise variance.
         *
         * @return
         *  0 if OK
         *  -1 if problems arose
         */
        virtual int Correct(const double& measurement, const double& measurementsGain, const double& measurementsNoiseVariance) throw(InvalidSolver)
        {

            // Create dummy matrices and vectors and call the full Correct() method
            Vector<double> dummyMeasurements(1,measurement);
            Matrix<double> dummyMeasurementsMatrix(1,1,measurementsGain);
            Matrix<double> dummyMeasurementsNoise(1,1,measurementsNoiseVariance);

            return ( (*this).Correct(dummyMeasurements, dummyMeasurementsMatrix, dummyMeasurementsNoise) );

        };

    }; // class SimpleKalmanFilter

   //@}

} // namespace

#endif
<|endoftext|>


<commit_before>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE JPetSignalTest

#include <boost/test/unit_test.hpp>
#include "../JPetRawSignal/JPetRawSignal.h"
#include "../JPetBarrelSlot/JPetBarrelSlot.h"
#include "../JPetPM/JPetPM.h"

// Tests
BOOST_AUTO_TEST_SUITE(ParamDataTS)

BOOST_AUTO_TEST_CASE(ToTTest) {
  JPetSigCh sigch;
  sigch.setType(JPetSigCh::Charge);
  sigch.setValue(17.f);
  JPetRawSignal signal;
  signal.addPoint(sigch);

  BOOST_REQUIRE_EQUAL(signal.getTOT(), 17.f);

  JPetRawSignal signal2;
  signal2.setTOTPoint(sigch);

  BOOST_REQUIRE_EQUAL(signal2.getTOT(), 17.f);
}

//
//BOOST_AUTO_TEST_CASE(QualityOfTimeTest) {
//  JPetSignal signal;
//
//  BOOST_REQUIRE_EQUAL(signal.getQualityOfTime(), 0.f);
//}
//
//BOOST_AUTO_TEST_CASE(QualityOfEnergyTest) {
//  JPetSignal signal;
//
//  BOOST_REQUIRE_EQUAL(signal.getQualityOfEnergy(), 0.f);
//}

BOOST_AUTO_TEST_CASE(GetNumberOfPointsTest) {
  JPetRawSignal signal;

  BOOST_REQUIRE_EQUAL(signal.getNumberOfPoints(JPetSigCh::Trailing), 0);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfPoints(JPetSigCh::Leading), 0);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfLeadingEdgePoints(), 0);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfTrailingEdgePoints(), 0);

}

BOOST_AUTO_TEST_CASE(AddLeadingPointTest) {
  JPetRawSignal signal;
  const JPetSigCh sigCh;

  signal.addPoint(sigCh);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfPoints(JPetSigCh::Leading), 1);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfLeadingEdgePoints(), 1);
}

BOOST_AUTO_TEST_CASE(AddTrailingPointTest) {
  JPetRawSignal signal;
  const JPetSigCh sigCh(JPetSigCh::Trailing, 8.f);

  signal.addPoint(sigCh);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfPoints(JPetSigCh::Trailing), 1);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfTrailingEdgePoints(), 1);
}

BOOST_AUTO_TEST_CASE(GetVectorOfPointsTest) {
  JPetRawSignal signal;
  JPetSigCh sigch1(JPetSigCh::Trailing, 8.f);
  sigch1.setThreshold(100.f);
  sigch1.setThresholdNumber(2);
  JPetSigCh sigch2(JPetSigCh::Trailing, 17.f);
  sigch2.setThreshold(200.f);
  sigch2.setThresholdNumber(1);

  signal.addPoint(sigch1);
  signal.addPoint(sigch2);

  BOOST_REQUIRE_EQUAL(
      signal.getPoints(JPetSigCh::Trailing, JPetRawSignal::ByThrNum).at(0).getValue(),
      17.f);

  BOOST_REQUIRE_EQUAL(
      signal.getPoints(JPetSigCh::Trailing, JPetRawSignal::ByThrValue).at(0).getValue(),
      8.f);

  BOOST_REQUIRE_EQUAL(
      signal.getPoints(JPetSigCh::Leading, JPetRawSignal::ByThrValue).size(),
      0);

}

BOOST_AUTO_TEST_CASE(GetMapOfTimesVsThrNumTest) {

  JPetRawSignal signal;
  JPetSigCh sigch1(JPetSigCh::Trailing, 8.f);
  sigch1.setThreshold(100.f);
  sigch1.setThresholdNumber(1);
  JPetSigCh sigch2(JPetSigCh::Trailing, 17.f);
  sigch2.setThreshold(200.f);
  sigch2.setThresholdNumber(2);
  JPetSigCh sigch3(JPetSigCh::Trailing, 43.f);
  sigch3.setThreshold(400.f);
  sigch3.setThresholdNumber(4);

  signal.addPoint(sigch1);
  signal.addPoint(sigch2);
  signal.addPoint(sigch3);

  std::map<int, double> map;
  map = signal.getTimesVsThresholdNumber(JPetSigCh::Trailing);

  BOOST_REQUIRE_EQUAL( map[sigch1.getThresholdNumber()], sigch1.getValue() );
  BOOST_REQUIRE_EQUAL( map[sigch2.getThresholdNumber()], sigch2.getValue() );
  BOOST_REQUIRE_EQUAL( map[sigch3.getThresholdNumber()], sigch3.getValue() );
  BOOST_REQUIRE_EQUAL( map[3], 0.f );
}

BOOST_AUTO_TEST_CASE(GetMapOfTimesVsThrValueTest) {

  JPetRawSignal signal;
  JPetSigCh sigch1(JPetSigCh::Trailing, 8.f);
  sigch1.setThreshold(100.f);
  sigch1.setThresholdNumber(1);
  JPetSigCh sigch2(JPetSigCh::Trailing, 17.f);
  sigch2.setThreshold(200.f);
  sigch2.setThresholdNumber(2);
  JPetSigCh sigch3(JPetSigCh::Trailing, 43.f);
  sigch3.setThreshold(400.f);
  sigch3.setThresholdNumber(4);

  signal.addPoint(sigch1);
  signal.addPoint(sigch2);
  signal.addPoint(sigch3);

  std::map<int, double> map;
  map = signal.getTimesVsThresholdValue(JPetSigCh::Trailing);

  BOOST_REQUIRE_EQUAL( map[100], sigch1.getValue() );
  BOOST_REQUIRE_EQUAL( map[sigch2.getThreshold()], sigch2.getValue() );
  BOOST_REQUIRE_EQUAL( map[sigch3.getThreshold()], sigch3.getValue() );
  BOOST_REQUIRE_EQUAL( map[300], 0.f );
}

BOOST_AUTO_TEST_CASE(SetAndGetTSlotIndexTest) {
  JPetRawSignal signal;
  signal.setTimeWindowIndex(8);
  BOOST_CHECK(signal.getTimeWindowIndex() == 8);
}

BOOST_AUTO_TEST_CASE(SetAndGetTRefPMObjectTest) {
  JPetRawSignal signal;
  JPetPM PM;
  signal.setPM(PM);
  PM = signal.getPM();

  BOOST_CHECK(PM.getSide() == JPetPM::SideA);

}

BOOST_AUTO_TEST_CASE(SetAndGetTRefBarrelSlotObjectTest) {
  JPetRawSignal signal;
  JPetBarrelSlot barrelSlot(2, true, "bs2", 30., 2);
  signal.setBarrelSlot(barrelSlot);
  barrelSlot = signal.getBarrelSlot();

  BOOST_CHECK(barrelSlot.getID() == 2);

}

BOOST_AUTO_TEST_SUITE_END()

<commit_msg>Update JPetRawSignal tests for new methods<commit_after>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE JPetSignalTest

#include <boost/test/unit_test.hpp>
#include "../JPetRawSignal/JPetRawSignal.h"
#include "../JPetBarrelSlot/JPetBarrelSlot.h"
#include "../JPetPM/JPetPM.h"

// Tests
BOOST_AUTO_TEST_SUITE(ParamDataTS)

/* BOOST_AUTO_TEST_CASE(ToTTest) { */
/*   JPetSigCh sigch; */
/*   sigch.setType(JPetSigCh::Charge); */
/*   sigch.setValue(17.f); */
/*   JPetRawSignal signal; */
/*   signal.addPoint(sigch); */

/*   BOOST_REQUIRE_EQUAL(signal.getTOT(), 17.f); */

/*   JPetRawSignal signal2; */
/*   signal2.setTOTPoint(sigch); */

/*   BOOST_REQUIRE_EQUAL(signal2.getTOT(), 17.f); */
/* } */

//
//BOOST_AUTO_TEST_CASE(QualityOfTimeTest) {
//  JPetSignal signal;
//
//  BOOST_REQUIRE_EQUAL(signal.getQualityOfTime(), 0.f);
//}
//
//BOOST_AUTO_TEST_CASE(QualityOfEnergyTest) {
//  JPetSignal signal;
//
//  BOOST_REQUIRE_EQUAL(signal.getQualityOfEnergy(), 0.f);
//}

BOOST_AUTO_TEST_CASE(GetNumberOfPointsTest) {
  JPetRawSignal signal;

  BOOST_REQUIRE_EQUAL(signal.getNumberOfPoints(JPetSigCh::Trailing), 0);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfPoints(JPetSigCh::Leading), 0);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfLeadingEdgePoints(), 0);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfTrailingEdgePoints(), 0);

}

BOOST_AUTO_TEST_CASE(AddLeadingPointTest) {
  JPetRawSignal signal;
  const JPetSigCh sigCh;

  signal.addPoint(sigCh);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfPoints(JPetSigCh::Leading), 1);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfLeadingEdgePoints(), 1);
}

BOOST_AUTO_TEST_CASE(AddTrailingPointTest) {
  JPetRawSignal signal;
  const JPetSigCh sigCh(JPetSigCh::Trailing, 8.f);

  signal.addPoint(sigCh);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfPoints(JPetSigCh::Trailing), 1);
  BOOST_REQUIRE_EQUAL(signal.getNumberOfTrailingEdgePoints(), 1);
}

BOOST_AUTO_TEST_CASE(GetVectorOfPointsTest) {
  JPetRawSignal signal;
  JPetSigCh sigch1(JPetSigCh::Trailing, 8.f);
  sigch1.setThreshold(100.f);
  sigch1.setThresholdNumber(2);
  JPetSigCh sigch2(JPetSigCh::Trailing, 17.f);
  sigch2.setThreshold(200.f);
  sigch2.setThresholdNumber(1);

  signal.addPoint(sigch1);
  signal.addPoint(sigch2);

  BOOST_REQUIRE_EQUAL(
      signal.getPoints(JPetSigCh::Trailing, JPetRawSignal::ByThrNum).at(0).getValue(),
      17.f);

  BOOST_REQUIRE_EQUAL(
      signal.getPoints(JPetSigCh::Trailing, JPetRawSignal::ByThrValue).at(0).getValue(),
      8.f);

  BOOST_REQUIRE_EQUAL(
      signal.getPoints(JPetSigCh::Leading, JPetRawSignal::ByThrValue).size(),
      0);

}

BOOST_AUTO_TEST_CASE(GetMapOfTimesVsThrNumTest) {

  JPetRawSignal signal;
  JPetSigCh sigch1(JPetSigCh::Trailing, 8.f);
  sigch1.setThreshold(100.f);
  sigch1.setThresholdNumber(1);
  JPetSigCh sigch2(JPetSigCh::Trailing, 17.f);
  sigch2.setThreshold(200.f);
  sigch2.setThresholdNumber(2);
  JPetSigCh sigch3(JPetSigCh::Trailing, 43.f);
  sigch3.setThreshold(400.f);
  sigch3.setThresholdNumber(4);

  signal.addPoint(sigch1);
  signal.addPoint(sigch2);
  signal.addPoint(sigch3);

  std::map<int, double> map;
  map = signal.getTimesVsThresholdNumber(JPetSigCh::Trailing);

  BOOST_REQUIRE_EQUAL( map[sigch1.getThresholdNumber()], sigch1.getValue() );
  BOOST_REQUIRE_EQUAL( map[sigch2.getThresholdNumber()], sigch2.getValue() );
  BOOST_REQUIRE_EQUAL( map[sigch3.getThresholdNumber()], sigch3.getValue() );
  BOOST_REQUIRE_EQUAL( map[3], 0.f );
}

BOOST_AUTO_TEST_CASE(GetMapOfTimesVsThrValueTest) {

  JPetRawSignal signal;
  JPetSigCh sigch1(JPetSigCh::Trailing, 8.f);
  sigch1.setThreshold(100.f);
  sigch1.setThresholdNumber(1);
  JPetSigCh sigch2(JPetSigCh::Trailing, 17.f);
  sigch2.setThreshold(200.f);
  sigch2.setThresholdNumber(2);
  JPetSigCh sigch3(JPetSigCh::Trailing, 43.f);
  sigch3.setThreshold(400.f);
  sigch3.setThresholdNumber(4);

  signal.addPoint(sigch1);
  signal.addPoint(sigch2);
  signal.addPoint(sigch3);

  std::map<int, double> map;
  map = signal.getTimesVsThresholdValue(JPetSigCh::Trailing);

  BOOST_REQUIRE_EQUAL( map[100], sigch1.getValue() );
  BOOST_REQUIRE_EQUAL( map[sigch2.getThreshold()], sigch2.getValue() );
  BOOST_REQUIRE_EQUAL( map[sigch3.getThreshold()], sigch3.getValue() );
  BOOST_REQUIRE_EQUAL( map[300], 0.f );
}

BOOST_AUTO_TEST_CASE(SetAndGetTSlotIndexTest) {
  JPetRawSignal signal;
  signal.setTimeWindowIndex(8);
  BOOST_CHECK(signal.getTimeWindowIndex() == 8);
}

BOOST_AUTO_TEST_CASE(SetAndGetTRefPMObjectTest) {
  JPetRawSignal signal;
  JPetPM PM;
  signal.setPM(PM);
  PM = signal.getPM();

  BOOST_CHECK(PM.getSide() == JPetPM::SideA);

}

BOOST_AUTO_TEST_CASE(SetAndGetTRefBarrelSlotObjectTest) {
  JPetRawSignal signal;
  JPetBarrelSlot barrelSlot(2, true, "bs2", 30., 2);
  signal.setBarrelSlot(barrelSlot);
  barrelSlot = signal.getBarrelSlot();

  BOOST_CHECK(barrelSlot.getID() == 2);

}

BOOST_AUTO_TEST_CASE(GetMapOfTOTsVsThrNumOrValueTest) {

  JPetRawSignal signal;

  JPetSigCh sigch1t(JPetSigCh::Trailing, 8.f);
  sigch1t.setThreshold(400.f);
  sigch1t.setThresholdNumber(1);
  JPetSigCh sigch2t(JPetSigCh::Trailing, 17.f);
  sigch2t.setThreshold(50.f);
  sigch2t.setThresholdNumber(2);
  JPetSigCh sigch3t(JPetSigCh::Trailing, 43.f);
  sigch3t.setThreshold(100.f);
  sigch3t.setThresholdNumber(4);

  JPetSigCh sigch1l(JPetSigCh::Leading, 8.f);
  sigch1l.setThreshold(100.f);
  sigch1l.setThresholdNumber(1);
  JPetSigCh sigch2l(JPetSigCh::Leading, 17.f);
  sigch2l.setThreshold(200.f);
  sigch2l.setThresholdNumber(3);
  JPetSigCh sigch3l(JPetSigCh::Leading, 43.f);
  sigch3l.setThreshold(400.f);
  sigch3l.setThresholdNumber(4);

  signal.addPoint(sigch1t);
  signal.addPoint(sigch2t);
  signal.addPoint(sigch3t);

  signal.addPoint(sigch1l);
  signal.addPoint(sigch2l);
  signal.addPoint(sigch3l);

  std::map<int, double> map;
  map = signal.getTOTsVsThresholdNumber();

  BOOST_REQUIRE_EQUAL( map.size(), 2 );
  BOOST_REQUIRE_EQUAL( map[1], sigch1t.getValue() - sigch1l.getValue() );
  BOOST_REQUIRE_EQUAL( map[4], sigch3t.getValue() - sigch3l.getValue() );
  BOOST_REQUIRE_EQUAL( map.count(2), 0 );
  BOOST_REQUIRE_EQUAL( map.count(3), 0 );
  BOOST_CHECK_THROW( map.at(2), std::out_of_range);

  std::map<int, double> map2;
  map2 = signal.getTOTsVsThresholdValue();

  BOOST_REQUIRE_EQUAL( map2.size(), 2 );
  BOOST_REQUIRE_EQUAL( map2[100.f], sigch3t.getValue() - sigch1l.getValue() );
  BOOST_REQUIRE_EQUAL( map2[400.f], sigch1t.getValue() - sigch3l.getValue() );
  BOOST_REQUIRE_EQUAL( map2.count(50.f), 0 );
  BOOST_REQUIRE_EQUAL( map2.count(200.f), 0 );

}

BOOST_AUTO_TEST_SUITE_END()

<|endoftext|>


<commit_before>/***********************************************************************
    created:    Tue Feb 17 2009
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2013 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/RendererModules/Ogre/RenderTarget.h"
#include "CEGUI/GeometryBuffer.h"
#include "CEGUI/RenderQueue.h"
#include "CEGUI/RendererModules/Ogre/GeometryBuffer.h"

#include <OgreRenderSystem.h>
#include <OgreCamera.h>
#include <OgreViewport.h>

#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

// Start of CEGUI namespace section
namespace CEGUI
{

//----------------------------------------------------------------------------//
template <typename T>
const float OgreRenderTarget<T>::d_yfov_tan = 0.267949192431123f;

//----------------------------------------------------------------------------//
template <typename T>
OgreRenderTarget<T>::OgreRenderTarget(OgreRenderer& owner,
                                      Ogre::RenderSystem& rs) :
    d_owner(owner),
    d_renderSystem(rs),
    d_area(0, 0, 0, 0),
    d_renderTarget(0),
    d_viewport(0),
    d_ogreViewportDimensions(0, 0, 0, 0),
    d_matrix(Ogre::Matrix4::IDENTITY),
    d_matrixValid(false),
    d_viewportValid(false),
    d_viewDistance(0)
{
}

//----------------------------------------------------------------------------//
template <typename T>
OgreRenderTarget<T>::~OgreRenderTarget()
{
    delete d_viewport;
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::draw(const GeometryBuffer& buffer)
{
    buffer.draw();
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::draw(const RenderQueue& queue)
{
    queue.draw();
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::setArea(const Rectf& area)
{
    d_area = area;
    setOgreViewportDimensions(area);

    d_matrixValid = false;

    RenderTargetEventArgs args(this);
    T::fireEvent(RenderTarget::EventAreaChanged, args);
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::setOgreViewportDimensions(const Rectf& area)
{
    d_ogreViewportDimensions = area;

    if (d_viewport)
        updateOgreViewportDimensions(d_viewport->getTarget());

    d_viewportValid = false;
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::updateOgreViewportDimensions(
                                            const Ogre::RenderTarget* const rt)
{
    if (rt)
    {
        if(d_viewport)
            d_viewport->setDimensions(
            d_ogreViewportDimensions.left() / rt->getWidth(),
            d_ogreViewportDimensions.top() / rt->getHeight(),
            d_ogreViewportDimensions.getWidth() / rt->getWidth(),
            d_ogreViewportDimensions.getHeight() / rt->getHeight());
    }
}

//----------------------------------------------------------------------------//
template <typename T>
const Rectf& OgreRenderTarget<T>::getArea() const
{
    return d_area;
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::activate()
{
    if (!d_matrixValid)
        updateMatrix();

    if (!d_viewportValid)
        updateViewport();

    d_renderSystem._setViewport(d_viewport);

    d_owner.setProjectionMatrix(d_matrix);
    d_owner.setViewMatrix(Ogre::Matrix4::IDENTITY);

    RenderTarget::activate();
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::deactivate()
{
    // currently nothing to do in the basic case
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::unprojectPoint(const GeometryBuffer& buff,
                                         const glm::vec2& p_in,
                                         glm::vec2& p_out) const
{
    if (!d_matrixValid)
        updateMatrix();

    const OgreGeometryBuffer& gb = static_cast<const OgreGeometryBuffer&>(buff);

    const Ogre::Real midx = d_area.getWidth() * 0.5f;
    const Ogre::Real midy = d_area.getHeight() * 0.5f;

    // viewport matrix
    const Ogre::Matrix4 vpmat(
        midx,    0,    0,    d_area.left() + midx,
         0,    -midy,  0,    d_area.top() + midy,
         0,      0,    1,    0,
         0,      0,    0,    1
    );

    // matrices used for projecting and unprojecting points

    const Ogre::Matrix4 proj(OgreRenderer::glmToOgreMatrix(gb.getModelMatrix()) * d_matrix * vpmat);
    const Ogre::Matrix4 unproj(proj.inverse());

    Ogre::Vector3 in;

    // unproject the ends of the ray
    in.x = midx;
    in.y = midy;
    in.z = -d_viewDistance;
    const Ogre::Vector3 r1(unproj * in);
    in.x = p_in.x;
    in.y = p_in.y;
    in.z = 0;
    // calculate vector of picking ray
    const Ogre::Vector3 rv(r1 - unproj * in);

    // project points to orientate them with GeometryBuffer plane
    in.x = 0.0;
    in.y = 0.0;
    const Ogre::Vector3 p1(proj * in);
    in.x = 1.0;
    in.y = 0.0;
    const Ogre::Vector3 p2(proj * in);
    in.x = 0.0;
    in.y = 1.0;
    const Ogre::Vector3 p3(proj * in);

    // calculate the plane normal
    const Ogre::Vector3 pn((p2 - p1).crossProduct(p3 - p1));
    // calculate distance from origin
    const Ogre::Real plen = pn.length();
    const Ogre::Real dist = -(p1.x * (pn.x / plen) +
                              p1.y * (pn.y / plen) +
                              p1.z * (pn.z / plen));

    // calculate intersection of ray and plane
    const Ogre::Real pn_dot_rv = pn.dotProduct(rv);
    const Ogre::Real tmp = pn_dot_rv != 0.0 ?
                            (pn.dotProduct(r1) + dist) / pn_dot_rv :
                            0.0f;

    p_out.x = static_cast<float>(r1.x - rv.x * tmp);
    p_out.y = static_cast<float>(r1.y - rv.y * tmp);
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::updateMatrix() const
{
    // Now with updated code from OpenGL renderer

    const float w = d_area.getWidth();
    const float h = d_area.getHeight();

    // We need to check if width or height are zero and act accordingly to prevent running into issues
    // with divisions by zero which would lead to undefined values, as well as faulty clipping planes
    // This is mostly important for avoiding asserts
    const bool widthAndHeightNotZero = ( w != 0.0f ) && ( h != 0.0f);

    const float aspect = widthAndHeightNotZero ? w / h : 1.0f;
    const float midx = widthAndHeightNotZero ? w * 0.5f : 0.5f;
    const float midy = widthAndHeightNotZero ? h * 0.5f : 0.5f;
    d_viewDistance = midx / (aspect * 0.267949192431123f);

    const float nearZ = d_viewDistance * 0.5f;
    const float farZ = d_viewDistance * 2.0f;
    const float nr_sub_far = nearZ - farZ;

    Ogre::Matrix4 tmp(Ogre::Matrix4::ZERO);
    tmp[0][0] = 3.732050808f / aspect;
    tmp[0][3] = -d_viewDistance;
    tmp[1][1] = -3.732050808f;
    tmp[1][3] = d_viewDistance;
    tmp[2][2] = -((farZ + nearZ) / nr_sub_far);
    tmp[3][2] = 1.0f;
    tmp[3][3] = d_viewDistance;

    d_renderSystem._convertProjectionMatrix(tmp, d_matrix);

    d_matrixValid = true;
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::updateViewport()
{
    if (!d_viewport)
    {
#ifdef CEGUI_USE_OGRE_COMPOSITOR2

        d_viewport = OGRE_NEW Ogre::Viewport(d_renderTarget, 0, 0, 1, 1);
#else
        d_viewport = OGRE_NEW Ogre::Viewport(0, d_renderTarget, 0, 0, 1, 1, 0);
#endif // CEGUI_USE_OGRE_COMPOSITOR2

        updateOgreViewportDimensions(d_renderTarget);
    }

    d_viewport->_updateDimensions();

    d_viewportValid = true;
}

//----------------------------------------------------------------------------//
template <typename T>
Renderer& OgreRenderTarget<T>::getOwner()
{
    return d_owner;
}

//----------------------------------------------------------------------------//

} // End of  CEGUI namespace section
<commit_msg>MOD: Adding missing activationCounter reset<commit_after>/***********************************************************************
    created:    Tue Feb 17 2009
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2013 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/RendererModules/Ogre/RenderTarget.h"
#include "CEGUI/GeometryBuffer.h"
#include "CEGUI/RenderQueue.h"
#include "CEGUI/RendererModules/Ogre/GeometryBuffer.h"

#include <OgreRenderSystem.h>
#include <OgreCamera.h>
#include <OgreViewport.h>

#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

// Start of CEGUI namespace section
namespace CEGUI
{

//----------------------------------------------------------------------------//
template <typename T>
const float OgreRenderTarget<T>::d_yfov_tan = 0.267949192431123f;

//----------------------------------------------------------------------------//
template <typename T>
OgreRenderTarget<T>::OgreRenderTarget(OgreRenderer& owner,
                                      Ogre::RenderSystem& rs) :
    d_owner(owner),
    d_renderSystem(rs),
    d_area(0, 0, 0, 0),
    d_renderTarget(0),
    d_viewport(0),
    d_ogreViewportDimensions(0, 0, 0, 0),
    d_matrix(Ogre::Matrix4::IDENTITY),
    d_matrixValid(false),
    d_viewportValid(false),
    d_viewDistance(0)
{
}

//----------------------------------------------------------------------------//
template <typename T>
OgreRenderTarget<T>::~OgreRenderTarget()
{
    delete d_viewport;
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::draw(const GeometryBuffer& buffer)
{
    buffer.draw();
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::draw(const RenderQueue& queue)
{
    queue.draw();
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::setArea(const Rectf& area)
{
    d_area = area;
    setOgreViewportDimensions(area);

    d_matrixValid = false;

    RenderTargetEventArgs args(this);
    T::fireEvent(RenderTarget::EventAreaChanged, args);
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::setOgreViewportDimensions(const Rectf& area)
{
    d_ogreViewportDimensions = area;

    if (d_viewport)
        updateOgreViewportDimensions(d_viewport->getTarget());

    d_viewportValid = false;
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::updateOgreViewportDimensions(
                                            const Ogre::RenderTarget* const rt)
{
    if (rt)
    {
        if(d_viewport)
            d_viewport->setDimensions(
            d_ogreViewportDimensions.left() / rt->getWidth(),
            d_ogreViewportDimensions.top() / rt->getHeight(),
            d_ogreViewportDimensions.getWidth() / rt->getWidth(),
            d_ogreViewportDimensions.getHeight() / rt->getHeight());
    }
}

//----------------------------------------------------------------------------//
template <typename T>
const Rectf& OgreRenderTarget<T>::getArea() const
{
    return d_area;
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::activate()
{
    if (!d_matrixValid)
        updateMatrix();

    if (!d_viewportValid)
        updateViewport();

    d_renderSystem._setViewport(d_viewport);

    d_owner.setProjectionMatrix(d_matrix);
    d_owner.setViewMatrix(Ogre::Matrix4::IDENTITY);

    RenderTarget::activate();
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::deactivate()
{
    // currently nothing to do in the basic case
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::unprojectPoint(const GeometryBuffer& buff,
                                         const glm::vec2& p_in,
                                         glm::vec2& p_out) const
{
    if (!d_matrixValid)
        updateMatrix();

    const OgreGeometryBuffer& gb = static_cast<const OgreGeometryBuffer&>(buff);

    const Ogre::Real midx = d_area.getWidth() * 0.5f;
    const Ogre::Real midy = d_area.getHeight() * 0.5f;

    // viewport matrix
    const Ogre::Matrix4 vpmat(
        midx,    0,    0,    d_area.left() + midx,
         0,    -midy,  0,    d_area.top() + midy,
         0,      0,    1,    0,
         0,      0,    0,    1
    );

    // matrices used for projecting and unprojecting points

    const Ogre::Matrix4 proj(OgreRenderer::glmToOgreMatrix(gb.getModelMatrix()) * d_matrix * vpmat);
    const Ogre::Matrix4 unproj(proj.inverse());

    Ogre::Vector3 in;

    // unproject the ends of the ray
    in.x = midx;
    in.y = midy;
    in.z = -d_viewDistance;
    const Ogre::Vector3 r1(unproj * in);
    in.x = p_in.x;
    in.y = p_in.y;
    in.z = 0;
    // calculate vector of picking ray
    const Ogre::Vector3 rv(r1 - unproj * in);

    // project points to orientate them with GeometryBuffer plane
    in.x = 0.0;
    in.y = 0.0;
    const Ogre::Vector3 p1(proj * in);
    in.x = 1.0;
    in.y = 0.0;
    const Ogre::Vector3 p2(proj * in);
    in.x = 0.0;
    in.y = 1.0;
    const Ogre::Vector3 p3(proj * in);

    // calculate the plane normal
    const Ogre::Vector3 pn((p2 - p1).crossProduct(p3 - p1));
    // calculate distance from origin
    const Ogre::Real plen = pn.length();
    const Ogre::Real dist = -(p1.x * (pn.x / plen) +
                              p1.y * (pn.y / plen) +
                              p1.z * (pn.z / plen));

    // calculate intersection of ray and plane
    const Ogre::Real pn_dot_rv = pn.dotProduct(rv);
    const Ogre::Real tmp = pn_dot_rv != 0.0 ?
                            (pn.dotProduct(r1) + dist) / pn_dot_rv :
                            0.0f;

    p_out.x = static_cast<float>(r1.x - rv.x * tmp);
    p_out.y = static_cast<float>(r1.y - rv.y * tmp);
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::updateMatrix() const
{
    // Now with updated code from OpenGL renderer

    const float w = d_area.getWidth();
    const float h = d_area.getHeight();

    // We need to check if width or height are zero and act accordingly to prevent running into issues
    // with divisions by zero which would lead to undefined values, as well as faulty clipping planes
    // This is mostly important for avoiding asserts
    const bool widthAndHeightNotZero = ( w != 0.0f ) && ( h != 0.0f);

    const float aspect = widthAndHeightNotZero ? w / h : 1.0f;
    const float midx = widthAndHeightNotZero ? w * 0.5f : 0.5f;
    const float midy = widthAndHeightNotZero ? h * 0.5f : 0.5f;
    d_viewDistance = midx / (aspect * 0.267949192431123f);

    const float nearZ = d_viewDistance * 0.5f;
    const float farZ = d_viewDistance * 2.0f;
    const float nr_sub_far = nearZ - farZ;

    Ogre::Matrix4 tmp(Ogre::Matrix4::ZERO);
    tmp[0][0] = 3.732050808f / aspect;
    tmp[0][3] = -d_viewDistance;
    tmp[1][1] = -3.732050808f;
    tmp[1][3] = d_viewDistance;
    tmp[2][2] = -((farZ + nearZ) / nr_sub_far);
    tmp[3][2] = 1.0f;
    tmp[3][3] = d_viewDistance;

    d_renderSystem._convertProjectionMatrix(tmp, d_matrix);

    d_matrixValid = true;
    //! This will trigger the RenderTarget to notify all of its GeometryBuffers to regenerate their matrices
    RenderTarget::d_activationCounter = -1;
}

//----------------------------------------------------------------------------//
template <typename T>
void OgreRenderTarget<T>::updateViewport()
{
    if (!d_viewport)
    {
#ifdef CEGUI_USE_OGRE_COMPOSITOR2

        d_viewport = OGRE_NEW Ogre::Viewport(d_renderTarget, 0, 0, 1, 1);
#else
        d_viewport = OGRE_NEW Ogre::Viewport(0, d_renderTarget, 0, 0, 1, 1, 0);
#endif // CEGUI_USE_OGRE_COMPOSITOR2

        updateOgreViewportDimensions(d_renderTarget);
    }

    d_viewport->_updateDimensions();

    d_viewportValid = true;
}

//----------------------------------------------------------------------------//
template <typename T>
Renderer& OgreRenderTarget<T>::getOwner()
{
    return d_owner;
}

//----------------------------------------------------------------------------//

} // End of  CEGUI namespace section
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <boost/program_options.hpp>
#include <vector>
#include <fstream>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem.hpp>
#include <map>
#include <unordered_map>
#include <boost/functional/hash.hpp>

#include "hts_PolyATTrim.h"

namespace
{
    const size_t SUCCESS = 0;
    const size_t ERROR_IN_COMMAND_LINE = 1;
    const size_t ERROR_UNHANDLED_EXCEPTION = 2;

} // namespace

namespace bi = boost::iostreams;

int main(int argc, char** argv)
{

    const std::string program_name = "hts_PolyATTrim";
    std::string app_description =
                       "hts_PolyATTrim trims poly A and T sequences from a read.\n";
    app_description += "  It start at either the 5' end or 3' end of a fragment and expands a\n";
    app_description += "  window towards the center until the max-mismatch-errorDensity parameter is met.\n";
    app_description += "  and at least perfect-windows of are found. If the window is at least <min-trim> bases long,\n";
    app_description += "  the window will be trimmed from the read.\n";

    try
    {
        /** Define and parse the program options
         */
        namespace po = boost::program_options;
        po::options_description standard = setStandardOptions();
            // version|v ; help|h ; notes|N ; stats-file|L ; append-stats-file|A
        po::options_description input = setInputOptions();
            // read1-input|1 ; read2-input|2 ; singleend-input|U
            // tab-input|T ; interleaved-input|I
        po::options_description output = setOutputOptions(program_name);
          // force|F ; uncompressed|u ; fastq-output|f
          // tab-output|t ; interleaved-output|i ; unmapped-output|z

        po::options_description desc("Application Specific Options");

        setDefaultParamsCutting(desc);
            // no-orphans|n ; stranded|s ; min-length|m
        setDefaultParamsTrim(desc);
            // no-left|l ; no-right|r

        desc.add_options()
            ("skip_polyA,i", po::bool_switch()->default_value(false), "Skip check for polyA sequence")
            ("skip_polyT,i", po::bool_switch()->default_value(false), "Skip check for polyT sequence")
            ("window-size,w", po::value<size_t>()->default_value(6)->notifier(boost::bind(&check_range<size_t>, "window-size", _1, 1, 10000)),    "Window size in which to trim (min 1, max 10000)")
            ("max-mismatch-errorDensity,e", po::value<double>()->default_value(.30)->notifier(boost::bind(&check_range<double>, "max-mismatch-errorDensity", _1, 0.0, 1.0)), "Max percent of mismatches allowed in overlapped section (min 0.0, max 1.0)")
            ("perfect-windows,i", po::value<size_t>()->default_value(1)->notifier(boost::bind(&check_range<size_t>, "perfect-windows", _1, 0, 10000)),    "Number perfect match windows needed before a match is reported  (min 1, max 10000)")
            ("min-trim,M", po::value<size_t>()->default_value(5)->notifier(boost::bind(&check_range<size_t>, "min-trim", _1, 1, 10000)), "Min base pairs trim for AT tail (min 1, max 10000)")
            ("max-size,x", po::value<size_t>()->default_value(30)->notifier(boost::bind(&check_range<size_t>, "max-size", _1, 0, 10000)), "Max size a polyAT can be (min 0, max 10000)");

        po::options_description cmdline_options;
        cmdline_options.add(standard).add(input).add(output).add(desc);

        po::variables_map vm;
        try
        {
            po::store(po::parse_command_line(argc, argv, cmdline_options), vm); // can throw

            /** --help option
            */
            version_or_help(program_name, app_description, cmdline_options, vm);
            po::notify(vm); // throws on error, so do after help in case

            std::shared_ptr<OutputWriter> pe = nullptr;
            std::shared_ptr<OutputWriter> se = nullptr;
            outputWriters(pe, se, vm);

            std::string statsFile(vm["stats-file"].as<std::string>());
            TrimmingCounters counters(statsFile, vm["force"].as<bool>(), vm["append-stats-file"].as<bool>(), program_name, vm["notes"].as<std::string>());

            if(vm.count("read1-input")) {
                if (!vm.count("read2-input")) {
                    throw std::runtime_error("must specify both read1 and read2 input files.");
                }
                auto read1_files = vm["read1-input"].as<std::vector<std::string> >();
                auto read2_files = vm["read2-input"].as<std::vector<std::string> >();
                if (read1_files.size() != read2_files.size()) {
                    throw std::runtime_error("must have same number of input files for read1 and read2");
                }
                for(size_t i = 0; i < read1_files.size(); ++i) {
                    bi::stream<bi::file_descriptor_source> is1{check_open_r(read1_files[i]), bi::close_handle};
                    bi::stream<bi::file_descriptor_source> is2{check_open_r(read2_files[i]), bi::close_handle};
                    InputReader<PairedEndRead, PairedEndReadFastqImpl> ifp(is1, is2);
                    helper_trim(ifp, pe, se, counters, vm["min-length"].as<std::size_t>(), vm["skip_read1"].as<bool>(), vm["skip_read2"].as<bool>(), vm["skip_polyA"].as<bool>(), vm["skip_polyT"].as<bool>(), vm["min-trim"].as<std::size_t>(), vm["window-size"].as<std::size_t>(), vm["perfect-windows"].as<std::size_t>(), vm["max-size"].as<std::size_t>(), vm["max-mismatch-errorDensity"].as<double>(), vm["stranded"].as<bool>(), vm["no-left"].as<bool>(), vm["no-right"].as<bool>(), vm["no-orphans"].as<bool>() );
                }
            }
            if (vm.count("interleaved-input")) {
                auto read_files = vm["interleaved-input"].as<std::vector<std::string > >();
                for (auto file : read_files) {
                    bi::stream<bi::file_descriptor_source> inter{ check_open_r(file), bi::close_handle};
                    InputReader<PairedEndRead, InterReadImpl> ifi(inter);
                    helper_trim(ifi, pe, se, counters, vm["min-length"].as<std::size_t>(), vm["skip_read1"].as<bool>(), vm["skip_read2"].as<bool>(), vm["skip_polyA"].as<bool>(), vm["skip_polyT"].as<bool>(), vm["min-trim"].as<std::size_t>(), vm["window-size"].as<std::size_t>(), vm["perfect-windows"].as<std::size_t>(), vm["max-size"].as<std::size_t>(), vm["max-mismatch-errorDensity"].as<double>(), vm["stranded"].as<bool>(), vm["no-left"].as<bool>(), vm["no-right"].as<bool>(), vm["no-orphans"].as<bool>() );
                }
            }
            if(vm.count("singleend-input")) {
                auto read_files = vm["singleend-input"].as<std::vector<std::string> >();
                for (auto file : read_files) {
                    bi::stream<bi::file_descriptor_source> sef{ check_open_r(file), bi::close_handle};
                    InputReader<SingleEndRead, SingleEndReadFastqImpl> ifs(sef);
                    helper_trim(ifs, pe, se, counters, vm["min-length"].as<std::size_t>(), vm["skip_polyA"].as<bool>(), vm["skip_polyT"].as<bool>(), vm["min-trim"].as<std::size_t>(), vm["window-size"].as<std::size_t>(), vm["perfect-windows"].as<std::size_t>(), vm["max-size"].as<std::size_t>(), vm["max-mismatch-errorDensity"].as<double>(), vm["stranded"].as<bool>(), vm["no-left"].as<bool>(), vm["no-right"].as<bool>(), vm["no-orphans"].as<bool>() );
                }
            }
            if(vm.count("tab-input")) {
                auto read_files = vm["tab-input"].as<std::vector<std::string> > ();
                for (auto file : read_files) {
                    bi::stream<bi::file_descriptor_source> tabin{ check_open_r(file), bi::close_handle};
                    InputReader<ReadBase, TabReadImpl> ift(tabin);
                    helper_trim(ift, pe, se, counters, vm["min-length"].as<std::size_t>(), vm["skip_read1"].as<bool>(), vm["skip_read2"].as<bool>(), vm["skip_polyA"].as<bool>(), vm["skip_polyT"].as<bool>(), vm["min-trim"].as<std::size_t>(), vm["window-size"].as<std::size_t>(), vm["perfect-windows"].as<std::size_t>(), vm["max-size"].as<std::size_t>(), vm["max-mismatch-errorDensity"].as<double>(), vm["stranded"].as<bool>(), vm["no-left"].as<bool>(), vm["no-right"].as<bool>(), vm["no-orphans"].as<bool>() );
                }
            }
            if (!isatty(fileno(stdin))) {
                bi::stream<bi::file_descriptor_source> tabin {fileno(stdin), bi::close_handle};
                InputReader<ReadBase, TabReadImpl> ift(tabin);
                helper_trim(ift, pe, se, counters, vm["min-length"].as<std::size_t>(), vm["skip_read1"].as<bool>(), vm["skip_read2"].as<bool>(), vm["skip_polyA"].as<bool>(), vm["skip_polyT"].as<bool>(), vm["min-trim"].as<std::size_t>(), vm["window-size"].as<std::size_t>(), vm["perfect-windows"].as<std::size_t>(), vm["max-size"].as<std::size_t>(), vm["max-mismatch-errorDensity"].as<double>(), vm["stranded"].as<bool>(), vm["no-left"].as<bool>(), vm["no-right"].as<bool>(), vm["no-orphans"].as<bool>() );
            }
            counters.write_out();
        }
        catch(po::error& e)
        {
            std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
            return ERROR_IN_COMMAND_LINE;
        }

    }
    catch(std::exception& e)
    {
        std::cerr << "\n\tUnhandled Exception: "
                  << e.what() << std::endl;
        return ERROR_UNHANDLED_EXCEPTION;

    }

    return SUCCESS;

}
<commit_msg>finish merge<commit_after>#include <iostream>
#include <string>
#include <boost/program_options.hpp>
#include <vector>
#include <fstream>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem.hpp>
#include <map>
#include <unordered_map>
#include <boost/functional/hash.hpp>

#include "hts_PolyATTrim.h"

namespace
{
    const size_t SUCCESS = 0;
    const size_t ERROR_IN_COMMAND_LINE = 1;
    const size_t ERROR_UNHANDLED_EXCEPTION = 2;

} // namespace

namespace bi = boost::iostreams;

int main(int argc, char** argv)
{

    const std::string program_name = "hts_PolyATTrim";
    std::string app_description =
                       "hts_PolyATTrim trims poly A and T sequences from a read.\n";
    app_description += "  It start at either the 5' end or 3' end of a fragment and expands a\n";
    app_description += "  window towards the center until the max-mismatch-errorDensity parameter is met.\n";
    app_description += "  and at least perfect-windows of are found. If the window is at least <min-trim> bases long,\n";
    app_description += "  the window will be trimmed from the read.\n";

    try
    {
        /** Define and parse the program options
         */
        namespace po = boost::program_options;
        po::options_description standard = setStandardOptions();
            // version|v ; help|h ; notes|N ; stats-file|L ; append-stats-file|A
        po::options_description input = setInputOptions();
            // read1-input|1 ; read2-input|2 ; singleend-input|U
            // tab-input|T ; interleaved-input|I
        po::options_description output = setOutputOptions(program_name);
          // force|F ; uncompressed|u ; fastq-output|f
          // tab-output|t ; interleaved-output|i ; unmapped-output|z

        po::options_description desc("Application Specific Options");

        setDefaultParamsCutting(desc);
            // no-orphans|n ; stranded|s ; min-length|m
        setDefaultParamsTrim(desc);
            // no-left|l ; no-right|r

        desc.add_options()
            ("skip_polyA,i", po::bool_switch()->default_value(false), "Skip check for polyA sequence")
            ("skip_polyT,i", po::bool_switch()->default_value(false), "Skip check for polyT sequence")
            ("window-size,w", po::value<size_t>()->default_value(6)->notifier(boost::bind(&check_range<size_t>, "window-size", _1, 1, 10000)),    "Window size in which to trim (min 1, max 10000)")
            ("max-mismatch-errorDensity,e", po::value<double>()->default_value(.30)->notifier(boost::bind(&check_range<double>, "max-mismatch-errorDensity", _1, 0.0, 1.0)), "Max percent of mismatches allowed in overlapped section (min 0.0, max 1.0)")
            ("perfect-windows,i", po::value<size_t>()->default_value(1)->notifier(boost::bind(&check_range<size_t>, "perfect-windows", _1, 0, 10000)),    "Number perfect match windows needed before a match is reported  (min 1, max 10000)")
            ("min-trim,M", po::value<size_t>()->default_value(5)->notifier(boost::bind(&check_range<size_t>, "min-trim", _1, 1, 10000)), "Min base pairs trim for AT tail (min 1, max 10000)")
            ("max-size,x", po::value<size_t>()->default_value(30)->notifier(boost::bind(&check_range<size_t>, "max-size", _1, 0, 10000)), "Max size a polyAT can be (min 0, max 10000)");

        po::options_description cmdline_options;
        cmdline_options.add(standard).add(input).add(output).add(desc);

        po::variables_map vm;
        try
        {
            po::store(po::parse_command_line(argc, argv, cmdline_options), vm); // can throw

            /** --help option
            */
            version_or_help(program_name, app_description, cmdline_options, vm);
            po::notify(vm); // throws on error, so do after help in case

            std::shared_ptr<OutputWriter> pe = nullptr;
            std::shared_ptr<OutputWriter> se = nullptr;
            outputWriters(pe, se, vm);

            std::string statsFile(vm["stats-file"].as<std::string>());
            TrimmingCounters counters(statsFile, vm["force"].as<bool>(), vm["append-stats-file"].as<bool>(), program_name, vm["notes"].as<std::string>());

            if(vm.count("read1-input")) {
                if (!vm.count("read2-input")) {
                    throw std::runtime_error("must specify both read1 and read2 input files.");
                }
                auto read1_files = vm["read1-input"].as<std::vector<std::string> >();
                auto read2_files = vm["read2-input"].as<std::vector<std::string> >();
                if (read1_files.size() != read2_files.size()) {
                    throw std::runtime_error("must have same number of input files for read1 and read2");
                }
                for(size_t i = 0; i < read1_files.size(); ++i) {
                    bi::stream<bi::file_descriptor_source> is1{check_open_r(read1_files[i]), bi::close_handle};
                    bi::stream<bi::file_descriptor_source> is2{check_open_r(read2_files[i]), bi::close_handle};
                    InputReader<PairedEndRead, PairedEndReadFastqImpl> ifp(is1, is2);
                    helper_trim(ifp, pe, se, counters, vm["min-length"].as<std::size_t>(), vm["skip_polyA"].as<bool>(), vm["skip_polyT"].as<bool>(), vm["min-trim"].as<std::size_t>(), vm["window-size"].as<std::size_t>(), vm["perfect-windows"].as<std::size_t>(), vm["max-size"].as<std::size_t>(), vm["max-mismatch-errorDensity"].as<double>(), vm["stranded"].as<bool>(), vm["no-left"].as<bool>(), vm["no-right"].as<bool>(), vm["no-orphans"].as<bool>() );
                }
            }
            if (vm.count("interleaved-input")) {
                auto read_files = vm["interleaved-input"].as<std::vector<std::string > >();
                for (auto file : read_files) {
                    bi::stream<bi::file_descriptor_source> inter{ check_open_r(file), bi::close_handle};
                    InputReader<PairedEndRead, InterReadImpl> ifi(inter);
                    helper_trim(ifi, pe, se, counters, vm["min-length"].as<std::size_t>(), vm["skip_polyA"].as<bool>(), vm["skip_polyT"].as<bool>(), vm["min-trim"].as<std::size_t>(), vm["window-size"].as<std::size_t>(), vm["perfect-windows"].as<std::size_t>(), vm["max-size"].as<std::size_t>(), vm["max-mismatch-errorDensity"].as<double>(), vm["stranded"].as<bool>(), vm["no-left"].as<bool>(), vm["no-right"].as<bool>(), vm["no-orphans"].as<bool>() );
                }
            }
            if(vm.count("singleend-input")) {
                auto read_files = vm["singleend-input"].as<std::vector<std::string> >();
                for (auto file : read_files) {
                    bi::stream<bi::file_descriptor_source> sef{ check_open_r(file), bi::close_handle};
                    InputReader<SingleEndRead, SingleEndReadFastqImpl> ifs(sef);
                    helper_trim(ifs, pe, se, counters, vm["min-length"].as<std::size_t>(), vm["skip_polyA"].as<bool>(), vm["skip_polyT"].as<bool>(), vm["min-trim"].as<std::size_t>(), vm["window-size"].as<std::size_t>(), vm["perfect-windows"].as<std::size_t>(), vm["max-size"].as<std::size_t>(), vm["max-mismatch-errorDensity"].as<double>(), vm["stranded"].as<bool>(), vm["no-left"].as<bool>(), vm["no-right"].as<bool>(), vm["no-orphans"].as<bool>() );
                }
            }
            if(vm.count("tab-input")) {
                auto read_files = vm["tab-input"].as<std::vector<std::string> > ();
                for (auto file : read_files) {
                    bi::stream<bi::file_descriptor_source> tabin{ check_open_r(file), bi::close_handle};
                    InputReader<ReadBase, TabReadImpl> ift(tabin);
                    helper_trim(ift, pe, se, counters, vm["min-length"].as<std::size_t>(), vm["skip_polyA"].as<bool>(), vm["skip_polyT"].as<bool>(), vm["min-trim"].as<std::size_t>(), vm["window-size"].as<std::size_t>(), vm["perfect-windows"].as<std::size_t>(), vm["max-size"].as<std::size_t>(), vm["max-mismatch-errorDensity"].as<double>(), vm["stranded"].as<bool>(), vm["no-left"].as<bool>(), vm["no-right"].as<bool>(), vm["no-orphans"].as<bool>() );
                }
            }
            if (!isatty(fileno(stdin))) {
                bi::stream<bi::file_descriptor_source> tabin {fileno(stdin), bi::close_handle};
                InputReader<ReadBase, TabReadImpl> ift(tabin);
                helper_trim(ift, pe, se, counters, vm["min-length"].as<std::size_t>(), vm["skip_polyA"].as<bool>(), vm["skip_polyT"].as<bool>(), vm["min-trim"].as<std::size_t>(), vm["window-size"].as<std::size_t>(), vm["perfect-windows"].as<std::size_t>(), vm["max-size"].as<std::size_t>(), vm["max-mismatch-errorDensity"].as<double>(), vm["stranded"].as<bool>(), vm["no-left"].as<bool>(), vm["no-right"].as<bool>(), vm["no-orphans"].as<bool>() );
            }
            counters.write_out();
        }
        catch(po::error& e)
        {
            std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
            return ERROR_IN_COMMAND_LINE;
        }

    }
    catch(std::exception& e)
    {
        std::cerr << "\n\tUnhandled Exception: "
                  << e.what() << std::endl;
        return ERROR_UNHANDLED_EXCEPTION;

    }

    return SUCCESS;

}
<|endoftext|>