]>
Commit | Line | Data |
---|---|---|
326c2d4b | 1 | // @(#) $Id$ |
d54804bf | 2 | //*************************************************************************** |
3 | // This file is property of and copyright by the ALICE HLT Project * | |
4 | // ALICE Experiment at CERN, All rights reserved. * | |
5 | // * | |
6 | // Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> * | |
7 | // Ivan Kisel <kisel@kip.uni-heidelberg.de> * | |
8 | // for The ALICE HLT Project. * | |
9 | // * | |
10 | // Permission to use, copy, modify and distribute this software and its * | |
11 | // documentation strictly for non-commercial purposes is hereby granted * | |
12 | // without fee, provided that the above copyright notice appears in all * | |
13 | // copies and that both the copyright notice and this permission notice * | |
14 | // appear in the supporting documentation. The authors make no claims * | |
15 | // about the suitability of this software for any purpose. It is * | |
16 | // provided "as is" without express or implied warranty. * | |
17 | //*************************************************************************** | |
326c2d4b | 18 | |
19 | #include "AliHLTTPCCATracker.h" | |
20 | ||
21 | #include "AliHLTTPCCAHit.h" | |
22 | #include "AliHLTTPCCACell.h" | |
d54804bf | 23 | #include "AliHLTTPCCAEndPoint.h" |
326c2d4b | 24 | #include "AliHLTTPCCAOutTrack.h" |
d54804bf | 25 | #include "AliHLTTPCCAGrid.h" |
26 | #include "AliHLTTPCCARow.h" | |
27 | #include "AliHLTTPCCATrack.h" | |
326c2d4b | 28 | |
29 | #include "TMath.h" | |
d54804bf | 30 | #include "Riostream.h" |
31 | //#include <algo.h> | |
dc4788ec | 32 | #include "TStopwatch.h" |
d54804bf | 33 | |
326c2d4b | 34 | //#define DRAW |
35 | ||
36 | #ifdef DRAW | |
d54804bf | 37 | #include "AliHLTTPCCADisplay.h" |
38 | #include "TApplication.h" | |
326c2d4b | 39 | #endif //DRAW |
40 | ||
dc4788ec | 41 | ClassImp(AliHLTTPCCATracker) |
326c2d4b | 42 | |
43 | ||
44 | AliHLTTPCCATracker::AliHLTTPCCATracker() | |
d54804bf | 45 | :fParam(),fRows(0),fOutTrackHits(0),fNOutTrackHits(0),fOutTracks(0),fNOutTracks(0),fNHitsTotal(0),fTracks(0),fNTracks(0),fCellHitPointers(0),fCells(0),fEndPoints(0) |
326c2d4b | 46 | { |
47 | // constructor | |
48 | fRows = new AliHLTTPCCARow[fParam.NRows()]; | |
49 | Initialize( fParam ); | |
50 | } | |
51 | ||
52 | AliHLTTPCCATracker::AliHLTTPCCATracker( const AliHLTTPCCATracker& ) | |
d54804bf | 53 | :fParam(),fRows(0),fOutTrackHits(0),fNOutTrackHits(0),fOutTracks(0),fNOutTracks(0),fNHitsTotal(0),fTracks(0),fNTracks(0),fCellHitPointers(0),fCells(0),fEndPoints(0) |
326c2d4b | 54 | { |
55 | // dummy | |
56 | } | |
57 | ||
58 | AliHLTTPCCATracker &AliHLTTPCCATracker::operator=( const AliHLTTPCCATracker& ) | |
59 | { | |
60 | // dummy | |
dc4788ec | 61 | fRows=0; |
62 | fOutTrackHits=0; | |
63 | fOutTracks=0; | |
64 | fNOutTracks=0; | |
ce622827 | 65 | return *this; |
326c2d4b | 66 | } |
67 | ||
68 | AliHLTTPCCATracker::~AliHLTTPCCATracker() | |
69 | { | |
70 | // destructor | |
71 | StartEvent(); | |
72 | delete[] fRows; | |
73 | } | |
74 | ||
75 | // ---------------------------------------------------------------------------------- | |
76 | void AliHLTTPCCATracker::Initialize( AliHLTTPCCAParam ¶m ) | |
77 | { | |
78 | // initialosation | |
79 | StartEvent(); | |
80 | delete[] fRows; | |
81 | fRows = 0; | |
82 | fParam = param; | |
83 | fParam.Update(); | |
84 | fRows = new AliHLTTPCCARow[fParam.NRows()]; | |
d54804bf | 85 | Float_t xStep = 1; |
86 | Float_t deltaY = TMath::Tan(fParam.CellConnectionAngleXY()); | |
87 | Float_t deltaZ = TMath::Tan(fParam.CellConnectionAngleXZ()); | |
326c2d4b | 88 | for( Int_t irow=0; irow<fParam.NRows(); irow++ ){ |
d54804bf | 89 | fRows[irow].X() = fParam.RowX(irow); |
90 | if( irow < fParam.NRows()-1 ) xStep = fParam.RowX(irow+1) - fParam.RowX(irow); | |
91 | fRows[irow].DeltaY() = xStep*deltaY; | |
92 | fRows[irow].DeltaZ() = xStep*deltaZ; | |
93 | fRows[irow].MaxY() = TMath::Tan( fParam.DAlpha()/2.)*fRows[irow].X(); | |
326c2d4b | 94 | } |
95 | StartEvent(); | |
96 | } | |
97 | ||
98 | void AliHLTTPCCATracker::StartEvent() | |
99 | { | |
100 | // start new event and fresh the memory | |
d54804bf | 101 | |
102 | if( fTracks ) delete[] fTracks; | |
103 | if( fOutTrackHits ) delete[] fOutTrackHits; | |
104 | if( fOutTracks ) delete[] fOutTracks; | |
105 | if( fCellHitPointers ) delete[] fCellHitPointers; | |
106 | if( fCells ) delete[] fCells; | |
107 | if( fEndPoints ) delete[] fEndPoints; | |
326c2d4b | 108 | fTracks = 0; |
326c2d4b | 109 | fOutTrackHits = 0; |
110 | fOutTracks = 0; | |
d54804bf | 111 | fCellHitPointers = 0; |
112 | fCells = 0; | |
113 | fEndPoints = 0; | |
326c2d4b | 114 | fNTracks = 0; |
115 | fNOutTrackHits = 0; | |
116 | fNOutTracks = 0; | |
117 | fNHitsTotal = 0; | |
118 | for( Int_t irow=0; irow<fParam.NRows(); irow++ ){ | |
119 | fRows[irow].Clear(); | |
120 | } | |
121 | } | |
122 | ||
123 | ||
124 | void AliHLTTPCCATracker::ReadHitRow( Int_t iRow, AliHLTTPCCAHit *Row, Int_t NHits ) | |
125 | { | |
126 | // read row of hits | |
127 | AliHLTTPCCARow &row = fRows[iRow]; | |
128 | row.Hits() = new AliHLTTPCCAHit[NHits]; | |
129 | for( Int_t i=0; i<NHits; i++ ){ | |
130 | row.Hits()[i]=Row[i]; | |
131 | row.Hits()[i].ErrY()*= fParam.YErrorCorrection(); | |
132 | row.Hits()[i].ErrZ()*= fParam.ZErrorCorrection(); | |
133 | } | |
134 | row.NHits() = NHits; | |
135 | fNHitsTotal += NHits; | |
136 | } | |
137 | ||
138 | void AliHLTTPCCATracker::Reconstruct() | |
139 | { | |
d54804bf | 140 | //* reconstruction of event |
141 | ||
142 | #ifdef DRAW | |
143 | if( !gApplication ){ | |
144 | TApplication *myapp = new TApplication("myapp",0,0); | |
145 | } | |
146 | //AliHLTTPCCADisplay::Instance().Init(); | |
147 | ||
148 | AliHLTTPCCADisplay::Instance().SetCurrentSector( this ); | |
149 | AliHLTTPCCADisplay::Instance().SetSectorView(); | |
150 | AliHLTTPCCADisplay::Instance().DrawSector( this ); | |
151 | for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ ) | |
152 | for (Int_t i = 0; i<fRows[iRow].NHits(); i++) | |
153 | AliHLTTPCCADisplay::Instance().DrawHit( iRow, i ); | |
154 | AliHLTTPCCADisplay::Instance().Ask(); | |
155 | #endif | |
156 | ||
157 | //if( fParam.ISec()!=8 ) return; | |
158 | //if( fParam.ISec()!=8 ) return; | |
159 | //if( fParam.ISec()!=33 ) return; | |
160 | //if( fParam.ISec()!=2 ) return; | |
dc4788ec | 161 | fTimers[0] = 0; |
162 | fTimers[1] = 0; | |
163 | fTimers[2] = 0; | |
164 | fTimers[3] = 0; | |
d54804bf | 165 | fTimers[4] = 0; |
166 | fTimers[5] = 0; | |
167 | fTimers[6] = 0; | |
168 | if( fNHitsTotal < 1 ) return; | |
169 | ||
dc4788ec | 170 | //cout<<"Find Cells..."<<endl; |
326c2d4b | 171 | FindCells(); |
d54804bf | 172 | //cout<<"Merge Cells..."<<endl; |
173 | MergeCells(); | |
dc4788ec | 174 | //cout<<"Find Tracks..."<<endl; |
d54804bf | 175 | FindTracks(); |
176 | //cout<<"Find Tracks OK"<<endl; | |
dc4788ec | 177 | } |
326c2d4b | 178 | |
179 | ||
180 | void AliHLTTPCCATracker::FindCells() | |
181 | { | |
d54804bf | 182 | //* cell finder - neighbouring hits are grouped to cells |
326c2d4b | 183 | |
dc4788ec | 184 | TStopwatch timer; |
d54804bf | 185 | |
dc4788ec | 186 | fCellHitPointers = new Int_t [fNHitsTotal]; |
d54804bf | 187 | fCells = new AliHLTTPCCACell[fNHitsTotal]; |
188 | fEndPoints = new AliHLTTPCCAEndPoint[fNHitsTotal]; | |
189 | ||
190 | struct THitCont{ | |
191 | Float_t Ymin, Ymax, Zmin, Zmax; | |
192 | Int_t binYmin, binYmax, binZmin, binZmax; | |
193 | Bool_t used; | |
194 | AliHLTTPCCAHit *h; | |
195 | THitCont *next; | |
196 | }; | |
197 | THitCont *hitCont = new THitCont[fNHitsTotal]; | |
dc4788ec | 198 | |
199 | Int_t lastCellHitPointer = 0; | |
d54804bf | 200 | Int_t lastCell = 0; |
201 | ||
326c2d4b | 202 | for( Int_t irow=0; irow<fParam.NRows(); irow++ ){ |
203 | AliHLTTPCCARow &row=fRows[irow]; | |
204 | Int_t nHits = row.NHits(); | |
d54804bf | 205 | //cout<<"row = "<<irow<<", x="<<row.X()<<endl; |
326c2d4b | 206 | if( nHits<1 ) continue; |
d54804bf | 207 | //cout<<nHits*sizeof(AliHLTTPCCAHit)/1024.<<endl; |
208 | ||
209 | Float_t deltaY = row.DeltaY(); | |
210 | Float_t deltaZ = row.DeltaZ(); | |
211 | ||
212 | Float_t yMin = 1.e20, zMin = 1.e20, yMax = -1.e20, zMax = -1.e20; | |
213 | for (Int_t ih = 0; ih<nHits; ih++){ | |
214 | AliHLTTPCCAHit &h = row.Hits()[ih]; | |
215 | if( yMin> h.Y() ) yMin = h.Y(); | |
216 | if( yMax< h.Y() ) yMax = h.Y(); | |
217 | if( zMin> h.Z() ) zMin = h.Z(); | |
218 | if( zMax< h.Z() ) zMax = h.Z(); | |
219 | } | |
220 | AliHLTTPCCAGrid grid; | |
221 | grid.Create( yMin, yMax, zMin, zMax, nHits ); | |
222 | //cout<<"row "<<irow<<", delta = "<<delta<<" :\n"<<endl; | |
223 | for (Int_t ih = 0; ih<nHits; ih++){ | |
224 | AliHLTTPCCAHit &h = row.Hits()[ih]; | |
225 | THitCont &cont = hitCont[ih]; | |
226 | THitCont *&bin = * ((THitCont **) grid.GetNoCheck(h.Y(),h.Z())); | |
227 | cont.h = &h; | |
228 | cont.used = 0; | |
229 | Float_t y = h.Y(); | |
230 | //cout<<"ih = "<<ih<<", y= "<<y<<endl; | |
231 | Float_t dY = 3.5*h.ErrY() + deltaY; | |
232 | cont.Ymin = y-dY; | |
233 | cont.Ymax = y+dY; | |
234 | Float_t z = h.Z(); | |
235 | Float_t dZ = 3.5*h.ErrZ() + deltaZ; | |
236 | cont.Zmin = z-dZ; | |
237 | cont.Zmax = z+dZ; | |
238 | cont.binYmin = (Int_t ) ( (cont.Ymin-dY-grid.YMin())*grid.StepYInv() ); | |
239 | cont.binYmax = (Int_t ) ( (cont.Ymax+dY-grid.YMin())*grid.StepYInv() ); | |
240 | cont.binZmin = (Int_t ) ( (cont.Zmin-dZ-grid.ZMin())*grid.StepZInv() ); | |
241 | cont.binZmax = (Int_t ) ( (cont.Zmax+dZ-grid.ZMin())*grid.StepZInv() ); | |
242 | if( cont.binYmin<0 ) cont.binYmin = 0; | |
243 | if( cont.binYmin>=grid.Ny() ) cont.binYmin = grid.Ny()-1; | |
244 | if( cont.binYmax<0 ) cont.binYmax = 0; | |
245 | if( cont.binYmax>=grid.Ny() ) cont.binYmax = grid.Ny()-1; | |
246 | if( cont.binZmin<0 ) cont.binZmin = 0; | |
247 | if( cont.binZmin>=grid.Nz() ) cont.binZmin = grid.Nz()-1; | |
248 | if( cont.binZmax<0 ) cont.binZmax = 0; | |
249 | if( cont.binZmax>=grid.Nz() ) cont.binZmax = grid.Nz()-1; | |
250 | cont.next = bin; | |
251 | bin = &cont; | |
252 | } | |
253 | ||
dc4788ec | 254 | row.CellHitPointers() = fCellHitPointers + lastCellHitPointer; |
d54804bf | 255 | row.Cells() = fCells + lastCell; |
326c2d4b | 256 | Int_t nPointers = 0; |
dc4788ec | 257 | Int_t nCells = 0; |
258 | ||
d54804bf | 259 | //Int_t statMaxBins = 0; |
260 | //Int_t statMaxHits = 0; | |
326c2d4b | 261 | for (Int_t ih = 0; ih<nHits; ih++){ |
d54804bf | 262 | THitCont &cont = hitCont[ih]; |
263 | if( cont.used ) continue; | |
326c2d4b | 264 | // cell start |
d54804bf | 265 | AliHLTTPCCACell &cell = row.Cells()[nCells++]; |
326c2d4b | 266 | cell.FirstHitRef() = nPointers; |
267 | cell.NHits() = 1; | |
d54804bf | 268 | cell.Link() = -1; |
269 | cell.Status() = 0; | |
270 | cell.TrackID() = -1; | |
326c2d4b | 271 | row.CellHitPointers()[nPointers++] = ih; |
d54804bf | 272 | cont.used = 1; |
273 | ||
274 | #ifdef DRAW | |
275 | //AliHLTTPCCADisplay::Instance().DrawHit( irow, ih, kRed ); | |
276 | #endif | |
277 | // cell finder - neighbouring hits are grouped to cells | |
278 | ||
279 | ||
280 | Float_t ymin = cont.Ymin; | |
281 | Float_t ymax = cont.Ymax; | |
282 | Float_t zmin = cont.Zmin; | |
283 | Float_t zmax = cont.Zmax; | |
284 | Int_t binYmin = cont.binYmin; | |
285 | Int_t binYmax = cont.binYmax; | |
286 | Int_t binZmin = cont.binZmin; | |
287 | Int_t binZmax = cont.binZmax; | |
288 | ||
289 | Bool_t repeat = 1; | |
290 | while( repeat ){ | |
291 | repeat = 0; | |
292 | THitCont ** startY = (THitCont **) grid.Grid() + binZmin*grid.Ny(); | |
293 | //Float_t Ymax1 = Ymax; | |
294 | //Float_t Ymin1 = Ymin; | |
295 | //Float_t Zmax1 = Zmax; | |
296 | //Float_t Zmin1 = Zmin; | |
297 | Int_t binYmax1 = binYmax; | |
298 | Int_t binYmin1 = binYmin; | |
299 | Int_t binZmax1 = binZmax; | |
300 | Int_t binZmin1 = binZmin; | |
301 | #ifdef DRAW | |
302 | //cell.Y() = .5*(Ymin+Ymax); | |
303 | //cell.Z() = .5*(Zmin+Zmax); | |
304 | //cell.ErrY() = .5*( Ymax - Ymin )/3.5; | |
305 | //cell.ErrZ() = .5*( Zmax - Zmin )/3.5; | |
306 | //cell.YMin() = Ymin; | |
307 | //cell.YMax() = Ymax; | |
308 | //AliHLTTPCCADisplay::Instance().DrawCell( irow, nCells-1, 1,kRed ); | |
309 | //AliHLTTPCCADisplay::Instance().Ask(); | |
310 | #endif | |
311 | for( Int_t iGridZ=binZmin1; iGridZ<=binZmax1; iGridZ++, startY += grid.Ny() ){ | |
312 | for( Int_t iGridY=binYmin1; iGridY<=binYmax1; iGridY++ ){ | |
313 | for( THitCont *bin = *(startY + iGridY); bin; bin=bin->next ){ | |
314 | Int_t jh = bin->h-row.Hits(); | |
315 | THitCont &cont1 = hitCont[jh]; | |
316 | if( cont1.used ) continue; | |
317 | //cout<<"["<<Ymin<<","<<Ymax<<"]: ["<<cont1.Ymin<<","<<cont1.Ymax<<"]"<<endl; | |
318 | if( cont1.Ymax < ymin ) continue; | |
319 | if( cont1.Ymin > ymax ) continue; | |
320 | if( cont1.Zmax < zmin ) break;// in the grid cell hit Y is decreasing | |
321 | if( cont1.Zmin > zmax ) continue; | |
322 | ||
323 | if( cont1.Ymin < ymin ){ ymin = cont1.Ymin; repeat = 1; } | |
324 | if( cont1.Ymax > ymax ){ ymax = cont1.Ymax; repeat = 1; } | |
325 | if( cont1.Zmin < zmin ){ zmin = cont1.Zmin; repeat = 1; } | |
326 | if( cont1.Zmax > zmax ){ zmax = cont1.Zmax; repeat = 1; } | |
327 | if( cont1.binYmin < binYmin ){ binYmin = cont1.binYmin; repeat = 1; } | |
328 | if( cont1.binYmax > binYmax ){ binYmax = cont1.binYmax; repeat = 1; } | |
329 | if( cont1.binZmin < binZmin ){ binZmin = cont1.binZmin; repeat = 1; } | |
330 | if( cont1.binZmax > binZmax ){ binZmax = cont1.binZmax; repeat = 1; } | |
331 | ||
332 | row.CellHitPointers()[nPointers++] = jh; | |
333 | cell.NHits()++; | |
334 | cont1.used = 1; | |
335 | #ifdef DRAW | |
336 | //AliHLTTPCCADisplay::Instance().DrawHit( irow, jh, kRed ); | |
337 | //AliHLTTPCCADisplay::Instance().Ask(); | |
338 | #endif | |
339 | } | |
326c2d4b | 340 | } |
341 | } | |
326c2d4b | 342 | } |
d54804bf | 343 | |
344 | cell.Y() = .5*(ymin+ymax); | |
345 | cell.Z() = .5*(zmin+zmax); | |
346 | cell.ErrY() = .5*( ymax - ymin - 2*deltaY)/3.5; | |
347 | cell.ErrZ() = .5*( zmax - zmin -2*deltaZ)/3.5; | |
348 | cell.ZMin() = zmin; | |
349 | cell.ZMax() = zmax; | |
350 | #ifdef DRAW | |
351 | //AliHLTTPCCADisplay::Instance().DrawCell( irow, nCells-1 ); | |
352 | //AliHLTTPCCADisplay::Instance().Ask(); | |
353 | #endif | |
326c2d4b | 354 | } |
d54804bf | 355 | //cout<<statMaxBins<<"/"<<grid.N()<<" "<<statMaxHits<<"/"<<nHits<<endl; |
356 | ||
326c2d4b | 357 | |
dc4788ec | 358 | row.NCells() = nCells; |
359 | lastCellHitPointer += nPointers; | |
d54804bf | 360 | lastCell += nCells; |
326c2d4b | 361 | } |
d54804bf | 362 | delete[] hitCont; |
dc4788ec | 363 | timer.Stop(); |
364 | fTimers[0] = timer.CpuTime(); | |
326c2d4b | 365 | } |
366 | ||
367 | ||
d54804bf | 368 | void AliHLTTPCCATracker::MergeCells() |
326c2d4b | 369 | { |
d54804bf | 370 | // First step: |
371 | // for each Cell find one neighbour in the next row (irow+1) | |
372 | // when there are no neighbours, look to the rows (irow+2),(irow+3) | |
373 | // | |
374 | // Initial state: | |
375 | // cell.Link =-1 | |
376 | // cell.Link1 =-1 | |
377 | // cell.Track =-1 | |
378 | // | |
379 | // Intermediate state: same as final | |
380 | // | |
381 | // Final state: | |
382 | // cell.Link = Neighbour ID, if there is a neighbour | |
383 | // = -1, if no neighbours found | |
384 | // = -2, if there was more than one neighbour | |
385 | // cell.Link1 = ID of the cell which has this Cell as a forward neighbour | |
386 | // = -1 there are no backward neighbours | |
387 | // = -2 there are more than one neighbour | |
388 | // cell.Track = -1 | |
389 | // | |
390 | ||
391 | TStopwatch timer1; | |
392 | ||
393 | Int_t nStartCells = 0; | |
394 | for( Int_t iRow1=0; iRow1<fParam.NRows(); iRow1++ ){ | |
395 | AliHLTTPCCARow &row1 = fRows[iRow1]; | |
396 | ||
397 | Float_t deltaY = row1.DeltaY(); | |
398 | Float_t deltaZ = row1.DeltaZ(); | |
399 | ||
400 | Int_t lastRow2 = iRow1+3; | |
401 | if( lastRow2>=fParam.NRows() ) lastRow2 = fParam.NRows()-1; | |
402 | ||
403 | for (Int_t i1 = 0; i1<row1.NCells(); i1++){ | |
404 | AliHLTTPCCACell &c1 = row1.Cells()[i1]; | |
405 | //cout<<"row, cell= "<<iRow1<<" "<<i1<<" "<<c1.Y()<<" "<<c1.ErrY()<<" "<<c1.Z()<<" "<<c1.ErrZ()<<endl; | |
406 | //Float_t sy1 = c1.ErrY()*c1.ErrY(); | |
407 | Float_t yMin = c1.Y() - 3.5*c1.ErrY() - deltaY; | |
408 | Float_t yMax = c1.Y() + 3.5*c1.ErrY() + deltaY; | |
409 | Float_t zMin = c1.Z() - 3.5*c1.ErrZ() - deltaZ; | |
410 | Float_t zMax = c1.Z() + 3.5*c1.ErrZ() + deltaZ; | |
411 | //Float_t sz1 = c1.ErrZ()*c1.ErrZ(); | |
412 | if( c1.Status()<=0 ) nStartCells++; | |
413 | ||
414 | // looking for neighbour for the Cell c1 | |
415 | Bool_t found = 0; | |
416 | for( Int_t iRow2=iRow1+1; iRow2<=lastRow2&&(!found); iRow2++ ){ | |
417 | AliHLTTPCCARow &row2 = fRows[iRow2]; | |
418 | AliHLTTPCCACell *cc2 = lower_bound(row2.Cells(),row2.Cells()+row2.NCells(),zMin,AliHLTTPCCARow::CompareCellZMax); | |
419 | for (Int_t i2 = (cc2 - row2.Cells()); i2<row2.NCells(); i2++){ | |
420 | //cout<<" candidat = "<<iRow2<<" "<<i2<<endl; | |
421 | ||
422 | AliHLTTPCCACell &c2 = row2.Cells()[i2]; | |
423 | Float_t y2Min = c2.Y() - 3.5*c2.ErrY(); | |
424 | Float_t y2Max = c2.Y() + 3.5*c2.ErrY(); | |
425 | Float_t z2Min = c2.Z() - 3.5*c2.ErrZ(); | |
426 | Float_t z2Max = c2.Z() + 3.5*c2.ErrZ(); | |
427 | ||
428 | if( y2Min > yMax ) continue; | |
429 | if( y2Max < yMin ) continue; | |
430 | if( z2Min > zMax ) break; | |
431 | if( z2Max < zMin ) continue; | |
432 | ||
433 | // c1 & c2 are neighbours | |
434 | ||
435 | found = 1; | |
436 | ||
437 | if( c1.Link() ==-1 && c2.Status()==0 ){ | |
438 | // one-to-one connection - OK | |
439 | c1.Link() = IRowICell2ID(iRow2,i2); | |
440 | c2.Status() = 1; | |
441 | }else{ | |
442 | // multi-connection - break all links | |
443 | if( c1.Link()>=0 ) ID2Cell(c1.Link()).Status() = -1; | |
444 | c1.Link() = -2; | |
445 | c2.Status() = -1; | |
446 | } | |
447 | } | |
448 | }//row2 | |
449 | } | |
450 | }//row1 | |
451 | ||
452 | timer1.Stop(); | |
453 | fTimers[1] = timer1.CpuTime(); | |
326c2d4b | 454 | |
d54804bf | 455 | // Second step: create tracks |
456 | // for each sequence of neighbouring Cells create Track object | |
457 | // | |
458 | // Final state: | |
459 | // cell.Track = TrackNumber for first and last track cell | |
460 | // = -1 for other cells | |
461 | // cell.Link = Neighbour ID, if there is a neighbour | |
462 | // = -1, if no neighbour (last cell on the track ) | |
463 | // cell.Link1 = backward neighbour ID, if there is a neighbour | |
464 | // = -1 for first and last track cells | |
465 | ||
466 | TStopwatch timer2; | |
467 | ||
468 | fTracks = new AliHLTTPCCATrack[nStartCells]; | |
469 | fNTracks = 0; | |
470 | ||
471 | for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ ){ | |
472 | AliHLTTPCCARow &row = fRows[iRow]; | |
473 | for( Int_t iCell = 0; iCell<row.NCells(); iCell++){ | |
474 | AliHLTTPCCACell &c = row.Cells()[iCell]; | |
475 | if( c.Status()>0 ) continue; // not a starting cell | |
476 | ||
477 | Int_t firstID = IRowICell2ID( iRow, iCell ); | |
478 | Int_t midID = firstID; | |
479 | Int_t lastID = firstID; | |
480 | ||
481 | AliHLTTPCCATrack &track = fTracks[fNTracks]; | |
482 | track.Alive() = 1; | |
483 | track.NCells() = 1; | |
484 | AliHLTTPCCACell *last = &c; | |
485 | while( last->Link() >=0 ){ | |
486 | Int_t nextID = last->Link(); | |
487 | AliHLTTPCCACell *next = & ID2Cell(nextID); | |
488 | if(next->Status()!=1 ){ | |
489 | last->Link() = -1; | |
490 | break; | |
491 | } | |
492 | track.NCells()++; | |
493 | last = next; | |
494 | lastID = nextID; | |
495 | } | |
496 | Int_t nCells05 = (track.NCells()-1)/2; | |
497 | for( Int_t i=0; i<nCells05; i++ ) midID = ID2Cell(midID).Link(); | |
498 | //cout<<fNTracks<<", NCells="<<track.NCells()<<" "<<nCells05<<"id="<<firstID<<" "<<midID<<" "<<lastID<<endl; | |
499 | c.TrackID() = fNTracks; | |
500 | last->TrackID() = fNTracks; | |
501 | track.FirstCellID() = firstID; | |
502 | track.CellID()[0] = firstID; | |
503 | track.CellID()[1] = midID; | |
504 | track.CellID()[2] = lastID; | |
505 | track.PointID()[0] = -1; | |
506 | track.PointID()[1] = -1; | |
507 | //cout<<"Track N "<<fNTracks<<", NCells="<<track.NCells()<<endl; | |
508 | ||
509 | fNTracks++; | |
510 | } | |
511 | } | |
512 | if( fNTracks != nStartCells ){ | |
513 | //cout<<"fNTracks="<<fNTracks<<", NStrartCells="<<nStartCells<<endl; | |
514 | //exit(0); | |
515 | return; | |
516 | } | |
517 | ||
518 | // create endpoints | |
519 | ||
520 | Int_t nEndPointsTotal = 0; | |
521 | for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ ){ | |
522 | AliHLTTPCCARow &row = fRows[iRow]; | |
523 | row.EndPoints()= fEndPoints + nEndPointsTotal; | |
524 | row.NEndPoints()=0; | |
525 | for( Int_t iCell = 0; iCell<row.NCells(); iCell++){ | |
526 | AliHLTTPCCACell &c = row.Cells()[iCell]; | |
527 | if( c.TrackID()< 0 ) continue; // not an endpoint | |
528 | AliHLTTPCCAEndPoint &p = row.EndPoints()[row.NEndPoints()]; | |
529 | p.CellID() = IRowICell2ID(iRow,iCell); | |
530 | p.TrackID() = c.TrackID(); | |
531 | p.Link() = -1; | |
532 | AliHLTTPCCATrack &track = fTracks[c.TrackID()]; | |
533 | if( c.Link()>=0 ){ | |
534 | track.PointID()[0] = IRowICell2ID(iRow,row.NEndPoints()); | |
535 | }else{ | |
536 | track.PointID()[1] = IRowICell2ID(iRow,row.NEndPoints()); | |
537 | if( track.PointID()[0]<0 )track.PointID()[0] = track.PointID()[1]; | |
538 | } | |
539 | row.NEndPoints()++; | |
540 | } | |
541 | nEndPointsTotal += row.NEndPoints(); | |
542 | } | |
543 | timer2.Stop(); | |
544 | fTimers[2] = timer2.CpuTime(); | |
545 | } | |
546 | ||
547 | void AliHLTTPCCATracker::FindTracks() | |
548 | { | |
549 | // the Cellular Automaton track finder | |
550 | TStopwatch timer3; | |
551 | //cout<<"combine & fit tracks"<<endl; | |
552 | for( Int_t itr=0; itr<fNTracks; itr++ ){ | |
553 | AliHLTTPCCATrack &iTrack = fTracks[itr]; | |
554 | //if( iTrack.NCells()<3 ) continue; | |
555 | //cout<<" fit track "<<itr<<", NCells="<<iTrack.NCells()<<endl; | |
556 | ID2Point(iTrack.PointID()[0]).Param().CosPhi() = -1;//[2] = -TMath::Pi(); | |
557 | ID2Point(iTrack.PointID()[1]).Param().CosPhi() = 1;//[2] = 0; | |
558 | FitTrack( iTrack ); | |
559 | //if( iTrack.Param().Chi2() > fParam.TrackChi2Cut()*iTrack.Param().NDF() ){ | |
560 | //iTrack.Alive() = 0; | |
561 | //} | |
562 | } | |
563 | timer3.Stop(); | |
564 | fTimers[3] = timer3.CpuTime(); | |
326c2d4b | 565 | |
566 | #ifdef DRAW | |
567 | if( !gApplication ){ | |
568 | TApplication *myapp = new TApplication("myapp",0,0); | |
dc4788ec | 569 | } |
570 | //AliHLTTPCCADisplay::Instance().Init(); | |
d54804bf | 571 | |
326c2d4b | 572 | AliHLTTPCCADisplay::Instance().SetCurrentSector( this ); |
573 | AliHLTTPCCADisplay::Instance().DrawSector( this ); | |
d54804bf | 574 | cout<<"draw hits..."<<endl; |
dc4788ec | 575 | for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ ) |
576 | for (Int_t i = 0; i<fRows[iRow].NHits(); i++) | |
577 | AliHLTTPCCADisplay::Instance().DrawHit( iRow, i ); | |
dc4788ec | 578 | AliHLTTPCCADisplay::Instance().Ask(); |
d54804bf | 579 | //AliHLTTPCCADisplay::Instance().Clear(); |
580 | //AliHLTTPCCADisplay::Instance().DrawSector( this ); | |
581 | cout<<"draw cells..."<<endl; | |
326c2d4b | 582 | for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ ) |
583 | for (Int_t i = 0; i<fRows[iRow].NCells(); i++) | |
584 | AliHLTTPCCADisplay::Instance().DrawCell( iRow, i ); | |
dc4788ec | 585 | AliHLTTPCCADisplay::Instance().Ask(); |
326c2d4b | 586 | |
d54804bf | 587 | Int_t nConnectedCells = 0; |
326c2d4b | 588 | |
d54804bf | 589 | cout<<"draw merged cells..."<<endl; |
dc4788ec | 590 | |
d54804bf | 591 | for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ ) |
592 | for (Int_t i = 0; i<fRows[iRow].NCells(); i++) | |
593 | { | |
594 | AliHLTTPCCACell &c = fRows[iRow].Cells()[i]; | |
595 | Int_t id = c.Link(); | |
596 | if( id<0 ) continue; | |
597 | AliHLTTPCCADisplay::Instance().ConnectCells( iRow,c,ID2IRow(id),ID2Cell(id) ); | |
598 | nConnectedCells++; | |
326c2d4b | 599 | } |
d54804bf | 600 | if( nConnectedCells>0 ){ |
601 | AliHLTTPCCADisplay::Instance().Ask(); | |
326c2d4b | 602 | } |
603 | ||
d54804bf | 604 | |
605 | AliHLTTPCCADisplay::Instance().Clear(); | |
606 | AliHLTTPCCADisplay::Instance().DrawSector( this ); | |
607 | for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ ) | |
608 | for (Int_t i = 0; i<fRows[iRow].NCells(); i++) | |
609 | AliHLTTPCCADisplay::Instance().DrawCell( iRow, i ); | |
dc4788ec | 610 | |
d54804bf | 611 | cout<<"draw initial tracks"<<endl; |
612 | ||
613 | for( Int_t itr=0; itr<fNTracks; itr++ ){ | |
614 | //if( itr!=58 ) continue; | |
615 | AliHLTTPCCATrack &iTrack = fTracks[itr]; | |
616 | if( iTrack.NCells()<3 ) continue; | |
617 | if( !iTrack.Alive() ) continue; | |
618 | AliHLTTPCCADisplay::Instance().DrawTrack1( iTrack ); | |
619 | } | |
620 | //if( fNTracks>0 ) | |
621 | AliHLTTPCCADisplay::Instance().Ask(); | |
326c2d4b | 622 | #endif |
d54804bf | 623 | |
624 | TStopwatch timer4; | |
625 | ||
626 | Bool_t doMerging=1; | |
627 | ||
628 | Float_t factor2 = fParam.TrackConnectionFactor()*fParam.TrackConnectionFactor(); | |
629 | Int_t *refEndPoints = new Int_t[fNHitsTotal]; | |
630 | Int_t nRefEndPoints = 0; | |
631 | for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ ){ | |
632 | AliHLTTPCCARow &irow = fRows[iRow]; | |
633 | for (Int_t iPoint = 0; iPoint<irow.NEndPoints(); iPoint++){ | |
634 | refEndPoints[nRefEndPoints++] = IRowICell2ID(iRow,iPoint); | |
326c2d4b | 635 | } |
636 | } | |
d54804bf | 637 | bool first = 1; |
638 | while( doMerging ){ | |
dc4788ec | 639 | |
d54804bf | 640 | //cout<<"do merging"<<endl; |
641 | ||
642 | doMerging = 0; | |
dc4788ec | 643 | |
d54804bf | 644 | // find nejghbouring tracks |
645 | TStopwatch timer5; | |
646 | //cout<<"nRefEndPoints = "<<nRefEndPoints<<endl; | |
dc4788ec | 647 | |
d54804bf | 648 | for( Int_t iRef=0; iRef<nRefEndPoints; iRef++ ){ |
649 | Int_t iRow = ID2IRow(refEndPoints[iRef]); | |
650 | AliHLTTPCCARow &irow = fRows[iRow]; | |
651 | Int_t iPoint = ID2ICell(refEndPoints[iRef]); | |
652 | AliHLTTPCCAEndPoint &ip = irow.EndPoints()[iPoint]; | |
653 | if( ip.TrackID()<0 ) continue; // not active endpoint | |
dc4788ec | 654 | |
d54804bf | 655 | AliHLTTPCCATrack &iTrack = fTracks[ip.TrackID()]; |
656 | if( iTrack.NCells()<3 ) continue; | |
657 | ||
658 | Int_t jRowMin = iRow - fParam.MaxTrackMatchDRow(); | |
659 | Int_t jRowMax = iRow + fParam.MaxTrackMatchDRow(); | |
660 | if( jRowMin<0 ) jRowMin = 0; | |
661 | if( jRowMax>=fParam.NRows() ) jRowMax = fParam.NRows()-1; | |
662 | ||
663 | if( ip.Param().CosPhi()>=0 ){ //TMath::Abs([2])<TMath::Pi()/2. ){ | |
664 | jRowMin = iRow; | |
665 | }else{ | |
666 | jRowMax = iRow; | |
667 | } | |
dc4788ec | 668 | |
d54804bf | 669 | Int_t bestNeighbourN = -1; |
670 | Float_t bestDist2 = 1.e20; | |
671 | Int_t bestLink = -1; | |
672 | if( ip.Link()>=0 ){ | |
673 | bestNeighbourN = fTracks[ID2Point(ip.Link()).TrackID()].NCells(); | |
674 | } | |
675 | ||
676 | Float_t y0 = ip.Param().GetY(); | |
677 | Float_t z0 = ip.Param().GetZ(); | |
678 | ||
679 | #ifdef DRAW | |
680 | //AliHLTTPCCADisplay::Instance().DrawTrackletPoint(ip.Param(),kBlue); | |
681 | //AliHLTTPCCADisplay::Instance().Ask(); | |
682 | #endif | |
683 | ||
684 | for( Int_t jRow = jRowMin; jRow<=jRowMax; jRow++){ | |
685 | AliHLTTPCCARow &jrow = fRows[jRow]; | |
686 | Float_t dx2 = (irow.X()-jrow.X())*(irow.X()-jrow.X()); | |
687 | ||
688 | // extrapolate the track to row jRow | |
689 | ||
690 | //for( int ii=0; ii<10; ii++){ | |
691 | //AliHLTTPCCATrackParam iPar = ip.Param(); | |
692 | //iPar.TransportToX( jrow.X()); | |
693 | //} | |
694 | AliHLTTPCCATrackParam iPar = ip.Param(); | |
695 | Bool_t ok = iPar.TransportToX( jrow.X()); | |
696 | if( !ok ) continue; | |
dc4788ec | 697 | #ifdef DRAW |
d54804bf | 698 | //AliHLTTPCCADisplay::Instance().DrawTrackletPoint(iPar, kBlack); |
699 | //AliHLTTPCCADisplay::Instance().Ask(); | |
700 | #endif | |
701 | Float_t zMin = iPar.GetZ() - 3.5*TMath::Sqrt(iPar.GetErr2Z()) - .2*3.5; | |
702 | AliHLTTPCCAEndPoint *jjp = lower_bound(jrow.EndPoints(),jrow.EndPoints()+jrow.NEndPoints(),zMin,AliHLTTPCCARow::CompareEndPointZ); | |
703 | ||
704 | for (Int_t jPoint = jjp-jrow.EndPoints(); jPoint<jrow.NEndPoints(); jPoint++){ | |
705 | ||
706 | AliHLTTPCCAEndPoint &jp = jrow.EndPoints()[jPoint]; | |
707 | ||
708 | if( jp.TrackID()<0 ) continue; // endpoint not active | |
709 | if( jp.TrackID()==ip.TrackID() ) continue; // same track | |
710 | ||
711 | AliHLTTPCCATrack &jTrack = fTracks[jp.TrackID()]; | |
712 | ||
713 | if( bestNeighbourN > jTrack.NCells() ){ | |
714 | continue; // there is already better neighbour found | |
dc4788ec | 715 | } |
d54804bf | 716 | if( jp.Link()>=0 && |
717 | fTracks[ID2Point(jp.Link()).TrackID()].NCells()>=iTrack.NCells() ){ | |
718 | continue; // jTrack is already linked to a better track or to iTrack | |
dc4788ec | 719 | } |
d54804bf | 720 | |
721 | Float_t dy2, dz2; | |
722 | AliHLTTPCCATrackParam &jPar = jp.Param(); | |
723 | ||
724 | // check for neighbouring | |
725 | { | |
726 | float d = jPar.GetY() - iPar.GetY(); | |
727 | float s2 = jPar.GetErr2Y() + iPar.GetErr2Y(); | |
728 | if( d*d>factor2*s2 ){ | |
729 | continue; | |
730 | } | |
731 | d = jPar.GetZ() - iPar.GetZ(); | |
732 | s2 = jPar.GetErr2Z() + iPar.GetErr2Z(); | |
733 | if( d*d>factor2*s2 ){ | |
734 | if( d>0 ) break; | |
735 | continue; | |
736 | } | |
737 | if( iTrack.NCells()>=3 && jTrack.NCells()>=3 ){ | |
738 | d = jPar.GetSinPhi() + iPar.GetSinPhi(); //! phi sign is different | |
739 | s2 = jPar.GetErr2SinPhi() + iPar.GetErr2SinPhi(); | |
740 | if( d*d>factor2*s2 ) continue; | |
741 | d = jPar.GetKappa() + iPar.GetKappa(); // ! kappa sign iz different | |
742 | s2 = jPar.GetErr2Kappa() + iPar.GetErr2Kappa(); | |
743 | if( d*d>factor2*s2 ) continue; | |
744 | d = jPar.GetDzDs() + iPar.GetDzDs(); // ! DzDs sign iz different | |
745 | s2 = jPar.GetErr2DzDs() + iPar.GetErr2DzDs(); | |
746 | if( d*d>factor2*s2 ) continue; | |
747 | } | |
dc4788ec | 748 | } |
d54804bf | 749 | |
750 | Float_t dy = jPar.GetY() - y0; | |
751 | dy2 = dy*dy; | |
752 | Float_t dz = jPar.GetZ() - z0; | |
753 | dz2 = dz*dz; | |
754 | Float_t dist2 = dx2+dy2+dz2; | |
755 | ||
756 | if( ( bestNeighbourN == jTrack.NCells() ) && dist2>bestDist2 ) continue; | |
757 | ||
758 | // tracks can be matched | |
759 | ||
760 | bestLink = IRowICell2ID( jRow, jPoint ); | |
761 | bestNeighbourN = jTrack.NCells(); | |
762 | bestDist2 = dist2; | |
326c2d4b | 763 | } |
326c2d4b | 764 | } |
d54804bf | 765 | |
766 | if( bestLink < 0 ) continue; // no neighbours found | |
767 | ||
768 | AliHLTTPCCAEndPoint &jp = ID2Point(bestLink); | |
769 | ||
770 | if( ip.Link()>=0 ){ // break existing link of iTrack | |
771 | ID2Point(ip.Link()).Link() = -1; | |
326c2d4b | 772 | } |
d54804bf | 773 | if( jp.Link()>=0 ){ // break existing link of jTrack |
774 | ID2Point(jp.Link()).Link() = -1; | |
775 | } | |
776 | ip.Link() = bestLink; | |
777 | jp.Link()= IRowICell2ID( iRow, iPoint ); | |
778 | ||
779 | //cout<<"create link ("<<jp.Link()<<","<<ip.TrackID()<<")->("<<ip.Link()<<","<<jp.TrackID()<<")"<<endl; | |
780 | ||
326c2d4b | 781 | } |
dc4788ec | 782 | |
d54804bf | 783 | timer5.Stop(); |
784 | if(first) fTimers[5] += timer5.CpuTime(); | |
dc4788ec | 785 | |
d54804bf | 786 | //cout<<"merge neighbours"<<endl; |
787 | // merge neighbours | |
788 | ||
789 | TStopwatch timer6; | |
790 | ||
791 | Int_t nRefEndPointsNew = 0; | |
792 | for( Int_t iRef=0; iRef<nRefEndPoints; iRef++ ){ | |
793 | ||
794 | Int_t iRow = ID2IRow(refEndPoints[iRef]); | |
795 | Int_t iPoint = ID2ICell(refEndPoints[iRef]); | |
796 | AliHLTTPCCARow &irow = fRows[iRow]; | |
797 | AliHLTTPCCAEndPoint &ip = irow.EndPoints()[iPoint]; | |
798 | if( ip.TrackID()<0 ) continue; // not active endpoint | |
799 | if( ip.Link()<0 ) continue; // no neighbours found | |
800 | ||
801 | Int_t ipID = IRowICell2ID(iRow,iPoint); | |
802 | Int_t jpID = ip.Link(); | |
803 | AliHLTTPCCAEndPoint &jp = ID2Point(jpID); | |
804 | ||
805 | if( jp.Link()!=ipID ){ | |
806 | //cout<<"broken link: jp.Link()!=iID"<<endl; | |
807 | //exit(0); | |
808 | return; | |
809 | } | |
810 | if( jp.TrackID()<0 ){ | |
811 | //cout<<"broken link: jp.TrackID()<=0"<<endl; | |
812 | //exit(0); | |
813 | return; | |
814 | } | |
815 | if( jp.TrackID()==ip.TrackID() ){ | |
816 | //cout<<"broken link: jp.TrackID()==ip.TrackID()"<<endl; | |
817 | //exit(0); | |
818 | return; | |
819 | } | |
820 | ||
821 | //cout<<"Merge neighbours ("<<ipID<<","<<ip.TrackID()<<")->("<<jpID<<","<<jp.TrackID()<<")"<<endl; | |
822 | ||
823 | AliHLTTPCCATrack &iTrack = fTracks[ip.TrackID()]; | |
824 | AliHLTTPCCATrack &jTrack = fTracks[jp.TrackID()]; | |
825 | ||
826 | // rotate cell link direction for jTrack if necessary | |
827 | ||
828 | Int_t icID = ip.CellID(); | |
829 | Int_t jcID = jp.CellID(); | |
830 | AliHLTTPCCACell &ic = ID2Cell(icID); | |
831 | AliHLTTPCCACell &jc = ID2Cell(jcID); | |
832 | ||
833 | if( ic.Link()<0 && jc.Link()<0 || ic.Link()>=0 && jc.Link()>=0 ){ | |
834 | ||
835 | Int_t currID = jTrack.CellID()[0]; | |
836 | jTrack.CellID()[0] = jTrack.CellID()[2]; | |
837 | jTrack.CellID()[2] = currID; | |
838 | ||
839 | Int_t pID = jTrack.PointID()[0]; | |
840 | jTrack.PointID()[0] = jTrack.PointID()[1]; | |
841 | jTrack.PointID()[1] = pID; | |
842 | ||
843 | currID = jTrack.FirstCellID(); | |
844 | Int_t lastID = -1; | |
845 | while( currID>=0 ){ | |
846 | AliHLTTPCCACell &c = ID2Cell( currID ); | |
847 | Int_t nextID = c.Link(); | |
848 | c.Link() = lastID; | |
849 | lastID = currID; | |
850 | currID = nextID; | |
851 | } | |
852 | jTrack.FirstCellID() = lastID; | |
853 | } | |
854 | //cout<<"track i "<<ip.TrackID()<<", points="<<ipID<<", "<<iTrack.PointID()[0]<<", "<<iTrack.PointID()[1]<<endl; | |
855 | //cout<<"track j "<<jp.TrackID()<<", points="<<jpID<<", "<<jTrack.PointID()[0]<<", "<<jTrack.PointID()[1]<<endl; | |
856 | Int_t itr = ip.TrackID(); | |
857 | ip.TrackID() = -1; | |
858 | jp.TrackID() = -1; | |
859 | ip.Link() = -1; | |
860 | jp.Link() = -1; | |
861 | jTrack.Alive() = 0; | |
862 | ||
863 | //cout<<"iTrack ID: "<<iTrack.CellID()[0]<<" "<<iTrack.CellID()[1]<<" "<<iTrack.CellID()[2]<<endl; | |
864 | //cout<<"jTrack ID: "<<jTrack.CellID()[0]<<" "<<jTrack.CellID()[1]<<" "<<jTrack.CellID()[2]<<endl; | |
865 | if( ic.Link()<0 ){ //match iTrack->jTrack | |
866 | ic.Link() = jcID; | |
867 | iTrack.PointID()[1] = jTrack.PointID()[1]; | |
868 | ID2Point(iTrack.PointID()[1]).TrackID() = itr; | |
869 | if( jTrack.NCells()<3 ){ | |
870 | refEndPoints[nRefEndPointsNew++] = iTrack.PointID()[1]; | |
871 | doMerging = 1; | |
872 | ID2Point(iTrack.PointID()[1]).Param() = ip.Param();// just to set phi direction | |
873 | } | |
874 | if( iTrack.NCells()<3 ){ | |
875 | refEndPoints[nRefEndPointsNew++] = iTrack.PointID()[0]; | |
876 | doMerging = 1; | |
877 | ID2Point(iTrack.PointID()[0]).Param() = jp.Param();// just to set phi direction | |
878 | } | |
879 | ||
880 | if( TMath::Abs(ID2Cell(jTrack.CellID()[2]).Z()-ID2Cell(iTrack.CellID()[0]).Z())> | |
881 | TMath::Abs(ID2Cell(iTrack.CellID()[2]).Z()-ID2Cell(iTrack.CellID()[0]).Z()) ){ | |
882 | iTrack.CellID()[2] = jTrack.CellID()[2]; | |
883 | } | |
884 | }else{ //match jTrack->iTrack | |
885 | jc.Link() = icID; | |
886 | iTrack.FirstCellID()=jTrack.FirstCellID(); | |
887 | iTrack.PointID()[0] = jTrack.PointID()[0]; | |
888 | ID2Point(iTrack.PointID()[0]).TrackID() = itr; | |
889 | if( jTrack.NCells()<3 ){ | |
890 | refEndPoints[nRefEndPointsNew++] = iTrack.PointID()[0]; | |
891 | doMerging = 1; | |
892 | ID2Point(iTrack.PointID()[0]).Param() = ip.Param(); // just to set phi direction | |
893 | } | |
894 | if( iTrack.NCells()<3 ){ | |
895 | refEndPoints[nRefEndPointsNew++] = iTrack.PointID()[1]; | |
896 | doMerging = 1; | |
897 | ID2Point(iTrack.PointID()[1]).Param() = jp.Param();// just to set phi direction | |
898 | } | |
899 | if( TMath::Abs(ID2Cell(jTrack.CellID()[0]).Z()-ID2Cell(iTrack.CellID()[2]).Z())> | |
900 | TMath::Abs(ID2Cell(iTrack.CellID()[0]).Z()-ID2Cell(iTrack.CellID()[2]).Z()) ){ | |
901 | iTrack.CellID()[0] = jTrack.CellID()[0]; | |
902 | } | |
903 | } | |
904 | ||
905 | //cout<<"merged ID: "<<iTrack.CellID()[0]<<" "<<iTrack.CellID()[1]<<" "<<iTrack.CellID()[2]<<endl; | |
906 | ||
907 | if( jTrack.NCells()>iTrack.NCells() ){ | |
908 | iTrack.CellID()[1] = jTrack.CellID()[1]; | |
909 | } | |
910 | ||
911 | AliHLTTPCCAEndPoint &p0 = ID2Point(iTrack.PointID()[0]); | |
912 | AliHLTTPCCAEndPoint &p1 = ID2Point(iTrack.PointID()[1]); | |
913 | ||
914 | if( p0.Link() == iTrack.PointID()[1] ){ | |
915 | p0.Link() = -1; | |
916 | p1.Link() = -1; | |
917 | } | |
918 | //cout<<" NCells itr/jtr= "<<iTrack.NCells()<<" "<<jTrack.NCells()<<endl; | |
919 | //cout<<" fit merged track "<<itr<<", NCells="<<iTrack.NCells()<<endl; | |
920 | Float_t *t0 = ( jTrack.NCells()>iTrack.NCells() ) ?jp.Param().Par() :ip.Param().Par(); | |
921 | iTrack.NCells()+=jTrack.NCells(); | |
922 | FitTrack(iTrack,t0); | |
923 | ||
924 | #ifdef DRAW | |
925 | cout<<"merged points..."<<ipID<<"/"<<jpID<<endl; | |
926 | //AliHLTTPCCADisplay::Instance().ConnectCells( iRow,ic,ID2IRow(jcID),jc,kRed ); | |
927 | AliHLTTPCCADisplay::Instance().ConnectEndPoints( ipID,jpID,1.,2,kRed ); | |
928 | //AliHLTTPCCADisplay::Instance().DrawEndPoint( ipID,1.,2,kRed ); | |
929 | //AliHLTTPCCADisplay::Instance().DrawEndPoint( jpID,1.,2,kRed ); | |
930 | AliHLTTPCCADisplay::Instance().Ask(); | |
931 | cout<<"merged track"<<endl; | |
932 | AliHLTTPCCADisplay::Instance().DrawTrack1(iTrack); | |
933 | AliHLTTPCCADisplay::Instance().Ask(); | |
934 | #endif | |
935 | /* | |
936 | static int ntr=0; | |
937 | if( ntr++==1 ){ | |
938 | doMerging = 0; | |
939 | break; | |
940 | } | |
941 | */ | |
942 | //doMerging = 1; | |
dc4788ec | 943 | } |
dc4788ec | 944 | |
d54804bf | 945 | timer6.Stop(); |
946 | if(first)fTimers[6] += timer6.CpuTime(); | |
dc4788ec | 947 | |
d54804bf | 948 | nRefEndPoints = nRefEndPointsNew; |
949 | ||
950 | //cout<<"merging ok"<<endl; | |
951 | //first = 0; | |
952 | }// do merging | |
953 | ||
954 | delete[] refEndPoints; | |
955 | timer4.Stop(); | |
956 | fTimers[4] = timer4.CpuTime(); | |
326c2d4b | 957 | |
326c2d4b | 958 | #ifdef DRAW |
d54804bf | 959 | if( fNTracks>0 ) AliHLTTPCCADisplay::Instance().Ask(); |
326c2d4b | 960 | #endif |
961 | ||
962 | ||
d54804bf | 963 | |
964 | ||
326c2d4b | 965 | #ifdef DRAW |
d54804bf | 966 | AliHLTTPCCADisplay::Instance().Clear(); |
967 | AliHLTTPCCADisplay::Instance().DrawSector( this ); | |
968 | for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ ) | |
969 | for (Int_t i = 0; i<fRows[iRow].NCells(); i++) | |
970 | AliHLTTPCCADisplay::Instance().DrawCell( iRow, i ); | |
971 | ||
972 | cout<<"draw final tracks"<<endl; | |
973 | ||
974 | for( Int_t itr=0; itr<fNTracks; itr++ ){ | |
975 | AliHLTTPCCATrack &iTrack = fTracks[itr]; | |
976 | //if( itr!=3 ) continue; | |
977 | if( iTrack.NCells()<3 ) continue; | |
978 | if( !iTrack.Alive() ) continue; | |
979 | AliHLTTPCCADisplay::Instance().DrawTrack1( iTrack ); | |
980 | } | |
981 | AliHLTTPCCADisplay::Instance().Ask(); | |
982 | #endif | |
983 | ||
984 | // write output | |
985 | //cout<<"write output"<<endl; | |
986 | fOutTrackHits = new Int_t[fNHitsTotal]; | |
987 | fOutTracks = new AliHLTTPCCAOutTrack[fNTracks]; | |
988 | fNOutTrackHits = 0; | |
989 | fNOutTracks = 0; | |
990 | ||
991 | for( Int_t iTr=0; iTr<fNTracks; iTr++){ | |
992 | AliHLTTPCCATrack &iTrack = fTracks[iTr]; | |
993 | if( !iTrack.Alive() ) continue; | |
994 | if( iTrack.NCells()<3 ) continue; | |
995 | AliHLTTPCCAOutTrack &out = fOutTracks[fNOutTracks]; | |
996 | out.FirstHitRef() = fNOutTrackHits; | |
997 | out.NHits() = 0; | |
998 | out.OrigTrackID() = iTr; | |
999 | { | |
1000 | AliHLTTPCCAEndPoint &p0 = ID2Point(iTrack.PointID()[0]); | |
1001 | AliHLTTPCCAEndPoint &p2 = ID2Point(iTrack.PointID()[1]); | |
1002 | out.StartPoint() = p0.Param(); | |
1003 | out.EndPoint() = p2.Param(); | |
1004 | } | |
1005 | AliHLTTPCCATrackParam t = out.StartPoint(); | |
1006 | Int_t iID = iTrack.FirstCellID(); | |
1007 | Int_t fNOutTrackHitsOld = fNOutTrackHits; | |
1008 | for( AliHLTTPCCACell *ic = &ID2Cell(iID); ic->Link()>=0; iID = ic->Link(), ic = &ID2Cell(iID) ){ | |
1009 | //cout<<"itr="<<iTr<<", cell ="<<ID2IRow(iID)<<" "<<ID2ICell(iID)<<endl; | |
1010 | AliHLTTPCCARow &row = ID2Row(iID); | |
1011 | for( Int_t iHit=0; iHit<ic->NHits(); iHit++ ){ | |
1012 | AliHLTTPCCAHit &h = row.GetCellHit(*ic,iHit); | |
1013 | ||
1014 | // check for wrong hits | |
1015 | ||
1016 | { | |
1017 | if( !t.TransportToX( row.X() ) ) continue; | |
1018 | Float_t dy = t.GetY() - h.Y(); | |
1019 | Float_t dz = t.GetZ() - h.Z(); | |
1020 | if( dy*dy > 3.5*3.5*(t.GetErr2Y() + h.ErrY()*h.ErrY() ) ) continue; | |
1021 | if( dz*dz > 3.5*3.5*(t.GetErr2Z() + h.ErrZ()*h.ErrZ() ) ) continue; | |
1022 | /* | |
1023 | Float_t m[3] = {row.X(), h.Y(), h.Z() }; | |
1024 | Float_t mV[6] = {fParam.ErrX()*fParam.ErrX(), 0, h.ErrY()*h.ErrY(), 0, 0, h.ErrZ()*h.ErrZ() }; | |
1025 | Float_t mG[6]; | |
1026 | t.TransportBz(fParam.Bz(),m); | |
1027 | t.GetConnectionMatrix(fParam.Bz(),m, mG); | |
1028 | Float_t chi2 = t.GetChi2( m, mV, mG )/2.; | |
1029 | if( chi2>10. ) continue; | |
1030 | */ | |
1031 | } | |
1032 | ||
1033 | fOutTrackHits[fNOutTrackHits] = h.ID(); | |
326c2d4b | 1034 | fNOutTrackHits++; |
d54804bf | 1035 | if( fNOutTrackHits>fNHitsTotal ){ |
1036 | //cout<<"fNOutTrackHits>fNHitsTotal"<<endl; | |
1037 | //exit(0); | |
1038 | return; | |
1039 | } | |
1040 | out.NHits()++; | |
326c2d4b | 1041 | } |
1042 | } | |
d54804bf | 1043 | if( out.NHits() > 3 ){ |
1044 | fNOutTracks++; | |
1045 | }else { | |
1046 | fNOutTrackHits = fNOutTrackHitsOld; | |
1047 | } | |
1048 | } | |
1049 | //cout<<"end writing"<<endl; | |
326c2d4b | 1050 | #ifdef DRAW |
1051 | AliHLTTPCCADisplay::Instance().Ask(); | |
1052 | //AliHLTTPCCADisplay::Instance().DrawMCTracks(fParam.fISec); | |
1053 | //AliHLTTPCCADisplay::Instance().Update(); | |
1054 | //AliHLTTPCCADisplay::Instance().Ask(); | |
1055 | #endif | |
1056 | } | |
1057 | ||
1058 | ||
d54804bf | 1059 | void AliHLTTPCCATracker::FitTrack( AliHLTTPCCATrack &track, Float_t t0[] ) const |
1060 | { | |
1061 | //* Fit the track | |
326c2d4b | 1062 | |
d54804bf | 1063 | AliHLTTPCCAEndPoint &p0 = ID2Point(track.PointID()[0]); |
1064 | AliHLTTPCCAEndPoint &p2 = ID2Point(track.PointID()[1]); | |
1065 | AliHLTTPCCACell &c0 = ID2Cell(p0.CellID()); | |
1066 | AliHLTTPCCACell &c1 = ID2Cell(track.CellID()[1]); | |
1067 | AliHLTTPCCACell &c2 = ID2Cell(p2.CellID()); | |
1068 | AliHLTTPCCARow &row0 = ID2Row(p0.CellID()); | |
1069 | AliHLTTPCCARow &row1 = ID2Row(track.CellID()[1]); | |
1070 | AliHLTTPCCARow &row2 = ID2Row(p2.CellID()); | |
dc4788ec | 1071 | |
dc4788ec | 1072 | |
d54804bf | 1073 | Float_t sp0[5] = {row0.X(), c0.Y(), c0.Z(), c0.ErrY(), c0.ErrZ() }; |
1074 | Float_t sp1[5] = {row1.X(), c1.Y(), c1.Z(), c1.ErrY(), c1.ErrZ() }; | |
1075 | Float_t sp2[5] = {row2.X(), c2.Y(), c2.Z(), c2.ErrY(), c2.ErrZ() }; | |
1076 | if( track.NCells()>=3 ){ | |
1077 | p0.Param().ConstructXYZ3(sp0,sp1,sp2,p0.Param().CosPhi(), t0); | |
1078 | p2.Param().ConstructXYZ3(sp2,sp1,sp0,p2.Param().CosPhi(), t0); | |
1079 | //p2.Param() = p0.Param(); | |
1080 | //p2.Param().TransportToX(row2.X()); | |
1081 | //p2.Param().Par()[1] = -p2.Param().Par()[1]; | |
1082 | //p2.Param().Par()[4] = -p2.Param().Par()[4]; | |
1083 | } else { | |
1084 | p0.Param().X() = row0.X(); | |
1085 | p0.Param().Y() = c0.Y(); | |
1086 | p0.Param().Z() = c0.Z(); | |
1087 | p0.Param().Err2Y() = c0.ErrY()*c0.ErrY(); | |
1088 | p0.Param().Err2Z() = c0.ErrZ()*c0.ErrZ(); | |
1089 | p2.Param().X() = row2.X(); | |
1090 | p2.Param().Y() = c2.Y(); | |
1091 | p2.Param().Z() = c2.Z(); | |
1092 | p2.Param().Err2Y() = c2.ErrY()*c2.ErrY(); | |
1093 | p2.Param().Err2Z() = c2.ErrZ()*c2.ErrZ(); | |
326c2d4b | 1094 | } |
1095 | } |