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