Updates for EMCal
[u/mrichter/AliRoot.git] / HLT / TPCLib / HWCFemulator / AliHLTTPCHWClusterMerger.h
1 //-*- Mode: C++ -*-
2 // $Id$
3
4 #ifndef ALIHLTTPCHWCLUSTERMERGER_H
5 #define ALIHLTTPCHWCLUSTERMERGER_H
6 //* This file is property of and copyright by the ALICE HLT Project        * 
7 //* ALICE Experiment at CERN, All rights reserved.                         *
8 //* See cxx source for full Copyright notice                               *
9
10 //  @file   AliHLTTPCHWClusterMerger.h
11 //  @author Matthias Richter, Sergey Gorbunov
12 //  @date   2011-11-25
13 //  @brief  Merger class for HLT TPC Hardware clusters
14 //          Handles merging of branch border clusters
15
16 #include "AliHLTTPCRawCluster.h"
17 #include "AliHLTLogging.h"
18 #include <vector>
19 #include "TObject.h"
20
21 /**
22  * @class AliHLTTPCHWClusterMerger
23  *
24  * @ingroup alihlt_base
25  */
26 class AliHLTTPCHWClusterMerger : public AliHLTLogging
27 {
28  public:
29   /// standard constructor
30   AliHLTTPCHWClusterMerger();
31   /// destructor
32   ~AliHLTTPCHWClusterMerger();
33
34   void Init();
35
36   //////////////////////////////////////////////////////////////////////////////////////////////////////////
37   //////////////////////////////////////////////////////////////////////////////////////////////////////////
38
39   /// check if a cluster is a candidate for merging
40   template<typename T> 
41   bool CheckCandidate(int slice, int partition, const T& c) {
42     return CheckCandidate(slice, partition, c.GetPadRow(), c.GetPad(), c.GetTime(), c.GetSigmaY2() );
43   }
44
45   /// check if a cluster is a candidate for merging
46   bool CheckCandidate(int slice,
47                       int partition,
48                       int partitionrow, // local row in partition
49                       float pad,
50                       float time,
51                       float sigmaPad2) ;
52
53   /// cache cluster for later merging
54   template<typename T> 
55   int AddCandidate(int slice,
56                    int partition,
57                    AliHLTUInt32_t id,
58                    const T& c) {
59     return AddCandidate(slice,
60                         partition,
61                         c.GetPadRow(),
62                         c.GetPad(),
63                         c.GetTime(),
64                         c.GetSigmaY2(),
65                         c.GetSigmaZ2(),
66                         c.GetCharge(),
67                         c.GetQMax(),
68                         id
69                         );
70   }
71
72   /// cache cluster for later merging
73   int AddCandidate(int slice,
74                    int partition,
75                    short partitionrow, // local row in the partition
76                    float pad,
77                    float time,
78                    float sigmaY2,
79                    float sigmaZ2,
80                    unsigned short charge,
81                    unsigned short qmax,
82                    AliHLTUInt32_t id=~AliHLTUInt32_t(0)
83                    );
84
85   /// merge clusters
86   int Merge();
87
88   /// cleanup
89   void Clear();
90
91   //////////////////////////////////////////////////////////////////////////////////////////////////////////
92   //////////////////////////////////////////////////////////////////////////////////////////////////////////
93
94   /// helper class to store relevant data for a cluster at border
95   struct AliBorderRecord {
96     AliHLTInt64_t fClusterRecordID;
97     AliHLTUInt32_t fTimeBin;    
98   };
99  
100   
101   /// helper class to store relevant data for a cluster candidate
102   class AliClusterRecord {
103   public:
104     AliClusterRecord()
105       : fSlice(-1), fPartition(-1), fBorder(-1), fMergedFlag(0), fId(~AliHLTUInt32_t(0)), fCluster() {}
106     AliClusterRecord(int slice, int partition, int border,bool merged, AliHLTUInt32_t id, AliHLTTPCRawCluster cluster)
107       : fSlice(slice), fPartition(partition), fBorder(border), fMergedFlag(merged), fId(id), fCluster(cluster) {}
108     AliClusterRecord(const AliClusterRecord& other)
109       : fSlice(other.fSlice), fPartition(other.fPartition), fBorder(other.fBorder), fMergedFlag(other.fMergedFlag), fId(other.fId), fCluster(other.fCluster) {}
110     AliClusterRecord& operator=(const AliClusterRecord& other) {
111       if (this==&other) return *this;
112       this->~AliClusterRecord();
113       new (this) AliClusterRecord(other);
114       return *this;
115     }
116
117     ~AliClusterRecord() {}    
118     
119     AliClusterRecord& operator=(const AliHLTTPCRawCluster& c) {
120       fCluster=c;
121       return *this;
122     }
123
124     bool GetMergedFlag() const { return fMergedFlag; }
125     int GetSlice() const {return fSlice;}
126     int GetBorder() const {return fBorder;}
127     int GetPartition() const {return fPartition;}
128     AliHLTUInt32_t GetId() const {return fId;}
129     operator AliHLTTPCRawCluster() const {return fCluster;}
130     const AliHLTTPCRawCluster& GetCluster() const {return fCluster;}
131     void SetMergedFlag(bool v ){ fMergedFlag = v;}
132     AliHLTTPCRawCluster &Cluster(){ return fCluster; }
133   private:
134     int fSlice; //!
135     int fPartition; //!
136     int fBorder; //!
137     bool fMergedFlag; //!
138     AliHLTUInt32_t fId; //!
139     AliHLTTPCRawCluster fCluster; //!
140   };
141
142   //////////////////////////////////////////////////////////////////////////////////////////////////////////
143   //////////////////////////////////////////////////////////////////////////////////////////////////////////
144
145   /// iterator class to access merged and remaining clusters
146   class iterator {
147   public:
148     iterator() : fArray(NULL), fIter() {}
149     iterator(vector<AliClusterRecord>* pArray) : fArray(pArray), fIter() {if (fArray) fIter=fArray->begin();}
150     iterator(const iterator& other) : fArray(other.fArray), fIter(other.fIter) {}
151     iterator& operator=(const iterator& other) {
152       if (this==&other) return *this;
153       fArray=other.fArray; fIter=other.fIter; return *this;
154     }
155     ~iterator() {}
156
157     AliClusterRecord operator*() {return *fIter;}
158
159     // prefix operators
160     iterator& operator++() {
161       if (!fArray || fIter==fArray->end()) return *this;
162       while ((++fIter)!=fArray->end()) {
163         // cout<<"Read flag: "<<fIter->GetMergedFlag()<<endl;
164         if (!fIter->GetMergedFlag() ) break;    
165       }      
166       return *this;
167     }
168     iterator& operator--() {
169       if (!fArray) return *this;
170       while (fIter!=fArray->begin()) {
171         --fIter;
172         if (!fIter->GetMergedFlag()) break;     
173       }
174       return *this;
175     }
176
177     // postfix operators
178     iterator operator++(int) {iterator i(*this); this->operator++(); return i;}
179     iterator operator--(int) {iterator i(*this); this->operator--(); return i;}
180
181     iterator& operator+=(int step) {
182       if (!fArray) return *this;
183       while ((fIter)!=fArray->end() && step-->0) {++fIter;}
184       return *this;
185     }
186
187     bool operator==(const iterator& other) {
188       return (other.fArray!=NULL && fArray!=NULL && other.fIter==fIter);
189     }
190
191     bool operator!=(const iterator& other) {
192       return (other.fArray!=NULL && fArray!=NULL && other.fIter!=fIter);
193     }
194
195   protected:
196   private:
197     vector<AliClusterRecord>* fArray; //!
198     vector<AliClusterRecord>::iterator fIter; //!
199   };
200
201   //////////////////////////////////////////////////////////////////////////////////////////////////////////
202   //////////////////////////////////////////////////////////////////////////////////////////////////////////
203
204   /// iterator function, start iteration
205   iterator& begin() {
206     fIter.~iterator();
207     new (&fIter) iterator(&fClusters);
208     fEnd=fIter;  fEnd+=fClusters.size();    
209     // skip empty (merged) clusters
210     while (fIter!=fEnd && (*fIter).GetMergedFlag() ) {
211       fIter++;
212     }
213     return fIter;
214   }
215
216   /// iterator function, end marker
217   iterator& end() {
218     return fEnd;
219   }
220
221   //////////////////////////////////////////////////////////////////////////////////////////////////////////
222   //////////////////////////////////////////////////////////////////////////////////////////////////////////
223
224  protected:
225
226  private:
227   /// copy constructor
228   AliHLTTPCHWClusterMerger(const AliHLTTPCHWClusterMerger&);
229   /// assignment operator
230   AliHLTTPCHWClusterMerger& operator=(const AliHLTTPCHWClusterMerger&);
231
232   int FillIndex();
233   static bool CompareTime( const AliBorderRecord &b1, const AliBorderRecord &b2){
234     return b1.fTimeBin > b2.fTimeBin;
235   }
236  
237
238   AliHLTInt16_t *fMapping;//!
239   int fNRows;//!
240   int fNRowPads;//!
241   int fNBorders;//!
242   AliHLTFloat32_t *fBorders; //!
243   int *fBorderNClusters; //!
244   int *fBorderFirstCluster; //!
245   AliBorderRecord *fBorderClusters;
246   int fBorderNClustersTotal; //!
247
248   vector<AliClusterRecord> fClusters; //! array of candidates
249   vector<AliHLTUInt32_t> fRemovedClusterIds; //! array of removed clusters by id
250   iterator fIter; //!
251   iterator fEnd; //!
252   static const int fkMergeWidth = 3;
253   static const int fkNSlices = 36;
254   static const int fkMergeTimeWindow = 2;
255   ClassDef(AliHLTTPCHWClusterMerger, 0)
256 };
257
258 #endif //ALIHLTTPCHWCLUSTERMERGER_H