]>
Commit | Line | Data |
---|---|---|
3e87ef69 | 1 | // @(#) $Id$ |
266829be | 2 | |
e9ecfae3 | 3 | /** \class AliL3ConfMapper |
4 | <pre> | |
5 | //_____________________________________________________________ | |
6 | // AliL3ConfMapper | |
7 | // | |
8 | // Conformal mapping base class | |
9 | // | |
b661165c | 10 | // Author: Anders Vestbo <mailto:vestbo@fi.uib.no> |
e9ecfae3 | 11 | // Copyright © ALICE HLT Group |
12 | </pre> | |
13 | */ | |
14 | ||
15 | #include <sys/time.h> | |
b661165c | 16 | |
118c26c3 | 17 | #include "AliL3StandardIncludes.h" |
e9ecfae3 | 18 | #include "AliL3RootTypes.h" |
19 | #include "AliL3SpacePointData.h" | |
355debe1 | 20 | #include "AliL3Logging.h" |
108615fc | 21 | #include "AliL3Vertex.h" |
22 | #include "AliL3ConfMapTrack.h" | |
23 | #include "AliL3ConfMapPoint.h" | |
24 | #include "AliL3TrackArray.h" | |
ef79795d | 25 | #include "AliL3Transform.h" |
02f030e3 | 26 | #include "AliL3ConfMapper.h" |
108615fc | 27 | |
3e87ef69 | 28 | |
108615fc | 29 | ClassImp(AliL3ConfMapper) |
30 | ||
108615fc | 31 | AliL3ConfMapper::AliL3ConfMapper() |
32 | { | |
33 | //Default constructor | |
34 | fVertex = NULL; | |
35 | fTrack = NULL; | |
36 | fHit = NULL; | |
108615fc | 37 | fVolume = NULL; |
38 | fRow = NULL; | |
39 | fBench = (Bool_t)true; | |
108615fc | 40 | fVertexConstraint = (Bool_t)true; |
0a86fbb7 | 41 | fParamSet[0]=0; |
42 | fParamSet[1]=0; | |
108615fc | 43 | } |
44 | ||
45 | ||
46 | AliL3ConfMapper::~AliL3ConfMapper() | |
47 | { | |
48 | // Destructor. | |
108615fc | 49 | if(fVolume) { |
50 | delete [] fVolume; | |
51 | } | |
52 | if(fRow) { | |
53 | delete [] fRow; | |
54 | } | |
108615fc | 55 | if(fHit) { |
56 | delete [] fHit; | |
57 | } | |
58 | if(fTrack) { | |
59 | delete fTrack; | |
60 | } | |
108615fc | 61 | } |
355debe1 | 62 | |
63 | void AliL3ConfMapper::InitVolumes() | |
64 | { | |
65 | //Data organization. | |
66 | //Allocate volumes, set conformal coordinates and pointers. | |
67 | ||
68 | //Should be done after setting the track parameters | |
69 | ||
68a27388 | 70 | fNumRowSegmentPlusOne = AliL3Transform::GetNRows();//NumRows[0]; //Maximum 32. |
355debe1 | 71 | fNumPhiSegmentPlusOne = fNumPhiSegment+1; |
72 | fNumEtaSegmentPlusOne = fNumEtaSegment+1; | |
73 | fNumPhiEtaSegmentPlusOne = fNumPhiSegmentPlusOne*fNumEtaSegmentPlusOne; | |
74 | fBounds = fNumRowSegmentPlusOne * fNumPhiSegmentPlusOne * fNumEtaSegmentPlusOne; | |
75 | ||
76 | //Allocate volumes: | |
77 | if(fVolume) delete [] fVolume; | |
78 | if(fRow) delete [] fRow; | |
79 | ||
80 | LOG(AliL3Log::kInformational,"AliL3ConfMapper::InitVolumes","Memory")<<AliL3Log::kDec<< | |
81 | "Allocating "<<fBounds*sizeof(AliL3ConfMapContainer)<<" Bytes to fVolume"<<ENDLOG; | |
82 | LOG(AliL3Log::kInformational,"AliL3ConfMapper::InitVolumes","Memory")<<AliL3Log::kDec<< | |
83 | "Allocating "<<fNumRowSegmentPlusOne*sizeof(AliL3ConfMapContainer)<<" Bytes to fRow"<<ENDLOG; | |
84 | ||
85 | fVolume = new AliL3ConfMapContainer[fBounds]; | |
86 | fRow = new AliL3ConfMapContainer[fNumRowSegmentPlusOne]; | |
87 | ||
88 | memset(fVolume,0,fBounds*sizeof(AliL3ConfMapContainer)); | |
89 | memset(fRow,0,fNumRowSegmentPlusOne*sizeof(AliL3ConfMapContainer)); | |
90 | ||
d5cdf5cf | 91 | Int_t maxnumoftracks = 2000; |
92 | Int_t maxnumofhits = 120000; | |
355debe1 | 93 | |
94 | if(fHit) | |
95 | delete [] fHit; | |
96 | if(fTrack) | |
97 | delete fTrack; | |
98 | ||
d5cdf5cf | 99 | fHit = new AliL3ConfMapPoint[maxnumofhits]; |
100 | fTrack = new AliL3TrackArray("AliL3ConfMapTrack",maxnumoftracks); | |
355debe1 | 101 | } |
108615fc | 102 | |
103 | void AliL3ConfMapper::InitSector(Int_t sector,Int_t *rowrange,Float_t *etarange) | |
02f030e3 | 104 | { //sector means slice here |
108615fc | 105 | //Initialize tracker for tracking in a given sector. |
106 | //Resets track and hit arrays. | |
107 | //Here it is also possible to specify a subsector, by defining | |
108 | //rowrange[0]=innermost row; | |
109 | //rowrange[1]=outermostrow; | |
110 | //Finally you can specify etaslices to save time (assuming a good seed from TRD...) | |
355debe1 | 111 | |
108615fc | 112 | //Define tracking area: |
113 | if(rowrange) | |
114 | { | |
115 | fRowMin = rowrange[0]; | |
116 | fRowMax = rowrange[1]; | |
117 | } | |
118 | else //complete sector | |
119 | { | |
120 | fRowMin = 0; | |
68a27388 | 121 | fRowMax = AliL3Transform::GetNRows() - 1; |
108615fc | 122 | } |
123 | if(etarange) | |
124 | { | |
125 | fEtaMin = etarange[0]; | |
ee35ea59 | 126 | fEtaMax = sector < 18 ? etarange[1] : -etarange[1]; |
108615fc | 127 | } |
128 | else | |
129 | { | |
130 | fEtaMin = 0; | |
494fad94 | 131 | fEtaMax = sector < 18 ? 0.9 : -0.9; |
108615fc | 132 | } |
133 | ||
134 | //Set the angles to sector 2: | |
5a31e9df | 135 | fPhiMin = -10*AliL3Transform::ToRad();//fParam->GetAngle(sector) - 10/todeg; |
136 | fPhiMax = 10*AliL3Transform::ToRad();//fParam->GetAngle(sector) + 10/todeg; | |
108615fc | 137 | |
d5cdf5cf | 138 | fNTracks=0; |
266829be | 139 | fMainVertexTracks = 0; |
108615fc | 140 | fClustersUnused = 0; |
68a27388 | 141 | fEtaHitsOutOfRange=0; |
142 | fPhiHitsOutOfRange=0; | |
108615fc | 143 | |
144 | fNumRowSegment = fRowMax - fRowMin; //number of rows to be considered by tracker | |
266829be | 145 | LOG(AliL3Log::kInformational,"AliL3ConfMapper::InitSector","B-field") |
eeddc64d | 146 | <<"Tracker initializing with a magnetic field of "<<AliL3Transform::GetBField()<<ENDLOG; |
355debe1 | 147 | |
148 | fTrack->Reset(); | |
108615fc | 149 | } |
150 | ||
108615fc | 151 | Bool_t AliL3ConfMapper::ReadHits(UInt_t count, AliL3SpacePointData* hits ) |
152 | { | |
b1ed0288 | 153 | //read hits |
108615fc | 154 | Int_t nhit=(Int_t)count; |
a9d69a4d | 155 | for (Int_t i=0;i<nhit;i++) |
355debe1 | 156 | { |
157 | fHit[i].Reset(); | |
158 | fHit[i].ReadHits(&(hits[i])); | |
159 | } | |
108615fc | 160 | fClustersUnused += nhit; |
355debe1 | 161 | LOG(AliL3Log::kInformational,"AliL3ConfMapper::ReadHits","#hits") |
162 | <<AliL3Log::kDec<<"hit_counter: "<<nhit<<" count: "<<count<<ENDLOG; | |
163 | ||
108615fc | 164 | return true; |
165 | } | |
166 | ||
108615fc | 167 | void AliL3ConfMapper::SetPointers() |
168 | { | |
3e87ef69 | 169 | //Check if there are not enough clusters to make a track in this sector |
170 | //Can happen in pp events. | |
02f030e3 | 171 | |
3e87ef69 | 172 | if(fClustersUnused < fMinPoints[fVertexConstraint]) |
173 | return; | |
174 | ||
355debe1 | 175 | //Reset detector volumes |
108615fc | 176 | memset(fVolume,0,fBounds*sizeof(AliL3ConfMapContainer)); |
177 | memset(fRow,0,fNumRowSegmentPlusOne*sizeof(AliL3ConfMapContainer)); | |
178 | ||
179 | Float_t phiSlice = (fPhiMax-fPhiMin)/fNumPhiSegment; | |
180 | Float_t etaSlice = (fEtaMax-fEtaMin)/fNumEtaSegment; | |
355debe1 | 181 | |
108615fc | 182 | Int_t volumeIndex; |
d5cdf5cf | 183 | Int_t localcounter=0; |
108615fc | 184 | for(Int_t j=0; j<fClustersUnused; j++) |
185 | { | |
108615fc | 186 | //AliL3ConfMapPoint *thisHit = (AliL3ConfMapPoint*)fHit->At(j); |
a9d69a4d | 187 | AliL3ConfMapPoint *thisHit = &(fHit[j]); |
108615fc | 188 | |
189 | thisHit->Setup(fVertex); | |
190 | ||
191 | Int_t localrow = thisHit->GetPadRow(); | |
192 | ||
108615fc | 193 | if(localrow < fRowMin || localrow > fRowMax) |
194 | continue; | |
108615fc | 195 | |
196 | //Get indexes: | |
47e75a3e | 197 | thisHit->SetPhiIndex((Int_t)((thisHit->GetPhi()-fPhiMin)/phiSlice +1)); |
108615fc | 198 | |
47e75a3e | 199 | if(thisHit->GetPhiIndex()<1 || thisHit->GetPhiIndex()>fNumPhiSegment) |
108615fc | 200 | { |
02f030e3 | 201 | //cout << "Phiindex: " << thisHit->phiIndex << " " << thisHit->GetPhi() << endl; |
108615fc | 202 | fPhiHitsOutOfRange++; |
203 | continue; | |
204 | } | |
205 | ||
47e75a3e | 206 | thisHit->SetEtaIndex((Int_t)((thisHit->GetEta()-fEtaMin)/etaSlice + 1)); |
207 | if(thisHit->GetEtaIndex()<1 || thisHit->GetEtaIndex()>fNumEtaSegment) | |
108615fc | 208 | { |
02f030e3 | 209 | //cout << "Etaindex: " << thisHit->etaIndex << " " << thisHit->GetEta() << endl; |
108615fc | 210 | fEtaHitsOutOfRange++; |
211 | continue; | |
212 | } | |
d5cdf5cf | 213 | localcounter++; |
355debe1 | 214 | |
47e75a3e | 215 | volumeIndex = (localrow-fRowMin)*fNumPhiEtaSegmentPlusOne + |
216 | thisHit->GetPhiIndex()*fNumEtaSegmentPlusOne+thisHit->GetEtaIndex(); | |
355debe1 | 217 | |
108615fc | 218 | if(fVolume[volumeIndex].first == NULL) |
219 | fVolume[volumeIndex].first = (void *)thisHit; | |
220 | else | |
47e75a3e | 221 | ((AliL3ConfMapPoint *)fVolume[volumeIndex].last)->SetNextVolumeHit(thisHit); |
108615fc | 222 | fVolume[volumeIndex].last = (void *)thisHit; |
223 | ||
224 | ||
225 | //set row pointers | |
355debe1 | 226 | if(fRow[(localrow-fRowMin)].first == NULL) |
227 | fRow[(localrow-fRowMin)].first = (void *)thisHit; | |
108615fc | 228 | else |
47e75a3e | 229 | ((AliL3ConfMapPoint *)(fRow[(localrow-fRowMin)].last))->SetNextRowHit(thisHit); |
355debe1 | 230 | fRow[(localrow-fRowMin)].last = (void *)thisHit; |
108615fc | 231 | } |
232 | ||
d5cdf5cf | 233 | if(fClustersUnused>0 && localcounter==0) |
e0e14b24 | 234 | LOG(AliL3Log::kError,"AliL3ConfMapper::SetPointers","Parameters") |
235 | <<AliL3Log::kDec<<"No points passed to track finder, hits out of range: " | |
236 | <<fEtaHitsOutOfRange+fPhiHitsOutOfRange<<ENDLOG; | |
355debe1 | 237 | |
02f030e3 | 238 | Int_t hits_accepted=fClustersUnused-(fEtaHitsOutOfRange+fPhiHitsOutOfRange); |
355debe1 | 239 | LOG(AliL3Log::kInformational,"AliL3ConfMapper::SetPointers","Setup") |
240 | <<"Setup finished, hits out of range: "<<fEtaHitsOutOfRange+fPhiHitsOutOfRange | |
02f030e3 | 241 | <<" hits accepted "<<hits_accepted<<ENDLOG; |
108615fc | 242 | } |
243 | ||
244 | void AliL3ConfMapper::MainVertexTracking_a() | |
245 | { | |
246 | //Tracking with vertex constraint. | |
247 | ||
0a86fbb7 | 248 | if(!fParamSet[(Int_t)kTRUE]) |
108615fc | 249 | { |
250 | LOG(AliL3Log::kError,"AliL3ConfMapper::MainVertexTracking","Parameters")<<AliL3Log::kDec<< | |
251 | "Tracking parameters not set!"<<ENDLOG; | |
252 | return; | |
253 | } | |
254 | ||
355debe1 | 255 | Double_t initCpuTime,cpuTime; |
256 | initCpuTime = CpuTime(); | |
02f030e3 | 257 | |
108615fc | 258 | SetPointers(); |
259 | SetVertexConstraint(true); | |
355debe1 | 260 | cpuTime = CpuTime() - initCpuTime; |
261 | if(fBench) | |
262 | LOG(AliL3Log::kInformational,"AliL3ConfMapper::MainVertexTracking_a","Timing") | |
263 | <<AliL3Log::kDec<<"Setup finished in "<<cpuTime*1000<<" ms"<<ENDLOG; | |
264 | ||
108615fc | 265 | } |
266 | ||
267 | void AliL3ConfMapper::MainVertexTracking_b() | |
268 | { | |
269 | //Tracking with vertex constraint. | |
270 | ||
0a86fbb7 | 271 | if(!fParamSet[(Int_t)kTRUE]) |
108615fc | 272 | { |
273 | LOG(AliL3Log::kError,"AliL3ConfMapper::MainVertexTracking","Parameters")<<AliL3Log::kDec<< | |
274 | "Tracking parameters not set!"<<ENDLOG; | |
275 | return; | |
276 | } | |
355debe1 | 277 | Double_t initCpuTime,cpuTime; |
278 | initCpuTime = CpuTime(); | |
279 | ||
108615fc | 280 | ClusterLoop(); |
355debe1 | 281 | |
282 | cpuTime = CpuTime() - initCpuTime; | |
283 | if(fBench) | |
284 | LOG(AliL3Log::kInformational,"AliL3ConfMapper::MainVertexTracking_b","Timing") | |
285 | <<AliL3Log::kDec<<"Main Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG; | |
108615fc | 286 | } |
287 | ||
288 | void AliL3ConfMapper::MainVertexTracking() | |
289 | { | |
290 | //Tracking with vertex constraint. | |
291 | ||
0a86fbb7 | 292 | if(!fParamSet[(Int_t)kTRUE]) |
108615fc | 293 | { |
294 | LOG(AliL3Log::kError,"AliL3ConfMapper::MainVertexTracking","Parameters")<<AliL3Log::kDec<< | |
295 | "Tracking parameters not set!"<<ENDLOG; | |
296 | return; | |
297 | } | |
298 | ||
299 | Double_t initCpuTime,cpuTime; | |
300 | initCpuTime = CpuTime(); | |
301 | ||
302 | SetPointers(); | |
303 | SetVertexConstraint(true); | |
304 | ||
305 | ClusterLoop(); | |
306 | ||
307 | cpuTime = CpuTime() - initCpuTime; | |
308 | if(fBench) | |
309 | LOG(AliL3Log::kInformational,"AliL3ConfMapper::MainVertexTracking","Timing")<<AliL3Log::kDec<< | |
310 | "Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG; | |
355debe1 | 311 | |
108615fc | 312 | return; |
313 | } | |
314 | ||
315 | void AliL3ConfMapper::NonVertexTracking() | |
316 | { | |
317 | //Tracking with no vertex constraint. This should be called after doing MainVertexTracking, | |
318 | //in order to do tracking on the remaining clusters. | |
319 | //The conformal mapping is now done with respect to the first cluster | |
320 | //assosciated with this track. | |
0a86fbb7 | 321 | |
322 | if(!fParamSet[(Int_t)kFALSE]) | |
323 | { | |
324 | LOG(AliL3Log::kError,"AliL3ConfMapper::NonVertexTracking","Parameters")<<AliL3Log::kDec<< | |
325 | "Tracking parameters not set!"<<ENDLOG; | |
326 | return; | |
327 | } | |
328 | ||
108615fc | 329 | SetVertexConstraint(false); |
330 | ClusterLoop(); | |
331 | LOG(AliL3Log::kInformational,"AliL3ConfMapper::NonVertexTracking","ntracks")<<AliL3Log::kDec<< | |
d5cdf5cf | 332 | "Number of nonvertex tracks found: "<<(fNTracks-fMainVertexTracks)<<ENDLOG; |
108615fc | 333 | return; |
334 | } | |
335 | ||
336 | void AliL3ConfMapper::MainVertexSettings(Int_t trackletlength, Int_t tracklength, | |
337 | Int_t rowscopetracklet, Int_t rowscopetrack, | |
338 | Double_t maxphi,Double_t maxeta) | |
339 | { | |
340 | //Settings for main vertex tracking. The cuts are: | |
341 | //TrackletLength: #hits on segment, before trying to build a track | |
342 | //TrackLength: Minimum hits on a track | |
343 | //RowScopeTracklet: Row search range for segments | |
344 | //RowScopeTrack: Row search range for tracks | |
345 | ||
346 | SetTrackletLength(trackletlength,(Bool_t)true); | |
347 | SetRowScopeTracklet(rowscopetracklet, (Bool_t) true); | |
348 | SetRowScopeTrack(rowscopetrack, (Bool_t) true); | |
349 | SetMinPoints(tracklength,(Bool_t)true); | |
350 | fMaxPhi=maxphi; | |
351 | fMaxEta=maxeta; | |
0a86fbb7 | 352 | SetParamDone(kTRUE); |
108615fc | 353 | } |
354 | ||
355 | void AliL3ConfMapper::NonVertexSettings(Int_t trackletlength, Int_t tracklength, | |
356 | Int_t rowscopetracklet, Int_t rowscopetrack) | |
357 | { | |
b1ed0288 | 358 | //set parameters for non-vertex tracking |
108615fc | 359 | SetTrackletLength(trackletlength,(Bool_t)false); |
360 | SetRowScopeTracklet(rowscopetracklet, (Bool_t)false); | |
361 | SetRowScopeTrack(rowscopetrack, (Bool_t)false); | |
362 | SetMinPoints(tracklength,(Bool_t)false); | |
0a86fbb7 | 363 | SetParamDone(kFALSE); |
108615fc | 364 | } |
365 | ||
02f030e3 | 366 | void AliL3ConfMapper::SetTrackCuts(Double_t hitChi2Cut, Double_t goodHitChi2, Double_t trackChi2Cut,Int_t maxdist,Bool_t vertexconstraint) |
108615fc | 367 | { |
368 | //Settings for tracks. The cuts are: | |
369 | //HitChi2Cut: Maximum hit chi2 | |
370 | //goodHitChi2: Chi2 to stop look for next hit | |
371 | //trackChi2Cut: Maximum track chi2 | |
372 | //maxdist: Maximum distance between two clusters when forming segments | |
266829be | 373 | |
374 | SetHitChi2Cut(hitChi2Cut,vertexconstraint); | |
375 | SetGoodHitChi2(goodHitChi2,vertexconstraint); | |
376 | SetTrackChi2Cut(trackChi2Cut,vertexconstraint); | |
377 | SetMaxDist(maxdist,vertexconstraint); | |
108615fc | 378 | } |
379 | ||
d5cdf5cf | 380 | void AliL3ConfMapper::SetTrackletCuts(Double_t maxangle,Double_t goodDist, Bool_t vc) |
108615fc | 381 | { |
382 | //Sets cuts of tracklets. Right now this is only: | |
383 | //maxangle: Maximum angle when forming segments (if trackletlength > 2) | |
384 | ||
385 | fGoodDist=goodDist; | |
d5cdf5cf | 386 | SetMaxAngleTracklet(maxangle, vc); |
108615fc | 387 | } |
388 | ||
389 | void AliL3ConfMapper::ClusterLoop() | |
390 | { | |
391 | //Loop over hits, starting at outermost padrow, and trying to build segments. | |
3e87ef69 | 392 | |
393 | //Check if there are not enough clusters to make a track in this sector | |
394 | //Can happen in pp events. | |
395 | if(fClustersUnused < fMinPoints[fVertexConstraint]) | |
396 | return; | |
397 | ||
d5cdf5cf | 398 | Int_t rowsegm,lastrow = fRowMin + fMinPoints[fVertexConstraint]; |
108615fc | 399 | AliL3ConfMapPoint *hit; |
400 | ||
401 | //Loop over rows, and try to create tracks from the hits. | |
402 | //Starts at the outermost row, and loops as long as a track can be build, due to length. | |
403 | ||
d5cdf5cf | 404 | for(rowsegm = fRowMax; rowsegm >= lastrow; rowsegm--) |
108615fc | 405 | { |
d5cdf5cf | 406 | if(fRow[(rowsegm-fRowMin)].first && ((AliL3ConfMapPoint*)fRow[(rowsegm-fRowMin)].first)->GetPadRow() < fRowMin + 1) |
108615fc | 407 | break; |
02f030e3 | 408 | |
47e75a3e | 409 | for(hit = (AliL3ConfMapPoint*)fRow[(rowsegm-fRowMin)].first; hit!=0; hit=hit->GetNextRowHit()) |
108615fc | 410 | { |
411 | if(hit->GetUsage() == true) | |
412 | continue; | |
413 | else | |
414 | CreateTrack(hit); | |
415 | } | |
416 | } | |
417 | ||
418 | return; | |
419 | } | |
420 | ||
421 | ||
422 | void AliL3ConfMapper::CreateTrack(AliL3ConfMapPoint *hit) | |
423 | { | |
424 | //Tries to create a track from the initial hit given by ClusterLoop() | |
425 | ||
d5cdf5cf | 426 | AliL3ConfMapPoint *closesthit = NULL; |
108615fc | 427 | AliL3ConfMapTrack *track = NULL; |
428 | ||
429 | Int_t point; | |
d5cdf5cf | 430 | Int_t tracks = fNTracks; |
431 | fNTracks++; | |
108615fc | 432 | |
433 | track = (AliL3ConfMapTrack*)fTrack->NextTrack(); | |
434 | ||
435 | //reset hit parameters: | |
436 | track->Reset(); | |
437 | ||
438 | UInt_t *trackhitnumber = track->GetHitNumbers(); | |
439 | ||
440 | //set conformal coordinates if we are looking for non vertex tracks | |
441 | if(!fVertexConstraint) | |
442 | { | |
443 | hit->SetAllCoord(hit); | |
444 | } | |
445 | ||
446 | //fill fit parameters of initial track: | |
447 | track->UpdateParam(hit); //here the number of hits is incremented. | |
448 | trackhitnumber[track->GetNumberOfPoints()-1] = hit->GetHitNumber(); | |
449 | ||
450 | Double_t dx,dy; | |
451 | //create tracklets: | |
452 | ||
453 | for(point=1; point<fTrackletLength[fVertexConstraint]; point++) | |
454 | { | |
d5cdf5cf | 455 | if((closesthit = GetNextNeighbor(hit))) |
108615fc | 456 | {//closest hit exist |
457 | ||
458 | // Calculate track length in sz plane | |
d5cdf5cf | 459 | dx = ((AliL3ConfMapPoint*)closesthit)->GetX() - ((AliL3ConfMapPoint*)hit)->GetX(); |
460 | dy = ((AliL3ConfMapPoint*)closesthit)->GetY() - ((AliL3ConfMapPoint*)hit)->GetY(); | |
108615fc | 461 | //track->fLength += (Double_t)sqrt ( dx * dx + dy * dy ) ; |
462 | Double_t length = track->GetLength()+(Double_t)sqrt ( dx * dx + dy * dy ); | |
463 | track->SetLength(length); | |
464 | ||
d5cdf5cf | 465 | //closesthit->SetS(track->fLength); |
466 | closesthit->SetS(track->GetLength()); | |
108615fc | 467 | |
468 | //update fit parameters | |
d5cdf5cf | 469 | track->UpdateParam(closesthit); |
470 | trackhitnumber[track->GetNumberOfPoints()-1] = closesthit->GetHitNumber(); | |
108615fc | 471 | |
d5cdf5cf | 472 | hit = closesthit; |
108615fc | 473 | } |
474 | else | |
475 | { | |
476 | //closest hit does not exist: | |
477 | track->DeleteCandidate(); | |
478 | fTrack->RemoveLast(); | |
d5cdf5cf | 479 | fNTracks--; |
108615fc | 480 | point = fTrackletLength[fVertexConstraint]; |
481 | } | |
482 | } | |
483 | ||
484 | //tracklet is long enough to be extended to a track | |
485 | if(track->GetNumberOfPoints() == fTrackletLength[fVertexConstraint]) | |
486 | { | |
487 | ||
488 | track->SetProperties(true); | |
489 | ||
490 | if(TrackletAngle(track) > fMaxAngleTracklet[fVertexConstraint]) | |
491 | {//proof if the first points seem to be a beginning of a track | |
108615fc | 492 | track->SetProperties(false); |
493 | track->DeleteCandidate(); | |
494 | fTrack->RemoveLast(); | |
d5cdf5cf | 495 | fNTracks--; |
108615fc | 496 | } |
497 | ||
498 | else//good tracklet ->proceed, follow the trackfit | |
499 | { | |
500 | tracks++; | |
501 | ||
502 | //define variables to keep the total chi: | |
b1ed0288 | 503 | Double_t xyChi2 = track->GetChiSq1(); |
504 | Double_t szChi2 = track->GetChiSq2(); | |
108615fc | 505 | |
506 | for(point = fTrackletLength[fVertexConstraint]; point <= fNumRowSegment; point++) | |
507 | { | |
b1ed0288 | 508 | track->SetChiSq1(fHitChi2Cut[fVertexConstraint]); |
d5cdf5cf | 509 | closesthit = GetNextNeighbor((AliL3ConfMapPoint*)track->GetLastHit(),track); |
108615fc | 510 | |
d5cdf5cf | 511 | if(closesthit) |
108615fc | 512 | { |
108615fc | 513 | //keep total chi: |
b1ed0288 | 514 | Double_t lxyChi2 = track->GetChiSq1()-track->GetChiSq2(); |
108615fc | 515 | xyChi2 += lxyChi2; |
47e75a3e | 516 | closesthit->SetXYChi2(lxyChi2); |
108615fc | 517 | |
518 | //update track length: | |
d5cdf5cf | 519 | track->SetLength(closesthit->GetS()); |
b1ed0288 | 520 | szChi2 += track->GetChiSq2(); |
47e75a3e | 521 | closesthit->SetSZChi2(track->GetChiSq2()); |
108615fc | 522 | |
d5cdf5cf | 523 | track->UpdateParam(closesthit); |
524 | trackhitnumber[track->GetNumberOfPoints()-1] = closesthit->GetHitNumber(); | |
108615fc | 525 | |
526 | //add closest hit to track | |
d5cdf5cf | 527 | closesthit->SetUsage(true); |
528 | closesthit->SetTrackNumber(tracks-1); | |
28a650e7 | 529 | |
d5cdf5cf | 530 | }//closesthit |
28a650e7 | 531 | |
108615fc | 532 | else |
533 | { | |
534 | //closest hit does not exist | |
535 | point = fNumRowSegment; //continue with next hit in segment | |
536 | }//else | |
537 | ||
538 | }//create tracks | |
539 | ||
540 | //store track chi2: | |
b1ed0288 | 541 | track->SetChiSq1(xyChi2); |
542 | track->SetChiSq2(szChi2); | |
d5cdf5cf | 543 | Double_t normalizedchi2 = (track->GetChiSq1()+track->GetChiSq2())/track->GetNumberOfPoints(); |
108615fc | 544 | |
545 | //remove tracks with not enough points already now | |
d5cdf5cf | 546 | if(track->GetNumberOfPoints() < fMinPoints[fVertexConstraint] || normalizedchi2 > fTrackChi2Cut[fVertexConstraint]) |
108615fc | 547 | { |
548 | track->SetProperties(false); | |
d5cdf5cf | 549 | fNTracks--; |
108615fc | 550 | track->DeleteCandidate(); |
551 | fTrack->RemoveLast(); | |
552 | tracks--; | |
553 | } | |
554 | ||
555 | else | |
556 | { | |
557 | fClustersUnused -= track->GetNumberOfPoints(); | |
558 | track->ComesFromMainVertex(fVertexConstraint); | |
559 | //mark track as main vertex track or not | |
560 | track->SetSector(2); //only needed for testing purposes. | |
561 | track->SetRowRange(fRowMin,fRowMax); | |
562 | ||
563 | if(fVertexConstraint) | |
564 | fMainVertexTracks++; | |
565 | } | |
566 | ||
567 | }//good tracklet | |
568 | ||
569 | } | |
570 | ||
571 | return; | |
572 | } | |
573 | ||
d5cdf5cf | 574 | AliL3ConfMapPoint *AliL3ConfMapper::GetNextNeighbor(AliL3ConfMapPoint *starthit, |
108615fc | 575 | AliL3ConfMapTrack *track) |
576 | { | |
577 | //When forming segments: Finds closest hit to input hit | |
578 | //When forming tracks: Find closest hit to track fit. | |
579 | ||
d5cdf5cf | 580 | Double_t dist,closestdist = fMaxDist[fVertexConstraint]; |
108615fc | 581 | |
582 | AliL3ConfMapPoint *hit = NULL; | |
d5cdf5cf | 583 | AliL3ConfMapPoint *closesthit = NULL; |
108615fc | 584 | |
d5cdf5cf | 585 | Int_t subrowsegm; |
586 | Int_t subphisegm; | |
587 | Int_t subetasegm; | |
108615fc | 588 | Int_t volumeIndex; |
d5cdf5cf | 589 | Int_t testhit; |
108615fc | 590 | |
d5cdf5cf | 591 | Int_t maxrow = starthit->GetPadRow()-1; |
592 | Int_t minrow; | |
108615fc | 593 | |
594 | if(track) //finding hit close to trackfit | |
595 | { | |
d5cdf5cf | 596 | minrow = starthit->GetPadRow()-fRowScopeTrack[fVertexConstraint]; |
108615fc | 597 | } |
598 | else | |
599 | { | |
d5cdf5cf | 600 | minrow = starthit->GetPadRow()-fRowScopeTracklet[fVertexConstraint]; |
108615fc | 601 | } |
602 | ||
603 | //make a smart loop | |
d5cdf5cf | 604 | Int_t loopeta[25] = {0,0,0,-1,-1,-1,1,1,1, 0,0,-1,-1,1,1,-2,-2,-2,-2,-2,2,2,2,2,2}; |
605 | Int_t loopphi[25] = {0,-1,1,0,-1,1,0,-1,1, -2,2,-2,2,-2,2,-2,-1,0,1,2,-2,-1,0,1,2}; | |
108615fc | 606 | |
d5cdf5cf | 607 | if(minrow < fRowMin) |
608 | minrow = fRowMin; | |
609 | if(maxrow < fRowMin) | |
108615fc | 610 | return 0; //reached the last padrow under consideration |
611 | ||
612 | else | |
613 | { | |
614 | //loop over sub rows | |
d5cdf5cf | 615 | for(subrowsegm=maxrow; subrowsegm>=minrow; subrowsegm--) |
108615fc | 616 | { |
617 | //loop over subsegments, in the order defined above. | |
618 | for(Int_t i=0; i<9; i++) | |
619 | { | |
47e75a3e | 620 | subphisegm = starthit->GetPhiIndex() + loopphi[i]; |
108615fc | 621 | |
d5cdf5cf | 622 | if(subphisegm < 0 || subphisegm >= fNumPhiSegment) |
0a86fbb7 | 623 | continue; |
624 | /* | |
d5cdf5cf | 625 | if(subphisegm<0) |
626 | subphisegm += fNumPhiSegment; | |
0a86fbb7 | 627 | |
d5cdf5cf | 628 | else if(subphisegm >=fNumPhiSegment) |
629 | subphisegm -= fNumPhiSegment; | |
0a86fbb7 | 630 | */ |
108615fc | 631 | //loop over sub eta segments |
632 | ||
47e75a3e | 633 | subetasegm = starthit->GetEtaIndex() + loopeta[i]; |
108615fc | 634 | |
d5cdf5cf | 635 | if(subetasegm < 0 || subetasegm >=fNumEtaSegment) |
108615fc | 636 | continue;//segment exceeds bounds->skip it |
637 | ||
638 | //loop over hits in this sub segment: | |
d5cdf5cf | 639 | volumeIndex=(subrowsegm-fRowMin)*fNumPhiEtaSegmentPlusOne + |
640 | subphisegm*fNumEtaSegmentPlusOne + subetasegm; | |
108615fc | 641 | |
642 | if(volumeIndex<0) | |
643 | {//debugging | |
644 | LOG(AliL3Log::kError,"AliL3ConfMapper::GetNextNeighbor","Memory")<<AliL3Log::kDec<< | |
645 | "VolumeIndex error "<<volumeIndex<<ENDLOG; | |
646 | } | |
647 | ||
648 | for(hit = (AliL3ConfMapPoint*)fVolume[volumeIndex].first; | |
47e75a3e | 649 | hit!=0; hit = hit->GetNextVolumeHit()) |
108615fc | 650 | { |
651 | ||
652 | if(!hit->GetUsage()) | |
653 | {//hit was not used before | |
654 | ||
655 | //set conformal mapping if looking for nonvertex tracks: | |
656 | if(!fVertexConstraint) | |
657 | { | |
d5cdf5cf | 658 | hit->SetAllCoord(starthit); |
108615fc | 659 | } |
660 | ||
661 | if(track)//track search - look for nearest neighbor to extrapolated track | |
662 | { | |
d5cdf5cf | 663 | if(!VerifyRange(starthit,hit)) |
108615fc | 664 | continue; |
665 | ||
d5cdf5cf | 666 | testhit = EvaluateHit(starthit,hit,track); |
108615fc | 667 | |
d5cdf5cf | 668 | if(testhit == 0)//chi2 not good enough, keep looking |
108615fc | 669 | continue; |
d5cdf5cf | 670 | else if(testhit==2)//chi2 good enough, return it |
108615fc | 671 | return hit; |
672 | else | |
d5cdf5cf | 673 | closesthit = hit;//chi2 acceptable, but keep looking |
108615fc | 674 | |
675 | }//track search | |
676 | ||
677 | else //tracklet search, look for nearest neighbor | |
678 | { | |
679 | ||
d5cdf5cf | 680 | if((dist=CalcDistance(starthit,hit)) < closestdist) |
108615fc | 681 | { |
d5cdf5cf | 682 | if(!VerifyRange(starthit,hit)) |
108615fc | 683 | continue; |
d5cdf5cf | 684 | closestdist = dist; |
685 | closesthit = hit; | |
108615fc | 686 | |
687 | //if this hit is good enough, return it: | |
d5cdf5cf | 688 | if(closestdist < fGoodDist) |
689 | return closesthit; | |
108615fc | 690 | } |
691 | else | |
692 | continue;//sub hit was farther away than a hit before | |
693 | ||
694 | }//tracklet search | |
695 | ||
696 | }//hit not used before | |
697 | ||
698 | else continue; //sub hit was used before | |
699 | ||
700 | }//loop over hits in sub segment | |
701 | ||
702 | }//loop over sub segments | |
703 | ||
704 | }//loop over subrows | |
705 | ||
706 | }//else | |
707 | ||
708 | //closest hit found: | |
d5cdf5cf | 709 | if(closesthit)// && closestdist < mMaxDist) |
710 | return closesthit; | |
108615fc | 711 | else |
712 | return 0; | |
713 | } | |
714 | ||
d5cdf5cf | 715 | Int_t AliL3ConfMapper::EvaluateHit(AliL3ConfMapPoint *starthit,AliL3ConfMapPoint *hit,AliL3ConfMapTrack *track) |
108615fc | 716 | { |
717 | //Check if space point gives a fit with acceptable chi2. | |
718 | ||
719 | Double_t temp,dxy,lchi2,dx,dy,slocal,dsz,lszChi2; | |
b1ed0288 | 720 | temp = (track->GetA2Xy()*hit->GetXprime()-hit->GetYprime()+track->GetA1Xy()); |
721 | dxy = temp*temp/(track->GetA2Xy()*track->GetA2Xy() + 1.); | |
108615fc | 722 | |
723 | //Calculate chi2 | |
724 | lchi2 = (dxy*hit->GetXYWeight()); | |
725 | ||
b1ed0288 | 726 | if(lchi2 > track->GetChiSq1())//chi2 was worse than before. |
108615fc | 727 | return 0; |
728 | ||
729 | //calculate s and the distance hit-line | |
d5cdf5cf | 730 | dx = starthit->GetX()-hit->GetX(); |
731 | dy = starthit->GetY()-hit->GetY(); | |
108615fc | 732 | //slocal = track->fLength+sqrt(dx*dx+dy*dy); |
733 | slocal = track->GetLength()+sqrt(dx*dx+dy*dy); | |
734 | ||
b1ed0288 | 735 | temp = (track->GetA2Sz()*slocal-hit->GetZ()+track->GetA1Sz()); |
736 | dsz = temp*temp/(track->GetA2Sz()*track->GetA2Sz()+1); | |
108615fc | 737 | |
738 | //calculate chi2 | |
739 | lszChi2 = dsz*hit->GetZWeight(); | |
740 | lchi2 += lszChi2; | |
741 | ||
742 | ||
743 | //check whether chi2 is better than previous one: | |
b1ed0288 | 744 | if(lchi2 < track->GetChiSq1()) |
108615fc | 745 | { |
b1ed0288 | 746 | track->SetChiSq1(lchi2); |
747 | track->SetChiSq2(lszChi2); | |
108615fc | 748 | |
749 | hit->SetS(slocal); | |
750 | ||
751 | //if chi2 good enough, stop here: | |
266829be | 752 | if(lchi2 < fGoodHitChi2[fVertexConstraint]) |
108615fc | 753 | return 2; |
754 | ||
755 | return 1; | |
756 | } | |
757 | ||
758 | return 0; | |
759 | ||
760 | } | |
761 | ||
762 | Double_t AliL3ConfMapper::CalcDistance(const AliL3ConfMapPoint *hit1,const AliL3ConfMapPoint *hit2) const | |
763 | { | |
764 | //Return distance between two clusters, defined by Pablo | |
765 | ||
d5cdf5cf | 766 | Double_t phidiff = fabs( hit1->GetPhi() - hit2->GetPhi() ); |
767 | if (phidiff > AliL3Transform::Pi()) phidiff = AliL3Transform::TwoPi() - phidiff; | |
108615fc | 768 | |
d5cdf5cf | 769 | return AliL3Transform::ToDeg()*fabs((Float_t)((hit1->GetPadRow() - hit2->GetPadRow()) * |
770 | (phidiff + fabs( hit1->GetEta() - hit2->GetEta())))); | |
108615fc | 771 | } |
772 | ||
773 | Bool_t AliL3ConfMapper::VerifyRange(const AliL3ConfMapPoint *hit1,const AliL3ConfMapPoint *hit2) const | |
774 | { | |
775 | //Check if the hit are within reasonable range in phi and eta | |
776 | Double_t dphi,deta;//maxphi=0.1,maxeta=0.1; | |
777 | dphi = fabs(hit1->GetPhi() - hit2->GetPhi()); | |
5a31e9df | 778 | if(dphi > AliL3Transform::Pi()) dphi = fabs(AliL3Transform::TwoPi() - dphi); |
108615fc | 779 | if(dphi > fMaxPhi) return false; |
780 | ||
781 | deta = fabs(hit1->GetEta() - hit2->GetEta()); | |
782 | if(deta > fMaxEta) return false; | |
783 | ||
784 | return true; | |
785 | ||
786 | } | |
787 | ||
3e87ef69 | 788 | Double_t AliL3ConfMapper::TrackletAngle(AliL3ConfMapTrack *track,Int_t n) const |
108615fc | 789 | { |
790 | // Returns the angle 'between' the last three points (started at point number n) on this track. | |
3e87ef69 | 791 | |
792 | if(n > track->GetNumberOfPoints()) | |
793 | n = track->GetNumberOfPoints(); | |
794 | ||
795 | if(n<3) | |
796 | return 0; | |
797 | ||
108615fc | 798 | Double_t x1[2]; |
799 | Double_t x2[2]; | |
3e87ef69 | 800 | Double_t x3[2]; |
801 | Double_t angle1,angle2; | |
802 | Int_t counter=0; | |
803 | for(track->StartLoop(); track->LoopDone(); track->GetNextHit()) | |
804 | { | |
b1ed0288 | 805 | AliL3ConfMapPoint *p = (AliL3ConfMapPoint*)track->GetCurrentHit(); |
3e87ef69 | 806 | if( (n-1) == counter) |
807 | { | |
808 | x1[0] = p->GetX(); | |
809 | x1[1] = p->GetY(); | |
810 | } | |
811 | else if( (n-2) == counter) | |
812 | { | |
813 | x2[0] = p->GetX(); | |
814 | x2[1] = p->GetY(); | |
815 | } | |
816 | else if( (n-3) == counter) | |
817 | { | |
818 | x3[0] = p->GetX(); | |
819 | x3[1] = p->GetY(); | |
820 | } | |
821 | counter++; | |
822 | } | |
823 | ||
824 | angle1 = atan2(x2[1]-x3[1],x2[0]-x3[0]); | |
825 | angle2 = atan2(x1[1]-x2[1],x1[0]-x2[0]); | |
826 | ||
827 | return fabs(angle1-angle2); | |
828 | ||
829 | /* | |
830 | Double_t x1[2]; | |
831 | Double_t x2[2]; | |
108615fc | 832 | Double_t angle1,angle2; |
833 | TObjArray *hits = track->GetHits(); | |
834 | ||
835 | if (n > track->GetNumberOfPoints()) { | |
836 | n = track->GetNumberOfPoints(); | |
837 | } | |
838 | ||
839 | if (n<3) | |
840 | return 0; | |
841 | ||
842 | ||
843 | x1[0] = ((AliL3ConfMapPoint *)hits->At(n-2))->GetX() - ((AliL3ConfMapPoint *)hits->At(n-3))->GetX(); | |
844 | x1[1] = ((AliL3ConfMapPoint *)hits->At(n-2))->GetY() - ((AliL3ConfMapPoint *)hits->At(n-3))->GetY(); | |
845 | ||
846 | x2[0] = ((AliL3ConfMapPoint *)hits->At(n-1))->GetX() - ((AliL3ConfMapPoint *)hits->At(n-2))->GetX(); | |
847 | x2[1] = ((AliL3ConfMapPoint *)hits->At(n-1))->GetY() - ((AliL3ConfMapPoint *)hits->At(n-2))->GetY(); | |
848 | ||
849 | angle1 = atan2(x1[1],x1[0]); | |
850 | angle2 = atan2(x2[1],x1[0]); | |
851 | return fabs(angle1-angle2); | |
852 | */ | |
853 | } | |
854 | ||
855 | Int_t AliL3ConfMapper::FillTracks() | |
856 | { | |
857 | //Fill track parameters. Which basically means do a fit of helix in real space, | |
858 | //which should be done in order to get nice tracks. | |
859 | ||
d5cdf5cf | 860 | Int_t numoftracks = fNTracks; |
861 | if(fNTracks == 0) | |
108615fc | 862 | { |
d5cdf5cf | 863 | LOG(AliL3Log::kError,"AliL3ConfMapper::FillTracks","fNTracks")<<AliL3Log::kDec<< |
108615fc | 864 | "No tracks found!!"<<ENDLOG; |
865 | return 0; | |
866 | } | |
b1ed0288 | 867 | |
d5cdf5cf | 868 | LOG(AliL3Log::kInformational,"AliL3ConfMapper::FillTracks","fNTracks")<<AliL3Log::kDec<< |
869 | "Number of found tracks: "<<fNTracks<<ENDLOG; | |
108615fc | 870 | |
871 | // fTrack->Sort(); | |
d5cdf5cf | 872 | for(Int_t i=0; i<numoftracks; i++) |
108615fc | 873 | { |
874 | AliL3ConfMapTrack *track = (AliL3ConfMapTrack*)fTrack->GetTrack(i); | |
875 | track->Fill(fVertex,fMaxDca); | |
876 | } | |
877 | return 1; | |
108615fc | 878 | } |
879 | ||
880 | Double_t AliL3ConfMapper::CpuTime() | |
881 | { | |
882 | //Return the Cputime in seconds. | |
355debe1 | 883 | struct timeval tv; |
884 | gettimeofday( &tv, NULL ); | |
885 | return tv.tv_sec+(((Double_t)tv.tv_usec)/1000000.); | |
108615fc | 886 | } |