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