#ifndef MARS_MCalibrationChargePix
#define MARS_MCalibrationChargePix

#ifndef MARS_MCalibrationPix
#include "MCalibrationPix.h"
#endif

class MCalibrationChargePix : public MCalibrationPix
{
private:

  static const Float_t gkElectronicPedRms;       //! Electronic component of ped. RMS (now set to: 1.5)
  static const Float_t gkElectronicPedRmsErr;    //! Error Electr. component ped. RMS (now set to: 0.3)
  static const Float_t gkFFactor;                //! Laboratory F-factor PMTs       (now set to: 1.15)
  static const Float_t gkFFactorErr;             //! Laboratory F-factor Error PMTs (now set to: 0.02)

  static const Float_t fgConversionHiLo;         //! Default fConversionHiLo        (now set to: 10.)
  static const Float_t fgConversionHiLoErr;      //! Default fConversionHiLoVar     (now set to: 2.5)
  static const Float_t fgPheFFactorMethodLimit;  //! Default fPheFFactorMethodLimit (now set to: 5.)
  
  Float_t fAbsTimeMean;                     // Mean Absolute Arrival Time
  Float_t fAbsTimeRms;                      // RMS Mean Absolute Arrival Time
  Byte_t  fCalibFlags;                      // Bit-field for the class-own bits
  Float_t fConversionFFactorMethodVar;      // Variance conversion factor (F-factor method)
  Float_t fConversionBlindPixelMethodVar;   // Variance conversion factor (Blind Pixel method)
  Float_t fConversionPINDiodeMethodVar;     // Variance conversion factor (PIN Diode method)
  Float_t fConversionCombinedMethodVar;     // Variance conversion factor (all methods combined)
  Float_t fConversionHiLo;                  // Conversion factor betw. Hi Gain and Lo Gain  
  Float_t fConversionHiLoVar;               // Variance Conversion factor betw. Hi and Lo Gain
  Float_t fLoGainPedRmsSquare;              // Pedestal RMS square of Low Gain
  Float_t fLoGainPedRmsSquareVar;           // Pedestal RMS square Variance of Low Gain
  Float_t fMeanConversionFFactorMethod;     // Conversion factor (F-factor method)
  Float_t fMeanConversionBlindPixelMethod;  // Conversion factor (Blind Pixel method)
  Float_t fMeanConversionPINDiodeMethod;    // Conversion factor (PIN Diode method)
  Float_t fMeanConversionCombinedMethod;    // Conversion factor (all methods combined)
  Float_t fPed;                             // Pedestal (from MPedestalPix) times number FADC slices
  Float_t fPedVar;                          // Variance of pedestal 
  Float_t fPedRms;                          // Pedestal RMS (from MPedestalPix) times sqrt nr. FADC slices
  Float_t fPheFFactorMethod;                // Number Phe's calculated (F-factor method)
  Float_t fPheFFactorMethodVar;             // Variance number of Phe's (F-factor method)
  Float_t fPheFFactorMethodLimit;           // Min. number Photo-electrons for pix to be accepted.
  Float_t fRSigmaSquare;                    // Square of Reduced sigma
  Float_t fRSigmaSquareVar;                 // Variance Reduced sigma
  Float_t fSigmaConversionFFactorMethod;    // Sigma Conversion factor (F-factor method)
  Float_t fSigmaConversionBlindPixelMethod; // Sigma Conversion factor (Blind Pixel method)
  Float_t fSigmaConversionPINDiodeMethod;   // Sigma Conversion factor (PIN Diode method)
  Float_t fSigmaConversionCombinedMethod;   // Sigma Conversion factor (all methods combined)
  Float_t fTotalFFactorFFactorMethod;       // Total F-Factor to Ph's (F-factor method)
  Float_t fTotalFFactorBlindPixelMethod;    // Total F-Factor to Ph's (Blind Pixel method)
  Float_t fTotalFFactorPINDiodeMethod;      // Total F-Factor to Ph's (PIN Diode method)
  Float_t fTotalFFactorCombinedMethod;      // Total F-Factor to Ph's (all methods combined)
  Float_t fTotalFFactorFFactorMethodVar;    // Variance total F-Factor (F-factor method)
  Float_t fTotalFFactorBlindPixelMethodVar; // Variance total F-Factor (Blind Pixel method)
  Float_t fTotalFFactorPINDiodeMethodVar;   // Variance total F-Factor (PIN Diode method)
  Float_t fTotalFFactorCombinedMethodVar;   // Variance total F-Factor (all methods combined)
  
  enum  { kBlindPixelMethodValid, kFFactorMethodValid,
          kPINDiodeMethodValid, kCombinedMethodValid }; // Possible bits to be set

  const Float_t GetConversionHiLoRelVar()  const;
  const Float_t GetFFactorRelVar()     const;
  
public:

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

  // Setter
  void SetAbsTimeMean ( const Float_t f ) { fAbsTimeMean = f; }
  void SetAbsTimeRms  ( const Float_t f ) { fAbsTimeRms  = f; }
  void SetConversionHiLo    ( const Float_t c=fgConversionHiLo    ) { fConversionHiLo    = c;   }
  void SetConversionHiLoErr ( const Float_t e=fgConversionHiLoErr ) { fConversionHiLoVar = e*e; }
  void SetConversionFFactorMethod   ( Float_t c, Float_t err, Float_t sig );
  void SetConversionBlindPixelMethod( Float_t c, Float_t err, Float_t sig );
  void SetConversionPINDiodeMethod  ( Float_t c, Float_t err, Float_t sig );
  void SetConversionCombinedMethod  ( Float_t c, Float_t err, Float_t sig );

  void SetBlindPixelMethodValid( const Bool_t b = kTRUE );
  void SetFFactorMethodValid   ( const Bool_t b = kTRUE );
  void SetPINDiodeMethodValid  ( const Bool_t b = kTRUE );
  void SetCombinedMethodValid  ( const Bool_t b = kTRUE );

  void SetPedestal              ( const Float_t ped, const Float_t pedrms, const Float_t pederr);
  void SetPheFFactorMethod      ( const Float_t f)                          { fPheFFactorMethod       = f; }
  void SetPheFFactorMethodVar   ( const Float_t f)                          { fPheFFactorMethodVar    = f; }  
  void SetPheFFactorMethodLimit ( const Float_t f=fgPheFFactorMethodLimit ) { fPheFFactorMethodLimit  = f; }
  void SetTotalFFactorFFactorMethod       ( const Float_t f)  { fTotalFFactorFFactorMethod       = f; }
  void SetTotalFFactorBlindPixelMethod    ( const Float_t f)  { fTotalFFactorBlindPixelMethod    = f; }
  void SetTotalFFactorPINDiodeMethod      ( const Float_t f)  { fTotalFFactorPINDiodeMethod      = f; }
  void SetTotalFFactorFFactorMethodErr    ( const Float_t f)  { fTotalFFactorFFactorMethodVar    = f*f; }
  void SetTotalFFactorBlindPixelMethodErr ( const Float_t f)  { fTotalFFactorBlindPixelMethodVar = f*f; }
  void SetTotalFFactorPINDiodeMethodErr   ( const Float_t f)  { fTotalFFactorPINDiodeMethodVar   = f*f; }
  
  // Getters
  Float_t GetAbsTimeMean                ()     const { return fAbsTimeMean;     }
  Float_t GetAbsTimeRms                 ()     const { return fAbsTimeRms;      }
  Float_t GetConversionHiLo             ()     const { return fConversionHiLo;  }
  Float_t GetConversionHiLoErr          ()     const;
  Float_t GetConversionBlindPixelMethodErr()   const;
  Float_t GetConversionFFactorMethodErr ()     const;
  Float_t GetConversionPINDiodeMethodErr()     const;
  Float_t GetConversionCombinedMethodErr()     const;
  Float_t GetConvertedLoGainMean        ()     const;
  Float_t GetConvertedLoGainMeanErr     ()     const;
  Float_t GetConvertedLoGainSigma       ()     const;
  Float_t GetConvertedLoGainSigmaErr    ()     const;
  Float_t GetMeanConversionBlindPixelMethod()  const { return fMeanConversionBlindPixelMethod  ; }
  Float_t GetMeanConversionCombinedMethod()    const { return fMeanConversionCombinedMethod ;    }
  Float_t GetMeanConversionFFactorMethod()     const { return fMeanConversionFFactorMethod;      }
  Float_t GetMeanConversionPINDiodeMethod()    const { return fMeanConversionPINDiodeMethod ;    }
  Float_t GetSigmaConversionBlindPixelMethod() const { return fSigmaConversionBlindPixelMethod ; }
  Float_t GetSigmaConversionCombinedMethod()   const { return fSigmaConversionCombinedMethod ;   }
  Float_t GetSigmaConversionFFactorMethod()    const { return fSigmaConversionFFactorMethod;     }
  Float_t GetSigmaConversionPINDiodeMethod()   const { return fSigmaConversionPINDiodeMethod ;   }
  Float_t GetPed                ()             const { return fPed;                              }
  Float_t GetPedErr             ()             const;
  Float_t GetPedRms             ()             const;
  Float_t GetPedRmsErr          ()             const;
  Float_t GetPheFFactorMethod   ()             const { return fPheFFactorMethod;                 }    
  Float_t GetPheFFactorMethodErr()             const;
  Float_t GetPheFFactorMethodVar()             const { return fPheFFactorMethodVar;              }
  Float_t GetRSigma             ()             const;
  Float_t GetRSigmaErr          ()             const;
  Float_t GetRSigmaRelVar       ()             const;
  Float_t GetTotalFFactorBlindPixelMethod()    const { return fTotalFFactorBlindPixelMethod;     }
  Float_t GetTotalFFactorBlindPixelMethodErr() const;
  Float_t GetTotalFFactorCombinedMethod()      const { return fTotalFFactorCombinedMethod;       }
  Float_t GetTotalFFactorCombinedMethodErr()   const;
  Float_t GetTotalFFactorFFactorMethod()       const { return fTotalFFactorFFactorMethod;        }
  Float_t GetTotalFFactorFFactorMethodErr()    const;
  Float_t GetTotalFFactorPINDiodeMethod()      const { return fTotalFFactorPINDiodeMethod;       }
  Float_t GetTotalFFactorPINDiodeMethodErr()   const;

  Bool_t IsBlindPixelMethodValid()             const;
  Bool_t IsPINDiodeMethodValid()               const;
  Bool_t IsFFactorMethodValid()                const;
  Bool_t IsCombinedMethodValid()               const;

  // Miscellaneous
  void   CalcLoGainPedestal(const Float_t logainsamples);
  Bool_t CalcReducedSigma();
  Bool_t CalcFFactorMethod();

  ClassDef(MCalibrationChargePix, 1)	// Container Charge Calibration Results Pixel
};

#endif

