2 // Original: AliHLTConfMapper.cxx,v 1.26 2005/06/14 10:55:21 cvetan Exp $
4 //**************************************************************************
5 //* This file is property of and copyright by the ALICE HLT Project *
6 //* ALICE Experiment at CERN, All rights reserved. *
8 //* Primary Authors: Anders Vestbo, maintained by
9 //* Matthias Richter <Matthias.Richter@ift.uib.no> *
10 //* for The ALICE HLT Project. *
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 //**************************************************************************
21 /** @file AliHLTTPCConfMapper.cxx
22 @author Anders Vestbo, Matthias Richter
23 @date Conformal mapping base class.
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"
44 ClassImp(AliHLTTPCConfMapper)
46 AliHLTTPCConfMapper::AliHLTTPCConfMapper()
51 fVertexFinder(kFALSE),
54 fMaxDca(0.0), // no clue whether this is reasonable, but at least better than without initialization
60 fNumRowSegmentPlusOne(0),
61 fNumPhiSegmentPlusOne(0),
62 fNumEtaSegmentPlusOne(0),
63 fNumPhiEtaSegmentPlusOne(0),
65 fPhiHitsOutOfRange(0),
66 fEtaHitsOutOfRange(0),
73 fVertexConstraint(kTRUE),
86 AliHLTTPCConfMapper::~AliHLTTPCConfMapper()
97 void AliHLTTPCConfMapper::InitVolumes()
100 //Allocate volumes, set conformal coordinates and pointers.
102 //Should be done after setting the track parameters
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;
112 fTrack = new AliHLTTPCTrackArray("AliHLTTPCConfMapTrack",10);
115 void AliHLTTPCConfMapper::Reset()
117 if(fVolume) delete [] fVolume;
119 if(fRow) delete [] fRow;
126 void 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...)
135 //Define tracking area:
138 fRowMin = rowrange[0];
139 fRowMax = rowrange[1];
141 else //complete sector
144 fRowMax = AliHLTTPCTransform::GetNRows() - 1;
148 fEtaMin = etarange[0];
149 fEtaMax = sector < 18 ? etarange[1] : -etarange[1];
154 fEtaMax = sector < 18 ? 0.9 : -0.9;
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;
162 fMainVertexTracks = 0;
164 fEtaHitsOutOfRange=0;
165 fPhiHitsOutOfRange=0;
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;
174 Bool_t AliHLTTPCConfMapper::ReadHits(UInt_t count, AliHLTTPCSpacePointData* hits )
176 //read hits with ReadHitsChecked
177 return ReadHitsChecked(count,hits,0);
180 Bool_t AliHLTTPCConfMapper::ReadHitsChecked(UInt_t count, AliHLTTPCSpacePointData* hits, unsigned int sizeInByte )
183 if(fClusterCutZ == -1){
184 if (fHit.size()<fClustersUnused+count) fHit.resize(fClustersUnused+count);
185 assert(fHit.size()>=fClustersUnused+count);
186 for (Int_t i=0;(UInt_t)i<count;i++)
188 AliHLTTPCSpacePointData *hit = &hits[i];
189 if (sizeInByte>0 && ((AliHLTUInt8_t*)hit)+sizeof(AliHLTTPCSpacePointData)>((AliHLTUInt8_t*)hits)+sizeInByte) {
190 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCConfMapper::ReadHits","")<<"Wrong size of data (" << sizeInByte << " byte), skipping array of AliHLTTPCSpacePointData" <<ENDLOG;;
193 fHit[i+fClustersUnused].Reset();
194 fHit[i+fClustersUnused].Read(hits[i]);
196 fClustersUnused += count;
199 //Skipping clusters with high Z.
202 if (fHit.size()<fClustersUnused+count) fHit.resize(fClustersUnused+count);
203 assert(fHit.size()>=fClustersUnused+count);
204 for (Int_t i=0;(UInt_t)i<count;i++)
206 AliHLTTPCSpacePointData *hit = &hits[i];
207 if (sizeInByte>0 && ((AliHLTUInt8_t*)hit)+sizeof(AliHLTTPCSpacePointData)>((AliHLTUInt8_t*)hits)+sizeInByte) {
208 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCConfMapper::ReadHits","")<<"Wrong size of data (" << sizeInByte << " byte), skipping array of AliHLTTPCSpacePointData" <<ENDLOG;;
211 if(hits[i].fZ > fClusterCutZ || hits[i].fZ < -1*fClusterCutZ){
215 fHit[i+fClustersUnused-skipped].Reset();
216 fHit[i+fClustersUnused-skipped].Read(hits[i]);
218 fClustersUnused += count - skipped;
219 fHit.resize(fClustersUnused);
222 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapper::ReadHits","#hits")
223 <<AliHLTTPCLog::kDec<<"#hits: "<<count<<" total: "<<fClustersUnused<<ENDLOG;
228 void AliHLTTPCConfMapper::SetPointers()
230 //Check if there are not enough clusters to make a track in this sector
231 //Can happen in pp events.
233 if(fClustersUnused < fMinPoints[fVertexConstraint])
236 //Allocate detector volumes
238 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapper::InitVolumes","Memory")<<AliHLTTPCLog::kDec<<
239 "Allocating "<<fBounds*sizeof(AliHLTTPCConfMapContainer)<<" Bytes to fVolume"<<ENDLOG;
240 fVolume = new AliHLTTPCConfMapContainer[fBounds];
244 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapper::InitVolumes","Memory")<<AliHLTTPCLog::kDec<<
245 "Allocating "<<fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer)<<" Bytes to fRow"<<ENDLOG;
246 fRow = new AliHLTTPCConfMapContainer[fNumRowSegmentPlusOne];
249 memset(fVolume,0,fBounds*sizeof(AliHLTTPCConfMapContainer));
250 memset(fRow,0,fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer));
252 Float_t phiSlice = (fPhiMax-fPhiMin)/fNumPhiSegment;
253 Float_t etaSlice = (fEtaMax-fEtaMin)/fNumEtaSegment;
256 Int_t localcounter=0;
257 assert((int)fHit.size()>=fClustersUnused);
258 for(Int_t j=0; j<fClustersUnused; j++)
260 AliHLTTPCConfMapPoint *thisHit = &(fHit[j]);
262 thisHit->Setup(fVertex);
264 Int_t localrow = thisHit->GetPadRow();
266 if(localrow < fRowMin || localrow > fRowMax)
270 thisHit->SetPhiIndex((Int_t)((thisHit->GetPhi()-fPhiMin)/phiSlice +1));
272 if(thisHit->GetPhiIndex()<1 || thisHit->GetPhiIndex()>fNumPhiSegment)
274 //cout << "Phiindex: " << thisHit->phiIndex << " " << thisHit->GetPhi() << endl;
275 fPhiHitsOutOfRange++;
279 thisHit->SetEtaIndex((Int_t)((thisHit->GetEta()-fEtaMin)/etaSlice + 1));
280 if(thisHit->GetEtaIndex()<1 || thisHit->GetEtaIndex()>fNumEtaSegment)
282 //cout << "Etaindex: " << thisHit->etaIndex << " " << thisHit->GetEta() << endl;
283 fEtaHitsOutOfRange++;
288 volumeIndex = (localrow-fRowMin)*fNumPhiEtaSegmentPlusOne +
289 thisHit->GetPhiIndex()*fNumEtaSegmentPlusOne+thisHit->GetEtaIndex();
291 if(fVolume[volumeIndex].first == NULL)
292 fVolume[volumeIndex].first = (void *)thisHit;
294 ((AliHLTTPCConfMapPoint *)fVolume[volumeIndex].last)->SetNextVolumeHit(thisHit);
295 fVolume[volumeIndex].last = (void *)thisHit;
299 if(fRow[(localrow-fRowMin)].first == NULL)
300 fRow[(localrow-fRowMin)].first = (void *)thisHit;
302 ((AliHLTTPCConfMapPoint *)(fRow[(localrow-fRowMin)].last))->SetNextRowHit(thisHit);
303 fRow[(localrow-fRowMin)].last = (void *)thisHit;
306 //If a cluster has an Eta outside the Eta or Phi range set in the Tracker, it will go in to
307 //the if here. This has been seen for high Eta clusters most likely from signal from the gating grid.
308 //These clusters are read in, but not used in the Tracking.
309 #ifdef PACKAGE_STRING
310 if(fClustersUnused>0 && localcounter==0)
311 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapper::SetPointers","Parameters")
312 <<AliHLTTPCLog::kDec<<"No points passed to track finder, hits out of range: "
313 <<fEtaHitsOutOfRange+fPhiHitsOutOfRange<<ENDLOG;
315 Int_t hits_accepted=fClustersUnused-(fEtaHitsOutOfRange+fPhiHitsOutOfRange);
316 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapper::SetPointers","Setup")
317 <<"Setup finished, hits out of range: "<<fEtaHitsOutOfRange+fPhiHitsOutOfRange
318 <<" hits accepted "<<hits_accepted<<ENDLOG;
319 #endif //PACKAGE_STRING
322 void AliHLTTPCConfMapper::MainVertexTrackingA()
324 //Tracking with vertex constraint.
326 if(!fParamSet[(Int_t)kTRUE])
328 LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
329 "Tracking parameters not set!"<<ENDLOG;
333 Double_t initCpuTime,cpuTime;
334 initCpuTime = CpuTime();
337 SetVertexConstraint(true);
338 cpuTime = CpuTime() - initCpuTime;
340 LOG(AliHLTTPCLog::kBenchmark,"AliHLTTPCConfMapper::MainVertexTrackingA","Timing")
341 <<AliHLTTPCLog::kDec<<"Setup finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
345 void AliHLTTPCConfMapper::MainVertexTrackingB()
347 //Tracking with vertex constraint.
349 if(!fParamSet[(Int_t)kTRUE])
351 LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
352 "Tracking parameters not set!"<<ENDLOG;
355 Double_t initCpuTime,cpuTime;
356 initCpuTime = CpuTime();
360 cpuTime = CpuTime() - initCpuTime;
362 LOG(AliHLTTPCLog::kBenchmark,"AliHLTTPCConfMapper::MainVertexTrackingB","Timing")
363 <<AliHLTTPCLog::kDec<<"Main Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
366 void AliHLTTPCConfMapper::MainVertexTracking()
368 //Tracking with vertex constraint.
370 if(!fParamSet[(Int_t)kTRUE])
372 LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
373 "Tracking parameters not set!"<<ENDLOG;
377 Double_t initCpuTime,cpuTime;
378 initCpuTime = CpuTime();
382 SetVertexConstraint(true);
386 cpuTime = CpuTime() - initCpuTime;
388 LOG(AliHLTTPCLog::kBenchmark,"AliHLTTPCConfMapper::MainVertexTracking","Timing")<<AliHLTTPCLog::kDec<<
389 "Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
394 void AliHLTTPCConfMapper::NonVertexTracking()
396 //Tracking with no vertex constraint. This should be called after doing MainVertexTracking,
397 //in order to do tracking on the remaining clusters.
398 //The conformal mapping is now done with respect to the first cluster
399 //assosciated with this track.
401 if(!fParamSet[(Int_t)kFALSE])
403 LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::NonVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
404 "Tracking parameters not set!"<<ENDLOG;
408 SetVertexConstraint(false);
410 SetPointers(); //To be able to do only nonvertextracking (more testing)
413 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::NonVertexTracking","ntracks")<<AliHLTTPCLog::kDec<<
414 "Number of nonvertex tracks found: "<<(fNTracks-fMainVertexTracks)<<ENDLOG;
418 void AliHLTTPCConfMapper::MainVertexSettings(Int_t trackletlength, Int_t tracklength,
419 Int_t rowscopetracklet, Int_t rowscopetrack,
420 Double_t maxphi,Double_t maxeta)
422 //Settings for main vertex tracking. The cuts are:
423 //TrackletLength: #hits on segment, before trying to build a track
424 //TrackLength: Minimum hits on a track
425 //RowScopeTracklet: Row search range for segments
426 //RowScopeTrack: Row search range for tracks
428 SetTrackletLength(trackletlength,(Bool_t)true);
429 SetRowScopeTracklet(rowscopetracklet, (Bool_t) true);
430 SetRowScopeTrack(rowscopetrack, (Bool_t) true);
431 SetMinPoints(tracklength,(Bool_t)true);
437 void AliHLTTPCConfMapper::NonVertexSettings(Int_t trackletlength, Int_t tracklength,
438 Int_t rowscopetracklet, Int_t rowscopetrack)
440 //set parameters for non-vertex tracking
441 SetTrackletLength(trackletlength,(Bool_t)false);
442 SetRowScopeTracklet(rowscopetracklet, (Bool_t)false);
443 SetRowScopeTrack(rowscopetrack, (Bool_t)false);
444 SetMinPoints(tracklength,(Bool_t)false);
445 SetParamDone(kFALSE);
448 void AliHLTTPCConfMapper::SetTrackCuts(Double_t hitChi2Cut, Double_t goodHitChi2, Double_t trackChi2Cut,Int_t maxdist,Bool_t vertexconstraint)
450 //Settings for tracks. The cuts are:
451 //HitChi2Cut: Maximum hit chi2
452 //goodHitChi2: Chi2 to stop look for next hit
453 //trackChi2Cut: Maximum track chi2
454 //maxdist: Maximum distance between two clusters when forming segments
456 SetHitChi2Cut(hitChi2Cut,vertexconstraint);
457 SetGoodHitChi2(goodHitChi2,vertexconstraint);
458 SetTrackChi2Cut(trackChi2Cut,vertexconstraint);
459 SetMaxDist(maxdist,vertexconstraint);
462 void AliHLTTPCConfMapper::SetTrackletCuts(Double_t maxangle,Double_t goodDist, Bool_t vc)
464 //Sets cuts of tracklets. Right now this is only:
465 //maxangle: Maximum angle when forming segments (if trackletlength > 2)
468 SetMaxAngleTracklet(maxangle, vc);
471 void AliHLTTPCConfMapper::ClusterLoop()
473 //Loop over hits, starting at outermost padrow, and trying to build segments.
475 //Check if there are not enough clusters to make a track in this sector
476 //Can happen in pp events.
477 if(fClustersUnused < fMinPoints[fVertexConstraint])
480 Int_t rowsegm,lastrow = fRowMin + fMinPoints[fVertexConstraint];
481 AliHLTTPCConfMapPoint *hit;
483 //Loop over rows, and try to create tracks from the hits.
484 //Starts at the outermost row, and loops as long as a track can be build, due to length.
486 for(rowsegm = fRowMax; rowsegm >= lastrow; rowsegm--)
488 if(fRow[(rowsegm-fRowMin)].first && ((AliHLTTPCConfMapPoint*)fRow[(rowsegm-fRowMin)].first)->GetPadRow() < fRowMin + 1)
491 for(hit = (AliHLTTPCConfMapPoint*)fRow[(rowsegm-fRowMin)].first; hit!=0; hit=hit->GetNextRowHit())
493 if(hit->GetUsage() == true)
504 void AliHLTTPCConfMapper::CreateTrack(AliHLTTPCConfMapPoint *hit)
506 //Tries to create a track from the initial hit given by ClusterLoop()
508 AliHLTTPCConfMapPoint *closesthit = NULL;
509 AliHLTTPCConfMapTrack *track = NULL;
512 Int_t tracks = fNTracks;
515 track = (AliHLTTPCConfMapTrack*)fTrack->NextTrack();
517 //reset hit parameters:
520 UInt_t *trackhitnumber = track->GetHitNumbers();
522 //set conformal coordinates if we are looking for non vertex tracks
523 if(!fVertexConstraint)
525 hit->SetAllCoord(hit);
528 //fill fit parameters of initial track:
529 track->UpdateParam(hit); //here the number of hits is incremented.
530 trackhitnumber[track->GetNumberOfPoints()-1] = hit->GetHitNumber();
535 for(point=1; point<fTrackletLength[fVertexConstraint]; point++)
537 if((closesthit = GetNextNeighbor(hit)))
540 // Calculate track length in sz plane
541 dx = ((AliHLTTPCConfMapPoint*)closesthit)->GetX() - ((AliHLTTPCConfMapPoint*)hit)->GetX();
542 dy = ((AliHLTTPCConfMapPoint*)closesthit)->GetY() - ((AliHLTTPCConfMapPoint*)hit)->GetY();
543 //track->fLength += (Double_t)sqrt ( dx * dx + dy * dy ) ;
544 Double_t length = track->GetLength()+(Double_t)sqrt ( dx * dx + dy * dy );
545 track->SetLength(length);
547 //closesthit->SetS(track->fLength);
548 closesthit->SetS(track->GetLength());
550 //update fit parameters
551 track->UpdateParam(closesthit);
552 trackhitnumber[track->GetNumberOfPoints()-1] = closesthit->GetHitNumber();
558 //closest hit does not exist:
559 track->DeleteCandidate();
560 fTrack->RemoveLast();
562 point = fTrackletLength[fVertexConstraint];
566 //tracklet is long enough to be extended to a track
567 if(track->GetNumberOfPoints() == fTrackletLength[fVertexConstraint])
570 track->SetProperties(true);
572 if(TrackletAngle(track) > fMaxAngleTracklet[fVertexConstraint])
573 {//proof if the first points seem to be a beginning of a track
574 track->SetProperties(false);
575 track->DeleteCandidate();
576 fTrack->RemoveLast();
580 else//good tracklet ->proceed, follow the trackfit
584 //define variables to keep the total chi:
585 Double_t xyChi2 = track->GetChiSq1();
586 Double_t szChi2 = track->GetChiSq2();
588 for(point = fTrackletLength[fVertexConstraint]; point <= fNumRowSegment; point++)
590 track->SetChiSq1(fHitChi2Cut[fVertexConstraint]);
591 closesthit = GetNextNeighbor((AliHLTTPCConfMapPoint*)track->GetLastHit(),track);
596 Double_t lxyChi2 = track->GetChiSq1()-track->GetChiSq2();
598 closesthit->SetXYChi2(lxyChi2);
600 //update track length:
601 track->SetLength(closesthit->GetS());
602 szChi2 += track->GetChiSq2();
603 closesthit->SetSZChi2(track->GetChiSq2());
605 track->UpdateParam(closesthit);
606 trackhitnumber[track->GetNumberOfPoints()-1] = closesthit->GetHitNumber();
608 //add closest hit to track
609 closesthit->SetUsage(true);
610 closesthit->SetTrackNumber(tracks-1);
616 //closest hit does not exist
617 point = fNumRowSegment; //continue with next hit in segment
623 track->SetChiSq1(xyChi2);
624 track->SetChiSq2(szChi2);
625 Double_t normalizedchi2 = (track->GetChiSq1()+track->GetChiSq2())/track->GetNumberOfPoints();
627 //remove tracks with not enough points already now
628 if(track->GetNumberOfPoints() < fMinPoints[fVertexConstraint] || normalizedchi2 > fTrackChi2Cut[fVertexConstraint])
630 track->SetProperties(false);
632 track->DeleteCandidate();
633 fTrack->RemoveLast();
639 fClustersUnused -= track->GetNumberOfPoints();
640 track->ComesFromMainVertex(fVertexConstraint);
641 //mark track as main vertex track or not
642 track->SetSector(2); //only needed for testing purposes.
643 track->SetRowRange(fRowMin,fRowMax);
645 if(fVertexConstraint)
656 AliHLTTPCConfMapPoint *AliHLTTPCConfMapper::GetNextNeighbor(AliHLTTPCConfMapPoint *starthit,
657 AliHLTTPCConfMapTrack *track)
659 //When forming segments: Finds closest hit to input hit
660 //When forming tracks: Find closest hit to track fit.
662 Double_t dist,closestdist = fMaxDist[fVertexConstraint];
664 AliHLTTPCConfMapPoint *hit = NULL;
665 AliHLTTPCConfMapPoint *closesthit = NULL;
673 Int_t maxrow = starthit->GetPadRow()-1;
676 if(track) //finding hit close to trackfit
678 minrow = starthit->GetPadRow()-fRowScopeTrack[fVertexConstraint];
682 minrow = starthit->GetPadRow()-fRowScopeTracklet[fVertexConstraint];
686 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};
687 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};
692 return 0; //reached the last padrow under consideration
697 for(subrowsegm=maxrow; subrowsegm>=minrow; subrowsegm--)
699 //loop over subsegments, in the order defined above.
700 for(Int_t i=0; i<9; i++)
702 subphisegm = starthit->GetPhiIndex() + loopphi[i];
704 if(subphisegm < 0 || subphisegm >= fNumPhiSegment)
708 subphisegm += fNumPhiSegment;
710 else if(subphisegm >=fNumPhiSegment)
711 subphisegm -= fNumPhiSegment;
713 //loop over sub eta segments
715 subetasegm = starthit->GetEtaIndex() + loopeta[i];
717 if(subetasegm < 0 || subetasegm >=fNumEtaSegment)
718 continue;//segment exceeds bounds->skip it
720 //loop over hits in this sub segment:
721 volumeIndex=(subrowsegm-fRowMin)*fNumPhiEtaSegmentPlusOne +
722 subphisegm*fNumEtaSegmentPlusOne + subetasegm;
726 LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::GetNextNeighbor","Memory")<<AliHLTTPCLog::kDec<<
727 "VolumeIndex error "<<volumeIndex<<ENDLOG;
730 assert(fVolume!=NULL);
731 for(hit = (AliHLTTPCConfMapPoint*)fVolume[volumeIndex].first;
732 hit!=0; hit = hit->GetNextVolumeHit())
736 {//hit was not used before
738 //set conformal mapping if looking for nonvertex tracks:
739 if(!fVertexConstraint)
741 hit->SetAllCoord(starthit);
744 if(track)//track search - look for nearest neighbor to extrapolated track
746 if (fVertexConstraint) {
747 if(!VerifyRange(starthit,hit))
750 testhit = EvaluateHit(starthit,hit,track);
752 if(testhit == 0)//chi2 not good enough, keep looking
754 else if(testhit==2)//chi2 good enough, return it
757 closesthit = hit;//chi2 acceptable, but keep looking
761 else //tracklet search, look for nearest neighbor
764 if((dist=CalcDistance(starthit,hit)) < closestdist)
766 if (fVertexConstraint) {
767 if(!VerifyRange(starthit,hit))
773 //if this hit is good enough, return it:
774 if(closestdist < fGoodDist)
778 continue;//sub hit was farther away than a hit before
782 }//hit not used before
784 else continue; //sub hit was used before
786 }//loop over hits in sub segment
788 }//loop over sub segments
795 if(closesthit)// && closestdist < mMaxDist)
801 Int_t AliHLTTPCConfMapper::EvaluateHit(AliHLTTPCConfMapPoint *starthit,AliHLTTPCConfMapPoint *hit,AliHLTTPCConfMapTrack *track)
803 //Check if space point gives a fit with acceptable chi2.
805 Double_t temp,dxy,lchi2,dx,dy,slocal,dsz,lszChi2;
806 temp = (track->GetA2Xy()*hit->GetXprime()-hit->GetYprime()+track->GetA1Xy());
807 dxy = temp*temp/(track->GetA2Xy()*track->GetA2Xy() + 1.);
810 lchi2 = (dxy*hit->GetXYWeight());
812 if(lchi2 > track->GetChiSq1())//chi2 was worse than before.
815 //calculate s and the distance hit-line
816 dx = starthit->GetX()-hit->GetX();
817 dy = starthit->GetY()-hit->GetY();
818 //slocal = track->fLength+sqrt(dx*dx+dy*dy);
819 slocal = track->GetLength()+sqrt(dx*dx+dy*dy);
821 temp = (track->GetA2Sz()*slocal-hit->GetZ()+track->GetA1Sz());
822 dsz = temp*temp/(track->GetA2Sz()*track->GetA2Sz()+1);
825 lszChi2 = dsz*hit->GetZWeight();
829 //check whether chi2 is better than previous one:
830 if(lchi2 < track->GetChiSq1())
832 track->SetChiSq1(lchi2);
833 track->SetChiSq2(lszChi2);
837 //if chi2 good enough, stop here:
838 if(lchi2 < fGoodHitChi2[fVertexConstraint])
848 Double_t AliHLTTPCConfMapper::CalcDistance(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const
850 //Return distance between two clusters, defined by Pablo
852 Double_t phidiff = fabs( hit1->GetPhi() - hit2->GetPhi() );
853 if (phidiff > AliHLTTPCTransform::Pi()) phidiff = AliHLTTPCTransform::TwoPi() - phidiff;
855 return AliHLTTPCTransform::ToDeg()*fabs((Float_t)((hit1->GetPadRow() - hit2->GetPadRow()) *
856 (phidiff + fabs( hit1->GetEta() - hit2->GetEta()))));
859 Bool_t AliHLTTPCConfMapper::VerifyRange(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const
861 //Check if the hit are within reasonable range in phi and eta
862 Double_t dphi,deta;//maxphi=0.1,maxeta=0.1;
863 dphi = fabs(hit1->GetPhi() - hit2->GetPhi());
864 if(dphi > AliHLTTPCTransform::Pi()) dphi = fabs(AliHLTTPCTransform::TwoPi() - dphi);
865 if(dphi > fMaxPhi) return false;
867 deta = fabs(hit1->GetEta() - hit2->GetEta());
868 if(deta > fMaxEta) return false;
874 Double_t AliHLTTPCConfMapper::TrackletAngle(AliHLTTPCConfMapTrack *track,Int_t n) const
876 // Returns the angle 'between' the last three points (started at point number n) on this track.
878 if(n > track->GetNumberOfPoints())
879 n = track->GetNumberOfPoints();
884 Double_t x1[2]={0,0};
885 Double_t x2[2]={0,0};
886 Double_t x3[2]={0,0};
887 Double_t angle1,angle2;
889 for(track->StartLoop(); track->LoopDone(); track->GetNextHit())
891 AliHLTTPCConfMapPoint *p = (AliHLTTPCConfMapPoint*)track->GetCurrentHit();
892 if( (n-1) == counter)
897 else if( (n-2) == counter)
902 else if( (n-3) == counter)
910 angle1 = atan2(x2[1]-x3[1],x2[0]-x3[0]);
911 angle2 = atan2(x1[1]-x2[1],x1[0]-x2[0]);
913 return fabs(angle1-angle2);
918 Double_t angle1,angle2;
919 TObjArray *hits = track->GetHits();
921 if (n > track->GetNumberOfPoints()) {
922 n = track->GetNumberOfPoints();
929 x1[0] = ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetX() - ((AliHLTTPCConfMapPoint *)hits->At(n-3))->GetX();
930 x1[1] = ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetY() - ((AliHLTTPCConfMapPoint *)hits->At(n-3))->GetY();
932 x2[0] = ((AliHLTTPCConfMapPoint *)hits->At(n-1))->GetX() - ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetX();
933 x2[1] = ((AliHLTTPCConfMapPoint *)hits->At(n-1))->GetY() - ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetY();
935 angle1 = atan2(x1[1],x1[0]);
936 angle2 = atan2(x2[1],x1[0]);
937 return fabs(angle1-angle2);
941 Int_t AliHLTTPCConfMapper::FillTracks()
943 //Fill track parameters. Which basically means do a fit of helix in real space,
944 //which should be done in order to get nice tracks.
946 Int_t numoftracks = fNTracks;
949 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapper::FillTracks","fNTracks")<<AliHLTTPCLog::kDec<<
950 "No tracks found!!"<<ENDLOG;
954 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::FillTracks","fNTracks")<<AliHLTTPCLog::kDec<<
955 "Number of found tracks: "<<fNTracks<<ENDLOG;
958 for(Int_t i=0; i<numoftracks; i++)
960 AliHLTTPCConfMapTrack *track = (AliHLTTPCConfMapTrack*)fTrack->GetTrack(i);
961 track->Fill(fVertex,fMaxDca);
966 Double_t AliHLTTPCConfMapper::CpuTime()
968 //Return the Cputime in seconds.
970 gettimeofday( &tv, NULL );
971 return tv.tv_sec+(((Double_t)tv.tv_usec)/1000000.);