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