#ifndef MARS_MCalibrateData
#define MARS_MCalibrateData

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// MCalibrateData                                                          //
//                                                                         //
// Integrates the desired ADC time slices of one pixel and apply           //
// calibration constants                                                   //
//                                                                         //
// Differences between MCalibrateData and MCalibrate :                     //
// in MCalibrateData                                                       //
// - in ReInit the MPedPhot container is filled using                      //
//      - the pedstals/slice from MPedestalCam                             //
//      - the number of used FADC slices from MExtractedSignalCam          //
//      - the photon/ADC conversion factor from MCalibrationCam            //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
#ifndef MARS_MTask
#include "MTask.h"
#endif

class MGeomCam;
class MBadPixelsCam;
class MPedestalCam;
class MCalibrationChargeCam;
class MCalibrationQECam;
class MExtractedSignalCam;

class MPedPhotCam;
class MCerPhotEvt;

class MCalibrateData : public MTask
{
private:

  MGeomCam              *fGeomCam;          //! Camera geometry container
  MPedestalCam          *fPedestal;         //! Pedestals/slice [ADC counts]
  MPedestalCam          *fPedestalFromData; //! Pedestals/slice [ADC counts]
  MBadPixelsCam         *fBadPixels;        //! Bad Pixels information
  MCalibrationChargeCam *fCalibrations;     //! Calibration constants
  MCalibrationQECam     *fQEs;              //! Quantum efficiencies
  MExtractedSignalCam   *fSignals;          //! Integrated charge in FADCs counts
  
  MPedPhotCam           *fPedPhot;          // Pedestals/(used slices) [photons]
  MPedPhotCam           *fPedPhotFromData;  // Pedestals/(used slices) [photons]
  MCerPhotEvt           *fCerPhotEvt;       // Cerenkov Photon Event used for calculation
  
  UShort_t fCalibrationMode;
  Float_t  fConversionHiLo;
  Byte_t   fPedestalFlag;                   // Flags defining to calibrate the pedestal each event or each run
  
  TString  fNamePedADCRunContainer;         // name of fPedestal
  TString  fNamePedADCEventContainer;       // name of fPedestalFromData
  TString  fNamePedPhotRunContainer;        // name of fPedPhot
  TString  fNamePedPhotEventContainer;      // name of fPedPhotFromData

  Float_t  fNumUsedHiGainFADCSlices;
  
  Bool_t   CalibratePedestal ( MPedestalCam *, MPedPhotCam * );
  
  Bool_t   GetConversionFactor(UInt_t, 
                               Float_t &, Float_t &, Float_t &, 
                               Float_t &, Float_t &);    
  
  Int_t    PreProcess( MParList *pList );
  Bool_t   ReInit    ( MParList *pList );
  Int_t    Process   ( );
  
public:

  enum CalibrationMode_t { kNone=0,kFlatCharge=1,
                           kBlindPixel,kFfactor,kPinDiode,kCombined, kDummy };

  static const CalibrationMode_t kDefault = kFfactor;
  
  enum PedestalType_t {
    kNo    = BIT(0),
    kRun   = BIT(1),
    kEvent = BIT(2)
  };
  
  MCalibrateData( CalibrationMode_t calmode=kDefault,
                  const char *name=NULL, const char *title=NULL);
  
  void   DisablePedestalType( PedestalType_t i      )              { fPedestalFlag &= ~i;      } 
  void   EnablePedestalType ( PedestalType_t i      )              { fPedestalFlag |=  i;      } 
  void   SetPedestalType    ( PedestalType_t i=kRun )              { fPedestalFlag  =  i;      } 
  Bool_t TestFlag           ( PedestalType_t i      ) const        { return fPedestalFlag & i; }
  
  void   SetCalibrationMode ( CalibrationMode_t calmode=kDefault ) { fCalibrationMode=calmode; }
  void   SetConversionHiLo  ( Float_t conv                       ) { fConversionHiLo = conv;   }
  
  void   SetNamePedADCRunContainer   ( const char *name="MPedestalCam" )         {
    fNamePedADCRunContainer    = name; }
  void   SetNamePedADCEventContainer ( const char *name="MPedestalCamFromData" ) {
    fNamePedADCEventContainer  = name; }
  void   SetNamePedPhotRunContainer  ( const char *name="MPedPhotCam" )          {
    fNamePedPhotRunContainer   = name; }
  void   SetNamePedPhotEventContainer( const char *name="MPedPhotCamFromData")   {
    fNamePedPhotEventContainer = name; }
  
  ClassDef(MCalibrateData, 0)   // Task to calibrate FADC counts into Cherenkov photons 
};

#endif   /* MCalibrateData */






