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>
117 #include <TTimeStamp.h>
119 #include "AliComplexCluster.h"
120 #include "AliESDEvent.h"
121 #include "AliESDtrack.h"
122 #include "AliESDVertex.h"
125 #include "AliHelix.h"
126 #include "AliRunLoader.h"
127 #include "AliTPCClustersRow.h"
128 #include "AliTPCParam.h"
129 #include "AliTPCReconstructor.h"
130 #include "AliTPCpolyTrack.h"
131 #include "AliTPCreco.h"
132 #include "AliTPCseed.h"
134 #include "AliTPCtrackerSector.h"
135 #include "AliTPCtrackerMI.h"
136 #include "TStopwatch.h"
137 #include "AliTPCReconstructor.h"
138 #include "AliAlignObj.h"
139 #include "AliTrackPointArray.h"
141 #include "AliTPCcalibDB.h"
142 #include "AliTPCcalibDButil.h"
143 #include "AliTPCTransform.h"
144 #include "AliTPCClusterParam.h"
145 #include "AliTPCdEdxInfo.h"
146 #include "AliDCSSensorArray.h"
147 #include "AliDCSSensor.h"
149 #include "AliCosmicTracker.h"
155 ClassImp(AliTPCtrackerMI)
159 class AliTPCFastMath {
162 static Double_t FastAsin(Double_t x);
164 static Double_t fgFastAsin[20000]; //lookup table for fast asin computation
167 Double_t AliTPCFastMath::fgFastAsin[20000];
168 AliTPCFastMath gAliTPCFastMath; // needed to fill the LUT
170 AliTPCFastMath::AliTPCFastMath(){
172 // initialized lookup table;
173 for (Int_t i=0;i<10000;i++){
174 fgFastAsin[2*i] = TMath::ASin(i/10000.);
175 fgFastAsin[2*i+1] = (TMath::ASin((i+1)/10000.)-fgFastAsin[2*i]);
179 Double_t AliTPCFastMath::FastAsin(Double_t x){
181 // return asin using lookup table
183 Int_t index = int(x*10000);
184 return fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1];
187 Int_t index = int(x*10000);
188 return -(fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1]);
190 //__________________________________________________________________
191 AliTPCtrackerMI::AliTPCtrackerMI()
219 // default constructor
221 for (Int_t irow=0; irow<200; irow++){
228 //_____________________________________________________________________
232 Int_t AliTPCtrackerMI::UpdateTrack(AliTPCseed * track, Int_t accept){
234 //update track information using current cluster - track->fCurrentCluster
237 AliTPCclusterMI* c =track->GetCurrentCluster();
238 if (accept > 0) //sign not accepted clusters
239 track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() | 0x8000);
240 else // unsign accpeted clusters
241 track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() & 0xffff7fff);
242 UInt_t i = track->GetCurrentClusterIndex1();
244 Int_t sec=(i&0xff000000)>>24;
245 //Int_t row = (i&0x00ff0000)>>16;
246 track->SetRow((i&0x00ff0000)>>16);
247 track->SetSector(sec);
248 // Int_t index = i&0xFFFF;
249 if (sec>=fkParam->GetNInnerSector()) track->SetRow(track->GetRow()+fkParam->GetNRowLow());
250 track->SetClusterIndex2(track->GetRow(), i);
251 //track->fFirstPoint = row;
252 //if ( track->fLastPoint<row) track->fLastPoint =row;
253 // if (track->fRow<0 || track->fRow>160) {
254 // printf("problem\n");
256 if (track->GetFirstPoint()>track->GetRow())
257 track->SetFirstPoint(track->GetRow());
258 if (track->GetLastPoint()<track->GetRow())
259 track->SetLastPoint(track->GetRow());
262 track->SetClusterPointer(track->GetRow(),c);
265 Double_t angle2 = track->GetSnp()*track->GetSnp();
267 //SET NEW Track Point
269 if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
271 angle2 = TMath::Sqrt(angle2/(1-angle2));
272 AliTPCTrackerPoint &point =*(track->GetTrackPoint(track->GetRow()));
274 point.SetSigmaY(c->GetSigmaY2()/track->GetCurrentSigmaY2());
275 point.SetSigmaZ(c->GetSigmaZ2()/track->GetCurrentSigmaZ2());
276 point.SetErrY(sqrt(track->GetErrorY2()));
277 point.SetErrZ(sqrt(track->GetErrorZ2()));
279 point.SetX(track->GetX());
280 point.SetY(track->GetY());
281 point.SetZ(track->GetZ());
282 point.SetAngleY(angle2);
283 point.SetAngleZ(track->GetTgl());
284 if (point.IsShared()){
285 track->SetErrorY2(track->GetErrorY2()*4);
286 track->SetErrorZ2(track->GetErrorZ2()*4);
290 Double_t chi2 = track->GetPredictedChi2(track->GetCurrentCluster());
292 // track->SetErrorY2(track->GetErrorY2()*1.3);
293 // track->SetErrorY2(track->GetErrorY2()+0.01);
294 // track->SetErrorZ2(track->GetErrorZ2()*1.3);
295 // track->SetErrorZ2(track->GetErrorZ2()+0.005);
297 if (accept>0) return 0;
298 if (track->GetNumberOfClusters()%20==0){
299 // if (track->fHelixIn){
300 // TClonesArray & larr = *(track->fHelixIn);
301 // Int_t ihelix = larr.GetEntriesFast();
302 // new(larr[ihelix]) AliHelix(*track) ;
305 track->SetNoCluster(0);
306 return track->Update(c,chi2,i);
311 Int_t AliTPCtrackerMI::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster)
314 // decide according desired precision to accept given
315 // cluster for tracking
317 seed->GetProlongation(cluster->GetX(),yt,zt);
318 Double_t sy2=ErrY2(seed,cluster);
319 Double_t sz2=ErrZ2(seed,cluster);
321 Double_t sdistancey2 = sy2+seed->GetSigmaY2();
322 Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
323 Double_t dy=seed->GetCurrentCluster()->GetY()-yt;
324 Double_t dz=seed->GetCurrentCluster()->GetZ()-zt;
325 Double_t rdistancey2 = (seed->GetCurrentCluster()->GetY()-yt)*
326 (seed->GetCurrentCluster()->GetY()-yt)/sdistancey2;
327 Double_t rdistancez2 = (seed->GetCurrentCluster()->GetZ()-zt)*
328 (seed->GetCurrentCluster()->GetZ()-zt)/sdistancez2;
330 Double_t rdistance2 = rdistancey2+rdistancez2;
333 if (AliTPCReconstructor::StreamLevel()>2 && seed->GetNumberOfClusters()>20) {
334 Float_t rmsy2 = seed->GetCurrentSigmaY2();
335 Float_t rmsz2 = seed->GetCurrentSigmaZ2();
336 Float_t rmsy2p30 = seed->GetCMeanSigmaY2p30();
337 Float_t rmsz2p30 = seed->GetCMeanSigmaZ2p30();
338 Float_t rmsy2p30R = seed->GetCMeanSigmaY2p30R();
339 Float_t rmsz2p30R = seed->GetCMeanSigmaZ2p30R();
340 AliExternalTrackParam param(*seed);
341 static TVectorD gcl(3),gtr(3);
343 param.GetXYZ(gcl.GetMatrixArray());
344 cluster->GetGlobalXYZ(gclf);
345 gcl[0]=gclf[0]; gcl[1]=gclf[1]; gcl[2]=gclf[2];
348 if (AliTPCReconstructor::StreamLevel()>2) {
349 (*fDebugStreamer)<<"ErrParam"<<
362 "rmsy2p30="<<rmsy2p30<<
363 "rmsz2p30="<<rmsz2p30<<
364 "rmsy2p30R="<<rmsy2p30R<<
365 "rmsz2p30R="<<rmsz2p30R<<
366 // normalize distance -
367 "rdisty="<<rdistancey2<<
368 "rdistz="<<rdistancez2<<
369 "rdist="<<rdistance2<< //
373 //return 0; // temporary
374 if (rdistance2>32) return 3;
377 if ((rdistancey2>9. || rdistancez2>9.) && cluster->GetType()==0)
378 return 2; //suspisiouce - will be changed
380 if ((rdistancey2>6.25 || rdistancez2>6.25) && cluster->GetType()>0)
381 // strict cut on overlaped cluster
382 return 2; //suspisiouce - will be changed
384 if ( (rdistancey2>1. || rdistancez2>6.25 )
385 && cluster->GetType()<0){
386 seed->SetNFoundable(seed->GetNFoundable()-1);
390 if (fUseHLTClusters == 3 || fUseHLTClusters == 4) {
392 if(!AliTPCReconstructor::GetRecoParam()->GetUseHLTOnePadCluster()) {
393 if (TMath::Abs(cluster->GetSigmaY2()) < kAlmost0)
406 //_____________________________________________________________________________
407 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCParam *par):
409 fkNIS(par->GetNInnerSector()/2),
411 fkNOS(par->GetNOuterSector()/2),
434 //---------------------------------------------------------------------
435 // The main TPC tracker constructor
436 //---------------------------------------------------------------------
437 fInnerSec=new AliTPCtrackerSector[fkNIS];
438 fOuterSec=new AliTPCtrackerSector[fkNOS];
441 for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
442 for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
445 Int_t nrowlow = par->GetNRowLow();
446 Int_t nrowup = par->GetNRowUp();
449 for (i=0;i<nrowlow;i++){
450 fXRow[i] = par->GetPadRowRadiiLow(i);
451 fPadLength[i]= par->GetPadPitchLength(0,i);
452 fYMax[i] = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
456 for (i=0;i<nrowup;i++){
457 fXRow[i+nrowlow] = par->GetPadRowRadiiUp(i);
458 fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
459 fYMax[i+nrowlow] = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
462 if (AliTPCReconstructor::StreamLevel()>0) {
463 fDebugStreamer = new TTreeSRedirector("TPCdebug.root");
466 fSeedsPool = new TClonesArray("AliTPCseed",1000);
468 //________________________________________________________________________
469 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCtrackerMI &t):
496 //------------------------------------
497 // dummy copy constructor
498 //------------------------------------------------------------------
500 for (Int_t irow=0; irow<200; irow++){
507 AliTPCtrackerMI & AliTPCtrackerMI::operator=(const AliTPCtrackerMI& /*r*/)
509 //------------------------------
511 //--------------------------------------------------------------
514 //_____________________________________________________________________________
515 AliTPCtrackerMI::~AliTPCtrackerMI() {
516 //------------------------------------------------------------------
517 // TPC tracker destructor
518 //------------------------------------------------------------------
525 if (fDebugStreamer) delete fDebugStreamer;
526 if (fSeedsPool) delete fSeedsPool;
530 void AliTPCtrackerMI::FillESD(const TObjArray* arr)
534 //fill esds using updated tracks
537 // write tracks to the event
538 // store index of the track
539 Int_t nseed=arr->GetEntriesFast();
540 //FindKinks(arr,fEvent);
541 for (Int_t i=0; i<nseed; i++) {
542 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
546 if (AliTPCReconstructor::StreamLevel()>1) {
547 (*fDebugStreamer)<<"Track0"<<
551 // pt->PropagateTo(fkParam->GetInnerRadiusLow());
552 if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
553 pt->PropagateTo(fkParam->GetInnerRadiusLow());
556 if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
558 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
559 iotrack.SetTPCPoints(pt->GetPoints());
560 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
561 iotrack.SetV0Indexes(pt->GetV0Indexes());
562 // iotrack.SetTPCpid(pt->fTPCr);
563 //iotrack.SetTPCindex(i);
564 MakeESDBitmaps(pt, &iotrack);
565 fEvent->AddTrack(&iotrack);
569 if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
571 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
572 iotrack.SetTPCPoints(pt->GetPoints());
573 //iotrack.SetTPCindex(i);
574 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
575 iotrack.SetV0Indexes(pt->GetV0Indexes());
576 MakeESDBitmaps(pt, &iotrack);
577 // iotrack.SetTPCpid(pt->fTPCr);
578 fEvent->AddTrack(&iotrack);
582 // short tracks - maybe decays
584 if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
585 Int_t found,foundable,shared;
586 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
587 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
589 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
590 //iotrack.SetTPCindex(i);
591 iotrack.SetTPCPoints(pt->GetPoints());
592 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
593 iotrack.SetV0Indexes(pt->GetV0Indexes());
594 MakeESDBitmaps(pt, &iotrack);
595 //iotrack.SetTPCpid(pt->fTPCr);
596 fEvent->AddTrack(&iotrack);
601 if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
602 Int_t found,foundable,shared;
603 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
604 if (found<20) continue;
605 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
608 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
609 iotrack.SetTPCPoints(pt->GetPoints());
610 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
611 iotrack.SetV0Indexes(pt->GetV0Indexes());
612 MakeESDBitmaps(pt, &iotrack);
613 //iotrack.SetTPCpid(pt->fTPCr);
614 //iotrack.SetTPCindex(i);
615 fEvent->AddTrack(&iotrack);
618 // short tracks - secondaties
620 if ( (pt->GetNumberOfClusters()>30) ) {
621 Int_t found,foundable,shared;
622 pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
623 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
625 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
626 iotrack.SetTPCPoints(pt->GetPoints());
627 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
628 iotrack.SetV0Indexes(pt->GetV0Indexes());
629 MakeESDBitmaps(pt, &iotrack);
630 //iotrack.SetTPCpid(pt->fTPCr);
631 //iotrack.SetTPCindex(i);
632 fEvent->AddTrack(&iotrack);
637 if ( (pt->GetNumberOfClusters()>15)) {
638 Int_t found,foundable,shared;
639 pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
640 if (found<15) continue;
641 if (foundable<=0) continue;
642 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
643 if (float(found)/float(foundable)<0.8) continue;
646 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
647 iotrack.SetTPCPoints(pt->GetPoints());
648 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
649 iotrack.SetV0Indexes(pt->GetV0Indexes());
650 MakeESDBitmaps(pt, &iotrack);
651 // iotrack.SetTPCpid(pt->fTPCr);
652 //iotrack.SetTPCindex(i);
653 fEvent->AddTrack(&iotrack);
657 // >> account for suppressed tracks in the kink indices (RS)
658 int nESDtracks = fEvent->GetNumberOfTracks();
659 for (int it=nESDtracks;it--;) {
660 AliESDtrack* esdTr = fEvent->GetTrack(it);
661 if (!esdTr || !esdTr->GetKinkIndex(0)) continue;
662 for (int ik=0;ik<3;ik++) {
664 if (!(knkId=esdTr->GetKinkIndex(ik))) break; // no more kinks for this track
665 AliESDkink* kink = fEvent->GetKink(TMath::Abs(knkId)-1);
667 AliError(Form("ESDTrack%d refers to non-existing kink %d",it,TMath::Abs(knkId)-1));
670 kink->SetIndex(it, knkId<0 ? 0:1); // update track index of the kink: mother at 0, daughter at 1
673 // << account for suppressed tracks in the kink indices (RS)
674 AliInfo(Form("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks()));
682 Double_t AliTPCtrackerMI::ErrY2(AliTPCseed* seed, const AliTPCclusterMI * cl){
685 // Use calibrated cluster error from OCDB
687 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
689 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
690 Int_t ctype = cl->GetType();
691 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
692 Double_t angle = seed->GetSnp()*seed->GetSnp();
693 angle = TMath::Sqrt(TMath::Abs(angle/(1.-angle)));
694 Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
696 erry2+=0.5; // edge cluster
700 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
701 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
702 erry2+=addErr*addErr;
703 seed->SetErrorY2(erry2);
707 //calculate look-up table at the beginning
708 // static Bool_t ginit = kFALSE;
709 // static Float_t gnoise1,gnoise2,gnoise3;
710 // static Float_t ggg1[10000];
711 // static Float_t ggg2[10000];
712 // static Float_t ggg3[10000];
713 // static Float_t glandau1[10000];
714 // static Float_t glandau2[10000];
715 // static Float_t glandau3[10000];
717 // static Float_t gcor01[500];
718 // static Float_t gcor02[500];
719 // static Float_t gcorp[500];
723 // if (ginit==kFALSE){
724 // for (Int_t i=1;i<500;i++){
725 // Float_t rsigma = float(i)/100.;
726 // gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
727 // gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
728 // gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
732 // for (Int_t i=3;i<10000;i++){
736 // Float_t amp = float(i);
737 // Float_t padlength =0.75;
738 // gnoise1 = 0.0004/padlength;
739 // Float_t nel = 0.268*amp;
740 // Float_t nprim = 0.155*amp;
741 // ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
742 // glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
743 // if (glandau1[i]>1) glandau1[i]=1;
744 // glandau1[i]*=padlength*padlength/12.;
748 // gnoise2 = 0.0004/padlength;
750 // nprim = 0.133*amp;
751 // ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
752 // glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
753 // if (glandau2[i]>1) glandau2[i]=1;
754 // glandau2[i]*=padlength*padlength/12.;
759 // gnoise3 = 0.0004/padlength;
761 // nprim = 0.133*amp;
762 // ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
763 // glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
764 // if (glandau3[i]>1) glandau3[i]=1;
765 // glandau3[i]*=padlength*padlength/12.;
773 // Int_t amp = int(TMath::Abs(cl->GetQ()));
775 // seed->SetErrorY2(1.);
779 // Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
780 // Int_t ctype = cl->GetType();
781 // Float_t padlength= GetPadPitchLength(seed->GetRow());
782 // Double_t angle2 = seed->GetSnp()*seed->GetSnp();
783 // angle2 = angle2/(1-angle2);
785 // //cluster "quality"
786 // Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
789 // if (fSectors==fInnerSec){
790 // snoise2 = gnoise1;
791 // res = ggg1[amp]*z+glandau1[amp]*angle2;
792 // if (ctype==0) res *= gcor01[rsigmay];
795 // res*= gcorp[rsigmay];
799 // if (padlength<1.1){
800 // snoise2 = gnoise2;
801 // res = ggg2[amp]*z+glandau2[amp]*angle2;
802 // if (ctype==0) res *= gcor02[rsigmay];
805 // res*= gcorp[rsigmay];
809 // snoise2 = gnoise3;
810 // res = ggg3[amp]*z+glandau3[amp]*angle2;
811 // if (ctype==0) res *= gcor02[rsigmay];
814 // res*= gcorp[rsigmay];
821 // res*=2.4; // overestimate error 2 times
825 // if (res<2*snoise2)
828 // seed->SetErrorY2(res);
836 Double_t AliTPCtrackerMI::ErrZ2(AliTPCseed* seed, const AliTPCclusterMI * cl){
839 // Use calibrated cluster error from OCDB
841 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
843 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
844 Int_t ctype = cl->GetType();
845 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
847 Double_t angle2 = seed->GetSnp()*seed->GetSnp();
848 angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
849 Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
850 Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
852 errz2+=0.5; // edge cluster
856 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
857 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
858 errz2+=addErr*addErr;
859 seed->SetErrorZ2(errz2);
865 // //seed->SetErrorY2(0.1);
867 // //calculate look-up table at the beginning
868 // static Bool_t ginit = kFALSE;
869 // static Float_t gnoise1,gnoise2,gnoise3;
870 // static Float_t ggg1[10000];
871 // static Float_t ggg2[10000];
872 // static Float_t ggg3[10000];
873 // static Float_t glandau1[10000];
874 // static Float_t glandau2[10000];
875 // static Float_t glandau3[10000];
877 // static Float_t gcor01[1000];
878 // static Float_t gcor02[1000];
879 // static Float_t gcorp[1000];
883 // if (ginit==kFALSE){
884 // for (Int_t i=1;i<1000;i++){
885 // Float_t rsigma = float(i)/100.;
886 // gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
887 // gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
888 // gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
892 // for (Int_t i=3;i<10000;i++){
896 // Float_t amp = float(i);
897 // Float_t padlength =0.75;
898 // gnoise1 = 0.0004/padlength;
899 // Float_t nel = 0.268*amp;
900 // Float_t nprim = 0.155*amp;
901 // ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
902 // glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
903 // if (glandau1[i]>1) glandau1[i]=1;
904 // glandau1[i]*=padlength*padlength/12.;
908 // gnoise2 = 0.0004/padlength;
910 // nprim = 0.133*amp;
911 // ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
912 // glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
913 // if (glandau2[i]>1) glandau2[i]=1;
914 // glandau2[i]*=padlength*padlength/12.;
919 // gnoise3 = 0.0004/padlength;
921 // nprim = 0.133*amp;
922 // ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
923 // glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
924 // if (glandau3[i]>1) glandau3[i]=1;
925 // glandau3[i]*=padlength*padlength/12.;
933 // Int_t amp = int(TMath::Abs(cl->GetQ()));
935 // seed->SetErrorY2(1.);
939 // Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
940 // Int_t ctype = cl->GetType();
941 // Float_t padlength= GetPadPitchLength(seed->GetRow());
943 // Double_t angle2 = seed->GetSnp()*seed->GetSnp();
944 // // if (angle2<0.6) angle2 = 0.6;
945 // angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
947 // //cluster "quality"
948 // Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
951 // if (fSectors==fInnerSec){
952 // snoise2 = gnoise1;
953 // res = ggg1[amp]*z+glandau1[amp]*angle2;
954 // if (ctype==0) res *= gcor01[rsigmaz];
957 // res*= gcorp[rsigmaz];
961 // if (padlength<1.1){
962 // snoise2 = gnoise2;
963 // res = ggg2[amp]*z+glandau2[amp]*angle2;
964 // if (ctype==0) res *= gcor02[rsigmaz];
967 // res*= gcorp[rsigmaz];
971 // snoise2 = gnoise3;
972 // res = ggg3[amp]*z+glandau3[amp]*angle2;
973 // if (ctype==0) res *= gcor02[rsigmaz];
976 // res*= gcorp[rsigmaz];
985 // if ((ctype<0) &&<70){
990 // if (res<2*snoise2)
992 // if (res>3) res =3;
993 // seed->SetErrorZ2(res);
1001 void AliTPCtrackerMI::RotateToLocal(AliTPCseed *seed)
1003 //rotate to track "local coordinata
1004 Float_t x = seed->GetX();
1005 Float_t y = seed->GetY();
1006 Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
1009 seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
1010 if (!seed->Rotate(fSectors->GetAlpha()))
1012 } else if (y <-ymax) {
1013 seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
1014 if (!seed->Rotate(-fSectors->GetAlpha()))
1022 //_____________________________________________________________________________
1023 Double_t AliTPCtrackerMI::F1old(Double_t x1,Double_t y1,
1024 Double_t x2,Double_t y2,
1025 Double_t x3,Double_t y3) const
1027 //-----------------------------------------------------------------
1028 // Initial approximation of the track curvature
1029 //-----------------------------------------------------------------
1030 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1031 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1032 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1033 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1034 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1036 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1037 if ( xr*xr+yr*yr<=0.00000000000001) return 100;
1038 return -xr*yr/sqrt(xr*xr+yr*yr);
1043 //_____________________________________________________________________________
1044 Double_t AliTPCtrackerMI::F1(Double_t x1,Double_t y1,
1045 Double_t x2,Double_t y2,
1046 Double_t x3,Double_t y3) const
1048 //-----------------------------------------------------------------
1049 // Initial approximation of the track curvature
1050 //-----------------------------------------------------------------
1056 Double_t det = x3*y2-x2*y3;
1057 if (TMath::Abs(det)<1e-10){
1061 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1062 Double_t x0 = x3*0.5-y3*u;
1063 Double_t y0 = y3*0.5+x3*u;
1064 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1070 Double_t AliTPCtrackerMI::F2(Double_t x1,Double_t y1,
1071 Double_t x2,Double_t y2,
1072 Double_t x3,Double_t y3) const
1074 //-----------------------------------------------------------------
1075 // Initial approximation of the track curvature
1076 //-----------------------------------------------------------------
1082 Double_t det = x3*y2-x2*y3;
1083 if (TMath::Abs(det)<1e-10) {
1087 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1088 Double_t x0 = x3*0.5-y3*u;
1089 Double_t y0 = y3*0.5+x3*u;
1090 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1099 //_____________________________________________________________________________
1100 Double_t AliTPCtrackerMI::F2old(Double_t x1,Double_t y1,
1101 Double_t x2,Double_t y2,
1102 Double_t x3,Double_t y3) const
1104 //-----------------------------------------------------------------
1105 // Initial approximation of the track curvature times center of curvature
1106 //-----------------------------------------------------------------
1107 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1108 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1109 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1110 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1111 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1113 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1115 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1118 //_____________________________________________________________________________
1119 Double_t AliTPCtrackerMI::F3(Double_t x1,Double_t y1,
1120 Double_t x2,Double_t y2,
1121 Double_t z1,Double_t z2) const
1123 //-----------------------------------------------------------------
1124 // Initial approximation of the tangent of the track dip angle
1125 //-----------------------------------------------------------------
1126 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1130 Double_t AliTPCtrackerMI::F3n(Double_t x1,Double_t y1,
1131 Double_t x2,Double_t y2,
1132 Double_t z1,Double_t z2, Double_t c) const
1134 //-----------------------------------------------------------------
1135 // Initial approximation of the tangent of the track dip angle
1136 //-----------------------------------------------------------------
1140 //angle1 = (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1142 Double_t d = TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1143 if (TMath::Abs(d*c*0.5)>1) return 0;
1144 // Double_t angle2 = TMath::ASin(d*c*0.5);
1145 // Double_t angle2 = AliTPCFastMath::FastAsin(d*c*0.5);
1146 Double_t angle2 = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): AliTPCFastMath::FastAsin(d*c*0.5);
1148 angle2 = (z1-z2)*c/(angle2*2.);
1152 Bool_t AliTPCtrackerMI::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
1153 {//-----------------------------------------------------------------
1154 // This function find proloncation of a track to a reference plane x=x2.
1155 //-----------------------------------------------------------------
1159 if (TMath::Abs(x[4]*x1 - x[2]) >= 0.999) {
1163 Double_t c1=x[4]*x1 - x[2], r1=TMath::Sqrt((1.-c1)*(1.+c1));
1164 Double_t c2=x[4]*x2 - x[2], r2=TMath::Sqrt((1.-c2)*(1.+c2));
1168 Double_t dy = dx*(c1+c2)/(r1+r2);
1171 Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1173 if (TMath::Abs(delta)>0.01){
1174 dz = x[3]*TMath::ASin(delta)/x[4];
1176 dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1179 //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1187 Int_t AliTPCtrackerMI::LoadClusters (TTree *const tree)
1192 return LoadClusters();
1196 Int_t AliTPCtrackerMI::LoadClusters(const TObjArray *arr)
1199 // load clusters to the memory
1200 AliTPCClustersRow *clrow = new AliTPCClustersRow("AliTPCclusterMI");
1201 Int_t lower = arr->LowerBound();
1202 Int_t entries = arr->GetEntriesFast();
1204 for (Int_t i=lower; i<entries; i++) {
1205 clrow = (AliTPCClustersRow*) arr->At(i);
1206 if(!clrow) continue;
1207 if(!clrow->GetArray()) continue;
1211 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
1213 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1214 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1217 if (clrow->GetArray()->GetEntriesFast()<=0) continue;
1218 AliTPCtrackerRow * tpcrow=0;
1221 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1225 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1226 left = (sec-fkNIS*2)/fkNOS;
1229 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
1230 for (Int_t j=0;j<tpcrow->GetN1();++j)
1231 tpcrow->SetCluster1(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
1234 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
1235 for (Int_t j=0;j<tpcrow->GetN2();++j)
1236 tpcrow->SetCluster2(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
1238 clrow->GetArray()->Clear("C");
1244 ApllyTailCancellation();
1248 Int_t AliTPCtrackerMI::LoadClusters(const TClonesArray *arr)
1251 // load clusters to the memory from one
1254 AliTPCclusterMI *clust=0;
1255 Int_t count[72][96] = { {0} , {0} };
1257 // loop over clusters
1258 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1259 clust = (AliTPCclusterMI*)arr->At(icl);
1260 if(!clust) continue;
1261 //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
1263 // transform clusters
1266 // count clusters per pad row
1267 count[clust->GetDetector()][clust->GetRow()]++;
1270 // insert clusters to sectors
1271 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1272 clust = (AliTPCclusterMI*)arr->At(icl);
1273 if(!clust) continue;
1275 Int_t sec = clust->GetDetector();
1276 Int_t row = clust->GetRow();
1278 // filter overlapping pad rows needed by HLT
1279 if(sec<fkNIS*2) { //IROCs
1280 if(row == 30) continue;
1283 if(row == 27 || row == 76) continue;
1288 // left = sec/fkNIS;
1289 fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fkParam);
1292 // left = (sec-fkNIS*2)/fkNOS;
1293 fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fkParam);
1297 // Load functions must be called behind LoadCluster(TClonesArray*)
1299 //LoadOuterSectors();
1300 //LoadInnerSectors();
1306 Int_t AliTPCtrackerMI::LoadClusters()
1309 // load clusters to the memory
1310 static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
1312 // TTree * tree = fClustersArray.GetTree();
1314 TTree * tree = fInput;
1315 TBranch * br = tree->GetBranch("Segment");
1316 br->SetAddress(&clrow);
1318 // Conversion of pad, row coordinates in local tracking coords.
1319 // Could be skipped here; is already done in clusterfinder
1321 Int_t j=Int_t(tree->GetEntries());
1322 for (Int_t i=0; i<j; i++) {
1326 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
1327 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1328 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1331 AliTPCtrackerRow * tpcrow=0;
1334 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1338 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1339 left = (sec-fkNIS*2)/fkNOS;
1342 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
1343 for (Int_t k=0;k<tpcrow->GetN1();++k)
1344 tpcrow->SetCluster1(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
1347 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
1348 for (Int_t k=0;k<tpcrow->GetN2();++k)
1349 tpcrow->SetCluster2(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
1360 void AliTPCtrackerMI::UnloadClusters()
1363 // unload clusters from the memory
1365 Int_t nrows = fOuterSec->GetNRows();
1366 for (Int_t sec = 0;sec<fkNOS;sec++)
1367 for (Int_t row = 0;row<nrows;row++){
1368 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1370 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1371 // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1373 tpcrow->ResetClusters();
1376 nrows = fInnerSec->GetNRows();
1377 for (Int_t sec = 0;sec<fkNIS;sec++)
1378 for (Int_t row = 0;row<nrows;row++){
1379 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1381 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1382 //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1384 tpcrow->ResetClusters();
1390 void AliTPCtrackerMI::FillClusterArray(TObjArray* array) const{
1392 // Filling cluster to the array - For visualization purposes
1395 nrows = fOuterSec->GetNRows();
1396 for (Int_t sec = 0;sec<fkNOS;sec++)
1397 for (Int_t row = 0;row<nrows;row++){
1398 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1399 if (!tpcrow) continue;
1400 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1401 array->AddLast((TObject*)((*tpcrow)[icl]));
1404 nrows = fInnerSec->GetNRows();
1405 for (Int_t sec = 0;sec<fkNIS;sec++)
1406 for (Int_t row = 0;row<nrows;row++){
1407 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1408 if (!tpcrow) continue;
1409 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1410 array->AddLast((TObject*)(*tpcrow)[icl]);
1416 void AliTPCtrackerMI::Transform(AliTPCclusterMI * cluster){
1420 AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1421 AliTPCTransform *transform = calibDB->GetTransform() ;
1423 AliFatal("Tranformations not in calibDB");
1426 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
1427 Double_t x[3]={cluster->GetRow(),cluster->GetPad(),cluster->GetTimeBin()};
1428 Int_t i[1]={cluster->GetDetector()};
1429 transform->Transform(x,i,0,1);
1430 // if (cluster->GetDetector()%36>17){
1435 // in debug mode check the transformation
1437 if (AliTPCReconstructor::StreamLevel()>2) {
1439 cluster->GetGlobalXYZ(gx);
1440 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
1441 TTreeSRedirector &cstream = *fDebugStreamer;
1442 cstream<<"Transform"<<
1453 cluster->SetX(x[0]);
1454 cluster->SetY(x[1]);
1455 cluster->SetZ(x[2]);
1460 //if (!fkParam->IsGeoRead()) fkParam->ReadGeoMatrices();
1461 if (AliTPCReconstructor::GetRecoParam()->GetUseSectorAlignment() && (!calibDB->HasAlignmentOCDB())){
1462 TGeoHMatrix *mat = fkParam->GetClusterMatrix(cluster->GetDetector());
1464 Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1465 Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1466 if (mat) mat->LocalToMaster(pos,posC);
1468 // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
1470 cluster->SetX(posC[0]);
1471 cluster->SetY(posC[1]);
1472 cluster->SetZ(posC[2]);
1476 void AliTPCtrackerMI::ApllyTailCancellation(){
1478 // Correct the cluster charge for the tail from the previous clusters
1479 // The TimeResponse function accessed via AliTPCcalibDB (TPC/Calib/IonTail)
1483 for (Int_t secType=0; secType<2; secType++){ //loop inner or outer sector
1486 for (Int_t sec = 0;sec<fkNOS;sec++){ //loop overs sectors
1489 AliTPCtrackerSector §or= (secType==0)?fInnerSec[sec]:fOuterSec[sec];
1491 Int_t nrows = sector.GetNRows();
1492 for (Int_t row = 0;row<nrows;row++){ //loop over rows
1493 AliTPCtrackerRow& tpcrow = sector[row];
1494 Int_t ncl = tpcrow.GetN1();
1496 for (Int_t icl0=0; icl0<ncl;icl0++){ // first loop over clusters
1497 AliTPCclusterMI *cl0= (tpcrow.GetCluster1(icl0));
1498 if (!icl0) continue;
1499 for (Int_t icl1=0; icl1<ncl;icl1++){ // second loop over clusters
1500 AliTPCclusterMI *cl1= (tpcrow.GetCluster1(icl1));
1501 if (!icl1) continue;
1502 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())>2) continue; // no contribution if far away in pad direction
1503 if (cl1->GetTimeBin()> cl0->GetTimeBin()) continue; // no contibution to the tail if later
1504 Double_t ionTailMax=0; //
1505 Double_t ionTailTotal=0; //
1507 cl0->SetQ(cl0->GetQ()+ionTailTotal);
1508 cl0->SetMax(cl0->GetMax()+ionTailMax);
1509 if (AliTPCReconstructor::StreamLevel()>5) {
1510 TTreeSRedirector &cstream = *fDebugStreamer;
1511 cstream<<"IonTail"<<
1512 "cl0.="<<cl0<< // cluster 0 (to be corrected)
1513 "cl1.="<<cl1<< // cluster 1 (previous cluster)
1514 "ionTailTotal="<<ionTailTotal<< // ion Tail from cluster 1 contribution to cluster0
1515 "ionTailMax="<<ionTailMax<< // ion Tail from cluster 1 contribution to cluster0
1517 }// dump the results to the debug streamer if in debug mode
1518 }//end of secon loop over clusters
1519 }//end of first loop over cluster
1520 }//end of loop over rows
1521 }//end of loop over sectors
1522 }//end of loop over IROC/OROC
1528 //_____________________________________________________________________________
1529 Int_t AliTPCtrackerMI::LoadOuterSectors() {
1530 //-----------------------------------------------------------------
1531 // This function fills outer TPC sectors with clusters.
1532 //-----------------------------------------------------------------
1533 Int_t nrows = fOuterSec->GetNRows();
1535 for (Int_t sec = 0;sec<fkNOS;sec++)
1536 for (Int_t row = 0;row<nrows;row++){
1537 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1538 Int_t sec2 = sec+2*fkNIS;
1540 Int_t ncl = tpcrow->GetN1();
1542 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1543 index=(((sec2<<8)+row)<<16)+ncl;
1544 tpcrow->InsertCluster(c,index);
1547 ncl = tpcrow->GetN2();
1549 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1550 index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
1551 tpcrow->InsertCluster(c,index);
1554 // write indexes for fast acces
1556 for (Int_t i=0;i<510;i++)
1557 tpcrow->SetFastCluster(i,-1);
1558 for (Int_t i=0;i<tpcrow->GetN();i++){
1559 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1560 tpcrow->SetFastCluster(zi,i); // write index
1563 for (Int_t i=0;i<510;i++){
1564 if (tpcrow->GetFastCluster(i)<0)
1565 tpcrow->SetFastCluster(i,last);
1567 last = tpcrow->GetFastCluster(i);
1576 //_____________________________________________________________________________
1577 Int_t AliTPCtrackerMI::LoadInnerSectors() {
1578 //-----------------------------------------------------------------
1579 // This function fills inner TPC sectors with clusters.
1580 //-----------------------------------------------------------------
1581 Int_t nrows = fInnerSec->GetNRows();
1583 for (Int_t sec = 0;sec<fkNIS;sec++)
1584 for (Int_t row = 0;row<nrows;row++){
1585 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1588 Int_t ncl = tpcrow->GetN1();
1590 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1591 index=(((sec<<8)+row)<<16)+ncl;
1592 tpcrow->InsertCluster(c,index);
1595 ncl = tpcrow->GetN2();
1597 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1598 index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
1599 tpcrow->InsertCluster(c,index);
1602 // write indexes for fast acces
1604 for (Int_t i=0;i<510;i++)
1605 tpcrow->SetFastCluster(i,-1);
1606 for (Int_t i=0;i<tpcrow->GetN();i++){
1607 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1608 tpcrow->SetFastCluster(zi,i); // write index
1611 for (Int_t i=0;i<510;i++){
1612 if (tpcrow->GetFastCluster(i)<0)
1613 tpcrow->SetFastCluster(i,last);
1615 last = tpcrow->GetFastCluster(i);
1627 //_________________________________________________________________________
1628 AliTPCclusterMI *AliTPCtrackerMI::GetClusterMI(Int_t index) const {
1629 //--------------------------------------------------------------------
1630 // Return pointer to a given cluster
1631 //--------------------------------------------------------------------
1632 if (index<0) return 0; // no cluster
1633 Int_t sec=(index&0xff000000)>>24;
1634 Int_t row=(index&0x00ff0000)>>16;
1635 Int_t ncl=(index&0x00007fff)>>00;
1637 const AliTPCtrackerRow * tpcrow=0;
1638 TClonesArray * clrow =0;
1640 if (sec<0 || sec>=fkNIS*4) {
1641 AliWarning(Form("Wrong sector %d",sec));
1646 AliTPCtrackerSector& tracksec = fInnerSec[sec%fkNIS];
1647 if (tracksec.GetNRows()<=row) return 0;
1648 tpcrow = &(tracksec[row]);
1649 if (tpcrow==0) return 0;
1652 if (tpcrow->GetN1()<=ncl) return 0;
1653 clrow = tpcrow->GetClusters1();
1656 if (tpcrow->GetN2()<=ncl) return 0;
1657 clrow = tpcrow->GetClusters2();
1661 AliTPCtrackerSector& tracksec = fOuterSec[(sec-fkNIS*2)%fkNOS];
1662 if (tracksec.GetNRows()<=row) return 0;
1663 tpcrow = &(tracksec[row]);
1664 if (tpcrow==0) return 0;
1666 if (sec-2*fkNIS<fkNOS) {
1667 if (tpcrow->GetN1()<=ncl) return 0;
1668 clrow = tpcrow->GetClusters1();
1671 if (tpcrow->GetN2()<=ncl) return 0;
1672 clrow = tpcrow->GetClusters2();
1676 return (AliTPCclusterMI*)clrow->At(ncl);
1682 Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
1683 //-----------------------------------------------------------------
1684 // This function tries to find a track prolongation to next pad row
1685 //-----------------------------------------------------------------
1687 Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
1690 AliTPCclusterMI *cl=0;
1691 Int_t tpcindex= t.GetClusterIndex2(nr);
1693 // update current shape info every 5 pad-row
1694 // if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
1698 if (fIteration>0 && tpcindex>=-1){ //if we have already clusters
1700 if (tpcindex==-1) return 0; //track in dead zone
1701 if (tpcindex >= 0){ //
1702 cl = t.GetClusterPointer(nr);
1703 //if (cl==0) cl = GetClusterMI(tpcindex);
1704 if (!cl) cl = GetClusterMI(tpcindex);
1705 t.SetCurrentClusterIndex1(tpcindex);
1708 Int_t relativesector = ((tpcindex&0xff000000)>>24)%18; // if previously accepted cluster in different sector
1709 Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
1711 if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
1712 if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
1714 if (TMath::Abs(angle-t.GetAlpha())>0.001){
1715 Double_t rotation = angle-t.GetAlpha();
1716 t.SetRelativeSector(relativesector);
1717 if (!t.Rotate(rotation)) {
1718 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
1722 if (!t.PropagateTo(x)) {
1723 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
1727 t.SetCurrentCluster(cl);
1729 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1730 if ((tpcindex&0x8000)==0) accept =0;
1732 //if founded cluster is acceptible
1733 if (cl->IsUsed(11)) { // id cluster is shared inrease uncertainty
1734 t.SetErrorY2(t.GetErrorY2()+0.03);
1735 t.SetErrorZ2(t.GetErrorZ2()+0.03);
1736 t.SetErrorY2(t.GetErrorY2()*3);
1737 t.SetErrorZ2(t.GetErrorZ2()*3);
1739 t.SetNFoundable(t.GetNFoundable()+1);
1740 UpdateTrack(&t,accept);
1743 else { // Remove old cluster from track
1744 t.SetClusterIndex(nr, -3);
1745 t.SetClusterPointer(nr, 0);
1749 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0; // cut on angle
1750 if (fIteration>1 && IsFindable(t)){
1751 // not look for new cluster during refitting
1752 t.SetNFoundable(t.GetNFoundable()+1);
1757 // if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
1758 if (!t.PropagateTo(x)) {
1759 if (fIteration==0) t.SetRemoval(10);
1762 Double_t y = t.GetY();
1763 if (TMath::Abs(y)>ymax){
1765 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1766 if (!t.Rotate(fSectors->GetAlpha()))
1768 } else if (y <-ymax) {
1769 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1770 if (!t.Rotate(-fSectors->GetAlpha()))
1773 if (!t.PropagateTo(x)) {
1774 if (fIteration==0) t.SetRemoval(10);
1780 Double_t z=t.GetZ();
1783 if (!IsActive(t.GetRelativeSector(),nr)) {
1785 t.SetClusterIndex2(nr,-1);
1788 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
1789 Bool_t isActive = IsActive(t.GetRelativeSector(),nr);
1790 Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
1792 if (!isActive || !isActive2) return 0;
1794 const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1795 if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
1797 Double_t roadz = 1.;
1799 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1801 t.SetClusterIndex2(nr,-1);
1807 // if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fkParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
1808 t.SetNFoundable(t.GetNFoundable()+1);
1814 // cl = krow.FindNearest2(y+10.,z,roady,roadz,index);
1815 cl = krow.FindNearest2(y,z,roady,roadz,index);
1816 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
1819 t.SetCurrentCluster(cl);
1821 if (fIteration==2&&cl->IsUsed(10)) return 0;
1822 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1823 if (fIteration==2&&cl->IsUsed(11)) {
1824 t.SetErrorY2(t.GetErrorY2()+0.03);
1825 t.SetErrorZ2(t.GetErrorZ2()+0.03);
1826 t.SetErrorY2(t.GetErrorY2()*3);
1827 t.SetErrorZ2(t.GetErrorZ2()*3);
1830 if (t.fCurrentCluster->IsUsed(10)){
1835 if (t.fNShared>0.7*t.GetNumberOfClusters()) {
1841 if (accept<3) UpdateTrack(&t,accept);
1844 if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
1852 //_________________________________________________________________________
1853 Bool_t AliTPCtrackerMI::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
1855 // Get track space point by index
1856 // return false in case the cluster doesn't exist
1857 AliTPCclusterMI *cl = GetClusterMI(index);
1858 if (!cl) return kFALSE;
1859 Int_t sector = (index&0xff000000)>>24;
1860 // Int_t row = (index&0x00ff0000)>>16;
1862 // xyz[0] = fkParam->GetPadRowRadii(sector,row);
1863 xyz[0] = cl->GetX();
1864 xyz[1] = cl->GetY();
1865 xyz[2] = cl->GetZ();
1867 fkParam->AdjustCosSin(sector,cos,sin);
1868 Float_t x = cos*xyz[0]-sin*xyz[1];
1869 Float_t y = cos*xyz[1]+sin*xyz[0];
1871 Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
1872 if (sector < fkParam->GetNInnerSector()) sigmaY2 *= 2.07;
1873 Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
1874 if (sector < fkParam->GetNInnerSector()) sigmaZ2 *= 1.77;
1875 cov[0] = sin*sin*sigmaY2;
1876 cov[1] = -sin*cos*sigmaY2;
1878 cov[3] = cos*cos*sigmaY2;
1881 p.SetXYZ(x,y,xyz[2],cov);
1882 AliGeomManager::ELayerID iLayer;
1884 if (sector < fkParam->GetNInnerSector()) {
1885 iLayer = AliGeomManager::kTPC1;
1889 iLayer = AliGeomManager::kTPC2;
1890 idet = sector - fkParam->GetNInnerSector();
1892 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
1893 p.SetVolumeID(volid);
1899 Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t, Int_t nr) {
1900 //-----------------------------------------------------------------
1901 // This function tries to find a track prolongation to next pad row
1902 //-----------------------------------------------------------------
1903 t.SetCurrentCluster(0);
1904 t.SetCurrentClusterIndex1(-3);
1906 Double_t xt=t.GetX();
1907 Int_t row = GetRowNumber(xt)-1;
1908 Double_t ymax= GetMaxY(nr);
1910 if (row < nr) return 1; // don't prolongate if not information until now -
1911 // if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
1913 // return 0; // not prolongate strongly inclined tracks
1915 // if (TMath::Abs(t.GetSnp())>0.95) {
1917 // return 0; // not prolongate strongly inclined tracks
1918 // }// patch 28 fev 06
1920 Double_t x= GetXrow(nr);
1922 //t.PropagateTo(x+0.02);
1923 //t.PropagateTo(x+0.01);
1924 if (!t.PropagateTo(x)){
1931 if (TMath::Abs(y)>ymax){
1933 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1934 if (!t.Rotate(fSectors->GetAlpha()))
1936 } else if (y <-ymax) {
1937 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1938 if (!t.Rotate(-fSectors->GetAlpha()))
1941 // if (!t.PropagateTo(x)){
1948 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
1950 if (!IsActive(t.GetRelativeSector(),nr)) {
1952 t.SetClusterIndex2(nr,-1);
1955 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
1957 AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1959 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1961 t.SetClusterIndex2(nr,-1);
1967 // if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
1968 if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
1974 if ( (nr%2==0) || t.GetNumberOfClusters()<2){
1975 // t.fCurrentSigmaY = GetSigmaY(&t);
1976 //t.fCurrentSigmaZ = GetSigmaZ(&t);
1980 AliTPCclusterMI *cl=0;
1983 Double_t roady = 1.;
1984 Double_t roadz = 1.;
1988 index = t.GetClusterIndex2(nr);
1989 if ( (index >= 0) && (index&0x8000)==0){
1990 cl = t.GetClusterPointer(nr);
1991 if ( (cl==0) && (index >= 0)) cl = GetClusterMI(index);
1992 t.SetCurrentClusterIndex1(index);
1994 t.SetCurrentCluster(cl);
2000 // if (index<0) return 0;
2001 UInt_t uindex = TMath::Abs(index);
2004 //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
2005 cl = krow.FindNearest2(y,z,roady,roadz,uindex);
2008 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));
2009 t.SetCurrentCluster(cl);
2015 Int_t AliTPCtrackerMI::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
2016 //-----------------------------------------------------------------
2017 // This function tries to find a track prolongation to next pad row
2018 //-----------------------------------------------------------------
2020 //update error according neighborhoud
2022 if (t.GetCurrentCluster()) {
2024 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
2026 if (t.GetCurrentCluster()->IsUsed(10)){
2031 t.SetNShared(t.GetNShared()+1);
2032 if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
2037 if (fIteration>0) accept = 0;
2038 if (accept<3) UpdateTrack(&t,accept);
2042 if ( t.GetNumberOfClusters()>18 && ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)) t.SetRemoval(10);
2043 if ( t.GetNumberOfClusters()>18 && t.GetChi2()/t.GetNumberOfClusters()>6 ) t.SetRemoval(10);
2045 if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
2053 //_____________________________________________________________________________
2054 Int_t AliTPCtrackerMI::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step, Bool_t fromSeeds) {
2055 //-----------------------------------------------------------------
2056 // This function tries to find a track prolongation.
2057 //-----------------------------------------------------------------
2058 Double_t xt=t.GetX();
2060 Double_t alpha=t.GetAlpha();
2061 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2062 if (alpha < 0. ) alpha += 2.*TMath::Pi();
2064 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
2066 Int_t first = GetRowNumber(xt);
2071 for (Int_t nr= first; nr>=rf; nr-=step) {
2073 if (t.GetKinkIndexes()[0]>0){
2074 for (Int_t i=0;i<3;i++){
2075 Int_t index = t.GetKinkIndexes()[i];
2076 if (index==0) break;
2077 if (index<0) continue;
2079 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
2081 printf("PROBLEM\n");
2084 Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
2086 AliExternalTrackParam paramd(t);
2087 kink->SetDaughter(paramd);
2088 kink->SetStatus(2,5);
2095 if (nr==80) t.UpdateReference();
2096 if (nr<fInnerSec->GetNRows())
2097 fSectors = fInnerSec;
2099 fSectors = fOuterSec;
2100 if (FollowToNext(t,nr)==0)
2113 Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf, Bool_t fromSeeds) {
2114 //-----------------------------------------------------------------
2115 // This function tries to find a track prolongation.
2116 //-----------------------------------------------------------------
2118 Double_t xt=t.GetX();
2119 Double_t alpha=t.GetAlpha();
2120 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2121 if (alpha < 0. ) alpha += 2.*TMath::Pi();
2122 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
2124 Int_t first = t.GetFirstPoint();
2125 Int_t ri = GetRowNumber(xt);
2129 if (first<ri) first = ri;
2131 if (first<0) first=0;
2132 for (Int_t nr=first; nr<=rf; nr++) {
2133 // if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
2134 if (t.GetKinkIndexes()[0]<0){
2135 for (Int_t i=0;i<3;i++){
2136 Int_t index = t.GetKinkIndexes()[i];
2137 if (index==0) break;
2138 if (index>0) continue;
2139 index = TMath::Abs(index);
2140 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
2142 printf("PROBLEM\n");
2145 Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
2147 AliExternalTrackParam paramm(t);
2148 kink->SetMother(paramm);
2149 kink->SetStatus(2,1);
2156 if (nr<fInnerSec->GetNRows())
2157 fSectors = fInnerSec;
2159 fSectors = fOuterSec;
2170 Float_t AliTPCtrackerMI::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
2172 // overlapping factor
2178 Float_t dz2 =(s1->GetZ() - s2->GetZ());
2181 Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
2183 Float_t distance = TMath::Sqrt(dz2+dy2);
2184 if (distance>4.) return 0; // if there are far away - not overlap - to reduce combinatorics
2187 Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
2188 Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
2193 if (firstpoint>lastpoint) {
2194 firstpoint =lastpoint;
2199 for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
2200 if (s1->GetClusterIndex2(i)>0) sum1++;
2201 if (s2->GetClusterIndex2(i)>0) sum2++;
2202 if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
2206 if (sum<5) return 0;
2208 Float_t summin = TMath::Min(sum1+1,sum2+1);
2209 Float_t ratio = (sum+1)/Float_t(summin);
2213 void AliTPCtrackerMI::SignShared(AliTPCseed * s1, AliTPCseed * s2)
2217 Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
2218 if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
2219 Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
2220 Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
2225 //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
2226 //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
2227 Int_t firstpoint = 0;
2228 Int_t lastpoint = 160;
2230 // if (firstpoint>=lastpoint-5) return;;
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) {
2238 if (sumshared>cutN0){
2241 for (Int_t i=firstpoint;i<lastpoint;i++){
2242 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2243 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2244 AliTPCTrackerPoint *p1 = s1->GetTrackPoint(i);
2245 AliTPCTrackerPoint *p2 = s2->GetTrackPoint(i);;
2246 if (s1->IsActive()&&s2->IsActive()){
2247 p1->SetShared(kTRUE);
2248 p2->SetShared(kTRUE);
2254 if (sumshared>cutN0){
2255 for (Int_t i=0;i<4;i++){
2256 if (s1->GetOverlapLabel(3*i)==0){
2257 s1->SetOverlapLabel(3*i, s2->GetLabel());
2258 s1->SetOverlapLabel(3*i+1,sumshared);
2259 s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
2263 for (Int_t i=0;i<4;i++){
2264 if (s2->GetOverlapLabel(3*i)==0){
2265 s2->SetOverlapLabel(3*i, s1->GetLabel());
2266 s2->SetOverlapLabel(3*i+1,sumshared);
2267 s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
2274 void AliTPCtrackerMI::SignShared(TObjArray * arr)
2277 //sort trackss according sectors
2279 for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2280 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2282 //if (pt) RotateToLocal(pt);
2286 arr->Sort(); // sorting according relative sectors
2287 arr->Expand(arr->GetEntries());
2290 Int_t nseed=arr->GetEntriesFast();
2291 for (Int_t i=0; i<nseed; i++) {
2292 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2294 for (Int_t j=0;j<12;j++){
2295 pt->SetOverlapLabel(j,0);
2298 for (Int_t i=0; i<nseed; i++) {
2299 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2301 if (pt->GetRemoval()>10) continue;
2302 for (Int_t j=i+1; j<nseed; j++){
2303 AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
2304 if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
2306 if (pt2->GetRemoval()<=10) {
2307 //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
2315 void AliTPCtrackerMI::SortTracks(TObjArray * arr, Int_t mode) const
2318 //sort tracks in array according mode criteria
2319 Int_t nseed = arr->GetEntriesFast();
2320 for (Int_t i=0; i<nseed; i++) {
2321 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2332 void AliTPCtrackerMI::RemoveUsed2(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t minimal)
2335 // Loop over all tracks and remove overlaped tracks (with lower quality)
2337 // 1. Unsign clusters
2338 // 2. Sort tracks according quality
2339 // Quality is defined by the number of cluster between first and last points
2341 // 3. Loop over tracks - decreasing quality order
2342 // a.) remove - If the fraction of shared cluster less than factor (1- n or 2)
2343 // b.) remove - If the minimal number of clusters less than minimal and not ITS
2344 // c.) if track accepted - sign clusters
2346 //Called in - AliTPCtrackerMI::Clusters2Tracks()
2347 // - AliTPCtrackerMI::PropagateBack()
2348 // - AliTPCtrackerMI::RefitInward()
2351 // factor1 - factor for constrained
2352 // factor2 - for non constrained tracks
2353 // if (Float_t(shared+1)/Float_t(found+1)>factor) - DELETE
2357 Int_t nseed = arr->GetEntriesFast();
2358 Float_t * quality = new Float_t[nseed];
2359 Int_t * indexes = new Int_t[nseed];
2363 for (Int_t i=0; i<nseed; i++) {
2364 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2369 pt->UpdatePoints(); //select first last max dens points
2370 Float_t * points = pt->GetPoints();
2371 if (points[3]<0.8) quality[i] =-1;
2372 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
2373 //prefer high momenta tracks if overlaps
2374 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
2376 TMath::Sort(nseed,quality,indexes);
2379 for (Int_t itrack=0; itrack<nseed; itrack++) {
2380 Int_t trackindex = indexes[itrack];
2381 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);
2384 if (quality[trackindex]<0){
2385 MarkSeedFree( arr->RemoveAt(trackindex) );
2390 Int_t first = Int_t(pt->GetPoints()[0]);
2391 Int_t last = Int_t(pt->GetPoints()[2]);
2392 Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
2394 Int_t found,foundable,shared;
2395 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
2396 // pt->GetClusterStatistic(0,160, found, foundable,shared,kFALSE);
2397 Bool_t itsgold =kFALSE;
2400 if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
2404 if (Float_t(shared+1)/Float_t(found+1)>factor){
2405 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
2406 if( AliTPCReconstructor::StreamLevel()>3){
2407 TTreeSRedirector &cstream = *fDebugStreamer;
2408 cstream<<"RemoveUsed"<<
2409 "iter="<<fIteration<<
2413 MarkSeedFree( arr->RemoveAt(trackindex) );
2416 if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){ //remove short tracks
2417 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
2418 if( AliTPCReconstructor::StreamLevel()>3){
2419 TTreeSRedirector &cstream = *fDebugStreamer;
2420 cstream<<"RemoveShort"<<
2421 "iter="<<fIteration<<
2425 MarkSeedFree( arr->RemoveAt(trackindex) );
2431 //if (sharedfactor>0.4) continue;
2432 if (pt->GetKinkIndexes()[0]>0) continue;
2433 //Remove tracks with undefined properties - seems
2434 if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ?
2436 for (Int_t i=first; i<last; i++) {
2437 Int_t index=pt->GetClusterIndex2(i);
2438 // if (index<0 || index&0x8000 ) continue;
2439 if (index<0 || index&0x8000 ) continue;
2440 AliTPCclusterMI *c= pt->GetClusterPointer(i);
2447 Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
2453 void AliTPCtrackerMI::DumpClusters(Int_t iter, TObjArray *trackArray)
2456 // Dump clusters after reco
2457 // signed and unsigned cluster can be visualized
2458 // 1. Unsign all cluster
2459 // 2. Sign all used clusters
2462 Int_t nseed = trackArray->GetEntries();
2463 for (Int_t i=0; i<nseed; i++){
2464 AliTPCseed *pt=(AliTPCseed*)trackArray->UncheckedAt(i);
2468 Bool_t isKink=pt->GetKinkIndex(0)!=0;
2469 for (Int_t j=0; j<160; ++j) {
2470 Int_t index=pt->GetClusterIndex2(j);
2471 if (index<0) continue;
2472 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2474 if (isKink) c->Use(100); // kink
2475 c->Use(10); // by default usage 10
2480 for (Int_t sec=0;sec<fkNIS;sec++){
2481 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
2482 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
2483 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++){
2484 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
2485 Float_t gx[3]; cl->GetGlobalXYZ(gx);
2486 (*fDebugStreamer)<<"clDump"<<
2494 cla = fInnerSec[sec][row].GetClusters2();
2495 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++){
2496 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
2497 Float_t gx[3]; cl->GetGlobalXYZ(gx);
2498 (*fDebugStreamer)<<"clDump"<<
2509 for (Int_t sec=0;sec<fkNOS;sec++){
2510 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
2511 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
2512 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++){
2514 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
2515 cl->GetGlobalXYZ(gx);
2516 (*fDebugStreamer)<<"clDump"<<
2524 cla = fOuterSec[sec][row].GetClusters2();
2525 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++){
2527 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
2528 cl->GetGlobalXYZ(gx);
2529 (*fDebugStreamer)<<"clDump"<<
2541 void AliTPCtrackerMI::UnsignClusters()
2544 // loop over all clusters and unsign them
2547 for (Int_t sec=0;sec<fkNIS;sec++){
2548 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
2549 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
2550 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
2551 // if (cl[icl].IsUsed(10))
2552 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2553 cla = fInnerSec[sec][row].GetClusters2();
2554 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
2555 //if (cl[icl].IsUsed(10))
2556 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2560 for (Int_t sec=0;sec<fkNOS;sec++){
2561 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
2562 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
2563 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
2564 //if (cl[icl].IsUsed(10))
2565 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2566 cla = fOuterSec[sec][row].GetClusters2();
2567 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
2568 //if (cl[icl].IsUsed(10))
2569 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2577 void AliTPCtrackerMI::SignClusters(const TObjArray * arr, Float_t fnumber, Float_t fdensity)
2580 //sign clusters to be "used"
2582 // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
2583 // loop over "primaries"
2597 Int_t nseed = arr->GetEntriesFast();
2598 for (Int_t i=0; i<nseed; i++) {
2599 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2603 if (!(pt->IsActive())) continue;
2604 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
2605 if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
2607 sumdens2+= dens*dens;
2608 sumn += pt->GetNumberOfClusters();
2609 sumn2 += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
2610 Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
2613 sumchi2 +=chi2*chi2;
2618 Float_t mdensity = 0.9;
2619 Float_t meann = 130;
2620 Float_t meanchi = 1;
2621 Float_t sdensity = 0.1;
2622 Float_t smeann = 10;
2623 Float_t smeanchi =0.4;
2627 mdensity = sumdens/sum;
2629 meanchi = sumchi/sum;
2631 sdensity = sumdens2/sum-mdensity*mdensity;
2633 sdensity = TMath::Sqrt(sdensity);
2637 smeann = sumn2/sum-meann*meann;
2639 smeann = TMath::Sqrt(smeann);
2643 smeanchi = sumchi2/sum - meanchi*meanchi;
2645 smeanchi = TMath::Sqrt(smeanchi);
2651 //REMOVE SHORT DELTAS or tracks going out of sensitive volume of TPC
2653 for (Int_t i=0; i<nseed; i++) {
2654 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2658 if (pt->GetBSigned()) continue;
2659 if (pt->GetBConstrain()) continue;
2660 //if (!(pt->IsActive())) continue;
2662 Int_t found,foundable,shared;
2663 pt->GetClusterStatistic(0,160,found, foundable,shared);
2664 if (shared/float(found)>0.3) {
2665 if (shared/float(found)>0.9 ){
2666 //MarkSeedFree( arr->RemoveAt(i) );
2671 Bool_t isok =kFALSE;
2672 if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
2674 if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
2676 if (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
2678 if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
2682 for (Int_t j=0; j<160; ++j) {
2683 Int_t index=pt->GetClusterIndex2(j);
2684 if (index<0) continue;
2685 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2687 //if (!(c->IsUsed(10))) c->Use();
2694 Double_t maxchi = meanchi+2.*smeanchi;
2696 for (Int_t i=0; i<nseed; i++) {
2697 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2701 //if (!(pt->IsActive())) continue;
2702 if (pt->GetBSigned()) continue;
2703 Double_t chi = pt->GetChi2()/pt->GetNumberOfClusters();
2704 if (chi>maxchi) continue;
2707 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
2709 //sign only tracks with enoug big density at the beginning
2711 if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue;
2714 Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
2715 Double_t minn = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
2717 // if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
2718 if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
2721 if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
2722 //Int_t noc=pt->GetNumberOfClusters();
2723 pt->SetBSigned(kTRUE);
2724 for (Int_t j=0; j<160; ++j) {
2726 Int_t index=pt->GetClusterIndex2(j);
2727 if (index<0) continue;
2728 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2730 // if (!(c->IsUsed(10))) c->Use();
2735 // gLastCheck = nseed;
2744 Int_t AliTPCtrackerMI::RefitInward(AliESDEvent *event)
2747 // back propagation of ESD tracks
2750 if (!event) return 0;
2751 const Int_t kMaxFriendTracks=2000;
2754 // extract correction object for multiplicity dependence of dEdx
2755 TObjArray * gainCalibArray = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(event->GetRunNumber());
2757 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
2759 AliFatal("Tranformations not in RefitInward");
2762 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
2763 const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
2764 Int_t nContribut = event->GetNumberOfTracks();
2765 TGraphErrors * graphMultDependenceDeDx = 0x0;
2766 if (recoParam && recoParam->GetUseMultiplicityCorrectionDedx() && gainCalibArray) {
2767 if (recoParam->GetUseTotCharge()) {
2768 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2770 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2776 //PrepareForProlongation(fSeeds,1);
2777 PropagateForward2(fSeeds);
2778 RemoveUsed2(fSeeds,0.4,0.4,20);
2780 TObjArray arraySeed(fSeeds->GetEntries());
2781 for (Int_t i=0;i<fSeeds->GetEntries();i++) {
2782 arraySeed.AddAt(fSeeds->At(i),i);
2784 SignShared(&arraySeed);
2785 // FindCurling(fSeeds, event,2); // find multi found tracks
2786 FindSplitted(fSeeds, event,2); // find multi found tracks
2787 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,2); // find multi found tracks
2790 Int_t nseed = fSeeds->GetEntriesFast();
2791 for (Int_t i=0;i<nseed;i++){
2792 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2793 if (!seed) continue;
2794 if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
2795 AliESDtrack *esd=event->GetTrack(i);
2797 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
2798 AliExternalTrackParam paramIn;
2799 AliExternalTrackParam paramOut;
2800 Int_t ncl = seed->RefitTrack(seed,¶mIn,¶mOut);
2801 if (AliTPCReconstructor::StreamLevel()>2) {
2802 (*fDebugStreamer)<<"RecoverIn"<<
2806 "pout.="<<¶mOut<<
2811 seed->Set(paramIn.GetX(),paramIn.GetAlpha(),paramIn.GetParameter(),paramIn.GetCovariance());
2812 seed->SetNumberOfClusters(ncl);
2816 seed->PropagateTo(fkParam->GetInnerRadiusLow());
2817 seed->UpdatePoints();
2818 AddCovariance(seed);
2819 MakeESDBitmaps(seed, esd);
2820 seed->CookdEdx(0.02,0.6);
2821 CookLabel(seed,0.1); //For comparison only
2823 if (AliTPCReconstructor::StreamLevel()>1 && seed!=0) {
2824 TTreeSRedirector &cstream = *fDebugStreamer;
2831 if (seed->GetNumberOfClusters()>15){
2832 esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
2833 esd->SetTPCPoints(seed->GetPoints());
2834 esd->SetTPCPointsF(seed->GetNFoundable());
2835 Int_t ndedx = seed->GetNCDEDX(0);
2836 Float_t sdedx = seed->GetSDEDX(0);
2837 Float_t dedx = seed->GetdEdx();
2838 // apply mutliplicity dependent dEdx correction if available
2839 if (graphMultDependenceDeDx) {
2840 Double_t corrGain = AliTPCcalibDButil::EvalGraphConst(graphMultDependenceDeDx, nContribut);
2841 dedx += (1 - corrGain)*50.; // MIP is normalized to 50
2843 esd->SetTPCsignal(dedx, sdedx, ndedx);
2845 // fill new dEdx information
2847 Double32_t signal[4];
2851 for(Int_t iarr=0;iarr<3;iarr++) {
2852 signal[iarr] = seed->GetDEDXregion(iarr+1);
2853 ncl[iarr] = seed->GetNCDEDX(iarr+1);
2854 nrows[iarr] = seed->GetNCDEDXInclThres(iarr+1);
2856 signal[3] = seed->GetDEDXregion(4);
2858 AliTPCdEdxInfo * infoTpcPid = new AliTPCdEdxInfo();
2859 infoTpcPid->SetTPCSignalRegionInfo(signal, ncl, nrows);
2860 esd->SetTPCdEdxInfo(infoTpcPid);
2862 // add seed to the esd track in Calib level
2864 Bool_t storeFriend = gRandom->Rndm()<(kMaxFriendTracks)/Float_t(nseed);
2865 if (AliTPCReconstructor::StreamLevel()>0 &&storeFriend){
2866 // RS: this is the only place where the seed is created not in the pool,
2867 // since it should belong to ESDevent
2868 AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE);
2869 esd->AddCalibObject(seedCopy);
2874 //printf("problem\n");
2877 //FindKinks(fSeeds,event);
2878 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(2,fSeeds);
2879 Info("RefitInward","Number of refitted tracks %d",ntracks);
2881 AliCosmicTracker::FindCosmic(event, kTRUE);
2887 Int_t AliTPCtrackerMI::PropagateBack(AliESDEvent *event)
2890 // back propagation of ESD tracks
2892 if (!event) return 0;
2897 PropagateBack(fSeeds);
2898 RemoveUsed2(fSeeds,0.4,0.4,20);
2899 //FindCurling(fSeeds, fEvent,1);
2900 FindSplitted(fSeeds, event,1); // find multi found tracks
2901 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,1); // find multi found tracks
2904 Int_t nseed = fSeeds->GetEntriesFast();
2906 for (Int_t i=0;i<nseed;i++){
2907 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2908 if (!seed) continue;
2909 if (seed->GetKinkIndex(0)<0) UpdateKinkQualityM(seed); // update quality informations for kinks
2910 seed->UpdatePoints();
2911 AddCovariance(seed);
2912 AliESDtrack *esd=event->GetTrack(i);
2913 if (!esd) continue; //never happen
2914 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
2915 AliExternalTrackParam paramIn;
2916 AliExternalTrackParam paramOut;
2917 Int_t ncl = seed->RefitTrack(seed,¶mIn,¶mOut);
2918 if (AliTPCReconstructor::StreamLevel()>2) {
2919 (*fDebugStreamer)<<"RecoverBack"<<
2923 "pout.="<<¶mOut<<
2928 seed->Set(paramOut.GetX(),paramOut.GetAlpha(),paramOut.GetParameter(),paramOut.GetCovariance());
2929 seed->SetNumberOfClusters(ncl);
2932 seed->CookdEdx(0.02,0.6);
2933 CookLabel(seed,0.1); //For comparison only
2934 if (seed->GetNumberOfClusters()>15){
2935 esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
2936 esd->SetTPCPoints(seed->GetPoints());
2937 esd->SetTPCPointsF(seed->GetNFoundable());
2938 Int_t ndedx = seed->GetNCDEDX(0);
2939 Float_t sdedx = seed->GetSDEDX(0);
2940 Float_t dedx = seed->GetdEdx();
2941 esd->SetTPCsignal(dedx, sdedx, ndedx);
2943 Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
2944 // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
2945 if (AliTPCReconstructor::StreamLevel()>1 && esd) {
2946 (*fDebugStreamer)<<"Cback"<<
2949 "EventNrInFile="<<eventnumber<<
2954 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(1,fSeeds);
2955 //FindKinks(fSeeds,event);
2956 Info("PropagateBack","Number of back propagated tracks %d",ntracks);
2964 Int_t AliTPCtrackerMI::PostProcess(AliESDEvent *event)
2967 // Post process events
2969 if (!event) return 0;
2972 // Set TPC event status
2975 // event affected by HV dip
2977 if(IsTPCHVDipEvent(event)) {
2978 event->ResetDetectorStatus(AliDAQ::kTPC);
2981 //printf("Status %d \n", event->IsDetectorOn(AliDAQ::kTPC));
2987 void AliTPCtrackerMI::DeleteSeeds()
2996 void AliTPCtrackerMI::ReadSeeds(const AliESDEvent *const event, Int_t direction)
2999 //read seeds from the event
3001 Int_t nentr=event->GetNumberOfTracks();
3003 Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
3008 fSeeds = new TObjArray(nentr);
3012 for (Int_t i=0; i<nentr; i++) {
3013 AliESDtrack *esd=event->GetTrack(i);
3014 ULong_t status=esd->GetStatus();
3015 if (!(status&AliESDtrack::kTPCin)) continue;
3016 AliTPCtrack t(*esd);
3017 t.SetNumberOfClusters(0);
3018 // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
3019 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(t/*,t.GetAlpha()*/);
3020 seed->SetPoolID(fLastSeedID);
3021 seed->SetUniqueID(esd->GetID());
3022 AddCovariance(seed); //add systematic ucertainty
3023 for (Int_t ikink=0;ikink<3;ikink++) {
3024 Int_t index = esd->GetKinkIndex(ikink);
3025 seed->GetKinkIndexes()[ikink] = index;
3026 if (index==0) continue;
3027 index = TMath::Abs(index);
3028 AliESDkink * kink = fEvent->GetKink(index-1);
3029 if (kink&&esd->GetKinkIndex(ikink)<0){
3030 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
3031 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,0);
3033 if (kink&&esd->GetKinkIndex(ikink)>0){
3034 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
3035 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,4);
3039 if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.);
3040 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
3041 //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
3042 // fSeeds->AddAt(0,i);
3043 // MarkSeedFree( seed );
3046 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) > 0 ) {
3047 Double_t par0[5],par1[5],alpha,x;
3048 esd->GetInnerExternalParameters(alpha,x,par0);
3049 esd->GetExternalParameters(x,par1);
3050 Double_t delta1 = TMath::Abs(par0[4]-par1[4])/(0.000000001+TMath::Abs(par0[4]+par1[4]));
3051 Double_t delta2 = TMath::Abs(par0[3]-par1[3]);
3053 if (esd->GetTRDncls()>0) trdchi2 = esd->GetTRDchi2()/esd->GetTRDncls();
3054 //reset covariance if suspicious
3055 if ( (delta1>0.1) || (delta2>0.006) ||trdchi2>7.)
3056 seed->ResetCovariance(10.);
3061 // rotate to the local coordinate system
3063 fSectors=fInnerSec; fN=fkNIS;
3064 Double_t alpha=seed->GetAlpha();
3065 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
3066 if (alpha < 0. ) alpha += 2.*TMath::Pi();
3067 Int_t ns=Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
3068 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
3069 alpha-=seed->GetAlpha();
3070 if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
3071 if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
3072 if (TMath::Abs(alpha) > 0.001) { // This should not happen normally
3073 AliWarning(Form("Rotating track over %f",alpha));
3074 if (!seed->Rotate(alpha)) {
3075 MarkSeedFree( seed );
3081 if (esd->GetKinkIndex(0)<=0){
3082 for (Int_t irow=0;irow<160;irow++){
3083 Int_t index = seed->GetClusterIndex2(irow);
3086 AliTPCclusterMI * cl = GetClusterMI(index);
3087 seed->SetClusterPointer(irow,cl);
3089 if ((index & 0x8000)==0){
3090 cl->Use(10); // accepted cluster
3092 cl->Use(6); // close cluster not accepted
3095 Info("ReadSeeds","Not found cluster");
3100 fSeeds->AddAt(seed,i);
3106 //_____________________________________________________________________________
3107 void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
3108 Float_t deltay, Int_t ddsec) {
3109 //-----------------------------------------------------------------
3110 // This function creates track seeds.
3111 // SEEDING WITH VERTEX CONSTRAIN
3112 //-----------------------------------------------------------------
3113 // cuts[0] - fP4 cut
3114 // cuts[1] - tan(phi) cut
3115 // cuts[2] - zvertex cut
3116 // cuts[3] - fP3 cut
3124 Double_t x[5], c[15];
3125 // Int_t di = i1-i2;
3127 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed();
3128 seed->SetPoolID(fLastSeedID);
3129 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
3130 Double_t cs=cos(alpha), sn=sin(alpha);
3132 // Double_t x1 =fOuterSec->GetX(i1);
3133 //Double_t xx2=fOuterSec->GetX(i2);
3135 Double_t x1 =GetXrow(i1);
3136 Double_t xx2=GetXrow(i2);
3138 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
3140 Int_t imiddle = (i2+i1)/2; //middle pad row index
3141 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
3142 const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
3146 const AliTPCtrackerRow& kr1=GetRow(ns,i1);
3147 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
3148 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
3151 // change cut on curvature if it can't reach this layer
3152 // maximal curvature set to reach it
3153 Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
3154 if (dvertexmax*0.5*cuts[0]>0.85){
3155 cuts[0] = 0.85/(dvertexmax*0.5+1.);
3157 Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
3160 if (deltay>0) ddsec = 0;
3161 // loop over clusters
3162 for (Int_t is=0; is < kr1; is++) {
3164 if (kr1[is]->IsUsed(10)) continue;
3165 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3166 //if (TMath::Abs(y1)>ymax) continue;
3168 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3170 // find possible directions
3171 Float_t anglez = (z1-z3)/(x1-x3);
3172 Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
3175 //find rotation angles relative to line given by vertex and point 1
3176 Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
3177 Double_t dvertex = TMath::Sqrt(dvertex2);
3178 Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
3179 Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
3182 // loop over 2 sectors
3188 Double_t dddz1=0; // direction of delta inclination in z axis
3195 for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
3196 Int_t sec2 = sec + dsec;
3198 // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
3199 //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
3200 AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
3201 AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
3202 Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
3203 Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
3205 // rotation angles to p1-p3
3206 Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
3207 Double_t x2, y2, z2;
3209 // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
3212 Double_t dxx0 = (xx2-x3)*cs13r;
3213 Double_t dyy0 = (xx2-x3)*sn13r;
3214 for (Int_t js=index1; js < index2; js++) {
3215 const AliTPCclusterMI *kcl = kr2[js];
3216 if (kcl->IsUsed(10)) continue;
3218 //calcutate parameters
3220 Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
3222 if (TMath::Abs(yy0)<0.000001) continue;
3223 Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
3224 Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
3225 Double_t r02 = (0.25+y0*y0)*dvertex2;
3226 //curvature (radius) cut
3227 if (r02<r2min) continue;
3231 Double_t c0 = 1/TMath::Sqrt(r02);
3235 //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
3236 //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
3237 Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
3238 Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
3241 Double_t z0 = kcl->GetZ();
3242 Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
3243 if (TMath::Abs(zzzz2-z0)>0.5) continue;
3246 Double_t dip = (z1-z0)*c0/dfi1;
3247 Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
3258 x2= xx2*cs-y2*sn*dsec;
3259 y2=+xx2*sn*dsec+y2*cs;
3269 // do we have cluster at the middle ?
3271 GetProlongation(x1,xm,x,ym,zm);
3273 AliTPCclusterMI * cm=0;
3274 if (TMath::Abs(ym)-ymaxm<0){
3275 cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3276 if ((!cm) || (cm->IsUsed(10))) {
3281 // rotate y1 to system 0
3282 // get state vector in rotated system
3283 Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
3284 Double_t xr2 = x0*cs+yr1*sn*dsec;
3285 Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3287 GetProlongation(xx2,xm,xr,ym,zm);
3288 if (TMath::Abs(ym)-ymaxm<0){
3289 cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3290 if ((!cm) || (cm->IsUsed(10))) {
3297 // Double_t dym = 0;
3298 // Double_t dzm = 0;
3300 // dym = ym - cm->GetY();
3301 // dzm = zm - cm->GetZ();
3308 Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
3309 Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
3310 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
3311 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3312 //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
3314 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3315 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3316 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3317 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3318 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3319 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3321 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3322 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3323 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3324 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
3328 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3329 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3330 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3331 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3332 c[13]=f30*sy1*f40+f32*sy2*f42;
3333 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3335 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3337 UInt_t index=kr1.GetIndex(is);
3338 if (seed) {MarkSeedFree(seed); seed = 0;}
3339 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, ns*alpha+shift, x, c, index);
3340 seed->SetPoolID(fLastSeedID);
3341 track->SetIsSeeding(kTRUE);
3342 track->SetSeed1(i1);
3343 track->SetSeed2(i2);
3344 track->SetSeedType(3);
3348 FollowProlongation(*track, (i1+i2)/2,1);
3349 Int_t foundable,found,shared;
3350 track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
3351 if ((found<0.55*foundable) || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
3352 MarkSeedFree(seed); seed = 0;
3358 FollowProlongation(*track, i2,1);
3362 track->SetBConstrain(1);
3363 // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
3364 track->SetLastPoint(i1); // first cluster in track position
3365 track->SetFirstPoint(track->GetLastPoint());
3367 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3368 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3369 track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
3370 MarkSeedFree(seed); seed = 0;
3374 // Z VERTEX CONDITION
3375 Double_t zv, bz=GetBz();
3376 if ( !track->GetZAt(0.,bz,zv) ) continue;
3377 if (TMath::Abs(zv-z3)>cuts[2]) {
3378 FollowProlongation(*track, TMath::Max(i2-20,0));
3379 if ( !track->GetZAt(0.,bz,zv) ) continue;
3380 if (TMath::Abs(zv-z3)>cuts[2]){
3381 FollowProlongation(*track, TMath::Max(i2-40,0));
3382 if ( !track->GetZAt(0.,bz,zv) ) continue;
3383 if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
3384 // make seed without constrain
3385 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
3386 FollowProlongation(*track2, i2,1);
3387 track2->SetBConstrain(kFALSE);
3388 track2->SetSeedType(1);
3389 arr->AddLast(track2);
3390 MarkSeedFree( seed ); seed = 0;
3394 MarkSeedFree( seed ); seed = 0;
3401 track->SetSeedType(0);
3402 arr->AddLast(track); // note, track is seed, don't free the seed
3403 seed = new( NextFreeSeed() ) AliTPCseed;
3404 seed->SetPoolID(fLastSeedID);
3406 // don't consider other combinations
3407 if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
3413 Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
3415 if (seed) MarkSeedFree( seed );
3419 void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
3424 //-----------------------------------------------------------------
3425 // This function creates track seeds.
3426 //-----------------------------------------------------------------
3427 // cuts[0] - fP4 cut
3428 // cuts[1] - tan(phi) cut
3429 // cuts[2] - zvertex cut
3430 // cuts[3] - fP3 cut
3440 Double_t x[5], c[15];
3442 // make temporary seed
3443 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
3444 seed->SetPoolID(fLastSeedID);
3445 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3446 // Double_t cs=cos(alpha), sn=sin(alpha);
3451 Double_t x1 = GetXrow(i1-1);
3452 const AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
3453 Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
3455 Double_t x1p = GetXrow(i1);
3456 const AliTPCtrackerRow& kr1p=GetRow(sec,i1);
3458 Double_t x1m = GetXrow(i1-2);
3459 const AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
3462 //last 3 padrow for seeding
3463 AliTPCtrackerRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
3464 Double_t x3 = GetXrow(i1-7);
3465 // Double_t y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;
3467 AliTPCtrackerRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
3468 Double_t x3p = GetXrow(i1-6);
3470 AliTPCtrackerRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
3471 Double_t x3m = GetXrow(i1-8);
3476 Int_t im = i1-4; //middle pad row index
3477 Double_t xm = GetXrow(im); // radius of middle pad-row
3478 const AliTPCtrackerRow& krm=GetRow(sec,im); //middle pad -row
3479 // Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;
3482 Double_t deltax = x1-x3;
3483 Double_t dymax = deltax*cuts[1];
3484 Double_t dzmax = deltax*cuts[3];
3486 // loop over clusters
3487 for (Int_t is=0; is < kr1; is++) {
3489 if (kr1[is]->IsUsed(10)) continue;
3490 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3492 if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3494 Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
3495 Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
3501 for (Int_t js=index1; js < index2; js++) {
3502 const AliTPCclusterMI *kcl = kr3[js];
3503 if (kcl->IsUsed(10)) continue;
3505 // apply angular cuts
3506 if (TMath::Abs(y1-y3)>dymax) continue;
3509 if (TMath::Abs(z1-z3)>dzmax) continue;
3511 Double_t angley = (y1-y3)/(x1-x3);
3512 Double_t anglez = (z1-z3)/(x1-x3);
3514 Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
3515 Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
3517 Double_t yyym = angley*(xm-x1)+y1;
3518 Double_t zzzm = anglez*(xm-x1)+z1;
3520 const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
3522 if (kcm->IsUsed(10)) continue;
3524 erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
3525 errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
3532 // look around first
3533 const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
3539 if (kc1m->IsUsed(10)) used++;
3541 const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
3547 if (kc1p->IsUsed(10)) used++;
3549 if (used>1) continue;
3550 if (found<1) continue;
3554 const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
3560 if (kc3m->IsUsed(10)) used++;
3564 const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
3570 if (kc3p->IsUsed(10)) used++;
3574 if (used>1) continue;
3575 if (found<3) continue;
3585 x[4]=F1(x1,y1,x2,y2,x3,y3);
3586 //if (TMath::Abs(x[4]) >= cuts[0]) continue;
3589 x[2]=F2(x1,y1,x2,y2,x3,y3);
3592 x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
3593 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3597 Double_t sy1=0.1, sz1=0.1;
3598 Double_t sy2=0.1, sz2=0.1;
3599 Double_t sy3=0.1, sy=0.1, sz=0.1;
3601 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3602 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3603 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3604 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3605 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3606 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3608 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3609 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3610 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3611 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
3615 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3616 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3617 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3618 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3619 c[13]=f30*sy1*f40+f32*sy2*f42;
3620 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3622 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3624 index=kr1.GetIndex(is);
3625 if (seed) {MarkSeedFree( seed ); seed = 0;}
3626 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, sec*alpha+shift, x, c, index);
3627 seed->SetPoolID(fLastSeedID);
3629 track->SetIsSeeding(kTRUE);
3632 FollowProlongation(*track, i1-7,1);
3633 if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
3634 track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
3635 MarkSeedFree( seed ); seed = 0;
3641 FollowProlongation(*track, i2,1);
3642 track->SetBConstrain(0);
3643 track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
3644 track->SetFirstPoint(track->GetLastPoint());
3646 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3647 track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
3648 track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
3649 MarkSeedFree( seed ); seed = 0;
3654 FollowProlongation(*track, TMath::Max(i2-10,0),1);
3655 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
3656 FollowProlongation(*track2, i2,1);
3657 track2->SetBConstrain(kFALSE);
3658 track2->SetSeedType(4);
3659 arr->AddLast(track2);
3660 MarkSeedFree( seed ); seed = 0;
3664 //arr->AddLast(track);
3665 //seed = new AliTPCseed;
3671 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);
3673 if (seed) MarkSeedFree(seed);
3677 //_____________________________________________________________________________
3678 void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
3679 Float_t deltay, Bool_t /*bconstrain*/) {
3680 //-----------------------------------------------------------------
3681 // This function creates track seeds - without vertex constraint
3682 //-----------------------------------------------------------------
3683 // cuts[0] - fP4 cut - not applied
3684 // cuts[1] - tan(phi) cut
3685 // cuts[2] - zvertex cut - not applied
3686 // cuts[3] - fP3 cut
3696 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3697 // Double_t cs=cos(alpha), sn=sin(alpha);
3698 Int_t row0 = (i1+i2)/2;
3699 Int_t drow = (i1-i2)/2;
3700 const AliTPCtrackerRow& kr0=fSectors[sec][row0];
3701 AliTPCtrackerRow * kr=0;
3703 AliTPCpolyTrack polytrack;
3704 Int_t nclusters=fSectors[sec][row0];
3705 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
3706 seed->SetPoolID(fLastSeedID);
3711 for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
3713 Int_t nfoundable =0;
3714 for (Int_t iter =1; iter<2; iter++){ //iterations
3715 const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
3716 const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];
3717 const AliTPCclusterMI * cl= kr0[is];
3719 if (cl->IsUsed(10)) {
3725 Double_t x = kr0.GetX();
3726 // Initialization of the polytrack
3731 Double_t y0= cl->GetY();
3732 Double_t z0= cl->GetZ();
3736 Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
3737 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
3739 erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
3740 errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
3741 polytrack.AddPoint(x,y0,z0,erry, errz);
3744 if (cl->IsUsed(10)) sumused++;
3747 Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
3748 Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
3751 AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
3752 if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
3753 erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
3754 errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
3755 if (cl1->IsUsed(10)) sumused++;
3756 polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
3760 AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
3762 erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
3763 errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
3764 if (cl2->IsUsed(10)) sumused++;
3765 polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
3768 if (sumused>0) continue;
3770 polytrack.UpdateParameters();
3776 nfoundable = polytrack.GetN();
3777 nfound = nfoundable;
3779 for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
3780 Float_t maxdist = 0.8*(1.+3./(ddrow));
3781 for (Int_t delta = -1;delta<=1;delta+=2){
3782 Int_t row = row0+ddrow*delta;
3783 kr = &(fSectors[sec][row]);
3784 Double_t xn = kr->GetX();
3785 Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
3786 polytrack.GetFitPoint(xn,yn,zn);
3787 if (TMath::Abs(yn)>ymax1) continue;
3789 AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
3791 Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
3794 erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3795 errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3796 if (cln->IsUsed(10)) {
3797 // printf("used\n");
3805 polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
3810 if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
3811 polytrack.UpdateParameters();
3814 if ( (sumused>3) || (sumused>0.5*nfound)) {
3815 //printf("sumused %d\n",sumused);
3820 polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
3821 AliTPCpolyTrack track2;
3823 polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
3824 if (track2.GetN()<0.5*nfoundable) continue;
3827 if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
3829 // test seed with and without constrain
3830 for (Int_t constrain=0; constrain<=0;constrain++){
3831 // add polytrack candidate
3833 Double_t x[5], c[15];
3834 Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
3835 track2.GetBoundaries(x3,x1);
3837 track2.GetFitPoint(x1,y1,z1);
3838 track2.GetFitPoint(x2,y2,z2);
3839 track2.GetFitPoint(x3,y3,z3);
3841 //is track pointing to the vertex ?
3844 polytrack.GetFitPoint(x0,y0,z0);
3857 x[4]=F1(x1,y1,x2,y2,x3,y3);
3859 // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
3860 x[2]=F2(x1,y1,x2,y2,x3,y3);
3862 //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
3863 //x[3]=F3(x1,y1,x2,y2,z1,z2);
3864 x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
3865 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3868 Double_t sy =0.1, sz =0.1;
3869 Double_t sy1=0.02, sz1=0.02;
3870 Double_t sy2=0.02, sz2=0.02;
3874 sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3877 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3878 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3879 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3880 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3881 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3882 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3884 Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
3885 Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
3886 Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
3887 Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
3892 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3893 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3894 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3895 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3896 c[13]=f30*sy1*f40+f32*sy2*f42;
3897 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3899 //Int_t row1 = fSectors->GetRowNumber(x1);
3900 Int_t row1 = GetRowNumber(x1);
3904 if (seed) {MarkSeedFree( seed ); seed = 0;}
3905 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1,sec*alpha+shift,x,c,index);
3906 seed->SetPoolID(fLastSeedID);
3907 track->SetIsSeeding(kTRUE);
3908 Int_t rc=FollowProlongation(*track, i2);
3909 if (constrain) track->SetBConstrain(1);
3911 track->SetBConstrain(0);
3912 track->SetLastPoint(row1+fInnerSec->GetNRows()); // first cluster in track position
3913 track->SetFirstPoint(track->GetLastPoint());
3915 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3916 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3917 track->GetNShared()>0.4*track->GetNumberOfClusters()) {
3918 MarkSeedFree( seed ); seed = 0;
3921 arr->AddLast(track); // track IS seed, don't free seed
3922 seed = new( NextFreeSeed() ) AliTPCseed;
3923 seed->SetPoolID(fLastSeedID);
3927 } // if accepted seed
3930 Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
3932 if (seed) MarkSeedFree( seed );
3936 AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *const track, Float_t r0, Float_t r1, Float_t r2)
3940 //reseed using track points
3941 Int_t p0 = int(r0*track->GetNumberOfClusters()); // point 0
3942 Int_t p1 = int(r1*track->GetNumberOfClusters());
3943 Int_t p2 = int(r2*track->GetNumberOfClusters()); // last point
3945 Double_t x0[3],x1[3],x2[3];
3946 for (Int_t i=0;i<3;i++){
3952 // find track position at given ratio of the length
3953 Int_t sec0=0, sec1=0, sec2=0;
3956 for (Int_t i=0;i<160;i++){
3957 if (track->GetClusterPointer(i)){
3959 AliTPCTrackerPoint *trpoint =track->GetTrackPoint(i);
3960 if ( (index<p0) || x0[0]<0 ){
3961 if (trpoint->GetX()>1){
3962 clindex = track->GetClusterIndex2(i);
3964 x0[0] = trpoint->GetX();
3965 x0[1] = trpoint->GetY();
3966 x0[2] = trpoint->GetZ();
3967 sec0 = ((clindex&0xff000000)>>24)%18;
3972 if ( (index<p1) &&(trpoint->GetX()>1)){
3973 clindex = track->GetClusterIndex2(i);
3975 x1[0] = trpoint->GetX();
3976 x1[1] = trpoint->GetY();
3977 x1[2] = trpoint->GetZ();
3978 sec1 = ((clindex&0xff000000)>>24)%18;
3981 if ( (index<p2) &&(trpoint->GetX()>1)){
3982 clindex = track->GetClusterIndex2(i);
3984 x2[0] = trpoint->GetX();
3985 x2[1] = trpoint->GetY();
3986 x2[2] = trpoint->GetZ();
3987 sec2 = ((clindex&0xff000000)>>24)%18;
3994 Double_t alpha, cs,sn, xx2,yy2;
3996 alpha = (sec1-sec2)*fSectors->GetAlpha();
3997 cs = TMath::Cos(alpha);
3998 sn = TMath::Sin(alpha);
3999 xx2= x1[0]*cs-x1[1]*sn;
4000 yy2= x1[0]*sn+x1[1]*cs;
4004 alpha = (sec0-sec2)*fSectors->GetAlpha();
4005 cs = TMath::Cos(alpha);
4006 sn = TMath::Sin(alpha);
4007 xx2= x0[0]*cs-x0[1]*sn;
4008 yy2= x0[0]*sn+x0[1]*cs;
4014 Double_t x[5],c[15];
4018 x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
4019 // if (x[4]>1) return 0;
4020 x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
4021 x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
4022 //if (TMath::Abs(x[3]) > 2.2) return 0;
4023 //if (TMath::Abs(x[2]) > 1.99) return 0;
4025 Double_t sy =0.1, sz =0.1;
4027 Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
4028 Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
4029 Double_t sy3=0.01+track->GetSigmaY2();
4031 Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
4032 Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
4033 Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
4034 Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
4035 Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
4036 Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
4038 Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
4039 Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
4040 Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
4041 Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
4046 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4047 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4048 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4049 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4050 c[13]=f30*sy1*f40+f32*sy2*f42;
4051 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4053 // Int_t row1 = fSectors->GetRowNumber(x2[0]);
4054 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4055 seed->SetPoolID(fLastSeedID);
4056 // Double_t y0,z0,y1,z1, y2,z2;
4057 //seed->GetProlongation(x0[0],y0,z0);
4058 // seed->GetProlongation(x1[0],y1,z1);
4059 //seed->GetProlongation(x2[0],y2,z2);
4061 seed->SetLastPoint(pp2);
4062 seed->SetFirstPoint(pp2);
4069 AliTPCseed *AliTPCtrackerMI::ReSeed(const AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
4073 //reseed using founded clusters
4075 // Find the number of clusters
4076 Int_t nclusters = 0;
4077 for (Int_t irow=0;irow<160;irow++){
4078 if (track->GetClusterIndex(irow)>0) nclusters++;
4082 ipos[0] = TMath::Max(int(r0*nclusters),0); // point 0 cluster
4083 ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1); //
4084 ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1); // last point
4087 Double_t xyz[3][3]={{0}};
4088 Int_t row[3]={0},sec[3]={0,0,0};
4090 // find track row position at given ratio of the length
4092 for (Int_t irow=0;irow<160;irow++){
4093 if (track->GetClusterIndex2(irow)<0) continue;
4095 for (Int_t ipoint=0;ipoint<3;ipoint++){
4096 if (index<=ipos[ipoint]) row[ipoint] = irow;
4100 //Get cluster and sector position
4101 for (Int_t ipoint=0;ipoint<3;ipoint++){
4102 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4103 AliTPCclusterMI * cl = GetClusterMI(clindex);
4106 // AliTPCclusterMI * cl = GetClusterMI(clindex);
4109 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4110 xyz[ipoint][0] = GetXrow(row[ipoint]);
4111 xyz[ipoint][1] = cl->GetY();
4112 xyz[ipoint][2] = cl->GetZ();
4116 // Calculate seed state vector and covariance matrix
4118 Double_t alpha, cs,sn, xx2,yy2;
4120 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4121 cs = TMath::Cos(alpha);
4122 sn = TMath::Sin(alpha);
4123 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4124 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4128 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4129 cs = TMath::Cos(alpha);
4130 sn = TMath::Sin(alpha);
4131 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4132 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4138 Double_t x[5],c[15];
4142 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4143 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4144 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4146 Double_t sy =0.1, sz =0.1;
4148 Double_t sy1=0.2, sz1=0.2;
4149 Double_t sy2=0.2, sz2=0.2;
4152 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;
4153 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;
4154 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;
4155 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;
4156 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;
4157 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;
4159 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;
4160 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;
4161 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;
4162 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;
4167 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4168 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4169 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4170 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4171 c[13]=f30*sy1*f40+f32*sy2*f42;
4172 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4174 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
4175 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4176 seed->SetPoolID(fLastSeedID);
4177 seed->SetLastPoint(row[2]);
4178 seed->SetFirstPoint(row[2]);
4183 AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
4187 //reseed using founded clusters
4190 Int_t row[3]={0,0,0};
4191 Int_t sec[3]={0,0,0};
4193 // forward direction
4195 for (Int_t irow=r0;irow<160;irow++){
4196 if (track->GetClusterIndex(irow)>0){
4201 for (Int_t irow=160;irow>r0;irow--){
4202 if (track->GetClusterIndex(irow)>0){
4207 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4208 if (track->GetClusterIndex(irow)>0){
4216 for (Int_t irow=0;irow<r0;irow++){
4217 if (track->GetClusterIndex(irow)>0){
4222 for (Int_t irow=r0;irow>0;irow--){
4223 if (track->GetClusterIndex(irow)>0){
4228 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4229 if (track->GetClusterIndex(irow)>0){
4236 if ((row[2]-row[0])<20) return 0;
4237 if (row[1]==0) return 0;
4240 //Get cluster and sector position
4241 for (Int_t ipoint=0;ipoint<3;ipoint++){
4242 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4243 AliTPCclusterMI * cl = GetClusterMI(clindex);
4246 // AliTPCclusterMI * cl = GetClusterMI(clindex);
4249 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4250 xyz[ipoint][0] = GetXrow(row[ipoint]);
4251 AliTPCTrackerPoint * point = track->GetTrackPoint(row[ipoint]);
4252 if (point&&ipoint<2){
4254 xyz[ipoint][1] = point->GetY();
4255 xyz[ipoint][2] = point->GetZ();
4258 xyz[ipoint][1] = cl->GetY();
4259 xyz[ipoint][2] = cl->GetZ();
4266 // Calculate seed state vector and covariance matrix
4268 Double_t alpha, cs,sn, xx2,yy2;
4270 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4271 cs = TMath::Cos(alpha);
4272 sn = TMath::Sin(alpha);
4273 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4274 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4278 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4279 cs = TMath::Cos(alpha);
4280 sn = TMath::Sin(alpha);
4281 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4282 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4288 Double_t x[5],c[15];
4292 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4293 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4294 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4296 Double_t sy =0.1, sz =0.1;
4298 Double_t sy1=0.2, sz1=0.2;
4299 Double_t sy2=0.2, sz2=0.2;
4302 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;
4303 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;
4304 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;
4305 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;
4306 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;
4307 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;
4309 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;
4310 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;
4311 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;
4312 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;
4317 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4318 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4319 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4320 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4321 c[13]=f30*sy1*f40+f32*sy2*f42;
4322 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4324 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
4325 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4326 seed->SetPoolID(fLastSeedID);
4327 seed->SetLastPoint(row[2]);
4328 seed->SetFirstPoint(row[2]);
4329 for (Int_t i=row[0];i<row[2];i++){
4330 seed->SetClusterIndex(i, track->GetClusterIndex(i));
4338 void AliTPCtrackerMI::FindMultiMC(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
4341 // find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
4343 // Use AliTPCReconstructor::StreamLevel()>2 if you want to tune parameters - cuts
4345 // Two reasons to have multiple find tracks
4346 // 1. Curling tracks can be find more than once
4347 // 2. Splitted tracks
4348 // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
4349 // b.) Edge effect on the sector boundaries
4352 // Algorithm done in 2 phases - because of CPU consumption
4353 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4355 // Algorihm for curling tracks sign:
4356 // 1 phase -makes a very rough fast cuts to minimize combinatorics
4357 // a.) opposite sign
4358 // b.) one of the tracks - not pointing to the primary vertex -
4359 // c.) delta tan(theta)
4361 // 2 phase - calculates DCA between tracks - time consument
4366 // General cuts - for splitted tracks and for curling tracks
4368 const Float_t kMaxdPhi = 0.2; // maximal distance in phi
4370 // Curling tracks cuts
4375 Int_t nentries = array->GetEntriesFast();
4376 AliHelix *helixes = new AliHelix[nentries];
4377 Float_t *xm = new Float_t[nentries];
4378 Float_t *dz0 = new Float_t[nentries];
4379 Float_t *dz1 = new Float_t[nentries];
4385 // Find track COG in x direction - point with best defined parameters
4387 for (Int_t i=0;i<nentries;i++){
4388 AliTPCseed* track = (AliTPCseed*)array->At(i);
4389 if (!track) continue;
4390 track->SetCircular(0);
4391 new (&helixes[i]) AliHelix(*track);
4395 track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
4398 for (Int_t icl=0; icl<160; icl++){
4399 AliTPCclusterMI * cl = track->GetClusterPointer(icl);
4405 if (ncl>0) xm[i]/=Float_t(ncl);
4408 for (Int_t i0=0;i0<nentries;i0++){
4409 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4410 if (!track0) continue;
4411 Float_t xc0 = helixes[i0].GetHelix(6);
4412 Float_t yc0 = helixes[i0].GetHelix(7);
4413 Float_t r0 = helixes[i0].GetHelix(8);
4414 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4415 Float_t fi0 = TMath::ATan2(yc0,xc0);
4417 for (Int_t i1=i0+1;i1<nentries;i1++){
4418 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4419 if (!track1) continue;
4420 Int_t lab0=track0->GetLabel();
4421 Int_t lab1=track1->GetLabel();
4422 if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
4424 Float_t xc1 = helixes[i1].GetHelix(6);
4425 Float_t yc1 = helixes[i1].GetHelix(7);
4426 Float_t r1 = helixes[i1].GetHelix(8);
4427 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4428 Float_t fi1 = TMath::ATan2(yc1,xc1);
4430 Float_t dfi = fi0-fi1;
4433 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
4434 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
4435 if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
4437 // if short tracks with undefined sign
4438 fi1 = -TMath::ATan2(yc1,-xc1);
4441 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4444 // debug stream to tune "fast cuts"
4446 Double_t dist[3]; // distance at X
4447 Double_t mdist[3]={0,0,0}; // mean distance X+-40cm
4448 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
4449 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4450 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
4451 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4452 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
4453 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4454 for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
4458 for (Int_t icl=0; icl<160; icl++){
4459 AliTPCclusterMI * cl0 = track0->GetClusterPointer(icl);
4460 AliTPCclusterMI * cl1 = track1->GetClusterPointer(icl);
4463 if (cl0==cl1) sums++;
4467 if (AliTPCReconstructor::StreamLevel()>5) {
4468 TTreeSRedirector &cstream = *fDebugStreamer;
4473 "Tr0.="<<track0<< // seed0
4474 "Tr1.="<<track1<< // seed1
4475 "h0.="<<&helixes[i0]<<
4476 "h1.="<<&helixes[i1]<<
4478 "sum="<<sum<< //the sum of rows with cl in both
4479 "sums="<<sums<< //the sum of shared clusters
4480 "xm0="<<xm[i0]<< // the center of track
4481 "xm1="<<xm[i1]<< // the x center of track
4482 // General cut variables
4483 "dfi="<<dfi<< // distance in fi angle
4484 "dtheta="<<dtheta<< // distance int theta angle
4490 "dist0="<<dist[0]<< //distance x
4491 "dist1="<<dist[1]<< //distance y
4492 "dist2="<<dist[2]<< //distance z
4493 "mdist0="<<mdist[0]<< //distance x
4494 "mdist1="<<mdist[1]<< //distance y
4495 "mdist2="<<mdist[2]<< //distance z
4511 if (AliTPCReconstructor::StreamLevel()>1) {
4512 AliInfo("Time for curling tracks removal DEBUGGING MC");
4519 void AliTPCtrackerMI::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t /*iter*/){
4521 // Find Splitted tracks and remove the one with worst quality
4522 // Corresponding debug streamer to tune selections - "Splitted2"
4524 // 0. Sort tracks according quility
4525 // 1. Propagate the tracks to the reference radius
4526 // 2. Double_t loop to select close tracks (only to speed up process)
4527 // 3. Calculate cluster overlap ratio - and remove the track if bigger than a threshold
4528 // 4. Delete temporary parameters
4530 const Double_t xref=GetXrow(63); // reference radius -IROC/OROC boundary
4532 const Double_t kCutP1=10; // delta Z cut 10 cm
4533 const Double_t kCutP2=0.15; // delta snp(fi) cut 0.15
4534 const Double_t kCutP3=0.15; // delta tgl(theta) cut 0.15
4535 const Double_t kCutAlpha=0.15; // delta alpha cut
4536 Int_t firstpoint = 0;
4537 Int_t lastpoint = 160;
4539 Int_t nentries = array->GetEntriesFast();
4540 AliExternalTrackParam *params = new AliExternalTrackParam[nentries];
4546 //0. Sort tracks according quality
4547 //1. Propagate the ext. param to reference radius
4548 Int_t nseed = array->GetEntriesFast();
4549 if (nseed<=0) return;
4550 Float_t * quality = new Float_t[nseed];
4551 Int_t * indexes = new Int_t[nseed];
4552 for (Int_t i=0; i<nseed; i++) {
4553 AliTPCseed *pt=(AliTPCseed*)array->UncheckedAt(i);
4558 pt->UpdatePoints(); //select first last max dens points
4559 Float_t * points = pt->GetPoints();
4560 if (points[3]<0.8) quality[i] =-1;
4561 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
4562 //prefer high momenta tracks if overlaps
4563 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
4565 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),5.,kTRUE);
4566 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),1.,kTRUE);
4568 TMath::Sort(nseed,quality,indexes);
4570 // 3. Loop over pair of tracks
4572 for (Int_t i0=0; i0<nseed; i0++) {
4573 Int_t index0=indexes[i0];
4574 if (!(array->UncheckedAt(index0))) continue;
4575 AliTPCseed *s1 = (AliTPCseed*)array->UncheckedAt(index0);
4576 if (!s1->IsActive()) continue;
4577 AliExternalTrackParam &par0=params[index0];
4578 for (Int_t i1=i0+1; i1<nseed; i1++) {
4579 Int_t index1=indexes[i1];
4580 if (!(array->UncheckedAt(index1))) continue;
4581 AliTPCseed *s2 = (AliTPCseed*)array->UncheckedAt(index1);
4582 if (!s2->IsActive()) continue;
4583 if (s2->GetKinkIndexes()[0]!=0)
4584 if (s2->GetKinkIndexes()[0] == -s1->GetKinkIndexes()[0]) continue;
4585 AliExternalTrackParam &par1=params[index1];
4586 if (TMath::Abs(par0.GetParameter()[3]-par1.GetParameter()[3])>kCutP3) continue;
4587 if (TMath::Abs(par0.GetParameter()[1]-par1.GetParameter()[1])>kCutP1) continue;
4588 if (TMath::Abs(par0.GetParameter()[2]-par1.GetParameter()[2])>kCutP2) continue;
4589 Double_t dAlpha= TMath::Abs(par0.GetAlpha()-par1.GetAlpha());
4590 if (dAlpha>TMath::Pi()) dAlpha-=TMath::Pi();
4591 if (TMath::Abs(dAlpha)>kCutAlpha) continue;
4596 Int_t firstShared=lastpoint, lastShared=firstpoint;
4597 Int_t firstRow=lastpoint, lastRow=firstpoint;
4599 for (Int_t i=firstpoint;i<lastpoint;i++){
4600 if (s1->GetClusterIndex2(i)>0) nall0++;
4601 if (s2->GetClusterIndex2(i)>0) nall1++;
4602 if (s1->GetClusterIndex2(i)>0 && s2->GetClusterIndex2(i)>0) {
4603 if (i<firstRow) firstRow=i;
4604 if (i>lastRow) lastRow=i;
4606 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
4607 if (i<firstShared) firstShared=i;
4608 if (i>lastShared) lastShared=i;
4612 Double_t ratio0 = Float_t(sumShared)/Float_t(TMath::Min(nall0+1,nall1+1));
4613 Double_t ratio1 = Float_t(sumShared)/Float_t(TMath::Max(nall0+1,nall1+1));
4615 if( AliTPCReconstructor::StreamLevel()>1){
4616 TTreeSRedirector &cstream = *fDebugStreamer;
4617 Int_t n0=s1->GetNumberOfClusters();
4618 Int_t n1=s2->GetNumberOfClusters();
4619 Int_t n0F=s1->GetNFoundable();
4620 Int_t n1F=s2->GetNFoundable();
4621 Int_t lab0=s1->GetLabel();
4622 Int_t lab1=s2->GetLabel();
4624 cstream<<"Splitted2"<<
4625 "iter="<<fIteration<<
4626 "lab0="<<lab0<< // MC label if exist
4627 "lab1="<<lab1<< // MC label if exist
4630 "ratio0="<<ratio0<< // shared ratio
4631 "ratio1="<<ratio1<< // shared ratio
4632 "p0.="<<&par0<< // track parameters
4634 "s0.="<<s1<< // full seed
4636 "n0="<<n0<< // number of clusters track 0
4637 "n1="<<n1<< // number of clusters track 1
4638 "nall0="<<nall0<< // number of clusters track 0
4639 "nall1="<<nall1<< // number of clusters track 1
4640 "n0F="<<n0F<< // number of findable
4641 "n1F="<<n1F<< // number of findable
4642 "shared="<<sumShared<< // number of shared clusters
4643 "firstS="<<firstShared<< // first and the last shared row
4644 "lastS="<<lastShared<<
4645 "firstRow="<<firstRow<< // first and the last row with cluster
4646 "lastRow="<<lastRow<< //
4650 // remove track with lower quality
4652 if (ratio0>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(0) ||
4653 ratio1>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(1)){
4657 MarkSeedFree( array->RemoveAt(index1) );
4662 // 4. Delete temporary array
4672 void AliTPCtrackerMI::FindCurling(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
4675 // find Curling tracks
4676 // Use AliTPCReconstructor::StreamLevel()>1 if you want to tune parameters - cuts
4679 // Algorithm done in 2 phases - because of CPU consumption
4680 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4681 // see detal in MC part what can be used to cut
4685 const Float_t kMaxC = 400; // maximal curvature to of the track
4686 const Float_t kMaxdTheta = 0.15; // maximal distance in theta
4687 const Float_t kMaxdPhi = 0.15; // maximal distance in phi
4688 const Float_t kPtRatio = 0.3; // ratio between pt
4689 const Float_t kMinDCAR = 2.; // distance to the primary vertex in r - see cpipe cut
4692 // Curling tracks cuts
4695 const Float_t kMaxDeltaRMax = 40; // distance in outer radius
4696 const Float_t kMaxDeltaRMin = 5.; // distance in lower radius - see cpipe cut
4697 const Float_t kMinAngle = 2.9; // angle between tracks
4698 const Float_t kMaxDist = 5; // biggest distance
4700 // The cuts can be tuned using the "MC information stored in Multi tree ==> see FindMultiMC
4703 TCut csign("csign","Tr0.fP[4]*Tr1.fP[4]<0"); //opposite sign
4704 TCut cmax("cmax","abs(Tr0.GetC())>1/400");
4705 TCut cda("cda","sqrt(dtheta^2+dfi^2)<0.15");
4706 TCut ccratio("ccratio","abs((Tr0.fP[4]+Tr1.fP[4])/(abs(Tr0.fP[4])+abs(Tr1.fP[4])))<0.3");
4707 TCut cpipe("cpipe", "min(abs(r0-rc0),abs(r1-rc1))>5");
4709 TCut cdrmax("cdrmax","abs(abs(rc0+r0)-abs(rc1+r1))<40")
4710 TCut cdrmin("cdrmin","abs(abs(rc0+r0)-abs(rc1+r1))<10")
4712 Multi->Draw("dfi","iter==0"+csign+cmax+cda+ccratio); ~94% of curling tracks fulfill
4713 Multi->Draw("min(abs(r0-rc0),abs(r1-rc1))","iter==0&&abs(lab1)==abs(lab0)"+csign+cmax+cda+ccratio+cpipe+cdrmin+cdrmax); //80%
4715 Curling2->Draw("dfi","iter==0&&abs(lab0)==abs(lab1)"+csign+cmax+cdtheta+cdfi+ccratio)
4721 Int_t nentries = array->GetEntriesFast();
4722 AliHelix *helixes = new AliHelix[nentries];
4723 for (Int_t i=0;i<nentries;i++){
4724 AliTPCseed* track = (AliTPCseed*)array->At(i);
4725 if (!track) continue;
4726 track->SetCircular(0);
4727 new (&helixes[i]) AliHelix(*track);
4733 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
4739 for (Int_t i0=0;i0<nentries;i0++){
4740 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4741 if (!track0) continue;
4742 if (TMath::Abs(track0->GetC())<1/kMaxC) continue;
4743 Float_t xc0 = helixes[i0].GetHelix(6);
4744 Float_t yc0 = helixes[i0].GetHelix(7);
4745 Float_t r0 = helixes[i0].GetHelix(8);
4746 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4747 Float_t fi0 = TMath::ATan2(yc0,xc0);
4749 for (Int_t i1=i0+1;i1<nentries;i1++){
4750 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4751 if (!track1) continue;
4752 if (TMath::Abs(track1->GetC())<1/kMaxC) continue;
4753 Float_t xc1 = helixes[i1].GetHelix(6);
4754 Float_t yc1 = helixes[i1].GetHelix(7);
4755 Float_t r1 = helixes[i1].GetHelix(8);
4756 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4757 Float_t fi1 = TMath::ATan2(yc1,xc1);
4759 Float_t dfi = fi0-fi1;
4762 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
4763 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
4764 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4768 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue; // not constrained
4769 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue; // not the same sign
4770 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>kMaxdTheta) continue; //distance in the Theta
4771 if ( TMath::Abs(dfi)>kMaxdPhi) continue; //distance in phi
4772 if ( TMath::Sqrt(dfi*dfi+dtheta*dtheta)>kMaxdPhi) continue; //common angular offset
4774 Float_t pt0 = track0->GetSignedPt();
4775 Float_t pt1 = track1->GetSignedPt();
4776 if ((TMath::Abs(pt0+pt1)/(TMath::Abs(pt0)+TMath::Abs(pt1)))>kPtRatio) continue;
4777 if ((iter==1) && TMath::Abs(TMath::Abs(rc0+r0)-TMath::Abs(rc1+r1))>kMaxDeltaRMax) continue;
4778 if ((iter!=1) &&TMath::Abs(TMath::Abs(rc0-r0)-TMath::Abs(rc1-r1))>kMaxDeltaRMin) continue;
4779 if (TMath::Min(TMath::Abs(rc0-r0),TMath::Abs(rc1-r1))<kMinDCAR) continue;
4782 // Now find closest approach
4786 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4787 if (npoints==0) continue;
4788 helixes[i0].GetClosestPhases(helixes[i1], phase);
4792 Double_t hangles[3];
4793 helixes[i0].Evaluate(phase[0][0],xyz0);
4794 helixes[i1].Evaluate(phase[0][1],xyz1);
4796 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
4797 Double_t deltah[2],deltabest;
4798 if (TMath::Abs(hangles[2])<kMinAngle) continue;
4802 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
4804 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
4805 if (deltah[1]<deltah[0]) ibest=1;
4807 deltabest = TMath::Sqrt(deltah[ibest]);
4808 helixes[i0].Evaluate(phase[ibest][0],xyz0);
4809 helixes[i1].Evaluate(phase[ibest][1],xyz1);
4810 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
4811 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
4813 if (deltabest>kMaxDist) continue;
4814 // if (mindcar+mindcaz<40 && (TMath::Abs(hangles[2])<kMinAngle ||deltabest>3)) continue;
4815 Bool_t sign =kFALSE;
4816 if (hangles[2]>kMinAngle) sign =kTRUE;
4819 // circular[i0] = kTRUE;
4820 // circular[i1] = kTRUE;
4821 if (track0->OneOverPt()<track1->OneOverPt()){
4822 track0->SetCircular(track0->GetCircular()+1);
4823 track1->SetCircular(track1->GetCircular()+2);
4826 track1->SetCircular(track1->GetCircular()+1);
4827 track0->SetCircular(track0->GetCircular()+2);
4830 if (AliTPCReconstructor::StreamLevel()>2){
4832 //debug stream to tune "fine" cuts
4833 Int_t lab0=track0->GetLabel();
4834 Int_t lab1=track1->GetLabel();
4835 TTreeSRedirector &cstream = *fDebugStreamer;
4836 cstream<<"Curling2"<<
4852 "npoints="<<npoints<<
4853 "hangles0="<<hangles[0]<<
4854 "hangles1="<<hangles[1]<<
4855 "hangles2="<<hangles[2]<<
4858 "radius="<<radiusbest<<
4859 "deltabest="<<deltabest<<
4860 "phase0="<<phase[ibest][0]<<
4861 "phase1="<<phase[ibest][1]<<
4869 if (AliTPCReconstructor::StreamLevel()>1) {
4870 AliInfo("Time for curling tracks removal");
4876 void AliTPCtrackerMI::FindKinks(TObjArray * array, AliESDEvent *esd)
4882 // RS something is wrong in this routine: not all seeds are assigned to daughters and mothers array, but they all are queried
4885 TObjArray *kinks= new TObjArray(10000);
4886 // TObjArray *v0s= new TObjArray(10000);
4887 Int_t nentries = array->GetEntriesFast();
4888 AliHelix *helixes = new AliHelix[nentries];
4889 Int_t *sign = new Int_t[nentries];
4890 Int_t *nclusters = new Int_t[nentries];
4891 Float_t *alpha = new Float_t[nentries];
4892 AliKink *kink = new AliKink();
4893 Int_t * usage = new Int_t[nentries];
4894 Float_t *zm = new Float_t[nentries];
4895 Float_t *z0 = new Float_t[nentries];
4896 Float_t *fim = new Float_t[nentries];
4897 Float_t *shared = new Float_t[nentries];
4898 Bool_t *circular = new Bool_t[nentries];
4899 Float_t *dca = new Float_t[nentries];
4900 //const AliESDVertex * primvertex = esd->GetVertex();
4902 // nentries = array->GetEntriesFast();
4907 for (Int_t i=0;i<nentries;i++){
4910 AliTPCseed* track = (AliTPCseed*)array->At(i);
4911 if (!track) continue;
4912 track->SetCircular(0);
4914 track->UpdatePoints();
4915 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
4917 nclusters[i]=track->GetNumberOfClusters();
4918 alpha[i] = track->GetAlpha();
4919 new (&helixes[i]) AliHelix(*track);
4921 helixes[i].Evaluate(0,xyz);
4922 sign[i] = (track->GetC()>0) ? -1:1;
4925 if (track->GetProlongation(x,y,z)){
4927 fim[i] = alpha[i]+TMath::ATan2(y,x);
4930 zm[i] = track->GetZ();
4934 circular[i]= kFALSE;
4935 if (track->GetProlongation(0,y,z)) z0[i] = z;
4936 dca[i] = track->GetD(0,0);
4942 Int_t ncandidates =0;
4945 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
4948 // Find circling track
4950 for (Int_t i0=0;i0<nentries;i0++){
4951 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4952 if (!track0) continue;
4953 if (track0->GetNumberOfClusters()<40) continue;
4954 if (TMath::Abs(1./track0->GetC())>200) continue;
4955 for (Int_t i1=i0+1;i1<nentries;i1++){
4956 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4957 if (!track1) continue;
4958 if (track1->GetNumberOfClusters()<40) continue;
4959 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
4960 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
4961 if (TMath::Abs(1./track1->GetC())>200) continue;
4962 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
4963 if (track1->GetTgl()*track0->GetTgl()>0) continue;
4964 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
4965 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
4966 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
4968 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
4969 if (mindcar<5) continue;
4970 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
4971 if (mindcaz<5) continue;
4972 if (mindcar+mindcaz<20) continue;
4975 Float_t xc0 = helixes[i0].GetHelix(6);
4976 Float_t yc0 = helixes[i0].GetHelix(7);
4977 Float_t r0 = helixes[i0].GetHelix(8);
4978 Float_t xc1 = helixes[i1].GetHelix(6);
4979 Float_t yc1 = helixes[i1].GetHelix(7);
4980 Float_t r1 = helixes[i1].GetHelix(8);
4982 Float_t rmean = (r0+r1)*0.5;
4983 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
4984 //if (delta>30) continue;
4985 if (delta>rmean*0.25) continue;
4986 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
4988 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4989 if (npoints==0) continue;
4990 helixes[i0].GetClosestPhases(helixes[i1], phase);
4994 Double_t hangles[3];
4995 helixes[i0].Evaluate(phase[0][0],xyz0);
4996 helixes[i1].Evaluate(phase[0][1],xyz1);
4998 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
4999 Double_t deltah[2],deltabest;
5000 if (hangles[2]<2.8) continue;
5003 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
5005 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
5006 if (deltah[1]<deltah[0]) ibest=1;
5008 deltabest = TMath::Sqrt(deltah[ibest]);
5009 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5010 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5011 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5012 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5014 if (deltabest>6) continue;
5015 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
5016 Bool_t lsign =kFALSE;
5017 if (hangles[2]>3.06) lsign =kTRUE;
5020 circular[i0] = kTRUE;
5021 circular[i1] = kTRUE;
5022 if (track0->OneOverPt()<track1->OneOverPt()){
5023 track0->SetCircular(track0->GetCircular()+1);
5024 track1->SetCircular(track1->GetCircular()+2);
5027 track1->SetCircular(track1->GetCircular()+1);
5028 track0->SetCircular(track0->GetCircular()+2);
5031 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
5033 Int_t lab0=track0->GetLabel();
5034 Int_t lab1=track1->GetLabel();
5035 TTreeSRedirector &cstream = *fDebugStreamer;
5036 cstream<<"Curling"<<
5043 "mindcar="<<mindcar<<
5044 "mindcaz="<<mindcaz<<
5047 "npoints="<<npoints<<
5048 "hangles0="<<hangles[0]<<
5049 "hangles2="<<hangles[2]<<
5054 "radius="<<radiusbest<<
5055 "deltabest="<<deltabest<<
5056 "phase0="<<phase[ibest][0]<<
5057 "phase1="<<phase[ibest][1]<<
5067 for (Int_t i =0;i<nentries;i++){
5068 if (sign[i]==0) continue;
5069 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5076 Double_t cradius0 = 40*40;
5077 Double_t cradius1 = 270*270;
5080 Double_t cdist3=0.55;
5081 for (Int_t j =i+1;j<nentries;j++){
5083 if (sign[j]*sign[i]<1) continue;
5084 if ( (nclusters[i]+nclusters[j])>200) continue;
5085 if ( (nclusters[i]+nclusters[j])<80) continue;
5086 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
5087 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
5088 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
5089 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5090 if (npoints<1) continue;
5093 if (radius[0]<cradius0||radius[0]>cradius1) continue;
5096 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
5099 Double_t delta1=10000,delta2=10000;
5100 // cuts on the intersection radius
5101 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5102 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5103 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5105 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5106 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5107 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5110 Double_t distance1 = TMath::Min(delta1,delta2);
5111 if (distance1>cdist1) continue; // cut on DCA linear approximation
5113 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5114 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5115 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5116 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5119 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5120 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5121 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5123 distance1 = TMath::Min(delta1,delta2);
5126 rkink = TMath::Sqrt(radius[0]);
5129 rkink = TMath::Sqrt(radius[1]);
5131 if (distance1>cdist2) continue;
5134 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5137 Int_t row0 = GetRowNumber(rkink);
5138 if (row0<10) continue;
5139 if (row0>150) continue;
5142 Float_t dens00=-1,dens01=-1;
5143 Float_t dens10=-1,dens11=-1;
5145 Int_t found,foundable,ishared;
5146 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5147 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
5148 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5149 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
5151 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5152 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
5153 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5154 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
5156 if (dens00<dens10 && dens01<dens11) continue;
5157 if (dens00>dens10 && dens01>dens11) continue;
5158 if (TMath::Max(dens00,dens10)<0.1) continue;
5159 if (TMath::Max(dens01,dens11)<0.3) continue;
5161 if (TMath::Min(dens00,dens10)>0.6) continue;
5162 if (TMath::Min(dens01,dens11)>0.6) continue;
5165 AliTPCseed * ktrack0, *ktrack1;
5174 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
5175 AliExternalTrackParam paramm(*ktrack0);
5176 AliExternalTrackParam paramd(*ktrack1);
5177 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (¶md) AliExternalTrackParam(ktrack1->GetReference());
5180 kink->SetMother(paramm);
5181 kink->SetDaughter(paramd);
5184 Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
5186 fkParam->Transform0to1(x,index);
5187 fkParam->Transform1to2(x,index);
5188 row0 = GetRowNumber(x[0]);
5190 if (kink->GetR()<100) continue;
5191 if (kink->GetR()>240) continue;
5192 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
5193 if (kink->GetDistance()>cdist3) continue;
5194 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
5195 if (dird<0) continue;
5197 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
5198 if (dirm<0) continue;
5199 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
5200 if (mpt<0.2) continue;
5203 //for high momenta momentum not defined well in first iteration
5204 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
5205 if (qt>0.35) continue;
5208 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
5209 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
5211 kink->SetTPCDensity(dens00,0,0);
5212 kink->SetTPCDensity(dens01,0,1);
5213 kink->SetTPCDensity(dens10,1,0);
5214 kink->SetTPCDensity(dens11,1,1);
5215 kink->SetIndex(i,0);
5216 kink->SetIndex(j,1);
5219 kink->SetTPCDensity(dens10,0,0);
5220 kink->SetTPCDensity(dens11,0,1);
5221 kink->SetTPCDensity(dens00,1,0);
5222 kink->SetTPCDensity(dens01,1,1);
5223 kink->SetIndex(j,0);
5224 kink->SetIndex(i,1);
5227 if (mpt<1||kink->GetAngle(2)>0.1){
5228 // angle and densities not defined yet
5229 if (kink->GetTPCDensityFactor()<0.8) continue;
5230 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
5231 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
5232 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5233 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5235 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5236 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
5237 criticalangle= 3*TMath::Sqrt(criticalangle);
5238 if (criticalangle>0.02) criticalangle=0.02;
5239 if (kink->GetAngle(2)<criticalangle) continue;
5242 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
5243 Float_t shapesum =0;
5245 for ( Int_t row = row0-drow; row<row0+drow;row++){
5246 if (row<0) continue;
5247 if (row>155) continue;
5248 if (ktrack0->GetClusterPointer(row)){
5249 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5250 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5253 if (ktrack1->GetClusterPointer(row)){
5254 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5255 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5260 kink->SetShapeFactor(-1.);
5263 kink->SetShapeFactor(shapesum/sum);
5265 // esd->AddKink(kink);
5267 // kink->SetMother(paramm);
5268 //kink->SetDaughter(paramd);
5270 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
5272 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
5273 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
5275 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
5277 if (AliTPCReconstructor::StreamLevel()>1) {
5278 (*fDebugStreamer)<<"kinkLpt"<<
5286 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
5290 kinks->AddLast(kink);
5296 // sort the kinks according quality - and refit them towards vertex
5298 Int_t nkinks = kinks->GetEntriesFast();
5299 Float_t *quality = new Float_t[nkinks];
5300 Int_t *indexes = new Int_t[nkinks];
5301 AliTPCseed *mothers = new AliTPCseed[nkinks];
5302 AliTPCseed *daughters = new AliTPCseed[nkinks];
5305 for (Int_t i=0;i<nkinks;i++){
5307 AliKink *kinkl = (AliKink*)kinks->At(i);
5309 // refit kinks towards vertex
5311 Int_t index0 = kinkl->GetIndex(0);
5312 Int_t index1 = kinkl->GetIndex(1);
5313 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5314 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5316 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
5318 // Refit Kink under if too small angle
5320 if (kinkl->GetAngle(2)<0.05){
5321 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5322 Int_t row0 = kinkl->GetTPCRow0();
5323 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
5326 Int_t last = row0-drow;
5327 if (last<40) last=40;
5328 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
5329 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
5332 Int_t first = row0+drow;
5333 if (first>130) first=130;
5334 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
5335 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
5337 if (seed0 && seed1){
5338 kinkl->SetStatus(1,8);
5339 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
5340 row0 = GetRowNumber(kinkl->GetR());
5341 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
5342 mothers[i] = *seed0;
5343 daughters[i] = *seed1;
5346 delete kinks->RemoveAt(i);
5347 if (seed0) MarkSeedFree( seed0 );
5348 if (seed1) MarkSeedFree( seed1 );
5351 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
5352 delete kinks->RemoveAt(i);
5353 if (seed0) MarkSeedFree( seed0 );
5354 if (seed1) MarkSeedFree( seed1 );
5358 MarkSeedFree( seed0 );
5359 MarkSeedFree( seed1 );
5362 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
5364 TMath::Sort(nkinks,quality,indexes,kFALSE);
5366 //remove double find kinks
5368 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
5369 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
5370 if (!kink0) continue;
5372 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
5373 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
5374 if (!kink0) continue;
5375 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
5376 if (!kink1) continue;
5377 // if not close kink continue
5378 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
5379 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
5380 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
5382 AliTPCseed &mother0 = mothers[indexes[ikink0]];
5383 AliTPCseed &daughter0 = daughters[indexes[ikink0]];
5384 AliTPCseed &mother1 = mothers[indexes[ikink1]];
5385 AliTPCseed &daughter1 = daughters[indexes[ikink1]];
5386 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
5395 for (Int_t i=0;i<row0;i++){
5396 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
5399 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
5406 for (Int_t i=row0;i<158;i++){
5407 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
5408 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
5411 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
5417 Float_t ratio = Float_t(same+1)/Float_t(both+1);
5418 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
5419 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
5420 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
5421 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
5422 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
5424 shared[kink0->GetIndex(0)]= kTRUE;
5425 shared[kink0->GetIndex(1)]= kTRUE;
5426 delete kinks->RemoveAt(indexes[ikink0]);
5430 shared[kink1->GetIndex(0)]= kTRUE;
5431 shared[kink1->GetIndex(1)]= kTRUE;
5432 delete kinks->RemoveAt(indexes[ikink1]);
5439 for (Int_t i=0;i<nkinks;i++){
5440 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
5441 if (!kinkl) continue;
5442 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5443 Int_t index0 = kinkl->GetIndex(0);
5444 Int_t index1 = kinkl->GetIndex(1);
5445 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
5446 kinkl->SetMultiple(usage[index0],0);
5447 kinkl->SetMultiple(usage[index1],1);
5448 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
5449 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
5450 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
5451 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
5453 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5454 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5455 if (!ktrack0 || !ktrack1) continue;
5456 Int_t index = esd->AddKink(kinkl);
5459 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
5460 if (mothers[indexes[i]].GetNumberOfClusters()>20 && daughters[indexes[i]].GetNumberOfClusters()>20 && (mothers[indexes[i]].GetNumberOfClusters()+daughters[indexes[i]].GetNumberOfClusters())>100){
5461 *ktrack0 = mothers[indexes[i]];
5462 *ktrack1 = daughters[indexes[i]];
5466 ktrack0->SetKinkIndex(usage[index0],-(index+1));
5467 ktrack1->SetKinkIndex(usage[index1], (index+1));
5472 // Remove tracks corresponding to shared kink's
5474 for (Int_t i=0;i<nentries;i++){
5475 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5476 if (!track0) continue;
5477 if (track0->GetKinkIndex(0)!=0) continue;
5478 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
5483 RemoveUsed2(array,0.5,0.4,30);
5485 for (Int_t i=0;i<nentries;i++){
5486 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5487 if (!track0) continue;
5488 track0->CookdEdx(0.02,0.6);
5492 for (Int_t i=0;i<nentries;i++){
5493 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5494 if (!track0) continue;
5495 if (track0->Pt()<1.4) continue;
5496 //remove double high momenta tracks - overlapped with kink candidates
5499 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
5500 if (track0->GetClusterPointer(icl)!=0){
5502 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
5505 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
5506 MarkSeedFree( array->RemoveAt(i) );
5510 if (track0->GetKinkIndex(0)!=0) continue;
5511 if (track0->GetNumberOfClusters()<80) continue;
5513 AliTPCseed *pmother = new AliTPCseed();
5514 AliTPCseed *pdaughter = new AliTPCseed();
5515 AliKink *pkink = new AliKink;
5517 AliTPCseed & mother = *pmother;
5518 AliTPCseed & daughter = *pdaughter;
5519 AliKink & kinkl = *pkink;
5520 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
5521 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
5525 continue; //too short tracks
5527 if (mother.Pt()<1.4) {
5533 Int_t row0= kinkl.GetTPCRow0();
5534 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
5541 Int_t index = esd->AddKink(&kinkl);
5542 mother.SetKinkIndex(0,-(index+1));
5543 daughter.SetKinkIndex(0,index+1);
5544 if (mother.GetNumberOfClusters()>50) {
5545 MarkSeedFree( array->RemoveAt(i) );
5546 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
5547 mtc->SetPoolID(fLastSeedID);
5548 array->AddAt(mtc,i);
5551 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
5552 mtc->SetPoolID(fLastSeedID);
5553 array->AddLast(mtc);
5555 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
5556 dtc->SetPoolID(fLastSeedID);
5557 array->AddLast(dtc);
5558 for (Int_t icl=0;icl<row0;icl++) {
5559 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
5562 for (Int_t icl=row0;icl<158;icl++) {
5563 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
5572 delete [] daughters;
5594 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
5600 void AliTPCtrackerMI::FindKinks(TObjArray * array, AliESDEvent *esd)
5607 TObjArray *kinks= new TObjArray(10000);
5608 // TObjArray *v0s= new TObjArray(10000);
5609 Int_t nentries = array->GetEntriesFast();
5610 AliHelix *helixes = new AliHelix[nentries];
5611 Int_t *sign = new Int_t[nentries];
5612 Int_t *nclusters = new Int_t[nentries];
5613 Float_t *alpha = new Float_t[nentries];
5614 AliKink *kink = new AliKink();
5615 Int_t * usage = new Int_t[nentries];
5616 Float_t *zm = new Float_t[nentries];
5617 Float_t *z0 = new Float_t[nentries];
5618 Float_t *fim = new Float_t[nentries];
5619 Float_t *shared = new Float_t[nentries];
5620 Bool_t *circular = new Bool_t[nentries];
5621 Float_t *dca = new Float_t[nentries];
5622 //const AliESDVertex * primvertex = esd->GetVertex();
5624 // nentries = array->GetEntriesFast();
5629 for (Int_t i=0;i<nentries;i++){
5632 AliTPCseed* track = (AliTPCseed*)array->At(i);
5633 if (!track) continue;
5634 track->SetCircular(0);
5636 track->UpdatePoints();
5637 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
5639 nclusters[i]=track->GetNumberOfClusters();
5640 alpha[i] = track->GetAlpha();
5641 new (&helixes[i]) AliHelix(*track);
5643 helixes[i].Evaluate(0,xyz);
5644 sign[i] = (track->GetC()>0) ? -1:1;
5647 if (track->GetProlongation(x,y,z)){
5649 fim[i] = alpha[i]+TMath::ATan2(y,x);
5652 zm[i] = track->GetZ();
5656 circular[i]= kFALSE;
5657 if (track->GetProlongation(0,y,z)) z0[i] = z;
5658 dca[i] = track->GetD(0,0);
5664 Int_t ncandidates =0;
5667 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
5670 // Find circling track
5672 for (Int_t i0=0;i0<nentries;i0++){
5673 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5674 if (!track0) continue;
5675 if (track0->GetNumberOfClusters()<40) continue;
5676 if (TMath::Abs(1./track0->GetC())>200) continue;
5677 for (Int_t i1=i0+1;i1<nentries;i1++){
5678 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5679 if (!track1) continue;
5680 if (track1->GetNumberOfClusters()<40) continue;
5681 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
5682 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
5683 if (TMath::Abs(1./track1->GetC())>200) continue;
5684 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
5685 if (track1->GetTgl()*track0->GetTgl()>0) continue;
5686 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
5687 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
5688 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
5690 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
5691 if (mindcar<5) continue;
5692 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
5693 if (mindcaz<5) continue;
5694 if (mindcar+mindcaz<20) continue;
5697 Float_t xc0 = helixes[i0].GetHelix(6);
5698 Float_t yc0 = helixes[i0].GetHelix(7);
5699 Float_t r0 = helixes[i0].GetHelix(8);
5700 Float_t xc1 = helixes[i1].GetHelix(6);
5701 Float_t yc1 = helixes[i1].GetHelix(7);
5702 Float_t r1 = helixes[i1].GetHelix(8);
5704 Float_t rmean = (r0+r1)*0.5;
5705 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
5706 //if (delta>30) continue;
5707 if (delta>rmean*0.25) continue;
5708 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
5710 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5711 if (npoints==0) continue;
5712 helixes[i0].GetClosestPhases(helixes[i1], phase);
5716 Double_t hangles[3];
5717 helixes[i0].Evaluate(phase[0][0],xyz0);
5718 helixes[i1].Evaluate(phase[0][1],xyz1);
5720 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5721 Double_t deltah[2],deltabest;
5722 if (hangles[2]<2.8) continue;
5725 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
5727 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
5728 if (deltah[1]<deltah[0]) ibest=1;
5730 deltabest = TMath::Sqrt(deltah[ibest]);
5731 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5732 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5733 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5734 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5736 if (deltabest>6) continue;
5737 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
5738 Bool_t lsign =kFALSE;
5739 if (hangles[2]>3.06) lsign =kTRUE;
5742 circular[i0] = kTRUE;
5743 circular[i1] = kTRUE;
5744 if (track0->OneOverPt()<track1->OneOverPt()){
5745 track0->SetCircular(track0->GetCircular()+1);
5746 track1->SetCircular(track1->GetCircular()+2);
5749 track1->SetCircular(track1->GetCircular()+1);
5750 track0->SetCircular(track0->GetCircular()+2);
5753 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
5755 Int_t lab0=track0->GetLabel();
5756 Int_t lab1=track1->GetLabel();
5757 TTreeSRedirector &cstream = *fDebugStreamer;
5758 cstream<<"Curling"<<
5765 "mindcar="<<mindcar<<
5766 "mindcaz="<<mindcaz<<
5769 "npoints="<<npoints<<
5770 "hangles0="<<hangles[0]<<
5771 "hangles2="<<hangles[2]<<
5776 "radius="<<radiusbest<<
5777 "deltabest="<<deltabest<<
5778 "phase0="<<phase[ibest][0]<<
5779 "phase1="<<phase[ibest][1]<<
5789 for (Int_t i =0;i<nentries;i++){
5790 if (sign[i]==0) continue;
5791 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5798 Double_t cradius0 = 40*40;
5799 Double_t cradius1 = 270*270;
5802 Double_t cdist3=0.55;
5803 for (Int_t j =i+1;j<nentries;j++){
5805 if (sign[j]*sign[i]<1) continue;
5806 if ( (nclusters[i]+nclusters[j])>200) continue;
5807 if ( (nclusters[i]+nclusters[j])<80) continue;
5808 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
5809 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
5810 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
5811 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5812 if (npoints<1) continue;
5815 if (radius[0]<cradius0||radius[0]>cradius1) continue;
5818 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
5821 Double_t delta1=10000,delta2=10000;
5822 // cuts on the intersection radius
5823 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5824 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5825 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5827 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5828 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5829 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5832 Double_t distance1 = TMath::Min(delta1,delta2);
5833 if (distance1>cdist1) continue; // cut on DCA linear approximation
5835 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5836 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5837 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5838 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5841 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5842 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5843 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5845 distance1 = TMath::Min(delta1,delta2);
5848 rkink = TMath::Sqrt(radius[0]);
5851 rkink = TMath::Sqrt(radius[1]);
5853 if (distance1>cdist2) continue;
5856 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5859 Int_t row0 = GetRowNumber(rkink);
5860 if (row0<10) continue;
5861 if (row0>150) continue;
5864 Float_t dens00=-1,dens01=-1;
5865 Float_t dens10=-1,dens11=-1;
5867 Int_t found,foundable,ishared;
5868 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5869 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
5870 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5871 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
5873 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5874 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
5875 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5876 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
5878 if (dens00<dens10 && dens01<dens11) continue;
5879 if (dens00>dens10 && dens01>dens11) continue;
5880 if (TMath::Max(dens00,dens10)<0.1) continue;
5881 if (TMath::Max(dens01,dens11)<0.3) continue;
5883 if (TMath::Min(dens00,dens10)>0.6) continue;
5884 if (TMath::Min(dens01,dens11)>0.6) continue;
5887 AliTPCseed * ktrack0, *ktrack1;
5896 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
5897 AliExternalTrackParam paramm(*ktrack0);
5898 AliExternalTrackParam paramd(*ktrack1);
5899 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (¶md) AliExternalTrackParam(ktrack1->GetReference());
5902 kink->SetMother(paramm);
5903 kink->SetDaughter(paramd);
5906 Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
5908 fkParam->Transform0to1(x,index);
5909 fkParam->Transform1to2(x,index);
5910 row0 = GetRowNumber(x[0]);
5912 if (kink->GetR()<100) continue;
5913 if (kink->GetR()>240) continue;
5914 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
5915 if (kink->GetDistance()>cdist3) continue;
5916 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
5917 if (dird<0) continue;
5919 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
5920 if (dirm<0) continue;
5921 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
5922 if (mpt<0.2) continue;
5925 //for high momenta momentum not defined well in first iteration
5926 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
5927 if (qt>0.35) continue;
5930 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
5931 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
5933 kink->SetTPCDensity(dens00,0,0);
5934 kink->SetTPCDensity(dens01,0,1);
5935 kink->SetTPCDensity(dens10,1,0);
5936 kink->SetTPCDensity(dens11,1,1);
5937 kink->SetIndex(i,0);
5938 kink->SetIndex(j,1);
5941 kink->SetTPCDensity(dens10,0,0);
5942 kink->SetTPCDensity(dens11,0,1);
5943 kink->SetTPCDensity(dens00,1,0);
5944 kink->SetTPCDensity(dens01,1,1);
5945 kink->SetIndex(j,0);
5946 kink->SetIndex(i,1);
5949 if (mpt<1||kink->GetAngle(2)>0.1){
5950 // angle and densities not defined yet
5951 if (kink->GetTPCDensityFactor()<0.8) continue;
5952 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
5953 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
5954 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5955 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5957 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5958 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
5959 criticalangle= 3*TMath::Sqrt(criticalangle);
5960 if (criticalangle>0.02) criticalangle=0.02;
5961 if (kink->GetAngle(2)<criticalangle) continue;
5964 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
5965 Float_t shapesum =0;
5967 for ( Int_t row = row0-drow; row<row0+drow;row++){
5968 if (row<0) continue;
5969 if (row>155) continue;
5970 if (ktrack0->GetClusterPointer(row)){
5971 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5972 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5975 if (ktrack1->GetClusterPointer(row)){
5976 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5977 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5982 kink->SetShapeFactor(-1.);
5985 kink->SetShapeFactor(shapesum/sum);
5987 // esd->AddKink(kink);
5989 // kink->SetMother(paramm);
5990 //kink->SetDaughter(paramd);
5992 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
5994 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
5995 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
5997 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
5999 if (AliTPCReconstructor::StreamLevel()>1) {
6000 (*fDebugStreamer)<<"kinkLpt"<<
6008 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
6012 kinks->AddLast(kink);
6018 // sort the kinks according quality - and refit them towards vertex
6020 Int_t nkinks = kinks->GetEntriesFast();
6021 Float_t *quality = new Float_t[nkinks];
6022 Int_t *indexes = new Int_t[nkinks];
6023 AliTPCseed **mothers = new AliTPCseed*[nkinks]; memset(mothers, 0, nkinks*sizeof(AliTPCseed*));
6024 AliTPCseed **daughters = new AliTPCseed*[nkinks]; memset(daughters, 0, nkinks*sizeof(AliTPCseed*));
6027 for (Int_t i=0;i<nkinks;i++){
6029 AliKink *kinkl = (AliKink*)kinks->At(i);
6031 // refit kinks towards vertex
6033 Int_t index0 = kinkl->GetIndex(0);
6034 Int_t index1 = kinkl->GetIndex(1);
6035 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6036 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6038 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
6040 // Refit Kink under if too small angle
6042 if (kinkl->GetAngle(2)<0.05){
6043 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6044 Int_t row0 = kinkl->GetTPCRow0();
6045 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
6048 Int_t last = row0-drow;
6049 if (last<40) last=40;
6050 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
6051 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
6054 Int_t first = row0+drow;
6055 if (first>130) first=130;
6056 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
6057 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
6059 if (seed0 && seed1){
6060 kinkl->SetStatus(1,8);
6061 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
6062 row0 = GetRowNumber(kinkl->GetR());
6063 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
6064 mothers[i] = new ( NextFreeSeed() ) AliTPCseed(*seed0);
6065 mothers[i]->SetPoolID(fLastSeedID);
6066 daughters[i] = new (NextFreeSeed() ) AliTPCseed(*seed1);
6067 daughters[i]->SetPoolID(fLastSeedID);
6070 delete kinks->RemoveAt(i);
6071 if (seed0) MarkSeedFree( seed0 );
6072 if (seed1) MarkSeedFree( seed1 );
6075 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
6076 delete kinks->RemoveAt(i);
6077 if (seed0) MarkSeedFree( seed0 );
6078 if (seed1) MarkSeedFree( seed1 );
6082 MarkSeedFree( seed0 );
6083 MarkSeedFree( seed1 );
6086 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
6088 TMath::Sort(nkinks,quality,indexes,kFALSE);
6090 //remove double find kinks
6092 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
6093 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6094 if (!kink0) continue;
6096 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
6097 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6098 if (!kink0) continue;
6099 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
6100 if (!kink1) continue;
6101 // if not close kink continue
6102 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
6103 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
6104 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
6106 AliTPCseed &mother0 = *mothers[indexes[ikink0]];
6107 AliTPCseed &daughter0 = *daughters[indexes[ikink0]];
6108 AliTPCseed &mother1 = *mothers[indexes[ikink1]];
6109 AliTPCseed &daughter1 = *daughters[indexes[ikink1]];
6110 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
6119 for (Int_t i=0;i<row0;i++){
6120 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
6123 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6130 for (Int_t i=row0;i<158;i++){
6131 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
6132 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
6135 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6141 Float_t ratio = Float_t(same+1)/Float_t(both+1);
6142 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
6143 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
6144 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
6145 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
6146 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
6148 shared[kink0->GetIndex(0)]= kTRUE;
6149 shared[kink0->GetIndex(1)]= kTRUE;
6150 delete kinks->RemoveAt(indexes[ikink0]);
6154 shared[kink1->GetIndex(0)]= kTRUE;
6155 shared[kink1->GetIndex(1)]= kTRUE;
6156 delete kinks->RemoveAt(indexes[ikink1]);
6163 for (Int_t i=0;i<nkinks;i++){
6164 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
6165 if (!kinkl) continue;
6166 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6167 Int_t index0 = kinkl->GetIndex(0);
6168 Int_t index1 = kinkl->GetIndex(1);
6169 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
6170 kinkl->SetMultiple(usage[index0],0);
6171 kinkl->SetMultiple(usage[index1],1);
6172 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
6173 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
6174 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
6175 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
6177 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6178 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6179 if (!ktrack0 || !ktrack1) continue;
6180 Int_t index = esd->AddKink(kinkl);
6183 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
6184 if (mothers[indexes[i]]->GetNumberOfClusters()>20 && daughters[indexes[i]]->GetNumberOfClusters()>20 &&
6185 (mothers[indexes[i]]->GetNumberOfClusters()+daughters[indexes[i]]->GetNumberOfClusters())>100){
6186 *ktrack0 = *mothers[indexes[i]];
6187 *ktrack1 = *daughters[indexes[i]];
6191 ktrack0->SetKinkIndex(usage[index0],-(index+1));
6192 ktrack1->SetKinkIndex(usage[index1], (index+1));
6197 // Remove tracks corresponding to shared kink's
6199 for (Int_t i=0;i<nentries;i++){
6200 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6201 if (!track0) continue;
6202 if (track0->GetKinkIndex(0)!=0) continue;
6203 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
6208 RemoveUsed2(array,0.5,0.4,30);
6210 for (Int_t i=0;i<nentries;i++){
6211 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6212 if (!track0) continue;
6213 track0->CookdEdx(0.02,0.6);
6217 for (Int_t i=0;i<nentries;i++){
6218 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6219 if (!track0) continue;
6220 if (track0->Pt()<1.4) continue;
6221 //remove double high momenta tracks - overlapped with kink candidates
6224 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
6225 if (track0->GetClusterPointer(icl)!=0){
6227 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
6230 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
6231 MarkSeedFree( array->RemoveAt(i) );
6235 if (track0->GetKinkIndex(0)!=0) continue;
6236 if (track0->GetNumberOfClusters()<80) continue;
6238 AliTPCseed *pmother = new( NextFreeSeed() ) AliTPCseed();
6239 pmother->SetPoolID(fLastSeedID);
6240 AliTPCseed *pdaughter = new( NextFreeSeed() ) AliTPCseed();
6241 pdaughter->SetPoolID(fLastSeedID);
6242 AliKink *pkink = new AliKink;
6244 AliTPCseed & mother = *pmother;
6245 AliTPCseed & daughter = *pdaughter;
6246 AliKink & kinkl = *pkink;
6247 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
6248 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
6249 MarkSeedFree( pmother );
6250 MarkSeedFree( pdaughter );
6252 continue; //too short tracks
6254 if (mother.Pt()<1.4) {
6255 MarkSeedFree( pmother );
6256 MarkSeedFree( pdaughter );
6260 Int_t row0= kinkl.GetTPCRow0();
6261 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
6262 MarkSeedFree( pmother );
6263 MarkSeedFree( pdaughter );
6268 Int_t index = esd->AddKink(&kinkl);
6269 mother.SetKinkIndex(0,-(index+1));
6270 daughter.SetKinkIndex(0,index+1);
6271 if (mother.GetNumberOfClusters()>50) {
6272 MarkSeedFree( array->RemoveAt(i) );
6273 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6274 mtc->SetPoolID(fLastSeedID);
6275 array->AddAt(mtc,i);
6278 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6279 mtc->SetPoolID(fLastSeedID);
6280 array->AddLast(mtc);
6282 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
6283 dtc->SetPoolID(fLastSeedID);
6284 array->AddLast(dtc);
6285 for (Int_t icl=0;icl<row0;icl++) {
6286 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
6289 for (Int_t icl=row0;icl<158;icl++) {
6290 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
6294 MarkSeedFree( pmother );
6295 MarkSeedFree( pdaughter );
6299 delete [] daughters;
6321 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
6326 Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
6329 // refit kink towards to the vertex
6332 AliKink &kink=(AliKink &)knk;
6334 Int_t row0 = GetRowNumber(kink.GetR());
6335 FollowProlongation(mother,0);
6336 mother.Reset(kFALSE);
6338 FollowProlongation(daughter,row0);
6339 daughter.Reset(kFALSE);
6340 FollowBackProlongation(daughter,158);
6341 daughter.Reset(kFALSE);
6342 Int_t first = TMath::Max(row0-20,30);
6343 Int_t last = TMath::Min(row0+20,140);
6345 const Int_t kNdiv =5;
6346 AliTPCseed param0[kNdiv]; // parameters along the track
6347 AliTPCseed param1[kNdiv]; // parameters along the track
6348 AliKink kinks[kNdiv]; // corresponding kink parameters
6351 for (Int_t irow=0; irow<kNdiv;irow++){
6352 rows[irow] = first +((last-first)*irow)/(kNdiv-1);
6354 // store parameters along the track
6356 for (Int_t irow=0;irow<kNdiv;irow++){
6357 FollowBackProlongation(mother, rows[irow]);
6358 FollowProlongation(daughter,rows[kNdiv-1-irow]);
6359 param0[irow] = mother;
6360 param1[kNdiv-1-irow] = daughter;
6364 for (Int_t irow=0; irow<kNdiv-1;irow++){
6365 if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
6366 kinks[irow].SetMother(param0[irow]);
6367 kinks[irow].SetDaughter(param1[irow]);
6368 kinks[irow].Update();
6371 // choose kink with best "quality"
6373 Double_t mindist = 10000;
6374 for (Int_t irow=0;irow<kNdiv;irow++){
6375 if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
6376 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
6377 if (TMath::Abs(kinks[irow].GetR())<100.) continue;
6379 Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
6380 normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
6381 if (normdist < mindist){
6387 if (index==-1) return 0;
6390 param0[index].Reset(kTRUE);
6391 FollowProlongation(param0[index],0);
6393 mother = param0[index];
6394 daughter = param1[index]; // daughter in vertex
6396 kink.SetMother(mother);
6397 kink.SetDaughter(daughter);
6399 kink.SetTPCRow0(GetRowNumber(kink.GetR()));
6400 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
6401 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
6402 kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
6403 kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
6404 mother.SetLabel(kink.GetLabel(0));
6405 daughter.SetLabel(kink.GetLabel(1));
6411 void AliTPCtrackerMI::UpdateKinkQualityM(AliTPCseed * seed){
6413 // update Kink quality information for mother after back propagation
6415 if (seed->GetKinkIndex(0)>=0) return;
6416 for (Int_t ikink=0;ikink<3;ikink++){
6417 Int_t index = seed->GetKinkIndex(ikink);
6418 if (index>=0) break;
6419 index = TMath::Abs(index)-1;
6420 AliESDkink * kink = fEvent->GetKink(index);
6421 kink->SetTPCDensity(-1,0,0);
6422 kink->SetTPCDensity(1,0,1);
6424 Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6425 if (row0<15) row0=15;
6427 Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6428 if (row1>145) row1=145;
6430 Int_t found,foundable,shared;
6431 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
6432 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,0);
6433 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
6434 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,1);
6439 void AliTPCtrackerMI::UpdateKinkQualityD(AliTPCseed * seed){
6441 // update Kink quality information for daughter after refit
6443 if (seed->GetKinkIndex(0)<=0) return;
6444 for (Int_t ikink=0;ikink<3;ikink++){
6445 Int_t index = seed->GetKinkIndex(ikink);
6446 if (index<=0) break;
6447 index = TMath::Abs(index)-1;
6448 AliESDkink * kink = fEvent->GetKink(index);
6449 kink->SetTPCDensity(-1,1,0);
6450 kink->SetTPCDensity(-1,1,1);
6452 Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6453 if (row0<15) row0=15;
6455 Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6456 if (row1>145) row1=145;
6458 Int_t found,foundable,shared;
6459 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
6460 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,0);
6461 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
6462 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,1);
6468 Int_t AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
6471 // check kink point for given track
6472 // if return value=0 kink point not found
6473 // otherwise seed0 correspond to mother particle
6474 // seed1 correspond to daughter particle
6475 // kink parameter of kink point
6476 AliKink &kink=(AliKink &)knk;
6478 Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
6479 Int_t first = seed->GetFirstPoint();
6480 Int_t last = seed->GetLastPoint();
6481 if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
6484 AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
6485 if (!seed1) return 0;
6486 FollowProlongation(*seed1,seed->GetLastPoint()-20);
6487 seed1->Reset(kTRUE);
6488 FollowProlongation(*seed1,158);
6489 seed1->Reset(kTRUE);
6490 last = seed1->GetLastPoint();
6492 AliTPCseed *seed0 = new( NextFreeSeed() ) AliTPCseed(*seed);
6493 seed0->SetPoolID(fLastSeedID);
6494 seed0->Reset(kFALSE);
6497 AliTPCseed param0[20]; // parameters along the track
6498 AliTPCseed param1[20]; // parameters along the track
6499 AliKink kinks[20]; // corresponding kink parameters
6501 for (Int_t irow=0; irow<20;irow++){
6502 rows[irow] = first +((last-first)*irow)/19;
6504 // store parameters along the track
6506 for (Int_t irow=0;irow<20;irow++){
6507 FollowBackProlongation(*seed0, rows[irow]);
6508 FollowProlongation(*seed1,rows[19-irow]);
6509 param0[irow] = *seed0;
6510 param1[19-irow] = *seed1;
6514 for (Int_t irow=0; irow<19;irow++){
6515 kinks[irow].SetMother(param0[irow]);
6516 kinks[irow].SetDaughter(param1[irow]);
6517 kinks[irow].Update();
6520 // choose kink with biggest change of angle
6522 Double_t maxchange= 0;
6523 for (Int_t irow=1;irow<19;irow++){
6524 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
6525 if (TMath::Abs(kinks[irow].GetR())<110.) continue;
6526 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
6527 if ( quality > maxchange){
6528 maxchange = quality;
6533 MarkSeedFree( seed0 );
6534 MarkSeedFree( seed1 );
6535 if (index<0) return 0;
6537 Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
6538 seed0 = new( NextFreeSeed() ) AliTPCseed(param0[index]);
6539 seed0->SetPoolID(fLastSeedID);
6540 seed1 = new( NextFreeSeed() ) AliTPCseed(param1[index]);
6541 seed1->SetPoolID(fLastSeedID);
6542 seed0->Reset(kFALSE);
6543 seed1->Reset(kFALSE);
6544 seed0->ResetCovariance(10.);
6545 seed1->ResetCovariance(10.);
6546 FollowProlongation(*seed0,0);
6547 FollowBackProlongation(*seed1,158);
6548 mother = *seed0; // backup mother at position 0
6549 seed0->Reset(kFALSE);
6550 seed1->Reset(kFALSE);
6551 seed0->ResetCovariance(10.);
6552 seed1->ResetCovariance(10.);
6554 first = TMath::Max(row0-20,0);
6555 last = TMath::Min(row0+20,158);
6557 for (Int_t irow=0; irow<20;irow++){
6558 rows[irow] = first +((last-first)*irow)/19;
6560 // store parameters along the track
6562 for (Int_t irow=0;irow<20;irow++){
6563 FollowBackProlongation(*seed0, rows[irow]);
6564 FollowProlongation(*seed1,rows[19-irow]);
6565 param0[irow] = *seed0;
6566 param1[19-irow] = *seed1;
6570 for (Int_t irow=0; irow<19;irow++){
6571 kinks[irow].SetMother(param0[irow]);
6572 kinks[irow].SetDaughter(param1[irow]);
6573 // param0[irow].Dump();
6574 //param1[irow].Dump();
6575 kinks[irow].Update();
6578 // choose kink with biggest change of angle
6581 for (Int_t irow=0;irow<20;irow++){
6582 if (TMath::Abs(kinks[irow].GetR())>250.) continue;
6583 if (TMath::Abs(kinks[irow].GetR())<90.) continue;
6584 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
6585 if ( quality > maxchange){
6586 maxchange = quality;
6593 if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
6594 MarkSeedFree( seed0 );
6595 MarkSeedFree( seed1 );
6599 // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
6601 kink.SetMother(param0[index]);
6602 kink.SetDaughter(param1[index]);
6605 Double_t chi2P2 = param0[index].GetParameter()[2]-param1[index].GetParameter()[2];
6607 chi2P2/=param0[index].GetCovariance()[5]+param1[index].GetCovariance()[5];
6608 Double_t chi2P3 = param0[index].GetParameter()[3]-param1[index].GetParameter()[3];
6610 chi2P3/=param0[index].GetCovariance()[9]+param1[index].GetCovariance()[9];
6612 if (AliTPCReconstructor::StreamLevel()>1) {
6613 (*fDebugStreamer)<<"kinkHpt"<<
6616 "p0.="<<¶m0[index]<<
6617 "p1.="<<¶m1[index]<<
6621 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
6622 MarkSeedFree( seed0 );
6623 MarkSeedFree( seed1 );
6628 row0 = GetRowNumber(kink.GetR());
6629 kink.SetTPCRow0(row0);
6630 kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
6631 kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
6632 kink.SetIndex(-10,0);
6633 kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
6634 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
6635 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
6638 // new (&mother) AliTPCseed(param0[index]);
6639 daughter = param1[index];
6640 daughter.SetLabel(kink.GetLabel(1));
6641 param0[index].Reset(kTRUE);
6642 FollowProlongation(param0[index],0);
6643 mother = param0[index];
6644 mother.SetLabel(kink.GetLabel(0));
6645 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(1)){
6648 MarkSeedFree( seed0 );
6649 MarkSeedFree( seed1 );
6657 AliTPCseed* AliTPCtrackerMI::ReSeed(AliTPCseed *t)
6660 // reseed - refit - track
6663 // Int_t last = fSectors->GetNRows()-1;
6665 if (fSectors == fOuterSec){
6666 first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
6670 first = t->GetFirstPoint();
6672 AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
6673 FollowBackProlongation(*t,fSectors->GetNRows()-1);
6675 FollowProlongation(*t,first);
6685 //_____________________________________________________________________________
6686 Int_t AliTPCtrackerMI::ReadSeeds(const TFile *inp) {
6687 //-----------------------------------------------------------------
6688 // This function reades track seeds.
6689 //-----------------------------------------------------------------
6690 TDirectory *savedir=gDirectory;
6692 TFile *in=(TFile*)inp;
6693 if (!in->IsOpen()) {
6694 cerr<<"AliTPCtrackerMI::ReadSeeds(): input file is not open !\n";
6699 TTree *seedTree=(TTree*)in->Get("Seeds");
6701 cerr<<"AliTPCtrackerMI::ReadSeeds(): ";
6702 cerr<<"can't get a tree with track seeds !\n";
6705 AliTPCtrack *seed=new AliTPCtrack;
6706 seedTree->SetBranchAddress("tracks",&seed);
6708 if (fSeeds==0) fSeeds=new TObjArray(15000);
6710 Int_t n=(Int_t)seedTree->GetEntries();
6711 for (Int_t i=0; i<n; i++) {
6712 seedTree->GetEvent(i);
6713 AliTPCseed* sdc = new( NextFreeSeed() ) AliTPCseed(*seed/*,seed->GetAlpha()*/);
6714 sdc->SetPoolID(fLastSeedID);
6715 fSeeds->AddLast(sdc);
6718 delete seed; // RS: this seed is not from the pool, delete it !!!
6724 Int_t AliTPCtrackerMI::Clusters2TracksHLT (AliESDEvent *const esd, const AliESDEvent *hltEvent)
6727 // clusters to tracks
6728 if (fSeeds) DeleteSeeds();
6729 else ResetSeedsPool();
6731 fEventHLT = hltEvent;
6733 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
6734 transform->SetCurrentTimeStamp( esd->GetTimeStamp());
6735 transform->SetCurrentRun(esd->GetRunNumber());
6739 if (!fSeeds) return 1;
6741 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(0,fSeeds);
6746 Int_t AliTPCtrackerMI::Clusters2Tracks(AliESDEvent *const esd)
6749 // clusters to tracks
6750 return Clusters2TracksHLT( esd, 0);
6753 //_____________________________________________________________________________
6754 Int_t AliTPCtrackerMI::Clusters2Tracks() {
6755 //-----------------------------------------------------------------
6756 // This is a track finder.
6757 //-----------------------------------------------------------------
6758 TDirectory *savedir=gDirectory;
6762 fSeeds = Tracking();
6765 Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
6767 //activate again some tracks
6768 for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
6769 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6771 Int_t nc=t.GetNumberOfClusters();
6773 MarkSeedFree( fSeeds->RemoveAt(i) );
6777 if (pt->GetRemoval()==10) {
6778 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
6779 pt->Desactivate(10); // make track again active // MvL: should be 0 ?
6781 pt->Desactivate(20);
6782 MarkSeedFree( fSeeds->RemoveAt(i) );
6787 RemoveUsed2(fSeeds,0.85,0.85,0);
6788 if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
6789 //FindCurling(fSeeds, fEvent,0);
6790 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,-1); // find multi found tracks
6791 RemoveUsed2(fSeeds,0.5,0.4,20);
6792 FindSplitted(fSeeds, fEvent,0); // find multi found tracks
6793 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
6796 // // refit short tracks
6798 Int_t nseed=fSeeds->GetEntriesFast();
6801 for (Int_t i=0; i<nseed; i++) {
6802 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6804 Int_t nc=t.GetNumberOfClusters();
6806 MarkSeedFree( fSeeds->RemoveAt(i) );
6809 CookLabel(pt,0.1); //For comparison only
6810 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6811 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6813 if (fDebug>0) cerr<<found<<'\r';
6817 MarkSeedFree( fSeeds->RemoveAt(i) );
6821 //RemoveOverlap(fSeeds,0.99,7,kTRUE);
6823 //RemoveUsed(fSeeds,0.9,0.9,6);
6825 nseed=fSeeds->GetEntriesFast();
6827 for (Int_t i=0; i<nseed; i++) {
6828 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6830 Int_t nc=t.GetNumberOfClusters();
6832 MarkSeedFree( fSeeds->RemoveAt(i) );
6836 t.CookdEdx(0.02,0.6);
6837 // CheckKinkPoint(&t,0.05);
6838 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6839 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6847 MarkSeedFree( fSeeds->RemoveAt(i) );
6848 //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
6850 // FollowProlongation(*seed1,0);
6851 // Int_t n = seed1->GetNumberOfClusters();
6852 // printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
6853 // printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
6856 //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
6860 SortTracks(fSeeds, 1);
6864 PrepareForBackProlongation(fSeeds,5.);
6865 PropagateBack(fSeeds);
6866 printf("Time for back propagation: \t");timer.Print();timer.Start();
6870 PrepareForProlongation(fSeeds,5.);
6871 PropagateForard2(fSeeds);
6873 printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
6874 // RemoveUsed(fSeeds,0.7,0.7,6);
6875 //RemoveOverlap(fSeeds,0.9,7,kTRUE);
6877 nseed=fSeeds->GetEntriesFast();
6879 for (Int_t i=0; i<nseed; i++) {
6880 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6882 Int_t nc=t.GetNumberOfClusters();
6884 MarkSeedFree( fSeeds->RemoveAt(i) );
6887 t.CookdEdx(0.02,0.6);
6888 // CookLabel(pt,0.1); //For comparison only
6889 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6890 if ((pt->IsActive() || (pt->fRemoval==10) )){
6891 cerr<<found++<<'\r';
6894 MarkSeedFree( fSeeds->RemoveAt(i) );
6899 // fNTracks = found;
6901 Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
6904 // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
6905 Info("Clusters2Tracks","Number of found tracks %d",found);
6907 // UnloadClusters();
6912 void AliTPCtrackerMI::Tracking(TObjArray * arr)
6915 // tracking of the seeds
6918 fSectors = fOuterSec;
6919 ParallelTracking(arr,150,63);
6920 fSectors = fOuterSec;
6921 ParallelTracking(arr,63,0);
6924 TObjArray * AliTPCtrackerMI::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
6929 static TObjArray arrTracks;
6930 TObjArray * arr = &arrTracks;
6932 fSectors = fOuterSec;
6935 for (Int_t sec=0;sec<fkNOS;sec++){
6936 if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
6937 if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);
6938 if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
6941 Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
6953 TObjArray * AliTPCtrackerMI::Tracking()
6957 if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
6960 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
6962 TObjArray * seeds = new TObjArray;
6964 Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
6965 Int_t gapPrim = AliTPCReconstructor::GetRecoParam()->GetSeedGapPrim();
6966 Int_t gapSec = AliTPCReconstructor::GetRecoParam()->GetSeedGapSec();
6974 Float_t fnumber = 3.0;
6975 Float_t fdensity = 3.0;
6978 if (AliTPCReconstructor::GetRecoParam()->GetUseHLTPreSeeding()) {
6979 arr = MakeSeedsHLT( fEventHLT );
6981 SumTracks(seeds,arr);
6984 //cout<<"HLT tracks left after sorting: "<<seeds->GetEntriesFast()<<endl;
6985 //SignClusters(seeds,fnumber,fdensity);
6992 for (Int_t delta = 0; delta<18; delta+=gapPrim){
6996 arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
6997 SumTracks(seeds,arr);
6998 SignClusters(seeds,fnumber,fdensity);
7000 for (Int_t i=2;i<6;i+=2){
7001 // seed high pt tracks
7004 arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
7005 SumTracks(seeds,arr);
7006 SignClusters(seeds,fnumber,fdensity);
7011 // RemoveUsed(seeds,0.9,0.9,1);
7012 // UnsignClusters();
7013 // SignClusters(seeds,fnumber,fdensity);
7017 for (Int_t delta = 20; delta<120; delta+=gapPrim){
7019 // seed high pt tracks
7023 arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
7024 SumTracks(seeds,arr);
7025 SignClusters(seeds,fnumber,fdensity);
7030 arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
7031 SumTracks(seeds,arr);
7032 SignClusters(seeds,fnumber,fdensity);
7043 Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
7047 // RemoveUsed(seeds,0.75,0.75,1);
7049 //SignClusters(seeds,fnumber,fdensity);
7058 arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
7059 SumTracks(seeds,arr);
7060 SignClusters(seeds,fnumber,fdensity);
7062 arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
7063 SumTracks(seeds,arr);
7064 SignClusters(seeds,fnumber,fdensity);
7066 arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
7067 SumTracks(seeds,arr);
7068 SignClusters(seeds,fnumber,fdensity);
7070 arr = Tracking(4,nup-5,nup-5-gap,cuts,-1);
7071 SumTracks(seeds,arr);
7072 SignClusters(seeds,fnumber,fdensity);
7074 arr = Tracking(4,nup-7,nup-7-gap,cuts,-1);
7075 SumTracks(seeds,arr);
7076 SignClusters(seeds,fnumber,fdensity);
7079 arr = Tracking(4,nup-9,nup-9-gap,cuts,-1);
7080 SumTracks(seeds,arr);
7081 SignClusters(seeds,fnumber,fdensity);
7085 for (Int_t delta = 9; delta<30; delta+=gapSec){
7091 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7092 SumTracks(seeds,arr);
7093 SignClusters(seeds,fnumber,fdensity);
7095 arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
7096 SumTracks(seeds,arr);
7097 SignClusters(seeds,fnumber,fdensity);
7110 for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=gapSec){
7116 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7117 SumTracks(seeds,arr);
7118 SignClusters(seeds,fnumber,fdensity);
7120 arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
7121 SumTracks(seeds,arr);
7122 SignClusters(seeds,fnumber,fdensity);
7126 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
7137 TObjArray * AliTPCtrackerMI::TrackingSpecial()
7140 // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
7141 // no primary vertex seeding tried
7145 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7147 TObjArray * seeds = new TObjArray;
7152 Float_t fnumber = 3.0;
7153 Float_t fdensity = 3.0;
7156 cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC(); // max curvature
7157 cuts[1] = 3.5; // max tan(phi) angle for seeding
7158 cuts[2] = 3.; // not used (cut on z primary vertex)
7159 cuts[3] = 3.5; // max tan(theta) angle for seeding
7161 for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
7163 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7164 SumTracks(seeds,arr);
7165 SignClusters(seeds,fnumber,fdensity);
7169 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
7180 void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *&arr2)
7183 //sum tracks to common container
7184 //remove suspicious tracks
7185 // RS: Attention: supplied tracks come in the static array, don't delete them
7186 Int_t nseed = arr2->GetEntriesFast();
7187 for (Int_t i=0;i<nseed;i++){
7188 AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);
7191 // remove tracks with too big curvature
7193 if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
7194 MarkSeedFree( arr2->RemoveAt(i) );
7197 // REMOVE VERY SHORT TRACKS
7198 if (pt->GetNumberOfClusters()<20){
7199 MarkSeedFree( arr2->RemoveAt(i) );
7202 // NORMAL ACTIVE TRACK
7203 if (pt->IsActive()){
7204 arr1->AddLast(arr2->RemoveAt(i));
7207 //remove not usable tracks
7208 if (pt->GetRemoval()!=10){
7209 MarkSeedFree( arr2->RemoveAt(i) );
7213 // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
7214 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
7215 arr1->AddLast(arr2->RemoveAt(i));
7217 MarkSeedFree( arr2->RemoveAt(i) );
7221 // delete arr2; arr2 = 0; // RS: this is static array, don't delete it
7226 void AliTPCtrackerMI::ParallelTracking(TObjArray *const arr, Int_t rfirst, Int_t rlast)
7229 // try to track in parralel
7231 Int_t nseed=arr->GetEntriesFast();
7232 //prepare seeds for tracking
7233 for (Int_t i=0; i<nseed; i++) {
7234 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
7236 if (!t.IsActive()) continue;
7237 // follow prolongation to the first layer
7238 if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fkParam->GetNRowLow()>rfirst+1) )
7239 FollowProlongation(t, rfirst+1);
7244 for (Int_t nr=rfirst; nr>=rlast; nr--){
7245 if (nr<fInnerSec->GetNRows())
7246 fSectors = fInnerSec;
7248 fSectors = fOuterSec;
7249 // make indexes with the cluster tracks for given
7251 // find nearest cluster
7252 for (Int_t i=0; i<nseed; i++) {
7253 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
7255 if (nr==80) pt->UpdateReference();
7256 if (!pt->IsActive()) continue;
7257 // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
7258 if (pt->GetRelativeSector()>17) {
7261 UpdateClusters(t,nr);
7263 // prolonagate to the nearest cluster - if founded
7264 for (Int_t i=0; i<nseed; i++) {
7265 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
7267 if (!pt->IsActive()) continue;
7268 // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
7269 if (pt->GetRelativeSector()>17) {
7272 FollowToNextCluster(*pt,nr);
7277 void AliTPCtrackerMI::PrepareForBackProlongation(const TObjArray *const arr,Float_t fac) const
7281 // if we use TPC track itself we have to "update" covariance
7283 Int_t nseed= arr->GetEntriesFast();
7284 for (Int_t i=0;i<nseed;i++){
7285 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7289 //rotate to current local system at first accepted point
7290 Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
7291 Int_t sec = (index&0xff000000)>>24;
7293 Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
7294 if (angle1>TMath::Pi())
7295 angle1-=2.*TMath::Pi();
7296 Float_t angle2 = pt->GetAlpha();
7298 if (TMath::Abs(angle1-angle2)>0.001){
7299 if (!pt->Rotate(angle1-angle2)) return;
7300 //angle2 = pt->GetAlpha();
7301 //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
7302 //if (pt->GetAlpha()<0)
7303 // pt->fRelativeSector+=18;
7304 //sec = pt->fRelativeSector;
7313 void AliTPCtrackerMI::PrepareForProlongation(TObjArray *const arr, Float_t fac) const
7317 // if we use TPC track itself we have to "update" covariance
7319 Int_t nseed= arr->GetEntriesFast();
7320 for (Int_t i=0;i<nseed;i++){
7321 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7324 pt->SetFirstPoint(pt->GetLastPoint());
7332 Int_t AliTPCtrackerMI::PropagateBack(const TObjArray *const arr)
7335 // make back propagation
7337 Int_t nseed= arr->GetEntriesFast();
7338 for (Int_t i=0;i<nseed;i++){
7339 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7340 if (pt&& pt->GetKinkIndex(0)<=0) {
7341 //AliTPCseed *pt2 = new AliTPCseed(*pt);
7342 fSectors = fInnerSec;
7343 //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
7344 //fSectors = fOuterSec;
7345 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
7346 //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
7347 // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
7348 // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
7351 if (pt&& pt->GetKinkIndex(0)>0) {
7352 AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
7353 pt->SetFirstPoint(kink->GetTPCRow0());
7354 fSectors = fInnerSec;
7355 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
7363 Int_t AliTPCtrackerMI::PropagateForward2(const TObjArray *const arr)
7366 // make forward propagation
7368 Int_t nseed= arr->GetEntriesFast();
7370 for (Int_t i=0;i<nseed;i++){
7371 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7373 FollowProlongation(*pt,0,1,1);
7382 Int_t AliTPCtrackerMI::PropagateForward()
7385 // propagate track forward
7387 Int_t nseed = fSeeds->GetEntriesFast();
7388 for (Int_t i=0;i<nseed;i++){
7389 AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
7391 AliTPCseed &t = *pt;
7392 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
7393 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
7394 if (alpha < 0. ) alpha += 2.*TMath::Pi();
7395 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
7399 fSectors = fOuterSec;
7400 ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
7401 fSectors = fInnerSec;
7402 ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
7411 Int_t AliTPCtrackerMI::PropagateBack(AliTPCseed *const pt, Int_t row0, Int_t row1)
7414 // make back propagation, in between row0 and row1
7418 fSectors = fInnerSec;
7421 if (row1<fSectors->GetNRows())
7424 r1 = fSectors->GetNRows()-1;
7426 if (row0<fSectors->GetNRows()&& r1>0 )
7427 FollowBackProlongation(*pt,r1);
7428 if (row1<=fSectors->GetNRows())
7431 r1 = row1 - fSectors->GetNRows();
7432 if (r1<=0) return 0;
7433 if (r1>=fOuterSec->GetNRows()) return 0;
7434 fSectors = fOuterSec;
7435 return FollowBackProlongation(*pt,r1);
7443 void AliTPCtrackerMI::GetShape(AliTPCseed * seed, Int_t row)
7445 // gets cluster shape
7447 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
7448 Float_t zdrift = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())));
7449 Int_t type = (seed->GetSector() < fkParam->GetNSector()/2) ? 0: (row>126) ? 1:2;
7450 Double_t angulary = seed->GetSnp();
7452 if (TMath::Abs(angulary)>AliTPCReconstructor::GetMaxSnpTracker()) {
7453 angulary = TMath::Sign(AliTPCReconstructor::GetMaxSnpTracker(),angulary);
7456 angulary = angulary*angulary/((1.-angulary)*(1.+angulary));
7457 Double_t angularz = seed->GetTgl()*seed->GetTgl()*(1.+angulary);
7459 Double_t sigmay = clparam->GetRMS0(0,type,zdrift,TMath::Sqrt(TMath::Abs(angulary)));
7460 Double_t sigmaz = clparam->GetRMS0(1,type,zdrift,TMath::Sqrt(TMath::Abs(angularz)));
7461 seed->SetCurrentSigmaY2(sigmay*sigmay);
7462 seed->SetCurrentSigmaZ2(sigmaz*sigmaz);
7463 // Float_t sd2 = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fkParam->GetDiffL()*fkParam->GetDiffL();
7464 // // Float_t padlength = fkParam->GetPadPitchLength(seed->fSector);
7465 // Float_t padlength = GetPadPitchLength(row);
7467 // Float_t sresy = (seed->GetSector() < fkParam->GetNSector()/2) ? 0.2 :0.3;
7468 // seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
7470 // Float_t sresz = fkParam->GetZSigma();
7471 // seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
7473 Float_t wy = GetSigmaY(seed);
7474 Float_t wz = GetSigmaZ(seed);
7477 if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
7478 printf("problem\n");
7485 //__________________________________________________________________________
7486 void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
7487 //--------------------------------------------------------------------
7488 //This function "cooks" a track label. If label<0, this track is fake.
7489 //--------------------------------------------------------------------
7490 AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
7492 printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
7496 Int_t noc=t->GetNumberOfClusters();
7498 //printf("\nnot founded prolongation\n\n\n");
7504 AliTPCclusterMI *clusters[160];
7506 for (Int_t i=0;i<160;i++) {
7513 for (i=0; i<160 && current<noc; i++) {
7515 Int_t index=t->GetClusterIndex2(i);
7516 if (index<=0) continue;
7517 if (index&0x8000) continue;
7519 //clusters[current]=GetClusterMI(index);
7520 if (t->GetClusterPointer(i)){
7521 clusters[current]=t->GetClusterPointer(i);
7527 Int_t lab=123456789;
7528 for (i=0; i<noc; i++) {
7529 AliTPCclusterMI *c=clusters[i];
7531 lab=TMath::Abs(c->GetLabel(0));
7533 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
7539 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
7541 for (i=0; i<noc; i++) {
7542 AliTPCclusterMI *c=clusters[i];
7544 if (TMath::Abs(c->GetLabel(1)) == lab ||
7545 TMath::Abs(c->GetLabel(2)) == lab ) max++;
7547 if (noc<=0) { lab=-1; return;}
7548 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
7551 Int_t tail=Int_t(0.10*noc);
7554 for (i=1; i<160&&ind<tail; i++) {
7555 // AliTPCclusterMI *c=clusters[noc-i];
7556 AliTPCclusterMI *c=clusters[i];
7558 if (lab == TMath::Abs(c->GetLabel(0)) ||
7559 lab == TMath::Abs(c->GetLabel(1)) ||
7560 lab == TMath::Abs(c->GetLabel(2))) max++;
7563 if (max < Int_t(0.5*tail)) lab=-lab;
7570 //delete[] clusters;
7574 //__________________________________________________________________________
7575 Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *const t, Float_t wrong,Int_t first, Int_t last) const {
7576 //--------------------------------------------------------------------
7577 //This function "cooks" a track label. If label<0, this track is fake.
7578 //--------------------------------------------------------------------
7579 Int_t noc=t->GetNumberOfClusters();
7581 //printf("\nnot founded prolongation\n\n\n");
7587 AliTPCclusterMI *clusters[160];
7589 for (Int_t i=0;i<160;i++) {
7596 for (i=0; i<160 && current<noc; i++) {
7597 if (i<first) continue;
7598 if (i>last) continue;
7599 Int_t index=t->GetClusterIndex2(i);
7600 if (index<=0) continue;
7601 if (index&0x8000) continue;
7603 //clusters[current]=GetClusterMI(index);
7604 if (t->GetClusterPointer(i)){
7605 clusters[current]=t->GetClusterPointer(i);
7610 //if (noc<5) return -1;
7611 Int_t lab=123456789;
7612 for (i=0; i<noc; i++) {
7613 AliTPCclusterMI *c=clusters[i];
7615 lab=TMath::Abs(c->GetLabel(0));
7617 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
7623 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
7625 for (i=0; i<noc; i++) {
7626 AliTPCclusterMI *c=clusters[i];
7628 if (TMath::Abs(c->GetLabel(1)) == lab ||
7629 TMath::Abs(c->GetLabel(2)) == lab ) max++;
7631 if (noc<=0) { lab=-1; return -1;}
7632 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
7635 Int_t tail=Int_t(0.10*noc);
7638 for (i=1; i<160&&ind<tail; i++) {
7639 // AliTPCclusterMI *c=clusters[noc-i];
7640 AliTPCclusterMI *c=clusters[i];
7642 if (lab == TMath::Abs(c->GetLabel(0)) ||
7643 lab == TMath::Abs(c->GetLabel(1)) ||
7644 lab == TMath::Abs(c->GetLabel(2))) max++;
7647 if (max < Int_t(0.5*tail)) lab=-lab;
7650 // t->SetLabel(lab);
7654 //delete[] clusters;
7658 Int_t AliTPCtrackerMI::GetRowNumber(Double_t x[3]) const
7660 //return pad row number for given x vector
7661 Float_t phi = TMath::ATan2(x[1],x[0]);
7662 if(phi<0) phi=2.*TMath::Pi()+phi;
7663 // Get the local angle in the sector philoc
7664 const Float_t kRaddeg = 180/3.14159265358979312;
7665 Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
7666 Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
7667 return GetRowNumber(localx);
7672 void AliTPCtrackerMI::MakeESDBitmaps(AliTPCseed *t, AliESDtrack *esd)
7674 //-----------------------------------------------------------------------
7675 // Fill the cluster and sharing bitmaps of the track
7676 //-----------------------------------------------------------------------
7678 Int_t firstpoint = 0;
7679 Int_t lastpoint = 159;
7680 AliTPCTrackerPoint *point;
7681 AliTPCclusterMI *cluster;
7684 TBits clusterMap(159);
7685 TBits sharedMap(159);
7687 for (int iter=firstpoint; iter<lastpoint; iter++) {
7688 // Change to cluster pointers to see if we have a cluster at given padrow
7690 cluster = t->GetClusterPointer(iter);
7692 clusterMap.SetBitNumber(iter, kTRUE);
7693 point = t->GetTrackPoint(iter);
7694 if (point->IsShared())
7695 sharedMap.SetBitNumber(iter,kTRUE);
7697 if (t->GetClusterIndex(iter) >= 0 && (t->GetClusterIndex(iter) & 0x8000) == 0) {
7698 fitMap.SetBitNumber(iter, kTRUE);
7702 esd->SetTPCClusterMap(clusterMap);
7703 esd->SetTPCSharedMap(sharedMap);
7704 esd->SetTPCFitMap(fitMap);
7705 if (nclsf != t->GetNumberOfClusters())
7706 AliDebug(3,Form("Inconsistency between ncls %d and indices %d (found %d)",t->GetNumberOfClusters(),nclsf,esd->GetTPCClusterMap().CountBits()));
7709 Bool_t AliTPCtrackerMI::IsFindable(AliTPCseed & track){
7711 // return flag if there is findable cluster at given position
7714 Float_t z = track.GetZ();
7716 if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*track.GetX()+kDeltaZ) &&
7717 TMath::Abs(z)<fkParam->GetZLength(0) &&
7718 (TMath::Abs(track.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
7724 void AliTPCtrackerMI::AddCovariance(AliTPCseed * seed){
7726 // Adding systematic error estimate to the covariance matrix
7727 // !!!! the systematic error for element 4 is in 1/GeV
7728 // 03.03.2012 MI changed in respect to the previous versions
7729 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
7731 // use only the diagonal part if not specified otherwise
7732 if (!AliTPCReconstructor::GetRecoParam()->GetUseSystematicCorrelation()) return AddCovarianceAdd(seed);
7734 Double_t *covarS= (Double_t*)seed->GetCovariance();
7735 Double_t factor[5]={1,1,1,1,1};
7736 factor[0]= TMath::Sqrt(TMath::Abs((covarS[0] + param[0]*param[0])/covarS[0]));
7737 factor[1]= TMath::Sqrt(TMath::Abs((covarS[2] + param[1]*param[1])/covarS[2]));
7738 factor[2]= TMath::Sqrt(TMath::Abs((covarS[5] + param[2]*param[2])/covarS[5]));
7739 factor[3]= TMath::Sqrt(TMath::Abs((covarS[9] + param[3]*param[3])/covarS[9]));
7740 factor[4]= TMath::Sqrt(TMath::Abs((covarS[14] +param[4]*param[4])/covarS[14]));
7742 factor[0]=factor[2];
7743 factor[4]=factor[2];
7749 for (Int_t i=0; i<5; i++){
7750 for (Int_t j=i; j<5; j++){
7751 Int_t index=seed->GetIndex(i,j);
7752 covarS[index]*=factor[i]*factor[j];
7758 void AliTPCtrackerMI::AddCovarianceAdd(AliTPCseed * seed){
7760 // Adding systematic error - as additive factor without correlation
7762 // !!!! the systematic error for element 4 is in 1/GeV
7763 // 03.03.2012 MI changed in respect to the previous versions
7765 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
7766 Double_t *covarIn= (Double_t*)seed->GetCovariance();
7768 for (Int_t i=0;i<15;i++) covar[i]=0;
7774 covar[0] = param[0]*param[0];
7775 covar[2] = param[1]*param[1];
7776 covar[5] = param[2]*param[2];
7777 covar[9] = param[3]*param[3];
7778 covar[14]= param[4]*param[4];
7780 covar[1]=TMath::Sqrt((covar[0]*covar[2]))*covarIn[1]/TMath::Sqrt((covarIn[0]*covarIn[2]));
7782 covar[3]=TMath::Sqrt((covar[0]*covar[5]))*covarIn[3]/TMath::Sqrt((covarIn[0]*covarIn[5]));
7783 covar[4]=TMath::Sqrt((covar[2]*covar[5]))*covarIn[4]/TMath::Sqrt((covarIn[2]*covarIn[5]));
7785 covar[6]=TMath::Sqrt((covar[0]*covar[9]))*covarIn[6]/TMath::Sqrt((covarIn[0]*covarIn[9]));
7786 covar[7]=TMath::Sqrt((covar[2]*covar[9]))*covarIn[7]/TMath::Sqrt((covarIn[2]*covarIn[9]));
7787 covar[8]=TMath::Sqrt((covar[5]*covar[9]))*covarIn[8]/TMath::Sqrt((covarIn[5]*covarIn[9]));
7789 covar[10]=TMath::Sqrt((covar[0]*covar[14]))*covarIn[10]/TMath::Sqrt((covarIn[0]*covarIn[14]));
7790 covar[11]=TMath::Sqrt((covar[2]*covar[14]))*covarIn[11]/TMath::Sqrt((covarIn[2]*covarIn[14]));
7791 covar[12]=TMath::Sqrt((covar[5]*covar[14]))*covarIn[12]/TMath::Sqrt((covarIn[5]*covarIn[14]));
7792 covar[13]=TMath::Sqrt((covar[9]*covar[14]))*covarIn[13]/TMath::Sqrt((covarIn[9]*covarIn[14]));
7794 seed->AddCovariance(covar);
7797 //_____________________________________________________________________________
7798 Bool_t AliTPCtrackerMI::IsTPCHVDipEvent(AliESDEvent const *esdEvent)
7801 // check events affected by TPC HV dip
7803 if(!esdEvent) return kFALSE;
7806 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
7807 if(!db) return kFALSE;
7808 db->SetRun(esdEvent->GetRunNumber());
7810 // maximum allowed voltage before an event is identified as a dip event
7811 // and scanning period
7812 const Double_t kTPCHVdip = db->GetParameters()->GetMaxDipVoltage();
7813 const Double_t dipEventScanPeriod = db->GetParameters()->GetVoltageDipScanPeriod();
7814 const Double_t tevSec = esdEvent->GetTimeStamp();
7816 for(Int_t sector=0; sector<72; sector++)
7818 // don't use excluded chambers, since the state is not defined at all
7819 if (!db->GetChamberHVStatus(sector)) continue;
7821 // get hv sensor of the chamber
7822 AliDCSSensor *sensor = db->GetChamberHVSensor(sector);
7823 if (!sensor) continue;
7824 TGraph *grSensor=sensor->GetGraph();
7825 if (!grSensor) continue;
7826 if (grSensor->GetN()<1) continue;
7829 const Double_t median = db->GetChamberHighVoltageMedian(sector);
7830 if(median < 1.) continue;
7832 for (Int_t ipoint=0; ipoint<grSensor->GetN()-1; ++ipoint){
7833 Double_t nextTime=grSensor->GetX()[ipoint+1]*3600+sensor->GetStartTime();
7834 if (tevSec-dipEventScanPeriod>nextTime) continue;
7835 const Float_t deltaV=TMath::Abs(grSensor->GetY()[ipoint]-median);
7836 if (deltaV>kTPCHVdip) {
7837 AliDebug(3,Form("HV dip detected in ROC '%02d' with dV '%.2f' at time stamp '%.0f'",sector,deltaV,tevSec));
7840 if (nextTime>tevSec+dipEventScanPeriod) break;
7847 //________________________________________
7848 void AliTPCtrackerMI::MarkSeedFree(TObject *sd)
7850 // account that this seed is "deleted"
7851 AliTPCseed* seed = dynamic_cast<AliTPCseed*>(sd);
7853 AliError(Form("Freeing of non-AliTPCseed %p from the pool is requested",sd));
7856 int id = seed->GetPoolID();
7858 AliError(Form("Freeing of seed %p NOT from the pool is requested",sd));
7861 // AliInfo(Form("%d %p",id, seed));
7862 fSeedsPool->RemoveAt(id);
7863 if (fFreeSeedsID.GetSize()<=fNFreeSeeds) fFreeSeedsID.Set( 2*fNFreeSeeds + 100 );
7864 fFreeSeedsID.GetArray()[fNFreeSeeds++] = id;
7867 //________________________________________
7868 TObject *&AliTPCtrackerMI::NextFreeSeed()
7870 // return next free slot where the seed can be created
7871 fLastSeedID = fNFreeSeeds ? fFreeSeedsID.GetArray()[--fNFreeSeeds] : fSeedsPool->GetEntriesFast();
7872 // AliInfo(Form("%d",fLastSeedID));
7873 return (*fSeedsPool)[ fLastSeedID ];
7877 //________________________________________
7878 void AliTPCtrackerMI::ResetSeedsPool()
7880 // mark all seeds in the pool as unused
7881 AliInfo(Form("CurrentSize: %d, BookedUpTo: %d, free: %d",fSeedsPool->GetSize(),fSeedsPool->GetEntriesFast(),fNFreeSeeds));
7883 fSeedsPool->Clear("C"); // RS: nominally the seeds may allocate memory...
7886 Int_t AliTPCtrackerMI::PropagateToRowHLT(AliTPCseed *pt, int nrow)
7889 Double_t x= GetXrow(nrow);
7890 Double_t ymax= GetMaxY(nrow);
7896 if (!t.PropagateTo(x) ){
7897 //cout<<"can't propagate to row "<<nrow<<", x="<<t.GetX()<<" -> "<<x<<endl;
7903 Double_t y = t.GetY();
7905 if( rotate!=-1 ) rotate=1;
7906 } else if (y <-ymax) {
7907 if( rotate!=1 ) rotate = -1;
7909 if( rotate==0 ) break;
7910 //cout<<"rotate at row "<<nrow<<": "<<rotate<<endl;
7911 if (!t.Rotate( rotate==1 ?fSectors->GetAlpha() :-fSectors->GetAlpha())) {
7912 //cout<<"can't rotate "<<endl;
7916 nRotations+= rotate;
7918 if( nRotations!=0 ){
7919 int newSec= t.GetRelativeSector()+nRotations;
7920 if( newSec>=fN ) newSec-=fN;
7921 else if( newSec<0 ) newSec +=fN;
7922 //cout<<"rotate at row "<<nrow<<": "<<nRotations<<" times "<<" sec "
7923 //<< t.GetRelativeSector()<<" -> "<<newSec<<endl;
7924 t.SetRelativeSector(newSec);
7929 void AliTPCtrackerMI::TrackFollowingHLT(TObjArray *const arr )
7932 // try to track in parralel
7934 Int_t nRows=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7937 Int_t nseed=arr->GetEntriesFast();
7938 //cout<<"Parallel tracking My.."<<endl;
7939 double shapeY2[160], shapeZ2[160];
7940 Int_t clusterIndex[160];
7942 for (Int_t iSeed=0; iSeed<nseed; iSeed++) {
7943 //if( iSeed!=1 ) continue;
7944 AliTPCseed *pt=(AliTPCseed*) (arr->UncheckedAt(iSeed));
7948 //cout <<"Pt "<<t.GetSigned1Pt()<<endl;
7952 for( int iter=0; iter<3; iter++ ){
7955 t.SetLastPoint(0); // first cluster in track position
7956 t.SetFirstPoint(nRows-1);
7957 t.ResetCovariance(.1);
7958 t.SetNumberOfClusters(0);
7959 for( int i=0; i<nRows; i++ ){
7963 t.SetClusterIndex2(i,-1);
7964 t.SetClusterIndex(i,-1);
7967 // pick up the clusters
7969 Double_t roady = 20.;
7970 Double_t roadz = 20.;
7977 t0.SetRelativeSector(t.GetRelativeSector());
7978 t0.SetLastPoint(0); // first cluster in track position
7979 t0.SetFirstPoint(159);
7980 for (Int_t nr=0; nr<nRows; nr++){
7981 if( nr<fInnerSec->GetNRows() ) fSectors=fInnerSec;
7982 else fSectors=fOuterSec;
7984 if( !PropagateToRowHLT(&t0, nr ) ){ break; }
7985 if (TMath::Abs(t0.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
7986 //cout<<"Snp is too big: "<<t0.GetSnp()<<endl;
7989 if (!IsActive(t0.GetRelativeSector(),nr)) {
7995 shapeY2[nr]=t0.GetCurrentSigmaY2();
7996 shapeZ2[nr]=t0.GetCurrentSigmaZ2();
7999 AliTPCtrackerRow &krow=GetRow(t0.GetRelativeSector(),nr);
8000 if( !krow ) continue;
8002 t.SetClusterIndex2(nr,-3); // foundable
8003 t.SetClusterIndex(nr,-3);
8005 AliTPCclusterMI *cl=0;
8007 cl = krow.FindNearest2(t0.GetY(),t0.GetZ(),roady,roadz,uindex);
8009 double dy = cl->GetY()-t0.GetY();
8010 double dz = cl->GetZ()-t0.GetZ();
8011 double dr = sqrt(dy*dy+dz*dz);
8013 //cout<<"row "<<nr<<", best cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8016 //cout<<"row "<<nr<<", found cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8018 t0.SetClusterPointer(nr, cl);
8019 clusterIndex[nr] = krow.GetIndex(uindex);
8020 if( t0.GetFirstPoint()>nr ) t0.SetFirstPoint(nr);
8021 t0.SetLastPoint(nr);
8027 //cout<<"NOT ENOUGTH CLUSTERS: "<<nClusters<<endl;
8030 Int_t basePoints[3] = {t0.GetFirstPoint(),t0.GetFirstPoint(),t0.GetLastPoint()};
8034 Int_t midRow = (t0.GetLastPoint()-t0.GetFirstPoint())/2;
8036 for( int nr=t0.GetFirstPoint()+1; nr< t0.GetLastPoint(); nr++){
8037 if( !t0.GetClusterPointer(nr) ) continue;
8038 int d = TMath::Abs(nr-midRow);
8046 // first fit 3 base points
8048 //cout<<"Fit3: "<<endl;
8049 for( int icl=0; icl<3; icl++){
8050 int nr = basePoints[icl];
8052 if( nr>=fInnerSec->GetNRows()){
8053 lr = nr - fInnerSec->GetNRows();
8055 } else fSectors=fInnerSec;
8057 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8059 //cout<<"WRONG!!!!"<<endl;
8062 int iSec = cl->GetDetector() %fkNIS;
8063 int rotate = iSec - t.GetRelativeSector();
8065 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8066 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8067 //cout<<"can't rotate "<<endl;
8070 t.SetRelativeSector(iSec);
8072 Double_t x= cl->GetX();
8073 if (!t.PropagateTo(x)){
8074 //cout<<"can't propagate to x="<<x<<endl;
8078 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8079 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8082 //cout<<"fit3 : row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8084 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8085 t.SetCurrentCluster(cl);
8088 t.SetErrorY2(shapeY2[nr]);
8089 t.SetErrorZ2(shapeZ2[nr]);
8092 for( int j=0; j<15; j++ ) cov[j]=0;
8098 t.AliExternalTrackParam::AddCovariance(cov);
8100 if( !UpdateTrack(&t,0) ){
8101 //cout<<"Can not update"<<endl;
8103 t.SetClusterIndex2(nr,-1);
8104 t.SetClusterIndex(nr,-1);
8105 t.SetClusterPointer(nr,0);
8108 //t.SetClusterPointer(nr, cl);
8111 //t.SetLastPoint(t0.GetLastPoint());
8112 //t.SetFirstPoint(t0.GetFirstPoint());
8114 //cout<<"Fit: "<<endl;
8115 for (Int_t nr=t0.GetLastPoint(); nr>=t0.GetFirstPoint(); nr-- ){
8117 if( nr>=fInnerSec->GetNRows()){
8118 lr = nr - fInnerSec->GetNRows();
8120 } else fSectors=fInnerSec;
8123 if( nr == basePoints[0] ) continue;
8124 if( nr == basePoints[1] ) continue;
8125 if( nr == basePoints[2] ) continue;
8127 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8130 int iSec = cl->GetDetector() %fkNIS;
8131 int rotate = iSec - t.GetRelativeSector();
8133 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8134 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8135 //cout<<"can't rotate "<<endl;
8138 t.SetRelativeSector(iSec);
8140 Double_t x= cl->GetX();
8141 if (!t.PropagateTo(x)){
8142 //cout<<"can't propagate to x="<<x<<endl;
8145 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8146 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8150 //cout<<"fit: row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8152 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8153 t.SetCurrentCluster(cl);
8155 t.SetErrorY2(shapeY2[nr]);
8156 t.SetErrorZ2(shapeZ2[nr]);
8158 if( !UpdateTrack(&t,0) ){
8159 //cout<<"Can not update"<<endl;
8161 t.SetClusterIndex2(nr,-1);
8162 t.SetClusterIndex(nr,-1);
8165 //t.SetClusterPointer(nr, cl);
8168 //cout<<"After iter "<<iter<<": N clusters="<<t.GetNumberOfClusters()<<" : "<<nClusters<<endl;
8171 //cout<<"fitted track"<<iSeed<<endl;
8173 //cout<<"Statistics: "<<endl;
8174 Int_t foundable,found,shared;
8175 t.GetClusterStatistic(0,nRows, found, foundable, shared, kTRUE);
8176 t.SetNFoundable(foundable);
8177 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8183 TObjArray * AliTPCtrackerMI::MakeSeedsHLT(const AliESDEvent *hltEvent)
8188 if( !hltEvent ) return 0;
8191 Int_t nentr=hltEvent->GetNumberOfTracks();
8193 AliInfo(Form("Using %d HLT tracks for seeding",nentr));
8195 TObjArray * seeds = new TObjArray(nentr);
8197 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8200 Int_t nTr=hltEvent->GetNumberOfTracks();
8202 for( int itr=0; itr<nTr; itr++ ){
8203 //if( itr!=97 ) continue;
8204 const AliExternalTrackParam *param = hltEvent->GetTrack(itr)->GetTPCInnerParam();
8205 if( !param ) continue;
8206 //if( TMath::Abs(esdTr->GetSigned1Pt())>1 ) continue;
8207 //if( TMath::Abs(esdTr->GetTgl())>1. ) continue;
8209 tr.Set(param->GetX(),param->GetAlpha(),param->GetParameter(),param->GetCovariance());
8210 tr.SetNumberOfClusters(0);
8211 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed(tr);
8213 Double_t alpha=seed->GetAlpha();// - fSectors->GetAlphaShift();
8214 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
8215 if (alpha < 0. ) alpha += 2.*TMath::Pi();
8217 seed->SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
8218 Double_t alphaSec = fSectors->GetAlpha() * seed->GetRelativeSector() + fSectors->GetAlphaShift();
8220 if (alphaSec >= TMath::Pi()) alphaSec -= 2.*TMath::Pi();
8221 if (alphaSec < -TMath::Pi()) alphaSec += 2.*TMath::Pi();
8223 seed->Rotate(alphaSec - alpha);
8225 seed->SetPoolID(fLastSeedID);
8226 seed->SetIsSeeding(kTRUE);
8227 seed->SetSeed1(nup-1);
8228 seed->SetSeed2(nup-2);
8229 seed->SetSeedType(0);
8230 seed->SetFirstPoint(-1);
8231 seed->SetLastPoint(-1);
8232 seeds->AddLast(seed); // note, track is seed, don't free the seed
8234 //if( index>3 ) break;
8238 fSectors = fOuterSec;
8240 TrackFollowingHLT(seeds );
8242 nTr = seeds->GetEntriesFast();
8243 for( int itr=0; itr<nTr; itr++ ){
8244 AliTPCseed * seed = (AliTPCseed*) seeds->UncheckedAt(itr);
8245 if( !seed ) continue;
8246 //FollowBackProlongation(*seed,0);
8247 // cout<<seed->GetNumberOfClusters()<<endl;
8248 Int_t foundable,found,shared;
8249 seed->GetClusterStatistic(0,nup, found, foundable, shared, kTRUE);
8250 seed->SetNFoundable(foundable);
8251 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8252 //if ((found<0.55*foundable) || shared>0.5*found ){// || (seed->GetSigmaY2()+seed->GetSigmaZ2())>0.5){
8253 //MarkSeedFree(seeds->RemoveAt(itr));
8256 if (seed->GetNumberOfClusters()<30 ||
8257 seed->GetNumberOfClusters() < seed->GetNFoundable()*0.6 ||
8258 seed->GetNShared()>0.4*seed->GetNumberOfClusters() ) {
8259 MarkSeedFree(seeds->RemoveAt(itr));
8263 for( int ir=0; ir<nup; ir++){
8264 AliTPCclusterMI *c = seed->GetClusterPointer(ir);
8268 std::cout<<"\n\nHLT tracks left: "<<seeds->GetEntries()<<" out of "<<hltEvent->GetNumberOfTracks()<<endl<<endl;