PWGPP-69 - initialize additional dEdx information diring tracking itteration 0 -...
[u/mrichter/AliRoot.git] / TPC / Rec / AliTPCtracker.cxx
CommitLineData
1c53abe2 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
1c53abe2 16
17//-------------------------------------------------------
18// Implementation of the TPC tracker
19//
20// Origin: Marian Ivanov Marian.Ivanov@cern.ch
21//
34acb742 22// AliTPC parallel tracker
6d493ea0 23//
dee67df8 24// The track fitting is based on Kalman filtering approach
6d493ea0 25
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
31
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) ...
35
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)
39
40// Repeating several seeding - tracking procedures some of the tracks can be find
41// several times.
42
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
53//
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
59// low efficiency
60//
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)
66//
67//
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
16299eac 70// use AliTPCReconstructor::SetStreamLevel(n);
6d493ea0 71//
72// The debug level - different procedure produce tree for numerical debugging
73// To enable them set AliTPCReconstructor::SetStreamLevel(n); where nis bigger 1
74//
92f513f5 75
76//
77// Adding systematic errors to the covariance:
78//
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
b87c2bbc 82// The systematic errors are expressed there in RMS - position (cm), angle (rad), curvature (1/GeV)
92f513f5 83// The default values are 0.
84//
85// The sytematic errors are added to the covariance matrix in following places:
86//
829455ad 87// 1. During fisrt itteration - AliTPCtracker::FillESD
92f513f5 88// 2. Second iteration -
829455ad 89// 2.a ITS->TPC - AliTPCtracker::ReadSeeds
90// 2.b TPC->TRD - AliTPCtracker::PropagateBack
92f513f5 91// 3. Third iteration -
829455ad 92// 3.a TRD->TPC - AliTPCtracker::ReadSeeds
93// 3.b TPC->ITS - AliTPCtracker::RefitInward
92f513f5 94//
fd065ea2 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
97//
16299eac 98// 1. ErrParam stream - dump information about
fd065ea2 99// 1.a) cluster
100// 2.a) cluster error estimate
101// 3.a) cluster shape estimate
102//
103//
16299eac 104// Debug streamer levels:
105//
1c53abe2 106//-------------------------------------------------------
47966a6d 107
108
109/* $Id$ */
110
cc5e9db0 111#include "Riostream.h"
6d171107 112#include <TClonesArray.h>
113#include <TFile.h>
114#include <TObjArray.h>
115#include <TTree.h>
6d64657a 116#include <TGraphErrors.h>
661f340b 117#include <TTimeStamp.h>
a3232aae 118#include "AliLog.h"
47966a6d 119#include "AliComplexCluster.h"
af885e0f 120#include "AliESDEvent.h"
aad72f45 121#include "AliESDtrack.h"
122#include "AliESDVertex.h"
6c94f330 123#include "AliKink.h"
124#include "AliV0.h"
91162307 125#include "AliHelix.h"
91162307 126#include "AliRunLoader.h"
6d171107 127#include "AliTPCClustersRow.h"
128#include "AliTPCParam.h"
9996a03b 129#include "AliTPCReconstructor.h"
6d171107 130#include "AliTPCpolyTrack.h"
81e97e0d 131#include "AliTPCreco.h"
9350f379 132#include "AliTPCseed.h"
133
134#include "AliTPCtrackerSector.h"
829455ad 135#include "AliTPCtracker.h"
6d171107 136#include "TStopwatch.h"
81e97e0d 137#include "AliTPCReconstructor.h"
5d837844 138#include "AliAlignObj.h"
139#include "AliTrackPointArray.h"
6d493ea0 140#include "TRandom.h"
24db6af7 141#include "AliTPCcalibDB.h"
6d64657a 142#include "AliTPCcalibDButil.h"
24db6af7 143#include "AliTPCTransform.h"
fd065ea2 144#include "AliTPCClusterParam.h"
64bf5ca0 145#include "AliTPCdEdxInfo.h"
ec7e4ad6 146#include "AliDCSSensorArray.h"
147#include "AliDCSSensor.h"
148#include "AliDAQ.h"
3aa6a136 149#include "AliCosmicTracker.h"
ddfbc51a 150
6d171107 151//
c9427e08 152
a11596ad 153using std::cerr;
154using std::endl;
829455ad 155ClassImp(AliTPCtracker)
c9427e08 156
157
002af263 158
b67e07dc 159class AliTPCFastMath {
91162307 160public:
b67e07dc 161 AliTPCFastMath();
91162307 162 static Double_t FastAsin(Double_t x);
163 private:
b67e07dc 164 static Double_t fgFastAsin[20000]; //lookup table for fast asin computation
91162307 165};
c9427e08 166
b67e07dc 167Double_t AliTPCFastMath::fgFastAsin[20000];
2274b54b 168AliTPCFastMath gAliTPCFastMath; // needed to fill the LUT
c9427e08 169
b67e07dc 170AliTPCFastMath::AliTPCFastMath(){
171 //
172 // initialized lookup table;
91162307 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]);
176 }
c9427e08 177}
178
b67e07dc 179Double_t AliTPCFastMath::FastAsin(Double_t x){
180 //
181 // return asin using lookup table
91162307 182 if (x>0){
183 Int_t index = int(x*10000);
184 return fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1];
185 }
186 x*=-1;
187 Int_t index = int(x*10000);
188 return -(fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1]);
1c53abe2 189}
e046d791 190//__________________________________________________________________
829455ad 191AliTPCtracker::AliTPCtracker()
e046d791 192 :AliTracker(),
193 fkNIS(0),
194 fInnerSec(0),
195 fkNOS(0),
196 fOuterSec(0),
197 fN(0),
198 fSectors(0),
199 fInput(0),
200 fOutput(0),
201 fSeedTree(0),
202 fTreeDebug(0),
203 fEvent(0),
72e25240 204 fEventHLT(0),
e046d791 205 fDebug(0),
206 fNewIO(kFALSE),
207 fNtracks(0),
208 fSeeds(0),
209 fIteration(0),
47af7ca4 210 fkParam(0),
1598ba75 211 fDebugStreamer(0),
f06a1ff6 212 fUseHLTClusters(4),
213 fSeedsPool(0),
ddfbc51a 214 fFreeSeedsID(500),
215 fNFreeSeeds(0),
216 fLastSeedID(-1)
e046d791 217{
218 //
219 // default constructor
220 //
0f923679 221 for (Int_t irow=0; irow<200; irow++){
222 fXRow[irow]=0;
223 fYMax[irow]=0;
224 fPadLength[irow]=0;
225 }
226
e046d791 227}
228//_____________________________________________________________________
1c53abe2 229
230
231
829455ad 232Int_t AliTPCtracker::UpdateTrack(AliTPCseed * track, Int_t accept){
b67e07dc 233 //
234 //update track information using current cluster - track->fCurrentCluster
235
1c53abe2 236
b9671574 237 AliTPCclusterMI* c =track->GetCurrentCluster();
f124f8bf 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);
b9671574 242 UInt_t i = track->GetCurrentClusterIndex1();
1c53abe2 243
244 Int_t sec=(i&0xff000000)>>24;
91162307 245 //Int_t row = (i&0x00ff0000)>>16;
b9671574 246 track->SetRow((i&0x00ff0000)>>16);
247 track->SetSector(sec);
1c53abe2 248 // Int_t index = i&0xFFFF;
47af7ca4 249 if (sec>=fkParam->GetNInnerSector()) track->SetRow(track->GetRow()+fkParam->GetNRowLow());
b9671574 250 track->SetClusterIndex2(track->GetRow(), i);
91162307 251 //track->fFirstPoint = row;
252 //if ( track->fLastPoint<row) track->fLastPoint =row;
253 // if (track->fRow<0 || track->fRow>160) {
254 // printf("problem\n");
255 //}
b9671574 256 if (track->GetFirstPoint()>track->GetRow())
257 track->SetFirstPoint(track->GetRow());
258 if (track->GetLastPoint()<track->GetRow())
259 track->SetLastPoint(track->GetRow());
91162307 260
261
b9671574 262 track->SetClusterPointer(track->GetRow(),c);
1c53abe2 263 //
264
3f82c4f2 265 Double_t angle2 = track->GetSnp()*track->GetSnp();
1c53abe2 266 //
267 //SET NEW Track Point
268 //
85e2b57d 269 if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
91162307 270 {
85e2b57d 271 angle2 = TMath::Sqrt(angle2/(1-angle2));
b9671574 272 AliTPCTrackerPoint &point =*(track->GetTrackPoint(track->GetRow()));
1c53abe2 273 //
b9671574 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()));
1c53abe2 278 //
91162307 279 point.SetX(track->GetX());
280 point.SetY(track->GetY());
281 point.SetZ(track->GetZ());
282 point.SetAngleY(angle2);
283 point.SetAngleZ(track->GetTgl());
b9671574 284 if (point.IsShared()){
285 track->SetErrorY2(track->GetErrorY2()*4);
286 track->SetErrorZ2(track->GetErrorZ2()*4);
91162307 287 }
288 }
289
b9671574 290 Double_t chi2 = track->GetPredictedChi2(track->GetCurrentCluster());
91162307 291 //
1d91d749 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);
91162307 296 //}
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) ;
303 //}
1c53abe2 304 }
518f85b7 305 if (AliTPCReconstructor::StreamLevel()>5) {
bda5ad6d 306 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
307 AliExternalTrackParam param(*track);
308 TTreeSRedirector &cstream = *fDebugStreamer;
309 cstream<<"Update"<<
310 "cl.="<<c<<
311 "track.="<<&param<<
312 "\n";
313 }
b9671574 314 track->SetNoCluster(0);
91162307 315 return track->Update(c,chi2,i);
316}
317
318
319
829455ad 320Int_t AliTPCtracker::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster)
91162307 321{
1c53abe2 322 //
91162307 323 // decide according desired precision to accept given
324 // cluster for tracking
6fbe1e5c 325 Double_t yt=0,zt=0;
326 seed->GetProlongation(cluster->GetX(),yt,zt);
00055a22 327 Double_t sy2=ErrY2(seed,cluster);
328 Double_t sz2=ErrZ2(seed,cluster);
1c53abe2 329
91162307 330 Double_t sdistancey2 = sy2+seed->GetSigmaY2();
331 Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
6fbe1e5c 332 Double_t dy=seed->GetCurrentCluster()->GetY()-yt;
f47588e0 333 Double_t dz=seed->GetCurrentCluster()->GetZ()-zt;
6fbe1e5c 334 Double_t rdistancey2 = (seed->GetCurrentCluster()->GetY()-yt)*
335 (seed->GetCurrentCluster()->GetY()-yt)/sdistancey2;
336 Double_t rdistancez2 = (seed->GetCurrentCluster()->GetZ()-zt)*
337 (seed->GetCurrentCluster()->GetZ()-zt)/sdistancez2;
91162307 338
339 Double_t rdistance2 = rdistancey2+rdistancez2;
340 //Int_t accept =0;
341
f5a565c3 342 if (AliTPCReconstructor::StreamLevel()>2 && ( (fIteration>0)|| (seed->GetNumberOfClusters()>20))) {
a9ff2f09 343 // if (AliTPCReconstructor::StreamLevel()>2 && seed->GetNumberOfClusters()>20) {
fd065ea2 344 Float_t rmsy2 = seed->GetCurrentSigmaY2();
345 Float_t rmsz2 = seed->GetCurrentSigmaZ2();
e0e13b88 346 Float_t rmsy2p30 = seed->GetCMeanSigmaY2p30();
347 Float_t rmsz2p30 = seed->GetCMeanSigmaZ2p30();
42aec1f1 348 Float_t rmsy2p30R = seed->GetCMeanSigmaY2p30R();
349 Float_t rmsz2p30R = seed->GetCMeanSigmaZ2p30R();
6fbe1e5c 350 AliExternalTrackParam param(*seed);
eea6b724 351 static TVectorD gcl(3),gtr(3);
352 Float_t gclf[3];
353 param.GetXYZ(gcl.GetMatrixArray());
354 cluster->GetGlobalXYZ(gclf);
355 gcl[0]=gclf[0]; gcl[1]=gclf[1]; gcl[2]=gclf[2];
a9ff2f09 356 Int_t nclSeed=seed->GetNumberOfClusters();
b194b32c 357
16299eac 358 if (AliTPCReconstructor::StreamLevel()>2) {
fd065ea2 359 (*fDebugStreamer)<<"ErrParam"<<
498b9441 360 "iter="<<fIteration<<
e0e13b88 361 "Cl.="<<cluster<<
a9ff2f09 362 "nclSeed="<<nclSeed<<
e0e13b88 363 "T.="<<&param<<
6fbe1e5c 364 "dy="<<dy<<
365 "dz="<<dz<<
366 "yt="<<yt<<
367 "zt="<<zt<<
eea6b724 368 "gcl.="<<&gcl<<
369 "gtr.="<<&gtr<<
e0e13b88 370 "erry2="<<sy2<<
371 "errz2="<<sz2<<
372 "rmsy2="<<rmsy2<<
373 "rmsz2="<<rmsz2<<
374 "rmsy2p30="<<rmsy2p30<<
375 "rmsz2p30="<<rmsz2p30<<
42aec1f1 376 "rmsy2p30R="<<rmsy2p30R<<
377 "rmsz2p30R="<<rmsz2p30R<<
f47588e0 378 // normalize distance -
379 "rdisty="<<rdistancey2<<
380 "rdistz="<<rdistancez2<<
381 "rdist="<<rdistance2<< //
e0e13b88 382 "\n";
b194b32c 383 }
fd065ea2 384 }
6fbe1e5c 385 //return 0; // temporary
386 if (rdistance2>32) return 3;
91162307 387
388
00055a22 389 if ((rdistancey2>9. || rdistancez2>9.) && cluster->GetType()==0)
91162307 390 return 2; //suspisiouce - will be changed
391
00055a22 392 if ((rdistancey2>6.25 || rdistancez2>6.25) && cluster->GetType()>0)
91162307 393 // strict cut on overlaped cluster
394 return 2; //suspisiouce - will be changed
1c53abe2 395
00055a22 396 if ( (rdistancey2>1. || rdistancez2>6.25 )
91162307 397 && cluster->GetType()<0){
b9671574 398 seed->SetNFoundable(seed->GetNFoundable()-1);
91162307 399 return 2;
1c53abe2 400 }
19dcf504 401
1598ba75 402 if (fUseHLTClusters == 3 || fUseHLTClusters == 4) {
36b89541 403 if (fIteration==2){
404 if(!AliTPCReconstructor::GetRecoParam()->GetUseHLTOnePadCluster()) {
405 if (TMath::Abs(cluster->GetSigmaY2()) < kAlmost0)
406 return 2;
407 }
1598ba75 408 }
19dcf504 409 }
1598ba75 410
91162307 411 return 0;
412}
413
414
1c53abe2 415
1c53abe2 416
1af5da7e 417
1c53abe2 418//_____________________________________________________________________________
829455ad 419AliTPCtracker::AliTPCtracker(const AliTPCParam *par):
e046d791 420AliTracker(),
421 fkNIS(par->GetNInnerSector()/2),
422 fInnerSec(0),
423 fkNOS(par->GetNOuterSector()/2),
424 fOuterSec(0),
425 fN(0),
426 fSectors(0),
427 fInput(0),
428 fOutput(0),
429 fSeedTree(0),
430 fTreeDebug(0),
431 fEvent(0),
72e25240 432 fEventHLT(0),
e046d791 433 fDebug(0),
434 fNewIO(0),
435 fNtracks(0),
436 fSeeds(0),
437 fIteration(0),
47af7ca4 438 fkParam(0),
1598ba75 439 fDebugStreamer(0),
f06a1ff6 440 fUseHLTClusters(4),
441 fSeedsPool(0),
ddfbc51a 442 fFreeSeedsID(500),
443 fNFreeSeeds(0),
444 fLastSeedID(-1)
1c53abe2 445{
446 //---------------------------------------------------------------------
447 // The main TPC tracker constructor
448 //---------------------------------------------------------------------
9350f379 449 fInnerSec=new AliTPCtrackerSector[fkNIS];
450 fOuterSec=new AliTPCtrackerSector[fkNOS];
91162307 451
1c53abe2 452 Int_t i;
453 for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
454 for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
455
47af7ca4 456 fkParam = par;
91162307 457 Int_t nrowlow = par->GetNRowLow();
458 Int_t nrowup = par->GetNRowUp();
459
460
77f88633 461 for (i=0;i<nrowlow;i++){
91162307 462 fXRow[i] = par->GetPadRowRadiiLow(i);
463 fPadLength[i]= par->GetPadPitchLength(0,i);
464 fYMax[i] = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
465 }
466
467
77f88633 468 for (i=0;i<nrowup;i++){
91162307 469 fXRow[i+nrowlow] = par->GetPadRowRadiiUp(i);
470 fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
471 fYMax[i+nrowlow] = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
472 }
e046d791 473
b194b32c 474 if (AliTPCReconstructor::StreamLevel()>0) {
3d674021 475 fDebugStreamer = new TTreeSRedirector("TPCdebug.root","recreate");
b194b32c 476 }
f06a1ff6 477 //
ddfbc51a 478 fSeedsPool = new TClonesArray("AliTPCseed",1000);
1c53abe2 479}
2fc0c115 480//________________________________________________________________________
829455ad 481AliTPCtracker::AliTPCtracker(const AliTPCtracker &t):
58251ea0 482 AliTracker(t),
e046d791 483 fkNIS(t.fkNIS),
484 fInnerSec(0),
485 fkNOS(t.fkNOS),
486 fOuterSec(0),
487 fN(0),
488 fSectors(0),
489 fInput(0),
490 fOutput(0),
491 fSeedTree(0),
492 fTreeDebug(0),
493 fEvent(0),
72e25240 494 fEventHLT(0),
e046d791 495 fDebug(0),
496 fNewIO(kFALSE),
497 fNtracks(0),
498 fSeeds(0),
499 fIteration(0),
47af7ca4 500 fkParam(0),
1598ba75 501 fDebugStreamer(0),
f06a1ff6 502 fUseHLTClusters(4),
503 fSeedsPool(0),
ddfbc51a 504 fFreeSeedsID(500),
505 fNFreeSeeds(0),
506 fLastSeedID(-1)
58251ea0 507{
2fc0c115 508 //------------------------------------
509 // dummy copy constructor
510 //------------------------------------------------------------------
e046d791 511 fOutput=t.fOutput;
17abbffb 512 for (Int_t irow=0; irow<200; irow++){
513 fXRow[irow]=0;
514 fYMax[irow]=0;
515 fPadLength[irow]=0;
516 }
517
2fc0c115 518}
829455ad 519AliTPCtracker & AliTPCtracker::operator=(const AliTPCtracker& /*r*/)
47af7ca4 520{
2fc0c115 521 //------------------------------
522 // dummy
523 //--------------------------------------------------------------
524 return *this;
525}
1c53abe2 526//_____________________________________________________________________________
829455ad 527AliTPCtracker::~AliTPCtracker() {
1c53abe2 528 //------------------------------------------------------------------
529 // TPC tracker destructor
530 //------------------------------------------------------------------
531 delete[] fInnerSec;
532 delete[] fOuterSec;
533 if (fSeeds) {
f06a1ff6 534 fSeeds->Clear();
1c53abe2 535 delete fSeeds;
536 }
81e97e0d 537 if (fDebugStreamer) delete fDebugStreamer;
ddfbc51a 538 if (fSeedsPool) delete fSeedsPool;
1c53abe2 539}
540
1c53abe2 541
829455ad 542void AliTPCtracker::FillESD(const TObjArray* arr)
91162307 543{
47966a6d 544 //
545 //
546 //fill esds using updated tracks
ada522d7 547
ec26e231 548 if (!fEvent) return;
ada522d7 549
550 AliESDtrack iotrack;
ec26e231 551
91162307 552 // write tracks to the event
553 // store index of the track
d26d9159 554 Int_t nseed=arr->GetEntriesFast();
51ad6848 555 //FindKinks(arr,fEvent);
91162307 556 for (Int_t i=0; i<nseed; i++) {
d26d9159 557 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 558 if (!pt) continue;
51ad6848 559 pt->UpdatePoints();
92f513f5 560 AddCovariance(pt);
8cecaa87 561 if (AliTPCReconstructor::StreamLevel()>1) {
562 (*fDebugStreamer)<<"Track0"<<
563 "Tr0.="<<pt<<
564 "\n";
565 }
47af7ca4 566 // pt->PropagateTo(fkParam->GetInnerRadiusLow());
eea478d3 567 if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
47af7ca4 568 pt->PropagateTo(fkParam->GetInnerRadiusLow());
eea478d3 569 }
51ad6848 570
571 if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
ada522d7 572 iotrack.~AliESDtrack();
573 new(&iotrack) AliESDtrack;
51ad6848 574 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 575 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 576 iotrack.SetTPCPoints(pt->GetPoints());
577 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 578 iotrack.SetV0Indexes(pt->GetV0Indexes());
579 // iotrack.SetTPCpid(pt->fTPCr);
f5cbf2ef 580 //iotrack.SetTPCindex(i);
581 MakeESDBitmaps(pt, &iotrack);
51ad6848 582 fEvent->AddTrack(&iotrack);
583 continue;
584 }
585
b9671574 586 if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
ada522d7 587 iotrack.~AliESDtrack();
588 new(&iotrack) AliESDtrack;
51ad6848 589 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 590 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 591 iotrack.SetTPCPoints(pt->GetPoints());
d26d9159 592 //iotrack.SetTPCindex(i);
51ad6848 593 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 594 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 595 MakeESDBitmaps(pt, &iotrack);
81e97e0d 596 // iotrack.SetTPCpid(pt->fTPCr);
d26d9159 597 fEvent->AddTrack(&iotrack);
a42a6bae 598 continue;
599 }
51ad6848 600 //
601 // short tracks - maybe decays
602
b9671574 603 if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
a42a6bae 604 Int_t found,foundable,shared;
605 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
b9671574 606 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
ada522d7 607 iotrack.~AliESDtrack();
608 new(&iotrack) AliESDtrack;
a42a6bae 609 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 610 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
a42a6bae 611 //iotrack.SetTPCindex(i);
51ad6848 612 iotrack.SetTPCPoints(pt->GetPoints());
613 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 614 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 615 MakeESDBitmaps(pt, &iotrack);
81e97e0d 616 //iotrack.SetTPCpid(pt->fTPCr);
a42a6bae 617 fEvent->AddTrack(&iotrack);
618 continue;
619 }
620 }
621
b9671574 622 if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
a42a6bae 623 Int_t found,foundable,shared;
624 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
625 if (found<20) continue;
b9671574 626 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
a42a6bae 627 //
ada522d7 628 iotrack.~AliESDtrack();
629 new(&iotrack) AliESDtrack;
a42a6bae 630 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 631 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 632 iotrack.SetTPCPoints(pt->GetPoints());
633 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 634 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 635 MakeESDBitmaps(pt, &iotrack);
81e97e0d 636 //iotrack.SetTPCpid(pt->fTPCr);
51ad6848 637 //iotrack.SetTPCindex(i);
638 fEvent->AddTrack(&iotrack);
639 continue;
640 }
641 // short tracks - secondaties
642 //
643 if ( (pt->GetNumberOfClusters()>30) ) {
644 Int_t found,foundable,shared;
645 pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
b9671574 646 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
ada522d7 647 iotrack.~AliESDtrack();
648 new(&iotrack) AliESDtrack;
51ad6848 649 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 650 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 651 iotrack.SetTPCPoints(pt->GetPoints());
652 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 653 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 654 MakeESDBitmaps(pt, &iotrack);
81e97e0d 655 //iotrack.SetTPCpid(pt->fTPCr);
51ad6848 656 //iotrack.SetTPCindex(i);
657 fEvent->AddTrack(&iotrack);
658 continue;
659 }
660 }
661
662 if ( (pt->GetNumberOfClusters()>15)) {
663 Int_t found,foundable,shared;
664 pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
665 if (found<15) continue;
e7eb17e4 666 if (foundable<=0) continue;
b9671574 667 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
51ad6848 668 if (float(found)/float(foundable)<0.8) continue;
669 //
ada522d7 670 iotrack.~AliESDtrack();
671 new(&iotrack) AliESDtrack;
51ad6848 672 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 673 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 674 iotrack.SetTPCPoints(pt->GetPoints());
675 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 676 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 677 MakeESDBitmaps(pt, &iotrack);
81e97e0d 678 // iotrack.SetTPCpid(pt->fTPCr);
a42a6bae 679 //iotrack.SetTPCindex(i);
680 fEvent->AddTrack(&iotrack);
681 continue;
682 }
91162307 683 }
6fbe1e5c 684 // >> account for suppressed tracks in the kink indices (RS)
685 int nESDtracks = fEvent->GetNumberOfTracks();
686 for (int it=nESDtracks;it--;) {
687 AliESDtrack* esdTr = fEvent->GetTrack(it);
688 if (!esdTr || !esdTr->GetKinkIndex(0)) continue;
689 for (int ik=0;ik<3;ik++) {
690 int knkId=0;
691 if (!(knkId=esdTr->GetKinkIndex(ik))) break; // no more kinks for this track
692 AliESDkink* kink = fEvent->GetKink(TMath::Abs(knkId)-1);
693 if (!kink) {
694 AliError(Form("ESDTrack%d refers to non-existing kink %d",it,TMath::Abs(knkId)-1));
695 continue;
696 }
697 kink->SetIndex(it, knkId<0 ? 0:1); // update track index of the kink: mother at 0, daughter at 1
698 }
699 }
ada522d7 700
ec26e231 701 // << account for suppressed tracks in the kink indices (RS)
702 AliInfo(Form("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks()));
703
d26d9159 704}
705
d26d9159 706
1c53abe2 707
1c53abe2 708
709
829455ad 710Double_t AliTPCtracker::ErrY2(AliTPCseed* seed, const AliTPCclusterMI * cl){
91162307 711 //
712 //
fd065ea2 713 // Use calibrated cluster error from OCDB
91162307 714 //
fd065ea2 715 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
91162307 716 //
47af7ca4 717 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
91162307 718 Int_t ctype = cl->GetType();
fd065ea2 719 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
720 Double_t angle = seed->GetSnp()*seed->GetSnp();
e0e13b88 721 angle = TMath::Sqrt(TMath::Abs(angle/(1.-angle)));
fd065ea2 722 Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
723 if (ctype<0) {
724 erry2+=0.5; // edge cluster
725 }
726 erry2*=erry2;
0b2c141b 727 Double_t addErr=0;
728 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
f858edae 729 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
0b2c141b 730 erry2+=addErr*addErr;
fd065ea2 731 seed->SetErrorY2(erry2);
732 //
733 return erry2;
734
735//calculate look-up table at the beginning
736// static Bool_t ginit = kFALSE;
737// static Float_t gnoise1,gnoise2,gnoise3;
738// static Float_t ggg1[10000];
739// static Float_t ggg2[10000];
740// static Float_t ggg3[10000];
741// static Float_t glandau1[10000];
742// static Float_t glandau2[10000];
743// static Float_t glandau3[10000];
744// //
745// static Float_t gcor01[500];
746// static Float_t gcor02[500];
747// static Float_t gcorp[500];
748// //
91162307 749
fd065ea2 750// //
751// if (ginit==kFALSE){
752// for (Int_t i=1;i<500;i++){
753// Float_t rsigma = float(i)/100.;
754// gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
755// gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
756// gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
757// }
758
759// //
760// for (Int_t i=3;i<10000;i++){
761// //
762// //
763// // inner sector
764// Float_t amp = float(i);
765// Float_t padlength =0.75;
766// gnoise1 = 0.0004/padlength;
767// Float_t nel = 0.268*amp;
768// Float_t nprim = 0.155*amp;
47af7ca4 769// ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
fd065ea2 770// glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
771// if (glandau1[i]>1) glandau1[i]=1;
772// glandau1[i]*=padlength*padlength/12.;
773// //
774// // outer short
775// padlength =1.;
776// gnoise2 = 0.0004/padlength;
777// nel = 0.3*amp;
778// nprim = 0.133*amp;
47af7ca4 779// ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 780// glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
781// if (glandau2[i]>1) glandau2[i]=1;
782// glandau2[i]*=padlength*padlength/12.;
783// //
784// //
785// // outer long
786// padlength =1.5;
787// gnoise3 = 0.0004/padlength;
788// nel = 0.3*amp;
789// nprim = 0.133*amp;
47af7ca4 790// ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 791// glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
792// if (glandau3[i]>1) glandau3[i]=1;
793// glandau3[i]*=padlength*padlength/12.;
794// //
795// }
796// ginit = kTRUE;
797// }
798// //
799// //
800// //
801// Int_t amp = int(TMath::Abs(cl->GetQ()));
802// if (amp>9999) {
803// seed->SetErrorY2(1.);
804// return 1.;
805// }
806// Float_t snoise2;
47af7ca4 807// Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
fd065ea2 808// Int_t ctype = cl->GetType();
809// Float_t padlength= GetPadPitchLength(seed->GetRow());
810// Double_t angle2 = seed->GetSnp()*seed->GetSnp();
811// angle2 = angle2/(1-angle2);
812// //
813// //cluster "quality"
814// Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
815// Float_t res;
816// //
817// if (fSectors==fInnerSec){
818// snoise2 = gnoise1;
819// res = ggg1[amp]*z+glandau1[amp]*angle2;
820// if (ctype==0) res *= gcor01[rsigmay];
821// if ((ctype>0)){
822// res+=0.002;
823// res*= gcorp[rsigmay];
824// }
825// }
826// else {
827// if (padlength<1.1){
828// snoise2 = gnoise2;
829// res = ggg2[amp]*z+glandau2[amp]*angle2;
830// if (ctype==0) res *= gcor02[rsigmay];
831// if ((ctype>0)){
832// res+=0.002;
833// res*= gcorp[rsigmay];
834// }
835// }
836// else{
837// snoise2 = gnoise3;
838// res = ggg3[amp]*z+glandau3[amp]*angle2;
839// if (ctype==0) res *= gcor02[rsigmay];
840// if ((ctype>0)){
841// res+=0.002;
842// res*= gcorp[rsigmay];
843// }
844// }
845// }
846
847// if (ctype<0){
848// res+=0.005;
849// res*=2.4; // overestimate error 2 times
850// }
851// res+= snoise2;
1c53abe2 852
fd065ea2 853// if (res<2*snoise2)
854// res = 2*snoise2;
91162307 855
fd065ea2 856// seed->SetErrorY2(res);
857// return res;
1c53abe2 858
859
91162307 860}
861
1c53abe2 862
863
829455ad 864Double_t AliTPCtracker::ErrZ2(AliTPCseed* seed, const AliTPCclusterMI * cl){
1c53abe2 865 //
866 //
fd065ea2 867 // Use calibrated cluster error from OCDB
91162307 868 //
fd065ea2 869 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
91162307 870 //
47af7ca4 871 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
91162307 872 Int_t ctype = cl->GetType();
fd065ea2 873 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
91162307 874 //
3f82c4f2 875 Double_t angle2 = seed->GetSnp()*seed->GetSnp();
91162307 876 angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
e0e13b88 877 Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
fd065ea2 878 Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
879 if (ctype<0) {
880 errz2+=0.5; // edge cluster
91162307 881 }
1af5da7e 882 errz2*=errz2;
0b2c141b 883 Double_t addErr=0;
884 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
f858edae 885 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
0b2c141b 886 errz2+=addErr*addErr;
fd065ea2 887 seed->SetErrorZ2(errz2);
888 //
889 return errz2;
1c53abe2 890
fd065ea2 891
892
893// //seed->SetErrorY2(0.1);
894// //return 0.1;
895// //calculate look-up table at the beginning
896// static Bool_t ginit = kFALSE;
897// static Float_t gnoise1,gnoise2,gnoise3;
898// static Float_t ggg1[10000];
899// static Float_t ggg2[10000];
900// static Float_t ggg3[10000];
901// static Float_t glandau1[10000];
902// static Float_t glandau2[10000];
903// static Float_t glandau3[10000];
904// //
905// static Float_t gcor01[1000];
906// static Float_t gcor02[1000];
907// static Float_t gcorp[1000];
908// //
909
910// //
911// if (ginit==kFALSE){
912// for (Int_t i=1;i<1000;i++){
913// Float_t rsigma = float(i)/100.;
914// gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
915// gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
916// gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
917// }
918
919// //
920// for (Int_t i=3;i<10000;i++){
921// //
922// //
923// // inner sector
924// Float_t amp = float(i);
925// Float_t padlength =0.75;
926// gnoise1 = 0.0004/padlength;
927// Float_t nel = 0.268*amp;
928// Float_t nprim = 0.155*amp;
47af7ca4 929// ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
fd065ea2 930// glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
931// if (glandau1[i]>1) glandau1[i]=1;
932// glandau1[i]*=padlength*padlength/12.;
933// //
934// // outer short
935// padlength =1.;
936// gnoise2 = 0.0004/padlength;
937// nel = 0.3*amp;
938// nprim = 0.133*amp;
47af7ca4 939// ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 940// glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
941// if (glandau2[i]>1) glandau2[i]=1;
942// glandau2[i]*=padlength*padlength/12.;
943// //
944// //
945// // outer long
946// padlength =1.5;
947// gnoise3 = 0.0004/padlength;
948// nel = 0.3*amp;
949// nprim = 0.133*amp;
47af7ca4 950// ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 951// glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
952// if (glandau3[i]>1) glandau3[i]=1;
953// glandau3[i]*=padlength*padlength/12.;
954// //
955// }
956// ginit = kTRUE;
957// }
958// //
959// //
960// //
961// Int_t amp = int(TMath::Abs(cl->GetQ()));
962// if (amp>9999) {
963// seed->SetErrorY2(1.);
964// return 1.;
965// }
966// Float_t snoise2;
47af7ca4 967// Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
fd065ea2 968// Int_t ctype = cl->GetType();
969// Float_t padlength= GetPadPitchLength(seed->GetRow());
970// //
971// Double_t angle2 = seed->GetSnp()*seed->GetSnp();
972// // if (angle2<0.6) angle2 = 0.6;
973// angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
974// //
975// //cluster "quality"
976// Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
977// Float_t res;
978// //
979// if (fSectors==fInnerSec){
980// snoise2 = gnoise1;
981// res = ggg1[amp]*z+glandau1[amp]*angle2;
982// if (ctype==0) res *= gcor01[rsigmaz];
983// if ((ctype>0)){
984// res+=0.002;
985// res*= gcorp[rsigmaz];
986// }
987// }
988// else {
989// if (padlength<1.1){
990// snoise2 = gnoise2;
991// res = ggg2[amp]*z+glandau2[amp]*angle2;
992// if (ctype==0) res *= gcor02[rsigmaz];
993// if ((ctype>0)){
994// res+=0.002;
995// res*= gcorp[rsigmaz];
996// }
997// }
998// else{
999// snoise2 = gnoise3;
1000// res = ggg3[amp]*z+glandau3[amp]*angle2;
1001// if (ctype==0) res *= gcor02[rsigmaz];
1002// if ((ctype>0)){
1003// res+=0.002;
1004// res*= gcorp[rsigmaz];
1005// }
1006// }
1007// }
1008
1009// if (ctype<0){
1010// res+=0.002;
1011// res*=1.3;
1012// }
1013// if ((ctype<0) &&amp<70){
1014// res+=0.002;
1015// res*=1.3;
1016// }
1017// res += snoise2;
1018// if (res<2*snoise2)
1019// res = 2*snoise2;
1020// if (res>3) res =3;
1021// seed->SetErrorZ2(res);
1022// return res;
91162307 1023}
1024
1025
1026
c9427e08 1027
1c53abe2 1028
829455ad 1029void AliTPCtracker::RotateToLocal(AliTPCseed *seed)
c9427e08 1030{
1031 //rotate to track "local coordinata
1032 Float_t x = seed->GetX();
1033 Float_t y = seed->GetY();
1034 Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
91162307 1035
c9427e08 1036 if (y > ymax) {
b9671574 1037 seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
c9427e08 1038 if (!seed->Rotate(fSectors->GetAlpha()))
1039 return;
1040 } else if (y <-ymax) {
b9671574 1041 seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
c9427e08 1042 if (!seed->Rotate(-fSectors->GetAlpha()))
1043 return;
1044 }
1c53abe2 1045
c9427e08 1046}
1c53abe2 1047
1048
1049
1c53abe2 1050//_____________________________________________________________________________
829455ad 1051Double_t AliTPCtracker::F1old(Double_t x1,Double_t y1,
1c53abe2 1052 Double_t x2,Double_t y2,
47af7ca4 1053 Double_t x3,Double_t y3) const
1c53abe2 1054{
1055 //-----------------------------------------------------------------
1056 // Initial approximation of the track curvature
1057 //-----------------------------------------------------------------
1058 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1059 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1060 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1061 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1062 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1063
1064 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
91162307 1065 if ( xr*xr+yr*yr<=0.00000000000001) return 100;
1c53abe2 1066 return -xr*yr/sqrt(xr*xr+yr*yr);
1067}
1068
1069
91162307 1070
1c53abe2 1071//_____________________________________________________________________________
829455ad 1072Double_t AliTPCtracker::F1(Double_t x1,Double_t y1,
91162307 1073 Double_t x2,Double_t y2,
47af7ca4 1074 Double_t x3,Double_t y3) const
91162307 1075{
1076 //-----------------------------------------------------------------
1077 // Initial approximation of the track curvature
1078 //-----------------------------------------------------------------
1079 x3 -=x1;
1080 x2 -=x1;
1081 y3 -=y1;
1082 y2 -=y1;
1083 //
1084 Double_t det = x3*y2-x2*y3;
6e23caff 1085 if (TMath::Abs(det)<1e-10){
91162307 1086 return 100;
1087 }
1088 //
1089 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1090 Double_t x0 = x3*0.5-y3*u;
1091 Double_t y0 = y3*0.5+x3*u;
1092 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1093 if (det<0) c2*=-1;
1094 return c2;
1095}
1096
1097
829455ad 1098Double_t AliTPCtracker::F2(Double_t x1,Double_t y1,
1c53abe2 1099 Double_t x2,Double_t y2,
47af7ca4 1100 Double_t x3,Double_t y3) const
1c53abe2 1101{
1102 //-----------------------------------------------------------------
91162307 1103 // Initial approximation of the track curvature
1104 //-----------------------------------------------------------------
1105 x3 -=x1;
1106 x2 -=x1;
1107 y3 -=y1;
1108 y2 -=y1;
1109 //
1110 Double_t det = x3*y2-x2*y3;
6e23caff 1111 if (TMath::Abs(det)<1e-10) {
91162307 1112 return 100;
1113 }
1114 //
1115 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1116 Double_t x0 = x3*0.5-y3*u;
1117 Double_t y0 = y3*0.5+x3*u;
1118 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1119 if (det<0) c2*=-1;
1120 x0+=x1;
1121 x0*=c2;
1122 return x0;
1123}
1124
1125
1126
1127//_____________________________________________________________________________
829455ad 1128Double_t AliTPCtracker::F2old(Double_t x1,Double_t y1,
91162307 1129 Double_t x2,Double_t y2,
47af7ca4 1130 Double_t x3,Double_t y3) const
91162307 1131{
1132 //-----------------------------------------------------------------
1c53abe2 1133 // Initial approximation of the track curvature times center of curvature
1134 //-----------------------------------------------------------------
1135 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1136 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1137 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1138 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1139 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1140
1141 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1142
1143 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1144}
1145
1146//_____________________________________________________________________________
829455ad 1147Double_t AliTPCtracker::F3(Double_t x1,Double_t y1,
1c53abe2 1148 Double_t x2,Double_t y2,
47af7ca4 1149 Double_t z1,Double_t z2) const
1c53abe2 1150{
1151 //-----------------------------------------------------------------
1152 // Initial approximation of the tangent of the track dip angle
1153 //-----------------------------------------------------------------
1154 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1155}
1156
1157
829455ad 1158Double_t AliTPCtracker::F3n(Double_t x1,Double_t y1,
91162307 1159 Double_t x2,Double_t y2,
47af7ca4 1160 Double_t z1,Double_t z2, Double_t c) const
1c53abe2 1161{
91162307 1162 //-----------------------------------------------------------------
1163 // Initial approximation of the tangent of the track dip angle
1164 //-----------------------------------------------------------------
1165
1166 // Double_t angle1;
1167
1168 //angle1 = (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1c53abe2 1169 //
91162307 1170 Double_t d = TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1171 if (TMath::Abs(d*c*0.5)>1) return 0;
1172 // Double_t angle2 = TMath::ASin(d*c*0.5);
b67e07dc 1173 // Double_t angle2 = AliTPCFastMath::FastAsin(d*c*0.5);
1174 Double_t angle2 = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): AliTPCFastMath::FastAsin(d*c*0.5);
91162307 1175
1176 angle2 = (z1-z2)*c/(angle2*2.);
1177 return angle2;
1178}
1179
829455ad 1180Bool_t AliTPCtracker::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
91162307 1181{//-----------------------------------------------------------------
1182 // This function find proloncation of a track to a reference plane x=x2.
1183 //-----------------------------------------------------------------
1184
1185 Double_t dx=x2-x1;
1186
1187 if (TMath::Abs(x[4]*x1 - x[2]) >= 0.999) {
1188 return kFALSE;
1c53abe2 1189 }
f8aae377 1190
bfd20868 1191 Double_t c1=x[4]*x1 - x[2], r1=TMath::Sqrt((1.-c1)*(1.+c1));
1192 Double_t c2=x[4]*x2 - x[2], r2=TMath::Sqrt((1.-c2)*(1.+c2));
91162307 1193 y = x[0];
1194 z = x[1];
1195
1196 Double_t dy = dx*(c1+c2)/(r1+r2);
1197 Double_t dz = 0;
1198 //
1199 Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1200
1201 if (TMath::Abs(delta)>0.01){
1202 dz = x[3]*TMath::ASin(delta)/x[4];
1203 }else{
b67e07dc 1204 dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
91162307 1205 }
1206
b67e07dc 1207 //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
f8aae377 1208
91162307 1209 y+=dy;
1210 z+=dz;
1211
1212 return kTRUE;
1c53abe2 1213}
1214
829455ad 1215Int_t AliTPCtracker::LoadClusters (TTree *const tree)
d26d9159 1216{
544c295f 1217 // load clusters
d26d9159 1218 //
1219 fInput = tree;
1220 return LoadClusters();
1221}
91162307 1222
af86c1fd 1223
829455ad 1224Int_t AliTPCtracker::LoadClusters(const TObjArray *arr)
af86c1fd 1225{
1226 //
1227 // load clusters to the memory
e7de6656 1228 AliTPCClustersRow *clrow = new AliTPCClustersRow("AliTPCclusterMI");
af86c1fd 1229 Int_t lower = arr->LowerBound();
1230 Int_t entries = arr->GetEntriesFast();
77f88633 1231
af86c1fd 1232 for (Int_t i=lower; i<entries; i++) {
1233 clrow = (AliTPCClustersRow*) arr->At(i);
77f88633 1234 if(!clrow) continue;
1235 if(!clrow->GetArray()) continue;
1236
af86c1fd 1237 //
1238 Int_t sec,row;
47af7ca4 1239 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
77f88633 1240
af86c1fd 1241 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1242 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1243 }
1244 //
1245 if (clrow->GetArray()->GetEntriesFast()<=0) continue;
bd26fa83 1246 AliTPCtrackerRow * tpcrow=0;
af86c1fd 1247 Int_t left=0;
1248 if (sec<fkNIS*2){
1249 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1250 left = sec/fkNIS;
1251 }
1252 else{
1253 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1254 left = (sec-fkNIS*2)/fkNOS;
1255 }
1256 if (left ==0){
1257 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
77f88633 1258 for (Int_t j=0;j<tpcrow->GetN1();++j)
1259 tpcrow->SetCluster1(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
af86c1fd 1260 }
1261 if (left ==1){
1262 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
77f88633 1263 for (Int_t j=0;j<tpcrow->GetN2();++j)
bfa00fba 1264 tpcrow->SetCluster2(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
af86c1fd 1265 }
e7de6656 1266 clrow->GetArray()->Clear("C");
af86c1fd 1267 }
1268 //
1269 delete clrow;
1270 LoadOuterSectors();
1271 LoadInnerSectors();
1272 return 0;
1273}
1274
829455ad 1275Int_t AliTPCtracker::LoadClusters(const TClonesArray *arr)
aa7f1a5a 1276{
1277 //
1278 // load clusters to the memory from one
1279 // TClonesArray
1280 //
1281 AliTPCclusterMI *clust=0;
98ee6d31 1282 Int_t count[72][96] = { {0} , {0} };
aa7f1a5a 1283
1284 // loop over clusters
1285 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1286 clust = (AliTPCclusterMI*)arr->At(icl);
1287 if(!clust) continue;
1288 //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
1289
1290 // transform clusters
1291 Transform(clust);
1292
1293 // count clusters per pad row
1294 count[clust->GetDetector()][clust->GetRow()]++;
1295 }
1296
1297 // insert clusters to sectors
1298 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1299 clust = (AliTPCclusterMI*)arr->At(icl);
1300 if(!clust) continue;
1301
1302 Int_t sec = clust->GetDetector();
1303 Int_t row = clust->GetRow();
98ee6d31 1304
1305 // filter overlapping pad rows needed by HLT
1306 if(sec<fkNIS*2) { //IROCs
1307 if(row == 30) continue;
1308 }
1309 else { // OROCs
1310 if(row == 27 || row == 76) continue;
1311 }
1312
2a97785a 1313 // Int_t left=0;
aa7f1a5a 1314 if (sec<fkNIS*2){
2a97785a 1315 // left = sec/fkNIS;
47af7ca4 1316 fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fkParam);
aa7f1a5a 1317 }
1318 else{
2a97785a 1319 // left = (sec-fkNIS*2)/fkNOS;
47af7ca4 1320 fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fkParam);
aa7f1a5a 1321 }
1322 }
1323
98ee6d31 1324 // Load functions must be called behind LoadCluster(TClonesArray*)
1325 // needed by HLT
1326 //LoadOuterSectors();
1327 //LoadInnerSectors();
aa7f1a5a 1328
1329 return 0;
1330}
1331
af86c1fd 1332
829455ad 1333Int_t AliTPCtracker::LoadClusters()
1c53abe2 1334{
1335 //
1336 // load clusters to the memory
bfa00fba 1337 static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
91162307 1338 //
1339 // TTree * tree = fClustersArray.GetTree();
9a836cc2 1340 AliInfo("LoadClusters()\n");
91162307 1341
1342 TTree * tree = fInput;
1343 TBranch * br = tree->GetBranch("Segment");
1344 br->SetAddress(&clrow);
bad6eb00 1345
1346 // Conversion of pad, row coordinates in local tracking coords.
1347 // Could be skipped here; is already done in clusterfinder
1348
91162307 1349 Int_t j=Int_t(tree->GetEntries());
1c53abe2 1350 for (Int_t i=0; i<j; i++) {
91162307 1351 br->GetEntry(i);
1352 //
1353 Int_t sec,row;
47af7ca4 1354 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
0201b65c 1355 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
75fb37cc 1356 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
0201b65c 1357 }
91162307 1358 //
bd26fa83 1359 AliTPCtrackerRow * tpcrow=0;
91162307 1360 Int_t left=0;
1361 if (sec<fkNIS*2){
1362 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1363 left = sec/fkNIS;
1364 }
1365 else{
1366 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1367 left = (sec-fkNIS*2)/fkNOS;
1368 }
1369 if (left ==0){
b9671574 1370 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
77f88633 1371 for (Int_t k=0;k<tpcrow->GetN1();++k)
1372 tpcrow->SetCluster1(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
91162307 1373 }
1374 if (left ==1){
b9671574 1375 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
77f88633 1376 for (Int_t k=0;k<tpcrow->GetN2();++k)
bfa00fba 1377 tpcrow->SetCluster2(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
91162307 1378 }
1c53abe2 1379 }
91162307 1380 //
bfa00fba 1381 clrow->Clear("C");
91162307 1382 LoadOuterSectors();
1383 LoadInnerSectors();
832977ba 1384 if (AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection()) ApplyTailCancellation();
91162307 1385 return 0;
1c53abe2 1386}
1387
1388
829455ad 1389void AliTPCtracker::UnloadClusters()
91162307 1390{
1391 //
1392 // unload clusters from the memory
1393 //
1394 Int_t nrows = fOuterSec->GetNRows();
1395 for (Int_t sec = 0;sec<fkNOS;sec++)
1396 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1397 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
982aff31 1398 // if (tpcrow){
1399 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1400 // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1401 //}
1402 tpcrow->ResetClusters();
91162307 1403 }
1404 //
1405 nrows = fInnerSec->GetNRows();
1406 for (Int_t sec = 0;sec<fkNIS;sec++)
1407 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1408 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
982aff31 1409 //if (tpcrow){
1410 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1411 //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1412 //}
1413 tpcrow->ResetClusters();
91162307 1414 }
1415
1416 return ;
1417}
1418
829455ad 1419void AliTPCtracker::FillClusterArray(TObjArray* array) const{
002af263 1420 //
1421 // Filling cluster to the array - For visualization purposes
1422 //
1423 Int_t nrows=0;
1424 nrows = fOuterSec->GetNRows();
1425 for (Int_t sec = 0;sec<fkNOS;sec++)
1426 for (Int_t row = 0;row<nrows;row++){
1427 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1428 if (!tpcrow) continue;
1429 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1430 array->AddLast((TObject*)((*tpcrow)[icl]));
1431 }
1432 }
1433 nrows = fInnerSec->GetNRows();
1434 for (Int_t sec = 0;sec<fkNIS;sec++)
1435 for (Int_t row = 0;row<nrows;row++){
1436 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1437 if (!tpcrow) continue;
1438 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1439 array->AddLast((TObject*)(*tpcrow)[icl]);
1440 }
1441 }
1442}
1443
1444
829455ad 1445void AliTPCtracker::Transform(AliTPCclusterMI * cluster){
893468d9 1446 //
544c295f 1447 // transformation
893468d9 1448 //
3f3549a3 1449 AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1450 AliTPCTransform *transform = calibDB->GetTransform() ;
24db6af7 1451 if (!transform) {
1452 AliFatal("Tranformations not in calibDB");
ec26e231 1453 return;
24db6af7 1454 }
239f39b1 1455 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
2942f542 1456 Double_t x[3]={static_cast<Double_t>(cluster->GetRow()),static_cast<Double_t>(cluster->GetPad()),static_cast<Double_t>(cluster->GetTimeBin())};
24db6af7 1457 Int_t i[1]={cluster->GetDetector()};
022ee144 1458 transform->Transform(x,i,0,1);
afbaa016 1459 // if (cluster->GetDetector()%36>17){
1460 // x[1]*=-1;
1461 //}
022ee144 1462
24db6af7 1463 //
1464 // in debug mode check the transformation
1465 //
16299eac 1466 if (AliTPCReconstructor::StreamLevel()>2) {
af86c1fd 1467 Float_t gx[3];
1468 cluster->GetGlobalXYZ(gx);
002af263 1469 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
24db6af7 1470 TTreeSRedirector &cstream = *fDebugStreamer;
1471 cstream<<"Transform"<<
002af263 1472 "event="<<event<<
24db6af7 1473 "x0="<<x[0]<<
1474 "x1="<<x[1]<<
1475 "x2="<<x[2]<<
af86c1fd 1476 "gx0="<<gx[0]<<
1477 "gx1="<<gx[1]<<
1478 "gx2="<<gx[2]<<
24db6af7 1479 "Cl.="<<cluster<<
1480 "\n";
1481 }
1482 cluster->SetX(x[0]);
1483 cluster->SetY(x[1]);
1484 cluster->SetZ(x[2]);
19b00333 1485 // The old stuff:
0201b65c 1486 //
1487 //
1488 //
47af7ca4 1489 //if (!fkParam->IsGeoRead()) fkParam->ReadGeoMatrices();
3f3549a3 1490 if (AliTPCReconstructor::GetRecoParam()->GetUseSectorAlignment() && (!calibDB->HasAlignmentOCDB())){
1491 TGeoHMatrix *mat = fkParam->GetClusterMatrix(cluster->GetDetector());
1492 //TGeoHMatrix mat;
1493 Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1494 Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1495 if (mat) mat->LocalToMaster(pos,posC);
1496 else{
1497 // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
1498 }
1499 cluster->SetX(posC[0]);
1500 cluster->SetY(posC[1]);
1501 cluster->SetZ(posC[2]);
a7760332 1502 }
0201b65c 1503}
1c53abe2 1504
9a836cc2 1505void AliTPCtracker::ApplyTailCancellation(){
7bc5f28b 1506 //
9a836cc2 1507 // Correct the cluster charge for the ion tail effect
7bc5f28b 1508 // The TimeResponse function accessed via AliTPCcalibDB (TPC/Calib/IonTail)
1509 //
7bc5f28b 1510
9a836cc2 1511 // Retrieve
1512 TObjArray *ionTailArr = (TObjArray*)AliTPCcalibDB::Instance()->GetIonTailArray();
1513 if (!ionTailArr) {AliFatal("TPC - Missing IonTail OCDB object");}
1514 TObject *rocFactorIROC = ionTailArr->FindObject("factorIROC");
1515 TObject *rocFactorOROC = ionTailArr->FindObject("factorOROC");
1516 Float_t factorIROC = (atof(rocFactorIROC->GetTitle()));
1517 Float_t factorOROC = (atof(rocFactorOROC->GetTitle()));
1518
1519 // find the number of clusters for the whole TPC (nclALL)
1520 Int_t nclALL=0;
1521 for (Int_t isector=0; isector<36; isector++){
1522 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1523 nclALL += sector.GetNClInSector(0);
1524 nclALL += sector.GetNClInSector(1);
1525 }
1526
1527 // start looping over all clusters
1528 for (Int_t iside=0; iside<2; iside++){ // loop over sides
7bc5f28b 1529 //
1530 //
9a836cc2 1531 for (Int_t secType=0; secType<2; secType++){ //loop over inner or outer sector
1532 // cache experimantal tuning factor for the different chamber type
1533 const Float_t ampfactor = (secType==0)?factorIROC:factorOROC;
1534 std::cout << " ampfactor = " << ampfactor << std::endl;
7bc5f28b 1535 //
9a836cc2 1536 for (Int_t sec = 0;sec<fkNOS;sec++){ //loop overs sectors
1537 //
1538 //
1539 // Cache time response functions and their positons to COG of the cluster
1540 TGraphErrors ** graphRes = new TGraphErrors *[20];
1541 Float_t * indexAmpGraphs = new Float_t[20];
1542 for (Int_t icache=0; icache<20; icache++)
1543 {
1544 graphRes[icache] = NULL;
1545 indexAmpGraphs[icache] = 0;
1546 }
1547 ///////////////////////////// --> position fo sie loop
d4559772 1548 if (!AliTPCcalibDB::Instance()->GetTailcancelationGraphs(sec+36*secType+18*iside,graphRes,indexAmpGraphs))
1549 {
1550 continue;
1551 }
9a836cc2 1552
1553 AliTPCtrackerSector &sector= (secType==0)?fInnerSec[sec]:fOuterSec[sec];
1554 Int_t nrows = sector.GetNRows(); // number of rows
1555 Int_t nclSector = sector.GetNClInSector(iside); // ncl per sector to be used for debugging
1556
1557 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1558
1559 AliTPCtrackerRow& tpcrow = sector[row]; // row object
1560 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1561 if (iside>0) ncl=tpcrow.GetN2();
1562
1563 // Order clusters in time for the proper correction of ion tail
1564 Float_t qTotArray[ncl]; // arrays to be filled with modified Qtot and Qmax values in order to avoid float->int conversion
1565 Float_t qMaxArray[ncl];
1566 Int_t sortedClusterIndex[ncl];
1567 Float_t sortedClusterTimeBin[ncl];
1568 TObjArray *rowClusterArray = new TObjArray(ncl); // cache clusters for each row
1569 for (Int_t i=0;i<ncl;i++)
1570 {
1571 qTotArray[i]=0;
1572 qMaxArray[i]=0;
1573 sortedClusterIndex[i]=i;
1574 AliTPCclusterMI *rowcl= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1575 if (rowcl) {
1576 rowClusterArray->AddAt(rowcl,i);
1577 } else {
1578 rowClusterArray->RemoveAt(i);
1579 }
1580 // Fill the timebin info to the array in order to sort wrt tb
1581 if (!rowcl) {
1582 sortedClusterTimeBin[i]=0.0;
1583 } else {
1584 sortedClusterTimeBin[i] = rowcl->GetTimeBin();
1585 }
1586
1587 }
1588 TMath::Sort(ncl,sortedClusterTimeBin,sortedClusterIndex,kFALSE); // sort clusters in time
1589
1590 // Main cluster correction loops over clusters
1591 for (Int_t icl0=0; icl0<ncl;icl0++){ // first loop over clusters
1592
1593 AliTPCclusterMI *cl0= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl0]));
1594
1595 if (!cl0) continue;
1596 Int_t nclPad=0;
1597 for (Int_t icl1=0; icl1<ncl;icl1++){ // second loop over clusters
1598
1599 AliTPCclusterMI *cl1= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl1]));
1600 if (!cl1) continue;
1601 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())>4) continue; // no contribution if far away in pad direction
1602 if (cl0->GetTimeBin()<= cl1->GetTimeBin()) continue; // no contibution to the tail if later
1603 if (TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin())>600) continue; // out of the range of response function
1604
1605 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())<4) nclPad++; // count ncl for every pad for debugging
1606
1607 // Get the correction values for Qmax and Qtot and find total correction for a given cluster
1608 Double_t ionTailMax=0.;
1609 Double_t ionTailTotal=0.;
1610 GetTailValue(ampfactor,ionTailMax,ionTailTotal,graphRes,indexAmpGraphs,cl0,cl1);
1611 ionTailMax=TMath::Abs(ionTailMax);
1612 ionTailTotal=TMath::Abs(ionTailTotal);
1613 qTotArray[icl0]+=ionTailTotal;
1614 qMaxArray[icl0]+=ionTailMax;
1615
1616 // Dump some info for debugging while clusters are being corrected
518f85b7 1617 if (AliTPCReconstructor::StreamLevel()>2) {
9a836cc2 1618 TTreeSRedirector &cstream = *fDebugStreamer;
1619 if (gRandom->Rndm() > 0.999){
1620 cstream<<"IonTail"<<
1621 "cl0.=" <<cl0 << // cluster 0 (to be corrected)
1622 "cl1.=" <<cl1 << // cluster 1 (previous cluster)
1623 "ionTailTotal=" <<ionTailTotal << // ion Tail from cluster 1 contribution to cluster0
1624 "ionTailMax=" <<ionTailMax << // ion Tail from cluster 1 contribution to cluster0
1625 "\n";
1626 }
1627 }// dump the results to the debug streamer if in debug mode
1628
1629 }//end of second loop over clusters
1630
1631 // Set corrected values of the corrected cluster
1632 cl0->SetQ(TMath::Nint(Float_t(cl0->GetQ())+Float_t(qTotArray[icl0])));
1633 cl0->SetMax(TMath::Nint(Float_t(cl0->GetMax())+qMaxArray[icl0]));
1634
1635 // Dump some info for debugging after clusters are corrected
518f85b7 1636 if (AliTPCReconstructor::StreamLevel()>2) {
9a836cc2 1637 TTreeSRedirector &cstream = *fDebugStreamer;
1638 if (gRandom->Rndm() > 0.999){
1639 cstream<<"IonTailCorrected"<<
1640 "cl0.=" << cl0 << // cluster 0 with huge Qmax
1641 "ionTailTotalPerCluster=" << qTotArray[icl0] <<
1642 "ionTailMaxPerCluster=" << qMaxArray[icl0] <<
1643 "nclALL=" << nclALL <<
1644 "nclSector=" << nclSector <<
1645 "nclRow=" << ncl <<
1646 "nclPad=" << nclPad <<
1647 "row=" << row <<
1648 "sector=" << sec <<
1649 "icl0=" << icl0 <<
1650 "\n";
1651 }
1652 }// dump the results to the debug streamer if in debug mode
1653
1654 }//end of first loop over cluster
1655 delete rowClusterArray;
1656 }//end of loop over rows
1657 for (int i=0; i<20; i++) delete graphRes[i];
1658 delete [] graphRes;
1659 delete [] indexAmpGraphs;
1660
1661 }//end of loop over sectors
1662 }//end of loop over IROC/OROC
1663 }// end of side loop
7bc5f28b 1664}
9a836cc2 1665//_____________________________________________________________________________
5a516e0a 1666void AliTPCtracker::GetTailValue(Float_t ampfactor,Double_t &ionTailMax, Double_t &ionTailTotal,TGraphErrors **graphRes,Float_t *indexAmpGraphs,AliTPCclusterMI *cl0,AliTPCclusterMI *cl1){
9a836cc2 1667
1668 //
1669 // Function in order to calculate the amount of the correction to be added for a given cluster, return values are ionTailTaoltal and ionTailMax
1670 //
7bc5f28b 1671
9a836cc2 1672 const Double_t kMinPRF = 0.5; // minimal PRF width
1673 ionTailTotal = 0.; // correction value to be added to Qtot of cl0
1674 ionTailMax = 0.; // correction value to be added to Qmax of cl0
1675
1676 Float_t qTot0 = cl0->GetQ(); // cl0 Qtot info
1677 Float_t qTot1 = cl1->GetQ(); // cl1 Qtot info
1678 Int_t sectorPad = cl1->GetDetector(); // sector number
1679 Int_t padcl0 = TMath::Nint(cl0->GetPad()); // pad0
1680 Int_t padcl1 = TMath::Nint(cl1->GetPad()); // pad1
1681 Float_t padWidth = (sectorPad < 36)?0.4:0.6; // pad width in cm
1682 const Int_t deltaTimebin = TMath::Nint(TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin()))+12; //distance between pads of cl1 and cl0 increased by 12 bins
1683 Double_t rmsPad1 = (cl1->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl1->GetSigmaY2())/padWidth);
1684 Double_t rmsPad0 = (cl0->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl0->GetSigmaY2())/padWidth);
1685
a3986da2 1686
9a836cc2 1687 Double_t sumAmp1=0.;
1688 for (Int_t idelta =-2; idelta<=2;idelta++){
1689 sumAmp1+=TMath::Exp(-idelta*idelta/(2*rmsPad1));
1690 }
7bc5f28b 1691
9a836cc2 1692 Double_t sumAmp0=0.;
1693 for (Int_t idelta =-2; idelta<=2;idelta++){
1694 sumAmp0+=TMath::Exp(-idelta*idelta/(2*rmsPad0));
1695 }
7bc5f28b 1696
9a836cc2 1697 // Apply the correction --> cl1 corrects cl0 (loop over cl1's pads and find which pads of cl0 are going to be corrected)
1698 Int_t padScan=2; // +-2 pad-timebin window will be scanned
1699 for (Int_t ipad1=padcl1-padScan; ipad1<=padcl1+padScan; ipad1++) {
1700 //
1701 //
1702 Float_t deltaPad1 = TMath::Abs(cl1->GetPad()-(Float_t)ipad1);
1703 Double_t amp1 = (TMath::Exp(-(deltaPad1*deltaPad1)/(2*rmsPad1)))/sumAmp1; // normalized pad response function
1704 Float_t qTotPad1 = amp1*qTot1; // used as a factor to multipliy the response function
1705
1706 // find closest value of cl1 to COG (among the time response functions' amplitude array --> to select proper t.r.f.)
1707 Int_t ampIndex = 0;
1708 Float_t diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[0]);
1709 for (Int_t j=0;j<20;j++) {
1710 if (diffAmp > TMath::Abs(deltaPad1-indexAmpGraphs[j]) && indexAmpGraphs[j]!=0)
1711 {
1712 diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[j]);
1713 ampIndex = j;
1714 }
1715 }
1716 if (!graphRes[ampIndex]) continue;
b4742ddd 1717 if (deltaTimebin+2 >= graphRes[ampIndex]->GetN()) continue;
9a836cc2 1718 if (graphRes[ampIndex]->GetY()[deltaTimebin+2]>=0) continue;
1719
1720 for (Int_t ipad0=padcl0-padScan; ipad0<=padcl0+padScan; ipad0++) {
1721 //
1722 //
1723 if (ipad1!=ipad0) continue; // check if ipad1 channel sees ipad0 channel, if not no correction to be applied.
1724
1725 Float_t deltaPad0 = TMath::Abs(cl0->GetPad()-(Float_t)ipad0);
1726 Double_t amp0 = (TMath::Exp(-(deltaPad0*deltaPad0)/(2*rmsPad0)))/sumAmp0; // normalized pad resp function
1727 Float_t qMaxPad0 = amp0*qTot0;
1728
1729 // Add 5 timebin range contribution around the max peak (-+2 tb window)
1730 for (Int_t itb=deltaTimebin-2; itb<=deltaTimebin+2; itb++) {
1731
1732 if (itb<0) continue;
1733 if (itb>=graphRes[ampIndex]->GetN()) continue;
1734
1735 // calculate contribution to qTot
1736 Float_t tailCorr = TMath::Abs((qTotPad1*ampfactor)*(graphRes[ampIndex])->GetY()[itb]);
1737 if (ipad1!=padcl0) {
1738 ionTailTotal += TMath::Min(qMaxPad0,tailCorr); // for side pad
1739 } else {
1740 ionTailTotal += tailCorr; // for center pad
1741 }
1742 // calculate contribution to qMax
1743 if (itb == deltaTimebin && ipad1 == padcl0) ionTailMax += tailCorr;
1744
1745 } // end of tb correction loop which is applied over 5 tb range
1746
1747 } // end of cl0 loop
1748 } // end of cl1 loop
1749
1750}
7bc5f28b 1751
1c53abe2 1752//_____________________________________________________________________________
829455ad 1753Int_t AliTPCtracker::LoadOuterSectors() {
1c53abe2 1754 //-----------------------------------------------------------------
1755 // This function fills outer TPC sectors with clusters.
1756 //-----------------------------------------------------------------
91162307 1757 Int_t nrows = fOuterSec->GetNRows();
1758 UInt_t index=0;
1759 for (Int_t sec = 0;sec<fkNOS;sec++)
1760 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1761 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
91162307 1762 Int_t sec2 = sec+2*fkNIS;
1763 //left
b9671574 1764 Int_t ncl = tpcrow->GetN1();
91162307 1765 while (ncl--) {
b9671574 1766 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
91162307 1767 index=(((sec2<<8)+row)<<16)+ncl;
1768 tpcrow->InsertCluster(c,index);
1769 }
1770 //right
b9671574 1771 ncl = tpcrow->GetN2();
91162307 1772 while (ncl--) {
b9671574 1773 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
91162307 1774 index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
1775 tpcrow->InsertCluster(c,index);
1776 }
1777 //
1778 // write indexes for fast acces
1779 //
1780 for (Int_t i=0;i<510;i++)
b9671574 1781 tpcrow->SetFastCluster(i,-1);
91162307 1782 for (Int_t i=0;i<tpcrow->GetN();i++){
1783 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
b9671574 1784 tpcrow->SetFastCluster(zi,i); // write index
91162307 1785 }
1786 Int_t last = 0;
1787 for (Int_t i=0;i<510;i++){
b9671574 1788 if (tpcrow->GetFastCluster(i)<0)
1789 tpcrow->SetFastCluster(i,last);
91162307 1790 else
b9671574 1791 last = tpcrow->GetFastCluster(i);
91162307 1792 }
1793 }
1c53abe2 1794 fN=fkNOS;
1795 fSectors=fOuterSec;
91162307 1796 return 0;
1c53abe2 1797}
1798
1799
1800//_____________________________________________________________________________
829455ad 1801Int_t AliTPCtracker::LoadInnerSectors() {
1c53abe2 1802 //-----------------------------------------------------------------
1803 // This function fills inner TPC sectors with clusters.
1804 //-----------------------------------------------------------------
91162307 1805 Int_t nrows = fInnerSec->GetNRows();
1806 UInt_t index=0;
1807 for (Int_t sec = 0;sec<fkNIS;sec++)
1808 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1809 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
91162307 1810 //
1811 //left
b9671574 1812 Int_t ncl = tpcrow->GetN1();
91162307 1813 while (ncl--) {
b9671574 1814 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
91162307 1815 index=(((sec<<8)+row)<<16)+ncl;
1816 tpcrow->InsertCluster(c,index);
1817 }
1818 //right
b9671574 1819 ncl = tpcrow->GetN2();
91162307 1820 while (ncl--) {
b9671574 1821 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
91162307 1822 index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
1823 tpcrow->InsertCluster(c,index);
1824 }
1825 //
1826 // write indexes for fast acces
1827 //
1828 for (Int_t i=0;i<510;i++)
b9671574 1829 tpcrow->SetFastCluster(i,-1);
91162307 1830 for (Int_t i=0;i<tpcrow->GetN();i++){
1831 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
b9671574 1832 tpcrow->SetFastCluster(zi,i); // write index
91162307 1833 }
1834 Int_t last = 0;
1835 for (Int_t i=0;i<510;i++){
b9671574 1836 if (tpcrow->GetFastCluster(i)<0)
1837 tpcrow->SetFastCluster(i,last);
91162307 1838 else
b9671574 1839 last = tpcrow->GetFastCluster(i);
91162307 1840 }
1c53abe2 1841
91162307 1842 }
1843
1c53abe2 1844 fN=fkNIS;
1845 fSectors=fInnerSec;
91162307 1846 return 0;
1847}
1848
1849
1850
1851//_________________________________________________________________________
829455ad 1852AliTPCclusterMI *AliTPCtracker::GetClusterMI(Int_t index) const {
91162307 1853 //--------------------------------------------------------------------
1854 // Return pointer to a given cluster
1855 //--------------------------------------------------------------------
e7eb17e4 1856 if (index<0) return 0; // no cluster
91162307 1857 Int_t sec=(index&0xff000000)>>24;
1858 Int_t row=(index&0x00ff0000)>>16;
d26d9159 1859 Int_t ncl=(index&0x00007fff)>>00;
91162307 1860
bd26fa83 1861 const AliTPCtrackerRow * tpcrow=0;
bfa00fba 1862 TClonesArray * clrow =0;
3da363a1 1863
ad23441a 1864 if (sec<0 || sec>=fkNIS*4) {
1865 AliWarning(Form("Wrong sector %d",sec));
1866 return 0x0;
1867 }
1868
91162307 1869 if (sec<fkNIS*2){
462fb6e0 1870 AliTPCtrackerSector& tracksec = fInnerSec[sec%fkNIS];
1871 if (tracksec.GetNRows()<=row) return 0;
1872 tpcrow = &(tracksec[row]);
3da363a1 1873 if (tpcrow==0) return 0;
1874
1875 if (sec<fkNIS) {
b9671574 1876 if (tpcrow->GetN1()<=ncl) return 0;
1877 clrow = tpcrow->GetClusters1();
3da363a1 1878 }
1879 else {
b9671574 1880 if (tpcrow->GetN2()<=ncl) return 0;
1881 clrow = tpcrow->GetClusters2();
3da363a1 1882 }
91162307 1883 }
3da363a1 1884 else {
462fb6e0 1885 AliTPCtrackerSector& tracksec = fOuterSec[(sec-fkNIS*2)%fkNOS];
1886 if (tracksec.GetNRows()<=row) return 0;
1887 tpcrow = &(tracksec[row]);
3da363a1 1888 if (tpcrow==0) return 0;
1889
1890 if (sec-2*fkNIS<fkNOS) {
b9671574 1891 if (tpcrow->GetN1()<=ncl) return 0;
1892 clrow = tpcrow->GetClusters1();
3da363a1 1893 }
1894 else {
b9671574 1895 if (tpcrow->GetN2()<=ncl) return 0;
1896 clrow = tpcrow->GetClusters2();
3da363a1 1897 }
91162307 1898 }
3da363a1 1899
bfa00fba 1900 return (AliTPCclusterMI*)clrow->At(ncl);
91162307 1901
1c53abe2 1902}
1903
91162307 1904
1905
829455ad 1906Int_t AliTPCtracker::FollowToNext(AliTPCseed& t, Int_t nr) {
1c53abe2 1907 //-----------------------------------------------------------------
1908 // This function tries to find a track prolongation to next pad row
1909 //-----------------------------------------------------------------
1c53abe2 1910 //
91162307 1911 Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
76d56fd6 1912 //
1913 //
4d158c36 1914 AliTPCclusterMI *cl=0;
1915 Int_t tpcindex= t.GetClusterIndex2(nr);
1916 //
1917 // update current shape info every 5 pad-row
1918 // if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
1919 GetShape(&t,nr);
1920 //}
1921 //
1922 if (fIteration>0 && tpcindex>=-1){ //if we have already clusters
1923 //
1924 if (tpcindex==-1) return 0; //track in dead zone
f124f8bf 1925 if (tpcindex >= 0){ //
b9671574 1926 cl = t.GetClusterPointer(nr);
97d77e7a 1927 //if (cl==0) cl = GetClusterMI(tpcindex);
1928 if (!cl) cl = GetClusterMI(tpcindex);
b9671574 1929 t.SetCurrentClusterIndex1(tpcindex);
4d158c36 1930 }
1931 if (cl){
1932 Int_t relativesector = ((tpcindex&0xff000000)>>24)%18; // if previously accepted cluster in different sector
1933 Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
1934 //
1935 if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
1936 if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
1937
1938 if (TMath::Abs(angle-t.GetAlpha())>0.001){
1939 Double_t rotation = angle-t.GetAlpha();
b9671574 1940 t.SetRelativeSector(relativesector);
1791d824 1941 if (!t.Rotate(rotation)) {
1942 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
1943 return 0;
1944 }
1945 }
1946 if (!t.PropagateTo(x)) {
1947 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
1948 return 0;
4d158c36 1949 }
4d158c36 1950 //
b9671574 1951 t.SetCurrentCluster(cl);
1952 t.SetRow(nr);
00055a22 1953 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
4d158c36 1954 if ((tpcindex&0x8000)==0) accept =0;
1955 if (accept<3) {
1956 //if founded cluster is acceptible
1957 if (cl->IsUsed(11)) { // id cluster is shared inrease uncertainty
b9671574 1958 t.SetErrorY2(t.GetErrorY2()+0.03);
1959 t.SetErrorZ2(t.GetErrorZ2()+0.03);
1960 t.SetErrorY2(t.GetErrorY2()*3);
1961 t.SetErrorZ2(t.GetErrorZ2()*3);
4d158c36 1962 }
b9671574 1963 t.SetNFoundable(t.GetNFoundable()+1);
4d158c36 1964 UpdateTrack(&t,accept);
1965 return 1;
f124f8bf 1966 }
1967 else { // Remove old cluster from track
1968 t.SetClusterIndex(nr, -3);
1969 t.SetClusterPointer(nr, 0);
1970 }
4d158c36 1971 }
1627d1c4 1972 }
3f82c4f2 1973 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0; // cut on angle
76d56fd6 1974 if (fIteration>1 && IsFindable(t)){
3f82c4f2 1975 // not look for new cluster during refitting
b9671574 1976 t.SetNFoundable(t.GetNFoundable()+1);
3f82c4f2 1977 return 0;
1978 }
91162307 1979 //
4d158c36 1980 UInt_t index=0;
ca142b1f 1981 // if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
f124f8bf 1982 if (!t.PropagateTo(x)) {
1983 if (fIteration==0) t.SetRemoval(10);
1984 return 0;
1985 }
1986 Double_t y = t.GetY();
91162307 1987 if (TMath::Abs(y)>ymax){
1988 if (y > ymax) {
b9671574 1989 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
91162307 1990 if (!t.Rotate(fSectors->GetAlpha()))
1991 return 0;
1992 } else if (y <-ymax) {
b9671574 1993 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
91162307 1994 if (!t.Rotate(-fSectors->GetAlpha()))
1995 return 0;
1996 }
f124f8bf 1997 if (!t.PropagateTo(x)) {
1998 if (fIteration==0) t.SetRemoval(10);
1999 return 0;
2000 }
2001 y = t.GetY();
91162307 2002 }
2003 //
4d158c36 2004 Double_t z=t.GetZ();
2005 //
a3232aae 2006
b9671574 2007 if (!IsActive(t.GetRelativeSector(),nr)) {
2008 t.SetInDead(kTRUE);
a3232aae 2009 t.SetClusterIndex2(nr,-1);
2010 return 0;
2011 }
2012 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
b9671574 2013 Bool_t isActive = IsActive(t.GetRelativeSector(),nr);
2014 Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
a3232aae 2015
2016 if (!isActive || !isActive2) return 0;
2017
bd26fa83 2018 const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
91162307 2019 if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
2020 Double_t roady =1.;
2021 Double_t roadz = 1.;
2022 //
b9671574 2023 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
2024 t.SetInDead(kTRUE);
91162307 2025 t.SetClusterIndex2(nr,-1);
1c53abe2 2026 return 0;
2027 }
2028 else
2029 {
76d56fd6 2030 if (IsFindable(t))
47af7ca4 2031 // if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fkParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
b9671574 2032 t.SetNFoundable(t.GetNFoundable()+1);
1627d1c4 2033 else
2034 return 0;
1c53abe2 2035 }
2036 //calculate
91162307 2037 if (krow) {
2038 // cl = krow.FindNearest2(y+10.,z,roady,roadz,index);
2039 cl = krow.FindNearest2(y,z,roady,roadz,index);
b9671574 2040 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
91162307 2041 }
91162307 2042 if (cl) {
b9671574 2043 t.SetCurrentCluster(cl);
2044 t.SetRow(nr);
4d158c36 2045 if (fIteration==2&&cl->IsUsed(10)) return 0;
00055a22 2046 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
4d158c36 2047 if (fIteration==2&&cl->IsUsed(11)) {
b9671574 2048 t.SetErrorY2(t.GetErrorY2()+0.03);
2049 t.SetErrorZ2(t.GetErrorZ2()+0.03);
2050 t.SetErrorY2(t.GetErrorY2()*3);
2051 t.SetErrorZ2(t.GetErrorZ2()*3);
4d158c36 2052 }
d26d9159 2053 /*
91162307 2054 if (t.fCurrentCluster->IsUsed(10)){
2055 //
2056 //
c9427e08 2057
91162307 2058 t.fNShared++;
2059 if (t.fNShared>0.7*t.GetNumberOfClusters()) {
2060 t.fRemoval =10;
2061 return 0;
2062 }
2063 }
d26d9159 2064 */
91162307 2065 if (accept<3) UpdateTrack(&t,accept);
c9427e08 2066
91162307 2067 } else {
b9671574 2068 if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
91162307 2069
2070 }
2071 return 1;
2072}
c9427e08 2073
1c53abe2 2074
91162307 2075
5d837844 2076//_________________________________________________________________________
829455ad 2077Bool_t AliTPCtracker::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
5d837844 2078{
2079 // Get track space point by index
2080 // return false in case the cluster doesn't exist
2081 AliTPCclusterMI *cl = GetClusterMI(index);
2082 if (!cl) return kFALSE;
2083 Int_t sector = (index&0xff000000)>>24;
0201b65c 2084 // Int_t row = (index&0x00ff0000)>>16;
5d837844 2085 Float_t xyz[3];
47af7ca4 2086 // xyz[0] = fkParam->GetPadRowRadii(sector,row);
0201b65c 2087 xyz[0] = cl->GetX();
5d837844 2088 xyz[1] = cl->GetY();
2089 xyz[2] = cl->GetZ();
2090 Float_t sin,cos;
47af7ca4 2091 fkParam->AdjustCosSin(sector,cos,sin);
5d837844 2092 Float_t x = cos*xyz[0]-sin*xyz[1];
2093 Float_t y = cos*xyz[1]+sin*xyz[0];
2094 Float_t cov[6];
2095 Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
47af7ca4 2096 if (sector < fkParam->GetNInnerSector()) sigmaY2 *= 2.07;
5d837844 2097 Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
47af7ca4 2098 if (sector < fkParam->GetNInnerSector()) sigmaZ2 *= 1.77;
5d837844 2099 cov[0] = sin*sin*sigmaY2;
2100 cov[1] = -sin*cos*sigmaY2;
2101 cov[2] = 0.;
2102 cov[3] = cos*cos*sigmaY2;
2103 cov[4] = 0.;
2104 cov[5] = sigmaZ2;
2105 p.SetXYZ(x,y,xyz[2],cov);
ae079791 2106 AliGeomManager::ELayerID iLayer;
5d837844 2107 Int_t idet;
47af7ca4 2108 if (sector < fkParam->GetNInnerSector()) {
ae079791 2109 iLayer = AliGeomManager::kTPC1;
5d837844 2110 idet = sector;
2111 }
2112 else {
ae079791 2113 iLayer = AliGeomManager::kTPC2;
47af7ca4 2114 idet = sector - fkParam->GetNInnerSector();
5d837844 2115 }
ae079791 2116 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
5d837844 2117 p.SetVolumeID(volid);
2118 return kTRUE;
2119}
2120
2121
2122
829455ad 2123Int_t AliTPCtracker::UpdateClusters(AliTPCseed& t, Int_t nr) {
1c53abe2 2124 //-----------------------------------------------------------------
2125 // This function tries to find a track prolongation to next pad row
2126 //-----------------------------------------------------------------
b9671574 2127 t.SetCurrentCluster(0);
f124f8bf 2128 t.SetCurrentClusterIndex1(-3);
1c53abe2 2129
2130 Double_t xt=t.GetX();
91162307 2131 Int_t row = GetRowNumber(xt)-1;
2132 Double_t ymax= GetMaxY(nr);
2133
1c53abe2 2134 if (row < nr) return 1; // don't prolongate if not information until now -
ca142b1f 2135// if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
2136// t.fRemoval =10;
2137// return 0; // not prolongate strongly inclined tracks
2138// }
2139// if (TMath::Abs(t.GetSnp())>0.95) {
2140// t.fRemoval =10;
2141// return 0; // not prolongate strongly inclined tracks
2142// }// patch 28 fev 06
91162307 2143
2144 Double_t x= GetXrow(nr);
2145 Double_t y,z;
2146 //t.PropagateTo(x+0.02);
2147 //t.PropagateTo(x+0.01);
1627d1c4 2148 if (!t.PropagateTo(x)){
1627d1c4 2149 return 0;
2150 }
1c53abe2 2151 //
91162307 2152 y=t.GetY();
2153 z=t.GetZ();
1c53abe2 2154
91162307 2155 if (TMath::Abs(y)>ymax){
2156 if (y > ymax) {
b9671574 2157 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
91162307 2158 if (!t.Rotate(fSectors->GetAlpha()))
2159 return 0;
2160 } else if (y <-ymax) {
b9671574 2161 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
91162307 2162 if (!t.Rotate(-fSectors->GetAlpha()))
2163 return 0;
2164 }
982aff31 2165 // if (!t.PropagateTo(x)){
2166 // return 0;
2167 //}
2168 return 1;
2169 //y = t.GetY();
1c53abe2 2170 }
91162307 2171 //
3f82c4f2 2172 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
a3232aae 2173
b9671574 2174 if (!IsActive(t.GetRelativeSector(),nr)) {
2175 t.SetInDead(kTRUE);
a3232aae 2176 t.SetClusterIndex2(nr,-1);
2177 return 0;
2178 }
2179 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
2180
bd26fa83 2181 AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1c53abe2 2182
b9671574 2183 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
2184 t.SetInDead(kTRUE);
91162307 2185 t.SetClusterIndex2(nr,-1);
1c53abe2 2186 return 0;
2187 }
2188 else
2189 {
76d56fd6 2190
2191 // if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
2192 if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
1627d1c4 2193 else
2194 return 0;
1c53abe2 2195 }
1c53abe2 2196
91162307 2197 // update current
42aec1f1 2198 if ( (nr%2==0) || t.GetNumberOfClusters()<2){
91162307 2199 // t.fCurrentSigmaY = GetSigmaY(&t);
2200 //t.fCurrentSigmaZ = GetSigmaZ(&t);
2201 GetShape(&t,nr);
2202 }
1c53abe2 2203
91162307 2204 AliTPCclusterMI *cl=0;
d184f295 2205 Int_t index=0;
91162307 2206 //
2207 Double_t roady = 1.;
2208 Double_t roadz = 1.;
2209 //
d26d9159 2210
2211 if (!cl){
2212 index = t.GetClusterIndex2(nr);
bad6eb00 2213 if ( (index >= 0) && (index&0x8000)==0){
b9671574 2214 cl = t.GetClusterPointer(nr);
bad6eb00 2215 if ( (cl==0) && (index >= 0)) cl = GetClusterMI(index);
b9671574 2216 t.SetCurrentClusterIndex1(index);
d26d9159 2217 if (cl) {
b9671574 2218 t.SetCurrentCluster(cl);
d26d9159 2219 return 1;
2220 }
2221 }
2222 }
2223
3d172d79 2224 // if (index<0) return 0;
2225 UInt_t uindex = TMath::Abs(index);
d184f295 2226
91162307 2227 if (krow) {
d184f295 2228 //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
2229 cl = krow.FindNearest2(y,z,roady,roadz,uindex);
91162307 2230 }
d26d9159 2231
b9671574 2232 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));
2233 t.SetCurrentCluster(cl);
d26d9159 2234
91162307 2235 return 1;
2236}
1c53abe2 2237
1c53abe2 2238
829455ad 2239Int_t AliTPCtracker::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
91162307 2240 //-----------------------------------------------------------------
2241 // This function tries to find a track prolongation to next pad row
2242 //-----------------------------------------------------------------
1c53abe2 2243
91162307 2244 //update error according neighborhoud
1c53abe2 2245
b9671574 2246 if (t.GetCurrentCluster()) {
2247 t.SetRow(nr);
00055a22 2248 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
91162307 2249
b9671574 2250 if (t.GetCurrentCluster()->IsUsed(10)){
91162307 2251 //
2252 //
2253 // t.fErrorZ2*=2;
2254 // t.fErrorY2*=2;
b9671574 2255 t.SetNShared(t.GetNShared()+1);
2256 if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
2257 t.SetRemoval(10);
91162307 2258 return 0;
2259 }
b364ca79 2260 }
d26d9159 2261 if (fIteration>0) accept = 0;
b364ca79 2262 if (accept<3) UpdateTrack(&t,accept);
2263
1c53abe2 2264 } else {
91162307 2265 if (fIteration==0){
f124f8bf 2266 if ( t.GetNumberOfClusters()>18 && ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)) t.SetRemoval(10);
2267 if ( t.GetNumberOfClusters()>18 && t.GetChi2()/t.GetNumberOfClusters()>6 ) t.SetRemoval(10);
91162307 2268
b9671574 2269 if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
1c53abe2 2270 }
2271 }
2272 return 1;
2273}
2274
2275
2276
91162307 2277//_____________________________________________________________________________
829455ad 2278Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step, Bool_t fromSeeds) {
1c53abe2 2279 //-----------------------------------------------------------------
91162307 2280 // This function tries to find a track prolongation.
1c53abe2 2281 //-----------------------------------------------------------------
2282 Double_t xt=t.GetX();
2283 //
f124f8bf 2284 Double_t alpha=t.GetAlpha();
1c53abe2 2285 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2286 if (alpha < 0. ) alpha += 2.*TMath::Pi();
91162307 2287 //
a3f36f42 2288 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1c53abe2 2289
f124f8bf 2290 Int_t first = GetRowNumber(xt);
2291 if (!fromSeeds)
2292 first -= step;
a3f36f42 2293 if (first < 0)
2294 first = 0;
51ad6848 2295 for (Int_t nr= first; nr>=rf; nr-=step) {
2296 // update kink info
2297 if (t.GetKinkIndexes()[0]>0){
2298 for (Int_t i=0;i<3;i++){
2299 Int_t index = t.GetKinkIndexes()[i];
2300 if (index==0) break;
2301 if (index<0) continue;
2302 //
6c94f330 2303 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
51ad6848 2304 if (!kink){
2305 printf("PROBLEM\n");
2306 }
2307 else{
eea478d3 2308 Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
51ad6848 2309 if (kinkrow==nr){
2310 AliExternalTrackParam paramd(t);
2311 kink->SetDaughter(paramd);
eea478d3 2312 kink->SetStatus(2,5);
51ad6848 2313 kink->Update();
51ad6848 2314 }
2315 }
2316 }
2317 }
2318
2319 if (nr==80) t.UpdateReference();
982aff31 2320 if (nr<fInnerSec->GetNRows())
2321 fSectors = fInnerSec;
2322 else
2323 fSectors = fOuterSec;
91162307 2324 if (FollowToNext(t,nr)==0)
4d158c36 2325 if (!t.IsActive())
2326 return 0;
91162307 2327
2328 }
2329 return 1;
2330}
2331
1c53abe2 2332
1c53abe2 2333
91162307 2334
2335
2336
829455ad 2337Int_t AliTPCtracker::FollowBackProlongation(AliTPCseed& t, Int_t rf, Bool_t fromSeeds) {
1c53abe2 2338 //-----------------------------------------------------------------
2339 // This function tries to find a track prolongation.
2340 //-----------------------------------------------------------------
1c53abe2 2341 //
eea478d3 2342 Double_t xt=t.GetX();
f124f8bf 2343 Double_t alpha=t.GetAlpha();
1c53abe2 2344 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2345 if (alpha < 0. ) alpha += 2.*TMath::Pi();
bad6eb00 2346 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1c53abe2 2347
b9671574 2348 Int_t first = t.GetFirstPoint();
f124f8bf 2349 Int_t ri = GetRowNumber(xt);
2350 if (!fromSeeds)
2351 ri += 1;
2352
2353 if (first<ri) first = ri;
91162307 2354 //
2355 if (first<0) first=0;
4d158c36 2356 for (Int_t nr=first; nr<=rf; nr++) {
ca142b1f 2357 // if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
51ad6848 2358 if (t.GetKinkIndexes()[0]<0){
2359 for (Int_t i=0;i<3;i++){
2360 Int_t index = t.GetKinkIndexes()[i];
2361 if (index==0) break;
2362 if (index>0) continue;
2363 index = TMath::Abs(index);
6c94f330 2364 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
51ad6848 2365 if (!kink){
2366 printf("PROBLEM\n");
2367 }
2368 else{
eea478d3 2369 Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
51ad6848 2370 if (kinkrow==nr){
2371 AliExternalTrackParam paramm(t);
2372 kink->SetMother(paramm);
eea478d3 2373 kink->SetStatus(2,1);
51ad6848 2374 kink->Update();
51ad6848 2375 }
2376 }
eea478d3 2377 }
51ad6848 2378 }
eea478d3 2379 //
d26d9159 2380 if (nr<fInnerSec->GetNRows())
2381 fSectors = fInnerSec;
2382 else
2383 fSectors = fOuterSec;
c274e255 2384
d26d9159 2385 FollowToNext(t,nr);
1c53abe2 2386 }
2387 return 1;
2388}
2389
2390
2391
2392
2393
829455ad 2394Float_t AliTPCtracker::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
1c53abe2 2395{
544c295f 2396 // overlapping factor
1c53abe2 2397 //
2398 sum1=0;
2399 sum2=0;
2400 Int_t sum=0;
1c53abe2 2401 //
2402 Float_t dz2 =(s1->GetZ() - s2->GetZ());
c9427e08 2403 dz2*=dz2;
91162307 2404
c9427e08 2405 Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
1c53abe2 2406 dy2*=dy2;
2407 Float_t distance = TMath::Sqrt(dz2+dy2);
c9427e08 2408 if (distance>4.) return 0; // if there are far away - not overlap - to reduce combinatorics
1c53abe2 2409
91162307 2410 // Int_t offset =0;
b9671574 2411 Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
2412 Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
c9427e08 2413 if (lastpoint>160)
2414 lastpoint =160;
2415 if (firstpoint<0)
2416 firstpoint = 0;
91162307 2417 if (firstpoint>lastpoint) {
2418 firstpoint =lastpoint;
2419 // lastpoint =160;
c9427e08 2420 }
2421
2422
91162307 2423 for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
2424 if (s1->GetClusterIndex2(i)>0) sum1++;
2425 if (s2->GetClusterIndex2(i)>0) sum2++;
2426 if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
1c53abe2 2427 sum++;
2428 }
2429 }
91162307 2430 if (sum<5) return 0;
2431
1627d1c4 2432 Float_t summin = TMath::Min(sum1+1,sum2+1);
2433 Float_t ratio = (sum+1)/Float_t(summin);
1c53abe2 2434 return ratio;
2435}
2436
829455ad 2437void AliTPCtracker::SignShared(AliTPCseed * s1, AliTPCseed * s2)
1c53abe2 2438{
544c295f 2439 // shared clusters
1c53abe2 2440 //
a0f4d6a6 2441 Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
2442 if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
2443 Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
2444 Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
91162307 2445
1c53abe2 2446 //
91162307 2447 Int_t sumshared=0;
2448 //
a0f4d6a6 2449 //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
2450 //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
2451 Int_t firstpoint = 0;
2452 Int_t lastpoint = 160;
91162307 2453 //
a0f4d6a6 2454 // if (firstpoint>=lastpoint-5) return;;
1af5da7e 2455
91162307 2456 for (Int_t i=firstpoint;i<lastpoint;i++){
2457 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2458 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2459 sumshared++;
2460 }
2461 }
a0f4d6a6 2462 if (sumshared>cutN0){
91162307 2463 // sign clusters
2464 //
2465 for (Int_t i=firstpoint;i<lastpoint;i++){
2466 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2467 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2468 AliTPCTrackerPoint *p1 = s1->GetTrackPoint(i);
2469 AliTPCTrackerPoint *p2 = s2->GetTrackPoint(i);;
2470 if (s1->IsActive()&&s2->IsActive()){
b9671574 2471 p1->SetShared(kTRUE);
2472 p2->SetShared(kTRUE);
91162307 2473 }
2474 }
2475 }
2476 }
2477 //
a0f4d6a6 2478 if (sumshared>cutN0){
91162307 2479 for (Int_t i=0;i<4;i++){
b9671574 2480 if (s1->GetOverlapLabel(3*i)==0){
2481 s1->SetOverlapLabel(3*i, s2->GetLabel());
2482 s1->SetOverlapLabel(3*i+1,sumshared);
2483 s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
91162307 2484 break;
2485 }
2486 }
2487 for (Int_t i=0;i<4;i++){
b9671574 2488 if (s2->GetOverlapLabel(3*i)==0){
2489 s2->SetOverlapLabel(3*i, s1->GetLabel());
2490 s2->SetOverlapLabel(3*i+1,sumshared);
2491 s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
91162307 2492 break;
2493 }
2494 }
2495 }
91162307 2496}
1c53abe2 2497
829455ad 2498void AliTPCtracker::SignShared(TObjArray * arr)
91162307 2499{
1c53abe2 2500 //
91162307 2501 //sort trackss according sectors
2502 //
c9427e08 2503 for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2504 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 2505 if (!pt) continue;
2506 //if (pt) RotateToLocal(pt);
b9671574 2507 pt->SetSort(0);
c9427e08 2508 }
91162307 2509 arr->UnSort();
6d493ea0 2510 arr->Sort(); // sorting according relative sectors
1c53abe2 2511 arr->Expand(arr->GetEntries());
91162307 2512 //
2513 //
1c53abe2 2514 Int_t nseed=arr->GetEntriesFast();
1c53abe2 2515 for (Int_t i=0; i<nseed; i++) {
2516 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 2517 if (!pt) continue;
ec26e231 2518 for (Int_t j=0;j<12;j++){
b9671574 2519 pt->SetOverlapLabel(j,0);
1c53abe2 2520 }
91162307 2521 }
2522 for (Int_t i=0; i<nseed; i++) {
2523 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2524 if (!pt) continue;
b9671574 2525 if (pt->GetRemoval()>10) continue;
1c53abe2 2526 for (Int_t j=i+1; j<nseed; j++){
2527 AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
1af5da7e 2528 if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
91162307 2529 // if (pt2){
b9671574 2530 if (pt2->GetRemoval()<=10) {
6d493ea0 2531 //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
91162307 2532 SignShared(pt,pt2);
c9427e08 2533 }
91162307 2534 }
2535 }
2536}
2537
91162307 2538
829455ad 2539void AliTPCtracker::SortTracks(TObjArray * arr, Int_t mode) const
91162307 2540{
2541 //
2542 //sort tracks in array according mode criteria
2543 Int_t nseed = arr->GetEntriesFast();
2544 for (Int_t i=0; i<nseed; i++) {
2545 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2546 if (!pt) {
2547 continue;
2548 }
b9671574 2549 pt->SetSort(mode);
91162307 2550 }
2551 arr->UnSort();
2552 arr->Sort();
1c53abe2 2553}
c9427e08 2554
51ad6848 2555
829455ad 2556void AliTPCtracker::RemoveUsed2(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t minimal)
51ad6848 2557{
51ad6848 2558 //
6d493ea0 2559 // Loop over all tracks and remove overlaped tracks (with lower quality)
2560 // Algorithm:
2561 // 1. Unsign clusters
2562 // 2. Sort tracks according quality
2563 // Quality is defined by the number of cluster between first and last points
2564 //
2565 // 3. Loop over tracks - decreasing quality order
2566 // a.) remove - If the fraction of shared cluster less than factor (1- n or 2)
2567 // b.) remove - If the minimal number of clusters less than minimal and not ITS
2568 // c.) if track accepted - sign clusters
51ad6848 2569 //
829455ad 2570 //Called in - AliTPCtracker::Clusters2Tracks()
2571 // - AliTPCtracker::PropagateBack()
2572 // - AliTPCtracker::RefitInward()
6d493ea0 2573 //
be34cb88 2574 // Arguments:
2575 // factor1 - factor for constrained
2576 // factor2 - for non constrained tracks
2577 // if (Float_t(shared+1)/Float_t(found+1)>factor) - DELETE
2578 //
51ad6848 2579 UnsignClusters();
2580 //
2581 Int_t nseed = arr->GetEntriesFast();
2582 Float_t * quality = new Float_t[nseed];
2583 Int_t * indexes = new Int_t[nseed];
2584 Int_t good =0;
2585 //
2586 //
2587 for (Int_t i=0; i<nseed; i++) {
2588 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2589 if (!pt){
2590 quality[i]=-1;
2591 continue;
2592 }
2593 pt->UpdatePoints(); //select first last max dens points
2594 Float_t * points = pt->GetPoints();
2595 if (points[3]<0.8) quality[i] =-1;
51ad6848 2596 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
6d493ea0 2597 //prefer high momenta tracks if overlaps
2598 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
51ad6848 2599 }
2600 TMath::Sort(nseed,quality,indexes);
2601 //
2602 //
2603 for (Int_t itrack=0; itrack<nseed; itrack++) {
2604 Int_t trackindex = indexes[itrack];
6d493ea0 2605 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);
2606 if (!pt) continue;
2607 //
51ad6848 2608 if (quality[trackindex]<0){
ddfbc51a 2609 MarkSeedFree( arr->RemoveAt(trackindex) );
f06a1ff6 2610 continue;
51ad6848 2611 }
2612 //
6d493ea0 2613 //
51ad6848 2614 Int_t first = Int_t(pt->GetPoints()[0]);
2615 Int_t last = Int_t(pt->GetPoints()[2]);
b9671574 2616 Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
51ad6848 2617 //
2618 Int_t found,foundable,shared;
6d493ea0 2619 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
2620 // pt->GetClusterStatistic(0,160, found, foundable,shared,kFALSE);
b406fdb0 2621 Bool_t itsgold =kFALSE;
b9671574 2622 if (pt->GetESD()){
ef7253ac 2623 Int_t dummy[12];
b9671574 2624 if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
51ad6848 2625 }
b406fdb0 2626 if (!itsgold){
2627 //
2628 if (Float_t(shared+1)/Float_t(found+1)>factor){
2629 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
16299eac 2630 if( AliTPCReconstructor::StreamLevel()>3){
be34cb88 2631 TTreeSRedirector &cstream = *fDebugStreamer;
2632 cstream<<"RemoveUsed"<<
2633 "iter="<<fIteration<<
2634 "pt.="<<pt<<
2635 "\n";
2636 }
ddfbc51a 2637 MarkSeedFree( arr->RemoveAt(trackindex) );
b406fdb0 2638 continue;
2639 }
2640 if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){ //remove short tracks
2641 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
16299eac 2642 if( AliTPCReconstructor::StreamLevel()>3){
be34cb88 2643 TTreeSRedirector &cstream = *fDebugStreamer;
2644 cstream<<"RemoveShort"<<
2645 "iter="<<fIteration<<
2646 "pt.="<<pt<<
2647 "\n";
2648 }
ddfbc51a 2649 MarkSeedFree( arr->RemoveAt(trackindex) );
b406fdb0 2650 continue;
2651 }
51ad6848 2652 }
2653
2654 good++;
6d493ea0 2655 //if (sharedfactor>0.4) continue;
b406fdb0 2656 if (pt->GetKinkIndexes()[0]>0) continue;
6d493ea0 2657 //Remove tracks with undefined properties - seems
2658 if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ?
2659 //
51ad6848 2660 for (Int_t i=first; i<last; i++) {
2661 Int_t index=pt->GetClusterIndex2(i);
2662 // if (index<0 || index&0x8000 ) continue;
2663 if (index<0 || index&0x8000 ) continue;
b9671574 2664 AliTPCclusterMI *c= pt->GetClusterPointer(i);
51ad6848 2665 if (!c) continue;
2666 c->Use(10);
2667 }
2668 }
2669 fNtracks = good;
2670 if (fDebug>0){
2671 Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
2672 }
2673 delete []quality;
2674 delete []indexes;
2675}
2676
829455ad 2677void AliTPCtracker::DumpClusters(Int_t iter, TObjArray *trackArray)
f47588e0 2678{
2679 //
2680 // Dump clusters after reco
2681 // signed and unsigned cluster can be visualized
2682 // 1. Unsign all cluster
2683 // 2. Sign all used clusters
2684 // 3. Dump clusters
2685 UnsignClusters();
2686 Int_t nseed = trackArray->GetEntries();
2687 for (Int_t i=0; i<nseed; i++){
2688 AliTPCseed *pt=(AliTPCseed*)trackArray->UncheckedAt(i);
2689 if (!pt) {
2690 continue;
2691 }
2692 Bool_t isKink=pt->GetKinkIndex(0)!=0;
2693 for (Int_t j=0; j<160; ++j) {
2694 Int_t index=pt->GetClusterIndex2(j);
2695 if (index<0) continue;
2696 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2697 if (!c) continue;
2698 if (isKink) c->Use(100); // kink
2699 c->Use(10); // by default usage 10
2700 }
2701 }
2702 //
2703
2704 for (Int_t sec=0;sec<fkNIS;sec++){
2705 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
bfa00fba 2706 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
f47588e0 2707 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++){
bfa00fba 2708 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
2709 Float_t gx[3]; cl->GetGlobalXYZ(gx);
f47588e0 2710 (*fDebugStreamer)<<"clDump"<<
2711 "iter="<<iter<<
bfa00fba 2712 "cl.="<<cl<<
f47588e0 2713 "gx0="<<gx[0]<<
2714 "gx1="<<gx[1]<<
2715 "gx2="<<gx[2]<<
2716 "\n";
2717 }
bfa00fba 2718 cla = fInnerSec[sec][row].GetClusters2();
f47588e0 2719 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++){
bfa00fba 2720 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
2721 Float_t gx[3]; cl->GetGlobalXYZ(gx);
f47588e0 2722 (*fDebugStreamer)<<"clDump"<<
2723 "iter="<<iter<<
bfa00fba 2724 "cl.="<<cl<<
f47588e0 2725 "gx0="<<gx[0]<<
2726 "gx1="<<gx[1]<<
2727 "gx2="<<gx[2]<<
2728 "\n";
2729 }
2730 }
2731 }
2732
2733 for (Int_t sec=0;sec<fkNOS;sec++){
2734 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
bfa00fba 2735 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
f47588e0 2736 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++){
bfa00fba 2737 Float_t gx[3];
2738 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
2739 cl->GetGlobalXYZ(gx);
f47588e0 2740 (*fDebugStreamer)<<"clDump"<<
2741 "iter="<<iter<<
bfa00fba 2742 "cl.="<<cl<<
f47588e0 2743 "gx0="<<gx[0]<<
2744 "gx1="<<gx[1]<<
2745 "gx2="<<gx[2]<<
2746 "\n";
2747 }
bfa00fba 2748 cla = fOuterSec[sec][row].GetClusters2();
f47588e0 2749 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++){
bfa00fba 2750 Float_t gx[3];
2751 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
2752 cl->GetGlobalXYZ(gx);
f47588e0 2753 (*fDebugStreamer)<<"clDump"<<
2754 "iter="<<iter<<
bfa00fba 2755 "cl.="<<cl<<
f47588e0 2756 "gx0="<<gx[0]<<
2757 "gx1="<<gx[1]<<
2758 "gx2="<<gx[2]<<
2759 "\n";
2760 }
2761 }
2762 }
2763
2764}
829455ad 2765void AliTPCtracker::UnsignClusters()
1c53abe2 2766{
91162307 2767 //
2768 // loop over all clusters and unsign them
2769 //
2770
2771 for (Int_t sec=0;sec<fkNIS;sec++){
2772 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
bfa00fba 2773 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
b9671574 2774 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
91162307 2775 // if (cl[icl].IsUsed(10))
bfa00fba 2776 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2777 cla = fInnerSec[sec][row].GetClusters2();
b9671574 2778 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
91162307 2779 //if (cl[icl].IsUsed(10))
bfa00fba 2780 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
91162307 2781 }
2782 }
2783
2784 for (Int_t sec=0;sec<fkNOS;sec++){
2785 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
bfa00fba 2786 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
b9671574 2787 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
91162307 2788 //if (cl[icl].IsUsed(10))
bfa00fba 2789 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2790 cla = fOuterSec[sec][row].GetClusters2();
b9671574 2791 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
91162307 2792 //if (cl[icl].IsUsed(10))
bfa00fba 2793 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
91162307 2794 }
2795 }
2796
1c53abe2 2797}
2798
91162307 2799
2800
829455ad 2801void AliTPCtracker::SignClusters(const TObjArray * arr, Float_t fnumber, Float_t fdensity)
1c53abe2 2802{
2803 //
91162307 2804 //sign clusters to be "used"
2805 //
2806 // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
2807 // loop over "primaries"
2808
2809 Float_t sumdens=0;
2810 Float_t sumdens2=0;
2811 Float_t sumn =0;
2812 Float_t sumn2 =0;
2813 Float_t sumchi =0;
2814 Float_t sumchi2 =0;
2815
2816 Float_t sum =0;
2817
1c53abe2 2818 TStopwatch timer;
91162307 2819 timer.Start();
1c53abe2 2820
91162307 2821 Int_t nseed = arr->GetEntriesFast();
2822 for (Int_t i=0; i<nseed; i++) {
2823 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2824 if (!pt) {
2825 continue;
2826 }
2827 if (!(pt->IsActive())) continue;
b9671574 2828 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
91162307 2829 if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
2830 sumdens += dens;
2831 sumdens2+= dens*dens;
2832 sumn += pt->GetNumberOfClusters();
2833 sumn2 += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
2834 Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
2835 if (chi2>5) chi2=5;
2836 sumchi +=chi2;
2837 sumchi2 +=chi2*chi2;
2838 sum++;
2839 }
1627d1c4 2840 }
91162307 2841
2842 Float_t mdensity = 0.9;
2843 Float_t meann = 130;
2844 Float_t meanchi = 1;
2845 Float_t sdensity = 0.1;
2846 Float_t smeann = 10;
2847 Float_t smeanchi =0.4;
1627d1c4 2848
91162307 2849
2850 if (sum>20){
2851 mdensity = sumdens/sum;
2852 meann = sumn/sum;
2853 meanchi = sumchi/sum;
2854 //
2855 sdensity = sumdens2/sum-mdensity*mdensity;
c1ea348f 2856 if (sdensity >= 0)
2857 sdensity = TMath::Sqrt(sdensity);
2858 else
2859 sdensity = 0.1;
91162307 2860 //
2861 smeann = sumn2/sum-meann*meann;
c1ea348f 2862 if (smeann >= 0)
2863 smeann = TMath::Sqrt(smeann);
2864 else
2865 smeann = 10;
91162307 2866 //
2867 smeanchi = sumchi2/sum - meanchi*meanchi;
c1ea348f 2868 if (smeanchi >= 0)
2869 smeanchi = TMath::Sqrt(smeanchi);
2870 else
2871 smeanchi = 0.4;
91162307 2872 }
2873
2874
2875 //REMOVE SHORT DELTAS or tracks going out of sensitive volume of TPC
2876 //
2877 for (Int_t i=0; i<nseed; i++) {
2878 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2879 if (!pt) {
2880 continue;
1c53abe2 2881 }
b9671574 2882 if (pt->GetBSigned()) continue;
2883 if (pt->GetBConstrain()) continue;
91162307 2884 //if (!(pt->IsActive())) continue;
2885 /*
2886 Int_t found,foundable,shared;
2887 pt->GetClusterStatistic(0,160,found, foundable,shared);
2888 if (shared/float(found)>0.3) {
2889 if (shared/float(found)>0.9 ){
ddfbc51a 2890 //MarkSeedFree( arr->RemoveAt(i) );
91162307 2891 }
2892 continue;
c9427e08 2893 }
91162307 2894 */
2895 Bool_t isok =kFALSE;
b9671574 2896 if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
91162307 2897 isok = kTRUE;
b9671574 2898 if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
91162307 2899 isok =kTRUE;
2900 if (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
2901 isok =kTRUE;
2902 if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
2903 isok =kTRUE;
2904
2905 if (isok)
77f88633 2906 for (Int_t j=0; j<160; ++j) {
2907 Int_t index=pt->GetClusterIndex2(j);
91162307 2908 if (index<0) continue;
77f88633 2909 AliTPCclusterMI *c= pt->GetClusterPointer(j);
91162307 2910 if (!c) continue;
2911 //if (!(c->IsUsed(10))) c->Use();
2912 c->Use(10);
2913 }
2914 }
2915
c9427e08 2916
1c53abe2 2917 //
91162307 2918 Double_t maxchi = meanchi+2.*smeanchi;
2919
2920 for (Int_t i=0; i<nseed; i++) {
2921 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2922 if (!pt) {
1c53abe2 2923 continue;
91162307 2924 }
2925 //if (!(pt->IsActive())) continue;
b9671574 2926 if (pt->GetBSigned()) continue;
91162307 2927 Double_t chi = pt->GetChi2()/pt->GetNumberOfClusters();
2928 if (chi>maxchi) continue;
2929
2930 Float_t bfactor=1;
b9671574 2931 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
91162307 2932
2933 //sign only tracks with enoug big density at the beginning
2934
2935 if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue;
2936
2937
3e5d0aa2 2938 Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
91162307 2939 Double_t minn = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
2940
2941 // if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
b9671574 2942 if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
91162307 2943 minn=0;
2944
2945 if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
2946 //Int_t noc=pt->GetNumberOfClusters();
b9671574 2947 pt->SetBSigned(kTRUE);
77f88633 2948 for (Int_t j=0; j<160; ++j) {
91162307 2949
77f88633 2950 Int_t index=pt->GetClusterIndex2(j);
91162307 2951 if (index<0) continue;
77f88633 2952 AliTPCclusterMI *c= pt->GetClusterPointer(j);
91162307 2953 if (!c) continue;
2954 // if (!(c->IsUsed(10))) c->Use();
2955 c->Use(10);
2956 }
1c53abe2 2957 }
91162307 2958 }
2959 // gLastCheck = nseed;
2960 // arr->Compress();
2961 if (fDebug>0){
2962 timer.Print();
2963 }
2964}
2965
2966
91162307 2967
829455ad 2968Int_t AliTPCtracker::RefitInward(AliESDEvent *event)
d26d9159 2969{
2970 //
2971 // back propagation of ESD tracks
2972 //
2973 //return 0;
ec26e231 2974 if (!event) return 0;
6d493ea0 2975 const Int_t kMaxFriendTracks=2000;
d26d9159 2976 fEvent = event;
72e25240 2977 fEventHLT = 0;
6d64657a 2978 // extract correction object for multiplicity dependence of dEdx
2979 TObjArray * gainCalibArray = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(event->GetRunNumber());
23728788 2980
2981 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
2982 if (!transform) {
2983 AliFatal("Tranformations not in RefitInward");
2984 return 0;
2985 }
2986 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
6d64657a 2987 const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
012c4694 2988 Int_t nContribut = event->GetNumberOfTracks();
6d64657a 2989 TGraphErrors * graphMultDependenceDeDx = 0x0;
23728788 2990 if (recoParam && recoParam->GetUseMultiplicityCorrectionDedx() && gainCalibArray) {
6d64657a 2991 if (recoParam->GetUseTotCharge()) {
2992 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2993 } else {
2994 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2995 }
2996 }
2997 //
d26d9159 2998 ReadSeeds(event,2);
2999 fIteration=2;
982aff31 3000 //PrepareForProlongation(fSeeds,1);
3001 PropagateForward2(fSeeds);
6d493ea0 3002 RemoveUsed2(fSeeds,0.4,0.4,20);
1af5da7e 3003
bda5ad6d 3004 Int_t entriesSeed=fSeeds->GetEntries();
3005 TObjArray arraySeed(entriesSeed);
3006 for (Int_t i=0;i<entriesSeed;i++) {
a0f4d6a6 3007 arraySeed.AddAt(fSeeds->At(i),i);
3008 }
3009 SignShared(&arraySeed);
6d493ea0 3010 // FindCurling(fSeeds, event,2); // find multi found tracks
1af5da7e 3011 FindSplitted(fSeeds, event,2); // find multi found tracks
16299eac 3012 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,2); // find multi found tracks
af32720d 3013
4d158c36 3014 Int_t ntracks=0;
d26d9159 3015 Int_t nseed = fSeeds->GetEntriesFast();
3016 for (Int_t i=0;i<nseed;i++){
3017 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
4d158c36 3018 if (!seed) continue;
eea478d3 3019 if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
be34cb88 3020 AliESDtrack *esd=event->GetTrack(i);
3021
3022 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
3023 AliExternalTrackParam paramIn;
3024 AliExternalTrackParam paramOut;
3025 Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
16299eac 3026 if (AliTPCReconstructor::StreamLevel()>2) {
0e90d29a 3027 (*fDebugStreamer)<<"RecoverIn"<<
3028 "seed.="<<seed<<
3029 "esd.="<<esd<<
3030 "pin.="<<&paramIn<<
3031 "pout.="<<&paramOut<<
3032 "ncl="<<ncl<<
3033 "\n";
3034 }
be34cb88 3035 if (ncl>15) {
3036 seed->Set(paramIn.GetX(),paramIn.GetAlpha(),paramIn.GetParameter(),paramIn.GetCovariance());
3037 seed->SetNumberOfClusters(ncl);
3038 }
3039 }
eea478d3 3040
47af7ca4 3041 seed->PropagateTo(fkParam->GetInnerRadiusLow());
51ad6848 3042 seed->UpdatePoints();
92f513f5 3043 AddCovariance(seed);
bad6eb00 3044 MakeESDBitmaps(seed, esd);
d26d9159 3045 seed->CookdEdx(0.02,0.6);
3046 CookLabel(seed,0.1); //For comparison only
af32720d 3047 //
ec26e231 3048 if (AliTPCReconstructor::StreamLevel()>1 && seed!=0) {
af32720d 3049 TTreeSRedirector &cstream = *fDebugStreamer;