]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/src/AliL3ConfMapper.cxx
Introduction of the online monitoring code into the alimdc package. Fixed some memory...
[u/mrichter/AliRoot.git] / HLT / src / AliL3ConfMapper.cxx
CommitLineData
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 &copy 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 29ClassImp(AliL3ConfMapper)
30
108615fc 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;
108615fc 40 fVertexConstraint = (Bool_t)true;
0a86fbb7 41 fParamSet[0]=0;
42 fParamSet[1]=0;
108615fc 43}
44
45
46AliL3ConfMapper::~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
63void 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
103void 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 151Bool_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 167void 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
244void 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
267void 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
288void 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
315void 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
336void 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
355void 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 366void 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 380void 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
389void 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
422void 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 574AliL3ConfMapPoint *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 715Int_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
762Double_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
773Bool_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 788Double_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
855Int_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
880Double_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}