#ifndef MARS_MHCalibrationChargeCam
#define MARS_MHCalibrationChargeCam

#ifndef ROOT_TObjArray
#include <TObjArray.h>
#endif

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

class TText;
class MRawEvtData;
class MGeomCam;
class MBadPixelsCam;
class MBadPixelsPix;
class MCalibrationChargeCam;
class MCalibrationChargePix;
class MHCalibrationChargeHiGainPix;
class MHCalibrationChargeLoGainPix;
class MHCalibrationChargeCam : public MH, public MCamEvent
{
private:

  static const Float_t fgNumHiGainSaturationLimit;   // The default number of fNumHiGainSaturationLimit
  static const Float_t fgNumLoGainSaturationLimit;   // The default number of fNumLoGainSaturationLimit

  Float_t fNumHiGainSaturationLimit;      // The rel. number of saturated higain FADC slices in the whole run upon which the pixel is called saturated
  Float_t fNumLoGainSaturationLimit;      // The rel. number of saturated logain FADC slices in the whole run upon which the pixel is called saturated
  
  TObjArray *fHiGainArray;                           //-> Array of MHCalibrationChargePix with hists
  TObjArray *fLoGainArray;                           //-> Array of MHCalibrationChargePix with hists
  MHCalibrationChargeHiGainPix *fAverageHiGainInnerPix;   //-> One MHCalibrationChargeHiGainPix with the average of all inner pixels
  MHCalibrationChargeLoGainPix *fAverageLoGainInnerPix;   //-> One MHCalibrationChargeLoGainPix with the average of all inner pixels
  MHCalibrationChargeHiGainPix *fAverageHiGainOuterPix;   //-> One MHCalibrationChargeHiGainPix with the average of all outer pixels
  MHCalibrationChargeLoGainPix *fAverageLoGainOuterPix;   //-> One MHCalibrationChargeLoGainPix with the average of all outer pixels

  MCalibrationChargeCam  *fCam;                      //!  Class holding the results
  MRawEvtData            *fRawEvt;                   //!  Raw event data (time slices)
  MGeomCam               *fGeom;                     //!  MAGIC geometry
  MBadPixelsCam          *fBadPixels;                //!  Bad Pixels

  Int_t fNumInnerPixels;
  Int_t fNumOuterPixels;
  Int_t fNumExcluded;

  Bool_t  fAverageInnerSat;
  Bool_t  fAverageOuterSat;  
  
  Float_t fAverageInnerPixSigma;
  Float_t fAverageOuterPixSigma;  
  
  Float_t fAverageInnerPixSigmaErr;
  Float_t fAverageOuterPixSigmaErr;  

  Float_t fAverageInnerPixRelSigma;
  Float_t fAverageOuterPixRelSigma;  
  
  Float_t fAverageInnerPixRelSigmaErr;
  Float_t fAverageOuterPixRelSigmaErr;  

  void FinalizeHiGainHists(MHCalibrationChargeHiGainPix &hist, MCalibrationChargePix &pix, MBadPixelsPix &bad);
  void FinalizeLoGainHists(MHCalibrationChargeLoGainPix &hist, MCalibrationChargePix &pix, MBadPixelsPix &bad);
  void FinalizeAveragePix (MCalibrationChargePix &pix, Int_t npix,
                           Float_t &sigma, Float_t &sigmaerr,
                           Float_t &relsigma, Float_t &relsigmaerr, 
                           Bool_t &b);
  void DrawAverageSigma(Bool_t sat, Bool_t inner,
                        Float_t sigma, Float_t sigmaerr,
                        Float_t relsigma, Float_t relsigmaerr) const; 
  
public:

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

  void SetNumHiGainSaturationLimit( const Float_t lim=fgNumHiGainSaturationLimit) { fNumHiGainSaturationLimit = lim; }
  void SetNumLoGainSaturationLimit( const Float_t lim=fgNumLoGainSaturationLimit) { fNumLoGainSaturationLimit = lim; }

  Float_t GetNumHiGainSaturationLimit()                       const  { return fNumHiGainSaturationLimit; }
  Float_t GetNumLoGainSaturationLimit()                       const  { return fNumLoGainSaturationLimit; }

        MHCalibrationChargeHiGainPix &operator[](UInt_t i);
  const MHCalibrationChargeHiGainPix &operator[](UInt_t i)    const;

        MHCalibrationChargeLoGainPix &operator()(UInt_t i);
  const MHCalibrationChargeLoGainPix &operator()(UInt_t i)    const;

        MHCalibrationChargeHiGainPix  &GetAverageHiGainInnerPix()        { return *fAverageHiGainInnerPix; }
  const MHCalibrationChargeHiGainPix  &GetAverageHiGainInnerPix()  const { return *fAverageHiGainInnerPix; }

        MHCalibrationChargeLoGainPix  &GetAverageLoGainInnerPix()        { return *fAverageLoGainInnerPix; }
  const MHCalibrationChargeLoGainPix  &GetAverageLoGainInnerPix()  const { return *fAverageLoGainInnerPix; }

        MHCalibrationChargeHiGainPix  &GetAverageHiGainOuterPix()        { return *fAverageHiGainOuterPix; }
  const MHCalibrationChargeHiGainPix  &GetAverageHiGainOuterPix()  const { return *fAverageHiGainOuterPix; }

        MHCalibrationChargeLoGainPix  &GetAverageLoGainOuterPix()        { return *fAverageLoGainOuterPix; }
  const MHCalibrationChargeLoGainPix  &GetAverageLoGainOuterPix()  const { return *fAverageLoGainOuterPix; }

  Bool_t SetupFill(const MParList *pList);
  Bool_t ReInit   (      MParList *pList);
  Bool_t Fill     (const MParContainer *par, const Stat_t w=1);
  Bool_t Finalize ( );
  
  // Draw
  void Draw(const Option_t *opt);

  Bool_t GetPixelContent ( Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type=0) const;
  void   DrawPixelContent( Int_t num )  const;    

  ClassDef(MHCalibrationChargeCam, 1)	// Container for calibration information of the camera
};

#endif









