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