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