#ifndef MARS_MCalibrationChargeCam
#define MARS_MCalibrationChargeCam

#ifndef MARS_MCalibrationCam
#include "MCalibrationCam.h"
#endif

class TH1D;
class TH2D;

class MCalibrationChargeBlindPix;
class MCalibrationChargePINDiode;
class MCalibrationChargePix;
class MCalibrationChargeCam : public MCalibrationCam
{
private:
  
  static const Float_t fgAverageQE;              //! Default for fAverageQE              (now set to: 0.18)
  static const Float_t fgAverageQEErr;           //! Default for fAverageQEErr           (now set to: 0.02)
  static const Float_t fgConvFFactorRelErrLimit; //! Default for fConvFFactorRelErrLimit (now set to: 0.35)
  static const Float_t fgPheFFactorRelErrLimit;  //! Default for fPheFFactorRelErrLimit  (now set to: 5.)
  
  Float_t fAverageQE;                // Average quantum efficieny (see Class description)
  Float_t fAverageQEVar;             // Error av. quantum eff.    (see Class description)
  Float_t fConvFFactorRelVarLimit;   // Acceptance limit rel. error conv. factor (F-Factor method)
  Float_t fPheFFactorRelVarLimit;    // Acceptance limit number phe's w.r.t its mean (in variances)
  
  TH1D* fOffsets;                    //! Histogram with Higain-vs-LoGain fit result Offsets
  TH1D* fSlopes;                     //! Histogram with Higain-vs-LoGain fit result Slopes
  TH2D* fOffvsSlope;                 //! Histogram with Higain-vs-LoGain fit result Offsets vs. Slopes

  enum  { kFFactorMethodValid, kBlindPixelMethodValid, kPINDiodeMethodValid, kCombinedMethodValid };

  Float_t fFluxPhesInnerPixel;       // Mean nr.  photo-electrons in INNER PIXEL
  Float_t fFluxPhesInnerPixelVar;    // Variance nr. photo-electrons INNER PIXEL  
  Float_t fFluxPhesOuterPixel;       // Mean nr. photo-electrons in an OUTER PIXEL
  Float_t fFluxPhesOuterPixelVar;    // Variance nr, photo-electrons OUTER PIXEL  
  Float_t fFluxPhotonsInnerPixel;    // Mean nr. photo-electrons in INNER PIXEL
  Float_t fFluxPhotonsInnerPixelVar; // Variance nr. photo-electrons INNER PIXEL  
  Float_t fFluxPhotonsOuterPixel;    // Mean nr. photo-electrons in OUTER PIXEL
  Float_t fFluxPhotonsOuterPixelVar; // Variance nr. photo-electrons OUTER PIXEL  
  Byte_t fFlags;                     // Bit-fieldto hold the flags
  
public:

  MCalibrationChargeCam(const char *name=NULL, const char *title=NULL);
  ~MCalibrationChargeCam();
  
  void Clear(    Option_t *o="" );

  // Setters   
  void SetAverageQE             ( const Float_t q=fgAverageQE, 
			          const Float_t e=fgAverageQEErr)      { fAverageQE = q; fAverageQEVar = e*e; }
  void SetBlindPixelMethodValid ( const Bool_t  b=kTRUE                    );
  void SetConvFFactorRelErrLimit( const Float_t f=fgConvFFactorRelErrLimit ) { fConvFFactorRelVarLimit = f*f; }
  void SetFFactorMethodValid    ( const Bool_t  b=kTRUE                    );
  void SetPheFFactorRelErrLimit ( const Float_t f=fgPheFFactorRelErrLimit  ) { fPheFFactorRelVarLimit  = f*f; }  
  void SetPINDiodeMethodValid   ( const Bool_t  b=kTRUE                    );  

  // Getters
  Bool_t  GetConversionFactorFFactor    ( Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma );
  Bool_t  GetConversionFactorBlindPixel ( Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma );
  Bool_t  GetConversionFactorPINDiode   ( Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma );
  Bool_t  GetConversionFactorCombined   ( Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma );

  Float_t GetFluxPhesInnerPixel()        const { return fFluxPhesInnerPixel;    }
  Float_t GetFluxPhesInnerPixelErr()     const;
  Float_t GetFluxPhesOuterPixel()        const { return fFluxPhesOuterPixel;    }
  Float_t GetFluxPhesOuterPixelErr()     const;
  Float_t GetFluxPhotonsInnerPixel()     const { return fFluxPhotonsInnerPixel; }
  Float_t GetFluxPhotonsInnerPixelErr()  const;
  Float_t GetFluxPhotonsOuterPixel()     const { return fFluxPhotonsOuterPixel; }
  Float_t GetFluxPhotonsOuterPixelErr()  const;

  Bool_t IsBlindPixelMethodValid()       const;
  Bool_t IsPINDiodeMethodValid()         const;  

  // Prints
  void Print(Option_t *o="")             const;
  
  // Draws
  void DrawPixelContent(Int_t num)       const;    
//  void DrawHiLoFits();
  
  // Others
  Bool_t GetPixelContent(Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type=0) const;

  Bool_t CalcFluxPhotonsFFactorMethod(const MGeomCam &geom, MBadPixelsCam &bad);  

  void   ApplyPINDiodeCalibration   ( const MGeomCam &geom,
                                      const MBadPixelsCam &bad,
                                      const MCalibrationChargePINDiode &pindiode );
  void   ApplyBlindPixelCalibration ( const MGeomCam &geom,
                                      const MBadPixelsCam &bad,
                                      const MCalibrationChargeBlindPix &blindpix );
  void   ApplyFFactorCalibration    ( const MGeomCam &geom, 
	                              const MBadPixelsCam &bad                   );

  ClassDef(MCalibrationChargeCam, 1)	// Container Charge Calibration Results Camera
};

#endif
