#ifndef MARS_MCalibrationPix
#define MARS_MCalibrationPix

#ifndef MARS_MParContainer
#include "MParContainer.h"
#endif

#include "MHCalibrationPixel.h"

class MCalibrationPix : public MParContainer
{
private:

  Int_t   fPixId;                        // the pixel Id
  
  Float_t fCharge;                       // The mean reduced charge after the fit
  Float_t fErrCharge;                    // The error of reduced mean charge after the fit
  Float_t fSigmaCharge;                  // The sigma of the mean charge after the fit
  Float_t fErrSigmaCharge;               // The error of the sigma of the mean charge after the fit
  Float_t fRSigmaSquare;                 // The reduced squares of sigmas after the fit
  Float_t fChargeProb;                   // The probability of the fit function 

  Float_t fPed;                          // The mean pedestal (from MPedestalPix)
  Float_t fPedRms;                       // The pedestal  RMS (from MPedestalPix)
  Float_t fErrPedRms;                    // The error of the pedestal  RMS (from MPedestalPix)  
  Float_t fElectronicPedRms;             // The pure electronic component of the RMS
  Float_t fErrElectronicPedRms;          // The error of the pure electronic component of the RMS

  Float_t fTime;                         // The mean arrival time after the fit  
  Float_t fSigmaTime;                    // The error of the mean arrival time after the fit
  Float_t fTimeChiSquare;                // The Chi Square of the fit function 
  Float_t fTimeProb;                     // The probability of the fit function 
  
  Float_t fFactor;                       // The laboratory F-factor
  Float_t fFactorError;                  // The laboratory F-factor Error
  Float_t fPheFFactorMethod;             // The number of Phe's calculated (F-factor method)
  Float_t fPheFFactorMethodError;        // The error on the number of Phe's calculated (F-factor method)

  Float_t fConversionFFactorMethod;      // The conversion factor to Phe's (F-factor method)
  Float_t fConversionBlindPixelMethod;   // The conversion factor to Ph's (Blind Pixel method)
  Float_t fConversionPINDiodeMethod;     // The conversion factor to Ph's (PIN Diode method)

  Float_t fConversionErrorFFactorMethod;    // The error of the conversion factor to Phe's (F-factor method)
  Float_t fConversionErrorBlindPixelMethod; // The error of the conversion factor to Ph's (Blind Pixel method)
  Float_t fConversionErrorPINDiodeMethod;   // The error of the conversion factor to Ph's (PIN Diode method)

  Float_t fConversionSigmaFFactorMethod;    // The sigma of conversion factor to Ph's (F-factor method)
  Float_t fConversionSigmaBlindPixelMethod; // The conversion factor to Ph's (Blind Pixel method)
  Float_t fConversionSigmaPINDiodeMethod;   // The conversion factor to Phd's (PIN Diode method)

  Float_t fConversionHiLo;                  // The conversion factor between Hi Gain and Lo Gain  
  Float_t fConversionHiLoError;             // The error of the conversion factor between Hi Gain and Lo Gain  
  
  Bool_t  fHiGainSaturation;                // Is Lo-Gain used at all?

  Bool_t  fFitValid;        
  Bool_t  fFitted; 
  Bool_t  fBlindPixelMethodValid;
  Bool_t  fFFactorMethodValid;
  Bool_t  fPINDiodeMethodValid;
  
  MHCalibrationPixel *fHist;    //! Pointer to the histograms performing the fits, etc.  

  Bool_t CheckChargeFitValidity();
  Bool_t CheckTimeFitValidity();
  
public:

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

  // Getter
  Bool_t IsFitValid()              const { return fFitValid;  }
  Bool_t IsFitted()                const { return fFitted;  }
  Bool_t IsBlindPixelMethodValid() const { return fBlindPixelMethodValid;  }
  Bool_t IsFFactorMethodValid()    const { return fFFactorMethodValid;  }
  Bool_t IsPINDiodeMethodValid()   const { return fPINDiodeMethodValid;  }

  // Charges
  Float_t GetCharge()              const { return fCharge;         }
  Float_t GetErrCharge()           const { return fErrCharge;      }
  Float_t GetChargeProb()          const { return fChargeProb;     }    
  Float_t GetSigmaCharge()         const { return fSigmaCharge;    }
  Float_t GetErrSigmaCharge()      const { return fErrSigmaCharge; }
  Float_t GetRSigmaSquare()        const { return fRSigmaSquare;   }

  // Times  
  Float_t GetTime()                const { return fTime;           }
  Float_t GetSigmaTime()           const { return fSigmaTime;      }
  Float_t GetTimeChiSquare()       const { return fTimeChiSquare;  }
  Float_t GetTimeProb()            const { return fTimeProb;  }      

  Float_t GetConversionHiLo()                 const  { return fConversionHiLo;        }
  Float_t GetConversionHiLoError()            const  { return fConversionHiLoError;   }

  Float_t GetMeanConversionBlindPixelMethod()  const { return fConversionBlindPixelMethod ; }
  Float_t GetErrorConversionBlindPixelMethod() const { return fConversionErrorBlindPixelMethod ; }
  Float_t GetSigmaConversionBlindPixelMethod() const { return fConversionSigmaBlindPixelMethod ; }

  Float_t GetMeanConversionFFactorMethod()     const { return fConversionFFactorMethod ;       }
  Float_t GetErrorConversionFFactorMethod()    const { return fConversionErrorFFactorMethod ;  }
  Float_t GetSigmaConversionFFactorMethod()    const { return fConversionSigmaFFactorMethod ;  }

  Float_t GetPheFFactorMethod()                const { return fPheFFactorMethod;               }
  Float_t GetPheFFactorMethodError()           const { return fPheFFactorMethodError;          }

  Float_t GetMeanConversionPINDiodeMethod()    const { return fConversionPINDiodeMethod ;      }
  Float_t GetErrorConversionPINDiodeMethod()   const { return fConversionErrorPINDiodeMethod ; }
  Float_t GetSigmaConversionPINDiodeMethod()   const { return fConversionSigmaPINDiodeMethod ; }

  // FIXME: Remove this from stored data members
  Float_t GetPed()                             const { return fPed;    }
  Float_t GetPedRms()                          const { return fPedRms; }

  // Setter
  void SetPedestal(Float_t ped, Float_t pedrms);
  void SetHiGainSaturation()             { fHiGainSaturation = kTRUE; fHist->SetUseLoGain(); }

  void SetConversionHiLo(Float_t c)      { fConversionHiLo      = c;    }
  void SetConversionHiLoError(Float_t e) { fConversionHiLoError = e;    }

  void SetConversionFFactorMethod(Float_t c, Float_t err, Float_t sig)
  {
      fConversionFFactorMethod = c;
      fConversionErrorFFactorMethod = err;
      fConversionSigmaFFactorMethod = sig;
  }
  void SetConversionBlindPixelMethod(Float_t c, Float_t err, Float_t sig)
  {
      fConversionBlindPixelMethod = c;
      fConversionErrorBlindPixelMethod = err;
      fConversionSigmaBlindPixelMethod = sig;
  }

  void SetConversionPINDiodeMethod(Float_t c, Float_t err, Float_t sig)
  {
      fConversionPINDiodeMethod = c ;
      fConversionErrorPINDiodeMethod = err;
      fConversionSigmaPINDiodeMethod = sig;
  }

  void SetFitValid()                            { fFitValid = kTRUE;  }
  void SetFitted()                              { fFitted = kTRUE;  }
  void SetBlindPixelMethodValid(Bool_t b=kTRUE) { fBlindPixelMethodValid = b;  }
  void SetFFactorMethodValid(Bool_t b=kTRUE)    { fFFactorMethodValid = b;  }
  void SetPINDiodeMethodValid(Bool_t b=kTRUE)   { fPINDiodeMethodValid = b;  }

  // Unknown
  void   ApplyLoGainConversion();

  void   SetChargesInGraph(Float_t qhi,Float_t qlo) { fHist->SetPointInGraph(qhi,qlo); }

  Bool_t FillChargeHiGain(Float_t q)                   { return fHist->FillChargeHiGain(q); }
  Bool_t FillTimeHiGain(Int_t t)                       { return fHist->FillTimeHiGain(t); }  
  Bool_t FillRChargevsTimeHiGain(Float_t rq, Int_t t)  { return fHist->FillChargevsNHiGain(rq,t); }    

  Bool_t FillChargeLoGain(Float_t q)                   { return fHist->FillChargeLoGain(q); }
  Bool_t FillTimeLoGain(Int_t t)                       { return fHist->FillTimeLoGain(t); }  
  Bool_t FillRChargevsTimeLoGain(Float_t rq, Int_t t)  { return fHist->FillChargevsNLoGain(rq,t); }    
  
  // FIXME: Not necessary -> pixidx (not id anyhow!) == index in array!
  //        Only needed n histograms which have to move to an MH-class anyhow!
  Int_t  GetPixId()                              const  { return fPixId;   }
  void   DefinePixId(Int_t i);
  
  Bool_t FitCharge();
  Bool_t FitTime();
  
  MHCalibrationPixel *GetHist() const   { return fHist;     }
  void Draw(Option_t *opt="")            { fHist->Draw(opt); }
  
  ClassDef(MCalibrationPix, 1)	// Storage Container for Calibration information of one pixel
};

#endif

