1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 //-------------------------------------------------------
18 // Implementation of the TPC tracker
20 // Origin: Marian Ivanov Marian.Ivanov@cern.ch
22 // AliTPC parallel tracker
24 // The track fitting is based on Kalaman filtering approach
26 // The track finding steps:
27 // 1. Seeding - with and without vertex constraint
28 // - seeding with vertex constain done at first n^2 proble
29 // - seeding without vertex constraint n^3 problem
30 // 2. Tracking - follow prolongation road - find cluster - update kalman track
32 // The seeding and tracking is repeated several times, in different seeding region.
33 // This approach enables to find the track which cannot be seeded in some region of TPC
34 // This can happen because of low momenta (track do not reach outer radius), or track is currently in the ded region between sectors, or the track is for the moment overlapped with other track (seed quality is poor) ...
36 // With this approach we reach almost 100 % efficiency also for high occupancy events.
37 // (If the seeding efficiency in a region is about 90 % than with logical or of several
38 // regions we will reach 100% (in theory - supposing independence)
40 // Repeating several seeding - tracking procedures some of the tracks can be find
43 // The procedures to remove multi find tacks are impremented:
44 // RemoveUsed2 - fast procedure n problem -
45 // Algorithm - Sorting tracks according quality
46 // remove tracks with some shared fraction
47 // Sharing in respect to all tacks
48 // Signing clusters in gold region
49 // FindSplitted - slower algorithm n^2
50 // Sort the tracks according quality
51 // Loop over pair of tracks
52 // If overlap with other track bigger than threshold - remove track
54 // FindCurling - Finds the pair of tracks which are curling
55 // - About 10% of tracks can be find with this procedure
56 // The combinatorial background is too big to be used in High
57 // multiplicity environment
58 // - n^2 problem - Slow procedure - currently it is disabled because of
61 // The number of splitted tracks can be reduced disabling the sharing of the cluster.
62 // tpcRecoParam-> SetClusterSharing(kFALSE);
63 // IT IS HIGHLY non recomended to use it in high flux enviroonment
64 // Even using this switch some tracks can be found more than once
65 // (because of multiple seeding and low quality tracks which will not cross full chamber)
68 // The tracker itself can be debugged - the information about tracks can be stored in several // phases of the reconstruction
69 // To enable storage of the TPC tracks in the ESD friend track
70 // use AliTPCReconstructor::SetStreamLevel(n);
72 // The debug level - different procedure produce tree for numerical debugging
73 // To enable them set AliTPCReconstructor::SetStreamLevel(n); where nis bigger 1
77 // Adding systematic errors to the covariance:
79 // The systematic errors due to the misalignment and miscalibration are added to the covariance matrix
80 // of the tracks (not to the clusters as they are dependent):
81 // The parameters form AliTPCRecoParam are used AliTPCRecoParam::GetSystematicError
82 // The systematic errors are expressed there in RMS - position (cm), angle (rad), curvature (1/GeV)
83 // The default values are 0.
85 // The sytematic errors are added to the covariance matrix in following places:
87 // 1. During fisrt itteration - AliTPCtrackerMI::FillESD
88 // 2. Second iteration -
89 // 2.a ITS->TPC - AliTPCtrackerMI::ReadSeeds
90 // 2.b TPC->TRD - AliTPCtrackerMI::PropagateBack
91 // 3. Third iteration -
92 // 3.a TRD->TPC - AliTPCtrackerMI::ReadSeeds
93 // 3.b TPC->ITS - AliTPCtrackerMI::RefitInward
95 // There are several places in the code which can be numerically debuged
96 // This code is keeped in order to enable code development and to check the calibration implementtion
98 // 1. ErrParam stream - dump information about
100 // 2.a) cluster error estimate
101 // 3.a) cluster shape estimate
104 // Debug streamer levels:
106 //-------------------------------------------------------
111 #include "Riostream.h"
112 #include <TClonesArray.h>
114 #include <TObjArray.h>
116 #include <TGraphErrors.h>
118 #include "AliComplexCluster.h"
119 #include "AliESDEvent.h"
120 #include "AliESDtrack.h"
121 #include "AliESDVertex.h"
124 #include "AliHelix.h"
125 #include "AliRunLoader.h"
126 #include "AliTPCClustersRow.h"
127 #include "AliTPCParam.h"
128 #include "AliTPCReconstructor.h"
129 #include "AliTPCpolyTrack.h"
130 #include "AliTPCreco.h"
131 #include "AliTPCseed.h"
133 #include "AliTPCtrackerSector.h"
134 #include "AliTPCtrackerMI.h"
135 #include "TStopwatch.h"
136 #include "AliTPCReconstructor.h"
137 #include "AliAlignObj.h"
138 #include "AliTrackPointArray.h"
140 #include "AliTPCcalibDB.h"
141 #include "AliTPCcalibDButil.h"
142 #include "AliTPCTransform.h"
143 #include "AliTPCClusterParam.h"
144 #include "AliTPCdEdxInfo.h"
145 #include "AliDCSSensorArray.h"
146 #include "AliDCSSensor.h"
148 #include "AliCosmicTracker.h"
154 ClassImp(AliTPCtrackerMI)
158 class AliTPCFastMath {
161 static Double_t FastAsin(Double_t x);
163 static Double_t fgFastAsin[20000]; //lookup table for fast asin computation
166 Double_t AliTPCFastMath::fgFastAsin[20000];
167 AliTPCFastMath gAliTPCFastMath; // needed to fill the LUT
169 AliTPCFastMath::AliTPCFastMath(){
171 // initialized lookup table;
172 for (Int_t i=0;i<10000;i++){
173 fgFastAsin[2*i] = TMath::ASin(i/10000.);
174 fgFastAsin[2*i+1] = (TMath::ASin((i+1)/10000.)-fgFastAsin[2*i]);
178 Double_t AliTPCFastMath::FastAsin(Double_t x){
180 // return asin using lookup table
182 Int_t index = int(x*10000);
183 return fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1];
186 Int_t index = int(x*10000);
187 return -(fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1]);
189 //__________________________________________________________________
190 AliTPCtrackerMI::AliTPCtrackerMI()
218 // default constructor
220 for (Int_t irow=0; irow<200; irow++){
227 //_____________________________________________________________________
231 Int_t AliTPCtrackerMI::UpdateTrack(AliTPCseed * track, Int_t accept){
233 //update track information using current cluster - track->fCurrentCluster
236 AliTPCclusterMI* c =track->GetCurrentCluster();
237 if (accept > 0) //sign not accepted clusters
238 track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() | 0x8000);
239 else // unsign accpeted clusters
240 track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() & 0xffff7fff);
241 UInt_t i = track->GetCurrentClusterIndex1();
243 Int_t sec=(i&0xff000000)>>24;
244 //Int_t row = (i&0x00ff0000)>>16;
245 track->SetRow((i&0x00ff0000)>>16);
246 track->SetSector(sec);
247 // Int_t index = i&0xFFFF;
248 if (sec>=fkParam->GetNInnerSector()) track->SetRow(track->GetRow()+fkParam->GetNRowLow());
249 track->SetClusterIndex2(track->GetRow(), i);
250 //track->fFirstPoint = row;
251 //if ( track->fLastPoint<row) track->fLastPoint =row;
252 // if (track->fRow<0 || track->fRow>160) {
253 // printf("problem\n");
255 if (track->GetFirstPoint()>track->GetRow())
256 track->SetFirstPoint(track->GetRow());
257 if (track->GetLastPoint()<track->GetRow())
258 track->SetLastPoint(track->GetRow());
261 track->SetClusterPointer(track->GetRow(),c);
264 Double_t angle2 = track->GetSnp()*track->GetSnp();
266 //SET NEW Track Point
268 if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
270 angle2 = TMath::Sqrt(angle2/(1-angle2));
271 AliTPCTrackerPoint &point =*(track->GetTrackPoint(track->GetRow()));
273 point.SetSigmaY(c->GetSigmaY2()/track->GetCurrentSigmaY2());
274 point.SetSigmaZ(c->GetSigmaZ2()/track->GetCurrentSigmaZ2());
275 point.SetErrY(sqrt(track->GetErrorY2()));
276 point.SetErrZ(sqrt(track->GetErrorZ2()));
278 point.SetX(track->GetX());
279 point.SetY(track->GetY());
280 point.SetZ(track->GetZ());
281 point.SetAngleY(angle2);
282 point.SetAngleZ(track->GetTgl());
283 if (point.IsShared()){
284 track->SetErrorY2(track->GetErrorY2()*4);
285 track->SetErrorZ2(track->GetErrorZ2()*4);
289 Double_t chi2 = track->GetPredictedChi2(track->GetCurrentCluster());
291 // track->SetErrorY2(track->GetErrorY2()*1.3);
292 // track->SetErrorY2(track->GetErrorY2()+0.01);
293 // track->SetErrorZ2(track->GetErrorZ2()*1.3);
294 // track->SetErrorZ2(track->GetErrorZ2()+0.005);
296 if (accept>0) return 0;
297 if (track->GetNumberOfClusters()%20==0){
298 // if (track->fHelixIn){
299 // TClonesArray & larr = *(track->fHelixIn);
300 // Int_t ihelix = larr.GetEntriesFast();
301 // new(larr[ihelix]) AliHelix(*track) ;
304 track->SetNoCluster(0);
305 return track->Update(c,chi2,i);
310 Int_t AliTPCtrackerMI::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster)
313 // decide according desired precision to accept given
314 // cluster for tracking
316 seed->GetProlongation(cluster->GetX(),yt,zt);
317 Double_t sy2=ErrY2(seed,cluster);
318 Double_t sz2=ErrZ2(seed,cluster);
320 Double_t sdistancey2 = sy2+seed->GetSigmaY2();
321 Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
322 Double_t dy=seed->GetCurrentCluster()->GetY()-yt;
323 Double_t dz=seed->GetCurrentCluster()->GetZ()-zt;
324 Double_t rdistancey2 = (seed->GetCurrentCluster()->GetY()-yt)*
325 (seed->GetCurrentCluster()->GetY()-yt)/sdistancey2;
326 Double_t rdistancez2 = (seed->GetCurrentCluster()->GetZ()-zt)*
327 (seed->GetCurrentCluster()->GetZ()-zt)/sdistancez2;
329 Double_t rdistance2 = rdistancey2+rdistancez2;
332 if (AliTPCReconstructor::StreamLevel()>2 && seed->GetNumberOfClusters()>20) {
333 Float_t rmsy2 = seed->GetCurrentSigmaY2();
334 Float_t rmsz2 = seed->GetCurrentSigmaZ2();
335 Float_t rmsy2p30 = seed->GetCMeanSigmaY2p30();
336 Float_t rmsz2p30 = seed->GetCMeanSigmaZ2p30();
337 Float_t rmsy2p30R = seed->GetCMeanSigmaY2p30R();
338 Float_t rmsz2p30R = seed->GetCMeanSigmaZ2p30R();
339 AliExternalTrackParam param(*seed);
340 static TVectorD gcl(3),gtr(3);
342 param.GetXYZ(gcl.GetMatrixArray());
343 cluster->GetGlobalXYZ(gclf);
344 gcl[0]=gclf[0]; gcl[1]=gclf[1]; gcl[2]=gclf[2];
347 if (AliTPCReconstructor::StreamLevel()>2) {
348 (*fDebugStreamer)<<"ErrParam"<<
361 "rmsy2p30="<<rmsy2p30<<
362 "rmsz2p30="<<rmsz2p30<<
363 "rmsy2p30R="<<rmsy2p30R<<
364 "rmsz2p30R="<<rmsz2p30R<<
365 // normalize distance -
366 "rdisty="<<rdistancey2<<
367 "rdistz="<<rdistancez2<<
368 "rdist="<<rdistance2<< //
372 //return 0; // temporary
373 if (rdistance2>32) return 3;
376 if ((rdistancey2>9. || rdistancez2>9.) && cluster->GetType()==0)
377 return 2; //suspisiouce - will be changed
379 if ((rdistancey2>6.25 || rdistancez2>6.25) && cluster->GetType()>0)
380 // strict cut on overlaped cluster
381 return 2; //suspisiouce - will be changed
383 if ( (rdistancey2>1. || rdistancez2>6.25 )
384 && cluster->GetType()<0){
385 seed->SetNFoundable(seed->GetNFoundable()-1);
389 if (fUseHLTClusters == 3 || fUseHLTClusters == 4) {
391 if(!AliTPCReconstructor::GetRecoParam()->GetUseHLTOnePadCluster()) {
392 if (TMath::Abs(cluster->GetSigmaY2()) < kAlmost0)
405 //_____________________________________________________________________________
406 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCParam *par):
408 fkNIS(par->GetNInnerSector()/2),
410 fkNOS(par->GetNOuterSector()/2),
433 //---------------------------------------------------------------------
434 // The main TPC tracker constructor
435 //---------------------------------------------------------------------
436 fInnerSec=new AliTPCtrackerSector[fkNIS];
437 fOuterSec=new AliTPCtrackerSector[fkNOS];
440 for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
441 for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
444 Int_t nrowlow = par->GetNRowLow();
445 Int_t nrowup = par->GetNRowUp();
448 for (i=0;i<nrowlow;i++){
449 fXRow[i] = par->GetPadRowRadiiLow(i);
450 fPadLength[i]= par->GetPadPitchLength(0,i);
451 fYMax[i] = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
455 for (i=0;i<nrowup;i++){
456 fXRow[i+nrowlow] = par->GetPadRowRadiiUp(i);
457 fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
458 fYMax[i+nrowlow] = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
461 if (AliTPCReconstructor::StreamLevel()>0) {
462 fDebugStreamer = new TTreeSRedirector("TPCdebug.root");
465 fSeedsPool = new TClonesArray("AliTPCseed",1000);
467 //________________________________________________________________________
468 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCtrackerMI &t):
495 //------------------------------------
496 // dummy copy constructor
497 //------------------------------------------------------------------
499 for (Int_t irow=0; irow<200; irow++){
506 AliTPCtrackerMI & AliTPCtrackerMI::operator=(const AliTPCtrackerMI& /*r*/)
508 //------------------------------
510 //--------------------------------------------------------------
513 //_____________________________________________________________________________
514 AliTPCtrackerMI::~AliTPCtrackerMI() {
515 //------------------------------------------------------------------
516 // TPC tracker destructor
517 //------------------------------------------------------------------
524 if (fDebugStreamer) delete fDebugStreamer;
525 if (fSeedsPool) delete fSeedsPool;
529 void AliTPCtrackerMI::FillESD(const TObjArray* arr)
533 //fill esds using updated tracks
536 // write tracks to the event
537 // store index of the track
538 Int_t nseed=arr->GetEntriesFast();
539 //FindKinks(arr,fEvent);
540 for (Int_t i=0; i<nseed; i++) {
541 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
545 if (AliTPCReconstructor::StreamLevel()>1) {
546 (*fDebugStreamer)<<"Track0"<<
550 // pt->PropagateTo(fkParam->GetInnerRadiusLow());
551 if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
552 pt->PropagateTo(fkParam->GetInnerRadiusLow());
555 if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
557 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
558 iotrack.SetTPCPoints(pt->GetPoints());
559 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
560 iotrack.SetV0Indexes(pt->GetV0Indexes());
561 // iotrack.SetTPCpid(pt->fTPCr);
562 //iotrack.SetTPCindex(i);
563 MakeESDBitmaps(pt, &iotrack);
564 fEvent->AddTrack(&iotrack);
568 if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
570 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
571 iotrack.SetTPCPoints(pt->GetPoints());
572 //iotrack.SetTPCindex(i);
573 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
574 iotrack.SetV0Indexes(pt->GetV0Indexes());
575 MakeESDBitmaps(pt, &iotrack);
576 // iotrack.SetTPCpid(pt->fTPCr);
577 fEvent->AddTrack(&iotrack);
581 // short tracks - maybe decays
583 if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
584 Int_t found,foundable,shared;
585 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
586 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
588 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
589 //iotrack.SetTPCindex(i);
590 iotrack.SetTPCPoints(pt->GetPoints());
591 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
592 iotrack.SetV0Indexes(pt->GetV0Indexes());
593 MakeESDBitmaps(pt, &iotrack);
594 //iotrack.SetTPCpid(pt->fTPCr);
595 fEvent->AddTrack(&iotrack);
600 if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
601 Int_t found,foundable,shared;
602 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
603 if (found<20) continue;
604 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
607 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
608 iotrack.SetTPCPoints(pt->GetPoints());
609 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
610 iotrack.SetV0Indexes(pt->GetV0Indexes());
611 MakeESDBitmaps(pt, &iotrack);
612 //iotrack.SetTPCpid(pt->fTPCr);
613 //iotrack.SetTPCindex(i);
614 fEvent->AddTrack(&iotrack);
617 // short tracks - secondaties
619 if ( (pt->GetNumberOfClusters()>30) ) {
620 Int_t found,foundable,shared;
621 pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
622 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
624 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
625 iotrack.SetTPCPoints(pt->GetPoints());
626 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
627 iotrack.SetV0Indexes(pt->GetV0Indexes());
628 MakeESDBitmaps(pt, &iotrack);
629 //iotrack.SetTPCpid(pt->fTPCr);
630 //iotrack.SetTPCindex(i);
631 fEvent->AddTrack(&iotrack);
636 if ( (pt->GetNumberOfClusters()>15)) {
637 Int_t found,foundable,shared;
638 pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
639 if (found<15) continue;
640 if (foundable<=0) continue;
641 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
642 if (float(found)/float(foundable)<0.8) continue;
645 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
646 iotrack.SetTPCPoints(pt->GetPoints());
647 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
648 iotrack.SetV0Indexes(pt->GetV0Indexes());
649 MakeESDBitmaps(pt, &iotrack);
650 // iotrack.SetTPCpid(pt->fTPCr);
651 //iotrack.SetTPCindex(i);
652 fEvent->AddTrack(&iotrack);
656 // >> account for suppressed tracks in the kink indices (RS)
657 int nESDtracks = fEvent->GetNumberOfTracks();
658 for (int it=nESDtracks;it--;) {
659 AliESDtrack* esdTr = fEvent->GetTrack(it);
660 if (!esdTr || !esdTr->GetKinkIndex(0)) continue;
661 for (int ik=0;ik<3;ik++) {
663 if (!(knkId=esdTr->GetKinkIndex(ik))) break; // no more kinks for this track
664 AliESDkink* kink = fEvent->GetKink(TMath::Abs(knkId)-1);
666 AliError(Form("ESDTrack%d refers to non-existing kink %d",it,TMath::Abs(knkId)-1));
669 kink->SetIndex(it, knkId<0 ? 0:1); // update track index of the kink: mother at 0, daughter at 1
672 // << account for suppressed tracks in the kink indices (RS)
673 AliInfo(Form("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks()));
681 Double_t AliTPCtrackerMI::ErrY2(AliTPCseed* seed, const AliTPCclusterMI * cl){
684 // Use calibrated cluster error from OCDB
686 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
688 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
689 Int_t ctype = cl->GetType();
690 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
691 Double_t angle = seed->GetSnp()*seed->GetSnp();
692 angle = TMath::Sqrt(TMath::Abs(angle/(1.-angle)));
693 Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
695 erry2+=0.5; // edge cluster
698 seed->SetErrorY2(erry2);
702 //calculate look-up table at the beginning
703 // static Bool_t ginit = kFALSE;
704 // static Float_t gnoise1,gnoise2,gnoise3;
705 // static Float_t ggg1[10000];
706 // static Float_t ggg2[10000];
707 // static Float_t ggg3[10000];
708 // static Float_t glandau1[10000];
709 // static Float_t glandau2[10000];
710 // static Float_t glandau3[10000];
712 // static Float_t gcor01[500];
713 // static Float_t gcor02[500];
714 // static Float_t gcorp[500];
718 // if (ginit==kFALSE){
719 // for (Int_t i=1;i<500;i++){
720 // Float_t rsigma = float(i)/100.;
721 // gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
722 // gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
723 // gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
727 // for (Int_t i=3;i<10000;i++){
731 // Float_t amp = float(i);
732 // Float_t padlength =0.75;
733 // gnoise1 = 0.0004/padlength;
734 // Float_t nel = 0.268*amp;
735 // Float_t nprim = 0.155*amp;
736 // ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
737 // glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
738 // if (glandau1[i]>1) glandau1[i]=1;
739 // glandau1[i]*=padlength*padlength/12.;
743 // gnoise2 = 0.0004/padlength;
745 // nprim = 0.133*amp;
746 // ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
747 // glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
748 // if (glandau2[i]>1) glandau2[i]=1;
749 // glandau2[i]*=padlength*padlength/12.;
754 // gnoise3 = 0.0004/padlength;
756 // nprim = 0.133*amp;
757 // ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
758 // glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
759 // if (glandau3[i]>1) glandau3[i]=1;
760 // glandau3[i]*=padlength*padlength/12.;
768 // Int_t amp = int(TMath::Abs(cl->GetQ()));
770 // seed->SetErrorY2(1.);
774 // Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
775 // Int_t ctype = cl->GetType();
776 // Float_t padlength= GetPadPitchLength(seed->GetRow());
777 // Double_t angle2 = seed->GetSnp()*seed->GetSnp();
778 // angle2 = angle2/(1-angle2);
780 // //cluster "quality"
781 // Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
784 // if (fSectors==fInnerSec){
785 // snoise2 = gnoise1;
786 // res = ggg1[amp]*z+glandau1[amp]*angle2;
787 // if (ctype==0) res *= gcor01[rsigmay];
790 // res*= gcorp[rsigmay];
794 // if (padlength<1.1){
795 // snoise2 = gnoise2;
796 // res = ggg2[amp]*z+glandau2[amp]*angle2;
797 // if (ctype==0) res *= gcor02[rsigmay];
800 // res*= gcorp[rsigmay];
804 // snoise2 = gnoise3;
805 // res = ggg3[amp]*z+glandau3[amp]*angle2;
806 // if (ctype==0) res *= gcor02[rsigmay];
809 // res*= gcorp[rsigmay];
816 // res*=2.4; // overestimate error 2 times
820 // if (res<2*snoise2)
823 // seed->SetErrorY2(res);
831 Double_t AliTPCtrackerMI::ErrZ2(AliTPCseed* seed, const AliTPCclusterMI * cl){
834 // Use calibrated cluster error from OCDB
836 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
838 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
839 Int_t ctype = cl->GetType();
840 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
842 Double_t angle2 = seed->GetSnp()*seed->GetSnp();
843 angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
844 Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
845 Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
847 errz2+=0.5; // edge cluster
850 seed->SetErrorZ2(errz2);
856 // //seed->SetErrorY2(0.1);
858 // //calculate look-up table at the beginning
859 // static Bool_t ginit = kFALSE;
860 // static Float_t gnoise1,gnoise2,gnoise3;
861 // static Float_t ggg1[10000];
862 // static Float_t ggg2[10000];
863 // static Float_t ggg3[10000];
864 // static Float_t glandau1[10000];
865 // static Float_t glandau2[10000];
866 // static Float_t glandau3[10000];
868 // static Float_t gcor01[1000];
869 // static Float_t gcor02[1000];
870 // static Float_t gcorp[1000];
874 // if (ginit==kFALSE){
875 // for (Int_t i=1;i<1000;i++){
876 // Float_t rsigma = float(i)/100.;
877 // gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
878 // gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
879 // gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
883 // for (Int_t i=3;i<10000;i++){
887 // Float_t amp = float(i);
888 // Float_t padlength =0.75;
889 // gnoise1 = 0.0004/padlength;
890 // Float_t nel = 0.268*amp;
891 // Float_t nprim = 0.155*amp;
892 // ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
893 // glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
894 // if (glandau1[i]>1) glandau1[i]=1;
895 // glandau1[i]*=padlength*padlength/12.;
899 // gnoise2 = 0.0004/padlength;
901 // nprim = 0.133*amp;
902 // ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
903 // glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
904 // if (glandau2[i]>1) glandau2[i]=1;
905 // glandau2[i]*=padlength*padlength/12.;
910 // gnoise3 = 0.0004/padlength;
912 // nprim = 0.133*amp;
913 // ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
914 // glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
915 // if (glandau3[i]>1) glandau3[i]=1;
916 // glandau3[i]*=padlength*padlength/12.;
924 // Int_t amp = int(TMath::Abs(cl->GetQ()));
926 // seed->SetErrorY2(1.);
930 // Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
931 // Int_t ctype = cl->GetType();
932 // Float_t padlength= GetPadPitchLength(seed->GetRow());
934 // Double_t angle2 = seed->GetSnp()*seed->GetSnp();
935 // // if (angle2<0.6) angle2 = 0.6;
936 // angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
938 // //cluster "quality"
939 // Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
942 // if (fSectors==fInnerSec){
943 // snoise2 = gnoise1;
944 // res = ggg1[amp]*z+glandau1[amp]*angle2;
945 // if (ctype==0) res *= gcor01[rsigmaz];
948 // res*= gcorp[rsigmaz];
952 // if (padlength<1.1){
953 // snoise2 = gnoise2;
954 // res = ggg2[amp]*z+glandau2[amp]*angle2;
955 // if (ctype==0) res *= gcor02[rsigmaz];
958 // res*= gcorp[rsigmaz];
962 // snoise2 = gnoise3;
963 // res = ggg3[amp]*z+glandau3[amp]*angle2;
964 // if (ctype==0) res *= gcor02[rsigmaz];
967 // res*= gcorp[rsigmaz];
976 // if ((ctype<0) &&<70){
981 // if (res<2*snoise2)
983 // if (res>3) res =3;
984 // seed->SetErrorZ2(res);
992 void AliTPCtrackerMI::RotateToLocal(AliTPCseed *seed)
994 //rotate to track "local coordinata
995 Float_t x = seed->GetX();
996 Float_t y = seed->GetY();
997 Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
1000 seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
1001 if (!seed->Rotate(fSectors->GetAlpha()))
1003 } else if (y <-ymax) {
1004 seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
1005 if (!seed->Rotate(-fSectors->GetAlpha()))
1013 //_____________________________________________________________________________
1014 Double_t AliTPCtrackerMI::F1old(Double_t x1,Double_t y1,
1015 Double_t x2,Double_t y2,
1016 Double_t x3,Double_t y3) const
1018 //-----------------------------------------------------------------
1019 // Initial approximation of the track curvature
1020 //-----------------------------------------------------------------
1021 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1022 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1023 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1024 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1025 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1027 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1028 if ( xr*xr+yr*yr<=0.00000000000001) return 100;
1029 return -xr*yr/sqrt(xr*xr+yr*yr);
1034 //_____________________________________________________________________________
1035 Double_t AliTPCtrackerMI::F1(Double_t x1,Double_t y1,
1036 Double_t x2,Double_t y2,
1037 Double_t x3,Double_t y3) const
1039 //-----------------------------------------------------------------
1040 // Initial approximation of the track curvature
1041 //-----------------------------------------------------------------
1047 Double_t det = x3*y2-x2*y3;
1048 if (TMath::Abs(det)<1e-10){
1052 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1053 Double_t x0 = x3*0.5-y3*u;
1054 Double_t y0 = y3*0.5+x3*u;
1055 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1061 Double_t AliTPCtrackerMI::F2(Double_t x1,Double_t y1,
1062 Double_t x2,Double_t y2,
1063 Double_t x3,Double_t y3) const
1065 //-----------------------------------------------------------------
1066 // Initial approximation of the track curvature
1067 //-----------------------------------------------------------------
1073 Double_t det = x3*y2-x2*y3;
1074 if (TMath::Abs(det)<1e-10) {
1078 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1079 Double_t x0 = x3*0.5-y3*u;
1080 Double_t y0 = y3*0.5+x3*u;
1081 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1090 //_____________________________________________________________________________
1091 Double_t AliTPCtrackerMI::F2old(Double_t x1,Double_t y1,
1092 Double_t x2,Double_t y2,
1093 Double_t x3,Double_t y3) const
1095 //-----------------------------------------------------------------
1096 // Initial approximation of the track curvature times center of curvature
1097 //-----------------------------------------------------------------
1098 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1099 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1100 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1101 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1102 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1104 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1106 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1109 //_____________________________________________________________________________
1110 Double_t AliTPCtrackerMI::F3(Double_t x1,Double_t y1,
1111 Double_t x2,Double_t y2,
1112 Double_t z1,Double_t z2) const
1114 //-----------------------------------------------------------------
1115 // Initial approximation of the tangent of the track dip angle
1116 //-----------------------------------------------------------------
1117 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1121 Double_t AliTPCtrackerMI::F3n(Double_t x1,Double_t y1,
1122 Double_t x2,Double_t y2,
1123 Double_t z1,Double_t z2, Double_t c) const
1125 //-----------------------------------------------------------------
1126 // Initial approximation of the tangent of the track dip angle
1127 //-----------------------------------------------------------------
1131 //angle1 = (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1133 Double_t d = TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1134 if (TMath::Abs(d*c*0.5)>1) return 0;
1135 // Double_t angle2 = TMath::ASin(d*c*0.5);
1136 // Double_t angle2 = AliTPCFastMath::FastAsin(d*c*0.5);
1137 Double_t angle2 = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): AliTPCFastMath::FastAsin(d*c*0.5);
1139 angle2 = (z1-z2)*c/(angle2*2.);
1143 Bool_t AliTPCtrackerMI::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
1144 {//-----------------------------------------------------------------
1145 // This function find proloncation of a track to a reference plane x=x2.
1146 //-----------------------------------------------------------------
1150 if (TMath::Abs(x[4]*x1 - x[2]) >= 0.999) {
1154 Double_t c1=x[4]*x1 - x[2], r1=TMath::Sqrt((1.-c1)*(1.+c1));
1155 Double_t c2=x[4]*x2 - x[2], r2=TMath::Sqrt((1.-c2)*(1.+c2));
1159 Double_t dy = dx*(c1+c2)/(r1+r2);
1162 Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1164 if (TMath::Abs(delta)>0.01){
1165 dz = x[3]*TMath::ASin(delta)/x[4];
1167 dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1170 //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1178 Int_t AliTPCtrackerMI::LoadClusters (TTree *const tree)
1183 return LoadClusters();
1187 Int_t AliTPCtrackerMI::LoadClusters(const TObjArray *arr)
1190 // load clusters to the memory
1191 AliTPCClustersRow *clrow = new AliTPCClustersRow("AliTPCclusterMI");
1192 Int_t lower = arr->LowerBound();
1193 Int_t entries = arr->GetEntriesFast();
1195 for (Int_t i=lower; i<entries; i++) {
1196 clrow = (AliTPCClustersRow*) arr->At(i);
1197 if(!clrow) continue;
1198 if(!clrow->GetArray()) continue;
1202 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
1204 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1205 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1208 if (clrow->GetArray()->GetEntriesFast()<=0) continue;
1209 AliTPCtrackerRow * tpcrow=0;
1212 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1216 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1217 left = (sec-fkNIS*2)/fkNOS;
1220 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
1221 for (Int_t j=0;j<tpcrow->GetN1();++j)
1222 tpcrow->SetCluster1(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
1225 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
1226 for (Int_t j=0;j<tpcrow->GetN2();++j)
1227 tpcrow->SetCluster2(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
1229 clrow->GetArray()->Clear("C");
1235 ApllyTailCancellation();
1239 Int_t AliTPCtrackerMI::LoadClusters(const TClonesArray *arr)
1242 // load clusters to the memory from one
1245 AliTPCclusterMI *clust=0;
1246 Int_t count[72][96] = { {0} , {0} };
1248 // loop over clusters
1249 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1250 clust = (AliTPCclusterMI*)arr->At(icl);
1251 if(!clust) continue;
1252 //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
1254 // transform clusters
1257 // count clusters per pad row
1258 count[clust->GetDetector()][clust->GetRow()]++;
1261 // insert clusters to sectors
1262 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1263 clust = (AliTPCclusterMI*)arr->At(icl);
1264 if(!clust) continue;
1266 Int_t sec = clust->GetDetector();
1267 Int_t row = clust->GetRow();
1269 // filter overlapping pad rows needed by HLT
1270 if(sec<fkNIS*2) { //IROCs
1271 if(row == 30) continue;
1274 if(row == 27 || row == 76) continue;
1279 // left = sec/fkNIS;
1280 fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fkParam);
1283 // left = (sec-fkNIS*2)/fkNOS;
1284 fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fkParam);
1288 // Load functions must be called behind LoadCluster(TClonesArray*)
1290 //LoadOuterSectors();
1291 //LoadInnerSectors();
1297 Int_t AliTPCtrackerMI::LoadClusters()
1300 // load clusters to the memory
1301 static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
1303 // TTree * tree = fClustersArray.GetTree();
1305 TTree * tree = fInput;
1306 TBranch * br = tree->GetBranch("Segment");
1307 br->SetAddress(&clrow);
1309 // Conversion of pad, row coordinates in local tracking coords.
1310 // Could be skipped here; is already done in clusterfinder
1312 Int_t j=Int_t(tree->GetEntries());
1313 for (Int_t i=0; i<j; i++) {
1317 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
1318 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1319 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1322 AliTPCtrackerRow * tpcrow=0;
1325 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1329 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1330 left = (sec-fkNIS*2)/fkNOS;
1333 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
1334 for (Int_t k=0;k<tpcrow->GetN1();++k)
1335 tpcrow->SetCluster1(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
1338 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
1339 for (Int_t k=0;k<tpcrow->GetN2();++k)
1340 tpcrow->SetCluster2(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
1351 void AliTPCtrackerMI::UnloadClusters()
1354 // unload clusters from the memory
1356 Int_t nrows = fOuterSec->GetNRows();
1357 for (Int_t sec = 0;sec<fkNOS;sec++)
1358 for (Int_t row = 0;row<nrows;row++){
1359 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1361 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1362 // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1364 tpcrow->ResetClusters();
1367 nrows = fInnerSec->GetNRows();
1368 for (Int_t sec = 0;sec<fkNIS;sec++)
1369 for (Int_t row = 0;row<nrows;row++){
1370 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1372 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1373 //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1375 tpcrow->ResetClusters();
1381 void AliTPCtrackerMI::FillClusterArray(TObjArray* array) const{
1383 // Filling cluster to the array - For visualization purposes
1386 nrows = fOuterSec->GetNRows();
1387 for (Int_t sec = 0;sec<fkNOS;sec++)
1388 for (Int_t row = 0;row<nrows;row++){
1389 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1390 if (!tpcrow) continue;
1391 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1392 array->AddLast((TObject*)((*tpcrow)[icl]));
1395 nrows = fInnerSec->GetNRows();
1396 for (Int_t sec = 0;sec<fkNIS;sec++)
1397 for (Int_t row = 0;row<nrows;row++){
1398 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1399 if (!tpcrow) continue;
1400 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1401 array->AddLast((TObject*)(*tpcrow)[icl]);
1407 void AliTPCtrackerMI::Transform(AliTPCclusterMI * cluster){
1411 AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1412 AliTPCTransform *transform = calibDB->GetTransform() ;
1414 AliFatal("Tranformations not in calibDB");
1417 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
1418 Double_t x[3]={cluster->GetRow(),cluster->GetPad(),cluster->GetTimeBin()};
1419 Int_t i[1]={cluster->GetDetector()};
1420 transform->Transform(x,i,0,1);
1421 // if (cluster->GetDetector()%36>17){
1426 // in debug mode check the transformation
1428 if (AliTPCReconstructor::StreamLevel()>2) {
1430 cluster->GetGlobalXYZ(gx);
1431 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
1432 TTreeSRedirector &cstream = *fDebugStreamer;
1433 cstream<<"Transform"<<
1444 cluster->SetX(x[0]);
1445 cluster->SetY(x[1]);
1446 cluster->SetZ(x[2]);
1451 //if (!fkParam->IsGeoRead()) fkParam->ReadGeoMatrices();
1452 if (AliTPCReconstructor::GetRecoParam()->GetUseSectorAlignment() && (!calibDB->HasAlignmentOCDB())){
1453 TGeoHMatrix *mat = fkParam->GetClusterMatrix(cluster->GetDetector());
1455 Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1456 Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1457 if (mat) mat->LocalToMaster(pos,posC);
1459 // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
1461 cluster->SetX(posC[0]);
1462 cluster->SetY(posC[1]);
1463 cluster->SetZ(posC[2]);
1467 void AliTPCtrackerMI::ApllyTailCancellation(){
1469 // Correct the cluster charge for the tail from the previous clusters
1470 // The TimeResponse function accessed via AliTPCcalibDB (TPC/Calib/IonTail)
1474 for (Int_t secType=0; secType<2; secType++){ //loop inner or outer sector
1477 for (Int_t sec = 0;sec<fkNOS;sec++){ //loop overs sectors
1480 AliTPCtrackerSector §or= (secType==0)?fInnerSec[sec]:fOuterSec[sec];
1482 Int_t nrows = sector.GetNRows();
1483 for (Int_t row = 0;row<nrows;row++){ //loop over rows
1484 AliTPCtrackerRow& tpcrow = sector[row];
1485 Int_t ncl = tpcrow.GetN1();
1487 for (Int_t icl0=0; icl0<ncl;icl0++){ // first loop over clusters
1488 AliTPCclusterMI *cl0= (tpcrow.GetCluster1(icl0));
1489 if (!icl0) continue;
1490 for (Int_t icl1=0; icl1<ncl;icl1++){ // second loop over clusters
1491 AliTPCclusterMI *cl1= (tpcrow.GetCluster1(icl1));
1492 if (!icl1) continue;
1493 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())>2) continue; // no contribution if far away in pad direction
1494 if (cl1->GetTimeBin()> cl0->GetTimeBin()) continue; // no contibution to the tail if later
1495 Double_t ionTailMax=0; //
1496 Double_t ionTailTotal=0; //
1498 cl0->SetQ(cl0->GetQ()+ionTailTotal);
1499 cl0->SetMax(cl0->GetMax()+ionTailMax);
1500 if (AliTPCReconstructor::StreamLevel()>5) {
1501 TTreeSRedirector &cstream = *fDebugStreamer;
1502 cstream<<"IonTail"<<
1503 "cl0.="<<cl0<< // cluster 0 (to be corrected)
1504 "cl1.="<<cl1<< // cluster 1 (previous cluster)
1505 "ionTailTotal="<<ionTailTotal<< // ion Tail from cluster 1 contribution to cluster0
1506 "ionTailMax="<<ionTailMax<< // ion Tail from cluster 1 contribution to cluster0
1508 }// dump the results to the debug streamer if in debug mode
1509 }//end of secon loop over clusters
1510 }//end of first loop over cluster
1511 }//end of loop over rows
1512 }//end of loop over sectors
1513 }//end of loop over IROC/OROC
1519 //_____________________________________________________________________________
1520 Int_t AliTPCtrackerMI::LoadOuterSectors() {
1521 //-----------------------------------------------------------------
1522 // This function fills outer TPC sectors with clusters.
1523 //-----------------------------------------------------------------
1524 Int_t nrows = fOuterSec->GetNRows();
1526 for (Int_t sec = 0;sec<fkNOS;sec++)
1527 for (Int_t row = 0;row<nrows;row++){
1528 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1529 Int_t sec2 = sec+2*fkNIS;
1531 Int_t ncl = tpcrow->GetN1();
1533 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1534 index=(((sec2<<8)+row)<<16)+ncl;
1535 tpcrow->InsertCluster(c,index);
1538 ncl = tpcrow->GetN2();
1540 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1541 index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
1542 tpcrow->InsertCluster(c,index);
1545 // write indexes for fast acces
1547 for (Int_t i=0;i<510;i++)
1548 tpcrow->SetFastCluster(i,-1);
1549 for (Int_t i=0;i<tpcrow->GetN();i++){
1550 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1551 tpcrow->SetFastCluster(zi,i); // write index
1554 for (Int_t i=0;i<510;i++){
1555 if (tpcrow->GetFastCluster(i)<0)
1556 tpcrow->SetFastCluster(i,last);
1558 last = tpcrow->GetFastCluster(i);
1567 //_____________________________________________________________________________
1568 Int_t AliTPCtrackerMI::LoadInnerSectors() {
1569 //-----------------------------------------------------------------
1570 // This function fills inner TPC sectors with clusters.
1571 //-----------------------------------------------------------------
1572 Int_t nrows = fInnerSec->GetNRows();
1574 for (Int_t sec = 0;sec<fkNIS;sec++)
1575 for (Int_t row = 0;row<nrows;row++){
1576 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1579 Int_t ncl = tpcrow->GetN1();
1581 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1582 index=(((sec<<8)+row)<<16)+ncl;
1583 tpcrow->InsertCluster(c,index);
1586 ncl = tpcrow->GetN2();
1588 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1589 index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
1590 tpcrow->InsertCluster(c,index);
1593 // write indexes for fast acces
1595 for (Int_t i=0;i<510;i++)
1596 tpcrow->SetFastCluster(i,-1);
1597 for (Int_t i=0;i<tpcrow->GetN();i++){
1598 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1599 tpcrow->SetFastCluster(zi,i); // write index
1602 for (Int_t i=0;i<510;i++){
1603 if (tpcrow->GetFastCluster(i)<0)
1604 tpcrow->SetFastCluster(i,last);
1606 last = tpcrow->GetFastCluster(i);
1618 //_________________________________________________________________________
1619 AliTPCclusterMI *AliTPCtrackerMI::GetClusterMI(Int_t index) const {
1620 //--------------------------------------------------------------------
1621 // Return pointer to a given cluster
1622 //--------------------------------------------------------------------
1623 if (index<0) return 0; // no cluster
1624 Int_t sec=(index&0xff000000)>>24;
1625 Int_t row=(index&0x00ff0000)>>16;
1626 Int_t ncl=(index&0x00007fff)>>00;
1628 const AliTPCtrackerRow * tpcrow=0;
1629 TClonesArray * clrow =0;
1631 if (sec<0 || sec>=fkNIS*4) {
1632 AliWarning(Form("Wrong sector %d",sec));
1637 AliTPCtrackerSector& tracksec = fInnerSec[sec%fkNIS];
1638 if (tracksec.GetNRows()<=row) return 0;
1639 tpcrow = &(tracksec[row]);
1640 if (tpcrow==0) return 0;
1643 if (tpcrow->GetN1()<=ncl) return 0;
1644 clrow = tpcrow->GetClusters1();
1647 if (tpcrow->GetN2()<=ncl) return 0;
1648 clrow = tpcrow->GetClusters2();
1652 AliTPCtrackerSector& tracksec = fOuterSec[(sec-fkNIS*2)%fkNOS];
1653 if (tracksec.GetNRows()<=row) return 0;
1654 tpcrow = &(tracksec[row]);
1655 if (tpcrow==0) return 0;
1657 if (sec-2*fkNIS<fkNOS) {
1658 if (tpcrow->GetN1()<=ncl) return 0;
1659 clrow = tpcrow->GetClusters1();
1662 if (tpcrow->GetN2()<=ncl) return 0;
1663 clrow = tpcrow->GetClusters2();
1667 return (AliTPCclusterMI*)clrow->At(ncl);
1673 Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
1674 //-----------------------------------------------------------------
1675 // This function tries to find a track prolongation to next pad row
1676 //-----------------------------------------------------------------
1678 Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
1681 AliTPCclusterMI *cl=0;
1682 Int_t tpcindex= t.GetClusterIndex2(nr);
1684 // update current shape info every 5 pad-row
1685 // if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
1689 if (fIteration>0 && tpcindex>=-1){ //if we have already clusters
1691 if (tpcindex==-1) return 0; //track in dead zone
1692 if (tpcindex >= 0){ //
1693 cl = t.GetClusterPointer(nr);
1694 //if (cl==0) cl = GetClusterMI(tpcindex);
1695 if (!cl) cl = GetClusterMI(tpcindex);
1696 t.SetCurrentClusterIndex1(tpcindex);
1699 Int_t relativesector = ((tpcindex&0xff000000)>>24)%18; // if previously accepted cluster in different sector
1700 Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
1702 if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
1703 if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
1705 if (TMath::Abs(angle-t.GetAlpha())>0.001){
1706 Double_t rotation = angle-t.GetAlpha();
1707 t.SetRelativeSector(relativesector);
1708 if (!t.Rotate(rotation)) {
1709 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
1713 if (!t.PropagateTo(x)) {
1714 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
1718 t.SetCurrentCluster(cl);
1720 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1721 if ((tpcindex&0x8000)==0) accept =0;
1723 //if founded cluster is acceptible
1724 if (cl->IsUsed(11)) { // id cluster is shared inrease uncertainty
1725 t.SetErrorY2(t.GetErrorY2()+0.03);
1726 t.SetErrorZ2(t.GetErrorZ2()+0.03);
1727 t.SetErrorY2(t.GetErrorY2()*3);
1728 t.SetErrorZ2(t.GetErrorZ2()*3);
1730 t.SetNFoundable(t.GetNFoundable()+1);
1731 UpdateTrack(&t,accept);
1734 else { // Remove old cluster from track
1735 t.SetClusterIndex(nr, -3);
1736 t.SetClusterPointer(nr, 0);
1740 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0; // cut on angle
1741 if (fIteration>1 && IsFindable(t)){
1742 // not look for new cluster during refitting
1743 t.SetNFoundable(t.GetNFoundable()+1);
1748 // if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
1749 if (!t.PropagateTo(x)) {
1750 if (fIteration==0) t.SetRemoval(10);
1753 Double_t y = t.GetY();
1754 if (TMath::Abs(y)>ymax){
1756 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1757 if (!t.Rotate(fSectors->GetAlpha()))
1759 } else if (y <-ymax) {
1760 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1761 if (!t.Rotate(-fSectors->GetAlpha()))
1764 if (!t.PropagateTo(x)) {
1765 if (fIteration==0) t.SetRemoval(10);
1771 Double_t z=t.GetZ();
1774 if (!IsActive(t.GetRelativeSector(),nr)) {
1776 t.SetClusterIndex2(nr,-1);
1779 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
1780 Bool_t isActive = IsActive(t.GetRelativeSector(),nr);
1781 Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
1783 if (!isActive || !isActive2) return 0;
1785 const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1786 if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
1788 Double_t roadz = 1.;
1790 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1792 t.SetClusterIndex2(nr,-1);
1798 // if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fkParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
1799 t.SetNFoundable(t.GetNFoundable()+1);
1805 // cl = krow.FindNearest2(y+10.,z,roady,roadz,index);
1806 cl = krow.FindNearest2(y,z,roady,roadz,index);
1807 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
1810 t.SetCurrentCluster(cl);
1812 if (fIteration==2&&cl->IsUsed(10)) return 0;
1813 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1814 if (fIteration==2&&cl->IsUsed(11)) {
1815 t.SetErrorY2(t.GetErrorY2()+0.03);
1816 t.SetErrorZ2(t.GetErrorZ2()+0.03);
1817 t.SetErrorY2(t.GetErrorY2()*3);
1818 t.SetErrorZ2(t.GetErrorZ2()*3);
1821 if (t.fCurrentCluster->IsUsed(10)){
1826 if (t.fNShared>0.7*t.GetNumberOfClusters()) {
1832 if (accept<3) UpdateTrack(&t,accept);
1835 if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
1843 //_________________________________________________________________________
1844 Bool_t AliTPCtrackerMI::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
1846 // Get track space point by index
1847 // return false in case the cluster doesn't exist
1848 AliTPCclusterMI *cl = GetClusterMI(index);
1849 if (!cl) return kFALSE;
1850 Int_t sector = (index&0xff000000)>>24;
1851 // Int_t row = (index&0x00ff0000)>>16;
1853 // xyz[0] = fkParam->GetPadRowRadii(sector,row);
1854 xyz[0] = cl->GetX();
1855 xyz[1] = cl->GetY();
1856 xyz[2] = cl->GetZ();
1858 fkParam->AdjustCosSin(sector,cos,sin);
1859 Float_t x = cos*xyz[0]-sin*xyz[1];
1860 Float_t y = cos*xyz[1]+sin*xyz[0];
1862 Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
1863 if (sector < fkParam->GetNInnerSector()) sigmaY2 *= 2.07;
1864 Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
1865 if (sector < fkParam->GetNInnerSector()) sigmaZ2 *= 1.77;
1866 cov[0] = sin*sin*sigmaY2;
1867 cov[1] = -sin*cos*sigmaY2;
1869 cov[3] = cos*cos*sigmaY2;
1872 p.SetXYZ(x,y,xyz[2],cov);
1873 AliGeomManager::ELayerID iLayer;
1875 if (sector < fkParam->GetNInnerSector()) {
1876 iLayer = AliGeomManager::kTPC1;
1880 iLayer = AliGeomManager::kTPC2;
1881 idet = sector - fkParam->GetNInnerSector();
1883 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
1884 p.SetVolumeID(volid);
1890 Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t, Int_t nr) {
1891 //-----------------------------------------------------------------
1892 // This function tries to find a track prolongation to next pad row
1893 //-----------------------------------------------------------------
1894 t.SetCurrentCluster(0);
1895 t.SetCurrentClusterIndex1(-3);
1897 Double_t xt=t.GetX();
1898 Int_t row = GetRowNumber(xt)-1;
1899 Double_t ymax= GetMaxY(nr);
1901 if (row < nr) return 1; // don't prolongate if not information until now -
1902 // if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
1904 // return 0; // not prolongate strongly inclined tracks
1906 // if (TMath::Abs(t.GetSnp())>0.95) {
1908 // return 0; // not prolongate strongly inclined tracks
1909 // }// patch 28 fev 06
1911 Double_t x= GetXrow(nr);
1913 //t.PropagateTo(x+0.02);
1914 //t.PropagateTo(x+0.01);
1915 if (!t.PropagateTo(x)){
1922 if (TMath::Abs(y)>ymax){
1924 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1925 if (!t.Rotate(fSectors->GetAlpha()))
1927 } else if (y <-ymax) {
1928 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1929 if (!t.Rotate(-fSectors->GetAlpha()))
1932 // if (!t.PropagateTo(x)){
1939 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
1941 if (!IsActive(t.GetRelativeSector(),nr)) {
1943 t.SetClusterIndex2(nr,-1);
1946 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
1948 AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1950 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1952 t.SetClusterIndex2(nr,-1);
1958 // if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
1959 if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
1965 if ( (nr%2==0) || t.GetNumberOfClusters()<2){
1966 // t.fCurrentSigmaY = GetSigmaY(&t);
1967 //t.fCurrentSigmaZ = GetSigmaZ(&t);
1971 AliTPCclusterMI *cl=0;
1974 Double_t roady = 1.;
1975 Double_t roadz = 1.;
1979 index = t.GetClusterIndex2(nr);
1980 if ( (index >= 0) && (index&0x8000)==0){
1981 cl = t.GetClusterPointer(nr);
1982 if ( (cl==0) && (index >= 0)) cl = GetClusterMI(index);
1983 t.SetCurrentClusterIndex1(index);
1985 t.SetCurrentCluster(cl);
1991 // if (index<0) return 0;
1992 UInt_t uindex = TMath::Abs(index);
1995 //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
1996 cl = krow.FindNearest2(y,z,roady,roadz,uindex);
1999 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));
2000 t.SetCurrentCluster(cl);
2006 Int_t AliTPCtrackerMI::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
2007 //-----------------------------------------------------------------
2008 // This function tries to find a track prolongation to next pad row
2009 //-----------------------------------------------------------------
2011 //update error according neighborhoud
2013 if (t.GetCurrentCluster()) {
2015 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
2017 if (t.GetCurrentCluster()->IsUsed(10)){
2022 t.SetNShared(t.GetNShared()+1);
2023 if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
2028 if (fIteration>0) accept = 0;
2029 if (accept<3) UpdateTrack(&t,accept);
2033 if ( t.GetNumberOfClusters()>18 && ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)) t.SetRemoval(10);
2034 if ( t.GetNumberOfClusters()>18 && t.GetChi2()/t.GetNumberOfClusters()>6 ) t.SetRemoval(10);
2036 if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
2044 //_____________________________________________________________________________
2045 Int_t AliTPCtrackerMI::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step, Bool_t fromSeeds) {
2046 //-----------------------------------------------------------------
2047 // This function tries to find a track prolongation.
2048 //-----------------------------------------------------------------
2049 Double_t xt=t.GetX();
2051 Double_t alpha=t.GetAlpha();
2052 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2053 if (alpha < 0. ) alpha += 2.*TMath::Pi();
2055 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
2057 Int_t first = GetRowNumber(xt);
2062 for (Int_t nr= first; nr>=rf; nr-=step) {
2064 if (t.GetKinkIndexes()[0]>0){
2065 for (Int_t i=0;i<3;i++){
2066 Int_t index = t.GetKinkIndexes()[i];
2067 if (index==0) break;
2068 if (index<0) continue;
2070 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
2072 printf("PROBLEM\n");
2075 Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
2077 AliExternalTrackParam paramd(t);
2078 kink->SetDaughter(paramd);
2079 kink->SetStatus(2,5);
2086 if (nr==80) t.UpdateReference();
2087 if (nr<fInnerSec->GetNRows())
2088 fSectors = fInnerSec;
2090 fSectors = fOuterSec;
2091 if (FollowToNext(t,nr)==0)
2104 Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf, Bool_t fromSeeds) {
2105 //-----------------------------------------------------------------
2106 // This function tries to find a track prolongation.
2107 //-----------------------------------------------------------------
2109 Double_t xt=t.GetX();
2110 Double_t alpha=t.GetAlpha();
2111 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2112 if (alpha < 0. ) alpha += 2.*TMath::Pi();
2113 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
2115 Int_t first = t.GetFirstPoint();
2116 Int_t ri = GetRowNumber(xt);
2120 if (first<ri) first = ri;
2122 if (first<0) first=0;
2123 for (Int_t nr=first; nr<=rf; nr++) {
2124 // if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
2125 if (t.GetKinkIndexes()[0]<0){
2126 for (Int_t i=0;i<3;i++){
2127 Int_t index = t.GetKinkIndexes()[i];
2128 if (index==0) break;
2129 if (index>0) continue;
2130 index = TMath::Abs(index);
2131 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
2133 printf("PROBLEM\n");
2136 Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
2138 AliExternalTrackParam paramm(t);
2139 kink->SetMother(paramm);
2140 kink->SetStatus(2,1);
2147 if (nr<fInnerSec->GetNRows())
2148 fSectors = fInnerSec;
2150 fSectors = fOuterSec;
2161 Float_t AliTPCtrackerMI::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
2163 // overlapping factor
2169 Float_t dz2 =(s1->GetZ() - s2->GetZ());
2172 Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
2174 Float_t distance = TMath::Sqrt(dz2+dy2);
2175 if (distance>4.) return 0; // if there are far away - not overlap - to reduce combinatorics
2178 Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
2179 Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
2184 if (firstpoint>lastpoint) {
2185 firstpoint =lastpoint;
2190 for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
2191 if (s1->GetClusterIndex2(i)>0) sum1++;
2192 if (s2->GetClusterIndex2(i)>0) sum2++;
2193 if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
2197 if (sum<5) return 0;
2199 Float_t summin = TMath::Min(sum1+1,sum2+1);
2200 Float_t ratio = (sum+1)/Float_t(summin);
2204 void AliTPCtrackerMI::SignShared(AliTPCseed * s1, AliTPCseed * s2)
2208 Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
2209 if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
2210 Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
2211 Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
2216 //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
2217 //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
2218 Int_t firstpoint = 0;
2219 Int_t lastpoint = 160;
2221 // if (firstpoint>=lastpoint-5) return;;
2223 for (Int_t i=firstpoint;i<lastpoint;i++){
2224 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2225 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2229 if (sumshared>cutN0){
2232 for (Int_t i=firstpoint;i<lastpoint;i++){
2233 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2234 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2235 AliTPCTrackerPoint *p1 = s1->GetTrackPoint(i);
2236 AliTPCTrackerPoint *p2 = s2->GetTrackPoint(i);;
2237 if (s1->IsActive()&&s2->IsActive()){
2238 p1->SetShared(kTRUE);
2239 p2->SetShared(kTRUE);
2245 if (sumshared>cutN0){
2246 for (Int_t i=0;i<4;i++){
2247 if (s1->GetOverlapLabel(3*i)==0){
2248 s1->SetOverlapLabel(3*i, s2->GetLabel());
2249 s1->SetOverlapLabel(3*i+1,sumshared);
2250 s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
2254 for (Int_t i=0;i<4;i++){
2255 if (s2->GetOverlapLabel(3*i)==0){
2256 s2->SetOverlapLabel(3*i, s1->GetLabel());
2257 s2->SetOverlapLabel(3*i+1,sumshared);
2258 s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
2265 void AliTPCtrackerMI::SignShared(TObjArray * arr)
2268 //sort trackss according sectors
2270 for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2271 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2273 //if (pt) RotateToLocal(pt);
2277 arr->Sort(); // sorting according relative sectors
2278 arr->Expand(arr->GetEntries());
2281 Int_t nseed=arr->GetEntriesFast();
2282 for (Int_t i=0; i<nseed; i++) {
2283 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2285 for (Int_t j=0;j<12;j++){
2286 pt->SetOverlapLabel(j,0);
2289 for (Int_t i=0; i<nseed; i++) {
2290 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2292 if (pt->GetRemoval()>10) continue;
2293 for (Int_t j=i+1; j<nseed; j++){
2294 AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
2295 if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
2297 if (pt2->GetRemoval()<=10) {
2298 //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
2306 void AliTPCtrackerMI::SortTracks(TObjArray * arr, Int_t mode) const
2309 //sort tracks in array according mode criteria
2310 Int_t nseed = arr->GetEntriesFast();
2311 for (Int_t i=0; i<nseed; i++) {
2312 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2323 void AliTPCtrackerMI::RemoveUsed2(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t minimal)
2326 // Loop over all tracks and remove overlaped tracks (with lower quality)
2328 // 1. Unsign clusters
2329 // 2. Sort tracks according quality
2330 // Quality is defined by the number of cluster between first and last points
2332 // 3. Loop over tracks - decreasing quality order
2333 // a.) remove - If the fraction of shared cluster less than factor (1- n or 2)
2334 // b.) remove - If the minimal number of clusters less than minimal and not ITS
2335 // c.) if track accepted - sign clusters
2337 //Called in - AliTPCtrackerMI::Clusters2Tracks()
2338 // - AliTPCtrackerMI::PropagateBack()
2339 // - AliTPCtrackerMI::RefitInward()
2342 // factor1 - factor for constrained
2343 // factor2 - for non constrained tracks
2344 // if (Float_t(shared+1)/Float_t(found+1)>factor) - DELETE
2348 Int_t nseed = arr->GetEntriesFast();
2349 Float_t * quality = new Float_t[nseed];
2350 Int_t * indexes = new Int_t[nseed];
2354 for (Int_t i=0; i<nseed; i++) {
2355 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2360 pt->UpdatePoints(); //select first last max dens points
2361 Float_t * points = pt->GetPoints();
2362 if (points[3]<0.8) quality[i] =-1;
2363 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
2364 //prefer high momenta tracks if overlaps
2365 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
2367 TMath::Sort(nseed,quality,indexes);
2370 for (Int_t itrack=0; itrack<nseed; itrack++) {
2371 Int_t trackindex = indexes[itrack];
2372 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);
2375 if (quality[trackindex]<0){
2376 MarkSeedFree( arr->RemoveAt(trackindex) );
2381 Int_t first = Int_t(pt->GetPoints()[0]);
2382 Int_t last = Int_t(pt->GetPoints()[2]);
2383 Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
2385 Int_t found,foundable,shared;
2386 pt->GetClusterStatistic(first,last, found, foundable,shared,kFALSE); // better to get statistic in "high-dens" region do't use full track as in line bellow
2387 // pt->GetClusterStatistic(0,160, found, foundable,shared,kFALSE);
2388 Bool_t itsgold =kFALSE;
2391 if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
2395 if (Float_t(shared+1)/Float_t(found+1)>factor){
2396 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
2397 if( AliTPCReconstructor::StreamLevel()>3){
2398 TTreeSRedirector &cstream = *fDebugStreamer;
2399 cstream<<"RemoveUsed"<<
2400 "iter="<<fIteration<<
2404 MarkSeedFree( arr->RemoveAt(trackindex) );
2407 if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){ //remove short tracks
2408 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
2409 if( AliTPCReconstructor::StreamLevel()>3){
2410 TTreeSRedirector &cstream = *fDebugStreamer;
2411 cstream<<"RemoveShort"<<
2412 "iter="<<fIteration<<
2416 MarkSeedFree( arr->RemoveAt(trackindex) );
2422 //if (sharedfactor>0.4) continue;
2423 if (pt->GetKinkIndexes()[0]>0) continue;
2424 //Remove tracks with undefined properties - seems
2425 if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ?
2427 for (Int_t i=first; i<last; i++) {
2428 Int_t index=pt->GetClusterIndex2(i);
2429 // if (index<0 || index&0x8000 ) continue;
2430 if (index<0 || index&0x8000 ) continue;
2431 AliTPCclusterMI *c= pt->GetClusterPointer(i);
2438 Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
2444 void AliTPCtrackerMI::DumpClusters(Int_t iter, TObjArray *trackArray)
2447 // Dump clusters after reco
2448 // signed and unsigned cluster can be visualized
2449 // 1. Unsign all cluster
2450 // 2. Sign all used clusters
2453 Int_t nseed = trackArray->GetEntries();
2454 for (Int_t i=0; i<nseed; i++){
2455 AliTPCseed *pt=(AliTPCseed*)trackArray->UncheckedAt(i);
2459 Bool_t isKink=pt->GetKinkIndex(0)!=0;
2460 for (Int_t j=0; j<160; ++j) {
2461 Int_t index=pt->GetClusterIndex2(j);
2462 if (index<0) continue;
2463 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2465 if (isKink) c->Use(100); // kink
2466 c->Use(10); // by default usage 10
2471 for (Int_t sec=0;sec<fkNIS;sec++){
2472 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
2473 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
2474 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++){
2475 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
2476 Float_t gx[3]; cl->GetGlobalXYZ(gx);
2477 (*fDebugStreamer)<<"clDump"<<
2485 cla = fInnerSec[sec][row].GetClusters2();
2486 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++){
2487 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
2488 Float_t gx[3]; cl->GetGlobalXYZ(gx);
2489 (*fDebugStreamer)<<"clDump"<<
2500 for (Int_t sec=0;sec<fkNOS;sec++){
2501 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
2502 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
2503 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++){
2505 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
2506 cl->GetGlobalXYZ(gx);
2507 (*fDebugStreamer)<<"clDump"<<
2515 cla = fOuterSec[sec][row].GetClusters2();
2516 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++){
2518 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
2519 cl->GetGlobalXYZ(gx);
2520 (*fDebugStreamer)<<"clDump"<<
2532 void AliTPCtrackerMI::UnsignClusters()
2535 // loop over all clusters and unsign them
2538 for (Int_t sec=0;sec<fkNIS;sec++){
2539 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
2540 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
2541 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
2542 // if (cl[icl].IsUsed(10))
2543 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2544 cla = fInnerSec[sec][row].GetClusters2();
2545 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
2546 //if (cl[icl].IsUsed(10))
2547 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2551 for (Int_t sec=0;sec<fkNOS;sec++){
2552 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
2553 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
2554 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
2555 //if (cl[icl].IsUsed(10))
2556 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2557 cla = fOuterSec[sec][row].GetClusters2();
2558 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
2559 //if (cl[icl].IsUsed(10))
2560 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2568 void AliTPCtrackerMI::SignClusters(const TObjArray * arr, Float_t fnumber, Float_t fdensity)
2571 //sign clusters to be "used"
2573 // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
2574 // loop over "primaries"
2588 Int_t nseed = arr->GetEntriesFast();
2589 for (Int_t i=0; i<nseed; i++) {
2590 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2594 if (!(pt->IsActive())) continue;
2595 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
2596 if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
2598 sumdens2+= dens*dens;
2599 sumn += pt->GetNumberOfClusters();
2600 sumn2 += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
2601 Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
2604 sumchi2 +=chi2*chi2;
2609 Float_t mdensity = 0.9;
2610 Float_t meann = 130;
2611 Float_t meanchi = 1;
2612 Float_t sdensity = 0.1;
2613 Float_t smeann = 10;
2614 Float_t smeanchi =0.4;
2618 mdensity = sumdens/sum;
2620 meanchi = sumchi/sum;
2622 sdensity = sumdens2/sum-mdensity*mdensity;
2624 sdensity = TMath::Sqrt(sdensity);
2628 smeann = sumn2/sum-meann*meann;
2630 smeann = TMath::Sqrt(smeann);
2634 smeanchi = sumchi2/sum - meanchi*meanchi;
2636 smeanchi = TMath::Sqrt(smeanchi);
2642 //REMOVE SHORT DELTAS or tracks going out of sensitive volume of TPC
2644 for (Int_t i=0; i<nseed; i++) {
2645 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2649 if (pt->GetBSigned()) continue;
2650 if (pt->GetBConstrain()) continue;
2651 //if (!(pt->IsActive())) continue;
2653 Int_t found,foundable,shared;
2654 pt->GetClusterStatistic(0,160,found, foundable,shared);
2655 if (shared/float(found)>0.3) {
2656 if (shared/float(found)>0.9 ){
2657 //MarkSeedFree( arr->RemoveAt(i) );
2662 Bool_t isok =kFALSE;
2663 if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
2665 if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
2667 if (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
2669 if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
2673 for (Int_t j=0; j<160; ++j) {
2674 Int_t index=pt->GetClusterIndex2(j);
2675 if (index<0) continue;
2676 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2678 //if (!(c->IsUsed(10))) c->Use();
2685 Double_t maxchi = meanchi+2.*smeanchi;
2687 for (Int_t i=0; i<nseed; i++) {
2688 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2692 //if (!(pt->IsActive())) continue;
2693 if (pt->GetBSigned()) continue;
2694 Double_t chi = pt->GetChi2()/pt->GetNumberOfClusters();
2695 if (chi>maxchi) continue;
2698 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
2700 //sign only tracks with enoug big density at the beginning
2702 if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue;
2705 Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
2706 Double_t minn = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
2708 // if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
2709 if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
2712 if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
2713 //Int_t noc=pt->GetNumberOfClusters();
2714 pt->SetBSigned(kTRUE);
2715 for (Int_t j=0; j<160; ++j) {
2717 Int_t index=pt->GetClusterIndex2(j);
2718 if (index<0) continue;
2719 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2721 // if (!(c->IsUsed(10))) c->Use();
2726 // gLastCheck = nseed;
2735 Int_t AliTPCtrackerMI::RefitInward(AliESDEvent *event)
2738 // back propagation of ESD tracks
2741 if (!event) return 0;
2742 const Int_t kMaxFriendTracks=2000;
2745 // extract correction object for multiplicity dependence of dEdx
2746 TObjArray * gainCalibArray = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(event->GetRunNumber());
2748 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
2750 AliFatal("Tranformations not in RefitInward");
2753 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
2754 const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
2755 Int_t nContribut = event->GetNumberOfTracks();
2756 TGraphErrors * graphMultDependenceDeDx = 0x0;
2757 if (recoParam && recoParam->GetUseMultiplicityCorrectionDedx() && gainCalibArray) {
2758 if (recoParam->GetUseTotCharge()) {
2759 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2761 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2767 //PrepareForProlongation(fSeeds,1);
2768 PropagateForward2(fSeeds);
2769 RemoveUsed2(fSeeds,0.4,0.4,20);
2771 TObjArray arraySeed(fSeeds->GetEntries());
2772 for (Int_t i=0;i<fSeeds->GetEntries();i++) {
2773 arraySeed.AddAt(fSeeds->At(i),i);
2775 SignShared(&arraySeed);
2776 // FindCurling(fSeeds, event,2); // find multi found tracks
2777 FindSplitted(fSeeds, event,2); // find multi found tracks
2778 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,2); // find multi found tracks
2781 Int_t nseed = fSeeds->GetEntriesFast();
2782 for (Int_t i=0;i<nseed;i++){
2783 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2784 if (!seed) continue;
2785 if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
2786 AliESDtrack *esd=event->GetTrack(i);
2788 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
2789 AliExternalTrackParam paramIn;
2790 AliExternalTrackParam paramOut;
2791 Int_t ncl = seed->RefitTrack(seed,¶mIn,¶mOut);
2792 if (AliTPCReconstructor::StreamLevel()>2) {
2793 (*fDebugStreamer)<<"RecoverIn"<<
2797 "pout.="<<¶mOut<<
2802 seed->Set(paramIn.GetX(),paramIn.GetAlpha(),paramIn.GetParameter(),paramIn.GetCovariance());
2803 seed->SetNumberOfClusters(ncl);
2807 seed->PropagateTo(fkParam->GetInnerRadiusLow());
2808 seed->UpdatePoints();
2809 AddCovariance(seed);
2810 MakeESDBitmaps(seed, esd);
2811 seed->CookdEdx(0.02,0.6);
2812 CookLabel(seed,0.1); //For comparison only
2814 if (AliTPCReconstructor::StreamLevel()>1 && seed!=0) {
2815 TTreeSRedirector &cstream = *fDebugStreamer;
2822 if (seed->GetNumberOfClusters()>15){
2823 esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
2824 esd->SetTPCPoints(seed->GetPoints());
2825 esd->SetTPCPointsF(seed->GetNFoundable());
2826 Int_t ndedx = seed->GetNCDEDX(0);
2827 Float_t sdedx = seed->GetSDEDX(0);
2828 Float_t dedx = seed->GetdEdx();
2829 // apply mutliplicity dependent dEdx correction if available
2830 if (graphMultDependenceDeDx) {
2831 Double_t corrGain = AliTPCcalibDButil::EvalGraphConst(graphMultDependenceDeDx, nContribut);
2832 dedx += (1 - corrGain)*50.; // MIP is normalized to 50
2834 esd->SetTPCsignal(dedx, sdedx, ndedx);
2836 // fill new dEdx information
2838 Double32_t signal[4];
2842 for(Int_t iarr=0;iarr<3;iarr++) {
2843 signal[iarr] = seed->GetDEDXregion(iarr+1);
2844 ncl[iarr] = seed->GetNCDEDX(iarr+1);
2845 nrows[iarr] = seed->GetNCDEDXInclThres(iarr+1);
2847 signal[3] = seed->GetDEDXregion(4);
2849 AliTPCdEdxInfo * infoTpcPid = new AliTPCdEdxInfo();
2850 infoTpcPid->SetTPCSignalRegionInfo(signal, ncl, nrows);
2851 esd->SetTPCdEdxInfo(infoTpcPid);
2853 // add seed to the esd track in Calib level
2855 Bool_t storeFriend = gRandom->Rndm()<(kMaxFriendTracks)/Float_t(nseed);
2856 if (AliTPCReconstructor::StreamLevel()>0 &&storeFriend){
2857 // RS: this is the only place where the seed is created not in the pool,
2858 // since it should belong to ESDevent
2859 AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE);
2860 esd->AddCalibObject(seedCopy);
2865 //printf("problem\n");
2868 //FindKinks(fSeeds,event);
2869 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(2,fSeeds);
2870 Info("RefitInward","Number of refitted tracks %d",ntracks);
2872 AliCosmicTracker::FindCosmic(event, kTRUE);
2878 Int_t AliTPCtrackerMI::PropagateBack(AliESDEvent *event)
2881 // back propagation of ESD tracks
2883 if (!event) return 0;
2888 PropagateBack(fSeeds);
2889 RemoveUsed2(fSeeds,0.4,0.4,20);
2890 //FindCurling(fSeeds, fEvent,1);
2891 FindSplitted(fSeeds, event,1); // find multi found tracks
2892 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,1); // find multi found tracks
2895 Int_t nseed = fSeeds->GetEntriesFast();
2897 for (Int_t i=0;i<nseed;i++){
2898 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2899 if (!seed) continue;
2900 if (seed->GetKinkIndex(0)<0) UpdateKinkQualityM(seed); // update quality informations for kinks
2901 seed->UpdatePoints();
2902 AddCovariance(seed);
2903 AliESDtrack *esd=event->GetTrack(i);
2904 if (!esd) continue; //never happen
2905 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
2906 AliExternalTrackParam paramIn;
2907 AliExternalTrackParam paramOut;
2908 Int_t ncl = seed->RefitTrack(seed,¶mIn,¶mOut);
2909 if (AliTPCReconstructor::StreamLevel()>2) {
2910 (*fDebugStreamer)<<"RecoverBack"<<
2914 "pout.="<<¶mOut<<
2919 seed->Set(paramOut.GetX(),paramOut.GetAlpha(),paramOut.GetParameter(),paramOut.GetCovariance());
2920 seed->SetNumberOfClusters(ncl);
2923 seed->CookdEdx(0.02,0.6);
2924 CookLabel(seed,0.1); //For comparison only
2925 if (seed->GetNumberOfClusters()>15){
2926 esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
2927 esd->SetTPCPoints(seed->GetPoints());
2928 esd->SetTPCPointsF(seed->GetNFoundable());
2929 Int_t ndedx = seed->GetNCDEDX(0);
2930 Float_t sdedx = seed->GetSDEDX(0);
2931 Float_t dedx = seed->GetdEdx();
2932 esd->SetTPCsignal(dedx, sdedx, ndedx);
2934 Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
2935 // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
2936 if (AliTPCReconstructor::StreamLevel()>1 && esd) {
2937 (*fDebugStreamer)<<"Cback"<<
2940 "EventNrInFile="<<eventnumber<<
2945 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(1,fSeeds);
2946 //FindKinks(fSeeds,event);
2947 Info("PropagateBack","Number of back propagated tracks %d",ntracks);
2955 Int_t AliTPCtrackerMI::PostProcess(AliESDEvent *event)
2958 // Post process events
2960 if (!event) return 0;
2963 // Set TPC event status
2966 // event affected by HV dip
2968 if(IsTPCHVDipEvent(event)) {
2969 event->ResetDetectorStatus(AliDAQ::kTPC);
2972 //printf("Status %d \n", event->IsDetectorOn(AliDAQ::kTPC));
2978 void AliTPCtrackerMI::DeleteSeeds()
2987 void AliTPCtrackerMI::ReadSeeds(const AliESDEvent *const event, Int_t direction)
2990 //read seeds from the event
2992 Int_t nentr=event->GetNumberOfTracks();
2994 Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
2999 fSeeds = new TObjArray(nentr);
3003 for (Int_t i=0; i<nentr; i++) {
3004 AliESDtrack *esd=event->GetTrack(i);
3005 ULong_t status=esd->GetStatus();
3006 if (!(status&AliESDtrack::kTPCin)) continue;
3007 AliTPCtrack t(*esd);
3008 t.SetNumberOfClusters(0);
3009 // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
3010 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(t/*,t.GetAlpha()*/);
3011 seed->SetPoolID(fLastSeedID);
3012 seed->SetUniqueID(esd->GetID());
3013 AddCovariance(seed); //add systematic ucertainty
3014 for (Int_t ikink=0;ikink<3;ikink++) {
3015 Int_t index = esd->GetKinkIndex(ikink);
3016 seed->GetKinkIndexes()[ikink] = index;
3017 if (index==0) continue;
3018 index = TMath::Abs(index);
3019 AliESDkink * kink = fEvent->GetKink(index-1);
3020 if (kink&&esd->GetKinkIndex(ikink)<0){
3021 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
3022 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,0);
3024 if (kink&&esd->GetKinkIndex(ikink)>0){
3025 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
3026 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,4);
3030 if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.);
3031 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
3032 //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
3033 // fSeeds->AddAt(0,i);
3034 // MarkSeedFree( seed );
3037 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) > 0 ) {
3038 Double_t par0[5],par1[5],alpha,x;
3039 esd->GetInnerExternalParameters(alpha,x,par0);
3040 esd->GetExternalParameters(x,par1);
3041 Double_t delta1 = TMath::Abs(par0[4]-par1[4])/(0.000000001+TMath::Abs(par0[4]+par1[4]));
3042 Double_t delta2 = TMath::Abs(par0[3]-par1[3]);
3044 if (esd->GetTRDncls()>0) trdchi2 = esd->GetTRDchi2()/esd->GetTRDncls();
3045 //reset covariance if suspicious
3046 if ( (delta1>0.1) || (delta2>0.006) ||trdchi2>7.)
3047 seed->ResetCovariance(10.);
3052 // rotate to the local coordinate system
3054 fSectors=fInnerSec; fN=fkNIS;
3055 Double_t alpha=seed->GetAlpha();
3056 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
3057 if (alpha < 0. ) alpha += 2.*TMath::Pi();
3058 Int_t ns=Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
3059 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
3060 alpha-=seed->GetAlpha();
3061 if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
3062 if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
3063 if (TMath::Abs(alpha) > 0.001) { // This should not happen normally
3064 AliWarning(Form("Rotating track over %f",alpha));
3065 if (!seed->Rotate(alpha)) {
3066 MarkSeedFree( seed );
3072 if (esd->GetKinkIndex(0)<=0){
3073 for (Int_t irow=0;irow<160;irow++){
3074 Int_t index = seed->GetClusterIndex2(irow);
3077 AliTPCclusterMI * cl = GetClusterMI(index);
3078 seed->SetClusterPointer(irow,cl);
3080 if ((index & 0x8000)==0){
3081 cl->Use(10); // accepted cluster
3083 cl->Use(6); // close cluster not accepted
3086 Info("ReadSeeds","Not found cluster");
3091 fSeeds->AddAt(seed,i);
3097 //_____________________________________________________________________________
3098 void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
3099 Float_t deltay, Int_t ddsec) {
3100 //-----------------------------------------------------------------
3101 // This function creates track seeds.
3102 // SEEDING WITH VERTEX CONSTRAIN
3103 //-----------------------------------------------------------------
3104 // cuts[0] - fP4 cut
3105 // cuts[1] - tan(phi) cut
3106 // cuts[2] - zvertex cut
3107 // cuts[3] - fP3 cut
3115 Double_t x[5], c[15];
3116 // Int_t di = i1-i2;
3118 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed();
3119 seed->SetPoolID(fLastSeedID);
3120 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
3121 Double_t cs=cos(alpha), sn=sin(alpha);
3123 // Double_t x1 =fOuterSec->GetX(i1);
3124 //Double_t xx2=fOuterSec->GetX(i2);
3126 Double_t x1 =GetXrow(i1);
3127 Double_t xx2=GetXrow(i2);
3129 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
3131 Int_t imiddle = (i2+i1)/2; //middle pad row index
3132 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
3133 const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
3137 const AliTPCtrackerRow& kr1=GetRow(ns,i1);
3138 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
3139 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
3142 // change cut on curvature if it can't reach this layer
3143 // maximal curvature set to reach it
3144 Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
3145 if (dvertexmax*0.5*cuts[0]>0.85){
3146 cuts[0] = 0.85/(dvertexmax*0.5+1.);
3148 Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
3151 if (deltay>0) ddsec = 0;
3152 // loop over clusters
3153 for (Int_t is=0; is < kr1; is++) {
3155 if (kr1[is]->IsUsed(10)) continue;
3156 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3157 //if (TMath::Abs(y1)>ymax) continue;
3159 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3161 // find possible directions
3162 Float_t anglez = (z1-z3)/(x1-x3);
3163 Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
3166 //find rotation angles relative to line given by vertex and point 1
3167 Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
3168 Double_t dvertex = TMath::Sqrt(dvertex2);
3169 Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
3170 Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
3173 // loop over 2 sectors
3179 Double_t dddz1=0; // direction of delta inclination in z axis
3186 for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
3187 Int_t sec2 = sec + dsec;
3189 // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
3190 //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
3191 AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
3192 AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
3193 Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
3194 Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
3196 // rotation angles to p1-p3
3197 Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
3198 Double_t x2, y2, z2;
3200 // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
3203 Double_t dxx0 = (xx2-x3)*cs13r;
3204 Double_t dyy0 = (xx2-x3)*sn13r;
3205 for (Int_t js=index1; js < index2; js++) {
3206 const AliTPCclusterMI *kcl = kr2[js];
3207 if (kcl->IsUsed(10)) continue;
3209 //calcutate parameters
3211 Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
3213 if (TMath::Abs(yy0)<0.000001) continue;
3214 Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
3215 Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
3216 Double_t r02 = (0.25+y0*y0)*dvertex2;
3217 //curvature (radius) cut
3218 if (r02<r2min) continue;
3222 Double_t c0 = 1/TMath::Sqrt(r02);
3226 //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
3227 //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
3228 Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
3229 Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
3232 Double_t z0 = kcl->GetZ();
3233 Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
3234 if (TMath::Abs(zzzz2-z0)>0.5) continue;
3237 Double_t dip = (z1-z0)*c0/dfi1;
3238 Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
3249 x2= xx2*cs-y2*sn*dsec;
3250 y2=+xx2*sn*dsec+y2*cs;
3260 // do we have cluster at the middle ?
3262 GetProlongation(x1,xm,x,ym,zm);
3264 AliTPCclusterMI * cm=0;
3265 if (TMath::Abs(ym)-ymaxm<0){
3266 cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3267 if ((!cm) || (cm->IsUsed(10))) {
3272 // rotate y1 to system 0
3273 // get state vector in rotated system
3274 Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
3275 Double_t xr2 = x0*cs+yr1*sn*dsec;
3276 Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3278 GetProlongation(xx2,xm,xr,ym,zm);
3279 if (TMath::Abs(ym)-ymaxm<0){
3280 cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3281 if ((!cm) || (cm->IsUsed(10))) {
3288 // Double_t dym = 0;
3289 // Double_t dzm = 0;
3291 // dym = ym - cm->GetY();
3292 // dzm = zm - cm->GetZ();
3299 Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
3300 Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
3301 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
3302 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3303 //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
3305 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3306 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3307 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3308 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3309 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3310 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3312 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3313 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3314 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3315 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
3319 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3320 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3321 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3322 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3323 c[13]=f30*sy1*f40+f32*sy2*f42;
3324 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3326 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3328 UInt_t index=kr1.GetIndex(is);
3329 if (seed) {MarkSeedFree(seed); seed = 0;}
3330 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, ns*alpha+shift, x, c, index);
3331 seed->SetPoolID(fLastSeedID);
3332 track->SetIsSeeding(kTRUE);
3333 track->SetSeed1(i1);
3334 track->SetSeed2(i2);
3335 track->SetSeedType(3);
3339 FollowProlongation(*track, (i1+i2)/2,1);
3340 Int_t foundable,found,shared;
3341 track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
3342 if ((found<0.55*foundable) || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
3343 MarkSeedFree(seed); seed = 0;
3349 FollowProlongation(*track, i2,1);
3353 track->SetBConstrain(1);
3354 // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
3355 track->SetLastPoint(i1); // first cluster in track position
3356 track->SetFirstPoint(track->GetLastPoint());
3358 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3359 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3360 track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
3361 MarkSeedFree(seed); seed = 0;
3365 // Z VERTEX CONDITION
3366 Double_t zv, bz=GetBz();
3367 if ( !track->GetZAt(0.,bz,zv) ) continue;
3368 if (TMath::Abs(zv-z3)>cuts[2]) {
3369 FollowProlongation(*track, TMath::Max(i2-20,0));
3370 if ( !track->GetZAt(0.,bz,zv) ) continue;
3371 if (TMath::Abs(zv-z3)>cuts[2]){
3372 FollowProlongation(*track, TMath::Max(i2-40,0));
3373 if ( !track->GetZAt(0.,bz,zv) ) continue;
3374 if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
3375 // make seed without constrain
3376 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
3377 FollowProlongation(*track2, i2,1);
3378 track2->SetBConstrain(kFALSE);
3379 track2->SetSeedType(1);
3380 arr->AddLast(track2);
3381 MarkSeedFree( seed ); seed = 0;
3385 MarkSeedFree( seed ); seed = 0;
3392 track->SetSeedType(0);
3393 arr->AddLast(track); // note, track is seed, don't free the seed
3394 seed = new( NextFreeSeed() ) AliTPCseed;
3395 seed->SetPoolID(fLastSeedID);
3397 // don't consider other combinations
3398 if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
3404 Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
3406 if (seed) MarkSeedFree( seed );
3410 void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
3415 //-----------------------------------------------------------------
3416 // This function creates track seeds.
3417 //-----------------------------------------------------------------
3418 // cuts[0] - fP4 cut
3419 // cuts[1] - tan(phi) cut
3420 // cuts[2] - zvertex cut
3421 // cuts[3] - fP3 cut
3431 Double_t x[5], c[15];
3433 // make temporary seed
3434 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
3435 seed->SetPoolID(fLastSeedID);
3436 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3437 // Double_t cs=cos(alpha), sn=sin(alpha);
3442 Double_t x1 = GetXrow(i1-1);
3443 const AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
3444 Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
3446 Double_t x1p = GetXrow(i1);
3447 const AliTPCtrackerRow& kr1p=GetRow(sec,i1);
3449 Double_t x1m = GetXrow(i1-2);
3450 const AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
3453 //last 3 padrow for seeding
3454 AliTPCtrackerRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
3455 Double_t x3 = GetXrow(i1-7);
3456 // Double_t y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;
3458 AliTPCtrackerRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
3459 Double_t x3p = GetXrow(i1-6);
3461 AliTPCtrackerRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
3462 Double_t x3m = GetXrow(i1-8);
3467 Int_t im = i1-4; //middle pad row index
3468 Double_t xm = GetXrow(im); // radius of middle pad-row
3469 const AliTPCtrackerRow& krm=GetRow(sec,im); //middle pad -row
3470 // Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;
3473 Double_t deltax = x1-x3;
3474 Double_t dymax = deltax*cuts[1];
3475 Double_t dzmax = deltax*cuts[3];
3477 // loop over clusters
3478 for (Int_t is=0; is < kr1; is++) {
3480 if (kr1[is]->IsUsed(10)) continue;
3481 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3483 if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3485 Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
3486 Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
3492 for (Int_t js=index1; js < index2; js++) {
3493 const AliTPCclusterMI *kcl = kr3[js];
3494 if (kcl->IsUsed(10)) continue;
3496 // apply angular cuts
3497 if (TMath::Abs(y1-y3)>dymax) continue;
3500 if (TMath::Abs(z1-z3)>dzmax) continue;
3502 Double_t angley = (y1-y3)/(x1-x3);
3503 Double_t anglez = (z1-z3)/(x1-x3);
3505 Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
3506 Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
3508 Double_t yyym = angley*(xm-x1)+y1;
3509 Double_t zzzm = anglez*(xm-x1)+z1;
3511 const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
3513 if (kcm->IsUsed(10)) continue;
3515 erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
3516 errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
3523 // look around first
3524 const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
3530 if (kc1m->IsUsed(10)) used++;
3532 const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
3538 if (kc1p->IsUsed(10)) used++;
3540 if (used>1) continue;
3541 if (found<1) continue;
3545 const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
3551 if (kc3m->IsUsed(10)) used++;
3555 const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
3561 if (kc3p->IsUsed(10)) used++;
3565 if (used>1) continue;
3566 if (found<3) continue;
3576 x[4]=F1(x1,y1,x2,y2,x3,y3);
3577 //if (TMath::Abs(x[4]) >= cuts[0]) continue;
3580 x[2]=F2(x1,y1,x2,y2,x3,y3);
3583 x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
3584 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3588 Double_t sy1=0.1, sz1=0.1;
3589 Double_t sy2=0.1, sz2=0.1;
3590 Double_t sy3=0.1, sy=0.1, sz=0.1;
3592 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3593 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3594 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3595 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3596 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3597 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3599 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3600 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3601 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3602 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
3606 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3607 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3608 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3609 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3610 c[13]=f30*sy1*f40+f32*sy2*f42;
3611 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3613 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3615 index=kr1.GetIndex(is);
3616 if (seed) {MarkSeedFree( seed ); seed = 0;}
3617 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, sec*alpha+shift, x, c, index);
3618 seed->SetPoolID(fLastSeedID);
3620 track->SetIsSeeding(kTRUE);
3623 FollowProlongation(*track, i1-7,1);
3624 if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
3625 track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
3626 MarkSeedFree( seed ); seed = 0;
3632 FollowProlongation(*track, i2,1);
3633 track->SetBConstrain(0);
3634 track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
3635 track->SetFirstPoint(track->GetLastPoint());
3637 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3638 track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
3639 track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
3640 MarkSeedFree( seed ); seed = 0;
3645 FollowProlongation(*track, TMath::Max(i2-10,0),1);
3646 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
3647 FollowProlongation(*track2, i2,1);
3648 track2->SetBConstrain(kFALSE);
3649 track2->SetSeedType(4);
3650 arr->AddLast(track2);
3651 MarkSeedFree( seed ); seed = 0;
3655 //arr->AddLast(track);
3656 //seed = new AliTPCseed;
3662 Info("MakeSeeds5","\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
3664 if (seed) MarkSeedFree(seed);
3668 //_____________________________________________________________________________
3669 void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
3670 Float_t deltay, Bool_t /*bconstrain*/) {
3671 //-----------------------------------------------------------------
3672 // This function creates track seeds - without vertex constraint
3673 //-----------------------------------------------------------------
3674 // cuts[0] - fP4 cut - not applied
3675 // cuts[1] - tan(phi) cut
3676 // cuts[2] - zvertex cut - not applied
3677 // cuts[3] - fP3 cut
3687 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3688 // Double_t cs=cos(alpha), sn=sin(alpha);
3689 Int_t row0 = (i1+i2)/2;
3690 Int_t drow = (i1-i2)/2;
3691 const AliTPCtrackerRow& kr0=fSectors[sec][row0];
3692 AliTPCtrackerRow * kr=0;
3694 AliTPCpolyTrack polytrack;
3695 Int_t nclusters=fSectors[sec][row0];
3696 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
3697 seed->SetPoolID(fLastSeedID);
3702 for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
3704 Int_t nfoundable =0;
3705 for (Int_t iter =1; iter<2; iter++){ //iterations
3706 const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
3707 const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];
3708 const AliTPCclusterMI * cl= kr0[is];
3710 if (cl->IsUsed(10)) {
3716 Double_t x = kr0.GetX();
3717 // Initialization of the polytrack
3722 Double_t y0= cl->GetY();
3723 Double_t z0= cl->GetZ();
3727 Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
3728 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
3730 erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
3731 errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
3732 polytrack.AddPoint(x,y0,z0,erry, errz);
3735 if (cl->IsUsed(10)) sumused++;
3738 Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
3739 Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
3742 AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
3743 if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
3744 erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
3745 errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
3746 if (cl1->IsUsed(10)) sumused++;
3747 polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
3751 AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
3753 erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
3754 errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
3755 if (cl2->IsUsed(10)) sumused++;
3756 polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
3759 if (sumused>0) continue;
3761 polytrack.UpdateParameters();
3767 nfoundable = polytrack.GetN();
3768 nfound = nfoundable;
3770 for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
3771 Float_t maxdist = 0.8*(1.+3./(ddrow));
3772 for (Int_t delta = -1;delta<=1;delta+=2){
3773 Int_t row = row0+ddrow*delta;
3774 kr = &(fSectors[sec][row]);
3775 Double_t xn = kr->GetX();
3776 Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
3777 polytrack.GetFitPoint(xn,yn,zn);
3778 if (TMath::Abs(yn)>ymax1) continue;
3780 AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
3782 Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
3785 erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3786 errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3787 if (cln->IsUsed(10)) {
3788 // printf("used\n");
3796 polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
3801 if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
3802 polytrack.UpdateParameters();
3805 if ( (sumused>3) || (sumused>0.5*nfound)) {
3806 //printf("sumused %d\n",sumused);
3811 polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
3812 AliTPCpolyTrack track2;
3814 polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
3815 if (track2.GetN()<0.5*nfoundable) continue;
3818 if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
3820 // test seed with and without constrain
3821 for (Int_t constrain=0; constrain<=0;constrain++){
3822 // add polytrack candidate
3824 Double_t x[5], c[15];
3825 Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
3826 track2.GetBoundaries(x3,x1);
3828 track2.GetFitPoint(x1,y1,z1);
3829 track2.GetFitPoint(x2,y2,z2);
3830 track2.GetFitPoint(x3,y3,z3);
3832 //is track pointing to the vertex ?
3835 polytrack.GetFitPoint(x0,y0,z0);
3848 x[4]=F1(x1,y1,x2,y2,x3,y3);
3850 // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
3851 x[2]=F2(x1,y1,x2,y2,x3,y3);
3853 //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
3854 //x[3]=F3(x1,y1,x2,y2,z1,z2);
3855 x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
3856 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3859 Double_t sy =0.1, sz =0.1;
3860 Double_t sy1=0.02, sz1=0.02;
3861 Double_t sy2=0.02, sz2=0.02;
3865 sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3868 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3869 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3870 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3871 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3872 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3873 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3875 Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
3876 Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
3877 Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
3878 Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
3883 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3884 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3885 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3886 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3887 c[13]=f30*sy1*f40+f32*sy2*f42;
3888 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3890 //Int_t row1 = fSectors->GetRowNumber(x1);
3891 Int_t row1 = GetRowNumber(x1);
3895 if (seed) {MarkSeedFree( seed ); seed = 0;}
3896 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1,sec*alpha+shift,x,c,index);
3897 seed->SetPoolID(fLastSeedID);
3898 track->SetIsSeeding(kTRUE);
3899 Int_t rc=FollowProlongation(*track, i2);
3900 if (constrain) track->SetBConstrain(1);
3902 track->SetBConstrain(0);
3903 track->SetLastPoint(row1+fInnerSec->GetNRows()); // first cluster in track position
3904 track->SetFirstPoint(track->GetLastPoint());
3906 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3907 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3908 track->GetNShared()>0.4*track->GetNumberOfClusters()) {
3909 MarkSeedFree( seed ); seed = 0;
3912 arr->AddLast(track); // track IS seed, don't free seed
3913 seed = new( NextFreeSeed() ) AliTPCseed;
3914 seed->SetPoolID(fLastSeedID);
3918 } // if accepted seed
3921 Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
3923 if (seed) MarkSeedFree( seed );
3927 AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *const track, Float_t r0, Float_t r1, Float_t r2)
3931 //reseed using track points
3932 Int_t p0 = int(r0*track->GetNumberOfClusters()); // point 0
3933 Int_t p1 = int(r1*track->GetNumberOfClusters());
3934 Int_t p2 = int(r2*track->GetNumberOfClusters()); // last point
3936 Double_t x0[3],x1[3],x2[3];
3937 for (Int_t i=0;i<3;i++){
3943 // find track position at given ratio of the length
3944 Int_t sec0=0, sec1=0, sec2=0;
3947 for (Int_t i=0;i<160;i++){
3948 if (track->GetClusterPointer(i)){
3950 AliTPCTrackerPoint *trpoint =track->GetTrackPoint(i);
3951 if ( (index<p0) || x0[0]<0 ){
3952 if (trpoint->GetX()>1){
3953 clindex = track->GetClusterIndex2(i);
3955 x0[0] = trpoint->GetX();
3956 x0[1] = trpoint->GetY();
3957 x0[2] = trpoint->GetZ();
3958 sec0 = ((clindex&0xff000000)>>24)%18;
3963 if ( (index<p1) &&(trpoint->GetX()>1)){
3964 clindex = track->GetClusterIndex2(i);
3966 x1[0] = trpoint->GetX();
3967 x1[1] = trpoint->GetY();
3968 x1[2] = trpoint->GetZ();
3969 sec1 = ((clindex&0xff000000)>>24)%18;
3972 if ( (index<p2) &&(trpoint->GetX()>1)){
3973 clindex = track->GetClusterIndex2(i);
3975 x2[0] = trpoint->GetX();
3976 x2[1] = trpoint->GetY();
3977 x2[2] = trpoint->GetZ();
3978 sec2 = ((clindex&0xff000000)>>24)%18;
3985 Double_t alpha, cs,sn, xx2,yy2;
3987 alpha = (sec1-sec2)*fSectors->GetAlpha();
3988 cs = TMath::Cos(alpha);
3989 sn = TMath::Sin(alpha);
3990 xx2= x1[0]*cs-x1[1]*sn;
3991 yy2= x1[0]*sn+x1[1]*cs;
3995 alpha = (sec0-sec2)*fSectors->GetAlpha();
3996 cs = TMath::Cos(alpha);
3997 sn = TMath::Sin(alpha);
3998 xx2= x0[0]*cs-x0[1]*sn;
3999 yy2= x0[0]*sn+x0[1]*cs;
4005 Double_t x[5],c[15];
4009 x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
4010 // if (x[4]>1) return 0;
4011 x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
4012 x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
4013 //if (TMath::Abs(x[3]) > 2.2) return 0;
4014 //if (TMath::Abs(x[2]) > 1.99) return 0;
4016 Double_t sy =0.1, sz =0.1;
4018 Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
4019 Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
4020 Double_t sy3=0.01+track->GetSigmaY2();
4022 Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
4023 Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
4024 Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
4025 Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
4026 Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
4027 Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
4029 Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
4030 Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
4031 Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
4032 Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
4037 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4038 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4039 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4040 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4041 c[13]=f30*sy1*f40+f32*sy2*f42;
4042 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4044 // Int_t row1 = fSectors->GetRowNumber(x2[0]);
4045 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4046 seed->SetPoolID(fLastSeedID);
4047 // Double_t y0,z0,y1,z1, y2,z2;
4048 //seed->GetProlongation(x0[0],y0,z0);
4049 // seed->GetProlongation(x1[0],y1,z1);
4050 //seed->GetProlongation(x2[0],y2,z2);
4052 seed->SetLastPoint(pp2);
4053 seed->SetFirstPoint(pp2);
4060 AliTPCseed *AliTPCtrackerMI::ReSeed(const AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
4064 //reseed using founded clusters
4066 // Find the number of clusters
4067 Int_t nclusters = 0;
4068 for (Int_t irow=0;irow<160;irow++){
4069 if (track->GetClusterIndex(irow)>0) nclusters++;
4073 ipos[0] = TMath::Max(int(r0*nclusters),0); // point 0 cluster
4074 ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1); //
4075 ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1); // last point
4078 Double_t xyz[3][3]={{0}};
4079 Int_t row[3]={0},sec[3]={0,0,0};
4081 // find track row position at given ratio of the length
4083 for (Int_t irow=0;irow<160;irow++){
4084 if (track->GetClusterIndex2(irow)<0) continue;
4086 for (Int_t ipoint=0;ipoint<3;ipoint++){
4087 if (index<=ipos[ipoint]) row[ipoint] = irow;
4091 //Get cluster and sector position
4092 for (Int_t ipoint=0;ipoint<3;ipoint++){
4093 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4094 AliTPCclusterMI * cl = GetClusterMI(clindex);
4097 // AliTPCclusterMI * cl = GetClusterMI(clindex);
4100 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4101 xyz[ipoint][0] = GetXrow(row[ipoint]);
4102 xyz[ipoint][1] = cl->GetY();
4103 xyz[ipoint][2] = cl->GetZ();
4107 // Calculate seed state vector and covariance matrix
4109 Double_t alpha, cs,sn, xx2,yy2;
4111 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4112 cs = TMath::Cos(alpha);
4113 sn = TMath::Sin(alpha);
4114 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4115 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4119 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4120 cs = TMath::Cos(alpha);
4121 sn = TMath::Sin(alpha);
4122 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4123 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4129 Double_t x[5],c[15];
4133 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4134 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4135 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4137 Double_t sy =0.1, sz =0.1;
4139 Double_t sy1=0.2, sz1=0.2;
4140 Double_t sy2=0.2, sz2=0.2;
4143 Double_t f40=(F1(xyz[2][0],xyz[2][1]+sy,xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1])-x[4])/sy;
4144 Double_t f42=(F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1]+sy,xyz[0][0],xyz[0][1])-x[4])/sy;
4145 Double_t f43=(F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]+sy)-x[4])/sy;
4146 Double_t f20=(F2(xyz[2][0],xyz[2][1]+sy,xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1])-x[2])/sy;
4147 Double_t f22=(F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1]+sy,xyz[0][0],xyz[0][1])-x[2])/sy;
4148 Double_t f23=(F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]+sy)-x[2])/sy;
4150 Double_t f30=(F3(xyz[2][0],xyz[2][1]+sy,xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2])-x[3])/sy;
4151 Double_t f31=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2]+sz,xyz[0][2])-x[3])/sz;
4152 Double_t f32=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1]+sy,xyz[2][2],xyz[0][2])-x[3])/sy;
4153 Double_t f34=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2]+sz)-x[3])/sz;
4158 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4159 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4160 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4161 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4162 c[13]=f30*sy1*f40+f32*sy2*f42;
4163 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4165 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
4166 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4167 seed->SetPoolID(fLastSeedID);
4168 seed->SetLastPoint(row[2]);
4169 seed->SetFirstPoint(row[2]);
4174 AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
4178 //reseed using founded clusters
4181 Int_t row[3]={0,0,0};
4182 Int_t sec[3]={0,0,0};
4184 // forward direction
4186 for (Int_t irow=r0;irow<160;irow++){
4187 if (track->GetClusterIndex(irow)>0){
4192 for (Int_t irow=160;irow>r0;irow--){
4193 if (track->GetClusterIndex(irow)>0){
4198 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4199 if (track->GetClusterIndex(irow)>0){
4207 for (Int_t irow=0;irow<r0;irow++){
4208 if (track->GetClusterIndex(irow)>0){
4213 for (Int_t irow=r0;irow>0;irow--){
4214 if (track->GetClusterIndex(irow)>0){
4219 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4220 if (track->GetClusterIndex(irow)>0){
4227 if ((row[2]-row[0])<20) return 0;
4228 if (row[1]==0) return 0;
4231 //Get cluster and sector position
4232 for (Int_t ipoint=0;ipoint<3;ipoint++){
4233 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4234 AliTPCclusterMI * cl = GetClusterMI(clindex);
4237 // AliTPCclusterMI * cl = GetClusterMI(clindex);
4240 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4241 xyz[ipoint][0] = GetXrow(row[ipoint]);
4242 AliTPCTrackerPoint * point = track->GetTrackPoint(row[ipoint]);
4243 if (point&&ipoint<2){
4245 xyz[ipoint][1] = point->GetY();
4246 xyz[ipoint][2] = point->GetZ();
4249 xyz[ipoint][1] = cl->GetY();
4250 xyz[ipoint][2] = cl->GetZ();
4257 // Calculate seed state vector and covariance matrix
4259 Double_t alpha, cs,sn, xx2,yy2;
4261 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4262 cs = TMath::Cos(alpha);
4263 sn = TMath::Sin(alpha);
4264 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4265 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4269 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4270 cs = TMath::Cos(alpha);
4271 sn = TMath::Sin(alpha);
4272 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4273 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4279 Double_t x[5],c[15];
4283 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4284 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4285 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4287 Double_t sy =0.1, sz =0.1;
4289 Double_t sy1=0.2, sz1=0.2;
4290 Double_t sy2=0.2, sz2=0.2;
4293 Double_t f40=(F1(xyz[2][0],xyz[2][1]+sy,xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1])-x[4])/sy;
4294 Double_t f42=(F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1]+sy,xyz[0][0],xyz[0][1])-x[4])/sy;
4295 Double_t f43=(F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]+sy)-x[4])/sy;
4296 Double_t f20=(F2(xyz[2][0],xyz[2][1]+sy,xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1])-x[2])/sy;
4297 Double_t f22=(F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1]+sy,xyz[0][0],xyz[0][1])-x[2])/sy;
4298 Double_t f23=(F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]+sy)-x[2])/sy;
4300 Double_t f30=(F3(xyz[2][0],xyz[2][1]+sy,xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2])-x[3])/sy;
4301 Double_t f31=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2]+sz,xyz[0][2])-x[3])/sz;
4302 Double_t f32=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1]+sy,xyz[2][2],xyz[0][2])-x[3])/sy;
4303 Double_t f34=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2]+sz)-x[3])/sz;
4308 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4309 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4310 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4311 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4312 c[13]=f30*sy1*f40+f32*sy2*f42;
4313 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4315 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
4316 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4317 seed->SetPoolID(fLastSeedID);
4318 seed->SetLastPoint(row[2]);
4319 seed->SetFirstPoint(row[2]);
4320 for (Int_t i=row[0];i<row[2];i++){
4321 seed->SetClusterIndex(i, track->GetClusterIndex(i));
4329 void AliTPCtrackerMI::FindMultiMC(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
4332 // find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
4334 // Use AliTPCReconstructor::StreamLevel()>2 if you want to tune parameters - cuts
4336 // Two reasons to have multiple find tracks
4337 // 1. Curling tracks can be find more than once
4338 // 2. Splitted tracks
4339 // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
4340 // b.) Edge effect on the sector boundaries
4343 // Algorithm done in 2 phases - because of CPU consumption
4344 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4346 // Algorihm for curling tracks sign:
4347 // 1 phase -makes a very rough fast cuts to minimize combinatorics
4348 // a.) opposite sign
4349 // b.) one of the tracks - not pointing to the primary vertex -
4350 // c.) delta tan(theta)
4352 // 2 phase - calculates DCA between tracks - time consument
4357 // General cuts - for splitted tracks and for curling tracks
4359 const Float_t kMaxdPhi = 0.2; // maximal distance in phi
4361 // Curling tracks cuts
4366 Int_t nentries = array->GetEntriesFast();
4367 AliHelix *helixes = new AliHelix[nentries];
4368 Float_t *xm = new Float_t[nentries];
4369 Float_t *dz0 = new Float_t[nentries];
4370 Float_t *dz1 = new Float_t[nentries];
4376 // Find track COG in x direction - point with best defined parameters
4378 for (Int_t i=0;i<nentries;i++){
4379 AliTPCseed* track = (AliTPCseed*)array->At(i);
4380 if (!track) continue;
4381 track->SetCircular(0);
4382 new (&helixes[i]) AliHelix(*track);
4386 track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
4389 for (Int_t icl=0; icl<160; icl++){
4390 AliTPCclusterMI * cl = track->GetClusterPointer(icl);
4396 if (ncl>0) xm[i]/=Float_t(ncl);
4399 for (Int_t i0=0;i0<nentries;i0++){
4400 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4401 if (!track0) continue;
4402 Float_t xc0 = helixes[i0].GetHelix(6);
4403 Float_t yc0 = helixes[i0].GetHelix(7);
4404 Float_t r0 = helixes[i0].GetHelix(8);
4405 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4406 Float_t fi0 = TMath::ATan2(yc0,xc0);
4408 for (Int_t i1=i0+1;i1<nentries;i1++){
4409 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4410 if (!track1) continue;
4411 Int_t lab0=track0->GetLabel();
4412 Int_t lab1=track1->GetLabel();
4413 if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
4415 Float_t xc1 = helixes[i1].GetHelix(6);
4416 Float_t yc1 = helixes[i1].GetHelix(7);
4417 Float_t r1 = helixes[i1].GetHelix(8);
4418 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4419 Float_t fi1 = TMath::ATan2(yc1,xc1);
4421 Float_t dfi = fi0-fi1;
4424 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
4425 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
4426 if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
4428 // if short tracks with undefined sign
4429 fi1 = -TMath::ATan2(yc1,-xc1);
4432 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4435 // debug stream to tune "fast cuts"
4437 Double_t dist[3]; // distance at X
4438 Double_t mdist[3]={0,0,0}; // mean distance X+-40cm
4439 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
4440 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4441 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
4442 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4443 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
4444 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4445 for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
4449 for (Int_t icl=0; icl<160; icl++){
4450 AliTPCclusterMI * cl0 = track0->GetClusterPointer(icl);
4451 AliTPCclusterMI * cl1 = track1->GetClusterPointer(icl);
4454 if (cl0==cl1) sums++;
4458 if (AliTPCReconstructor::StreamLevel()>5) {
4459 TTreeSRedirector &cstream = *fDebugStreamer;
4464 "Tr0.="<<track0<< // seed0
4465 "Tr1.="<<track1<< // seed1
4466 "h0.="<<&helixes[i0]<<
4467 "h1.="<<&helixes[i1]<<
4469 "sum="<<sum<< //the sum of rows with cl in both
4470 "sums="<<sums<< //the sum of shared clusters
4471 "xm0="<<xm[i0]<< // the center of track
4472 "xm1="<<xm[i1]<< // the x center of track
4473 // General cut variables
4474 "dfi="<<dfi<< // distance in fi angle
4475 "dtheta="<<dtheta<< // distance int theta angle
4481 "dist0="<<dist[0]<< //distance x
4482 "dist1="<<dist[1]<< //distance y
4483 "dist2="<<dist[2]<< //distance z
4484 "mdist0="<<mdist[0]<< //distance x
4485 "mdist1="<<mdist[1]<< //distance y
4486 "mdist2="<<mdist[2]<< //distance z
4502 if (AliTPCReconstructor::StreamLevel()>1) {
4503 AliInfo("Time for curling tracks removal DEBUGGING MC");
4510 void AliTPCtrackerMI::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t /*iter*/){
4512 // Find Splitted tracks and remove the one with worst quality
4513 // Corresponding debug streamer to tune selections - "Splitted2"
4515 // 0. Sort tracks according quility
4516 // 1. Propagate the tracks to the reference radius
4517 // 2. Double_t loop to select close tracks (only to speed up process)
4518 // 3. Calculate cluster overlap ratio - and remove the track if bigger than a threshold
4519 // 4. Delete temporary parameters
4521 const Double_t xref=GetXrow(63); // reference radius -IROC/OROC boundary
4523 const Double_t kCutP1=10; // delta Z cut 10 cm
4524 const Double_t kCutP2=0.15; // delta snp(fi) cut 0.15
4525 const Double_t kCutP3=0.15; // delta tgl(theta) cut 0.15
4526 const Double_t kCutAlpha=0.15; // delta alpha cut
4527 Int_t firstpoint = 0;
4528 Int_t lastpoint = 160;
4530 Int_t nentries = array->GetEntriesFast();
4531 AliExternalTrackParam *params = new AliExternalTrackParam[nentries];
4537 //0. Sort tracks according quality
4538 //1. Propagate the ext. param to reference radius
4539 Int_t nseed = array->GetEntriesFast();
4540 if (nseed<=0) return;
4541 Float_t * quality = new Float_t[nseed];
4542 Int_t * indexes = new Int_t[nseed];
4543 for (Int_t i=0; i<nseed; i++) {
4544 AliTPCseed *pt=(AliTPCseed*)array->UncheckedAt(i);
4549 pt->UpdatePoints(); //select first last max dens points
4550 Float_t * points = pt->GetPoints();
4551 if (points[3]<0.8) quality[i] =-1;
4552 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
4553 //prefer high momenta tracks if overlaps
4554 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
4556 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),5.,kTRUE);
4557 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),1.,kTRUE);
4559 TMath::Sort(nseed,quality,indexes);
4561 // 3. Loop over pair of tracks
4563 for (Int_t i0=0; i0<nseed; i0++) {
4564 Int_t index0=indexes[i0];
4565 if (!(array->UncheckedAt(index0))) continue;
4566 AliTPCseed *s1 = (AliTPCseed*)array->UncheckedAt(index0);
4567 if (!s1->IsActive()) continue;
4568 AliExternalTrackParam &par0=params[index0];
4569 for (Int_t i1=i0+1; i1<nseed; i1++) {
4570 Int_t index1=indexes[i1];
4571 if (!(array->UncheckedAt(index1))) continue;
4572 AliTPCseed *s2 = (AliTPCseed*)array->UncheckedAt(index1);
4573 if (!s2->IsActive()) continue;
4574 if (s2->GetKinkIndexes()[0]!=0)
4575 if (s2->GetKinkIndexes()[0] == -s1->GetKinkIndexes()[0]) continue;
4576 AliExternalTrackParam &par1=params[index1];
4577 if (TMath::Abs(par0.GetParameter()[3]-par1.GetParameter()[3])>kCutP3) continue;
4578 if (TMath::Abs(par0.GetParameter()[1]-par1.GetParameter()[1])>kCutP1) continue;
4579 if (TMath::Abs(par0.GetParameter()[2]-par1.GetParameter()[2])>kCutP2) continue;
4580 Double_t dAlpha= TMath::Abs(par0.GetAlpha()-par1.GetAlpha());
4581 if (dAlpha>TMath::Pi()) dAlpha-=TMath::Pi();
4582 if (TMath::Abs(dAlpha)>kCutAlpha) continue;
4587 Int_t firstShared=lastpoint, lastShared=firstpoint;
4588 Int_t firstRow=lastpoint, lastRow=firstpoint;
4590 for (Int_t i=firstpoint;i<lastpoint;i++){
4591 if (s1->GetClusterIndex2(i)>0) nall0++;
4592 if (s2->GetClusterIndex2(i)>0) nall1++;
4593 if (s1->GetClusterIndex2(i)>0 && s2->GetClusterIndex2(i)>0) {
4594 if (i<firstRow) firstRow=i;
4595 if (i>lastRow) lastRow=i;
4597 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
4598 if (i<firstShared) firstShared=i;
4599 if (i>lastShared) lastShared=i;
4603 Double_t ratio0 = Float_t(sumShared)/Float_t(TMath::Min(nall0+1,nall1+1));
4604 Double_t ratio1 = Float_t(sumShared)/Float_t(TMath::Max(nall0+1,nall1+1));
4606 if( AliTPCReconstructor::StreamLevel()>1){
4607 TTreeSRedirector &cstream = *fDebugStreamer;
4608 Int_t n0=s1->GetNumberOfClusters();
4609 Int_t n1=s2->GetNumberOfClusters();
4610 Int_t n0F=s1->GetNFoundable();
4611 Int_t n1F=s2->GetNFoundable();
4612 Int_t lab0=s1->GetLabel();
4613 Int_t lab1=s2->GetLabel();
4615 cstream<<"Splitted2"<<
4616 "iter="<<fIteration<<
4617 "lab0="<<lab0<< // MC label if exist
4618 "lab1="<<lab1<< // MC label if exist
4621 "ratio0="<<ratio0<< // shared ratio
4622 "ratio1="<<ratio1<< // shared ratio
4623 "p0.="<<&par0<< // track parameters
4625 "s0.="<<s1<< // full seed
4627 "n0="<<n0<< // number of clusters track 0
4628 "n1="<<n1<< // number of clusters track 1
4629 "nall0="<<nall0<< // number of clusters track 0
4630 "nall1="<<nall1<< // number of clusters track 1
4631 "n0F="<<n0F<< // number of findable
4632 "n1F="<<n1F<< // number of findable
4633 "shared="<<sumShared<< // number of shared clusters
4634 "firstS="<<firstShared<< // first and the last shared row
4635 "lastS="<<lastShared<<
4636 "firstRow="<<firstRow<< // first and the last row with cluster
4637 "lastRow="<<lastRow<< //
4641 // remove track with lower quality
4643 if (ratio0>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(0) ||
4644 ratio1>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(1)){
4648 MarkSeedFree( array->RemoveAt(index1) );
4653 // 4. Delete temporary array
4663 void AliTPCtrackerMI::FindCurling(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
4666 // find Curling tracks
4667 // Use AliTPCReconstructor::StreamLevel()>1 if you want to tune parameters - cuts
4670 // Algorithm done in 2 phases - because of CPU consumption
4671 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4672 // see detal in MC part what can be used to cut
4676 const Float_t kMaxC = 400; // maximal curvature to of the track
4677 const Float_t kMaxdTheta = 0.15; // maximal distance in theta
4678 const Float_t kMaxdPhi = 0.15; // maximal distance in phi
4679 const Float_t kPtRatio = 0.3; // ratio between pt
4680 const Float_t kMinDCAR = 2.; // distance to the primary vertex in r - see cpipe cut
4683 // Curling tracks cuts
4686 const Float_t kMaxDeltaRMax = 40; // distance in outer radius
4687 const Float_t kMaxDeltaRMin = 5.; // distance in lower radius - see cpipe cut
4688 const Float_t kMinAngle = 2.9; // angle between tracks
4689 const Float_t kMaxDist = 5; // biggest distance
4691 // The cuts can be tuned using the "MC information stored in Multi tree ==> see FindMultiMC
4694 TCut csign("csign","Tr0.fP[4]*Tr1.fP[4]<0"); //opposite sign
4695 TCut cmax("cmax","abs(Tr0.GetC())>1/400");
4696 TCut cda("cda","sqrt(dtheta^2+dfi^2)<0.15");
4697 TCut ccratio("ccratio","abs((Tr0.fP[4]+Tr1.fP[4])/(abs(Tr0.fP[4])+abs(Tr1.fP[4])))<0.3");
4698 TCut cpipe("cpipe", "min(abs(r0-rc0),abs(r1-rc1))>5");
4700 TCut cdrmax("cdrmax","abs(abs(rc0+r0)-abs(rc1+r1))<40")
4701 TCut cdrmin("cdrmin","abs(abs(rc0+r0)-abs(rc1+r1))<10")
4703 Multi->Draw("dfi","iter==0"+csign+cmax+cda+ccratio); ~94% of curling tracks fulfill
4704 Multi->Draw("min(abs(r0-rc0),abs(r1-rc1))","iter==0&&abs(lab1)==abs(lab0)"+csign+cmax+cda+ccratio+cpipe+cdrmin+cdrmax); //80%
4706 Curling2->Draw("dfi","iter==0&&abs(lab0)==abs(lab1)"+csign+cmax+cdtheta+cdfi+ccratio)
4712 Int_t nentries = array->GetEntriesFast();
4713 AliHelix *helixes = new AliHelix[nentries];
4714 for (Int_t i=0;i<nentries;i++){
4715 AliTPCseed* track = (AliTPCseed*)array->At(i);
4716 if (!track) continue;
4717 track->SetCircular(0);
4718 new (&helixes[i]) AliHelix(*track);
4724 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
4730 for (Int_t i0=0;i0<nentries;i0++){
4731 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4732 if (!track0) continue;
4733 if (TMath::Abs(track0->GetC())<1/kMaxC) continue;
4734 Float_t xc0 = helixes[i0].GetHelix(6);
4735 Float_t yc0 = helixes[i0].GetHelix(7);
4736 Float_t r0 = helixes[i0].GetHelix(8);
4737 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4738 Float_t fi0 = TMath::ATan2(yc0,xc0);
4740 for (Int_t i1=i0+1;i1<nentries;i1++){
4741 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4742 if (!track1) continue;
4743 if (TMath::Abs(track1->GetC())<1/kMaxC) continue;
4744 Float_t xc1 = helixes[i1].GetHelix(6);
4745 Float_t yc1 = helixes[i1].GetHelix(7);
4746 Float_t r1 = helixes[i1].GetHelix(8);
4747 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4748 Float_t fi1 = TMath::ATan2(yc1,xc1);
4750 Float_t dfi = fi0-fi1;
4753 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
4754 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
4755 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4759 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue; // not constrained
4760 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue; // not the same sign
4761 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>kMaxdTheta) continue; //distance in the Theta
4762 if ( TMath::Abs(dfi)>kMaxdPhi) continue; //distance in phi
4763 if ( TMath::Sqrt(dfi*dfi+dtheta*dtheta)>kMaxdPhi) continue; //common angular offset
4765 Float_t pt0 = track0->GetSignedPt();
4766 Float_t pt1 = track1->GetSignedPt();
4767 if ((TMath::Abs(pt0+pt1)/(TMath::Abs(pt0)+TMath::Abs(pt1)))>kPtRatio) continue;
4768 if ((iter==1) && TMath::Abs(TMath::Abs(rc0+r0)-TMath::Abs(rc1+r1))>kMaxDeltaRMax) continue;
4769 if ((iter!=1) &&TMath::Abs(TMath::Abs(rc0-r0)-TMath::Abs(rc1-r1))>kMaxDeltaRMin) continue;
4770 if (TMath::Min(TMath::Abs(rc0-r0),TMath::Abs(rc1-r1))<kMinDCAR) continue;
4773 // Now find closest approach
4777 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4778 if (npoints==0) continue;
4779 helixes[i0].GetClosestPhases(helixes[i1], phase);
4783 Double_t hangles[3];
4784 helixes[i0].Evaluate(phase[0][0],xyz0);
4785 helixes[i1].Evaluate(phase[0][1],xyz1);
4787 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
4788 Double_t deltah[2],deltabest;
4789 if (TMath::Abs(hangles[2])<kMinAngle) continue;
4793 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
4795 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
4796 if (deltah[1]<deltah[0]) ibest=1;
4798 deltabest = TMath::Sqrt(deltah[ibest]);
4799 helixes[i0].Evaluate(phase[ibest][0],xyz0);
4800 helixes[i1].Evaluate(phase[ibest][1],xyz1);
4801 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
4802 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
4804 if (deltabest>kMaxDist) continue;
4805 // if (mindcar+mindcaz<40 && (TMath::Abs(hangles[2])<kMinAngle ||deltabest>3)) continue;
4806 Bool_t sign =kFALSE;
4807 if (hangles[2]>kMinAngle) sign =kTRUE;
4810 // circular[i0] = kTRUE;
4811 // circular[i1] = kTRUE;
4812 if (track0->OneOverPt()<track1->OneOverPt()){
4813 track0->SetCircular(track0->GetCircular()+1);
4814 track1->SetCircular(track1->GetCircular()+2);
4817 track1->SetCircular(track1->GetCircular()+1);
4818 track0->SetCircular(track0->GetCircular()+2);
4821 if (AliTPCReconstructor::StreamLevel()>2){
4823 //debug stream to tune "fine" cuts
4824 Int_t lab0=track0->GetLabel();
4825 Int_t lab1=track1->GetLabel();
4826 TTreeSRedirector &cstream = *fDebugStreamer;
4827 cstream<<"Curling2"<<
4843 "npoints="<<npoints<<
4844 "hangles0="<<hangles[0]<<
4845 "hangles1="<<hangles[1]<<
4846 "hangles2="<<hangles[2]<<
4849 "radius="<<radiusbest<<
4850 "deltabest="<<deltabest<<
4851 "phase0="<<phase[ibest][0]<<
4852 "phase1="<<phase[ibest][1]<<
4860 if (AliTPCReconstructor::StreamLevel()>1) {
4861 AliInfo("Time for curling tracks removal");
4867 void AliTPCtrackerMI::FindKinks(TObjArray * array, AliESDEvent *esd)
4873 // RS something is wrong in this routine: not all seeds are assigned to daughters and mothers array, but they all are queried
4876 TObjArray *kinks= new TObjArray(10000);
4877 // TObjArray *v0s= new TObjArray(10000);
4878 Int_t nentries = array->GetEntriesFast();
4879 AliHelix *helixes = new AliHelix[nentries];
4880 Int_t *sign = new Int_t[nentries];
4881 Int_t *nclusters = new Int_t[nentries];
4882 Float_t *alpha = new Float_t[nentries];
4883 AliKink *kink = new AliKink();
4884 Int_t * usage = new Int_t[nentries];
4885 Float_t *zm = new Float_t[nentries];
4886 Float_t *z0 = new Float_t[nentries];
4887 Float_t *fim = new Float_t[nentries];
4888 Float_t *shared = new Float_t[nentries];
4889 Bool_t *circular = new Bool_t[nentries];
4890 Float_t *dca = new Float_t[nentries];
4891 //const AliESDVertex * primvertex = esd->GetVertex();
4893 // nentries = array->GetEntriesFast();
4898 for (Int_t i=0;i<nentries;i++){
4901 AliTPCseed* track = (AliTPCseed*)array->At(i);
4902 if (!track) continue;
4903 track->SetCircular(0);
4905 track->UpdatePoints();
4906 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
4908 nclusters[i]=track->GetNumberOfClusters();
4909 alpha[i] = track->GetAlpha();
4910 new (&helixes[i]) AliHelix(*track);
4912 helixes[i].Evaluate(0,xyz);
4913 sign[i] = (track->GetC()>0) ? -1:1;
4916 if (track->GetProlongation(x,y,z)){
4918 fim[i] = alpha[i]+TMath::ATan2(y,x);
4921 zm[i] = track->GetZ();
4925 circular[i]= kFALSE;
4926 if (track->GetProlongation(0,y,z)) z0[i] = z;
4927 dca[i] = track->GetD(0,0);
4933 Int_t ncandidates =0;
4936 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
4939 // Find circling track
4941 for (Int_t i0=0;i0<nentries;i0++){
4942 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4943 if (!track0) continue;
4944 if (track0->GetNumberOfClusters()<40) continue;
4945 if (TMath::Abs(1./track0->GetC())>200) continue;
4946 for (Int_t i1=i0+1;i1<nentries;i1++){
4947 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4948 if (!track1) continue;
4949 if (track1->GetNumberOfClusters()<40) continue;
4950 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
4951 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
4952 if (TMath::Abs(1./track1->GetC())>200) continue;
4953 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
4954 if (track1->GetTgl()*track0->GetTgl()>0) continue;
4955 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
4956 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
4957 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
4959 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
4960 if (mindcar<5) continue;
4961 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
4962 if (mindcaz<5) continue;
4963 if (mindcar+mindcaz<20) continue;
4966 Float_t xc0 = helixes[i0].GetHelix(6);
4967 Float_t yc0 = helixes[i0].GetHelix(7);
4968 Float_t r0 = helixes[i0].GetHelix(8);
4969 Float_t xc1 = helixes[i1].GetHelix(6);
4970 Float_t yc1 = helixes[i1].GetHelix(7);
4971 Float_t r1 = helixes[i1].GetHelix(8);
4973 Float_t rmean = (r0+r1)*0.5;
4974 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
4975 //if (delta>30) continue;
4976 if (delta>rmean*0.25) continue;
4977 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
4979 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4980 if (npoints==0) continue;
4981 helixes[i0].GetClosestPhases(helixes[i1], phase);
4985 Double_t hangles[3];
4986 helixes[i0].Evaluate(phase[0][0],xyz0);
4987 helixes[i1].Evaluate(phase[0][1],xyz1);
4989 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
4990 Double_t deltah[2],deltabest;
4991 if (hangles[2]<2.8) continue;
4994 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
4996 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
4997 if (deltah[1]<deltah[0]) ibest=1;
4999 deltabest = TMath::Sqrt(deltah[ibest]);
5000 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5001 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5002 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5003 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5005 if (deltabest>6) continue;
5006 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
5007 Bool_t lsign =kFALSE;
5008 if (hangles[2]>3.06) lsign =kTRUE;
5011 circular[i0] = kTRUE;
5012 circular[i1] = kTRUE;
5013 if (track0->OneOverPt()<track1->OneOverPt()){
5014 track0->SetCircular(track0->GetCircular()+1);
5015 track1->SetCircular(track1->GetCircular()+2);
5018 track1->SetCircular(track1->GetCircular()+1);
5019 track0->SetCircular(track0->GetCircular()+2);
5022 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
5024 Int_t lab0=track0->GetLabel();
5025 Int_t lab1=track1->GetLabel();
5026 TTreeSRedirector &cstream = *fDebugStreamer;
5027 cstream<<"Curling"<<
5034 "mindcar="<<mindcar<<
5035 "mindcaz="<<mindcaz<<
5038 "npoints="<<npoints<<
5039 "hangles0="<<hangles[0]<<
5040 "hangles2="<<hangles[2]<<
5045 "radius="<<radiusbest<<
5046 "deltabest="<<deltabest<<
5047 "phase0="<<phase[ibest][0]<<
5048 "phase1="<<phase[ibest][1]<<
5058 for (Int_t i =0;i<nentries;i++){
5059 if (sign[i]==0) continue;
5060 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5067 Double_t cradius0 = 40*40;
5068 Double_t cradius1 = 270*270;
5071 Double_t cdist3=0.55;
5072 for (Int_t j =i+1;j<nentries;j++){
5074 if (sign[j]*sign[i]<1) continue;
5075 if ( (nclusters[i]+nclusters[j])>200) continue;
5076 if ( (nclusters[i]+nclusters[j])<80) continue;
5077 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
5078 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
5079 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
5080 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5081 if (npoints<1) continue;
5084 if (radius[0]<cradius0||radius[0]>cradius1) continue;
5087 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
5090 Double_t delta1=10000,delta2=10000;
5091 // cuts on the intersection radius
5092 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5093 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5094 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5096 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5097 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5098 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5101 Double_t distance1 = TMath::Min(delta1,delta2);
5102 if (distance1>cdist1) continue; // cut on DCA linear approximation
5104 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5105 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5106 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5107 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5110 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5111 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5112 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5114 distance1 = TMath::Min(delta1,delta2);
5117 rkink = TMath::Sqrt(radius[0]);
5120 rkink = TMath::Sqrt(radius[1]);
5122 if (distance1>cdist2) continue;
5125 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5128 Int_t row0 = GetRowNumber(rkink);
5129 if (row0<10) continue;
5130 if (row0>150) continue;
5133 Float_t dens00=-1,dens01=-1;
5134 Float_t dens10=-1,dens11=-1;
5136 Int_t found,foundable,ishared;
5137 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5138 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
5139 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5140 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
5142 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5143 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
5144 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5145 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
5147 if (dens00<dens10 && dens01<dens11) continue;
5148 if (dens00>dens10 && dens01>dens11) continue;
5149 if (TMath::Max(dens00,dens10)<0.1) continue;
5150 if (TMath::Max(dens01,dens11)<0.3) continue;
5152 if (TMath::Min(dens00,dens10)>0.6) continue;
5153 if (TMath::Min(dens01,dens11)>0.6) continue;
5156 AliTPCseed * ktrack0, *ktrack1;
5165 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
5166 AliExternalTrackParam paramm(*ktrack0);
5167 AliExternalTrackParam paramd(*ktrack1);
5168 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (¶md) AliExternalTrackParam(ktrack1->GetReference());
5171 kink->SetMother(paramm);
5172 kink->SetDaughter(paramd);
5175 Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
5177 fkParam->Transform0to1(x,index);
5178 fkParam->Transform1to2(x,index);
5179 row0 = GetRowNumber(x[0]);
5181 if (kink->GetR()<100) continue;
5182 if (kink->GetR()>240) continue;
5183 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
5184 if (kink->GetDistance()>cdist3) continue;
5185 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
5186 if (dird<0) continue;
5188 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
5189 if (dirm<0) continue;
5190 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
5191 if (mpt<0.2) continue;
5194 //for high momenta momentum not defined well in first iteration
5195 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
5196 if (qt>0.35) continue;
5199 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
5200 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
5202 kink->SetTPCDensity(dens00,0,0);
5203 kink->SetTPCDensity(dens01,0,1);
5204 kink->SetTPCDensity(dens10,1,0);
5205 kink->SetTPCDensity(dens11,1,1);
5206 kink->SetIndex(i,0);
5207 kink->SetIndex(j,1);
5210 kink->SetTPCDensity(dens10,0,0);
5211 kink->SetTPCDensity(dens11,0,1);
5212 kink->SetTPCDensity(dens00,1,0);
5213 kink->SetTPCDensity(dens01,1,1);
5214 kink->SetIndex(j,0);
5215 kink->SetIndex(i,1);
5218 if (mpt<1||kink->GetAngle(2)>0.1){
5219 // angle and densities not defined yet
5220 if (kink->GetTPCDensityFactor()<0.8) continue;
5221 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
5222 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
5223 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5224 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5226 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5227 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
5228 criticalangle= 3*TMath::Sqrt(criticalangle);
5229 if (criticalangle>0.02) criticalangle=0.02;
5230 if (kink->GetAngle(2)<criticalangle) continue;
5233 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
5234 Float_t shapesum =0;
5236 for ( Int_t row = row0-drow; row<row0+drow;row++){
5237 if (row<0) continue;
5238 if (row>155) continue;
5239 if (ktrack0->GetClusterPointer(row)){
5240 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5241 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5244 if (ktrack1->GetClusterPointer(row)){
5245 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5246 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5251 kink->SetShapeFactor(-1.);
5254 kink->SetShapeFactor(shapesum/sum);
5256 // esd->AddKink(kink);
5258 // kink->SetMother(paramm);
5259 //kink->SetDaughter(paramd);
5261 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
5263 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
5264 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
5266 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
5268 if (AliTPCReconstructor::StreamLevel()>1) {
5269 (*fDebugStreamer)<<"kinkLpt"<<
5277 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
5281 kinks->AddLast(kink);
5287 // sort the kinks according quality - and refit them towards vertex
5289 Int_t nkinks = kinks->GetEntriesFast();
5290 Float_t *quality = new Float_t[nkinks];
5291 Int_t *indexes = new Int_t[nkinks];
5292 AliTPCseed *mothers = new AliTPCseed[nkinks];
5293 AliTPCseed *daughters = new AliTPCseed[nkinks];
5296 for (Int_t i=0;i<nkinks;i++){
5298 AliKink *kinkl = (AliKink*)kinks->At(i);
5300 // refit kinks towards vertex
5302 Int_t index0 = kinkl->GetIndex(0);
5303 Int_t index1 = kinkl->GetIndex(1);
5304 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5305 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5307 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
5309 // Refit Kink under if too small angle
5311 if (kinkl->GetAngle(2)<0.05){
5312 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5313 Int_t row0 = kinkl->GetTPCRow0();
5314 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
5317 Int_t last = row0-drow;
5318 if (last<40) last=40;
5319 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
5320 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
5323 Int_t first = row0+drow;
5324 if (first>130) first=130;
5325 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
5326 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
5328 if (seed0 && seed1){
5329 kinkl->SetStatus(1,8);
5330 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
5331 row0 = GetRowNumber(kinkl->GetR());
5332 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
5333 mothers[i] = *seed0;
5334 daughters[i] = *seed1;
5337 delete kinks->RemoveAt(i);
5338 if (seed0) MarkSeedFree( seed0 );
5339 if (seed1) MarkSeedFree( seed1 );
5342 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
5343 delete kinks->RemoveAt(i);
5344 if (seed0) MarkSeedFree( seed0 );
5345 if (seed1) MarkSeedFree( seed1 );
5349 MarkSeedFree( seed0 );
5350 MarkSeedFree( seed1 );
5353 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
5355 TMath::Sort(nkinks,quality,indexes,kFALSE);
5357 //remove double find kinks
5359 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
5360 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
5361 if (!kink0) continue;
5363 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
5364 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
5365 if (!kink0) continue;
5366 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
5367 if (!kink1) continue;
5368 // if not close kink continue
5369 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
5370 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
5371 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
5373 AliTPCseed &mother0 = mothers[indexes[ikink0]];
5374 AliTPCseed &daughter0 = daughters[indexes[ikink0]];
5375 AliTPCseed &mother1 = mothers[indexes[ikink1]];
5376 AliTPCseed &daughter1 = daughters[indexes[ikink1]];
5377 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
5386 for (Int_t i=0;i<row0;i++){
5387 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
5390 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
5397 for (Int_t i=row0;i<158;i++){
5398 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
5399 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
5402 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
5408 Float_t ratio = Float_t(same+1)/Float_t(both+1);
5409 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
5410 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
5411 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
5412 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
5413 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
5415 shared[kink0->GetIndex(0)]= kTRUE;
5416 shared[kink0->GetIndex(1)]= kTRUE;
5417 delete kinks->RemoveAt(indexes[ikink0]);
5421 shared[kink1->GetIndex(0)]= kTRUE;
5422 shared[kink1->GetIndex(1)]= kTRUE;
5423 delete kinks->RemoveAt(indexes[ikink1]);
5430 for (Int_t i=0;i<nkinks;i++){
5431 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
5432 if (!kinkl) continue;
5433 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5434 Int_t index0 = kinkl->GetIndex(0);
5435 Int_t index1 = kinkl->GetIndex(1);
5436 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
5437 kinkl->SetMultiple(usage[index0],0);
5438 kinkl->SetMultiple(usage[index1],1);
5439 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
5440 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
5441 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
5442 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
5444 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5445 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5446 if (!ktrack0 || !ktrack1) continue;
5447 Int_t index = esd->AddKink(kinkl);
5450 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
5451 if (mothers[indexes[i]].GetNumberOfClusters()>20 && daughters[indexes[i]].GetNumberOfClusters()>20 && (mothers[indexes[i]].GetNumberOfClusters()+daughters[indexes[i]].GetNumberOfClusters())>100){
5452 *ktrack0 = mothers[indexes[i]];
5453 *ktrack1 = daughters[indexes[i]];
5457 ktrack0->SetKinkIndex(usage[index0],-(index+1));
5458 ktrack1->SetKinkIndex(usage[index1], (index+1));
5463 // Remove tracks corresponding to shared kink's
5465 for (Int_t i=0;i<nentries;i++){
5466 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5467 if (!track0) continue;
5468 if (track0->GetKinkIndex(0)!=0) continue;
5469 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
5474 RemoveUsed2(array,0.5,0.4,30);
5476 for (Int_t i=0;i<nentries;i++){
5477 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5478 if (!track0) continue;
5479 track0->CookdEdx(0.02,0.6);
5483 for (Int_t i=0;i<nentries;i++){
5484 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5485 if (!track0) continue;
5486 if (track0->Pt()<1.4) continue;
5487 //remove double high momenta tracks - overlapped with kink candidates
5490 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
5491 if (track0->GetClusterPointer(icl)!=0){
5493 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
5496 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
5497 MarkSeedFree( array->RemoveAt(i) );
5501 if (track0->GetKinkIndex(0)!=0) continue;
5502 if (track0->GetNumberOfClusters()<80) continue;
5504 AliTPCseed *pmother = new AliTPCseed();
5505 AliTPCseed *pdaughter = new AliTPCseed();
5506 AliKink *pkink = new AliKink;
5508 AliTPCseed & mother = *pmother;
5509 AliTPCseed & daughter = *pdaughter;
5510 AliKink & kinkl = *pkink;
5511 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
5512 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
5516 continue; //too short tracks
5518 if (mother.Pt()<1.4) {
5524 Int_t row0= kinkl.GetTPCRow0();
5525 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
5532 Int_t index = esd->AddKink(&kinkl);
5533 mother.SetKinkIndex(0,-(index+1));
5534 daughter.SetKinkIndex(0,index+1);
5535 if (mother.GetNumberOfClusters()>50) {
5536 MarkSeedFree( array->RemoveAt(i) );
5537 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
5538 mtc->SetPoolID(fLastSeedID);
5539 array->AddAt(mtc,i);
5542 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
5543 mtc->SetPoolID(fLastSeedID);
5544 array->AddLast(mtc);
5546 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
5547 dtc->SetPoolID(fLastSeedID);
5548 array->AddLast(dtc);
5549 for (Int_t icl=0;icl<row0;icl++) {
5550 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
5553 for (Int_t icl=row0;icl<158;icl++) {
5554 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
5563 delete [] daughters;
5585 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
5591 void AliTPCtrackerMI::FindKinks(TObjArray * array, AliESDEvent *esd)
5598 TObjArray *kinks= new TObjArray(10000);
5599 // TObjArray *v0s= new TObjArray(10000);
5600 Int_t nentries = array->GetEntriesFast();
5601 AliHelix *helixes = new AliHelix[nentries];
5602 Int_t *sign = new Int_t[nentries];
5603 Int_t *nclusters = new Int_t[nentries];
5604 Float_t *alpha = new Float_t[nentries];
5605 AliKink *kink = new AliKink();
5606 Int_t * usage = new Int_t[nentries];
5607 Float_t *zm = new Float_t[nentries];
5608 Float_t *z0 = new Float_t[nentries];
5609 Float_t *fim = new Float_t[nentries];
5610 Float_t *shared = new Float_t[nentries];
5611 Bool_t *circular = new Bool_t[nentries];
5612 Float_t *dca = new Float_t[nentries];
5613 //const AliESDVertex * primvertex = esd->GetVertex();
5615 // nentries = array->GetEntriesFast();
5620 for (Int_t i=0;i<nentries;i++){
5623 AliTPCseed* track = (AliTPCseed*)array->At(i);
5624 if (!track) continue;
5625 track->SetCircular(0);
5627 track->UpdatePoints();
5628 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
5630 nclusters[i]=track->GetNumberOfClusters();
5631 alpha[i] = track->GetAlpha();
5632 new (&helixes[i]) AliHelix(*track);
5634 helixes[i].Evaluate(0,xyz);
5635 sign[i] = (track->GetC()>0) ? -1:1;
5638 if (track->GetProlongation(x,y,z)){
5640 fim[i] = alpha[i]+TMath::ATan2(y,x);
5643 zm[i] = track->GetZ();
5647 circular[i]= kFALSE;
5648 if (track->GetProlongation(0,y,z)) z0[i] = z;
5649 dca[i] = track->GetD(0,0);
5655 Int_t ncandidates =0;
5658 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
5661 // Find circling track
5663 for (Int_t i0=0;i0<nentries;i0++){
5664 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5665 if (!track0) continue;
5666 if (track0->GetNumberOfClusters()<40) continue;
5667 if (TMath::Abs(1./track0->GetC())>200) continue;
5668 for (Int_t i1=i0+1;i1<nentries;i1++){
5669 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5670 if (!track1) continue;
5671 if (track1->GetNumberOfClusters()<40) continue;
5672 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
5673 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
5674 if (TMath::Abs(1./track1->GetC())>200) continue;
5675 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
5676 if (track1->GetTgl()*track0->GetTgl()>0) continue;
5677 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
5678 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
5679 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
5681 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
5682 if (mindcar<5) continue;
5683 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
5684 if (mindcaz<5) continue;
5685 if (mindcar+mindcaz<20) continue;
5688 Float_t xc0 = helixes[i0].GetHelix(6);
5689 Float_t yc0 = helixes[i0].GetHelix(7);
5690 Float_t r0 = helixes[i0].GetHelix(8);
5691 Float_t xc1 = helixes[i1].GetHelix(6);
5692 Float_t yc1 = helixes[i1].GetHelix(7);
5693 Float_t r1 = helixes[i1].GetHelix(8);
5695 Float_t rmean = (r0+r1)*0.5;
5696 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
5697 //if (delta>30) continue;
5698 if (delta>rmean*0.25) continue;
5699 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
5701 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5702 if (npoints==0) continue;
5703 helixes[i0].GetClosestPhases(helixes[i1], phase);
5707 Double_t hangles[3];
5708 helixes[i0].Evaluate(phase[0][0],xyz0);
5709 helixes[i1].Evaluate(phase[0][1],xyz1);
5711 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5712 Double_t deltah[2],deltabest;
5713 if (hangles[2]<2.8) continue;
5716 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
5718 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
5719 if (deltah[1]<deltah[0]) ibest=1;
5721 deltabest = TMath::Sqrt(deltah[ibest]);
5722 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5723 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5724 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5725 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5727 if (deltabest>6) continue;
5728 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
5729 Bool_t lsign =kFALSE;
5730 if (hangles[2]>3.06) lsign =kTRUE;
5733 circular[i0] = kTRUE;
5734 circular[i1] = kTRUE;
5735 if (track0->OneOverPt()<track1->OneOverPt()){
5736 track0->SetCircular(track0->GetCircular()+1);
5737 track1->SetCircular(track1->GetCircular()+2);
5740 track1->SetCircular(track1->GetCircular()+1);
5741 track0->SetCircular(track0->GetCircular()+2);
5744 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
5746 Int_t lab0=track0->GetLabel();
5747 Int_t lab1=track1->GetLabel();
5748 TTreeSRedirector &cstream = *fDebugStreamer;
5749 cstream<<"Curling"<<
5756 "mindcar="<<mindcar<<
5757 "mindcaz="<<mindcaz<<
5760 "npoints="<<npoints<<
5761 "hangles0="<<hangles[0]<<
5762 "hangles2="<<hangles[2]<<
5767 "radius="<<radiusbest<<
5768 "deltabest="<<deltabest<<
5769 "phase0="<<phase[ibest][0]<<
5770 "phase1="<<phase[ibest][1]<<
5780 for (Int_t i =0;i<nentries;i++){
5781 if (sign[i]==0) continue;
5782 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5789 Double_t cradius0 = 40*40;
5790 Double_t cradius1 = 270*270;
5793 Double_t cdist3=0.55;
5794 for (Int_t j =i+1;j<nentries;j++){
5796 if (sign[j]*sign[i]<1) continue;
5797 if ( (nclusters[i]+nclusters[j])>200) continue;
5798 if ( (nclusters[i]+nclusters[j])<80) continue;
5799 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
5800 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
5801 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
5802 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5803 if (npoints<1) continue;
5806 if (radius[0]<cradius0||radius[0]>cradius1) continue;
5809 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
5812 Double_t delta1=10000,delta2=10000;
5813 // cuts on the intersection radius
5814 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5815 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5816 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5818 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5819 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5820 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5823 Double_t distance1 = TMath::Min(delta1,delta2);
5824 if (distance1>cdist1) continue; // cut on DCA linear approximation
5826 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5827 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5828 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5829 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5832 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5833 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5834 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5836 distance1 = TMath::Min(delta1,delta2);
5839 rkink = TMath::Sqrt(radius[0]);
5842 rkink = TMath::Sqrt(radius[1]);
5844 if (distance1>cdist2) continue;
5847 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5850 Int_t row0 = GetRowNumber(rkink);
5851 if (row0<10) continue;
5852 if (row0>150) continue;
5855 Float_t dens00=-1,dens01=-1;
5856 Float_t dens10=-1,dens11=-1;
5858 Int_t found,foundable,ishared;
5859 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5860 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
5861 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5862 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
5864 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5865 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
5866 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5867 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
5869 if (dens00<dens10 && dens01<dens11) continue;
5870 if (dens00>dens10 && dens01>dens11) continue;
5871 if (TMath::Max(dens00,dens10)<0.1) continue;
5872 if (TMath::Max(dens01,dens11)<0.3) continue;
5874 if (TMath::Min(dens00,dens10)>0.6) continue;
5875 if (TMath::Min(dens01,dens11)>0.6) continue;
5878 AliTPCseed * ktrack0, *ktrack1;
5887 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
5888 AliExternalTrackParam paramm(*ktrack0);
5889 AliExternalTrackParam paramd(*ktrack1);
5890 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (¶md) AliExternalTrackParam(ktrack1->GetReference());
5893 kink->SetMother(paramm);
5894 kink->SetDaughter(paramd);
5897 Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
5899 fkParam->Transform0to1(x,index);
5900 fkParam->Transform1to2(x,index);
5901 row0 = GetRowNumber(x[0]);
5903 if (kink->GetR()<100) continue;
5904 if (kink->GetR()>240) continue;
5905 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
5906 if (kink->GetDistance()>cdist3) continue;
5907 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
5908 if (dird<0) continue;
5910 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
5911 if (dirm<0) continue;
5912 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
5913 if (mpt<0.2) continue;
5916 //for high momenta momentum not defined well in first iteration
5917 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
5918 if (qt>0.35) continue;
5921 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
5922 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
5924 kink->SetTPCDensity(dens00,0,0);
5925 kink->SetTPCDensity(dens01,0,1);
5926 kink->SetTPCDensity(dens10,1,0);
5927 kink->SetTPCDensity(dens11,1,1);
5928 kink->SetIndex(i,0);
5929 kink->SetIndex(j,1);
5932 kink->SetTPCDensity(dens10,0,0);
5933 kink->SetTPCDensity(dens11,0,1);
5934 kink->SetTPCDensity(dens00,1,0);
5935 kink->SetTPCDensity(dens01,1,1);
5936 kink->SetIndex(j,0);
5937 kink->SetIndex(i,1);
5940 if (mpt<1||kink->GetAngle(2)>0.1){
5941 // angle and densities not defined yet
5942 if (kink->GetTPCDensityFactor()<0.8) continue;
5943 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
5944 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
5945 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5946 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5948 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5949 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
5950 criticalangle= 3*TMath::Sqrt(criticalangle);
5951 if (criticalangle>0.02) criticalangle=0.02;
5952 if (kink->GetAngle(2)<criticalangle) continue;
5955 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
5956 Float_t shapesum =0;
5958 for ( Int_t row = row0-drow; row<row0+drow;row++){
5959 if (row<0) continue;
5960 if (row>155) continue;
5961 if (ktrack0->GetClusterPointer(row)){
5962 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5963 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5966 if (ktrack1->GetClusterPointer(row)){
5967 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5968 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5973 kink->SetShapeFactor(-1.);
5976 kink->SetShapeFactor(shapesum/sum);
5978 // esd->AddKink(kink);
5980 // kink->SetMother(paramm);
5981 //kink->SetDaughter(paramd);
5983 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
5985 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
5986 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
5988 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
5990 if (AliTPCReconstructor::StreamLevel()>1) {
5991 (*fDebugStreamer)<<"kinkLpt"<<
5999 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
6003 kinks->AddLast(kink);
6009 // sort the kinks according quality - and refit them towards vertex
6011 Int_t nkinks = kinks->GetEntriesFast();
6012 Float_t *quality = new Float_t[nkinks];
6013 Int_t *indexes = new Int_t[nkinks];
6014 AliTPCseed **mothers = new AliTPCseed*[nkinks]; memset(mothers, 0, nkinks*sizeof(AliTPCseed*));
6015 AliTPCseed **daughters = new AliTPCseed*[nkinks]; memset(daughters, 0, nkinks*sizeof(AliTPCseed*));
6018 for (Int_t i=0;i<nkinks;i++){
6020 AliKink *kinkl = (AliKink*)kinks->At(i);
6022 // refit kinks towards vertex
6024 Int_t index0 = kinkl->GetIndex(0);
6025 Int_t index1 = kinkl->GetIndex(1);
6026 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6027 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6029 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
6031 // Refit Kink under if too small angle
6033 if (kinkl->GetAngle(2)<0.05){
6034 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6035 Int_t row0 = kinkl->GetTPCRow0();
6036 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
6039 Int_t last = row0-drow;
6040 if (last<40) last=40;
6041 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
6042 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
6045 Int_t first = row0+drow;
6046 if (first>130) first=130;
6047 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
6048 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
6050 if (seed0 && seed1){
6051 kinkl->SetStatus(1,8);
6052 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
6053 row0 = GetRowNumber(kinkl->GetR());
6054 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
6055 mothers[i] = new ( NextFreeSeed() ) AliTPCseed(*seed0);
6056 mothers[i]->SetPoolID(fLastSeedID);
6057 daughters[i] = new (NextFreeSeed() ) AliTPCseed(*seed1);
6058 daughters[i]->SetPoolID(fLastSeedID);
6061 delete kinks->RemoveAt(i);
6062 if (seed0) MarkSeedFree( seed0 );
6063 if (seed1) MarkSeedFree( seed1 );
6066 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
6067 delete kinks->RemoveAt(i);
6068 if (seed0) MarkSeedFree( seed0 );
6069 if (seed1) MarkSeedFree( seed1 );
6073 MarkSeedFree( seed0 );
6074 MarkSeedFree( seed1 );
6077 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
6079 TMath::Sort(nkinks,quality,indexes,kFALSE);
6081 //remove double find kinks
6083 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
6084 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6085 if (!kink0) continue;
6087 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
6088 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6089 if (!kink0) continue;
6090 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
6091 if (!kink1) continue;
6092 // if not close kink continue
6093 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
6094 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
6095 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
6097 AliTPCseed &mother0 = *mothers[indexes[ikink0]];
6098 AliTPCseed &daughter0 = *daughters[indexes[ikink0]];
6099 AliTPCseed &mother1 = *mothers[indexes[ikink1]];
6100 AliTPCseed &daughter1 = *daughters[indexes[ikink1]];
6101 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
6110 for (Int_t i=0;i<row0;i++){
6111 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
6114 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6121 for (Int_t i=row0;i<158;i++){
6122 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
6123 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
6126 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6132 Float_t ratio = Float_t(same+1)/Float_t(both+1);
6133 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
6134 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
6135 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
6136 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
6137 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
6139 shared[kink0->GetIndex(0)]= kTRUE;
6140 shared[kink0->GetIndex(1)]= kTRUE;
6141 delete kinks->RemoveAt(indexes[ikink0]);
6145 shared[kink1->GetIndex(0)]= kTRUE;
6146 shared[kink1->GetIndex(1)]= kTRUE;
6147 delete kinks->RemoveAt(indexes[ikink1]);
6154 for (Int_t i=0;i<nkinks;i++){
6155 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
6156 if (!kinkl) continue;
6157 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6158 Int_t index0 = kinkl->GetIndex(0);
6159 Int_t index1 = kinkl->GetIndex(1);
6160 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
6161 kinkl->SetMultiple(usage[index0],0);
6162 kinkl->SetMultiple(usage[index1],1);
6163 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
6164 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
6165 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
6166 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
6168 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6169 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6170 if (!ktrack0 || !ktrack1) continue;
6171 Int_t index = esd->AddKink(kinkl);
6174 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
6175 if (mothers[indexes[i]]->GetNumberOfClusters()>20 && daughters[indexes[i]]->GetNumberOfClusters()>20 &&
6176 (mothers[indexes[i]]->GetNumberOfClusters()+daughters[indexes[i]]->GetNumberOfClusters())>100){
6177 *ktrack0 = *mothers[indexes[i]];
6178 *ktrack1 = *daughters[indexes[i]];
6182 ktrack0->SetKinkIndex(usage[index0],-(index+1));
6183 ktrack1->SetKinkIndex(usage[index1], (index+1));
6188 // Remove tracks corresponding to shared kink's
6190 for (Int_t i=0;i<nentries;i++){
6191 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6192 if (!track0) continue;
6193 if (track0->GetKinkIndex(0)!=0) continue;
6194 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
6199 RemoveUsed2(array,0.5,0.4,30);
6201 for (Int_t i=0;i<nentries;i++){
6202 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6203 if (!track0) continue;
6204 track0->CookdEdx(0.02,0.6);
6208 for (Int_t i=0;i<nentries;i++){
6209 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6210 if (!track0) continue;
6211 if (track0->Pt()<1.4) continue;
6212 //remove double high momenta tracks - overlapped with kink candidates
6215 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
6216 if (track0->GetClusterPointer(icl)!=0){
6218 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
6221 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
6222 MarkSeedFree( array->RemoveAt(i) );
6226 if (track0->GetKinkIndex(0)!=0) continue;
6227 if (track0->GetNumberOfClusters()<80) continue;
6229 AliTPCseed *pmother = new( NextFreeSeed() ) AliTPCseed();
6230 pmother->SetPoolID(fLastSeedID);
6231 AliTPCseed *pdaughter = new( NextFreeSeed() ) AliTPCseed();
6232 pdaughter->SetPoolID(fLastSeedID);
6233 AliKink *pkink = new AliKink;
6235 AliTPCseed & mother = *pmother;
6236 AliTPCseed & daughter = *pdaughter;
6237 AliKink & kinkl = *pkink;
6238 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
6239 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
6240 MarkSeedFree( pmother );
6241 MarkSeedFree( pdaughter );
6243 continue; //too short tracks
6245 if (mother.Pt()<1.4) {
6246 MarkSeedFree( pmother );
6247 MarkSeedFree( pdaughter );
6251 Int_t row0= kinkl.GetTPCRow0();
6252 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
6253 MarkSeedFree( pmother );
6254 MarkSeedFree( pdaughter );
6259 Int_t index = esd->AddKink(&kinkl);
6260 mother.SetKinkIndex(0,-(index+1));
6261 daughter.SetKinkIndex(0,index+1);
6262 if (mother.GetNumberOfClusters()>50) {
6263 MarkSeedFree( array->RemoveAt(i) );
6264 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6265 mtc->SetPoolID(fLastSeedID);
6266 array->AddAt(mtc,i);
6269 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6270 mtc->SetPoolID(fLastSeedID);
6271 array->AddLast(mtc);
6273 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
6274 dtc->SetPoolID(fLastSeedID);
6275 array->AddLast(dtc);
6276 for (Int_t icl=0;icl<row0;icl++) {
6277 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
6280 for (Int_t icl=row0;icl<158;icl++) {
6281 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
6285 MarkSeedFree( pmother );
6286 MarkSeedFree( pdaughter );
6290 delete [] daughters;
6312 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
6317 Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
6320 // refit kink towards to the vertex
6323 AliKink &kink=(AliKink &)knk;
6325 Int_t row0 = GetRowNumber(kink.GetR());
6326 FollowProlongation(mother,0);
6327 mother.Reset(kFALSE);
6329 FollowProlongation(daughter,row0);
6330 daughter.Reset(kFALSE);
6331 FollowBackProlongation(daughter,158);
6332 daughter.Reset(kFALSE);
6333 Int_t first = TMath::Max(row0-20,30);
6334 Int_t last = TMath::Min(row0+20,140);
6336 const Int_t kNdiv =5;
6337 AliTPCseed param0[kNdiv]; // parameters along the track
6338 AliTPCseed param1[kNdiv]; // parameters along the track
6339 AliKink kinks[kNdiv]; // corresponding kink parameters
6342 for (Int_t irow=0; irow<kNdiv;irow++){
6343 rows[irow] = first +((last-first)*irow)/(kNdiv-1);
6345 // store parameters along the track
6347 for (Int_t irow=0;irow<kNdiv;irow++){
6348 FollowBackProlongation(mother, rows[irow]);
6349 FollowProlongation(daughter,rows[kNdiv-1-irow]);
6350 param0[irow] = mother;
6351 param1[kNdiv-1-irow] = daughter;
6355 for (Int_t irow=0; irow<kNdiv-1;irow++){
6356 if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
6357 kinks[irow].SetMother(param0[irow]);
6358 kinks[irow].SetDaughter(param1[irow]);
6359 kinks[irow].Update();
6362 // choose kink with best "quality"
6364 Double_t mindist = 10000;
6365 for (Int_t irow=0;irow<kNdiv;irow++){
6366 if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
6367 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
6368 if (TMath::Abs(kinks[irow].GetR())<100.) continue;
6370 Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
6371 normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
6372 if (normdist < mindist){
6378 if (index==-1) return 0;
6381 param0[index].Reset(kTRUE);
6382 FollowProlongation(param0[index],0);
6384 mother = param0[index];
6385 daughter = param1[index]; // daughter in vertex
6387 kink.SetMother(mother);
6388 kink.SetDaughter(daughter);
6390 kink.SetTPCRow0(GetRowNumber(kink.GetR()));
6391 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
6392 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
6393 kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
6394 kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
6395 mother.SetLabel(kink.GetLabel(0));
6396 daughter.SetLabel(kink.GetLabel(1));
6402 void AliTPCtrackerMI::UpdateKinkQualityM(AliTPCseed * seed){
6404 // update Kink quality information for mother after back propagation
6406 if (seed->GetKinkIndex(0)>=0) return;
6407 for (Int_t ikink=0;ikink<3;ikink++){
6408 Int_t index = seed->GetKinkIndex(ikink);
6409 if (index>=0) break;
6410 index = TMath::Abs(index)-1;
6411 AliESDkink * kink = fEvent->GetKink(index);
6412 kink->SetTPCDensity(-1,0,0);
6413 kink->SetTPCDensity(1,0,1);
6415 Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6416 if (row0<15) row0=15;
6418 Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6419 if (row1>145) row1=145;
6421 Int_t found,foundable,shared;
6422 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
6423 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,0);
6424 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
6425 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,1);
6430 void AliTPCtrackerMI::UpdateKinkQualityD(AliTPCseed * seed){
6432 // update Kink quality information for daughter after refit
6434 if (seed->GetKinkIndex(0)<=0) return;
6435 for (Int_t ikink=0;ikink<3;ikink++){
6436 Int_t index = seed->GetKinkIndex(ikink);
6437 if (index<=0) break;
6438 index = TMath::Abs(index)-1;
6439 AliESDkink * kink = fEvent->GetKink(index);
6440 kink->SetTPCDensity(-1,1,0);
6441 kink->SetTPCDensity(-1,1,1);
6443 Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6444 if (row0<15) row0=15;
6446 Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6447 if (row1>145) row1=145;
6449 Int_t found,foundable,shared;
6450 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
6451 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,0);
6452 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
6453 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,1);
6459 Int_t AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
6462 // check kink point for given track
6463 // if return value=0 kink point not found
6464 // otherwise seed0 correspond to mother particle
6465 // seed1 correspond to daughter particle
6466 // kink parameter of kink point
6467 AliKink &kink=(AliKink &)knk;
6469 Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
6470 Int_t first = seed->GetFirstPoint();
6471 Int_t last = seed->GetLastPoint();
6472 if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
6475 AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
6476 if (!seed1) return 0;
6477 FollowProlongation(*seed1,seed->GetLastPoint()-20);
6478 seed1->Reset(kTRUE);
6479 FollowProlongation(*seed1,158);
6480 seed1->Reset(kTRUE);
6481 last = seed1->GetLastPoint();
6483 AliTPCseed *seed0 = new( NextFreeSeed() ) AliTPCseed(*seed);
6484 seed0->SetPoolID(fLastSeedID);
6485 seed0->Reset(kFALSE);
6488 AliTPCseed param0[20]; // parameters along the track
6489 AliTPCseed param1[20]; // parameters along the track
6490 AliKink kinks[20]; // corresponding kink parameters
6492 for (Int_t irow=0; irow<20;irow++){
6493 rows[irow] = first +((last-first)*irow)/19;
6495 // store parameters along the track
6497 for (Int_t irow=0;irow<20;irow++){
6498 FollowBackProlongation(*seed0, rows[irow]);
6499 FollowProlongation(*seed1,rows[19-irow]);
6500 param0[irow] = *seed0;
6501 param1[19-irow] = *seed1;
6505 for (Int_t irow=0; irow<19;irow++){
6506 kinks[irow].SetMother(param0[irow]);
6507 kinks[irow].SetDaughter(param1[irow]);
6508 kinks[irow].Update();
6511 // choose kink with biggest change of angle
6513 Double_t maxchange= 0;
6514 for (Int_t irow=1;irow<19;irow++){
6515 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
6516 if (TMath::Abs(kinks[irow].GetR())<110.) continue;
6517 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
6518 if ( quality > maxchange){
6519 maxchange = quality;
6524 MarkSeedFree( seed0 );
6525 MarkSeedFree( seed1 );
6526 if (index<0) return 0;
6528 Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
6529 seed0 = new( NextFreeSeed() ) AliTPCseed(param0[index]);
6530 seed0->SetPoolID(fLastSeedID);
6531 seed1 = new( NextFreeSeed() ) AliTPCseed(param1[index]);
6532 seed1->SetPoolID(fLastSeedID);
6533 seed0->Reset(kFALSE);
6534 seed1->Reset(kFALSE);
6535 seed0->ResetCovariance(10.);
6536 seed1->ResetCovariance(10.);
6537 FollowProlongation(*seed0,0);
6538 FollowBackProlongation(*seed1,158);
6539 mother = *seed0; // backup mother at position 0
6540 seed0->Reset(kFALSE);
6541 seed1->Reset(kFALSE);
6542 seed0->ResetCovariance(10.);
6543 seed1->ResetCovariance(10.);
6545 first = TMath::Max(row0-20,0);
6546 last = TMath::Min(row0+20,158);
6548 for (Int_t irow=0; irow<20;irow++){
6549 rows[irow] = first +((last-first)*irow)/19;
6551 // store parameters along the track
6553 for (Int_t irow=0;irow<20;irow++){
6554 FollowBackProlongation(*seed0, rows[irow]);
6555 FollowProlongation(*seed1,rows[19-irow]);
6556 param0[irow] = *seed0;
6557 param1[19-irow] = *seed1;
6561 for (Int_t irow=0; irow<19;irow++){
6562 kinks[irow].SetMother(param0[irow]);
6563 kinks[irow].SetDaughter(param1[irow]);
6564 // param0[irow].Dump();
6565 //param1[irow].Dump();
6566 kinks[irow].Update();
6569 // choose kink with biggest change of angle
6572 for (Int_t irow=0;irow<20;irow++){
6573 if (TMath::Abs(kinks[irow].GetR())>250.) continue;
6574 if (TMath::Abs(kinks[irow].GetR())<90.) continue;
6575 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
6576 if ( quality > maxchange){
6577 maxchange = quality;
6584 if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
6585 MarkSeedFree( seed0 );
6586 MarkSeedFree( seed1 );
6590 // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
6592 kink.SetMother(param0[index]);
6593 kink.SetDaughter(param1[index]);
6596 Double_t chi2P2 = param0[index].GetParameter()[2]-param1[index].GetParameter()[2];
6598 chi2P2/=param0[index].GetCovariance()[5]+param1[index].GetCovariance()[5];
6599 Double_t chi2P3 = param0[index].GetParameter()[3]-param1[index].GetParameter()[3];
6601 chi2P3/=param0[index].GetCovariance()[9]+param1[index].GetCovariance()[9];
6603 if (AliTPCReconstructor::StreamLevel()>1) {
6604 (*fDebugStreamer)<<"kinkHpt"<<
6607 "p0.="<<¶m0[index]<<
6608 "p1.="<<¶m1[index]<<
6612 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
6613 MarkSeedFree( seed0 );
6614 MarkSeedFree( seed1 );
6619 row0 = GetRowNumber(kink.GetR());
6620 kink.SetTPCRow0(row0);
6621 kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
6622 kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
6623 kink.SetIndex(-10,0);
6624 kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
6625 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
6626 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
6629 // new (&mother) AliTPCseed(param0[index]);
6630 daughter = param1[index];
6631 daughter.SetLabel(kink.GetLabel(1));
6632 param0[index].Reset(kTRUE);
6633 FollowProlongation(param0[index],0);
6634 mother = param0[index];
6635 mother.SetLabel(kink.GetLabel(0));
6636 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(1)){
6639 MarkSeedFree( seed0 );
6640 MarkSeedFree( seed1 );
6648 AliTPCseed* AliTPCtrackerMI::ReSeed(AliTPCseed *t)
6651 // reseed - refit - track
6654 // Int_t last = fSectors->GetNRows()-1;
6656 if (fSectors == fOuterSec){
6657 first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
6661 first = t->GetFirstPoint();
6663 AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
6664 FollowBackProlongation(*t,fSectors->GetNRows()-1);
6666 FollowProlongation(*t,first);
6676 //_____________________________________________________________________________
6677 Int_t AliTPCtrackerMI::ReadSeeds(const TFile *inp) {
6678 //-----------------------------------------------------------------
6679 // This function reades track seeds.
6680 //-----------------------------------------------------------------
6681 TDirectory *savedir=gDirectory;
6683 TFile *in=(TFile*)inp;
6684 if (!in->IsOpen()) {
6685 cerr<<"AliTPCtrackerMI::ReadSeeds(): input file is not open !\n";
6690 TTree *seedTree=(TTree*)in->Get("Seeds");
6692 cerr<<"AliTPCtrackerMI::ReadSeeds(): ";
6693 cerr<<"can't get a tree with track seeds !\n";
6696 AliTPCtrack *seed=new AliTPCtrack;
6697 seedTree->SetBranchAddress("tracks",&seed);
6699 if (fSeeds==0) fSeeds=new TObjArray(15000);
6701 Int_t n=(Int_t)seedTree->GetEntries();
6702 for (Int_t i=0; i<n; i++) {
6703 seedTree->GetEvent(i);
6704 AliTPCseed* sdc = new( NextFreeSeed() ) AliTPCseed(*seed/*,seed->GetAlpha()*/);
6705 sdc->SetPoolID(fLastSeedID);
6706 fSeeds->AddLast(sdc);
6709 delete seed; // RS: this seed is not from the pool, delete it !!!
6715 Int_t AliTPCtrackerMI::Clusters2TracksHLT (AliESDEvent *const esd, const AliESDEvent *hltEvent)
6718 // clusters to tracks
6719 if (fSeeds) DeleteSeeds();
6720 else ResetSeedsPool();
6722 fEventHLT = hltEvent;
6724 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
6725 transform->SetCurrentTimeStamp( esd->GetTimeStamp());
6726 transform->SetCurrentRun(esd->GetRunNumber());
6730 if (!fSeeds) return 1;
6732 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(0,fSeeds);
6737 Int_t AliTPCtrackerMI::Clusters2Tracks(AliESDEvent *const esd)
6740 // clusters to tracks
6741 return Clusters2TracksHLT( esd, 0);
6744 //_____________________________________________________________________________
6745 Int_t AliTPCtrackerMI::Clusters2Tracks() {
6746 //-----------------------------------------------------------------
6747 // This is a track finder.
6748 //-----------------------------------------------------------------
6749 TDirectory *savedir=gDirectory;
6753 fSeeds = Tracking();
6756 Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
6758 //activate again some tracks
6759 for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
6760 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6762 Int_t nc=t.GetNumberOfClusters();
6764 MarkSeedFree( fSeeds->RemoveAt(i) );
6768 if (pt->GetRemoval()==10) {
6769 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
6770 pt->Desactivate(10); // make track again active // MvL: should be 0 ?
6772 pt->Desactivate(20);
6773 MarkSeedFree( fSeeds->RemoveAt(i) );
6778 RemoveUsed2(fSeeds,0.85,0.85,0);
6779 if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
6780 //FindCurling(fSeeds, fEvent,0);
6781 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,-1); // find multi found tracks
6782 RemoveUsed2(fSeeds,0.5,0.4,20);
6783 FindSplitted(fSeeds, fEvent,0); // find multi found tracks
6784 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
6787 // // refit short tracks
6789 Int_t nseed=fSeeds->GetEntriesFast();
6792 for (Int_t i=0; i<nseed; i++) {
6793 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6795 Int_t nc=t.GetNumberOfClusters();
6797 MarkSeedFree( fSeeds->RemoveAt(i) );
6800 CookLabel(pt,0.1); //For comparison only
6801 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6802 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6804 if (fDebug>0) cerr<<found<<'\r';
6808 MarkSeedFree( fSeeds->RemoveAt(i) );
6812 //RemoveOverlap(fSeeds,0.99,7,kTRUE);
6814 //RemoveUsed(fSeeds,0.9,0.9,6);
6816 nseed=fSeeds->GetEntriesFast();
6818 for (Int_t i=0; i<nseed; i++) {
6819 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6821 Int_t nc=t.GetNumberOfClusters();
6823 MarkSeedFree( fSeeds->RemoveAt(i) );
6827 t.CookdEdx(0.02,0.6);
6828 // CheckKinkPoint(&t,0.05);
6829 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6830 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6838 MarkSeedFree( fSeeds->RemoveAt(i) );
6839 //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
6841 // FollowProlongation(*seed1,0);
6842 // Int_t n = seed1->GetNumberOfClusters();
6843 // printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
6844 // printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
6847 //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
6851 SortTracks(fSeeds, 1);
6855 PrepareForBackProlongation(fSeeds,5.);
6856 PropagateBack(fSeeds);
6857 printf("Time for back propagation: \t");timer.Print();timer.Start();
6861 PrepareForProlongation(fSeeds,5.);
6862 PropagateForard2(fSeeds);
6864 printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
6865 // RemoveUsed(fSeeds,0.7,0.7,6);
6866 //RemoveOverlap(fSeeds,0.9,7,kTRUE);
6868 nseed=fSeeds->GetEntriesFast();
6870 for (Int_t i=0; i<nseed; i++) {
6871 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6873 Int_t nc=t.GetNumberOfClusters();
6875 MarkSeedFree( fSeeds->RemoveAt(i) );
6878 t.CookdEdx(0.02,0.6);
6879 // CookLabel(pt,0.1); //For comparison only
6880 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6881 if ((pt->IsActive() || (pt->fRemoval==10) )){
6882 cerr<<found++<<'\r';
6885 MarkSeedFree( fSeeds->RemoveAt(i) );
6890 // fNTracks = found;
6892 Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
6895 // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
6896 Info("Clusters2Tracks","Number of found tracks %d",found);
6898 // UnloadClusters();
6903 void AliTPCtrackerMI::Tracking(TObjArray * arr)
6906 // tracking of the seeds
6909 fSectors = fOuterSec;
6910 ParallelTracking(arr,150,63);
6911 fSectors = fOuterSec;
6912 ParallelTracking(arr,63,0);
6915 TObjArray * AliTPCtrackerMI::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
6920 static TObjArray arrTracks;
6921 TObjArray * arr = &arrTracks;
6923 fSectors = fOuterSec;
6926 for (Int_t sec=0;sec<fkNOS;sec++){
6927 if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
6928 if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);
6929 if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
6932 Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
6944 TObjArray * AliTPCtrackerMI::Tracking()
6948 if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
6951 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
6953 TObjArray * seeds = new TObjArray;
6955 Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
6956 Int_t gapPrim = AliTPCReconstructor::GetRecoParam()->GetSeedGapPrim();
6957 Int_t gapSec = AliTPCReconstructor::GetRecoParam()->GetSeedGapSec();
6965 Float_t fnumber = 3.0;
6966 Float_t fdensity = 3.0;
6969 if (AliTPCReconstructor::GetRecoParam()->GetUseHLTPreSeeding()) {
6970 arr = MakeSeedsHLT( fEventHLT );
6972 SumTracks(seeds,arr);
6975 //cout<<"HLT tracks left after sorting: "<<seeds->GetEntriesFast()<<endl;
6976 //SignClusters(seeds,fnumber,fdensity);
6983 for (Int_t delta = 0; delta<18; delta+=gapPrim){
6987 arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
6988 SumTracks(seeds,arr);
6989 SignClusters(seeds,fnumber,fdensity);
6991 for (Int_t i=2;i<6;i+=2){
6992 // seed high pt tracks
6995 arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
6996 SumTracks(seeds,arr);
6997 SignClusters(seeds,fnumber,fdensity);
7002 // RemoveUsed(seeds,0.9,0.9,1);
7003 // UnsignClusters();
7004 // SignClusters(seeds,fnumber,fdensity);
7008 for (Int_t delta = 20; delta<120; delta+=gapPrim){
7010 // seed high pt tracks
7014 arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
7015 SumTracks(seeds,arr);
7016 SignClusters(seeds,fnumber,fdensity);
7021 arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
7022 SumTracks(seeds,arr);
7023 SignClusters(seeds,fnumber,fdensity);
7034 Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
7038 // RemoveUsed(seeds,0.75,0.75,1);
7040 //SignClusters(seeds,fnumber,fdensity);
7049 arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
7050 SumTracks(seeds,arr);
7051 SignClusters(seeds,fnumber,fdensity);
7053 arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
7054 SumTracks(seeds,arr);
7055 SignClusters(seeds,fnumber,fdensity);
7057 arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
7058 SumTracks(seeds,arr);
7059 SignClusters(seeds,fnumber,fdensity);
7061 arr = Tracking(4,nup-5,nup-5-gap,cuts,-1);
7062 SumTracks(seeds,arr);
7063 SignClusters(seeds,fnumber,fdensity);
7065 arr = Tracking(4,nup-7,nup-7-gap,cuts,-1);
7066 SumTracks(seeds,arr);
7067 SignClusters(seeds,fnumber,fdensity);
7070 arr = Tracking(4,nup-9,nup-9-gap,cuts,-1);
7071 SumTracks(seeds,arr);
7072 SignClusters(seeds,fnumber,fdensity);
7076 for (Int_t delta = 9; delta<30; delta+=gapSec){
7082 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7083 SumTracks(seeds,arr);
7084 SignClusters(seeds,fnumber,fdensity);
7086 arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
7087 SumTracks(seeds,arr);
7088 SignClusters(seeds,fnumber,fdensity);
7101 for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=gapSec){
7107 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7108 SumTracks(seeds,arr);
7109 SignClusters(seeds,fnumber,fdensity);
7111 arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
7112 SumTracks(seeds,arr);
7113 SignClusters(seeds,fnumber,fdensity);
7117 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
7128 TObjArray * AliTPCtrackerMI::TrackingSpecial()
7131 // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
7132 // no primary vertex seeding tried
7136 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7138 TObjArray * seeds = new TObjArray;
7143 Float_t fnumber = 3.0;
7144 Float_t fdensity = 3.0;
7147 cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC(); // max curvature
7148 cuts[1] = 3.5; // max tan(phi) angle for seeding
7149 cuts[2] = 3.; // not used (cut on z primary vertex)
7150 cuts[3] = 3.5; // max tan(theta) angle for seeding
7152 for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
7154 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7155 SumTracks(seeds,arr);
7156 SignClusters(seeds,fnumber,fdensity);
7160 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
7171 void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *&arr2)
7174 //sum tracks to common container
7175 //remove suspicious tracks
7176 // RS: Attention: supplied tracks come in the static array, don't delete them
7177 Int_t nseed = arr2->GetEntriesFast();
7178 for (Int_t i=0;i<nseed;i++){
7179 AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);
7182 // remove tracks with too big curvature
7184 if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
7185 MarkSeedFree( arr2->RemoveAt(i) );
7188 // REMOVE VERY SHORT TRACKS
7189 if (pt->GetNumberOfClusters()<20){
7190 MarkSeedFree( arr2->RemoveAt(i) );
7193 // NORMAL ACTIVE TRACK
7194 if (pt->IsActive()){
7195 arr1->AddLast(arr2->RemoveAt(i));
7198 //remove not usable tracks
7199 if (pt->GetRemoval()!=10){
7200 MarkSeedFree( arr2->RemoveAt(i) );
7204 // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
7205 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
7206 arr1->AddLast(arr2->RemoveAt(i));
7208 MarkSeedFree( arr2->RemoveAt(i) );
7212 // delete arr2; arr2 = 0; // RS: this is static array, don't delete it
7217 void AliTPCtrackerMI::ParallelTracking(TObjArray *const arr, Int_t rfirst, Int_t rlast)
7220 // try to track in parralel
7222 Int_t nseed=arr->GetEntriesFast();
7223 //prepare seeds for tracking
7224 for (Int_t i=0; i<nseed; i++) {
7225 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
7227 if (!t.IsActive()) continue;
7228 // follow prolongation to the first layer
7229 if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fkParam->GetNRowLow()>rfirst+1) )
7230 FollowProlongation(t, rfirst+1);
7235 for (Int_t nr=rfirst; nr>=rlast; nr--){
7236 if (nr<fInnerSec->GetNRows())
7237 fSectors = fInnerSec;
7239 fSectors = fOuterSec;
7240 // make indexes with the cluster tracks for given
7242 // find nearest cluster
7243 for (Int_t i=0; i<nseed; i++) {
7244 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
7246 if (nr==80) pt->UpdateReference();
7247 if (!pt->IsActive()) continue;
7248 // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
7249 if (pt->GetRelativeSector()>17) {
7252 UpdateClusters(t,nr);
7254 // prolonagate to the nearest cluster - if founded
7255 for (Int_t i=0; i<nseed; i++) {
7256 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
7258 if (!pt->IsActive()) continue;
7259 // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
7260 if (pt->GetRelativeSector()>17) {
7263 FollowToNextCluster(*pt,nr);
7268 void AliTPCtrackerMI::PrepareForBackProlongation(const TObjArray *const arr,Float_t fac) const
7272 // if we use TPC track itself we have to "update" covariance
7274 Int_t nseed= arr->GetEntriesFast();
7275 for (Int_t i=0;i<nseed;i++){
7276 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7280 //rotate to current local system at first accepted point
7281 Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
7282 Int_t sec = (index&0xff000000)>>24;
7284 Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
7285 if (angle1>TMath::Pi())
7286 angle1-=2.*TMath::Pi();
7287 Float_t angle2 = pt->GetAlpha();
7289 if (TMath::Abs(angle1-angle2)>0.001){
7290 if (!pt->Rotate(angle1-angle2)) return;
7291 //angle2 = pt->GetAlpha();
7292 //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
7293 //if (pt->GetAlpha()<0)
7294 // pt->fRelativeSector+=18;
7295 //sec = pt->fRelativeSector;
7304 void AliTPCtrackerMI::PrepareForProlongation(TObjArray *const arr, Float_t fac) const
7308 // if we use TPC track itself we have to "update" covariance
7310 Int_t nseed= arr->GetEntriesFast();
7311 for (Int_t i=0;i<nseed;i++){
7312 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7315 pt->SetFirstPoint(pt->GetLastPoint());
7323 Int_t AliTPCtrackerMI::PropagateBack(const TObjArray *const arr)
7326 // make back propagation
7328 Int_t nseed= arr->GetEntriesFast();
7329 for (Int_t i=0;i<nseed;i++){
7330 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7331 if (pt&& pt->GetKinkIndex(0)<=0) {
7332 //AliTPCseed *pt2 = new AliTPCseed(*pt);
7333 fSectors = fInnerSec;
7334 //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
7335 //fSectors = fOuterSec;
7336 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
7337 //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
7338 // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
7339 // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
7342 if (pt&& pt->GetKinkIndex(0)>0) {
7343 AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
7344 pt->SetFirstPoint(kink->GetTPCRow0());
7345 fSectors = fInnerSec;
7346 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
7354 Int_t AliTPCtrackerMI::PropagateForward2(const TObjArray *const arr)
7357 // make forward propagation
7359 Int_t nseed= arr->GetEntriesFast();
7361 for (Int_t i=0;i<nseed;i++){
7362 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7364 FollowProlongation(*pt,0,1,1);
7373 Int_t AliTPCtrackerMI::PropagateForward()
7376 // propagate track forward
7378 Int_t nseed = fSeeds->GetEntriesFast();
7379 for (Int_t i=0;i<nseed;i++){
7380 AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
7382 AliTPCseed &t = *pt;
7383 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
7384 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
7385 if (alpha < 0. ) alpha += 2.*TMath::Pi();
7386 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
7390 fSectors = fOuterSec;
7391 ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
7392 fSectors = fInnerSec;
7393 ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
7402 Int_t AliTPCtrackerMI::PropagateBack(AliTPCseed *const pt, Int_t row0, Int_t row1)
7405 // make back propagation, in between row0 and row1
7409 fSectors = fInnerSec;
7412 if (row1<fSectors->GetNRows())
7415 r1 = fSectors->GetNRows()-1;
7417 if (row0<fSectors->GetNRows()&& r1>0 )
7418 FollowBackProlongation(*pt,r1);
7419 if (row1<=fSectors->GetNRows())
7422 r1 = row1 - fSectors->GetNRows();
7423 if (r1<=0) return 0;
7424 if (r1>=fOuterSec->GetNRows()) return 0;
7425 fSectors = fOuterSec;
7426 return FollowBackProlongation(*pt,r1);
7434 void AliTPCtrackerMI::GetShape(AliTPCseed * seed, Int_t row)
7436 // gets cluster shape
7438 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
7439 Float_t zdrift = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())));
7440 Int_t type = (seed->GetSector() < fkParam->GetNSector()/2) ? 0: (row>126) ? 1:2;
7441 Double_t angulary = seed->GetSnp();
7443 if (TMath::Abs(angulary)>AliTPCReconstructor::GetMaxSnpTracker()) {
7444 angulary = TMath::Sign(AliTPCReconstructor::GetMaxSnpTracker(),angulary);
7447 angulary = angulary*angulary/((1.-angulary)*(1.+angulary));
7448 Double_t angularz = seed->GetTgl()*seed->GetTgl()*(1.+angulary);
7450 Double_t sigmay = clparam->GetRMS0(0,type,zdrift,TMath::Sqrt(TMath::Abs(angulary)));
7451 Double_t sigmaz = clparam->GetRMS0(1,type,zdrift,TMath::Sqrt(TMath::Abs(angularz)));
7452 seed->SetCurrentSigmaY2(sigmay*sigmay);
7453 seed->SetCurrentSigmaZ2(sigmaz*sigmaz);
7454 // Float_t sd2 = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fkParam->GetDiffL()*fkParam->GetDiffL();
7455 // // Float_t padlength = fkParam->GetPadPitchLength(seed->fSector);
7456 // Float_t padlength = GetPadPitchLength(row);
7458 // Float_t sresy = (seed->GetSector() < fkParam->GetNSector()/2) ? 0.2 :0.3;
7459 // seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
7461 // Float_t sresz = fkParam->GetZSigma();
7462 // seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
7464 Float_t wy = GetSigmaY(seed);
7465 Float_t wz = GetSigmaZ(seed);
7468 if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
7469 printf("problem\n");
7476 //__________________________________________________________________________
7477 void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
7478 //--------------------------------------------------------------------
7479 //This function "cooks" a track label. If label<0, this track is fake.
7480 //--------------------------------------------------------------------
7481 AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
7483 printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
7487 Int_t noc=t->GetNumberOfClusters();
7489 //printf("\nnot founded prolongation\n\n\n");
7495 AliTPCclusterMI *clusters[160];
7497 for (Int_t i=0;i<160;i++) {
7504 for (i=0; i<160 && current<noc; i++) {
7506 Int_t index=t->GetClusterIndex2(i);
7507 if (index<=0) continue;
7508 if (index&0x8000) continue;
7510 //clusters[current]=GetClusterMI(index);
7511 if (t->GetClusterPointer(i)){
7512 clusters[current]=t->GetClusterPointer(i);
7518 Int_t lab=123456789;
7519 for (i=0; i<noc; i++) {
7520 AliTPCclusterMI *c=clusters[i];
7522 lab=TMath::Abs(c->GetLabel(0));
7524 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
7530 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
7532 for (i=0; i<noc; i++) {
7533 AliTPCclusterMI *c=clusters[i];
7535 if (TMath::Abs(c->GetLabel(1)) == lab ||
7536 TMath::Abs(c->GetLabel(2)) == lab ) max++;
7538 if (noc<=0) { lab=-1; return;}
7539 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
7542 Int_t tail=Int_t(0.10*noc);
7545 for (i=1; i<160&&ind<tail; i++) {
7546 // AliTPCclusterMI *c=clusters[noc-i];
7547 AliTPCclusterMI *c=clusters[i];
7549 if (lab == TMath::Abs(c->GetLabel(0)) ||
7550 lab == TMath::Abs(c->GetLabel(1)) ||
7551 lab == TMath::Abs(c->GetLabel(2))) max++;
7554 if (max < Int_t(0.5*tail)) lab=-lab;
7561 //delete[] clusters;
7565 //__________________________________________________________________________
7566 Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *const t, Float_t wrong,Int_t first, Int_t last) const {
7567 //--------------------------------------------------------------------
7568 //This function "cooks" a track label. If label<0, this track is fake.
7569 //--------------------------------------------------------------------
7570 Int_t noc=t->GetNumberOfClusters();
7572 //printf("\nnot founded prolongation\n\n\n");
7578 AliTPCclusterMI *clusters[160];
7580 for (Int_t i=0;i<160;i++) {
7587 for (i=0; i<160 && current<noc; i++) {
7588 if (i<first) continue;
7589 if (i>last) continue;
7590 Int_t index=t->GetClusterIndex2(i);
7591 if (index<=0) continue;
7592 if (index&0x8000) continue;
7594 //clusters[current]=GetClusterMI(index);
7595 if (t->GetClusterPointer(i)){
7596 clusters[current]=t->GetClusterPointer(i);
7601 //if (noc<5) return -1;
7602 Int_t lab=123456789;
7603 for (i=0; i<noc; i++) {
7604 AliTPCclusterMI *c=clusters[i];
7606 lab=TMath::Abs(c->GetLabel(0));
7608 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
7614 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
7616 for (i=0; i<noc; i++) {
7617 AliTPCclusterMI *c=clusters[i];
7619 if (TMath::Abs(c->GetLabel(1)) == lab ||
7620 TMath::Abs(c->GetLabel(2)) == lab ) max++;
7622 if (noc<=0) { lab=-1; return -1;}
7623 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
7626 Int_t tail=Int_t(0.10*noc);
7629 for (i=1; i<160&&ind<tail; i++) {
7630 // AliTPCclusterMI *c=clusters[noc-i];
7631 AliTPCclusterMI *c=clusters[i];
7633 if (lab == TMath::Abs(c->GetLabel(0)) ||
7634 lab == TMath::Abs(c->GetLabel(1)) ||
7635 lab == TMath::Abs(c->GetLabel(2))) max++;
7638 if (max < Int_t(0.5*tail)) lab=-lab;
7641 // t->SetLabel(lab);
7645 //delete[] clusters;
7649 Int_t AliTPCtrackerMI::GetRowNumber(Double_t x[3]) const
7651 //return pad row number for given x vector
7652 Float_t phi = TMath::ATan2(x[1],x[0]);
7653 if(phi<0) phi=2.*TMath::Pi()+phi;
7654 // Get the local angle in the sector philoc
7655 const Float_t kRaddeg = 180/3.14159265358979312;
7656 Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
7657 Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
7658 return GetRowNumber(localx);
7663 void AliTPCtrackerMI::MakeESDBitmaps(AliTPCseed *t, AliESDtrack *esd)
7665 //-----------------------------------------------------------------------
7666 // Fill the cluster and sharing bitmaps of the track
7667 //-----------------------------------------------------------------------
7669 Int_t firstpoint = 0;
7670 Int_t lastpoint = 159;
7671 AliTPCTrackerPoint *point;
7672 AliTPCclusterMI *cluster;
7675 TBits clusterMap(159);
7676 TBits sharedMap(159);
7678 for (int iter=firstpoint; iter<lastpoint; iter++) {
7679 // Change to cluster pointers to see if we have a cluster at given padrow
7681 cluster = t->GetClusterPointer(iter);
7683 clusterMap.SetBitNumber(iter, kTRUE);
7684 point = t->GetTrackPoint(iter);
7685 if (point->IsShared())
7686 sharedMap.SetBitNumber(iter,kTRUE);
7688 if (t->GetClusterIndex(iter) >= 0 && (t->GetClusterIndex(iter) & 0x8000) == 0) {
7689 fitMap.SetBitNumber(iter, kTRUE);
7693 esd->SetTPCClusterMap(clusterMap);
7694 esd->SetTPCSharedMap(sharedMap);
7695 esd->SetTPCFitMap(fitMap);
7696 if (nclsf != t->GetNumberOfClusters())
7697 AliWarning(Form("Inconsistency between ncls %d and indices %d (found %d)",t->GetNumberOfClusters(),nclsf,esd->GetTPCClusterMap().CountBits()));
7700 Bool_t AliTPCtrackerMI::IsFindable(AliTPCseed & track){
7702 // return flag if there is findable cluster at given position
7705 Float_t z = track.GetZ();
7707 if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*track.GetX()+kDeltaZ) &&
7708 TMath::Abs(z)<fkParam->GetZLength(0) &&
7709 (TMath::Abs(track.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
7715 void AliTPCtrackerMI::AddCovariance(AliTPCseed * seed){
7717 // Adding systematic error estimate to the covariance matrix
7718 // !!!! the systematic error for element 4 is in 1/GeV
7719 // 03.03.2012 MI changed in respect to the previous versions
7720 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
7722 // use only the diagonal part if not specified otherwise
7723 if (!AliTPCReconstructor::GetRecoParam()->GetUseSystematicCorrelation()) return AddCovarianceAdd(seed);
7725 Double_t *covarS= (Double_t*)seed->GetCovariance();
7726 Double_t factor[5]={1,1,1,1,1};
7727 factor[0]= TMath::Sqrt(TMath::Abs((covarS[0] + param[0]*param[0])/covarS[0]));
7728 factor[1]= TMath::Sqrt(TMath::Abs((covarS[2] + param[1]*param[1])/covarS[2]));
7729 factor[2]= TMath::Sqrt(TMath::Abs((covarS[5] + param[2]*param[2])/covarS[5]));
7730 factor[3]= TMath::Sqrt(TMath::Abs((covarS[9] + param[3]*param[3])/covarS[9]));
7731 factor[4]= TMath::Sqrt(TMath::Abs((covarS[14] +param[4]*param[4])/covarS[14]));
7733 factor[0]=factor[2];
7734 factor[4]=factor[2];
7740 for (Int_t i=0; i<5; i++){
7741 for (Int_t j=i; j<5; j++){
7742 Int_t index=seed->GetIndex(i,j);
7743 covarS[index]*=factor[i]*factor[j];
7749 void AliTPCtrackerMI::AddCovarianceAdd(AliTPCseed * seed){
7751 // Adding systematic error - as additive factor without correlation
7753 // !!!! the systematic error for element 4 is in 1/GeV
7754 // 03.03.2012 MI changed in respect to the previous versions
7756 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
7757 Double_t *covarIn= (Double_t*)seed->GetCovariance();
7759 for (Int_t i=0;i<15;i++) covar[i]=0;
7765 covar[0] = param[0]*param[0];
7766 covar[2] = param[1]*param[1];
7767 covar[5] = param[2]*param[2];
7768 covar[9] = param[3]*param[3];
7769 covar[14]= param[4]*param[4];
7771 covar[1]=TMath::Sqrt((covar[0]*covar[2]))*covarIn[1]/TMath::Sqrt((covarIn[0]*covarIn[2]));
7773 covar[3]=TMath::Sqrt((covar[0]*covar[5]))*covarIn[3]/TMath::Sqrt((covarIn[0]*covarIn[5]));
7774 covar[4]=TMath::Sqrt((covar[2]*covar[5]))*covarIn[4]/TMath::Sqrt((covarIn[2]*covarIn[5]));
7776 covar[6]=TMath::Sqrt((covar[0]*covar[9]))*covarIn[6]/TMath::Sqrt((covarIn[0]*covarIn[9]));
7777 covar[7]=TMath::Sqrt((covar[2]*covar[9]))*covarIn[7]/TMath::Sqrt((covarIn[2]*covarIn[9]));
7778 covar[8]=TMath::Sqrt((covar[5]*covar[9]))*covarIn[8]/TMath::Sqrt((covarIn[5]*covarIn[9]));
7780 covar[10]=TMath::Sqrt((covar[0]*covar[14]))*covarIn[10]/TMath::Sqrt((covarIn[0]*covarIn[14]));
7781 covar[11]=TMath::Sqrt((covar[2]*covar[14]))*covarIn[11]/TMath::Sqrt((covarIn[2]*covarIn[14]));
7782 covar[12]=TMath::Sqrt((covar[5]*covar[14]))*covarIn[12]/TMath::Sqrt((covarIn[5]*covarIn[14]));
7783 covar[13]=TMath::Sqrt((covar[9]*covar[14]))*covarIn[13]/TMath::Sqrt((covarIn[9]*covarIn[14]));
7785 seed->AddCovariance(covar);
7788 //_____________________________________________________________________________
7789 Bool_t AliTPCtrackerMI::IsTPCHVDipEvent(AliESDEvent const *esdEvent) {
7791 // check events affected by TPC HV dip
7793 if(!esdEvent) return kFALSE;
7796 if(!AliTPCcalibDB::Instance()) return kFALSE;
7797 AliTPCcalibDB::Instance()->SetRun(esdEvent->GetRunNumber());
7799 // Get HV TPC chamber sensors and calculate the median
7800 AliDCSSensorArray *voltageArray= AliTPCcalibDB::Instance()->GetVoltageSensors(esdEvent->GetRunNumber());
7801 if(!voltageArray) return kFALSE;
7803 TString sensorName="";
7804 Double_t kTPCHVdip = 2.0; // allow for 2V dip as compared to median from given sensor
7807 for(Int_t sector=0; sector<72; sector++)
7809 Char_t sideName='A';
7810 if ((sector/18)%2==1) sideName='C';
7813 sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,sector%18);
7816 sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,sector%18);
7819 AliDCSSensor* sensor = voltageArray->GetSensor(sensorName.Data());
7820 if(!sensor) continue;
7821 TGraph *graph = sensor->GetGraph();
7822 if(!graph) continue;
7823 Double_t median = TMath::Median(graph->GetN(), graph->GetY());
7824 if(median == 0) continue;
7826 //printf("chamber %d, sensor %s, HV %f, median %f\n", sector, sensorName.Data(), sensor->GetValue(esdEvent->GetTimeStamp()), median);
7828 if(TMath::Abs(sensor->GetValue(esdEvent->GetTimeStamp())-median)>kTPCHVdip) {
7836 //________________________________________
7837 void AliTPCtrackerMI::MarkSeedFree(TObject *sd)
7839 // account that this seed is "deleted"
7840 AliTPCseed* seed = dynamic_cast<AliTPCseed*>(sd);
7842 AliError(Form("Freeing of non-AliTPCseed %p from the pool is requested",sd));
7845 int id = seed->GetPoolID();
7847 AliError(Form("Freeing of seed %p NOT from the pool is requested",sd));
7850 // AliInfo(Form("%d %p",id, seed));
7851 fSeedsPool->RemoveAt(id);
7852 if (fFreeSeedsID.GetSize()<=fNFreeSeeds) fFreeSeedsID.Set( 2*fNFreeSeeds + 100 );
7853 fFreeSeedsID.GetArray()[fNFreeSeeds++] = id;
7856 //________________________________________
7857 TObject *&AliTPCtrackerMI::NextFreeSeed()
7859 // return next free slot where the seed can be created
7860 fLastSeedID = fNFreeSeeds ? fFreeSeedsID.GetArray()[--fNFreeSeeds] : fSeedsPool->GetEntriesFast();
7861 // AliInfo(Form("%d",fLastSeedID));
7862 return (*fSeedsPool)[ fLastSeedID ];
7866 //________________________________________
7867 void AliTPCtrackerMI::ResetSeedsPool()
7869 // mark all seeds in the pool as unused
7870 AliInfo(Form("CurrentSize: %d, BookedUpTo: %d, free: %d",fSeedsPool->GetSize(),fSeedsPool->GetEntriesFast(),fNFreeSeeds));
7872 fSeedsPool->Clear("C"); // RS: nominally the seeds may allocate memory...
7875 Int_t AliTPCtrackerMI::PropagateToRowHLT(AliTPCseed *pt, int nrow)
7878 Double_t x= GetXrow(nrow);
7879 Double_t ymax= GetMaxY(nrow);
7885 if (!t.PropagateTo(x) ){
7886 //cout<<"can't propagate to row "<<nrow<<", x="<<t.GetX()<<" -> "<<x<<endl;
7892 Double_t y = t.GetY();
7894 if( rotate!=-1 ) rotate=1;
7895 } else if (y <-ymax) {
7896 if( rotate!=1 ) rotate = -1;
7898 if( rotate==0 ) break;
7899 //cout<<"rotate at row "<<nrow<<": "<<rotate<<endl;
7900 if (!t.Rotate( rotate==1 ?fSectors->GetAlpha() :-fSectors->GetAlpha())) {
7901 //cout<<"can't rotate "<<endl;
7905 nRotations+= rotate;
7907 if( nRotations!=0 ){
7908 int newSec= t.GetRelativeSector()+nRotations;
7909 if( newSec>=fN ) newSec-=fN;
7910 else if( newSec<0 ) newSec +=fN;
7911 //cout<<"rotate at row "<<nrow<<": "<<nRotations<<" times "<<" sec "
7912 //<< t.GetRelativeSector()<<" -> "<<newSec<<endl;
7913 t.SetRelativeSector(newSec);
7918 void AliTPCtrackerMI::TrackFollowingHLT(TObjArray *const arr )
7921 // try to track in parralel
7923 Int_t nRows=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7926 Int_t nseed=arr->GetEntriesFast();
7927 //cout<<"Parallel tracking My.."<<endl;
7928 double shapeY2[160], shapeZ2[160];
7929 Int_t clusterIndex[160];
7931 for (Int_t iSeed=0; iSeed<nseed; iSeed++) {
7932 //if( iSeed!=1 ) continue;
7933 AliTPCseed *pt=(AliTPCseed*) (arr->UncheckedAt(iSeed));
7937 //cout <<"Pt "<<t.GetSigned1Pt()<<endl;
7941 for( int iter=0; iter<3; iter++ ){
7944 t.SetLastPoint(0); // first cluster in track position
7945 t.SetFirstPoint(nRows-1);
7946 t.ResetCovariance(.1);
7947 t.SetNumberOfClusters(0);
7948 for( int i=0; i<nRows; i++ ){
7952 t.SetClusterIndex2(i,-1);
7953 t.SetClusterIndex(i,-1);
7956 // pick up the clusters
7958 Double_t roady = 20.;
7959 Double_t roadz = 20.;
7966 t0.SetRelativeSector(t.GetRelativeSector());
7967 t0.SetLastPoint(0); // first cluster in track position
7968 t0.SetFirstPoint(159);
7969 for (Int_t nr=0; nr<nRows; nr++){
7970 if( nr<fInnerSec->GetNRows() ) fSectors=fInnerSec;
7971 else fSectors=fOuterSec;
7973 if( !PropagateToRowHLT(&t0, nr ) ){ break; }
7974 if (TMath::Abs(t0.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
7975 //cout<<"Snp is too big: "<<t0.GetSnp()<<endl;
7978 if (!IsActive(t0.GetRelativeSector(),nr)) {
7984 shapeY2[nr]=t0.GetCurrentSigmaY2();
7985 shapeZ2[nr]=t0.GetCurrentSigmaZ2();
7988 AliTPCtrackerRow &krow=GetRow(t0.GetRelativeSector(),nr);
7989 if( !krow ) continue;
7991 t.SetClusterIndex2(nr,-3); // foundable
7992 t.SetClusterIndex(nr,-3);
7994 AliTPCclusterMI *cl=0;
7996 cl = krow.FindNearest2(t0.GetY(),t0.GetZ(),roady,roadz,uindex);
7998 double dy = cl->GetY()-t0.GetY();
7999 double dz = cl->GetZ()-t0.GetZ();
8000 double dr = sqrt(dy*dy+dz*dz);
8002 //cout<<"row "<<nr<<", best cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8005 //cout<<"row "<<nr<<", found cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8007 t0.SetClusterPointer(nr, cl);
8008 clusterIndex[nr] = krow.GetIndex(uindex);
8009 if( t0.GetFirstPoint()>nr ) t0.SetFirstPoint(nr);
8010 t0.SetLastPoint(nr);
8016 //cout<<"NOT ENOUGTH CLUSTERS: "<<nClusters<<endl;
8019 Int_t basePoints[3] = {t0.GetFirstPoint(),t0.GetFirstPoint(),t0.GetLastPoint()};
8023 Int_t midRow = (t0.GetLastPoint()-t0.GetFirstPoint())/2;
8025 for( int nr=t0.GetFirstPoint()+1; nr< t0.GetLastPoint(); nr++){
8026 if( !t0.GetClusterPointer(nr) ) continue;
8027 int d = TMath::Abs(nr-midRow);
8035 // first fit 3 base points
8037 //cout<<"Fit3: "<<endl;
8038 for( int icl=0; icl<3; icl++){
8039 int nr = basePoints[icl];
8041 if( nr>=fInnerSec->GetNRows()){
8042 lr = nr - fInnerSec->GetNRows();
8044 } else fSectors=fInnerSec;
8046 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8048 //cout<<"WRONG!!!!"<<endl;
8051 int iSec = cl->GetDetector() %fkNIS;
8052 int rotate = iSec - t.GetRelativeSector();
8054 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8055 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8056 //cout<<"can't rotate "<<endl;
8059 t.SetRelativeSector(iSec);
8061 Double_t x= cl->GetX();
8062 if (!t.PropagateTo(x)){
8063 //cout<<"can't propagate to x="<<x<<endl;
8067 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8068 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8071 //cout<<"fit3 : row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8073 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8074 t.SetCurrentCluster(cl);
8077 t.SetErrorY2(shapeY2[nr]);
8078 t.SetErrorZ2(shapeZ2[nr]);
8081 for( int j=0; j<15; j++ ) cov[j]=0;
8087 t.AliExternalTrackParam::AddCovariance(cov);
8089 if( !UpdateTrack(&t,0) ){
8090 //cout<<"Can not update"<<endl;
8092 t.SetClusterIndex2(nr,-1);
8093 t.SetClusterIndex(nr,-1);
8094 t.SetClusterPointer(nr,0);
8097 //t.SetClusterPointer(nr, cl);
8100 //t.SetLastPoint(t0.GetLastPoint());
8101 //t.SetFirstPoint(t0.GetFirstPoint());
8103 //cout<<"Fit: "<<endl;
8104 for (Int_t nr=t0.GetLastPoint(); nr>=t0.GetFirstPoint(); nr-- ){
8106 if( nr>=fInnerSec->GetNRows()){
8107 lr = nr - fInnerSec->GetNRows();
8109 } else fSectors=fInnerSec;
8112 if( nr == basePoints[0] ) continue;
8113 if( nr == basePoints[1] ) continue;
8114 if( nr == basePoints[2] ) continue;
8116 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8119 int iSec = cl->GetDetector() %fkNIS;
8120 int rotate = iSec - t.GetRelativeSector();
8122 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8123 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8124 //cout<<"can't rotate "<<endl;
8127 t.SetRelativeSector(iSec);
8129 Double_t x= cl->GetX();
8130 if (!t.PropagateTo(x)){
8131 //cout<<"can't propagate to x="<<x<<endl;
8134 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8135 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8139 //cout<<"fit: row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8141 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8142 t.SetCurrentCluster(cl);
8144 t.SetErrorY2(shapeY2[nr]);
8145 t.SetErrorZ2(shapeZ2[nr]);
8147 if( !UpdateTrack(&t,0) ){
8148 //cout<<"Can not update"<<endl;
8150 t.SetClusterIndex2(nr,-1);
8151 t.SetClusterIndex(nr,-1);
8154 //t.SetClusterPointer(nr, cl);
8157 //cout<<"After iter "<<iter<<": N clusters="<<t.GetNumberOfClusters()<<" : "<<nClusters<<endl;
8160 //cout<<"fitted track"<<iSeed<<endl;
8162 //cout<<"Statistics: "<<endl;
8163 Int_t foundable,found,shared;
8164 t.GetClusterStatistic(0,nRows, found, foundable, shared, kTRUE);
8165 t.SetNFoundable(foundable);
8166 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8172 TObjArray * AliTPCtrackerMI::MakeSeedsHLT(const AliESDEvent *hltEvent)
8177 if( !hltEvent ) return 0;
8180 Int_t nentr=hltEvent->GetNumberOfTracks();
8182 AliInfo(Form("Using %d HLT tracks for seeding",nentr));
8184 TObjArray * seeds = new TObjArray(nentr);
8186 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8189 Int_t nTr=hltEvent->GetNumberOfTracks();
8191 for( int itr=0; itr<nTr; itr++ ){
8192 //if( itr!=97 ) continue;
8193 const AliExternalTrackParam *param = hltEvent->GetTrack(itr)->GetTPCInnerParam();
8194 if( !param ) continue;
8195 //if( TMath::Abs(esdTr->GetSigned1Pt())>1 ) continue;
8196 //if( TMath::Abs(esdTr->GetTgl())>1. ) continue;
8198 tr.Set(param->GetX(),param->GetAlpha(),param->GetParameter(),param->GetCovariance());
8199 tr.SetNumberOfClusters(0);
8200 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed(tr);
8202 Double_t alpha=seed->GetAlpha();// - fSectors->GetAlphaShift();
8203 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
8204 if (alpha < 0. ) alpha += 2.*TMath::Pi();
8206 seed->SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
8207 Double_t alphaSec = fSectors->GetAlpha() * seed->GetRelativeSector() + fSectors->GetAlphaShift();
8209 if (alphaSec >= TMath::Pi()) alphaSec -= 2.*TMath::Pi();
8210 if (alphaSec < -TMath::Pi()) alphaSec += 2.*TMath::Pi();
8212 seed->Rotate(alphaSec - alpha);
8214 seed->SetPoolID(fLastSeedID);
8215 seed->SetIsSeeding(kTRUE);
8216 seed->SetSeed1(nup-1);
8217 seed->SetSeed2(nup-2);
8218 seed->SetSeedType(0);
8219 seed->SetFirstPoint(-1);
8220 seed->SetLastPoint(-1);
8221 seeds->AddLast(seed); // note, track is seed, don't free the seed
8223 //if( index>3 ) break;
8227 fSectors = fOuterSec;
8229 TrackFollowingHLT(seeds );
8231 nTr = seeds->GetEntriesFast();
8232 for( int itr=0; itr<nTr; itr++ ){
8233 AliTPCseed * seed = (AliTPCseed*) seeds->UncheckedAt(itr);
8234 if( !seed ) continue;
8235 //FollowBackProlongation(*seed,0);
8236 // cout<<seed->GetNumberOfClusters()<<endl;
8237 Int_t foundable,found,shared;
8238 seed->GetClusterStatistic(0,nup, found, foundable, shared, kTRUE);
8239 seed->SetNFoundable(foundable);
8240 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8241 //if ((found<0.55*foundable) || shared>0.5*found ){// || (seed->GetSigmaY2()+seed->GetSigmaZ2())>0.5){
8242 //MarkSeedFree(seeds->RemoveAt(itr));
8245 if (seed->GetNumberOfClusters()<30 ||
8246 seed->GetNumberOfClusters() < seed->GetNFoundable()*0.6 ||
8247 seed->GetNShared()>0.4*seed->GetNumberOfClusters() ) {
8248 MarkSeedFree(seeds->RemoveAt(itr));
8252 for( int ir=0; ir<nup; ir++){
8253 AliTPCclusterMI *c = seed->GetClusterPointer(ir);
8257 std::cout<<"\n\nHLT tracks left: "<<seeds->GetEntries()<<" out of "<<hltEvent->GetNumberOfTracks()<<endl<<endl;