]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/TPCLib/AliHLTTPCConfMapper.cxx
added cutoff parameter in z direction to ignore clusters of large z (Gaute)
[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),
887a0bd9 78 fClustersUnused(0),
79 fClusterCutZ(-1)
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
887a0bd9 177 if(fClusterCutZ == -1){
178 if (fHit.size()<fClustersUnused+count) fHit.resize(fClustersUnused+count);
179 assert(fHit.size()>=fClustersUnused+count);
180 for (Int_t i=0;(UInt_t)i<count;i++)
181 {
182 fHit[i+fClustersUnused].Reset();
183 fHit[i+fClustersUnused].Read(hits[i]);
184 }
185 fClustersUnused += count;
186 }
187 else{
188 //Skipping clusters with high Z.
189 UInt_t skipped=0;
190
191 if (fHit.size()<fClustersUnused+count) fHit.resize(fClustersUnused+count);
192 assert(fHit.size()>=fClustersUnused+count);
193 for (Int_t i=0;(UInt_t)i<count;i++)
194 {
195 if(hits[i].fZ > fClusterCutZ || hits[i].fZ < -1*fClusterCutZ){
196 ++skipped;
197 continue;
198 }
199 fHit[i+fClustersUnused-skipped].Reset();
200 fHit[i+fClustersUnused-skipped].Read(hits[i]);
201 }
202 fClustersUnused += count - skipped;
203 fHit.resize(fClustersUnused);
204 }
738c049f 205
fc455fba 206 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapper::ReadHits","#hits")
055fed30 207 <<AliHLTTPCLog::kDec<<"#hits: "<<count<<" total: "<<fClustersUnused<<ENDLOG;
a6c02c85 208
209 return true;
210}
211
212void AliHLTTPCConfMapper::SetPointers()
213{
214 //Check if there are not enough clusters to make a track in this sector
215 //Can happen in pp events.
216
217 if(fClustersUnused < fMinPoints[fVertexConstraint])
218 return;
219
055fed30 220 //Allocate detector volumes
221 if (fVolume==NULL) {
222 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapper::InitVolumes","Memory")<<AliHLTTPCLog::kDec<<
223 "Allocating "<<fBounds*sizeof(AliHLTTPCConfMapContainer)<<" Bytes to fVolume"<<ENDLOG;
224 fVolume = new AliHLTTPCConfMapContainer[fBounds];
225 }
226
227 if (fRow==NULL) {
228 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapper::InitVolumes","Memory")<<AliHLTTPCLog::kDec<<
229 "Allocating "<<fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer)<<" Bytes to fRow"<<ENDLOG;
230 fRow = new AliHLTTPCConfMapContainer[fNumRowSegmentPlusOne];
231 }
232
a6c02c85 233 memset(fVolume,0,fBounds*sizeof(AliHLTTPCConfMapContainer));
234 memset(fRow,0,fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer));
235
236 Float_t phiSlice = (fPhiMax-fPhiMin)/fNumPhiSegment;
237 Float_t etaSlice = (fEtaMax-fEtaMin)/fNumEtaSegment;
238
239 Int_t volumeIndex;
240 Int_t localcounter=0;
13398559 241 assert((int)fHit.size()>=fClustersUnused);
a6c02c85 242 for(Int_t j=0; j<fClustersUnused; j++)
243 {
a6c02c85 244 AliHLTTPCConfMapPoint *thisHit = &(fHit[j]);
245
246 thisHit->Setup(fVertex);
247
248 Int_t localrow = thisHit->GetPadRow();
249
250 if(localrow < fRowMin || localrow > fRowMax)
251 continue;
252
253 //Get indexes:
254 thisHit->SetPhiIndex((Int_t)((thisHit->GetPhi()-fPhiMin)/phiSlice +1));
255
256 if(thisHit->GetPhiIndex()<1 || thisHit->GetPhiIndex()>fNumPhiSegment)
257 {
258 //cout << "Phiindex: " << thisHit->phiIndex << " " << thisHit->GetPhi() << endl;
259 fPhiHitsOutOfRange++;
260 continue;
261 }
262
263 thisHit->SetEtaIndex((Int_t)((thisHit->GetEta()-fEtaMin)/etaSlice + 1));
264 if(thisHit->GetEtaIndex()<1 || thisHit->GetEtaIndex()>fNumEtaSegment)
265 {
266 //cout << "Etaindex: " << thisHit->etaIndex << " " << thisHit->GetEta() << endl;
267 fEtaHitsOutOfRange++;
268 continue;
269 }
270 localcounter++;
271
272 volumeIndex = (localrow-fRowMin)*fNumPhiEtaSegmentPlusOne +
273 thisHit->GetPhiIndex()*fNumEtaSegmentPlusOne+thisHit->GetEtaIndex();
274
275 if(fVolume[volumeIndex].first == NULL)
276 fVolume[volumeIndex].first = (void *)thisHit;
277 else
278 ((AliHLTTPCConfMapPoint *)fVolume[volumeIndex].last)->SetNextVolumeHit(thisHit);
279 fVolume[volumeIndex].last = (void *)thisHit;
280
281
282 //set row pointers
283 if(fRow[(localrow-fRowMin)].first == NULL)
284 fRow[(localrow-fRowMin)].first = (void *)thisHit;
285 else
286 ((AliHLTTPCConfMapPoint *)(fRow[(localrow-fRowMin)].last))->SetNextRowHit(thisHit);
287 fRow[(localrow-fRowMin)].last = (void *)thisHit;
288 }
289
0ba35c53 290 // Matthias 2008-03-25
291 // I'm not really sure if this is en error condition. Has to be investigated.
292 // With the ifdef below, the message is only printed if the library was build
293 // in the HLT build system. By that we avoid irritating messages for the
294 // reconstruction included into the Grid tests
295#ifdef PACKAGE_STRING
a6c02c85 296 if(fClustersUnused>0 && localcounter==0)
297 LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::SetPointers","Parameters")
298 <<AliHLTTPCLog::kDec<<"No points passed to track finder, hits out of range: "
299 <<fEtaHitsOutOfRange+fPhiHitsOutOfRange<<ENDLOG;
300
301 Int_t hits_accepted=fClustersUnused-(fEtaHitsOutOfRange+fPhiHitsOutOfRange);
055fed30 302 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapper::SetPointers","Setup")
a6c02c85 303 <<"Setup finished, hits out of range: "<<fEtaHitsOutOfRange+fPhiHitsOutOfRange
304 <<" hits accepted "<<hits_accepted<<ENDLOG;
0ba35c53 305#endif //PACKAGE_STRING
a6c02c85 306}
307
2a083ac4 308void AliHLTTPCConfMapper::MainVertexTrackingA()
a6c02c85 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();
321
322 SetPointers();
323 SetVertexConstraint(true);
324 cpuTime = CpuTime() - initCpuTime;
325 if(fBench)
055fed30 326 LOG(AliHLTTPCLog::kBenchmark,"AliHLTTPCConfMapper::MainVertexTrackingA","Timing")
a6c02c85 327 <<AliHLTTPCLog::kDec<<"Setup finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
328
329}
330
2a083ac4 331void AliHLTTPCConfMapper::MainVertexTrackingB()
a6c02c85 332{
333 //Tracking with vertex constraint.
334
335 if(!fParamSet[(Int_t)kTRUE])
336 {
337 LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
338 "Tracking parameters not set!"<<ENDLOG;
339 return;
340 }
341 Double_t initCpuTime,cpuTime;
342 initCpuTime = CpuTime();
343
344 ClusterLoop();
345
346 cpuTime = CpuTime() - initCpuTime;
347 if(fBench)
055fed30 348 LOG(AliHLTTPCLog::kBenchmark,"AliHLTTPCConfMapper::MainVertexTrackingB","Timing")
a6c02c85 349 <<AliHLTTPCLog::kDec<<"Main Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
350}
351
352void AliHLTTPCConfMapper::MainVertexTracking()
353{
354 //Tracking with vertex constraint.
355
356 if(!fParamSet[(Int_t)kTRUE])
357 {
358 LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
359 "Tracking parameters not set!"<<ENDLOG;
360 return;
361 }
362
363 Double_t initCpuTime,cpuTime;
364 initCpuTime = CpuTime();
437e8e54 365
366 SetPointers();
367
a6c02c85 368 SetVertexConstraint(true);
369
370 ClusterLoop();
371
372 cpuTime = CpuTime() - initCpuTime;
373 if(fBench)
055fed30 374 LOG(AliHLTTPCLog::kBenchmark,"AliHLTTPCConfMapper::MainVertexTracking","Timing")<<AliHLTTPCLog::kDec<<
a6c02c85 375 "Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
376
377 return;
378}
379
380void AliHLTTPCConfMapper::NonVertexTracking()
381{
382 //Tracking with no vertex constraint. This should be called after doing MainVertexTracking,
383 //in order to do tracking on the remaining clusters.
384 //The conformal mapping is now done with respect to the first cluster
385 //assosciated with this track.
386
387 if(!fParamSet[(Int_t)kFALSE])
388 {
389 LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::NonVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
390 "Tracking parameters not set!"<<ENDLOG;
391 return;
392 }
393
394 SetVertexConstraint(false);
437e8e54 395
396 SetPointers(); //To be able to do only nonvertextracking (more testing)
397
a6c02c85 398 ClusterLoop();
399 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::NonVertexTracking","ntracks")<<AliHLTTPCLog::kDec<<
400 "Number of nonvertex tracks found: "<<(fNTracks-fMainVertexTracks)<<ENDLOG;
401 return;
402}
403
404void AliHLTTPCConfMapper::MainVertexSettings(Int_t trackletlength, Int_t tracklength,
405 Int_t rowscopetracklet, Int_t rowscopetrack,
406 Double_t maxphi,Double_t maxeta)
407{
408 //Settings for main vertex tracking. The cuts are:
409 //TrackletLength: #hits on segment, before trying to build a track
410 //TrackLength: Minimum hits on a track
411 //RowScopeTracklet: Row search range for segments
412 //RowScopeTrack: Row search range for tracks
413
414 SetTrackletLength(trackletlength,(Bool_t)true);
415 SetRowScopeTracklet(rowscopetracklet, (Bool_t) true);
416 SetRowScopeTrack(rowscopetrack, (Bool_t) true);
417 SetMinPoints(tracklength,(Bool_t)true);
418 fMaxPhi=maxphi;
419 fMaxEta=maxeta;
420 SetParamDone(kTRUE);
421}
422
423void AliHLTTPCConfMapper::NonVertexSettings(Int_t trackletlength, Int_t tracklength,
424 Int_t rowscopetracklet, Int_t rowscopetrack)
425{
426 //set parameters for non-vertex tracking
427 SetTrackletLength(trackletlength,(Bool_t)false);
428 SetRowScopeTracklet(rowscopetracklet, (Bool_t)false);
429 SetRowScopeTrack(rowscopetrack, (Bool_t)false);
430 SetMinPoints(tracklength,(Bool_t)false);
431 SetParamDone(kFALSE);
432}
433
434void AliHLTTPCConfMapper::SetTrackCuts(Double_t hitChi2Cut, Double_t goodHitChi2, Double_t trackChi2Cut,Int_t maxdist,Bool_t vertexconstraint)
435{
436 //Settings for tracks. The cuts are:
437 //HitChi2Cut: Maximum hit chi2
438 //goodHitChi2: Chi2 to stop look for next hit
439 //trackChi2Cut: Maximum track chi2
440 //maxdist: Maximum distance between two clusters when forming segments
441
442 SetHitChi2Cut(hitChi2Cut,vertexconstraint);
443 SetGoodHitChi2(goodHitChi2,vertexconstraint);
444 SetTrackChi2Cut(trackChi2Cut,vertexconstraint);
445 SetMaxDist(maxdist,vertexconstraint);
446}
447
448void AliHLTTPCConfMapper::SetTrackletCuts(Double_t maxangle,Double_t goodDist, Bool_t vc)
449{
450 //Sets cuts of tracklets. Right now this is only:
451 //maxangle: Maximum angle when forming segments (if trackletlength > 2)
452
453 fGoodDist=goodDist;
454 SetMaxAngleTracklet(maxangle, vc);
455}
456
457void AliHLTTPCConfMapper::ClusterLoop()
458{
459 //Loop over hits, starting at outermost padrow, and trying to build segments.
460
461 //Check if there are not enough clusters to make a track in this sector
462 //Can happen in pp events.
463 if(fClustersUnused < fMinPoints[fVertexConstraint])
464 return;
465
466 Int_t rowsegm,lastrow = fRowMin + fMinPoints[fVertexConstraint];
467 AliHLTTPCConfMapPoint *hit;
468
469 //Loop over rows, and try to create tracks from the hits.
470 //Starts at the outermost row, and loops as long as a track can be build, due to length.
471
472 for(rowsegm = fRowMax; rowsegm >= lastrow; rowsegm--)
473 {
474 if(fRow[(rowsegm-fRowMin)].first && ((AliHLTTPCConfMapPoint*)fRow[(rowsegm-fRowMin)].first)->GetPadRow() < fRowMin + 1)
475 break;
476
477 for(hit = (AliHLTTPCConfMapPoint*)fRow[(rowsegm-fRowMin)].first; hit!=0; hit=hit->GetNextRowHit())
478 {
479 if(hit->GetUsage() == true)
480 continue;
481 else
482 CreateTrack(hit);
483 }
484 }
485
486 return;
487}
488
489
490void AliHLTTPCConfMapper::CreateTrack(AliHLTTPCConfMapPoint *hit)
491{
492 //Tries to create a track from the initial hit given by ClusterLoop()
493
494 AliHLTTPCConfMapPoint *closesthit = NULL;
495 AliHLTTPCConfMapTrack *track = NULL;
496
497 Int_t point;
498 Int_t tracks = fNTracks;
499 fNTracks++;
500
501 track = (AliHLTTPCConfMapTrack*)fTrack->NextTrack();
502
503 //reset hit parameters:
504 track->Reset();
505
506 UInt_t *trackhitnumber = track->GetHitNumbers();
507
508 //set conformal coordinates if we are looking for non vertex tracks
509 if(!fVertexConstraint)
510 {
511 hit->SetAllCoord(hit);
512 }
513
514 //fill fit parameters of initial track:
515 track->UpdateParam(hit); //here the number of hits is incremented.
516 trackhitnumber[track->GetNumberOfPoints()-1] = hit->GetHitNumber();
517
518 Double_t dx,dy;
519 //create tracklets:
520
521 for(point=1; point<fTrackletLength[fVertexConstraint]; point++)
522 {
523 if((closesthit = GetNextNeighbor(hit)))
524 {//closest hit exist
525
526 // Calculate track length in sz plane
527 dx = ((AliHLTTPCConfMapPoint*)closesthit)->GetX() - ((AliHLTTPCConfMapPoint*)hit)->GetX();
528 dy = ((AliHLTTPCConfMapPoint*)closesthit)->GetY() - ((AliHLTTPCConfMapPoint*)hit)->GetY();
529 //track->fLength += (Double_t)sqrt ( dx * dx + dy * dy ) ;
530 Double_t length = track->GetLength()+(Double_t)sqrt ( dx * dx + dy * dy );
531 track->SetLength(length);
532
533 //closesthit->SetS(track->fLength);
534 closesthit->SetS(track->GetLength());
535
536 //update fit parameters
537 track->UpdateParam(closesthit);
538 trackhitnumber[track->GetNumberOfPoints()-1] = closesthit->GetHitNumber();
539
540 hit = closesthit;
541 }
542 else
543 {
544 //closest hit does not exist:
545 track->DeleteCandidate();
546 fTrack->RemoveLast();
547 fNTracks--;
548 point = fTrackletLength[fVertexConstraint];
549 }
550 }
551
552 //tracklet is long enough to be extended to a track
553 if(track->GetNumberOfPoints() == fTrackletLength[fVertexConstraint])
554 {
555
556 track->SetProperties(true);
557
558 if(TrackletAngle(track) > fMaxAngleTracklet[fVertexConstraint])
559 {//proof if the first points seem to be a beginning of a track
560 track->SetProperties(false);
561 track->DeleteCandidate();
562 fTrack->RemoveLast();
563 fNTracks--;
564 }
565
566 else//good tracklet ->proceed, follow the trackfit
567 {
568 tracks++;
569
570 //define variables to keep the total chi:
571 Double_t xyChi2 = track->GetChiSq1();
572 Double_t szChi2 = track->GetChiSq2();
573
574 for(point = fTrackletLength[fVertexConstraint]; point <= fNumRowSegment; point++)
575 {
576 track->SetChiSq1(fHitChi2Cut[fVertexConstraint]);
577 closesthit = GetNextNeighbor((AliHLTTPCConfMapPoint*)track->GetLastHit(),track);
578
579 if(closesthit)
580 {
581 //keep total chi:
582 Double_t lxyChi2 = track->GetChiSq1()-track->GetChiSq2();
583 xyChi2 += lxyChi2;
584 closesthit->SetXYChi2(lxyChi2);
585
586 //update track length:
587 track->SetLength(closesthit->GetS());
588 szChi2 += track->GetChiSq2();
589 closesthit->SetSZChi2(track->GetChiSq2());
590
591 track->UpdateParam(closesthit);
592 trackhitnumber[track->GetNumberOfPoints()-1] = closesthit->GetHitNumber();
593
594 //add closest hit to track
595 closesthit->SetUsage(true);
596 closesthit->SetTrackNumber(tracks-1);
597
598 }//closesthit
599
600 else
601 {
602 //closest hit does not exist
603 point = fNumRowSegment; //continue with next hit in segment
604 }//else
605
606 }//create tracks
607
608 //store track chi2:
609 track->SetChiSq1(xyChi2);
610 track->SetChiSq2(szChi2);
611 Double_t normalizedchi2 = (track->GetChiSq1()+track->GetChiSq2())/track->GetNumberOfPoints();
612
613 //remove tracks with not enough points already now
614 if(track->GetNumberOfPoints() < fMinPoints[fVertexConstraint] || normalizedchi2 > fTrackChi2Cut[fVertexConstraint])
615 {
616 track->SetProperties(false);
617 fNTracks--;
618 track->DeleteCandidate();
619 fTrack->RemoveLast();
620 tracks--;
621 }
622
623 else
624 {
625 fClustersUnused -= track->GetNumberOfPoints();
626 track->ComesFromMainVertex(fVertexConstraint);
627 //mark track as main vertex track or not
628 track->SetSector(2); //only needed for testing purposes.
629 track->SetRowRange(fRowMin,fRowMax);
630
631 if(fVertexConstraint)
632 fMainVertexTracks++;
633 }
634
635 }//good tracklet
636
637 }
638
639 return;
640}
641
642AliHLTTPCConfMapPoint *AliHLTTPCConfMapper::GetNextNeighbor(AliHLTTPCConfMapPoint *starthit,
643 AliHLTTPCConfMapTrack *track)
644{
645 //When forming segments: Finds closest hit to input hit
646 //When forming tracks: Find closest hit to track fit.
647
648 Double_t dist,closestdist = fMaxDist[fVertexConstraint];
649
650 AliHLTTPCConfMapPoint *hit = NULL;
651 AliHLTTPCConfMapPoint *closesthit = NULL;
652
653 Int_t subrowsegm;
654 Int_t subphisegm;
655 Int_t subetasegm;
656 Int_t volumeIndex;
657 Int_t testhit;
658
659 Int_t maxrow = starthit->GetPadRow()-1;
660 Int_t minrow;
661
662 if(track) //finding hit close to trackfit
663 {
664 minrow = starthit->GetPadRow()-fRowScopeTrack[fVertexConstraint];
665 }
666 else
667 {
668 minrow = starthit->GetPadRow()-fRowScopeTracklet[fVertexConstraint];
669 }
670
671 //make a smart loop
672 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};
673 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};
674
675 if(minrow < fRowMin)
676 minrow = fRowMin;
677 if(maxrow < fRowMin)
678 return 0; //reached the last padrow under consideration
679
680 else
681 {
682 //loop over sub rows
683 for(subrowsegm=maxrow; subrowsegm>=minrow; subrowsegm--)
684 {
685 //loop over subsegments, in the order defined above.
686 for(Int_t i=0; i<9; i++)
687 {
688 subphisegm = starthit->GetPhiIndex() + loopphi[i];
689
690 if(subphisegm < 0 || subphisegm >= fNumPhiSegment)
691 continue;
692 /*
693 if(subphisegm<0)
694 subphisegm += fNumPhiSegment;
695
696 else if(subphisegm >=fNumPhiSegment)
697 subphisegm -= fNumPhiSegment;
698 */
699 //loop over sub eta segments
700
701 subetasegm = starthit->GetEtaIndex() + loopeta[i];
702
703 if(subetasegm < 0 || subetasegm >=fNumEtaSegment)
704 continue;//segment exceeds bounds->skip it
705
706 //loop over hits in this sub segment:
707 volumeIndex=(subrowsegm-fRowMin)*fNumPhiEtaSegmentPlusOne +
708 subphisegm*fNumEtaSegmentPlusOne + subetasegm;
709
710 if(volumeIndex<0)
711 {//debugging
712 LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::GetNextNeighbor","Memory")<<AliHLTTPCLog::kDec<<
713 "VolumeIndex error "<<volumeIndex<<ENDLOG;
714 }
715
055fed30 716 assert(fVolume!=NULL);
a6c02c85 717 for(hit = (AliHLTTPCConfMapPoint*)fVolume[volumeIndex].first;
718 hit!=0; hit = hit->GetNextVolumeHit())
719 {
720
721 if(!hit->GetUsage())
722 {//hit was not used before
723
724 //set conformal mapping if looking for nonvertex tracks:
725 if(!fVertexConstraint)
726 {
727 hit->SetAllCoord(starthit);
728 }
729
730 if(track)//track search - look for nearest neighbor to extrapolated track
731 {
437e8e54 732 if (fVertexConstraint) {
733 if(!VerifyRange(starthit,hit))
734 continue;
735 }
a6c02c85 736 testhit = EvaluateHit(starthit,hit,track);
737
738 if(testhit == 0)//chi2 not good enough, keep looking
739 continue;
740 else if(testhit==2)//chi2 good enough, return it
741 return hit;
742 else
743 closesthit = hit;//chi2 acceptable, but keep looking
744
745 }//track search
746
747 else //tracklet search, look for nearest neighbor
748 {
749
750 if((dist=CalcDistance(starthit,hit)) < closestdist)
751 {
437e8e54 752 if (fVertexConstraint) {
738c049f 753 if(!VerifyRange(starthit,hit))
437e8e54 754 continue;
755 }
a6c02c85 756 closestdist = dist;
757 closesthit = hit;
758
759 //if this hit is good enough, return it:
760 if(closestdist < fGoodDist)
761 return closesthit;
762 }
763 else
764 continue;//sub hit was farther away than a hit before
765
766 }//tracklet search
767
768 }//hit not used before
769
770 else continue; //sub hit was used before
771
772 }//loop over hits in sub segment
773
774 }//loop over sub segments
775
776 }//loop over subrows
777
778 }//else
779
780 //closest hit found:
781 if(closesthit)// && closestdist < mMaxDist)
782 return closesthit;
783 else
784 return 0;
785}
786
787Int_t AliHLTTPCConfMapper::EvaluateHit(AliHLTTPCConfMapPoint *starthit,AliHLTTPCConfMapPoint *hit,AliHLTTPCConfMapTrack *track)
788{
789 //Check if space point gives a fit with acceptable chi2.
790
791 Double_t temp,dxy,lchi2,dx,dy,slocal,dsz,lszChi2;
792 temp = (track->GetA2Xy()*hit->GetXprime()-hit->GetYprime()+track->GetA1Xy());
793 dxy = temp*temp/(track->GetA2Xy()*track->GetA2Xy() + 1.);
794
795 //Calculate chi2
796 lchi2 = (dxy*hit->GetXYWeight());
797
798 if(lchi2 > track->GetChiSq1())//chi2 was worse than before.
799 return 0;
800
801 //calculate s and the distance hit-line
802 dx = starthit->GetX()-hit->GetX();
803 dy = starthit->GetY()-hit->GetY();
804 //slocal = track->fLength+sqrt(dx*dx+dy*dy);
805 slocal = track->GetLength()+sqrt(dx*dx+dy*dy);
806
807 temp = (track->GetA2Sz()*slocal-hit->GetZ()+track->GetA1Sz());
808 dsz = temp*temp/(track->GetA2Sz()*track->GetA2Sz()+1);
809
810 //calculate chi2
811 lszChi2 = dsz*hit->GetZWeight();
812 lchi2 += lszChi2;
813
814
815 //check whether chi2 is better than previous one:
816 if(lchi2 < track->GetChiSq1())
817 {
818 track->SetChiSq1(lchi2);
819 track->SetChiSq2(lszChi2);
820
821 hit->SetS(slocal);
822
823 //if chi2 good enough, stop here:
824 if(lchi2 < fGoodHitChi2[fVertexConstraint])
825 return 2;
826
827 return 1;
828 }
829
830 return 0;
831
832}
833
834Double_t AliHLTTPCConfMapper::CalcDistance(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const
835{
836 //Return distance between two clusters, defined by Pablo
837
838 Double_t phidiff = fabs( hit1->GetPhi() - hit2->GetPhi() );
839 if (phidiff > AliHLTTPCTransform::Pi()) phidiff = AliHLTTPCTransform::TwoPi() - phidiff;
840
841 return AliHLTTPCTransform::ToDeg()*fabs((Float_t)((hit1->GetPadRow() - hit2->GetPadRow()) *
842 (phidiff + fabs( hit1->GetEta() - hit2->GetEta()))));
843}
844
845Bool_t AliHLTTPCConfMapper::VerifyRange(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const
846{
847 //Check if the hit are within reasonable range in phi and eta
848 Double_t dphi,deta;//maxphi=0.1,maxeta=0.1;
849 dphi = fabs(hit1->GetPhi() - hit2->GetPhi());
850 if(dphi > AliHLTTPCTransform::Pi()) dphi = fabs(AliHLTTPCTransform::TwoPi() - dphi);
851 if(dphi > fMaxPhi) return false;
852
853 deta = fabs(hit1->GetEta() - hit2->GetEta());
854 if(deta > fMaxEta) return false;
855
856 return true;
857
858}
859
860Double_t AliHLTTPCConfMapper::TrackletAngle(AliHLTTPCConfMapTrack *track,Int_t n) const
861{
862 // Returns the angle 'between' the last three points (started at point number n) on this track.
863
864 if(n > track->GetNumberOfPoints())
865 n = track->GetNumberOfPoints();
866
867 if(n<3)
868 return 0;
869
d6e2c707 870 Double_t x1[2]={0,0};
871 Double_t x2[2]={0,0};
872 Double_t x3[2]={0,0};
a6c02c85 873 Double_t angle1,angle2;
874 Int_t counter=0;
875 for(track->StartLoop(); track->LoopDone(); track->GetNextHit())
876 {
877 AliHLTTPCConfMapPoint *p = (AliHLTTPCConfMapPoint*)track->GetCurrentHit();
878 if( (n-1) == counter)
879 {
880 x1[0] = p->GetX();
881 x1[1] = p->GetY();
882 }
883 else if( (n-2) == counter)
884 {
885 x2[0] = p->GetX();
886 x2[1] = p->GetY();
887 }
888 else if( (n-3) == counter)
889 {
890 x3[0] = p->GetX();
891 x3[1] = p->GetY();
892 }
893 counter++;
894 }
895
896 angle1 = atan2(x2[1]-x3[1],x2[0]-x3[0]);
897 angle2 = atan2(x1[1]-x2[1],x1[0]-x2[0]);
898
899 return fabs(angle1-angle2);
900
901 /*
902 Double_t x1[2];
903 Double_t x2[2];
904 Double_t angle1,angle2;
905 TObjArray *hits = track->GetHits();
906
907 if (n > track->GetNumberOfPoints()) {
908 n = track->GetNumberOfPoints();
909 }
910
911 if (n<3)
912 return 0;
913
914
915 x1[0] = ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetX() - ((AliHLTTPCConfMapPoint *)hits->At(n-3))->GetX();
916 x1[1] = ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetY() - ((AliHLTTPCConfMapPoint *)hits->At(n-3))->GetY();
917
918 x2[0] = ((AliHLTTPCConfMapPoint *)hits->At(n-1))->GetX() - ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetX();
919 x2[1] = ((AliHLTTPCConfMapPoint *)hits->At(n-1))->GetY() - ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetY();
920
921 angle1 = atan2(x1[1],x1[0]);
922 angle2 = atan2(x2[1],x1[0]);
923 return fabs(angle1-angle2);
924 */
925}
926
927Int_t AliHLTTPCConfMapper::FillTracks()
928{
929 //Fill track parameters. Which basically means do a fit of helix in real space,
930 //which should be done in order to get nice tracks.
931
932 Int_t numoftracks = fNTracks;
933 if(fNTracks == 0)
934 {
cb703d46 935 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapper::FillTracks","fNTracks")<<AliHLTTPCLog::kDec<<
a6c02c85 936 "No tracks found!!"<<ENDLOG;
937 return 0;
938 }
939
055fed30 940 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::FillTracks","fNTracks")<<AliHLTTPCLog::kDec<<
a6c02c85 941 "Number of found tracks: "<<fNTracks<<ENDLOG;
942
943 // fTrack->Sort();
944 for(Int_t i=0; i<numoftracks; i++)
945 {
946 AliHLTTPCConfMapTrack *track = (AliHLTTPCConfMapTrack*)fTrack->GetTrack(i);
947 track->Fill(fVertex,fMaxDca);
948 }
949 return 1;
950}
951
952Double_t AliHLTTPCConfMapper::CpuTime()
953{
954 //Return the Cputime in seconds.
955 struct timeval tv;
956 gettimeofday( &tv, NULL );
957 return tv.tv_sec+(((Double_t)tv.tv_usec)/1000000.);
958}