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