clusterizer,reconstructor + many fixes (Magnus,Stefan)
[u/mrichter/AliRoot.git] / ITS / UPGRADE / AliITSUClusterizer.cxx
1 #include "AliITSUClusterizer.h"
2
3
4 ClassImp(AliITSUClusterizer)
5
6 //______________________________________________________________________________
7 AliITSUClusterizer::AliITSUClusterizer(Int_t initNRow) 
8 :  fVolID(-1)
9   ,fSegm(0)
10   ,fInputDigits(0)
11   ,fInputDigitsReadIndex(0)
12   ,fOutputClusters(0)
13   ,fDigitFreelist(0)
14   ,fPartFreelist(0)
15   ,fCandFreelist(0)
16   ,fDigitFreelistBptrFirst(0)
17   ,fDigitFreelistBptrLast(0)
18   ,fPartFreelistBptr(0)
19   ,fCandFreelistBptr(0)
20 {
21   SetUniqueID(0);
22   // c-tor
23   SetNRow(initNRow);
24 }
25
26 //______________________________________________________________________________
27 void AliITSUClusterizer::SetSegmentation(const AliITSUSegmentationPix *segm) 
28 {
29   // attach segmentation, if needed, reinitialize array
30   fSegm = segm;
31   SetNRow(fSegm->GetNRow()); // reinitialize if needed
32
33 }
34
35 //______________________________________________________________________________
36 void AliITSUClusterizer::SetNRow(Int_t nr)
37 {
38   // update buffers
39   int nrOld = GetUniqueID();
40   if (nrOld>=nr) return;
41   SetUniqueID(nr);
42   while (fDigitFreelistBptrFirst) {
43     AliITSUClusterizerClusterDigit *next = fDigitFreelistBptrFirst[kDigitChunkSize-1].fNext;
44     delete[] fDigitFreelistBptrFirst;
45     fDigitFreelistBptrFirst=next;
46   }
47   delete[] fPartFreelistBptr;
48   delete[] fCandFreelistBptr;
49   //
50   fPartFreelist=fPartFreelistBptr = new AliITSUClusterizerClusterPart[nr+1];
51   fCandFreelist=fCandFreelistBptr = new AliITSUClusterizerClusterCand[nr+1];
52   for (int i=0;i<nr;++i) {
53     fPartFreelistBptr[i].fNextInRow = &fPartFreelistBptr[i+1];
54     fCandFreelistBptr[i].fNext      = &fCandFreelistBptr[i+1];
55   }  
56 }
57
58 //______________________________________________________________________________
59 AliITSUClusterizer::~AliITSUClusterizer() 
60 {
61   // d-tor
62   while (fDigitFreelistBptrFirst) {
63     AliITSUClusterizerClusterDigit *next = fDigitFreelistBptrFirst[kDigitChunkSize-1].fNext;
64     delete[] fDigitFreelistBptrFirst;
65     fDigitFreelistBptrFirst=next;
66   }
67   delete[] fPartFreelistBptr;
68   delete[] fCandFreelistBptr;
69 }
70
71 //______________________________________________________________________________
72 AliITSUClusterizer::AliITSUClusterizerClusterDigit* AliITSUClusterizer::AllocDigitFreelist() 
73 {
74   // allocate aux space
75   AliITSUClusterizerClusterDigit *tmp = new AliITSUClusterizerClusterDigit[kDigitChunkSize];
76   for (int i=0;i<kDigitChunkSize-2;++i) tmp[i].fNext=&tmp[i+1];
77   tmp[kDigitChunkSize-2].fNext=0;
78   tmp[kDigitChunkSize-1].fNext=0;
79   if (!fDigitFreelistBptrFirst) fDigitFreelistBptrFirst=tmp;
80   else                          fDigitFreelistBptrLast[kDigitChunkSize-1].fNext=tmp;
81   fDigitFreelistBptrLast=tmp;
82   return tmp;
83 }
84
85 //______________________________________________________________________________
86 AliITSUClusterizer::AliITSUClusterizerClusterDigit* AliITSUClusterizer::NextDigit() 
87 {
88   // get next digit
89   if (fInputDigitsReadIndex<fInputDigits->GetEntriesFast()) {
90     AliITSdigit *tmp=static_cast<AliITSdigit*>(fInputDigits->UncheckedAt(fInputDigitsReadIndex++));
91     AliITSUClusterizerClusterDigit *digit=AllocDigit();
92     digit->fDigit=tmp;
93     // IMPORTANT: A lexiographical order (fV,fU) is assumed
94     digit->fU=tmp->GetCoord1();
95     digit->fV=tmp->GetCoord2();
96     return digit;
97   }
98   else
99     return 0;
100 }
101
102 //______________________________________________________________________________
103 void AliITSUClusterizer::AttachPartToCand(AliITSUClusterizerClusterCand *cand,AliITSUClusterizerClusterPart *part) 
104 {
105   // attach part
106   part->fParent = cand;
107   part->fPrevInCluster = 0;
108   part->fNextInCluster = cand->fFirstPart;
109   if (cand->fFirstPart) cand->fFirstPart->fPrevInCluster = part;
110   cand->fFirstPart=part;
111 }
112
113 //______________________________________________________________________________
114 void AliITSUClusterizer::MergeCands(AliITSUClusterizerClusterCand *a,AliITSUClusterizerClusterCand *b) 
115 {
116   // merge cluster parts
117   AliITSUClusterizerClusterPart *ipart=b->fFirstPart; 
118   AliITSUClusterizerClusterPart *jpart; 
119   do {
120     jpart=ipart;
121     jpart->fParent=a;
122   } while ((ipart=ipart->fNextInCluster));
123   jpart->fNextInCluster=a->fFirstPart;
124   jpart->fNextInCluster->fPrevInCluster=jpart;
125   a->fFirstPart=b->fFirstPart;
126   // merge digits
127   b->fLastDigit->fNext=a->fFirstDigit;
128   a->fFirstDigit=b->fFirstDigit;
129   //  DeallocCand(b);
130 }
131
132 //______________________________________________________________________________
133 void AliITSUClusterizer::Transform(AliCluster *cluster,AliITSUClusterizerClusterCand *cand) 
134 {
135   // convert set of digits to clusted data
136   Double_t su=0.,sv=0.;
137   Int_t n=0;
138   cand->fLastDigit->fNext=0;
139   for (AliITSUClusterizerClusterDigit *idigit=cand->fFirstDigit;idigit;idigit=idigit->fNext) {
140     su+=idigit->fU;
141     sv+=idigit->fV;
142     ++n;
143   }
144   Double_t fac=1./n; // Todo: weighting by signal
145   Double_t detX = fac*sv, detZ = fac*su;
146   
147   // Set local coordinates
148   Float_t x = detX, z = detZ;
149   if (fSegm) { // local coordinates in cm
150     x = (-0.5*fSegm->Dx() + detX*fSegm->Dpx() + 0.5*fSegm->Dpx());
151     z = (-0.5*fSegm->Dz() + detZ*fSegm->Dpz(0)+ 0.5*fSegm->Dpz(0));
152   }
153   cluster->SetX(x);
154   cluster->SetZ(z);
155   // Set Volume id
156   cluster->SetVolumeId(fVolID);
157   //    printf("mod %d: (%.4lf,%.4lf)cm\n",fVolID,x,z);
158 }
159
160 //______________________________________________________________________________
161 void AliITSUClusterizer::CloseCand(AliITSUClusterizerClusterCand *cand) 
162 {
163   // finish cluster
164   AliCluster *cluster=NextCluster();
165   Transform(cluster,cand);
166   DeallocDigits(cand->fFirstDigit,cand->fLastDigit);
167   DeallocCand(cand);
168 }
169
170 //______________________________________________________________________________
171 void AliITSUClusterizer::ClosePart(AliITSUClusterizerClusterPart *part) 
172 {
173   // finish cluster part
174   AliITSUClusterizerClusterCand *cand=part->fParent;
175   DetachPartFromCand(cand,part);
176   DeallocPart(part);
177   if (!cand->fFirstPart) CloseCand(cand); 
178 }
179
180 //______________________________________________________________________________
181 void AliITSUClusterizer::CloseRemainingParts(AliITSUClusterizerClusterPart *part) 
182 {
183   // finish what is left
184   while (part) {
185     AliITSUClusterizerClusterPart *next=part->fNextInRow;
186     ClosePart(part);
187     part=next;
188   } 
189 }
190
191 //______________________________________________________________________________
192 void AliITSUClusterizer::Clusterize() 
193 {
194   // main algo
195   AliITSUClusterizerClusterDigit *iDigit=NextDigit();
196   AliITSUClusterizerClusterPart *iPrevRowBegin=0;
197   AliITSUClusterizerClusterPart *iNextRowBegin=0;
198   AliITSUClusterizerClusterPart *iPrevRow=0;
199   AliITSUClusterizerClusterPart *iNextRow=0;
200   Int_t lastV=0;
201   while (iDigit) {
202     if (iDigit->fV!=lastV) {
203       // NEW ROW
204       if (iNextRow) iNextRow->fNextInRow=0;
205       if (iPrevRowBegin) CloseRemainingParts(iPrevRowBegin);
206       if (iDigit->fV==lastV+1) {
207         iPrevRowBegin=iNextRowBegin;
208         iPrevRow     =iNextRowBegin;
209       }
210       else {
211         // there was an empty row
212         CloseRemainingParts(iNextRowBegin);
213         iPrevRowBegin=0;
214         iPrevRow     =0;
215       }
216       iNextRowBegin=0;
217       iNextRow     =0;
218       lastV=iDigit->fV; 
219     }
220     // skip cluster parts before this digit
221     while (iPrevRow && iPrevRow->fUEnd<iDigit->fU) {
222       iPrevRow=iPrevRow->fNextInRow;
223     }
224     // find the longest continous line of digits [iDigit,pDigit]=[iDigit,jDigit)
225     AliITSUClusterizerClusterCand *cand=AllocCand(); 
226     AliITSUClusterizerClusterDigit *pDigit=iDigit;
227     AliITSUClusterizerClusterDigit *jDigit=NextDigit();
228     cand->fFirstPart=0;
229     cand->fFirstDigit=cand->fLastDigit=iDigit; // NB: first diggit is attached differently
230     iDigit->fNext=0;
231     Int_t lastU =iDigit->fU;
232     Int_t lastU1=lastU+1;
233     while (jDigit && jDigit->fU==lastU1 && jDigit->fV==lastV) {
234       pDigit=jDigit;
235       jDigit=NextDigit();
236       AttachDigitToCand(cand,pDigit);
237       ++lastU1;
238     }
239     --lastU1;
240     AliITSUClusterizerClusterPart *part=AllocPart();
241     part->fUBegin=lastU ;
242     part->fUEnd  =lastU1;
243     AttachPartToCand(cand,part);
244     // merge all cluster candidates of the previous line touching this one,
245     // advance to the last one, but keep that one the next active one
246     AliITSUClusterizerClusterPart *jPrevRow=iPrevRow;
247     while (jPrevRow && jPrevRow->fUBegin<=lastU1) {
248       if (jPrevRow->fParent!=cand) {
249         MergeCands(jPrevRow->fParent,cand);
250         DeallocCand(cand);
251         cand=jPrevRow->fParent;
252       }
253       iPrevRow=jPrevRow;
254       jPrevRow=jPrevRow->fNextInRow;
255     }
256     if (iNextRow)
257       iNextRow->fNextInRow=part;
258     else
259       iNextRowBegin=part;
260     iNextRow=part;
261     iDigit=jDigit;
262   }
263   // remove remaining cluster parts
264   CloseRemainingParts(iPrevRowBegin);
265   if (iNextRow) iNextRow->fNextInRow=0;
266   CloseRemainingParts(iNextRowBegin);
267   return;
268 }