#ifndef ALITPCDATAQA_H
#define ALITPCDATAQA_H
#include <TBits.h>
#include <TH1F.h>
#include <TProfile.h>
#include <TProfile2D.h>
#include "AliRecoParam.h"
#include <TArray.h>
class TH2F;
class TTreeSRedirector;
class AliTPCROC;
class AliTPCCalROC;
class AliTPCRawStreamV3;
class AliRawReader;
class AliTPCAltroMapping;
class AliTPCCalPad;
class TMap;
class TObjArray;
struct eventHeaderStruct;
class AliTPCdataQA : public TH1F {
public:
AliTPCdataQA();
AliTPCdataQA(const AliTPCdataQA &ped);
AliTPCdataQA(const TMap *config);
virtual ~AliTPCdataQA();
AliTPCdataQA& operator = (const AliTPCdataQA &source);
void DumpToFile(const Char_t *filename, const Char_t *dir="", Bool_t append=kFALSE);
void MakeTree(const char *fname="QApad.root") const;
Bool_t ProcessEvent(AliTPCRawStreamV3 *const rawStreamV3);
Bool_t ProcessEvent(AliRawReader *const rawReader);
Bool_t ProcessEvent(eventHeaderStruct *const event);
void Analyse();
void SetPedestal(AliTPCCalPad *const pedestalCal){ fPedestal = pedestalCal;}
void SetNoise(AliTPCCalPad *const noiseCal){ fNoise = noiseCal;}
void SetMinQMax (Float_t minQmax ) { fMinQMax = minQmax; }
void SetRequireNeighbouringPad(Bool_t req=kTRUE) { fRequireNeighbouringPad = req; }
void FillOccupancyProfile();
void ResetProfiles();
AliTPCCalPad *GetNoThreshold() const { return fNoThreshold;}
AliTPCCalPad *GetMaxCharge() const { return fMaxCharge;}
AliTPCCalPad *GetMeanCharge() const { return fMeanCharge;}
AliTPCCalPad *GetNLocalMaxima() const { return fNLocalMaxima;}
AliTPCCalPad *GetOverThreshold10() const { return fOverThreshold10;}
AliTPCCalPad *GetOverThreshold20() const { return fOverThreshold20;}
AliTPCCalPad *GetOverThreshold30() const { return fOverThreshold30;}
AliTPCCalPad *GetNTimeBins() const { return fNTimeBins;}
AliTPCCalPad *GetNPads() const { return fNPads;}
AliTPCCalPad *GetTimePosition() const { return fTimePosition;}
TProfile* GetHistQVsTimeSideA() const {return fHistQVsTimeSideA;}
TProfile* GetHistQVsTimeSideC() const {return fHistQVsTimeSideC;}
TProfile* GetHistQMaxVsTimeSideA() const {return fHistQMaxVsTimeSideA;}
TProfile* GetHistQMaxVsTimeSideC() const {return fHistQMaxVsTimeSideC;}
TH1F* GetHistOccupancyVsEventConst() const {return fHistOccupancyVsEvent;}
TH1F* GetHistNclustersVsEventConst() const {return fHistNclustersVsEvent;}
TH1F* GetHistOccupancyVsEvent();
TH1F* GetHistNclustersVsEvent();
TProfile* GetHistOccVsSector() const { return fHistOccVsSector; }
TProfile2D* GetHistOcc2dVsSector() const { return fHistOcc2dVsSector; }
TProfile* GetHistQVsSector() const { return fHistQVsSector; }
TProfile* GetHistQmaxVsSector() const { return fHistQmaxVsSector; }
AliTPCAltroMapping **GetAltroMapping() const { return fMapping; };
void SetAltroMapping(AliTPCAltroMapping **mapp) { fMapping = mapp; };
Int_t GetFirstTimeBin() const { return fFirstTimeBin; }
Int_t GetLastTimeBin() const { return fLastTimeBin; }
Int_t GetAdcMin() const { return fAdcMin; }
Int_t GetAdcMax() const { return fAdcMax; }
Int_t GetEventCounter() const { return fEventCounter; }
Bool_t GetIsAnalysed() const { return fIsAnalysed; }
Int_t GetMaxEvents() const { return fMaxEvents; }
Int_t GetEventsPerBin() const { return fEventsPerBin; }
Int_t GetSignalCounter() const { return fSignalCounter; }
Int_t GetClusterCounter() const { return fClusterCounter;}
Float_t GetMinQMax() const { return fMinQMax; }
Bool_t GetRequireNeighbouringPad() const { return fRequireNeighbouringPad; }
Bool_t GetIsDQM() const { return fIsDQM; }
void SetRangeTime(Int_t tMin, Int_t tMax){ fFirstTimeBin=tMin; fLastTimeBin=tMax;}
void SetRangeAdc (Int_t aMin, Int_t aMax){ fAdcMin=aMin; fAdcMax=aMax; }
void SetMaxEvents (Int_t value) { fMaxEvents = value; }
void SetEventsPerBin(Int_t value) { fEventsPerBin = value; }
void SetIsDQM(Bool_t value) { fIsDQM = value; }
void ResetData();
void SetChamberStatus(UInt_t roc, Bool_t status) { fActiveChambers.SetBitNumber(roc,status); }
Bool_t GetChamberStatus(UInt_t roc) {return fActiveChambers.TestBitNumber(roc);}
private:
Int_t Update(const Int_t iSector, const Int_t iRow, const Int_t iPad,
const Int_t iTimeBin, Float_t signal,
const Int_t iPatch=-1, const Int_t iBranch=-1);
void FindLocalMaxima(const Int_t iSector);
void MakeArrays();
void CleanArrays();
void SetExpandDigit(const Int_t iRow, Int_t iPad, Int_t iTimeBin,
const Float_t signal);
void GetPadAndTimeBin(Int_t bin, Int_t& iPad, Int_t& iTimeBin);
Float_t GetQ(const Float_t* adcArray, const Int_t time,
const Int_t pad, const Int_t maxTimeBins,
Int_t& timeMin,Int_t& timeMax,Int_t& padMin,Int_t& padMax) const;
void UpdateEventHistograms();
void Init();
TObjArray *ConfigArrRocs(TObjArray *arr, const Text_t* name);
Int_t fFirstTimeBin;
Int_t fLastTimeBin;
Int_t fAdcMin;
Int_t fAdcMax;
Float_t fMinQMax;
Bool_t fRequireNeighbouringPad;
AliTPCAltroMapping **fMapping;
AliTPCCalPad * fPedestal;
AliTPCCalPad * fNoise;
AliTPCCalPad * fNLocalMaxima;
AliTPCCalPad * fMaxCharge;
AliTPCCalPad * fMeanCharge;
AliTPCCalPad * fNoThreshold;
AliTPCCalPad * fNTimeBins;
AliTPCCalPad * fNPads;
AliTPCCalPad * fTimePosition;
AliTPCCalPad * fOverThreshold10;
AliTPCCalPad * fOverThreshold20;
AliTPCCalPad * fOverThreshold30;
TProfile* fHistQVsTimeSideA;
TProfile* fHistQVsTimeSideC;
TProfile* fHistQMaxVsTimeSideA;
TProfile* fHistQMaxVsTimeSideC;
TH1F* fHistOccupancyVsEvent;
TH1F* fHistNclustersVsEvent;
Int_t fEventCounter;
Bool_t fIsAnalysed;
Int_t fMaxEvents;
Int_t fEventsPerBin;
Int_t fSignalCounter;
Int_t fClusterCounter;
TBits fActiveChambers;
Float_t** fAllBins;
Int_t** fAllSigBins;
Int_t* fAllNSigBins;
Int_t fRowsMax;
Int_t fPadsMax;
Int_t fTimeBinsMax;
Bool_t fIsDQM;
TProfile* fHistOccVsSector;
TProfile2D* fHistOcc2dVsSector;
TProfile* fHistQVsSector;
TProfile* fHistQmaxVsSector;
TArrayD* fOccVec;
TArrayD* fOccMaxVec;
TArrayD* fOccVecFine;
TArrayD* fOccMaxVecFine;
ClassDef(AliTPCdataQA, 6)
};
#endif