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