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