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