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 Kalman 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 - AliTPCtracker::FillESD
88 // 2. Second iteration -
89 // 2.a ITS->TPC - AliTPCtracker::ReadSeeds
90 // 2.b TPC->TRD - AliTPCtracker::PropagateBack
91 // 3. Third iteration -
92 // 3.a TRD->TPC - AliTPCtracker::ReadSeeds
93 // 3.b TPC->ITS - AliTPCtracker::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 "AliTPCtracker.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(AliTPCtracker)
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 AliTPCtracker::AliTPCtracker()
219 // default constructor
221 for (Int_t irow=0; irow<200; irow++){
228 //_____________________________________________________________________
232 Int_t AliTPCtracker::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 AliTPCtracker::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 AliTPCtracker::AliTPCtracker(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","recreate");
466 fSeedsPool = new TClonesArray("AliTPCseed",1000);
468 //________________________________________________________________________
469 AliTPCtracker::AliTPCtracker(const AliTPCtracker &t):
496 //------------------------------------
497 // dummy copy constructor
498 //------------------------------------------------------------------
500 for (Int_t irow=0; irow<200; irow++){
507 AliTPCtracker & AliTPCtracker::operator=(const AliTPCtracker& /*r*/)
509 //------------------------------
511 //--------------------------------------------------------------
514 //_____________________________________________________________________________
515 AliTPCtracker::~AliTPCtracker() {
516 //------------------------------------------------------------------
517 // TPC tracker destructor
518 //------------------------------------------------------------------
525 if (fDebugStreamer) delete fDebugStreamer;
526 if (fSeedsPool) delete fSeedsPool;
530 void AliTPCtracker::FillESD(const TObjArray* arr)
534 //fill esds using updated tracks
540 // write tracks to the event
541 // store index of the track
542 Int_t nseed=arr->GetEntriesFast();
543 //FindKinks(arr,fEvent);
544 for (Int_t i=0; i<nseed; i++) {
545 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
549 if (AliTPCReconstructor::StreamLevel()>1) {
550 (*fDebugStreamer)<<"Track0"<<
554 // pt->PropagateTo(fkParam->GetInnerRadiusLow());
555 if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
556 pt->PropagateTo(fkParam->GetInnerRadiusLow());
559 if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
560 iotrack.~AliESDtrack();
561 new(&iotrack) AliESDtrack;
562 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
563 iotrack.SetTPCPoints(pt->GetPoints());
564 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
565 iotrack.SetV0Indexes(pt->GetV0Indexes());
566 // iotrack.SetTPCpid(pt->fTPCr);
567 //iotrack.SetTPCindex(i);
568 MakeESDBitmaps(pt, &iotrack);
569 fEvent->AddTrack(&iotrack);
573 if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
574 iotrack.~AliESDtrack();
575 new(&iotrack) AliESDtrack;
576 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
577 iotrack.SetTPCPoints(pt->GetPoints());
578 //iotrack.SetTPCindex(i);
579 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
580 iotrack.SetV0Indexes(pt->GetV0Indexes());
581 MakeESDBitmaps(pt, &iotrack);
582 // iotrack.SetTPCpid(pt->fTPCr);
583 fEvent->AddTrack(&iotrack);
587 // short tracks - maybe decays
589 if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
590 Int_t found,foundable,shared;
591 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
592 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
593 iotrack.~AliESDtrack();
594 new(&iotrack) AliESDtrack;
595 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
596 //iotrack.SetTPCindex(i);
597 iotrack.SetTPCPoints(pt->GetPoints());
598 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
599 iotrack.SetV0Indexes(pt->GetV0Indexes());
600 MakeESDBitmaps(pt, &iotrack);
601 //iotrack.SetTPCpid(pt->fTPCr);
602 fEvent->AddTrack(&iotrack);
607 if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
608 Int_t found,foundable,shared;
609 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
610 if (found<20) continue;
611 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
613 iotrack.~AliESDtrack();
614 new(&iotrack) AliESDtrack;
615 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
616 iotrack.SetTPCPoints(pt->GetPoints());
617 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
618 iotrack.SetV0Indexes(pt->GetV0Indexes());
619 MakeESDBitmaps(pt, &iotrack);
620 //iotrack.SetTPCpid(pt->fTPCr);
621 //iotrack.SetTPCindex(i);
622 fEvent->AddTrack(&iotrack);
625 // short tracks - secondaties
627 if ( (pt->GetNumberOfClusters()>30) ) {
628 Int_t found,foundable,shared;
629 pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
630 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
631 iotrack.~AliESDtrack();
632 new(&iotrack) AliESDtrack;
633 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
634 iotrack.SetTPCPoints(pt->GetPoints());
635 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
636 iotrack.SetV0Indexes(pt->GetV0Indexes());
637 MakeESDBitmaps(pt, &iotrack);
638 //iotrack.SetTPCpid(pt->fTPCr);
639 //iotrack.SetTPCindex(i);
640 fEvent->AddTrack(&iotrack);
645 if ( (pt->GetNumberOfClusters()>15)) {
646 Int_t found,foundable,shared;
647 pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
648 if (found<15) continue;
649 if (foundable<=0) continue;
650 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
651 if (float(found)/float(foundable)<0.8) continue;
653 iotrack.~AliESDtrack();
654 new(&iotrack) AliESDtrack;
655 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
656 iotrack.SetTPCPoints(pt->GetPoints());
657 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
658 iotrack.SetV0Indexes(pt->GetV0Indexes());
659 MakeESDBitmaps(pt, &iotrack);
660 // iotrack.SetTPCpid(pt->fTPCr);
661 //iotrack.SetTPCindex(i);
662 fEvent->AddTrack(&iotrack);
666 // >> account for suppressed tracks in the kink indices (RS)
667 int nESDtracks = fEvent->GetNumberOfTracks();
668 for (int it=nESDtracks;it--;) {
669 AliESDtrack* esdTr = fEvent->GetTrack(it);
670 if (!esdTr || !esdTr->GetKinkIndex(0)) continue;
671 for (int ik=0;ik<3;ik++) {
673 if (!(knkId=esdTr->GetKinkIndex(ik))) break; // no more kinks for this track
674 AliESDkink* kink = fEvent->GetKink(TMath::Abs(knkId)-1);
676 AliError(Form("ESDTrack%d refers to non-existing kink %d",it,TMath::Abs(knkId)-1));
679 kink->SetIndex(it, knkId<0 ? 0:1); // update track index of the kink: mother at 0, daughter at 1
683 // << account for suppressed tracks in the kink indices (RS)
684 AliInfo(Form("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks()));
692 Double_t AliTPCtracker::ErrY2(AliTPCseed* seed, const AliTPCclusterMI * cl){
695 // Use calibrated cluster error from OCDB
697 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
699 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
700 Int_t ctype = cl->GetType();
701 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
702 Double_t angle = seed->GetSnp()*seed->GetSnp();
703 angle = TMath::Sqrt(TMath::Abs(angle/(1.-angle)));
704 Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
706 erry2+=0.5; // edge cluster
710 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
711 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
712 erry2+=addErr*addErr;
713 seed->SetErrorY2(erry2);
717 //calculate look-up table at the beginning
718 // static Bool_t ginit = kFALSE;
719 // static Float_t gnoise1,gnoise2,gnoise3;
720 // static Float_t ggg1[10000];
721 // static Float_t ggg2[10000];
722 // static Float_t ggg3[10000];
723 // static Float_t glandau1[10000];
724 // static Float_t glandau2[10000];
725 // static Float_t glandau3[10000];
727 // static Float_t gcor01[500];
728 // static Float_t gcor02[500];
729 // static Float_t gcorp[500];
733 // if (ginit==kFALSE){
734 // for (Int_t i=1;i<500;i++){
735 // Float_t rsigma = float(i)/100.;
736 // gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
737 // gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
738 // gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
742 // for (Int_t i=3;i<10000;i++){
746 // Float_t amp = float(i);
747 // Float_t padlength =0.75;
748 // gnoise1 = 0.0004/padlength;
749 // Float_t nel = 0.268*amp;
750 // Float_t nprim = 0.155*amp;
751 // ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
752 // glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
753 // if (glandau1[i]>1) glandau1[i]=1;
754 // glandau1[i]*=padlength*padlength/12.;
758 // gnoise2 = 0.0004/padlength;
760 // nprim = 0.133*amp;
761 // ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
762 // glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
763 // if (glandau2[i]>1) glandau2[i]=1;
764 // glandau2[i]*=padlength*padlength/12.;
769 // gnoise3 = 0.0004/padlength;
771 // nprim = 0.133*amp;
772 // ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
773 // glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
774 // if (glandau3[i]>1) glandau3[i]=1;
775 // glandau3[i]*=padlength*padlength/12.;
783 // Int_t amp = int(TMath::Abs(cl->GetQ()));
785 // seed->SetErrorY2(1.);
789 // Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
790 // Int_t ctype = cl->GetType();
791 // Float_t padlength= GetPadPitchLength(seed->GetRow());
792 // Double_t angle2 = seed->GetSnp()*seed->GetSnp();
793 // angle2 = angle2/(1-angle2);
795 // //cluster "quality"
796 // Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
799 // if (fSectors==fInnerSec){
800 // snoise2 = gnoise1;
801 // res = ggg1[amp]*z+glandau1[amp]*angle2;
802 // if (ctype==0) res *= gcor01[rsigmay];
805 // res*= gcorp[rsigmay];
809 // if (padlength<1.1){
810 // snoise2 = gnoise2;
811 // res = ggg2[amp]*z+glandau2[amp]*angle2;
812 // if (ctype==0) res *= gcor02[rsigmay];
815 // res*= gcorp[rsigmay];
819 // snoise2 = gnoise3;
820 // res = ggg3[amp]*z+glandau3[amp]*angle2;
821 // if (ctype==0) res *= gcor02[rsigmay];
824 // res*= gcorp[rsigmay];
831 // res*=2.4; // overestimate error 2 times
835 // if (res<2*snoise2)
838 // seed->SetErrorY2(res);
846 Double_t AliTPCtracker::ErrZ2(AliTPCseed* seed, const AliTPCclusterMI * cl){
849 // Use calibrated cluster error from OCDB
851 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
853 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
854 Int_t ctype = cl->GetType();
855 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
857 Double_t angle2 = seed->GetSnp()*seed->GetSnp();
858 angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
859 Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
860 Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
862 errz2+=0.5; // edge cluster
866 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
867 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
868 errz2+=addErr*addErr;
869 seed->SetErrorZ2(errz2);
875 // //seed->SetErrorY2(0.1);
877 // //calculate look-up table at the beginning
878 // static Bool_t ginit = kFALSE;
879 // static Float_t gnoise1,gnoise2,gnoise3;
880 // static Float_t ggg1[10000];
881 // static Float_t ggg2[10000];
882 // static Float_t ggg3[10000];
883 // static Float_t glandau1[10000];
884 // static Float_t glandau2[10000];
885 // static Float_t glandau3[10000];
887 // static Float_t gcor01[1000];
888 // static Float_t gcor02[1000];
889 // static Float_t gcorp[1000];
893 // if (ginit==kFALSE){
894 // for (Int_t i=1;i<1000;i++){
895 // Float_t rsigma = float(i)/100.;
896 // gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
897 // gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
898 // gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
902 // for (Int_t i=3;i<10000;i++){
906 // Float_t amp = float(i);
907 // Float_t padlength =0.75;
908 // gnoise1 = 0.0004/padlength;
909 // Float_t nel = 0.268*amp;
910 // Float_t nprim = 0.155*amp;
911 // ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
912 // glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
913 // if (glandau1[i]>1) glandau1[i]=1;
914 // glandau1[i]*=padlength*padlength/12.;
918 // gnoise2 = 0.0004/padlength;
920 // nprim = 0.133*amp;
921 // ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
922 // glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
923 // if (glandau2[i]>1) glandau2[i]=1;
924 // glandau2[i]*=padlength*padlength/12.;
929 // gnoise3 = 0.0004/padlength;
931 // nprim = 0.133*amp;
932 // ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
933 // glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
934 // if (glandau3[i]>1) glandau3[i]=1;
935 // glandau3[i]*=padlength*padlength/12.;
943 // Int_t amp = int(TMath::Abs(cl->GetQ()));
945 // seed->SetErrorY2(1.);
949 // Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
950 // Int_t ctype = cl->GetType();
951 // Float_t padlength= GetPadPitchLength(seed->GetRow());
953 // Double_t angle2 = seed->GetSnp()*seed->GetSnp();
954 // // if (angle2<0.6) angle2 = 0.6;
955 // angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
957 // //cluster "quality"
958 // Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
961 // if (fSectors==fInnerSec){
962 // snoise2 = gnoise1;
963 // res = ggg1[amp]*z+glandau1[amp]*angle2;
964 // if (ctype==0) res *= gcor01[rsigmaz];
967 // res*= gcorp[rsigmaz];
971 // if (padlength<1.1){
972 // snoise2 = gnoise2;
973 // res = ggg2[amp]*z+glandau2[amp]*angle2;
974 // if (ctype==0) res *= gcor02[rsigmaz];
977 // res*= gcorp[rsigmaz];
981 // snoise2 = gnoise3;
982 // res = ggg3[amp]*z+glandau3[amp]*angle2;
983 // if (ctype==0) res *= gcor02[rsigmaz];
986 // res*= gcorp[rsigmaz];
995 // if ((ctype<0) &&<70){
1000 // if (res<2*snoise2)
1002 // if (res>3) res =3;
1003 // seed->SetErrorZ2(res);
1011 void AliTPCtracker::RotateToLocal(AliTPCseed *seed)
1013 //rotate to track "local coordinata
1014 Float_t x = seed->GetX();
1015 Float_t y = seed->GetY();
1016 Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
1019 seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
1020 if (!seed->Rotate(fSectors->GetAlpha()))
1022 } else if (y <-ymax) {
1023 seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
1024 if (!seed->Rotate(-fSectors->GetAlpha()))
1032 //_____________________________________________________________________________
1033 Double_t AliTPCtracker::F1old(Double_t x1,Double_t y1,
1034 Double_t x2,Double_t y2,
1035 Double_t x3,Double_t y3) const
1037 //-----------------------------------------------------------------
1038 // Initial approximation of the track curvature
1039 //-----------------------------------------------------------------
1040 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1041 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1042 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1043 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1044 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1046 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1047 if ( xr*xr+yr*yr<=0.00000000000001) return 100;
1048 return -xr*yr/sqrt(xr*xr+yr*yr);
1053 //_____________________________________________________________________________
1054 Double_t AliTPCtracker::F1(Double_t x1,Double_t y1,
1055 Double_t x2,Double_t y2,
1056 Double_t x3,Double_t y3) const
1058 //-----------------------------------------------------------------
1059 // Initial approximation of the track curvature
1060 //-----------------------------------------------------------------
1066 Double_t det = x3*y2-x2*y3;
1067 if (TMath::Abs(det)<1e-10){
1071 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1072 Double_t x0 = x3*0.5-y3*u;
1073 Double_t y0 = y3*0.5+x3*u;
1074 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1080 Double_t AliTPCtracker::F2(Double_t x1,Double_t y1,
1081 Double_t x2,Double_t y2,
1082 Double_t x3,Double_t y3) const
1084 //-----------------------------------------------------------------
1085 // Initial approximation of the track curvature
1086 //-----------------------------------------------------------------
1092 Double_t det = x3*y2-x2*y3;
1093 if (TMath::Abs(det)<1e-10) {
1097 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1098 Double_t x0 = x3*0.5-y3*u;
1099 Double_t y0 = y3*0.5+x3*u;
1100 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1109 //_____________________________________________________________________________
1110 Double_t AliTPCtracker::F2old(Double_t x1,Double_t y1,
1111 Double_t x2,Double_t y2,
1112 Double_t x3,Double_t y3) const
1114 //-----------------------------------------------------------------
1115 // Initial approximation of the track curvature times center of curvature
1116 //-----------------------------------------------------------------
1117 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1118 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1119 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1120 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1121 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1123 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1125 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1128 //_____________________________________________________________________________
1129 Double_t AliTPCtracker::F3(Double_t x1,Double_t y1,
1130 Double_t x2,Double_t y2,
1131 Double_t z1,Double_t z2) const
1133 //-----------------------------------------------------------------
1134 // Initial approximation of the tangent of the track dip angle
1135 //-----------------------------------------------------------------
1136 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1140 Double_t AliTPCtracker::F3n(Double_t x1,Double_t y1,
1141 Double_t x2,Double_t y2,
1142 Double_t z1,Double_t z2, Double_t c) const
1144 //-----------------------------------------------------------------
1145 // Initial approximation of the tangent of the track dip angle
1146 //-----------------------------------------------------------------
1150 //angle1 = (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1152 Double_t d = TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1153 if (TMath::Abs(d*c*0.5)>1) return 0;
1154 // Double_t angle2 = TMath::ASin(d*c*0.5);
1155 // Double_t angle2 = AliTPCFastMath::FastAsin(d*c*0.5);
1156 Double_t angle2 = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): AliTPCFastMath::FastAsin(d*c*0.5);
1158 angle2 = (z1-z2)*c/(angle2*2.);
1162 Bool_t AliTPCtracker::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
1163 {//-----------------------------------------------------------------
1164 // This function find proloncation of a track to a reference plane x=x2.
1165 //-----------------------------------------------------------------
1169 if (TMath::Abs(x[4]*x1 - x[2]) >= 0.999) {
1173 Double_t c1=x[4]*x1 - x[2], r1=TMath::Sqrt((1.-c1)*(1.+c1));
1174 Double_t c2=x[4]*x2 - x[2], r2=TMath::Sqrt((1.-c2)*(1.+c2));
1178 Double_t dy = dx*(c1+c2)/(r1+r2);
1181 Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1183 if (TMath::Abs(delta)>0.01){
1184 dz = x[3]*TMath::ASin(delta)/x[4];
1186 dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1189 //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1197 Int_t AliTPCtracker::LoadClusters (TTree *const tree)
1202 return LoadClusters();
1206 Int_t AliTPCtracker::LoadClusters(const TObjArray *arr)
1209 // load clusters to the memory
1210 AliTPCClustersRow *clrow = new AliTPCClustersRow("AliTPCclusterMI");
1211 Int_t lower = arr->LowerBound();
1212 Int_t entries = arr->GetEntriesFast();
1214 for (Int_t i=lower; i<entries; i++) {
1215 clrow = (AliTPCClustersRow*) arr->At(i);
1216 if(!clrow) continue;
1217 if(!clrow->GetArray()) continue;
1221 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
1223 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1224 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1227 if (clrow->GetArray()->GetEntriesFast()<=0) continue;
1228 AliTPCtrackerRow * tpcrow=0;
1231 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1235 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1236 left = (sec-fkNIS*2)/fkNOS;
1239 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
1240 for (Int_t j=0;j<tpcrow->GetN1();++j)
1241 tpcrow->SetCluster1(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
1244 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
1245 for (Int_t j=0;j<tpcrow->GetN2();++j)
1246 tpcrow->SetCluster2(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
1248 clrow->GetArray()->Clear("C");
1257 Int_t AliTPCtracker::LoadClusters(const TClonesArray *arr)
1260 // load clusters to the memory from one
1263 AliTPCclusterMI *clust=0;
1264 Int_t count[72][96] = { {0} , {0} };
1266 // loop over clusters
1267 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1268 clust = (AliTPCclusterMI*)arr->At(icl);
1269 if(!clust) continue;
1270 //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
1272 // transform clusters
1275 // count clusters per pad row
1276 count[clust->GetDetector()][clust->GetRow()]++;
1279 // insert clusters to sectors
1280 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1281 clust = (AliTPCclusterMI*)arr->At(icl);
1282 if(!clust) continue;
1284 Int_t sec = clust->GetDetector();
1285 Int_t row = clust->GetRow();
1287 // filter overlapping pad rows needed by HLT
1288 if(sec<fkNIS*2) { //IROCs
1289 if(row == 30) continue;
1292 if(row == 27 || row == 76) continue;
1297 // left = sec/fkNIS;
1298 fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fkParam);
1301 // left = (sec-fkNIS*2)/fkNOS;
1302 fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fkParam);
1306 // Load functions must be called behind LoadCluster(TClonesArray*)
1308 //LoadOuterSectors();
1309 //LoadInnerSectors();
1315 Int_t AliTPCtracker::LoadClusters()
1318 // load clusters to the memory
1319 static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
1321 // TTree * tree = fClustersArray.GetTree();
1322 AliInfo("LoadClusters()\n");
1324 TTree * tree = fInput;
1325 TBranch * br = tree->GetBranch("Segment");
1326 br->SetAddress(&clrow);
1328 // Conversion of pad, row coordinates in local tracking coords.
1329 // Could be skipped here; is already done in clusterfinder
1331 Int_t j=Int_t(tree->GetEntries());
1332 for (Int_t i=0; i<j; i++) {
1336 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
1337 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1338 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1341 AliTPCtrackerRow * tpcrow=0;
1344 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1348 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1349 left = (sec-fkNIS*2)/fkNOS;
1352 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
1353 for (Int_t k=0;k<tpcrow->GetN1();++k)
1354 tpcrow->SetCluster1(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
1357 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
1358 for (Int_t k=0;k<tpcrow->GetN2();++k)
1359 tpcrow->SetCluster2(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
1366 if (AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection()) ApplyTailCancellation();
1371 void AliTPCtracker::UnloadClusters()
1374 // unload clusters from the memory
1376 Int_t nrows = fOuterSec->GetNRows();
1377 for (Int_t sec = 0;sec<fkNOS;sec++)
1378 for (Int_t row = 0;row<nrows;row++){
1379 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1381 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1382 // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1384 tpcrow->ResetClusters();
1387 nrows = fInnerSec->GetNRows();
1388 for (Int_t sec = 0;sec<fkNIS;sec++)
1389 for (Int_t row = 0;row<nrows;row++){
1390 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1392 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1393 //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1395 tpcrow->ResetClusters();
1401 void AliTPCtracker::FillClusterArray(TObjArray* array) const{
1403 // Filling cluster to the array - For visualization purposes
1406 nrows = fOuterSec->GetNRows();
1407 for (Int_t sec = 0;sec<fkNOS;sec++)
1408 for (Int_t row = 0;row<nrows;row++){
1409 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1410 if (!tpcrow) continue;
1411 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1412 array->AddLast((TObject*)((*tpcrow)[icl]));
1415 nrows = fInnerSec->GetNRows();
1416 for (Int_t sec = 0;sec<fkNIS;sec++)
1417 for (Int_t row = 0;row<nrows;row++){
1418 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1419 if (!tpcrow) continue;
1420 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1421 array->AddLast((TObject*)(*tpcrow)[icl]);
1427 void AliTPCtracker::Transform(AliTPCclusterMI * cluster){
1431 AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1432 AliTPCTransform *transform = calibDB->GetTransform() ;
1434 AliFatal("Tranformations not in calibDB");
1437 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
1438 Double_t x[3]={cluster->GetRow(),cluster->GetPad(),cluster->GetTimeBin()};
1439 Int_t i[1]={cluster->GetDetector()};
1440 transform->Transform(x,i,0,1);
1441 // if (cluster->GetDetector()%36>17){
1446 // in debug mode check the transformation
1448 if (AliTPCReconstructor::StreamLevel()>2) {
1450 cluster->GetGlobalXYZ(gx);
1451 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
1452 TTreeSRedirector &cstream = *fDebugStreamer;
1453 cstream<<"Transform"<<
1464 cluster->SetX(x[0]);
1465 cluster->SetY(x[1]);
1466 cluster->SetZ(x[2]);
1471 //if (!fkParam->IsGeoRead()) fkParam->ReadGeoMatrices();
1472 if (AliTPCReconstructor::GetRecoParam()->GetUseSectorAlignment() && (!calibDB->HasAlignmentOCDB())){
1473 TGeoHMatrix *mat = fkParam->GetClusterMatrix(cluster->GetDetector());
1475 Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1476 Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1477 if (mat) mat->LocalToMaster(pos,posC);
1479 // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
1481 cluster->SetX(posC[0]);
1482 cluster->SetY(posC[1]);
1483 cluster->SetZ(posC[2]);
1487 void AliTPCtracker::ApplyTailCancellation(){
1489 // Correct the cluster charge for the ion tail effect
1490 // The TimeResponse function accessed via AliTPCcalibDB (TPC/Calib/IonTail)
1494 TObjArray *ionTailArr = (TObjArray*)AliTPCcalibDB::Instance()->GetIonTailArray();
1495 if (!ionTailArr) {AliFatal("TPC - Missing IonTail OCDB object");}
1496 TObject *rocFactorIROC = ionTailArr->FindObject("factorIROC");
1497 TObject *rocFactorOROC = ionTailArr->FindObject("factorOROC");
1498 Float_t factorIROC = (atof(rocFactorIROC->GetTitle()));
1499 Float_t factorOROC = (atof(rocFactorOROC->GetTitle()));
1501 // find the number of clusters for the whole TPC (nclALL)
1503 for (Int_t isector=0; isector<36; isector++){
1504 AliTPCtrackerSector §or= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1505 nclALL += sector.GetNClInSector(0);
1506 nclALL += sector.GetNClInSector(1);
1509 // start looping over all clusters
1510 for (Int_t iside=0; iside<2; iside++){ // loop over sides
1513 for (Int_t secType=0; secType<2; secType++){ //loop over inner or outer sector
1514 // cache experimantal tuning factor for the different chamber type
1515 const Float_t ampfactor = (secType==0)?factorIROC:factorOROC;
1516 std::cout << " ampfactor = " << ampfactor << std::endl;
1518 for (Int_t sec = 0;sec<fkNOS;sec++){ //loop overs sectors
1521 // Cache time response functions and their positons to COG of the cluster
1522 TGraphErrors ** graphRes = new TGraphErrors *[20];
1523 Float_t * indexAmpGraphs = new Float_t[20];
1524 for (Int_t icache=0; icache<20; icache++)
1526 graphRes[icache] = NULL;
1527 indexAmpGraphs[icache] = 0;
1529 ///////////////////////////// --> position fo sie loop
1530 if (!AliTPCcalibDB::Instance()->GetTailcancelationGraphs(sec+36*secType+18*iside,graphRes,indexAmpGraphs))
1535 AliTPCtrackerSector §or= (secType==0)?fInnerSec[sec]:fOuterSec[sec];
1536 Int_t nrows = sector.GetNRows(); // number of rows
1537 Int_t nclSector = sector.GetNClInSector(iside); // ncl per sector to be used for debugging
1539 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1541 AliTPCtrackerRow& tpcrow = sector[row]; // row object
1542 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1543 if (iside>0) ncl=tpcrow.GetN2();
1545 // Order clusters in time for the proper correction of ion tail
1546 Float_t qTotArray[ncl]; // arrays to be filled with modified Qtot and Qmax values in order to avoid float->int conversion
1547 Float_t qMaxArray[ncl];
1548 Int_t sortedClusterIndex[ncl];
1549 Float_t sortedClusterTimeBin[ncl];
1550 TObjArray *rowClusterArray = new TObjArray(ncl); // cache clusters for each row
1551 for (Int_t i=0;i<ncl;i++)
1555 sortedClusterIndex[i]=i;
1556 AliTPCclusterMI *rowcl= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1558 rowClusterArray->AddAt(rowcl,i);
1560 rowClusterArray->RemoveAt(i);
1562 // Fill the timebin info to the array in order to sort wrt tb
1564 sortedClusterTimeBin[i]=0.0;
1566 sortedClusterTimeBin[i] = rowcl->GetTimeBin();
1570 TMath::Sort(ncl,sortedClusterTimeBin,sortedClusterIndex,kFALSE); // sort clusters in time
1572 // Main cluster correction loops over clusters
1573 for (Int_t icl0=0; icl0<ncl;icl0++){ // first loop over clusters
1575 AliTPCclusterMI *cl0= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl0]));
1579 for (Int_t icl1=0; icl1<ncl;icl1++){ // second loop over clusters
1581 AliTPCclusterMI *cl1= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl1]));
1583 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())>4) continue; // no contribution if far away in pad direction
1584 if (cl0->GetTimeBin()<= cl1->GetTimeBin()) continue; // no contibution to the tail if later
1585 if (TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin())>600) continue; // out of the range of response function
1587 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())<4) nclPad++; // count ncl for every pad for debugging
1589 // Get the correction values for Qmax and Qtot and find total correction for a given cluster
1590 Double_t ionTailMax=0.;
1591 Double_t ionTailTotal=0.;
1592 GetTailValue(ampfactor,ionTailMax,ionTailTotal,graphRes,indexAmpGraphs,cl0,cl1);
1593 ionTailMax=TMath::Abs(ionTailMax);
1594 ionTailTotal=TMath::Abs(ionTailTotal);
1595 qTotArray[icl0]+=ionTailTotal;
1596 qMaxArray[icl0]+=ionTailMax;
1598 // Dump some info for debugging while clusters are being corrected
1599 if (AliTPCReconstructor::StreamLevel()==1) {
1600 TTreeSRedirector &cstream = *fDebugStreamer;
1601 if (gRandom->Rndm() > 0.999){
1602 cstream<<"IonTail"<<
1603 "cl0.=" <<cl0 << // cluster 0 (to be corrected)
1604 "cl1.=" <<cl1 << // cluster 1 (previous cluster)
1605 "ionTailTotal=" <<ionTailTotal << // ion Tail from cluster 1 contribution to cluster0
1606 "ionTailMax=" <<ionTailMax << // ion Tail from cluster 1 contribution to cluster0
1609 }// dump the results to the debug streamer if in debug mode
1611 }//end of second loop over clusters
1613 // Set corrected values of the corrected cluster
1614 cl0->SetQ(TMath::Nint(Float_t(cl0->GetQ())+Float_t(qTotArray[icl0])));
1615 cl0->SetMax(TMath::Nint(Float_t(cl0->GetMax())+qMaxArray[icl0]));
1617 // Dump some info for debugging after clusters are corrected
1618 if (AliTPCReconstructor::StreamLevel()==1) {
1619 TTreeSRedirector &cstream = *fDebugStreamer;
1620 if (gRandom->Rndm() > 0.999){
1621 cstream<<"IonTailCorrected"<<
1622 "cl0.=" << cl0 << // cluster 0 with huge Qmax
1623 "ionTailTotalPerCluster=" << qTotArray[icl0] <<
1624 "ionTailMaxPerCluster=" << qMaxArray[icl0] <<
1625 "nclALL=" << nclALL <<
1626 "nclSector=" << nclSector <<
1628 "nclPad=" << nclPad <<
1634 }// dump the results to the debug streamer if in debug mode
1636 }//end of first loop over cluster
1637 delete rowClusterArray;
1638 }//end of loop over rows
1639 for (int i=0; i<20; i++) delete graphRes[i];
1641 delete [] indexAmpGraphs;
1643 }//end of loop over sectors
1644 }//end of loop over IROC/OROC
1645 }// end of side loop
1647 //_____________________________________________________________________________
1648 void AliTPCtracker::GetTailValue(Float_t ampfactor,Double_t &ionTailMax, Double_t &ionTailTotal,TGraphErrors **graphRes,Float_t *indexAmpGraphs,AliTPCclusterMI *cl0,AliTPCclusterMI *cl1){
1651 // Function in order to calculate the amount of the correction to be added for a given cluster, return values are ionTailTaoltal and ionTailMax
1654 const Double_t kMinPRF = 0.5; // minimal PRF width
1655 ionTailTotal = 0.; // correction value to be added to Qtot of cl0
1656 ionTailMax = 0.; // correction value to be added to Qmax of cl0
1658 Float_t qTot0 = cl0->GetQ(); // cl0 Qtot info
1659 Float_t qTot1 = cl1->GetQ(); // cl1 Qtot info
1660 Int_t sectorPad = cl1->GetDetector(); // sector number
1661 Int_t padcl0 = TMath::Nint(cl0->GetPad()); // pad0
1662 Int_t padcl1 = TMath::Nint(cl1->GetPad()); // pad1
1663 Float_t padWidth = (sectorPad < 36)?0.4:0.6; // pad width in cm
1664 const Int_t deltaTimebin = TMath::Nint(TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin()))+12; //distance between pads of cl1 and cl0 increased by 12 bins
1665 Double_t rmsPad1 = (cl1->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl1->GetSigmaY2())/padWidth);
1666 Double_t rmsPad0 = (cl0->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl0->GetSigmaY2())/padWidth);
1669 Double_t sumAmp1=0.;
1670 for (Int_t idelta =-2; idelta<=2;idelta++){
1671 sumAmp1+=TMath::Exp(-idelta*idelta/(2*rmsPad1));
1674 Double_t sumAmp0=0.;
1675 for (Int_t idelta =-2; idelta<=2;idelta++){
1676 sumAmp0+=TMath::Exp(-idelta*idelta/(2*rmsPad0));
1679 // Apply the correction --> cl1 corrects cl0 (loop over cl1's pads and find which pads of cl0 are going to be corrected)
1680 Int_t padScan=2; // +-2 pad-timebin window will be scanned
1681 for (Int_t ipad1=padcl1-padScan; ipad1<=padcl1+padScan; ipad1++) {
1684 Float_t deltaPad1 = TMath::Abs(cl1->GetPad()-(Float_t)ipad1);
1685 Double_t amp1 = (TMath::Exp(-(deltaPad1*deltaPad1)/(2*rmsPad1)))/sumAmp1; // normalized pad response function
1686 Float_t qTotPad1 = amp1*qTot1; // used as a factor to multipliy the response function
1688 // find closest value of cl1 to COG (among the time response functions' amplitude array --> to select proper t.r.f.)
1690 Float_t diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[0]);
1691 for (Int_t j=0;j<20;j++) {
1692 if (diffAmp > TMath::Abs(deltaPad1-indexAmpGraphs[j]) && indexAmpGraphs[j]!=0)
1694 diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[j]);
1698 if (!graphRes[ampIndex]) continue;
1699 if (deltaTimebin+2 >= graphRes[ampIndex]->GetN()) continue;
1700 if (graphRes[ampIndex]->GetY()[deltaTimebin+2]>=0) continue;
1702 for (Int_t ipad0=padcl0-padScan; ipad0<=padcl0+padScan; ipad0++) {
1705 if (ipad1!=ipad0) continue; // check if ipad1 channel sees ipad0 channel, if not no correction to be applied.
1707 Float_t deltaPad0 = TMath::Abs(cl0->GetPad()-(Float_t)ipad0);
1708 Double_t amp0 = (TMath::Exp(-(deltaPad0*deltaPad0)/(2*rmsPad0)))/sumAmp0; // normalized pad resp function
1709 Float_t qMaxPad0 = amp0*qTot0;
1711 // Add 5 timebin range contribution around the max peak (-+2 tb window)
1712 for (Int_t itb=deltaTimebin-2; itb<=deltaTimebin+2; itb++) {
1714 if (itb<0) continue;
1715 if (itb>=graphRes[ampIndex]->GetN()) continue;
1717 // calculate contribution to qTot
1718 Float_t tailCorr = TMath::Abs((qTotPad1*ampfactor)*(graphRes[ampIndex])->GetY()[itb]);
1719 if (ipad1!=padcl0) {
1720 ionTailTotal += TMath::Min(qMaxPad0,tailCorr); // for side pad
1722 ionTailTotal += tailCorr; // for center pad
1724 // calculate contribution to qMax
1725 if (itb == deltaTimebin && ipad1 == padcl0) ionTailMax += tailCorr;
1727 } // end of tb correction loop which is applied over 5 tb range
1729 } // end of cl0 loop
1730 } // end of cl1 loop
1734 //_____________________________________________________________________________
1735 Int_t AliTPCtracker::LoadOuterSectors() {
1736 //-----------------------------------------------------------------
1737 // This function fills outer TPC sectors with clusters.
1738 //-----------------------------------------------------------------
1739 Int_t nrows = fOuterSec->GetNRows();
1741 for (Int_t sec = 0;sec<fkNOS;sec++)
1742 for (Int_t row = 0;row<nrows;row++){
1743 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1744 Int_t sec2 = sec+2*fkNIS;
1746 Int_t ncl = tpcrow->GetN1();
1748 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1749 index=(((sec2<<8)+row)<<16)+ncl;
1750 tpcrow->InsertCluster(c,index);
1753 ncl = tpcrow->GetN2();
1755 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1756 index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
1757 tpcrow->InsertCluster(c,index);
1760 // write indexes for fast acces
1762 for (Int_t i=0;i<510;i++)
1763 tpcrow->SetFastCluster(i,-1);
1764 for (Int_t i=0;i<tpcrow->GetN();i++){
1765 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1766 tpcrow->SetFastCluster(zi,i); // write index
1769 for (Int_t i=0;i<510;i++){
1770 if (tpcrow->GetFastCluster(i)<0)
1771 tpcrow->SetFastCluster(i,last);
1773 last = tpcrow->GetFastCluster(i);
1782 //_____________________________________________________________________________
1783 Int_t AliTPCtracker::LoadInnerSectors() {
1784 //-----------------------------------------------------------------
1785 // This function fills inner TPC sectors with clusters.
1786 //-----------------------------------------------------------------
1787 Int_t nrows = fInnerSec->GetNRows();
1789 for (Int_t sec = 0;sec<fkNIS;sec++)
1790 for (Int_t row = 0;row<nrows;row++){
1791 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1794 Int_t ncl = tpcrow->GetN1();
1796 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1797 index=(((sec<<8)+row)<<16)+ncl;
1798 tpcrow->InsertCluster(c,index);
1801 ncl = tpcrow->GetN2();
1803 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1804 index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
1805 tpcrow->InsertCluster(c,index);
1808 // write indexes for fast acces
1810 for (Int_t i=0;i<510;i++)
1811 tpcrow->SetFastCluster(i,-1);
1812 for (Int_t i=0;i<tpcrow->GetN();i++){
1813 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1814 tpcrow->SetFastCluster(zi,i); // write index
1817 for (Int_t i=0;i<510;i++){
1818 if (tpcrow->GetFastCluster(i)<0)
1819 tpcrow->SetFastCluster(i,last);
1821 last = tpcrow->GetFastCluster(i);
1833 //_________________________________________________________________________
1834 AliTPCclusterMI *AliTPCtracker::GetClusterMI(Int_t index) const {
1835 //--------------------------------------------------------------------
1836 // Return pointer to a given cluster
1837 //--------------------------------------------------------------------
1838 if (index<0) return 0; // no cluster
1839 Int_t sec=(index&0xff000000)>>24;
1840 Int_t row=(index&0x00ff0000)>>16;
1841 Int_t ncl=(index&0x00007fff)>>00;
1843 const AliTPCtrackerRow * tpcrow=0;
1844 TClonesArray * clrow =0;
1846 if (sec<0 || sec>=fkNIS*4) {
1847 AliWarning(Form("Wrong sector %d",sec));
1852 AliTPCtrackerSector& tracksec = fInnerSec[sec%fkNIS];
1853 if (tracksec.GetNRows()<=row) return 0;
1854 tpcrow = &(tracksec[row]);
1855 if (tpcrow==0) return 0;
1858 if (tpcrow->GetN1()<=ncl) return 0;
1859 clrow = tpcrow->GetClusters1();
1862 if (tpcrow->GetN2()<=ncl) return 0;
1863 clrow = tpcrow->GetClusters2();
1867 AliTPCtrackerSector& tracksec = fOuterSec[(sec-fkNIS*2)%fkNOS];
1868 if (tracksec.GetNRows()<=row) return 0;
1869 tpcrow = &(tracksec[row]);
1870 if (tpcrow==0) return 0;
1872 if (sec-2*fkNIS<fkNOS) {
1873 if (tpcrow->GetN1()<=ncl) return 0;
1874 clrow = tpcrow->GetClusters1();
1877 if (tpcrow->GetN2()<=ncl) return 0;
1878 clrow = tpcrow->GetClusters2();
1882 return (AliTPCclusterMI*)clrow->At(ncl);
1888 Int_t AliTPCtracker::FollowToNext(AliTPCseed& t, Int_t nr) {
1889 //-----------------------------------------------------------------
1890 // This function tries to find a track prolongation to next pad row
1891 //-----------------------------------------------------------------
1893 Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
1896 AliTPCclusterMI *cl=0;
1897 Int_t tpcindex= t.GetClusterIndex2(nr);
1899 // update current shape info every 5 pad-row
1900 // if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
1904 if (fIteration>0 && tpcindex>=-1){ //if we have already clusters
1906 if (tpcindex==-1) return 0; //track in dead zone
1907 if (tpcindex >= 0){ //
1908 cl = t.GetClusterPointer(nr);
1909 //if (cl==0) cl = GetClusterMI(tpcindex);
1910 if (!cl) cl = GetClusterMI(tpcindex);
1911 t.SetCurrentClusterIndex1(tpcindex);
1914 Int_t relativesector = ((tpcindex&0xff000000)>>24)%18; // if previously accepted cluster in different sector
1915 Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
1917 if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
1918 if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
1920 if (TMath::Abs(angle-t.GetAlpha())>0.001){
1921 Double_t rotation = angle-t.GetAlpha();
1922 t.SetRelativeSector(relativesector);
1923 if (!t.Rotate(rotation)) {
1924 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
1928 if (!t.PropagateTo(x)) {
1929 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
1933 t.SetCurrentCluster(cl);
1935 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1936 if ((tpcindex&0x8000)==0) accept =0;
1938 //if founded cluster is acceptible
1939 if (cl->IsUsed(11)) { // id cluster is shared inrease uncertainty
1940 t.SetErrorY2(t.GetErrorY2()+0.03);
1941 t.SetErrorZ2(t.GetErrorZ2()+0.03);
1942 t.SetErrorY2(t.GetErrorY2()*3);
1943 t.SetErrorZ2(t.GetErrorZ2()*3);
1945 t.SetNFoundable(t.GetNFoundable()+1);
1946 UpdateTrack(&t,accept);
1949 else { // Remove old cluster from track
1950 t.SetClusterIndex(nr, -3);
1951 t.SetClusterPointer(nr, 0);
1955 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0; // cut on angle
1956 if (fIteration>1 && IsFindable(t)){
1957 // not look for new cluster during refitting
1958 t.SetNFoundable(t.GetNFoundable()+1);
1963 // if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
1964 if (!t.PropagateTo(x)) {
1965 if (fIteration==0) t.SetRemoval(10);
1968 Double_t y = t.GetY();
1969 if (TMath::Abs(y)>ymax){
1971 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1972 if (!t.Rotate(fSectors->GetAlpha()))
1974 } else if (y <-ymax) {
1975 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1976 if (!t.Rotate(-fSectors->GetAlpha()))
1979 if (!t.PropagateTo(x)) {
1980 if (fIteration==0) t.SetRemoval(10);
1986 Double_t z=t.GetZ();
1989 if (!IsActive(t.GetRelativeSector(),nr)) {
1991 t.SetClusterIndex2(nr,-1);
1994 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
1995 Bool_t isActive = IsActive(t.GetRelativeSector(),nr);
1996 Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
1998 if (!isActive || !isActive2) return 0;
2000 const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
2001 if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
2003 Double_t roadz = 1.;
2005 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
2007 t.SetClusterIndex2(nr,-1);
2013 // if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fkParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
2014 t.SetNFoundable(t.GetNFoundable()+1);
2020 // cl = krow.FindNearest2(y+10.,z,roady,roadz,index);
2021 cl = krow.FindNearest2(y,z,roady,roadz,index);
2022 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
2025 t.SetCurrentCluster(cl);
2027 if (fIteration==2&&cl->IsUsed(10)) return 0;
2028 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
2029 if (fIteration==2&&cl->IsUsed(11)) {
2030 t.SetErrorY2(t.GetErrorY2()+0.03);
2031 t.SetErrorZ2(t.GetErrorZ2()+0.03);
2032 t.SetErrorY2(t.GetErrorY2()*3);
2033 t.SetErrorZ2(t.GetErrorZ2()*3);
2036 if (t.fCurrentCluster->IsUsed(10)){
2041 if (t.fNShared>0.7*t.GetNumberOfClusters()) {
2047 if (accept<3) UpdateTrack(&t,accept);
2050 if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
2058 //_________________________________________________________________________
2059 Bool_t AliTPCtracker::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
2061 // Get track space point by index
2062 // return false in case the cluster doesn't exist
2063 AliTPCclusterMI *cl = GetClusterMI(index);
2064 if (!cl) return kFALSE;
2065 Int_t sector = (index&0xff000000)>>24;
2066 // Int_t row = (index&0x00ff0000)>>16;
2068 // xyz[0] = fkParam->GetPadRowRadii(sector,row);
2069 xyz[0] = cl->GetX();
2070 xyz[1] = cl->GetY();
2071 xyz[2] = cl->GetZ();
2073 fkParam->AdjustCosSin(sector,cos,sin);
2074 Float_t x = cos*xyz[0]-sin*xyz[1];
2075 Float_t y = cos*xyz[1]+sin*xyz[0];
2077 Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
2078 if (sector < fkParam->GetNInnerSector()) sigmaY2 *= 2.07;
2079 Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
2080 if (sector < fkParam->GetNInnerSector()) sigmaZ2 *= 1.77;
2081 cov[0] = sin*sin*sigmaY2;
2082 cov[1] = -sin*cos*sigmaY2;
2084 cov[3] = cos*cos*sigmaY2;
2087 p.SetXYZ(x,y,xyz[2],cov);
2088 AliGeomManager::ELayerID iLayer;
2090 if (sector < fkParam->GetNInnerSector()) {
2091 iLayer = AliGeomManager::kTPC1;
2095 iLayer = AliGeomManager::kTPC2;
2096 idet = sector - fkParam->GetNInnerSector();
2098 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
2099 p.SetVolumeID(volid);
2105 Int_t AliTPCtracker::UpdateClusters(AliTPCseed& t, Int_t nr) {
2106 //-----------------------------------------------------------------
2107 // This function tries to find a track prolongation to next pad row
2108 //-----------------------------------------------------------------
2109 t.SetCurrentCluster(0);
2110 t.SetCurrentClusterIndex1(-3);
2112 Double_t xt=t.GetX();
2113 Int_t row = GetRowNumber(xt)-1;
2114 Double_t ymax= GetMaxY(nr);
2116 if (row < nr) return 1; // don't prolongate if not information until now -
2117 // if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
2119 // return 0; // not prolongate strongly inclined tracks
2121 // if (TMath::Abs(t.GetSnp())>0.95) {
2123 // return 0; // not prolongate strongly inclined tracks
2124 // }// patch 28 fev 06
2126 Double_t x= GetXrow(nr);
2128 //t.PropagateTo(x+0.02);
2129 //t.PropagateTo(x+0.01);
2130 if (!t.PropagateTo(x)){
2137 if (TMath::Abs(y)>ymax){
2139 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
2140 if (!t.Rotate(fSectors->GetAlpha()))
2142 } else if (y <-ymax) {
2143 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
2144 if (!t.Rotate(-fSectors->GetAlpha()))
2147 // if (!t.PropagateTo(x)){
2154 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
2156 if (!IsActive(t.GetRelativeSector(),nr)) {
2158 t.SetClusterIndex2(nr,-1);
2161 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
2163 AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
2165 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
2167 t.SetClusterIndex2(nr,-1);
2173 // if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
2174 if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
2180 if ( (nr%2==0) || t.GetNumberOfClusters()<2){
2181 // t.fCurrentSigmaY = GetSigmaY(&t);
2182 //t.fCurrentSigmaZ = GetSigmaZ(&t);
2186 AliTPCclusterMI *cl=0;
2189 Double_t roady = 1.;
2190 Double_t roadz = 1.;
2194 index = t.GetClusterIndex2(nr);
2195 if ( (index >= 0) && (index&0x8000)==0){
2196 cl = t.GetClusterPointer(nr);
2197 if ( (cl==0) && (index >= 0)) cl = GetClusterMI(index);
2198 t.SetCurrentClusterIndex1(index);
2200 t.SetCurrentCluster(cl);
2206 // if (index<0) return 0;
2207 UInt_t uindex = TMath::Abs(index);
2210 //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
2211 cl = krow.FindNearest2(y,z,roady,roadz,uindex);
2214 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));
2215 t.SetCurrentCluster(cl);
2221 Int_t AliTPCtracker::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
2222 //-----------------------------------------------------------------
2223 // This function tries to find a track prolongation to next pad row
2224 //-----------------------------------------------------------------
2226 //update error according neighborhoud
2228 if (t.GetCurrentCluster()) {
2230 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
2232 if (t.GetCurrentCluster()->IsUsed(10)){
2237 t.SetNShared(t.GetNShared()+1);
2238 if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
2243 if (fIteration>0) accept = 0;
2244 if (accept<3) UpdateTrack(&t,accept);
2248 if ( t.GetNumberOfClusters()>18 && ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)) t.SetRemoval(10);
2249 if ( t.GetNumberOfClusters()>18 && t.GetChi2()/t.GetNumberOfClusters()>6 ) t.SetRemoval(10);
2251 if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
2259 //_____________________________________________________________________________
2260 Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step, Bool_t fromSeeds) {
2261 //-----------------------------------------------------------------
2262 // This function tries to find a track prolongation.
2263 //-----------------------------------------------------------------
2264 Double_t xt=t.GetX();
2266 Double_t alpha=t.GetAlpha();
2267 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2268 if (alpha < 0. ) alpha += 2.*TMath::Pi();
2270 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
2272 Int_t first = GetRowNumber(xt);
2277 for (Int_t nr= first; nr>=rf; nr-=step) {
2279 if (t.GetKinkIndexes()[0]>0){
2280 for (Int_t i=0;i<3;i++){
2281 Int_t index = t.GetKinkIndexes()[i];
2282 if (index==0) break;
2283 if (index<0) continue;
2285 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
2287 printf("PROBLEM\n");
2290 Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
2292 AliExternalTrackParam paramd(t);
2293 kink->SetDaughter(paramd);
2294 kink->SetStatus(2,5);
2301 if (nr==80) t.UpdateReference();
2302 if (nr<fInnerSec->GetNRows())
2303 fSectors = fInnerSec;
2305 fSectors = fOuterSec;
2306 if (FollowToNext(t,nr)==0)
2319 Int_t AliTPCtracker::FollowBackProlongation(AliTPCseed& t, Int_t rf, Bool_t fromSeeds) {
2320 //-----------------------------------------------------------------
2321 // This function tries to find a track prolongation.
2322 //-----------------------------------------------------------------
2324 Double_t xt=t.GetX();
2325 Double_t alpha=t.GetAlpha();
2326 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2327 if (alpha < 0. ) alpha += 2.*TMath::Pi();
2328 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
2330 Int_t first = t.GetFirstPoint();
2331 Int_t ri = GetRowNumber(xt);
2335 if (first<ri) first = ri;
2337 if (first<0) first=0;
2338 for (Int_t nr=first; nr<=rf; nr++) {
2339 // if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
2340 if (t.GetKinkIndexes()[0]<0){
2341 for (Int_t i=0;i<3;i++){
2342 Int_t index = t.GetKinkIndexes()[i];
2343 if (index==0) break;
2344 if (index>0) continue;
2345 index = TMath::Abs(index);
2346 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
2348 printf("PROBLEM\n");
2351 Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
2353 AliExternalTrackParam paramm(t);
2354 kink->SetMother(paramm);
2355 kink->SetStatus(2,1);
2362 if (nr<fInnerSec->GetNRows())
2363 fSectors = fInnerSec;
2365 fSectors = fOuterSec;
2376 Float_t AliTPCtracker::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
2378 // overlapping factor
2384 Float_t dz2 =(s1->GetZ() - s2->GetZ());
2387 Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
2389 Float_t distance = TMath::Sqrt(dz2+dy2);
2390 if (distance>4.) return 0; // if there are far away - not overlap - to reduce combinatorics
2393 Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
2394 Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
2399 if (firstpoint>lastpoint) {
2400 firstpoint =lastpoint;
2405 for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
2406 if (s1->GetClusterIndex2(i)>0) sum1++;
2407 if (s2->GetClusterIndex2(i)>0) sum2++;
2408 if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
2412 if (sum<5) return 0;
2414 Float_t summin = TMath::Min(sum1+1,sum2+1);
2415 Float_t ratio = (sum+1)/Float_t(summin);
2419 void AliTPCtracker::SignShared(AliTPCseed * s1, AliTPCseed * s2)
2423 Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
2424 if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
2425 Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
2426 Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
2431 //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
2432 //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
2433 Int_t firstpoint = 0;
2434 Int_t lastpoint = 160;
2436 // if (firstpoint>=lastpoint-5) return;;
2438 for (Int_t i=firstpoint;i<lastpoint;i++){
2439 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2440 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2444 if (sumshared>cutN0){
2447 for (Int_t i=firstpoint;i<lastpoint;i++){
2448 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2449 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2450 AliTPCTrackerPoint *p1 = s1->GetTrackPoint(i);
2451 AliTPCTrackerPoint *p2 = s2->GetTrackPoint(i);;
2452 if (s1->IsActive()&&s2->IsActive()){
2453 p1->SetShared(kTRUE);
2454 p2->SetShared(kTRUE);
2460 if (sumshared>cutN0){
2461 for (Int_t i=0;i<4;i++){
2462 if (s1->GetOverlapLabel(3*i)==0){
2463 s1->SetOverlapLabel(3*i, s2->GetLabel());
2464 s1->SetOverlapLabel(3*i+1,sumshared);
2465 s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
2469 for (Int_t i=0;i<4;i++){
2470 if (s2->GetOverlapLabel(3*i)==0){
2471 s2->SetOverlapLabel(3*i, s1->GetLabel());
2472 s2->SetOverlapLabel(3*i+1,sumshared);
2473 s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
2480 void AliTPCtracker::SignShared(TObjArray * arr)
2483 //sort trackss according sectors
2485 for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2486 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2488 //if (pt) RotateToLocal(pt);
2492 arr->Sort(); // sorting according relative sectors
2493 arr->Expand(arr->GetEntries());
2496 Int_t nseed=arr->GetEntriesFast();
2497 for (Int_t i=0; i<nseed; i++) {
2498 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2500 for (Int_t j=0;j<12;j++){
2501 pt->SetOverlapLabel(j,0);
2504 for (Int_t i=0; i<nseed; i++) {
2505 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2507 if (pt->GetRemoval()>10) continue;
2508 for (Int_t j=i+1; j<nseed; j++){
2509 AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
2510 if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
2512 if (pt2->GetRemoval()<=10) {
2513 //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
2521 void AliTPCtracker::SortTracks(TObjArray * arr, Int_t mode) const
2524 //sort tracks in array according mode criteria
2525 Int_t nseed = arr->GetEntriesFast();
2526 for (Int_t i=0; i<nseed; i++) {
2527 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2538 void AliTPCtracker::RemoveUsed2(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t minimal)
2541 // Loop over all tracks and remove overlaped tracks (with lower quality)
2543 // 1. Unsign clusters
2544 // 2. Sort tracks according quality
2545 // Quality is defined by the number of cluster between first and last points
2547 // 3. Loop over tracks - decreasing quality order
2548 // a.) remove - If the fraction of shared cluster less than factor (1- n or 2)
2549 // b.) remove - If the minimal number of clusters less than minimal and not ITS
2550 // c.) if track accepted - sign clusters
2552 //Called in - AliTPCtracker::Clusters2Tracks()
2553 // - AliTPCtracker::PropagateBack()
2554 // - AliTPCtracker::RefitInward()
2557 // factor1 - factor for constrained
2558 // factor2 - for non constrained tracks
2559 // if (Float_t(shared+1)/Float_t(found+1)>factor) - DELETE
2563 Int_t nseed = arr->GetEntriesFast();
2564 Float_t * quality = new Float_t[nseed];
2565 Int_t * indexes = new Int_t[nseed];
2569 for (Int_t i=0; i<nseed; i++) {
2570 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2575 pt->UpdatePoints(); //select first last max dens points
2576 Float_t * points = pt->GetPoints();
2577 if (points[3]<0.8) quality[i] =-1;
2578 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
2579 //prefer high momenta tracks if overlaps
2580 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
2582 TMath::Sort(nseed,quality,indexes);
2585 for (Int_t itrack=0; itrack<nseed; itrack++) {
2586 Int_t trackindex = indexes[itrack];
2587 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);
2590 if (quality[trackindex]<0){
2591 MarkSeedFree( arr->RemoveAt(trackindex) );
2596 Int_t first = Int_t(pt->GetPoints()[0]);
2597 Int_t last = Int_t(pt->GetPoints()[2]);
2598 Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
2600 Int_t found,foundable,shared;
2601 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
2602 // pt->GetClusterStatistic(0,160, found, foundable,shared,kFALSE);
2603 Bool_t itsgold =kFALSE;
2606 if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
2610 if (Float_t(shared+1)/Float_t(found+1)>factor){
2611 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
2612 if( AliTPCReconstructor::StreamLevel()>3){
2613 TTreeSRedirector &cstream = *fDebugStreamer;
2614 cstream<<"RemoveUsed"<<
2615 "iter="<<fIteration<<
2619 MarkSeedFree( arr->RemoveAt(trackindex) );
2622 if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){ //remove short tracks
2623 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
2624 if( AliTPCReconstructor::StreamLevel()>3){
2625 TTreeSRedirector &cstream = *fDebugStreamer;
2626 cstream<<"RemoveShort"<<
2627 "iter="<<fIteration<<
2631 MarkSeedFree( arr->RemoveAt(trackindex) );
2637 //if (sharedfactor>0.4) continue;
2638 if (pt->GetKinkIndexes()[0]>0) continue;
2639 //Remove tracks with undefined properties - seems
2640 if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ?
2642 for (Int_t i=first; i<last; i++) {
2643 Int_t index=pt->GetClusterIndex2(i);
2644 // if (index<0 || index&0x8000 ) continue;
2645 if (index<0 || index&0x8000 ) continue;
2646 AliTPCclusterMI *c= pt->GetClusterPointer(i);
2653 Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
2659 void AliTPCtracker::DumpClusters(Int_t iter, TObjArray *trackArray)
2662 // Dump clusters after reco
2663 // signed and unsigned cluster can be visualized
2664 // 1. Unsign all cluster
2665 // 2. Sign all used clusters
2668 Int_t nseed = trackArray->GetEntries();
2669 for (Int_t i=0; i<nseed; i++){
2670 AliTPCseed *pt=(AliTPCseed*)trackArray->UncheckedAt(i);
2674 Bool_t isKink=pt->GetKinkIndex(0)!=0;
2675 for (Int_t j=0; j<160; ++j) {
2676 Int_t index=pt->GetClusterIndex2(j);
2677 if (index<0) continue;
2678 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2680 if (isKink) c->Use(100); // kink
2681 c->Use(10); // by default usage 10
2686 for (Int_t sec=0;sec<fkNIS;sec++){
2687 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
2688 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
2689 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++){
2690 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
2691 Float_t gx[3]; cl->GetGlobalXYZ(gx);
2692 (*fDebugStreamer)<<"clDump"<<
2700 cla = fInnerSec[sec][row].GetClusters2();
2701 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++){
2702 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
2703 Float_t gx[3]; cl->GetGlobalXYZ(gx);
2704 (*fDebugStreamer)<<"clDump"<<
2715 for (Int_t sec=0;sec<fkNOS;sec++){
2716 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
2717 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
2718 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++){
2720 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
2721 cl->GetGlobalXYZ(gx);
2722 (*fDebugStreamer)<<"clDump"<<
2730 cla = fOuterSec[sec][row].GetClusters2();
2731 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++){
2733 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
2734 cl->GetGlobalXYZ(gx);
2735 (*fDebugStreamer)<<"clDump"<<
2747 void AliTPCtracker::UnsignClusters()
2750 // loop over all clusters and unsign them
2753 for (Int_t sec=0;sec<fkNIS;sec++){
2754 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
2755 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
2756 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
2757 // if (cl[icl].IsUsed(10))
2758 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2759 cla = fInnerSec[sec][row].GetClusters2();
2760 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
2761 //if (cl[icl].IsUsed(10))
2762 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2766 for (Int_t sec=0;sec<fkNOS;sec++){
2767 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
2768 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
2769 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
2770 //if (cl[icl].IsUsed(10))
2771 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2772 cla = fOuterSec[sec][row].GetClusters2();
2773 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
2774 //if (cl[icl].IsUsed(10))
2775 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2783 void AliTPCtracker::SignClusters(const TObjArray * arr, Float_t fnumber, Float_t fdensity)
2786 //sign clusters to be "used"
2788 // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
2789 // loop over "primaries"
2803 Int_t nseed = arr->GetEntriesFast();
2804 for (Int_t i=0; i<nseed; i++) {
2805 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2809 if (!(pt->IsActive())) continue;
2810 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
2811 if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
2813 sumdens2+= dens*dens;
2814 sumn += pt->GetNumberOfClusters();
2815 sumn2 += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
2816 Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
2819 sumchi2 +=chi2*chi2;
2824 Float_t mdensity = 0.9;
2825 Float_t meann = 130;
2826 Float_t meanchi = 1;
2827 Float_t sdensity = 0.1;
2828 Float_t smeann = 10;
2829 Float_t smeanchi =0.4;
2833 mdensity = sumdens/sum;
2835 meanchi = sumchi/sum;
2837 sdensity = sumdens2/sum-mdensity*mdensity;
2839 sdensity = TMath::Sqrt(sdensity);
2843 smeann = sumn2/sum-meann*meann;
2845 smeann = TMath::Sqrt(smeann);
2849 smeanchi = sumchi2/sum - meanchi*meanchi;
2851 smeanchi = TMath::Sqrt(smeanchi);
2857 //REMOVE SHORT DELTAS or tracks going out of sensitive volume of TPC
2859 for (Int_t i=0; i<nseed; i++) {
2860 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2864 if (pt->GetBSigned()) continue;
2865 if (pt->GetBConstrain()) continue;
2866 //if (!(pt->IsActive())) continue;
2868 Int_t found,foundable,shared;
2869 pt->GetClusterStatistic(0,160,found, foundable,shared);
2870 if (shared/float(found)>0.3) {
2871 if (shared/float(found)>0.9 ){
2872 //MarkSeedFree( arr->RemoveAt(i) );
2877 Bool_t isok =kFALSE;
2878 if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
2880 if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
2882 if (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
2884 if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
2888 for (Int_t j=0; j<160; ++j) {
2889 Int_t index=pt->GetClusterIndex2(j);
2890 if (index<0) continue;
2891 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2893 //if (!(c->IsUsed(10))) c->Use();
2900 Double_t maxchi = meanchi+2.*smeanchi;
2902 for (Int_t i=0; i<nseed; i++) {
2903 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2907 //if (!(pt->IsActive())) continue;
2908 if (pt->GetBSigned()) continue;
2909 Double_t chi = pt->GetChi2()/pt->GetNumberOfClusters();
2910 if (chi>maxchi) continue;
2913 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
2915 //sign only tracks with enoug big density at the beginning
2917 if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue;
2920 Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
2921 Double_t minn = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
2923 // if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
2924 if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
2927 if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
2928 //Int_t noc=pt->GetNumberOfClusters();
2929 pt->SetBSigned(kTRUE);
2930 for (Int_t j=0; j<160; ++j) {
2932 Int_t index=pt->GetClusterIndex2(j);
2933 if (index<0) continue;
2934 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2936 // if (!(c->IsUsed(10))) c->Use();
2941 // gLastCheck = nseed;
2950 Int_t AliTPCtracker::RefitInward(AliESDEvent *event)
2953 // back propagation of ESD tracks
2956 if (!event) return 0;
2957 const Int_t kMaxFriendTracks=2000;
2960 // extract correction object for multiplicity dependence of dEdx
2961 TObjArray * gainCalibArray = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(event->GetRunNumber());
2963 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
2965 AliFatal("Tranformations not in RefitInward");
2968 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
2969 const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
2970 Int_t nContribut = event->GetNumberOfTracks();
2971 TGraphErrors * graphMultDependenceDeDx = 0x0;
2972 if (recoParam && recoParam->GetUseMultiplicityCorrectionDedx() && gainCalibArray) {
2973 if (recoParam->GetUseTotCharge()) {
2974 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2976 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2982 //PrepareForProlongation(fSeeds,1);
2983 PropagateForward2(fSeeds);
2984 RemoveUsed2(fSeeds,0.4,0.4,20);
2986 TObjArray arraySeed(fSeeds->GetEntries());
2987 for (Int_t i=0;i<fSeeds->GetEntries();i++) {
2988 arraySeed.AddAt(fSeeds->At(i),i);
2990 SignShared(&arraySeed);
2991 // FindCurling(fSeeds, event,2); // find multi found tracks
2992 FindSplitted(fSeeds, event,2); // find multi found tracks
2993 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,2); // find multi found tracks
2996 Int_t nseed = fSeeds->GetEntriesFast();
2997 for (Int_t i=0;i<nseed;i++){
2998 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2999 if (!seed) continue;
3000 if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
3001 AliESDtrack *esd=event->GetTrack(i);
3003 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
3004 AliExternalTrackParam paramIn;
3005 AliExternalTrackParam paramOut;
3006 Int_t ncl = seed->RefitTrack(seed,¶mIn,¶mOut);
3007 if (AliTPCReconstructor::StreamLevel()>2) {
3008 (*fDebugStreamer)<<"RecoverIn"<<
3012 "pout.="<<¶mOut<<
3017 seed->Set(paramIn.GetX(),paramIn.GetAlpha(),paramIn.GetParameter(),paramIn.GetCovariance());
3018 seed->SetNumberOfClusters(ncl);
3022 seed->PropagateTo(fkParam->GetInnerRadiusLow());
3023 seed->UpdatePoints();
3024 AddCovariance(seed);
3025 MakeESDBitmaps(seed, esd);
3026 seed->CookdEdx(0.02,0.6);
3027 CookLabel(seed,0.1); //For comparison only
3029 if (AliTPCReconstructor::StreamLevel()>1 && seed!=0) {
3030 TTreeSRedirector &cstream = *fDebugStreamer;
3037 if (seed->GetNumberOfClusters()>15){
3038 esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
3039 esd->SetTPCPoints(seed->GetPoints());
3040 esd->SetTPCPointsF(seed->GetNFoundable());
3041 Int_t ndedx = seed->GetNCDEDX(0);
3042 Float_t sdedx = seed->GetSDEDX(0);
3043 Float_t dedx = seed->GetdEdx();
3044 // apply mutliplicity dependent dEdx correction if available
3045 if (graphMultDependenceDeDx) {
3046 Double_t corrGain = AliTPCcalibDButil::EvalGraphConst(graphMultDependenceDeDx, nContribut);
3047 dedx += (1 - corrGain)*50.; // MIP is normalized to 50
3049 esd->SetTPCsignal(dedx, sdedx, ndedx);
3051 // fill new dEdx information
3053 Double32_t signal[4];
3054 Double32_t signalMax[4];
3058 for(Int_t iarr=0;iarr<3;iarr++) {
3059 signal[iarr] = seed->GetDEDXregion(iarr+1);
3060 signalMax[iarr] = seed->GetDEDXregion(iarr+5);
3061 ncl[iarr] = seed->GetNCDEDX(iarr+1);
3062 nrows[iarr] = seed->GetNCDEDXInclThres(iarr+1);
3064 signal[3] = seed->GetDEDXregion(4);
3065 signalMax[3] = seed->GetDEDXregion(8);
3068 AliTPCdEdxInfo * infoTpcPid = new AliTPCdEdxInfo();
3069 infoTpcPid->SetTPCSignalRegionInfo(signal, ncl, nrows);
3070 infoTpcPid->SetTPCSignalsQmax(signalMax);
3071 esd->SetTPCdEdxInfo(infoTpcPid);
3073 // add seed to the esd track in Calib level
3075 Bool_t storeFriend = gRandom->Rndm()<(kMaxFriendTracks)/Float_t(nseed);
3076 if (AliTPCReconstructor::StreamLevel()>0 &&storeFriend){
3077 // RS: this is the only place where the seed is created not in the pool,
3078 // since it should belong to ESDevent
3079 AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE);
3080 esd->AddCalibObject(seedCopy);
3085 //printf("problem\n");
3088 //FindKinks(fSeeds,event);
3089 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(2,fSeeds);
3090 Info("RefitInward","Number of refitted tracks %d",ntracks);
3092 AliCosmicTracker::FindCosmic(event, kTRUE);
3094 FillClusterOccupancyInfo();
3100 Int_t AliTPCtracker::PropagateBack(AliESDEvent *event)
3103 // back propagation of ESD tracks
3105 if (!event) return 0;
3110 PropagateBack(fSeeds);
3111 RemoveUsed2(fSeeds,0.4,0.4,20);
3112 //FindCurling(fSeeds, fEvent,1);
3113 FindSplitted(fSeeds, event,1); // find multi found tracks
3114 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,1); // find multi found tracks
3117 Int_t nseed = fSeeds->GetEntriesFast();
3119 for (Int_t i=0;i<nseed;i++){
3120 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
3121 if (!seed) continue;
3122 if (seed->GetKinkIndex(0)<0) UpdateKinkQualityM(seed); // update quality informations for kinks
3123 seed->UpdatePoints();
3124 AddCovariance(seed);
3125 AliESDtrack *esd=event->GetTrack(i);
3126 if (!esd) continue; //never happen
3127 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
3128 AliExternalTrackParam paramIn;
3129 AliExternalTrackParam paramOut;
3130 Int_t ncl = seed->RefitTrack(seed,¶mIn,¶mOut);
3131 if (AliTPCReconstructor::StreamLevel()>2) {
3132 (*fDebugStreamer)<<"RecoverBack"<<
3136 "pout.="<<¶mOut<<
3141 seed->Set(paramOut.GetX(),paramOut.GetAlpha(),paramOut.GetParameter(),paramOut.GetCovariance());
3142 seed->SetNumberOfClusters(ncl);
3145 seed->CookdEdx(0.02,0.6);
3146 CookLabel(seed,0.1); //For comparison only
3147 if (seed->GetNumberOfClusters()>15){
3148 esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
3149 esd->SetTPCPoints(seed->GetPoints());
3150 esd->SetTPCPointsF(seed->GetNFoundable());
3151 Int_t ndedx = seed->GetNCDEDX(0);
3152 Float_t sdedx = seed->GetSDEDX(0);
3153 Float_t dedx = seed->GetdEdx();
3154 esd->SetTPCsignal(dedx, sdedx, ndedx);
3156 Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
3157 // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
3158 if (AliTPCReconstructor::StreamLevel()>1 && esd) {
3159 (*fDebugStreamer)<<"Cback"<<
3162 "EventNrInFile="<<eventnumber<<
3167 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(1,fSeeds);
3168 //FindKinks(fSeeds,event);
3169 Info("PropagateBack","Number of back propagated tracks %d",ntracks);
3177 Int_t AliTPCtracker::PostProcess(AliESDEvent *event)
3180 // Post process events
3182 if (!event) return 0;
3185 // Set TPC event status
3188 // event affected by HV dip
3190 if(IsTPCHVDipEvent(event)) {
3191 event->ResetDetectorStatus(AliDAQ::kTPC);
3194 //printf("Status %d \n", event->IsDetectorOn(AliDAQ::kTPC));
3200 void AliTPCtracker::DeleteSeeds()
3209 void AliTPCtracker::ReadSeeds(const AliESDEvent *const event, Int_t direction)
3212 //read seeds from the event
3214 Int_t nentr=event->GetNumberOfTracks();
3216 Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
3221 fSeeds = new TObjArray(nentr);
3225 for (Int_t i=0; i<nentr; i++) {
3226 AliESDtrack *esd=event->GetTrack(i);
3227 ULong_t status=esd->GetStatus();
3228 if (!(status&AliESDtrack::kTPCin)) continue;
3229 AliTPCtrack t(*esd);
3230 t.SetNumberOfClusters(0);
3231 // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
3232 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(t/*,t.GetAlpha()*/);
3233 seed->SetPoolID(fLastSeedID);
3234 seed->SetUniqueID(esd->GetID());
3235 AddCovariance(seed); //add systematic ucertainty
3236 for (Int_t ikink=0;ikink<3;ikink++) {
3237 Int_t index = esd->GetKinkIndex(ikink);
3238 seed->GetKinkIndexes()[ikink] = index;
3239 if (index==0) continue;
3240 index = TMath::Abs(index);
3241 AliESDkink * kink = fEvent->GetKink(index-1);
3242 if (kink&&esd->GetKinkIndex(ikink)<0){
3243 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
3244 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,0);
3246 if (kink&&esd->GetKinkIndex(ikink)>0){
3247 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
3248 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,4);
3252 if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.);
3253 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
3254 //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
3255 // fSeeds->AddAt(0,i);
3256 // MarkSeedFree( seed );
3262 // rotate to the local coordinate system
3264 fSectors=fInnerSec; fN=fkNIS;
3265 Double_t alpha=seed->GetAlpha();
3266 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
3267 if (alpha < 0. ) alpha += 2.*TMath::Pi();
3268 Int_t ns=Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
3269 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
3270 alpha-=seed->GetAlpha();
3271 if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
3272 if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
3273 if (TMath::Abs(alpha) > 0.001) { // This should not happen normally
3274 AliWarning(Form("Rotating track over %f",alpha));
3275 if (!seed->Rotate(alpha)) {
3276 MarkSeedFree( seed );
3282 if (esd->GetKinkIndex(0)<=0){
3283 for (Int_t irow=0;irow<160;irow++){
3284 Int_t index = seed->GetClusterIndex2(irow);
3287 AliTPCclusterMI * cl = GetClusterMI(index);
3288 seed->SetClusterPointer(irow,cl);
3290 if ((index & 0x8000)==0){
3291 cl->Use(10); // accepted cluster
3293 cl->Use(6); // close cluster not accepted
3296 Info("ReadSeeds","Not found cluster");
3301 fSeeds->AddAt(seed,i);
3307 //_____________________________________________________________________________
3308 void AliTPCtracker::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
3309 Float_t deltay, Int_t ddsec) {
3310 //-----------------------------------------------------------------
3311 // This function creates track seeds.
3312 // SEEDING WITH VERTEX CONSTRAIN
3313 //-----------------------------------------------------------------
3314 // cuts[0] - fP4 cut
3315 // cuts[1] - tan(phi) cut
3316 // cuts[2] - zvertex cut
3317 // cuts[3] - fP3 cut
3325 Double_t x[5], c[15];
3326 // Int_t di = i1-i2;
3328 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed();
3329 seed->SetPoolID(fLastSeedID);
3330 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
3331 Double_t cs=cos(alpha), sn=sin(alpha);
3333 // Double_t x1 =fOuterSec->GetX(i1);
3334 //Double_t xx2=fOuterSec->GetX(i2);
3336 Double_t x1 =GetXrow(i1);
3337 Double_t xx2=GetXrow(i2);
3339 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
3341 Int_t imiddle = (i2+i1)/2; //middle pad row index
3342 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
3343 const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
3347 const AliTPCtrackerRow& kr1=GetRow(ns,i1);
3348 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
3349 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
3352 // change cut on curvature if it can't reach this layer
3353 // maximal curvature set to reach it
3354 Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
3355 if (dvertexmax*0.5*cuts[0]>0.85){
3356 cuts[0] = 0.85/(dvertexmax*0.5+1.);
3358 Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
3361 if (deltay>0) ddsec = 0;
3362 // loop over clusters
3363 for (Int_t is=0; is < kr1; is++) {
3365 if (kr1[is]->IsUsed(10)) continue;
3366 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3367 //if (TMath::Abs(y1)>ymax) continue;
3369 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3371 // find possible directions
3372 Float_t anglez = (z1-z3)/(x1-x3);
3373 Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
3376 //find rotation angles relative to line given by vertex and point 1
3377 Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
3378 Double_t dvertex = TMath::Sqrt(dvertex2);
3379 Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
3380 Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
3383 // loop over 2 sectors
3389 Double_t dddz1=0; // direction of delta inclination in z axis
3396 for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
3397 Int_t sec2 = sec + dsec;
3399 // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
3400 //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
3401 AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
3402 AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
3403 Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
3404 Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
3406 // rotation angles to p1-p3
3407 Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
3408 Double_t x2, y2, z2;
3410 // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
3413 Double_t dxx0 = (xx2-x3)*cs13r;
3414 Double_t dyy0 = (xx2-x3)*sn13r;
3415 for (Int_t js=index1; js < index2; js++) {
3416 const AliTPCclusterMI *kcl = kr2[js];
3417 if (kcl->IsUsed(10)) continue;
3419 //calcutate parameters
3421 Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
3423 if (TMath::Abs(yy0)<0.000001) continue;
3424 Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
3425 Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
3426 Double_t r02 = (0.25+y0*y0)*dvertex2;
3427 //curvature (radius) cut
3428 if (r02<r2min) continue;
3432 Double_t c0 = 1/TMath::Sqrt(r02);
3436 //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
3437 //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
3438 Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
3439 Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
3442 Double_t z0 = kcl->GetZ();
3443 Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
3444 if (TMath::Abs(zzzz2-z0)>0.5) continue;
3447 Double_t dip = (z1-z0)*c0/dfi1;
3448 Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
3459 x2= xx2*cs-y2*sn*dsec;
3460 y2=+xx2*sn*dsec+y2*cs;
3470 // do we have cluster at the middle ?
3472 GetProlongation(x1,xm,x,ym,zm);
3474 AliTPCclusterMI * cm=0;
3475 if (TMath::Abs(ym)-ymaxm<0){
3476 cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3477 if ((!cm) || (cm->IsUsed(10))) {
3482 // rotate y1 to system 0
3483 // get state vector in rotated system
3484 Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
3485 Double_t xr2 = x0*cs+yr1*sn*dsec;
3486 Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3488 GetProlongation(xx2,xm,xr,ym,zm);
3489 if (TMath::Abs(ym)-ymaxm<0){
3490 cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3491 if ((!cm) || (cm->IsUsed(10))) {
3498 // Double_t dym = 0;
3499 // Double_t dzm = 0;
3501 // dym = ym - cm->GetY();
3502 // dzm = zm - cm->GetZ();
3509 Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
3510 Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
3511 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
3512 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3513 //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;