#ifndef ALITPCCLUSTERER_H
#define ALITPCCLUSTERER_H
#include <Rtypes.h>
#include <TObject.h>
#include <AliTPCRecoParam.h>
#define kMAXCLUSTER 2500
class TFile;
class TClonesArray;
class AliTPCParam;
class AliTPCRecoParam;
class AliTPCclusterMI;
class AliTPCClustersRow;
class AliRawReader;
class AliSimDigits;
class TTree;
class TTreeSRedirector;
class AliRawEventHeaderBase;
class AliTPCCalROC;
class AliTPCclusterer : public TObject{
public:
AliTPCclusterer(const AliTPCParam* par, const AliTPCRecoParam * recoParam = 0);
virtual ~AliTPCclusterer();
virtual void Digits2Clusters();
virtual void Digits2Clusters(AliRawReader* rawReader);
virtual void SetInput(TTree * tree);
virtual void SetOutput(TTree * tree);
virtual void FillRow();
TObjArray * GetOutputArray(){return fOutputArray;}
TClonesArray * GetOutputClonesArray(){return fOutputClonesArray;}
void StoreInClonesArray(Bool_t bOutput = kTRUE) {fBClonesArray = bOutput;}
void SetUseHLTClusters(Int_t useHLTClusters) {fUseHLTClusters = useHLTClusters;}
private:
AliTPCclusterer(const AliTPCclusterer ¶m);
AliTPCclusterer &operator = (const AliTPCclusterer & param);
Bool_t IsMaximum(Float_t k, Int_t max, const Float_t *bins) const;
void MakeCluster2(Int_t k,Int_t max,Float_t *bins,UInt_t m,
AliTPCclusterMI &c);
void MakeCluster(Int_t k,Int_t max,Float_t *bins,UInt_t m,
AliTPCclusterMI &c);
Float_t GetSigmaY2(Int_t iz);
Float_t GetSigmaZ2(Int_t iz);
Float_t FitMax(Float_t vmatrix[5][5], Float_t y, Float_t z, Float_t sigmay, Float_t sigmaz);
void AddCluster(AliTPCclusterMI &c, Float_t *matrix, Int_t pos);
void UnfoldCluster(Float_t * matrix[7], Float_t recmatrix[5][5],
Float_t & meani, Float_t & meanj, Float_t & sum, Float_t &overlap );
void FindClusters(AliTPCCalROC * noiseROC);
Bool_t AcceptCluster(AliTPCclusterMI*c);
Double_t ProcesSignal(Float_t * signal, Int_t nchannels, Int_t id[3], Double_t &rms, Double_t &pedestalCalib);
void ProcessSectorData();
Int_t ReadHLTClusters();
Float_t * fBins;
Int_t * fSigBins;
Int_t fNSigBins;
Int_t fLoop;
Int_t fMaxBin;
Int_t fMaxTime;
Int_t fMaxPad;
Int_t fSector;
Int_t fRow;
Float_t fSign;
Float_t fRx;
Float_t fPadWidth;
Float_t fPadLength;
Float_t fZWidth;
Bool_t fPedSubtraction;
AliRawEventHeaderBase *fEventHeader;
UInt_t fTimeStamp;
UInt_t fEventType;
TTree * fInput;
TTree * fOutput;
TObjArray *fOutputArray;
TClonesArray *fOutputClonesArray;
AliTPCClustersRow * fRowCl;
AliSimDigits * fRowDig;
const AliTPCParam * fParam;
Int_t fNcluster;
Int_t fNclusters;
TTreeSRedirector *fDebugStreamer;
const AliTPCRecoParam * fRecoParam;
Bool_t fBDumpSignal;
Bool_t fBClonesArray;
Int_t fUseHLTClusters;
Float_t** fAllBins;
Int_t** fAllSigBins;
Int_t* fAllNSigBins;
TObject* fHLTClusterAccess;
ClassDef(AliTPCclusterer,0)
};
inline Bool_t AliTPCclusterer::IsMaximum(Float_t q,Int_t max,const Float_t *bins) const {
if (bins[-max] >= q) return kFALSE;
if (bins[-1 ] >= q) return kFALSE;
if (bins[+max] > q) return kFALSE;
if (bins[+1 ] > q) return kFALSE;
if (bins[-max-1] >= q) return kFALSE;
if (bins[+max-1] >= q) return kFALSE;
if (bins[+max+1] > q) return kFALSE;
if (bins[-max+1] >= q) return kFALSE;
if (fRecoParam->GetClusterMaxRange(1)>0){
if (bins[-2] > q) return kFALSE;
if (bins[ 2] > q) return kFALSE;
}
if (fRecoParam->GetClusterMaxRange(0)>0){
if (bins[-2*max] > q) return kFALSE;
if (bins[ 2*max] > q) return kFALSE;
}
return kTRUE;
}
#endif