#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   fChargevsNbins;
  static const Int_t   fAbsTimeNbins;
  static const Axis_t  fAbsTimeFirst;
  static const Axis_t  fAbsTimeLast;
  static const Int_t   fRelTimeNbins;
  static const Axis_t  fRelTimeFirst;
  static const Axis_t  fRelTimeLast;
  static const Float_t fProbLimit;
  static const Int_t   fNDFLimit;  
  
  Int_t fPixId;                  // Pixel Nr

  TArrayF *fHiGains;             //->
  TArrayF *fLoGains;             //->

  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* fHRelTimeHiGain;         //-> Mean arrival time in number of FADC sice
  TH1I* fHChargevsNHiGain;       //-> Summed Charge vs. Event Nr. 
                          
  TH1F* fHChargeLoGain;          //-> Summed FADC slices Low Gain
  TH1F* fHAbsTimeLoGain;         //-> Mean arrival time in number of FADC sice
  TH1F* fHRelTimeLoGain;         //-> Mean arrival time in number of FADC sice
  TH1I* fHChargevsNLoGain;       //-> Summed Charge vs. Event Nr. 

  TH1F* fHPSD;                   // Power spectrum density of fHBlindPixelChargevsN
  
  TF1* fChargeGausFit;
  TF1* fRelTimeGausFit;  
  
  TPaveText *fFitLegend;  
  
  Int_t fTotalEntries;           // Number of entries

  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;
  
  Double_t fRelTimeChisquare;
  Double_t fRelTimeProb;
  Int_t    fRelTimeNdf;
  Double_t fRelTimeMean;
  Double_t fRelTimeMeanErr;
  Double_t fRelTimeSigma;

  Float_t  fAbsTimeMean;
  Float_t  fAbsTimeMeanErr;  
  Float_t  fAbsTimeRms;
  
  Float_t  fRelTimeLowerFitRangeHiGain;
  Float_t  fRelTimeUpperFitRangeHiGain;
  Float_t  fRelTimeLowerFitRangeLoGain;
  Float_t  fRelTimeUpperFitRangeLoGain;

  Float_t  fAbsTimeFirstHiGain;
  Float_t  fAbsTimeFirstLoGain;
  Float_t  fAbsTimeLastHiGain;
  Float_t  fAbsTimeLastLoGain;
  
  Byte_t   fFlags;

  enum     { kUseLoGain, kChargeFitOK, kTimeFitOK };
  
  virtual void DrawLegend();
  
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 Double_t GetRelTimeMean()      const { return fRelTimeMean;     }
  const Double_t GetRelTimeMeanErr()    const { return fRelTimeMeanErr;     }
  const Double_t GetRelTimeSigma()     const { return fRelTimeSigma;    }
  const Double_t GetRelTimeChiSquare() const { return fRelTimeChisquare;}
  const Double_t GetRelTimeProb()      const { return fRelTimeProb;     }
  const Int_t    GetRelTimeNdf()       const { return fRelTimeNdf;      }   


  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;  }
  
  const TH1F *GetHRelTime()                  { return fHRelTimeHiGain;  }
  const TH1F *GetHRelTime()            const { return fHRelTimeHiGain;  }
  
  const TH1I *GetHChargevsN()                { return fHChargevsNHiGain;}
  const TH1I *GetHChargevsN()          const { return fHChargevsNHiGain;}

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

  Bool_t UseLoGain();

  Bool_t IsChargeFitOK()               const;
  Bool_t IsTimeFitOK()                 const;      
  Bool_t IsUseLoGain()                 const;
  Bool_t IsEmpty()                     const;
  
  // Fill histos
  Bool_t FillChargeLoGain(Float_t q);
  Bool_t FillAbsTimeLoGain(Float_t t);
  Bool_t FillRelTimeLoGain(Float_t t);
  Bool_t FillChargevsNLoGain(Float_t q, Int_t n);

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

  Bool_t FillPointInGraph(Float_t qhi, Float_t qlo);

  Bool_t SetupFill(const MParList *pList);
  Bool_t Fill(const MParContainer *, const Stat_t w=1) { return kTRUE; }
  
  // Fits
  Bool_t FitCharge(Option_t *option="RQ0");  
  Bool_t FitTime(Option_t *option="RQ0");    

  void   FitHiGainvsLoGain();

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

  // Others
  virtual void CutAllEdges();

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

#endif
