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