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