#ifndef ALITPCCALIBCE_H
#define ALITPCCALIBCE_H
#include <TVectorT.h>
#include <THnSparse.h>
#include "AliTPCCalibRawBase.h"
class TH1S;
#include "TObjArray.h"
class TH2S;
class TH1F;
class TTreeSRedirector;
class AliTPCCalPad;
class AliTPCROC;
class AliTPCCalROC;
class AliTPCParam;
class AliRawReader;
class TGraph;
class TMap;
class TCollection;
struct eventHeaderStruct;
class AliTPCCalibCE : public AliTPCCalibRawBase {
public:
AliTPCCalibCE();
AliTPCCalibCE(const AliTPCCalibCE &sig);
AliTPCCalibCE(const TMap *config);
virtual ~AliTPCCalibCE();
AliTPCCalibCE& operator = (const AliTPCCalibCE &source);
virtual Int_t Update(const Int_t isector, const Int_t iRow, const Int_t iPad,
const Int_t iTimeBin, const Float_t signal);
virtual void ProcessBunch(const Int_t sector, const Int_t row, const Int_t pad,
const Int_t length, const UInt_t startTimeBin, const UShort_t* signal);
virtual void Analyse();
void AnalyseTrack();
AliTPCCalROC* GetCalRocT0 (Int_t sector, Bool_t force=kFALSE);
AliTPCCalROC* GetCalRocT0Err(Int_t sector, Bool_t force=kFALSE);
AliTPCCalROC* GetCalRocQ (Int_t sector, Bool_t force=kFALSE);
AliTPCCalROC* GetCalRocRMS(Int_t sector, Bool_t force=kFALSE);
AliTPCCalROC* GetCalRocOutliers(Int_t sector, Bool_t force=kFALSE);
const TObjArray* GetCalPadT0() const { return &fCalRocArrayT0; }
const TObjArray* GetCalPadT0Err() const { return &fCalRocArrayT0Err; }
const TObjArray* GetCalPadQ() const { return &fCalRocArrayQ; }
const TObjArray* GetCalPadRMS() const { return &fCalRocArrayRMS;}
const TObjArray* GetCalPadOutliers() const { return &fCalRocArrayOutliers;}
TH2S* GetHistoQ (Int_t sector, Bool_t force=kFALSE);
TH2S* GetHistoT0 (Int_t sector, Bool_t force=kFALSE);
TH2S* GetHistoRMS(Int_t sector, Bool_t force=kFALSE);
Float_t GetMeanT0rms() const {return fMeanT0rms;}
Float_t GetMeanQrms() const {return fMeanQrms;}
Float_t GetMeanRMSrms() const {return fMeanRMSrms;}
Int_t GetPeakDetectionMinus() const {return fPeakDetMinus;}
Int_t GetPeakDetectionPlus() const {return fPeakDetPlus;}
Int_t GetPeakIntRangeMinus() const {return fPeakIntMinus;}
Int_t GetPeakIntRangePlus() const {return fPeakIntPlus;}
Float_t GetNnoiseThresholdMax() const {return fNoiseThresholdMax;}
Float_t GetNnoiseThresholdSum() const {return fNoiseThresholdSum;}
TH1S* GetHistoTmean(Int_t sector, Bool_t force=kFALSE);
TObjArray* GetParamArrayPol1(Int_t sector, Bool_t force=kFALSE);
TObjArray* GetParamArrayPol2(Int_t sector, Bool_t force=kFALSE);
TVectorF* GetTMeanEvents(Int_t sector, Bool_t force=kFALSE);
TVectorF* GetQMeanEvents(Int_t sector, Bool_t force=kFALSE);
const TVectorD* GetEventTimes() const { return &fVEventTime; }
const TVectorD* GetEventIds() const { return &fVEventNumber; }
void SetRangeRefQ (Int_t nBins, Float_t xMin, Float_t xMax){ fNbinsQ = nBins; fXminQ = xMin; fXmaxQ = xMax; }
void SetRangeRefT0 (Int_t nBins, Float_t xMin, Float_t xMax){ fNbinsT0 = nBins; fXminT0 = xMin; fXmaxT0 = xMax; }
void SetRangeRefRMS(Int_t nBins, Float_t xMin, Float_t xMax){ fNbinsRMS = nBins; fXminRMS = xMin; fXmaxRMS = xMax; }
void SetRangePeakDetection(Int_t minus, Int_t plus) { fPeakDetMinus=minus; fPeakDetPlus=plus;}
void SetRangePeakIntegral(Int_t minus, Int_t plus) { fPeakIntMinus=minus; fPeakIntPlus=plus;}
void SetNnoiseThresholdMax(Float_t n) {fNoiseThresholdMax=n;}
void SetNnoiseThresholdSum(Float_t n) {fNoiseThresholdSum=n;}
void SetEventInfo(UInt_t runNumber,UInt_t timestamp, UInt_t eventId){ fRunNumber=runNumber; fTimeStamp=timestamp; fEventId=eventId;}
void SetPedestalDatabase(AliTPCCalPad * const pedestalTPC, AliTPCCalPad * const padNoiseTPC) {fPedestalTPC = pedestalTPC; fPadNoiseTPC = padNoiseTPC;}
void SetIsZeroSuppressed(Bool_t zs=kTRUE) { fIsZeroSuppressed=zs; }
void SetSecRejectRatio(Float_t ratio) { fSecRejectRatio=ratio; }
void SetProcessOld(Bool_t process=kTRUE) {fProcessOld=process;}
void SetProcessNew(Bool_t process=kTRUE) {fProcessNew=process; if (process&&!fHnDrift) CreateDVhist(); }
Int_t GetNeventsProcessed() const { return fNevents; }
Bool_t GetIsZeroSuppressed() const { return fIsZeroSuppressed; }
Float_t GetSecRejectRatio() const { return fSecRejectRatio; }
const TVectorF *GetTime0Side(Int_t side=0) const {return (side==0)?&fVTime0SideA:&fVTime0SideC;}
Float_t GetPeakIntegralMinus() const {return fPeakIntMinus;}
Float_t GetPeakIntegralPlus() const {return fPeakIntPlus;}
void Merge(AliTPCCalibCE * const ce);
virtual Long64_t Merge(TCollection * const list);
TGraph *MakeGraphTimeCE(Int_t sector, Int_t xVariable=0, Int_t fitType=0, Int_t fitParameter=0);
Bool_t IsEdgePad(Int_t sector, Int_t row, Int_t pad) const;
void FindLocalMaxima(TObjArray * const arrObj, Double_t timestamp, Int_t burst);
Int_t FindLaserTrackID(Int_t sector,Int_t row, const Double_t *peakpos,Double_t &mindist, const Double_t *peakposloc, Int_t &itrackMin2);
const THnSparseI *GetHnDrift() const {return fHnDrift;}
const TObjArray& GetArrHnDrift() const {return fArrHnDrift;}
const TVectorD& GetTimeBursts() const {return fTimeBursts;}
const TObjArray *GetArrFitGraphs() const {return fArrFitGraphs;}
virtual void DumpToFile(const Char_t *filename, const Char_t *dir="", Bool_t append=kFALSE);
static AliTPCCalibCE *ReadFromFile(const Char_t *filename);
protected:
virtual void EndEvent();
virtual void ResetEvent();
private:
Int_t fNbinsT0;
Float_t fXminT0;
Float_t fXmaxT0;
Int_t fNbinsQ;
Float_t fXminQ;
Float_t fXmaxQ;
Int_t fNbinsRMS;
Float_t fXminRMS;
Float_t fXmaxRMS;
Int_t fPeakDetMinus;
Int_t fPeakDetPlus;
Int_t fPeakIntMinus;
Int_t fPeakIntPlus;
Float_t fNoiseThresholdMax;
Float_t fNoiseThresholdSum;
Bool_t fIsZeroSuppressed;
Int_t fLastSector;
Float_t fSecRejectRatio;
AliTPCParam *fParam;
AliTPCCalPad *fPedestalTPC;
AliTPCCalPad *fPadNoiseTPC;
AliTPCCalROC *fPedestalROC;
AliTPCCalROC *fPadNoiseROC;
TObjArray fCalRocArrayT0;
TObjArray fCalRocArrayT0Err;
TObjArray fCalRocArrayQ;
TObjArray fCalRocArrayRMS;
TObjArray fCalRocArrayOutliers;
TObjArray fHistoQArray;
TObjArray fHistoT0Array;
TObjArray fHistoRMSArray;
Float_t fMeanT0rms;
Float_t fMeanQrms;
Float_t fMeanRMSrms;
TObjArray fHistoTmean;
TObjArray fParamArrayEventPol1;
TObjArray fParamArrayEventPol2;
TObjArray fTMeanArrayEvent;
TObjArray fQMeanArrayEvent;
TVectorD fVEventTime;
TVectorD fVEventNumber;
TVectorF fVTime0SideA;
TVectorF fVTime0SideC;
Double_t fEventId;
UInt_t fOldRunNumber;
TObjArray fPadTimesArrayEvent;
TObjArray fPadQArrayEvent;
TObjArray fPadRMSArrayEvent;
TObjArray fPadPedestalArrayEvent;
Int_t fCurrentChannel;
Int_t fCurrentSector;
Int_t fCurrentRow;
Float_t fMaxPadSignal;
Int_t fMaxTimeBin;
Float_t fPadSignal[1024];
Float_t fPadPedestal;
Float_t fPadNoise;
TVectorD fVTime0Offset;
TVectorD fVTime0OffsetCounter;
TVectorD fVMeanQ;
TVectorD fVMeanQCounter;
Float_t fCurrentCETimeRef;
Bool_t fProcessOld;
Bool_t fProcessNew;
Bool_t fAnalyseNew;
enum {kHnBinsDV=5};
THnSparseI *fHnDrift;
TObjArray fArrHnDrift;
TVectorD fTimeBursts;
UInt_t fBinsLastAna[100];
UShort_t fPeaks[14];
UShort_t fPeakWidths[14];
TObjArray *fArrFitGraphs;
UInt_t fEventInBunch;
void FindPedestal(Float_t part=.6);
void UpdateCETimeRef();
void FindCESignal(TVectorD ¶m, Float_t &qSum, const TVectorF maxima);
void FindLocalMaxima(TVectorF &maxima);
Bool_t IsPeak(Int_t pos, Int_t tminus, Int_t tplus) const;
TH2S* GetHisto(Int_t sector, TObjArray *arr,
Int_t nbinsY, Float_t ymin, Float_t ymax,
const Char_t *type, Bool_t force);
TH1S* GetHisto(Int_t sector, TObjArray *arr,
const Char_t *type, Bool_t force);
AliTPCCalROC* GetCalRoc(Int_t sector, TObjArray* arr, Bool_t force) const;
TVectorF* GetVectSector(Int_t sector, TObjArray *arr, UInt_t size, Bool_t force=kFALSE) const;
TVectorF* GetPadTimesEvent(Int_t sector, Bool_t force=kFALSE);
TObjArray* GetParamArray(Int_t sector, TObjArray *arr, Bool_t force=kFALSE) const;
void ResetPad();
void ProcessPad();
void CreateDVhist();
void FindLaserLayers();
Bool_t IsPeakInRange(UShort_t timebin, Int_t roc) const;
TObjArray *SetupMeasured();
void ResetMeasured(TObjArray * const arr);
void AddCEtoIdeal(TObjArray *arr);
void CalculateDV(TObjArray * const arrIdeal, TObjArray * const arrMeasured, Int_t burst);
Double_t SetBurstHnDrift();
TVectorF* GetPadQEvent(Int_t sector, Bool_t force=kFALSE);
TVectorF* GetPadRMSEvent(Int_t sector, Bool_t force=kFALSE);
TVectorF* GetPadPedestalEvent(Int_t sector, Bool_t force=kFALSE);
ClassDef(AliTPCCalibCE,10)
};
inline Bool_t AliTPCCalibCE::IsPeakInRange(UShort_t timebin, Int_t roc) const
{
Int_t side=(roc/18)%2;
Int_t add=7*side;
if (fPeaks[13]<2) return kTRUE;
for (Int_t i=add; i<add+7; ++i){
if (TMath::Abs((Short_t)timebin-(Short_t)fPeaks[i])<(Short_t)fPeakWidths[i]) return kTRUE;
}
return kFALSE;
}
#endif