#ifndef ALIITSUCLUSTERIZER_H
#define ALIITSUCLUSTERIZER_H
#include <TBits.h>
#include <TClonesArray.h>
#include "AliITSUClusterPix.h"
class TTree;
class TObjAray;
class AliITSUSegmentationPix;
class AliITSdigit;
class AliCluster;
class AliITSURecoParam;
class AliITSUClusterizer : public TObject
{
public:
enum {kDigitChunkSize=1024, kMaxLabels=20,kMaxLabInCluster=3};
enum {kMaskNZ=0xff,kMaskNX=0xff,kMaskNPix=0x1ff,kMaskClUse=0x7f};
AliITSUClusterizer(Int_t nrowInit=0);
virtual ~AliITSUClusterizer();
void SetRawData(Bool_t v=kTRUE) {fRawData = v;}
void Clusterize();
void SetSegmentation(const AliITSUSegmentationPix *segm);
void SetRecoParam(const AliITSURecoParam* param) {fRecoParam = param;}
void SetLayerID(Int_t id) {fLayerID = id;}
void SetVolID(Int_t id) {fVolID = id;}
void SetNRow(Int_t nrow);
void SetAllowDiagonalClusterization(Bool_t v) {fAllowDiagonalClusterization = v;}
void PrepareLorentzAngleCorrection(Double_t bz);
void MakeRecPointBranch(TTree *) {};
void SetRecPointTreeAddress(TTree *) {};
void DigitsToRecPoints(const TObjArray *) {};
void SetDigits(const TClonesArray *digits) {fInputDigits=digits;fInputDigitsReadIndex=0;}
void SetClusters(TClonesArray *clusters) {fOutputClusters=clusters;}
void AddLabel(int label);
void CheckLabels();
protected:
struct AliITSUClusterizerClusterDigit {
AliITSUClusterizerClusterDigit *fNext;
AliITSdigit *fDigit;
};
struct AliITSUClusterizerClusterCand;
struct AliITSUClusterizerClusterPart {
AliITSUClusterizerClusterPart *fNextInRow;
AliITSUClusterizerClusterPart *fPrevInCluster;
AliITSUClusterizerClusterPart *fNextInCluster;
AliITSUClusterizerClusterCand *fParent;
Int_t fUBegin;
Int_t fUEnd;
};
struct AliITSUClusterizerClusterCand {
AliITSUClusterizerClusterCand *fNext;
AliITSUClusterizerClusterPart *fFirstPart;
AliITSUClusterizerClusterDigit *fFirstDigit;
AliITSUClusterizerClusterDigit *fLastDigit ;
};
protected:
AliITSUClusterizerClusterDigit* AllocDigitFreelist();
AliITSUClusterizerClusterCand* AllocCand();
void DeallocCand(AliITSUClusterizerClusterCand *cand);
AliITSUClusterizerClusterPart* AllocPart();
void DeallocPart(AliITSUClusterizerClusterPart *part) {DeallocParts(part,part); }
void DeallocParts(AliITSUClusterizerClusterPart *first,AliITSUClusterizerClusterPart *last);
AliITSUClusterizerClusterDigit* AllocDigit();
void DeallocDigit(AliITSUClusterizerClusterDigit *digit) {DeallocDigits(digit,digit);}
void DeallocDigits(AliITSUClusterizerClusterDigit *first,AliITSUClusterizerClusterDigit *last);
AliITSUClusterizerClusterDigit* NextDigit();
AliCluster* NextCluster() {return (AliCluster*)fOutputClusters->New(fOutputClusters->GetEntriesFast());}
void SetAllowDiagonalClusterization();
void AttachDigitToCand(AliITSUClusterizerClusterCand *cand,AliITSUClusterizerClusterDigit *digit);
void AttachPartToCand(AliITSUClusterizerClusterCand *cand,AliITSUClusterizerClusterPart *part);
void DetachPartFromCand(AliITSUClusterizerClusterCand *cand,AliITSUClusterizerClusterPart *part);
void MergeCands(AliITSUClusterizerClusterCand *a,AliITSUClusterizerClusterCand *b);
void Transform(AliITSUClusterPix *cluster, AliITSUClusterizerClusterCand *cand);
void CloseCand(AliITSUClusterizerClusterCand *cand);
void ClosePart(AliITSUClusterizerClusterPart *part);
void CloseRemainingParts(AliITSUClusterizerClusterPart *part);
protected:
Int_t fVolID;
Bool_t fAllowDiagonalClusterization;
const AliITSUSegmentationPix* fSegm;
const AliITSURecoParam* fRecoParam;
const TClonesArray *fInputDigits;
Int_t fInputDigitsReadIndex;
Int_t fLayerID;
Int_t fCurrLabels[kMaxLabels];
Int_t fNLabels;
Bool_t fRawData;
Double_t fLorAngCorrection;
TClonesArray *fOutputClusters;
AliITSUClusterizerClusterDigit *fDigitFreelist ;
AliITSUClusterizerClusterPart *fPartFreelist ;
AliITSUClusterizerClusterCand *fCandFreelist ;
AliITSUClusterizerClusterDigit *fDigitFreelistBptrFirst;
AliITSUClusterizerClusterDigit *fDigitFreelistBptrLast ;
AliITSUClusterizerClusterPart *fPartFreelistBptr ;
AliITSUClusterizerClusterCand *fCandFreelistBptr ;
#ifdef _ClusterTopology_
TBits fTopology;
UShort_t fMinCol;
UShort_t fMinRow;
void FillClusterTopology(const AliITSUClusterizerClusterCand *cand, AliITSUClusterPix* cl) const;
#endif //_ClusterTopology_
private:
AliITSUClusterizer(const AliITSUClusterizer&);
AliITSUClusterizer& operator=(const AliITSUClusterizer&);
ClassDef(AliITSUClusterizer,0)
};
inline void AliITSUClusterizer::DeallocCand(AliITSUClusterizerClusterCand *cand)
{
cand->fNext=fCandFreelist;
fCandFreelist=cand;
}
inline void AliITSUClusterizer::DeallocParts(AliITSUClusterizerClusterPart *first,AliITSUClusterizerClusterPart *last)
{
last->fNextInRow=fPartFreelist;
fPartFreelist=first;
}
inline AliITSUClusterizer::AliITSUClusterizerClusterDigit* AliITSUClusterizer::AllocDigit()
{
if (!fDigitFreelist) fDigitFreelist = AllocDigitFreelist();
AliITSUClusterizerClusterDigit *digit = fDigitFreelist;
fDigitFreelist = fDigitFreelist->fNext;
return digit;
}
inline AliITSUClusterizer::AliITSUClusterizerClusterPart* AliITSUClusterizer::AllocPart()
{
AliITSUClusterizerClusterPart *part=fPartFreelist;
fPartFreelist=fPartFreelist->fNextInRow;
return part;
}
inline AliITSUClusterizer::AliITSUClusterizerClusterCand* AliITSUClusterizer::AllocCand()
{
AliITSUClusterizerClusterCand *cand=fCandFreelist;
fCandFreelist=fCandFreelist->fNext;
return cand;
}
inline void AliITSUClusterizer::DeallocDigits(AliITSUClusterizerClusterDigit *first, AliITSUClusterizerClusterDigit *last)
{
last->fNext = fDigitFreelist;
fDigitFreelist = first;
}
inline void AliITSUClusterizer::AttachDigitToCand(AliITSUClusterizerClusterCand *cand,AliITSUClusterizerClusterDigit *digit)
{
digit->fNext = cand->fFirstDigit;
cand->fFirstDigit = digit;
}
inline void AliITSUClusterizer::DetachPartFromCand(AliITSUClusterizerClusterCand *cand,AliITSUClusterizerClusterPart *part)
{
if (part->fPrevInCluster) part->fPrevInCluster->fNextInCluster=part->fNextInCluster;
else cand->fFirstPart=part->fNextInCluster;
if (part->fNextInCluster) part->fNextInCluster->fPrevInCluster=part->fPrevInCluster;
}
inline void AliITSUClusterizer::AddLabel(int label)
{
if (fNLabels==kMaxLabels) return;
for (int i=fNLabels;i--;) if (fCurrLabels[i]==label) return;
fCurrLabels[fNLabels++] = label;
}
#endif