#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:

  static const Int_t   fChargeNbinsHiGain;
  static const Int_t   fChargeNbinsLoGain;
  static const Int_t   fAbsTimeNbins;
  static const Axis_t  fAbsTimeFirst;
  static const Axis_t  fAbsTimeLast;
  static const Float_t fProbLimit;
  static const Int_t   fNDFLimit;  

  static const Axis_t  fNyquistFreq;
  static const Axis_t  fMinFreq;
  static const Int_t   fPSDNbins;
  
  Int_t fPixId;                  // Pixel Nr

  TProfile* fHivsLoGain;         //->

  Double_t fOffset;
  Double_t fSlope;

protected:

  TH1F* fHChargeHiGain;          //-> Summed FADC slices High Gain
  TH1F* fHAbsTimeHiGain;         //-> Mean arrival time in number of FADC sice
                          
  TH1F* fHChargeLoGain;          //-> Summed FADC slices Low Gain
  TH1F* fHAbsTimeLoGain;         //-> Mean arrival time in number of FADC sice

  TArrayF* fPSDHiGain;           //-> Power spectrum density of fHiGains
  TArrayF* fPSDLoGain;           //-> Power spectrum density of fLoGains
  
  TF1* fChargeGausFit;           //->

  TH1F* fHPSD;                   //-> 
  TF1*  fPSDExpFit;              //->
  
  TArrayF *fHiGains;             //->
  TArrayF *fLoGains;             //->
  TArrayF *fChargeXaxis;         //
  TArrayF *fPSDXaxis;            //
  
  TPaveText *fFitLegend;         //->
  
  Int_t fTotalEntries;           // Number of entries
  Int_t fCurrentSize;
  
  Axis_t  fChargeFirstHiGain;
  Axis_t  fChargeLastHiGain;
  Axis_t  fChargeFirstLoGain;
  Axis_t  fChargeLastLoGain;

  Double_t fChargeChisquare;
  Double_t fChargeProb;
  Int_t    fChargeNdf;

  Double_t fChargeMean;
  Double_t fChargeMeanErr;
  Double_t fChargeSigma;
  Double_t fChargeSigmaErr;
  
  Float_t  fAbsTimeMean;
  Float_t  fAbsTimeMeanErr;  
  Float_t  fAbsTimeRms;
  
  Float_t  fAbsTimeFirstHiGain;
  Float_t  fAbsTimeFirstLoGain;
  Float_t  fAbsTimeLastHiGain;
  Float_t  fAbsTimeLastLoGain;

  Float_t  fPSDProb;
  
  Byte_t   fFlags;

  enum     { kUseLoGain, kChargeFitOK, kOscillating };
  
  virtual void DrawLegend();
  virtual void CreateChargeXaxis(Int_t n);
  virtual void CreatePSDXaxis(Int_t n);
  virtual void CutArrayBorder(TArrayF *array);
  
public:

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

  void Clear(Option_t *o="");
  void Reset();  

  void ChangeHistId(Int_t i);
  
  // Setters
  void SetUseLoGain(Bool_t b = kTRUE);
  
  // Getters
  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 GetChargeChiSquare()  const { return fChargeChisquare; }
  const Double_t GetChargeProb()       const { return fChargeProb;      }  
  const Int_t    GetChargeNdf()        const { return fChargeNdf;       }   

  const Float_t  GetAbsTimeFirstHiGain() const { return fAbsTimeFirstHiGain; }
  const Float_t  GetAbsTimeFirstLoGain() const { return fAbsTimeFirstLoGain; }
  const Float_t  GetAbsTimeLastHiGain()  const { return fAbsTimeLastHiGain;  }
  const Float_t  GetAbsTimeLastLoGain()  const { return fAbsTimeLastLoGain;  }

  const Float_t  GetAbsTimeMean()      const { return fAbsTimeMean;     }
  const Float_t  GetAbsTimeMeanErr()   const { return fAbsTimeMeanErr;   }  
  const Float_t  GetAbsTimeRms()       const { return fAbsTimeRms;      }
  
  const TH1F *GetHCharge()                   { return fHChargeHiGain;   }
  const TH1F *GetHCharge()             const { return fHChargeHiGain;   } 

  const TH1F *GetHAbsTime()                  { return fHAbsTimeHiGain;  }
  const TH1F *GetHAbsTime()            const { return fHAbsTimeHiGain;  }
  
  Double_t GetOffset()                 const { return fOffset;          }
  Double_t GetSlope()                  const { return fSlope;           }

  Bool_t UseLoGain();
  Bool_t CheckOscillations();
  
  Bool_t IsChargeFitOK()               const;
  Bool_t IsOscillating();
  Bool_t IsUseLoGain()                 const;
  Bool_t IsEmpty()                     const;
  
  // Fill histos
  Bool_t FillChargeLoGain(Float_t q);
  Bool_t FillAbsTimeLoGain(Float_t t);

  Bool_t FillChargeHiGain(Float_t q);
  Bool_t FillAbsTimeHiGain(Float_t t);

  Bool_t FillGraphs(Float_t qhi, Float_t qlo);

  // Fits
  Bool_t FitCharge(Option_t *option="RQ0");  

  void   FitHiGainvsLoGain();

  // Draws
  virtual void Draw(Option_t *option="");
  TObject *DrawClone(Option_t *option="") const;
  
  // Prints
  void PrintChargeFitResult();

  // Others
  virtual void CutAllEdges();

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

#endif
