#ifndef MARS_MHCalibrationPixel
#define MARS_MHCalibrationPixel

#ifndef MARS_MH
#include "MH.h"
#endif

class TArrayF;
class TH1F;
class TH1I;
class TF1;
class TProfile;
class TPaveText;

class MHCalibrationPixel : public MH
{

private:

  Int_t fPixId;                  // Pixel Nr
  Int_t fTotalEntries;           // Number of entries

  TArrayF *fHiGains;
  TArrayF *fLoGains;

protected:

  TH1F* fHChargeHiGain;          // Summed FADC slices High Gain
  TH1I* fHTimeHiGain;            // Mean arrival time in number of FADC sice
  TH1I* fHChargevsNHiGain;       // Summed Charge vs. Event Nr. 
  
  TH1F* fHChargeLoGain;          // Summed FADC slices Low Gain
  TH1I* fHTimeLoGain;            // Mean arrival time in number of FADC sice
  TH1I* fHChargevsNLoGain;       // Summed Charge vs. Event Nr. 

  TF1* fChargeGausFit;
  TF1* fTimeGausFit;
  
  TProfile* fHivsLoGain;

  TPaveText *fFitLegend;  
  
  Axis_t  fLowerFitRange;
  Axis_t  fChargeFirstHiGain;
  Axis_t  fChargeLastHiGain;
  Int_t   fChargeNbinsHiGain;

  Axis_t  fChargeFirstLoGain;
  Axis_t  fChargeLastLoGain;
  Int_t   fChargeNbinsLoGain;

  Double_t fChargeChisquare;
  Double_t fChargeProb;
  Int_t    fChargeNdf;

  Double_t fChargeMean;
  Double_t fChargeMeanErr;
  Double_t fChargeSigma;
  Double_t fChargeSigmaErr;
  
  Double_t fTimeChisquare;
  Double_t fTimeProb;
  Int_t    fTimeNdf;

  Double_t fTimeMean;
  Double_t fTimeSigma;

  Byte_t   fTimeLowerFitRangeHiGain;
  Byte_t   fTimeUpperFitRangeHiGain;
  Byte_t   fTimeLowerFitRangeLoGain;
  Byte_t   fTimeUpperFitRangeLoGain;
  
  Bool_t fUseLoGain;
  Bool_t fFitOK;

  Double_t fOffset;
  Double_t fSlope;
  
  virtual void DrawLegend();
  
public:

  MHCalibrationPixel(const char *name=NULL, const char *title=NULL);
  ~MHCalibrationPixel();

  void ChangeHistId(Int_t i);
  
  // Setters
  void   SetPointInGraph(Float_t qhi, Float_t qlo);
  void   SetUseLoGain(Bool_t b = kTRUE)                { fUseLoGain = b; }

  void SetTimeFitRangesHiGain(Byte_t low, Byte_t up) { fTimeLowerFitRangeHiGain = low,
                                               fTimeUpperFitRangeHiGain = up ;  }
  void SetTimeFitRangesLoGain(Byte_t low, Byte_t up) { fTimeLowerFitRangeLoGain = low,
                                               fTimeUpperFitRangeLoGain = up ;  }

  void SetLowerFitRange(Axis_t min)                {  fLowerFitRange = min; }

  // Getters
  const TH1F *GetHCharge()                 { return fHChargeHiGain;    }
  const TH1F *GetHCharge() const           { return fHChargeHiGain;    }

  const Double_t GetChargeMean()     const { return fChargeMean;    }
  const Double_t GetChargeMeanErr()  const { return fChargeMeanErr; }
  const Double_t GetChargeSigma()    const { return fChargeSigma;   }
  const Double_t GetChargeSigmaErr() const { return fChargeSigmaErr; }
  const Double_t GetArea()           const;
  const Double_t GetAreaErr()        const;

  const Double_t GetChargeChiSquare() const { return fChargeChisquare; }
  const Double_t GetChargeProb()      const { return fChargeProb;      }  
  const Int_t    GetChargeNdf()       const { return fChargeNdf;       }   

  const Double_t GetTimeMean()        const { return fTimeMean;  }
  const Double_t GetTimeSigma()       const { return fTimeSigma; }

  const Byte_t   GetTimeLowerFitRangeHiGain()  const { return fTimeLowerFitRangeHiGain;  }
  const Byte_t   GetTimeUpperFitRangeHiGain()  const { return fTimeUpperFitRangeHiGain;  }
  const Byte_t   GetTimeLowerFitRangeLoGain()  const { return fTimeLowerFitRangeLoGain;  }
  const Byte_t   GetTimeUpperFitRangeLoGain()  const { return fTimeUpperFitRangeLoGain;  }
  
  const Double_t GetTimeChiSquare()     const { return fTimeChisquare; }
  const Double_t GetTimeProb()        const { return fTimeProb;      }
  const Int_t    GetTimeNdf()         const { return fTimeNdf;       }   
  
  const TH1I *GetHTime()                    { return fHTimeHiGain; }
  const TH1I *GetHTime()              const { return fHTimeHiGain; }
  
  const TH1I *GetHChargevsN()               { return fHChargevsNHiGain; }
  const TH1I *GetHChargevsN()         const { return fHChargevsNHiGain; }

  Double_t GetOffset()  { return fOffset; }
  Double_t GetSlope()   { return fSlope;  }

  Bool_t UseLoGain();

  Bool_t IsFitOK() { return fFitOK; }
  Bool_t IsEmpty();
  
  // Fill histos
  Bool_t FillChargeLoGain(Float_t q);
  Bool_t FillTimeLoGain(Int_t t);
  Bool_t FillChargevsNLoGain(Float_t q, Int_t n);

  Bool_t FillChargeHiGain(Float_t q);
  Bool_t FillTimeHiGain(Int_t t);
  Bool_t FillChargevsNHiGain(Float_t q, Int_t n);

  // Fits
  Bool_t FitChargeHiGain(Option_t *option="RQ0");  
  Bool_t FitTimeHiGain(Axis_t rmin=0, Axis_t rmax=0, Option_t *option="RQ0");    

  Bool_t FitChargeLoGain(Option_t *option="RQ0");  
  Bool_t FitTimeLoGain(Axis_t rmin=0, Axis_t rmax=0, Option_t *option="RQ0");    

  void   FitHiGainvsLoGain();

  // Draws
  virtual void Draw(Option_t *option="");

  // Prints
  void PrintChargeFitResult();
  void PrintTimeFitResult();  

  // Others
  virtual void CutAllEdges();
  virtual void Reset();

  ClassDef(MHCalibrationPixel, 1)     // Histograms for each calibrated pixel
};

#endif
