/*
$Id: DoubleBinArrange.hh 2273 2011-06-22 09:38:14Z jisuzuki $
*/


#ifndef DOUBLEBINARRANGE
#define DOUBLEBINARRANGE

#include "Header.hh"
#include "HeaderBase.hh"
#include "NeutronVector.hh"
//#include <float.h>

//!Converter of bin width of one-dimensional histograms
/*!This class is a converter of bin width of one-dimensional histogram
stored. This class will be called in ElementContainer.
Only four steps are required to convert it.
1, constructor.
2, SetHist().
3, Binning() or Averaging().
4, PutResultValue() and PutResultError().
If you use the method of "Binning()" in the procedure,
  this class will calculate simple addition concerning with its errors.
  If you use "Averaging()", simple averaging will be done.
*/


class DoubleBinArrange
{
private:
  UInt4 SourceBinNumber;
  UInt4 ResultBinNumber;
  std::vector<Double> SourceBinMin;
  std::vector<Double> SourceBinMax;
  std::vector<Double> SourceValue;
  std::vector<Double> SourceError;
  std::vector<Double> ResultBinMin;
  std::vector<Double> ResultBinMax;
  std::vector<Double> ResultValue;
  std::vector<Double> ResultError;
  NeutronVector< std::vector<Double>, HeaderBase > * CPercent;
  NeutronVector< std::vector<UInt4>, HeaderBase > * CNumber;

  void MakeArray();
  Int4 SelectOrigBin( Double value );
  Int4 SelectResultBin( Double value );

  void SetSourceBinBoundary( const std::vector<Double> &array );
  void SetResultBinBoundary( const std::vector<Double> &array );
  void SetSourceValue( const std::vector<Double> &array );
  void SetSourceError( const std::vector<Double> &array );
  void FormatBin();

  UInt4 AveFlag;
  UInt4 BinFlag;

public:
  //! Constructor.
  /*!
    @param SourceBinNumber is the number of bins of input histogram.
    @param ResultBinNumber is the number of bins of output histogram.
  */
  DoubleBinArrange( UInt4 SourceBinNumber,
                    UInt4 ResultBinNumber );


 ~DoubleBinArrange();

  void SetHist( const std::vector<Double> &SourceBinBoundary,
                const std::vector<Double> &SourceValue,
                const std::vector<Double> &SourceError,
                const std::vector<Double> &ResultBinBoundary );
  /*!<
    @param SourceBinBoundary is the boundary values of bins of input histogram.
    @param SourceValue is the hights of each bin of input histogram.
    @param SourceError is the error values of each bin of input histogram.
    @param ResultBinBoundary is the boundary values of bins of output histogram.

    The size of vectors of the arguments should be have the following
    relationship, SourceValue.size() = SourceError.size() = SourceBinBoundary.size()-1.
  */

  std::vector<Double> &PutResultBinMin();
  /*!<
    @return the lower boundary values of bins of output histogram.
  */
  std::vector<Double> &PutResultBinMax();
  /*!<
    @return the upper boundary values of bins of output histogram.
  */
  std::vector<Double> PutResultBin();
  /*!<
    @return the center of each bin of the output histogram.
  */
  std::vector<Double> PutResultBinVector();
  /*!<
    @return the values of bin boundaries of the output histogram.
    The values in the returned vector is the same as those in "ResultBinBoundary".
  */

  std::vector<Double> &PutResultValue();
  /*!<
    @return result histogram values converted in this class.
  */
  std::vector<Double> &PutResultError();
  /*!<
    @return result histogram error values converted in this class.
  */

  void Binning( Int4 DefaultErrorValue=0 );
  /*!<Execute simple binning, see the manual of this class. */
  void Averaging();
  /*!<Execute simple averaging, see the manual of this class. */
};

#endif

