/*
$Id: GslHistogram.hh 2001 2009-03-16 06:28:16Z jisuzuki $
 */

#ifndef GSLHISTOGRAM
#define GSLHISTOGRAM

#include "Header.hh"
#include <gsl/gsl_histogram.h>
#include "CppToPython.hh"

//! converter from event type data to histogram in 1d
/*! This class is a converter from a set of event data
  to a histogram data.

  The procedure of conversion is following,

  (1) The boundary of the histogram bin is set with
  the constructor of this class.
  (2) The event data is filled into the histogram bins with
  "Increment(Double,Double)" or "Increment(std::vector<Double>)".
  (3) The result of the conversion is obtained with
  "PutHistogram()".

 */

class GslHistogram {
private:
  gsl_histogram **h;
  void Set( Double *Bin, UInt4 Size );
  PyObject *VtoL( std::vector<Double> v );
  UInt4 NumOfMulTh;
public:

  GslHistogram( Double *Bin, UInt4 Size, UInt4 _NumOfMulTh=1 );
  /*!< Constructor.
    The bins of the histogram will be set with the arguments.
    The each value of the array is the boundary of the bins.
   */
 ~GslHistogram();
  /*!< Destructor*/

  UInt4 PutHistSize(){ return (UInt4)(gsl_histogram_bins( h[0] )); }
  /*!< Returns the number of bins.*/

  PyObject *PutHistogramList(){ return VtoL( PutHistogram() );}
  /*!< This method returns a vector object.
    The vector object has the contents of each bin of the histogram.
   */
  std::vector<Double> PutHistogram();
  /*!< This method returns a vector object.
    The vector object has the contents of each bin of the histogram.
   */

  std::vector<Double> PutHistogramErr();
  /*!< This method returns a vector object.
    The vector object has the error values corresponding with the vector
    returned by "PutHistogram()".
   */
  PyObject *PutHistogramErrList(){ return VtoL( PutHistogramErr() ); }
  /*!< This method returns a vector object.
    The vector object has the error values corresponding with the vector
    returned by "PutHistogram()".
  */
  Int4 Increment( Double x, UInt4 ThNum=0, Double Weight=1.0 );
  /*!<
    The second argument is ommitted,
    this method updates the histogram by adding 1.0 to the bin
    whose range contains the value of "x".
    The second value is not ommitted, this method increase the value
    by the number of "Weight".
   */

  void Increment( std::vector<Double> x, UInt4 ThNum=0 );
  /*!< Each value of x is filled into the histogram.
    "Increment(Double,1.0)" is executed in this method.
   */
  void Increment( std::vector<Int4> x, UInt4 ThNum=0 );
  /*!< Each value of x is filled into the histogram.
    "Increment(Double,1.0)" is executed in this method.
   */

  void Dump(){ gsl_histogram_fprintf( stdout, h[0], "%g", "%g"); }
  /*!< This method dumps All data stored in this class to stdout. */
  //void Reset(){ gsl_histogram_reset( h ); }
  void Reset();
  /*!< This method clears
    all data stored with "Increment(double,double)".*/
  gsl_histogram *PutHistPointer( UInt4 ThNum=0 ){ return h[ThNum]; }
  /*!< The return value of this method is the pointer of "gsl_histogram".
    You can use all functions prepared in the gsl-library with the pointer.
   */

  std::vector<Double> PutBin();
  /*!<
    Returns bin boundaries.
    The size of returnd vector is PutHistSize()+1.
   */
  PyObject *PutBinList(){ return VtoL( PutBin() ); }
  /*!<
    Returns bin boundaries.
    The size of returnd list is PutHistSize()+1.
   */

  Double PutHistogramSum();
  /*!<
    Returns the sum of all bin values.
   */
};

#endif
