]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/Rec/AliTPCtracker.cxx
ALIROOT-5347 Change StreamLevel for the tracker debugging
[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;
1c53abe2 341
16299eac 342 if (AliTPCReconstructor::StreamLevel()>2 && seed->GetNumberOfClusters()>20) {
fd065ea2 343 Float_t rmsy2 = seed->GetCurrentSigmaY2();
344 Float_t rmsz2 = seed->GetCurrentSigmaZ2();
e0e13b88 345 Float_t rmsy2p30 = seed->GetCMeanSigmaY2p30();
346 Float_t rmsz2p30 = seed->GetCMeanSigmaZ2p30();
42aec1f1 347 Float_t rmsy2p30R = seed->GetCMeanSigmaY2p30R();
348 Float_t rmsz2p30R = seed->GetCMeanSigmaZ2p30R();
6fbe1e5c 349 AliExternalTrackParam param(*seed);
eea6b724 350 static TVectorD gcl(3),gtr(3);
351 Float_t gclf[3];
352 param.GetXYZ(gcl.GetMatrixArray());
353 cluster->GetGlobalXYZ(gclf);
354 gcl[0]=gclf[0]; gcl[1]=gclf[1]; gcl[2]=gclf[2];
6fbe1e5c 355
b194b32c 356
16299eac 357 if (AliTPCReconstructor::StreamLevel()>2) {
fd065ea2 358 (*fDebugStreamer)<<"ErrParam"<<
498b9441 359 "iter="<<fIteration<<
e0e13b88 360 "Cl.="<<cluster<<
361 "T.="<<&param<<
6fbe1e5c 362 "dy="<<dy<<
363 "dz="<<dz<<
364 "yt="<<yt<<
365 "zt="<<zt<<
eea6b724 366 "gcl.="<<&gcl<<
367 "gtr.="<<&gtr<<
e0e13b88 368 "erry2="<<sy2<<
369 "errz2="<<sz2<<
370 "rmsy2="<<rmsy2<<
371 "rmsz2="<<rmsz2<<
372 "rmsy2p30="<<rmsy2p30<<
373 "rmsz2p30="<<rmsz2p30<<
42aec1f1 374 "rmsy2p30R="<<rmsy2p30R<<
375 "rmsz2p30R="<<rmsz2p30R<<
f47588e0 376 // normalize distance -
377 "rdisty="<<rdistancey2<<
378 "rdistz="<<rdistancez2<<
379 "rdist="<<rdistance2<< //
e0e13b88 380 "\n";
b194b32c 381 }
fd065ea2 382 }
6fbe1e5c 383 //return 0; // temporary
384 if (rdistance2>32) return 3;
91162307 385
386
00055a22 387 if ((rdistancey2>9. || rdistancez2>9.) && cluster->GetType()==0)
91162307 388 return 2; //suspisiouce - will be changed
389
00055a22 390 if ((rdistancey2>6.25 || rdistancez2>6.25) && cluster->GetType()>0)
91162307 391 // strict cut on overlaped cluster
392 return 2; //suspisiouce - will be changed
393
00055a22 394 if ( (rdistancey2>1. || rdistancez2>6.25 )
91162307 395 && cluster->GetType()<0){
b9671574 396 seed->SetNFoundable(seed->GetNFoundable()-1);
91162307 397 return 2;
1c53abe2 398 }
19dcf504 399
1598ba75 400 if (fUseHLTClusters == 3 || fUseHLTClusters == 4) {
36b89541 401 if (fIteration==2){
402 if(!AliTPCReconstructor::GetRecoParam()->GetUseHLTOnePadCluster()) {
403 if (TMath::Abs(cluster->GetSigmaY2()) < kAlmost0)
404 return 2;
405 }
1598ba75 406 }
19dcf504 407 }
1598ba75 408
91162307 409 return 0;
410}
411
412
1c53abe2 413
1c53abe2 414
1af5da7e 415
1c53abe2 416//_____________________________________________________________________________
829455ad 417AliTPCtracker::AliTPCtracker(const AliTPCParam *par):
e046d791 418AliTracker(),
419 fkNIS(par->GetNInnerSector()/2),
420 fInnerSec(0),
421 fkNOS(par->GetNOuterSector()/2),
422 fOuterSec(0),
423 fN(0),
424 fSectors(0),
425 fInput(0),
426 fOutput(0),
427 fSeedTree(0),
428 fTreeDebug(0),
429 fEvent(0),
72e25240 430 fEventHLT(0),
e046d791 431 fDebug(0),
432 fNewIO(0),
433 fNtracks(0),
434 fSeeds(0),
435 fIteration(0),
47af7ca4 436 fkParam(0),
1598ba75 437 fDebugStreamer(0),
f06a1ff6 438 fUseHLTClusters(4),
439 fSeedsPool(0),
ddfbc51a 440 fFreeSeedsID(500),
441 fNFreeSeeds(0),
442 fLastSeedID(-1)
1c53abe2 443{
444 //---------------------------------------------------------------------
445 // The main TPC tracker constructor
446 //---------------------------------------------------------------------
9350f379 447 fInnerSec=new AliTPCtrackerSector[fkNIS];
448 fOuterSec=new AliTPCtrackerSector[fkNOS];
91162307 449
1c53abe2 450 Int_t i;
451 for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
452 for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
453
47af7ca4 454 fkParam = par;
91162307 455 Int_t nrowlow = par->GetNRowLow();
456 Int_t nrowup = par->GetNRowUp();
457
458
77f88633 459 for (i=0;i<nrowlow;i++){
91162307 460 fXRow[i] = par->GetPadRowRadiiLow(i);
461 fPadLength[i]= par->GetPadPitchLength(0,i);
462 fYMax[i] = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
463 }
464
465
77f88633 466 for (i=0;i<nrowup;i++){
91162307 467 fXRow[i+nrowlow] = par->GetPadRowRadiiUp(i);
468 fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
469 fYMax[i+nrowlow] = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
470 }
e046d791 471
b194b32c 472 if (AliTPCReconstructor::StreamLevel()>0) {
3d674021 473 fDebugStreamer = new TTreeSRedirector("TPCdebug.root","recreate");
b194b32c 474 }
f06a1ff6 475 //
ddfbc51a 476 fSeedsPool = new TClonesArray("AliTPCseed",1000);
1c53abe2 477}
2fc0c115 478//________________________________________________________________________
829455ad 479AliTPCtracker::AliTPCtracker(const AliTPCtracker &t):
58251ea0 480 AliTracker(t),
e046d791 481 fkNIS(t.fkNIS),
482 fInnerSec(0),
483 fkNOS(t.fkNOS),
484 fOuterSec(0),
485 fN(0),
486 fSectors(0),
487 fInput(0),
488 fOutput(0),
489 fSeedTree(0),
490 fTreeDebug(0),
491 fEvent(0),
72e25240 492 fEventHLT(0),
e046d791 493 fDebug(0),
494 fNewIO(kFALSE),
495 fNtracks(0),
496 fSeeds(0),
497 fIteration(0),
47af7ca4 498 fkParam(0),
1598ba75 499 fDebugStreamer(0),
f06a1ff6 500 fUseHLTClusters(4),
501 fSeedsPool(0),
ddfbc51a 502 fFreeSeedsID(500),
503 fNFreeSeeds(0),
504 fLastSeedID(-1)
58251ea0 505{
2fc0c115 506 //------------------------------------
507 // dummy copy constructor
508 //------------------------------------------------------------------
e046d791 509 fOutput=t.fOutput;
17abbffb 510 for (Int_t irow=0; irow<200; irow++){
511 fXRow[irow]=0;
512 fYMax[irow]=0;
513 fPadLength[irow]=0;
514 }
515
2fc0c115 516}
829455ad 517AliTPCtracker & AliTPCtracker::operator=(const AliTPCtracker& /*r*/)
47af7ca4 518{
2fc0c115 519 //------------------------------
520 // dummy
521 //--------------------------------------------------------------
522 return *this;
523}
1c53abe2 524//_____________________________________________________________________________
829455ad 525AliTPCtracker::~AliTPCtracker() {
1c53abe2 526 //------------------------------------------------------------------
527 // TPC tracker destructor
528 //------------------------------------------------------------------
529 delete[] fInnerSec;
530 delete[] fOuterSec;
531 if (fSeeds) {
f06a1ff6 532 fSeeds->Clear();
1c53abe2 533 delete fSeeds;
534 }
81e97e0d 535 if (fDebugStreamer) delete fDebugStreamer;
ddfbc51a 536 if (fSeedsPool) delete fSeedsPool;
1c53abe2 537}
538
1c53abe2 539
829455ad 540void AliTPCtracker::FillESD(const TObjArray* arr)
91162307 541{
47966a6d 542 //
543 //
544 //fill esds using updated tracks
ada522d7 545
ec26e231 546 if (!fEvent) return;
ada522d7 547
548 AliESDtrack iotrack;
ec26e231 549
91162307 550 // write tracks to the event
551 // store index of the track
d26d9159 552 Int_t nseed=arr->GetEntriesFast();
51ad6848 553 //FindKinks(arr,fEvent);
91162307 554 for (Int_t i=0; i<nseed; i++) {
d26d9159 555 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 556 if (!pt) continue;
51ad6848 557 pt->UpdatePoints();
92f513f5 558 AddCovariance(pt);
8cecaa87 559 if (AliTPCReconstructor::StreamLevel()>1) {
560 (*fDebugStreamer)<<"Track0"<<
561 "Tr0.="<<pt<<
562 "\n";
563 }
47af7ca4 564 // pt->PropagateTo(fkParam->GetInnerRadiusLow());
eea478d3 565 if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
47af7ca4 566 pt->PropagateTo(fkParam->GetInnerRadiusLow());
eea478d3 567 }
51ad6848 568
569 if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
ada522d7 570 iotrack.~AliESDtrack();
571 new(&iotrack) AliESDtrack;
51ad6848 572 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
573 iotrack.SetTPCPoints(pt->GetPoints());
574 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 575 iotrack.SetV0Indexes(pt->GetV0Indexes());
576 // iotrack.SetTPCpid(pt->fTPCr);
f5cbf2ef 577 //iotrack.SetTPCindex(i);
578 MakeESDBitmaps(pt, &iotrack);
51ad6848 579 fEvent->AddTrack(&iotrack);
580 continue;
581 }
582
b9671574 583 if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
ada522d7 584 iotrack.~AliESDtrack();
585 new(&iotrack) AliESDtrack;
51ad6848 586 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
587 iotrack.SetTPCPoints(pt->GetPoints());
d26d9159 588 //iotrack.SetTPCindex(i);
51ad6848 589 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 590 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 591 MakeESDBitmaps(pt, &iotrack);
81e97e0d 592 // iotrack.SetTPCpid(pt->fTPCr);
d26d9159 593 fEvent->AddTrack(&iotrack);
a42a6bae 594 continue;
595 }
51ad6848 596 //
597 // short tracks - maybe decays
598
b9671574 599 if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
a42a6bae 600 Int_t found,foundable,shared;
601 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
b9671574 602 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
ada522d7 603 iotrack.~AliESDtrack();
604 new(&iotrack) AliESDtrack;
a42a6bae 605 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
606 //iotrack.SetTPCindex(i);
51ad6848 607 iotrack.SetTPCPoints(pt->GetPoints());
608 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 609 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 610 MakeESDBitmaps(pt, &iotrack);
81e97e0d 611 //iotrack.SetTPCpid(pt->fTPCr);
a42a6bae 612 fEvent->AddTrack(&iotrack);
613 continue;
614 }
615 }
616
b9671574 617 if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
a42a6bae 618 Int_t found,foundable,shared;
619 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
620 if (found<20) continue;
b9671574 621 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
a42a6bae 622 //
ada522d7 623 iotrack.~AliESDtrack();
624 new(&iotrack) AliESDtrack;
a42a6bae 625 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
51ad6848 626 iotrack.SetTPCPoints(pt->GetPoints());
627 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 628 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 629 MakeESDBitmaps(pt, &iotrack);
81e97e0d 630 //iotrack.SetTPCpid(pt->fTPCr);
51ad6848 631 //iotrack.SetTPCindex(i);
632 fEvent->AddTrack(&iotrack);
633 continue;
634 }
635 // short tracks - secondaties
636 //
637 if ( (pt->GetNumberOfClusters()>30) ) {
638 Int_t found,foundable,shared;
639 pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
b9671574 640 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
ada522d7 641 iotrack.~AliESDtrack();
642 new(&iotrack) AliESDtrack;
51ad6848 643 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
644 iotrack.SetTPCPoints(pt->GetPoints());
645 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 646 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 647 MakeESDBitmaps(pt, &iotrack);
81e97e0d 648 //iotrack.SetTPCpid(pt->fTPCr);
51ad6848 649 //iotrack.SetTPCindex(i);
650 fEvent->AddTrack(&iotrack);
651 continue;
652 }
653 }
654
655 if ( (pt->GetNumberOfClusters()>15)) {
656 Int_t found,foundable,shared;
657 pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
658 if (found<15) continue;
e7eb17e4 659 if (foundable<=0) continue;
b9671574 660 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
51ad6848 661 if (float(found)/float(foundable)<0.8) continue;
662 //
ada522d7 663 iotrack.~AliESDtrack();
664 new(&iotrack) AliESDtrack;
51ad6848 665 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
666 iotrack.SetTPCPoints(pt->GetPoints());
667 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 668 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 669 MakeESDBitmaps(pt, &iotrack);
81e97e0d 670 // iotrack.SetTPCpid(pt->fTPCr);
a42a6bae 671 //iotrack.SetTPCindex(i);
672 fEvent->AddTrack(&iotrack);
673 continue;
674 }
91162307 675 }
6fbe1e5c 676 // >> account for suppressed tracks in the kink indices (RS)
677 int nESDtracks = fEvent->GetNumberOfTracks();
678 for (int it=nESDtracks;it--;) {
679 AliESDtrack* esdTr = fEvent->GetTrack(it);
680 if (!esdTr || !esdTr->GetKinkIndex(0)) continue;
681 for (int ik=0;ik<3;ik++) {
682 int knkId=0;
683 if (!(knkId=esdTr->GetKinkIndex(ik))) break; // no more kinks for this track
684 AliESDkink* kink = fEvent->GetKink(TMath::Abs(knkId)-1);
685 if (!kink) {
686 AliError(Form("ESDTrack%d refers to non-existing kink %d",it,TMath::Abs(knkId)-1));
687 continue;
688 }
689 kink->SetIndex(it, knkId<0 ? 0:1); // update track index of the kink: mother at 0, daughter at 1
690 }
691 }
ada522d7 692
ec26e231 693 // << account for suppressed tracks in the kink indices (RS)
694 AliInfo(Form("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks()));
695
d26d9159 696}
697
d26d9159 698
1c53abe2 699
1c53abe2 700
701
829455ad 702Double_t AliTPCtracker::ErrY2(AliTPCseed* seed, const AliTPCclusterMI * cl){
91162307 703 //
704 //
fd065ea2 705 // Use calibrated cluster error from OCDB
91162307 706 //
fd065ea2 707 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
91162307 708 //
47af7ca4 709 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
91162307 710 Int_t ctype = cl->GetType();
fd065ea2 711 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
712 Double_t angle = seed->GetSnp()*seed->GetSnp();
e0e13b88 713 angle = TMath::Sqrt(TMath::Abs(angle/(1.-angle)));
fd065ea2 714 Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
715 if (ctype<0) {
716 erry2+=0.5; // edge cluster
717 }
718 erry2*=erry2;
0b2c141b 719 Double_t addErr=0;
720 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
f858edae 721 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
0b2c141b 722 erry2+=addErr*addErr;
fd065ea2 723 seed->SetErrorY2(erry2);
724 //
725 return erry2;
726
727//calculate look-up table at the beginning
728// static Bool_t ginit = kFALSE;
729// static Float_t gnoise1,gnoise2,gnoise3;
730// static Float_t ggg1[10000];
731// static Float_t ggg2[10000];
732// static Float_t ggg3[10000];
733// static Float_t glandau1[10000];
734// static Float_t glandau2[10000];
735// static Float_t glandau3[10000];
736// //
737// static Float_t gcor01[500];
738// static Float_t gcor02[500];
739// static Float_t gcorp[500];
740// //
1c53abe2 741
fd065ea2 742// //
743// if (ginit==kFALSE){
744// for (Int_t i=1;i<500;i++){
745// Float_t rsigma = float(i)/100.;
746// gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
747// gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
748// gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
749// }
750
751// //
752// for (Int_t i=3;i<10000;i++){
753// //
754// //
755// // inner sector
756// Float_t amp = float(i);
757// Float_t padlength =0.75;
758// gnoise1 = 0.0004/padlength;
759// Float_t nel = 0.268*amp;
760// Float_t nprim = 0.155*amp;
47af7ca4 761// ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
fd065ea2 762// glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
763// if (glandau1[i]>1) glandau1[i]=1;
764// glandau1[i]*=padlength*padlength/12.;
765// //
766// // outer short
767// padlength =1.;
768// gnoise2 = 0.0004/padlength;
769// nel = 0.3*amp;
770// nprim = 0.133*amp;
47af7ca4 771// ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 772// glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
773// if (glandau2[i]>1) glandau2[i]=1;
774// glandau2[i]*=padlength*padlength/12.;
775// //
776// //
777// // outer long
778// padlength =1.5;
779// gnoise3 = 0.0004/padlength;
780// nel = 0.3*amp;
781// nprim = 0.133*amp;
47af7ca4 782// ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 783// glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
784// if (glandau3[i]>1) glandau3[i]=1;
785// glandau3[i]*=padlength*padlength/12.;
786// //
787// }
788// ginit = kTRUE;
789// }
790// //
791// //
792// //
793// Int_t amp = int(TMath::Abs(cl->GetQ()));
794// if (amp>9999) {
795// seed->SetErrorY2(1.);
796// return 1.;
797// }
798// Float_t snoise2;
47af7ca4 799// Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
fd065ea2 800// Int_t ctype = cl->GetType();
801// Float_t padlength= GetPadPitchLength(seed->GetRow());
802// Double_t angle2 = seed->GetSnp()*seed->GetSnp();
803// angle2 = angle2/(1-angle2);
804// //
805// //cluster "quality"
806// Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
807// Float_t res;
808// //
809// if (fSectors==fInnerSec){
810// snoise2 = gnoise1;
811// res = ggg1[amp]*z+glandau1[amp]*angle2;
812// if (ctype==0) res *= gcor01[rsigmay];
813// if ((ctype>0)){
814// res+=0.002;
815// res*= gcorp[rsigmay];
816// }
817// }
818// else {
819// if (padlength<1.1){
820// snoise2 = gnoise2;
821// res = ggg2[amp]*z+glandau2[amp]*angle2;
822// if (ctype==0) res *= gcor02[rsigmay];
823// if ((ctype>0)){
824// res+=0.002;
825// res*= gcorp[rsigmay];
826// }
827// }
828// else{
829// snoise2 = gnoise3;
830// res = ggg3[amp]*z+glandau3[amp]*angle2;
831// if (ctype==0) res *= gcor02[rsigmay];
832// if ((ctype>0)){
833// res+=0.002;
834// res*= gcorp[rsigmay];
835// }
836// }
837// }
838
839// if (ctype<0){
840// res+=0.005;
841// res*=2.4; // overestimate error 2 times
842// }
843// res+= snoise2;
91162307 844
fd065ea2 845// if (res<2*snoise2)
846// res = 2*snoise2;
91162307 847
fd065ea2 848// seed->SetErrorY2(res);
849// return res;
1c53abe2 850
851
91162307 852}
c9427e08 853
854
855
829455ad 856Double_t AliTPCtracker::ErrZ2(AliTPCseed* seed, const AliTPCclusterMI * cl){
91162307 857 //
858 //
fd065ea2 859 // Use calibrated cluster error from OCDB
91162307 860 //
fd065ea2 861 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
91162307 862 //
47af7ca4 863 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
91162307 864 Int_t ctype = cl->GetType();
fd065ea2 865 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
91162307 866 //
3f82c4f2 867 Double_t angle2 = seed->GetSnp()*seed->GetSnp();
91162307 868 angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
e0e13b88 869 Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
fd065ea2 870 Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
871 if (ctype<0) {
872 errz2+=0.5; // edge cluster
91162307 873 }
1af5da7e 874 errz2*=errz2;
0b2c141b 875 Double_t addErr=0;
876 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
f858edae 877 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
0b2c141b 878 errz2+=addErr*addErr;
fd065ea2 879 seed->SetErrorZ2(errz2);
880 //
881 return errz2;
91162307 882
fd065ea2 883
884
885// //seed->SetErrorY2(0.1);
886// //return 0.1;
887// //calculate look-up table at the beginning
888// static Bool_t ginit = kFALSE;
889// static Float_t gnoise1,gnoise2,gnoise3;
890// static Float_t ggg1[10000];
891// static Float_t ggg2[10000];
892// static Float_t ggg3[10000];
893// static Float_t glandau1[10000];
894// static Float_t glandau2[10000];
895// static Float_t glandau3[10000];
896// //
897// static Float_t gcor01[1000];
898// static Float_t gcor02[1000];
899// static Float_t gcorp[1000];
900// //
901
902// //
903// if (ginit==kFALSE){
904// for (Int_t i=1;i<1000;i++){
905// Float_t rsigma = float(i)/100.;
906// gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
907// gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
908// gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
909// }
910
911// //
912// for (Int_t i=3;i<10000;i++){
913// //
914// //
915// // inner sector
916// Float_t amp = float(i);
917// Float_t padlength =0.75;
918// gnoise1 = 0.0004/padlength;
919// Float_t nel = 0.268*amp;
920// Float_t nprim = 0.155*amp;
47af7ca4 921// ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
fd065ea2 922// glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
923// if (glandau1[i]>1) glandau1[i]=1;
924// glandau1[i]*=padlength*padlength/12.;
925// //
926// // outer short
927// padlength =1.;
928// gnoise2 = 0.0004/padlength;
929// nel = 0.3*amp;
930// nprim = 0.133*amp;
47af7ca4 931// ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 932// glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
933// if (glandau2[i]>1) glandau2[i]=1;
934// glandau2[i]*=padlength*padlength/12.;
935// //
936// //
937// // outer long
938// padlength =1.5;
939// gnoise3 = 0.0004/padlength;
940// nel = 0.3*amp;
941// nprim = 0.133*amp;
47af7ca4 942// ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 943// glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
944// if (glandau3[i]>1) glandau3[i]=1;
945// glandau3[i]*=padlength*padlength/12.;
946// //
947// }
948// ginit = kTRUE;
949// }
950// //
951// //
952// //
953// Int_t amp = int(TMath::Abs(cl->GetQ()));
954// if (amp>9999) {
955// seed->SetErrorY2(1.);
956// return 1.;
957// }
958// Float_t snoise2;
47af7ca4 959// Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
fd065ea2 960// Int_t ctype = cl->GetType();
961// Float_t padlength= GetPadPitchLength(seed->GetRow());
962// //
963// Double_t angle2 = seed->GetSnp()*seed->GetSnp();
964// // if (angle2<0.6) angle2 = 0.6;
965// angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
966// //
967// //cluster "quality"
968// Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
969// Float_t res;
970// //
971// if (fSectors==fInnerSec){
972// snoise2 = gnoise1;
973// res = ggg1[amp]*z+glandau1[amp]*angle2;
974// if (ctype==0) res *= gcor01[rsigmaz];
975// if ((ctype>0)){
976// res+=0.002;
977// res*= gcorp[rsigmaz];
978// }
979// }
980// else {
981// if (padlength<1.1){
982// snoise2 = gnoise2;
983// res = ggg2[amp]*z+glandau2[amp]*angle2;
984// if (ctype==0) res *= gcor02[rsigmaz];
985// if ((ctype>0)){
986// res+=0.002;
987// res*= gcorp[rsigmaz];
988// }
989// }
990// else{
991// snoise2 = gnoise3;
992// res = ggg3[amp]*z+glandau3[amp]*angle2;
993// if (ctype==0) res *= gcor02[rsigmaz];
994// if ((ctype>0)){
995// res+=0.002;
996// res*= gcorp[rsigmaz];
997// }
998// }
999// }
1000
1001// if (ctype<0){
1002// res+=0.002;
1003// res*=1.3;
1004// }
1005// if ((ctype<0) &&amp<70){
1006// res+=0.002;
1007// res*=1.3;
1008// }
1009// res += snoise2;
1010// if (res<2*snoise2)
1011// res = 2*snoise2;
1012// if (res>3) res =3;
1013// seed->SetErrorZ2(res);
1014// return res;
91162307 1015}
1016
1017
1018
91162307 1019
1c53abe2 1020
829455ad 1021void AliTPCtracker::RotateToLocal(AliTPCseed *seed)
c9427e08 1022{
1023 //rotate to track "local coordinata
1024 Float_t x = seed->GetX();
1025 Float_t y = seed->GetY();
1026 Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
91162307 1027
c9427e08 1028 if (y > ymax) {
b9671574 1029 seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
c9427e08 1030 if (!seed->Rotate(fSectors->GetAlpha()))
1031 return;
1032 } else if (y <-ymax) {
b9671574 1033 seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
c9427e08 1034 if (!seed->Rotate(-fSectors->GetAlpha()))
1035 return;
1036 }
1c53abe2 1037
c9427e08 1038}
1c53abe2 1039
1040
1041
1c53abe2 1042//_____________________________________________________________________________
829455ad 1043Double_t AliTPCtracker::F1old(Double_t x1,Double_t y1,
1c53abe2 1044 Double_t x2,Double_t y2,
47af7ca4 1045 Double_t x3,Double_t y3) const
1c53abe2 1046{
1047 //-----------------------------------------------------------------
1048 // Initial approximation of the track curvature
1049 //-----------------------------------------------------------------
1050 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1051 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1052 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1053 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1054 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1055
1056 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
91162307 1057 if ( xr*xr+yr*yr<=0.00000000000001) return 100;
1c53abe2 1058 return -xr*yr/sqrt(xr*xr+yr*yr);
1059}
1060
1061
91162307 1062
1c53abe2 1063//_____________________________________________________________________________
829455ad 1064Double_t AliTPCtracker::F1(Double_t x1,Double_t y1,
91162307 1065 Double_t x2,Double_t y2,
47af7ca4 1066 Double_t x3,Double_t y3) const
91162307 1067{
1068 //-----------------------------------------------------------------
1069 // Initial approximation of the track curvature
1070 //-----------------------------------------------------------------
1071 x3 -=x1;
1072 x2 -=x1;
1073 y3 -=y1;
1074 y2 -=y1;
1075 //
1076 Double_t det = x3*y2-x2*y3;
6e23caff 1077 if (TMath::Abs(det)<1e-10){
91162307 1078 return 100;
1079 }
1080 //
1081 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1082 Double_t x0 = x3*0.5-y3*u;
1083 Double_t y0 = y3*0.5+x3*u;
1084 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1085 if (det<0) c2*=-1;
1086 return c2;
1087}
1088
1089
829455ad 1090Double_t AliTPCtracker::F2(Double_t x1,Double_t y1,
1c53abe2 1091 Double_t x2,Double_t y2,
47af7ca4 1092 Double_t x3,Double_t y3) const
91162307 1093{
1094 //-----------------------------------------------------------------
1095 // Initial approximation of the track curvature
1096 //-----------------------------------------------------------------
1097 x3 -=x1;
1098 x2 -=x1;
1099 y3 -=y1;
1100 y2 -=y1;
1101 //
1102 Double_t det = x3*y2-x2*y3;
6e23caff 1103 if (TMath::Abs(det)<1e-10) {
91162307 1104 return 100;
1105 }
1106 //
1107 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1108 Double_t x0 = x3*0.5-y3*u;
1109 Double_t y0 = y3*0.5+x3*u;
1110 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1111 if (det<0) c2*=-1;
1112 x0+=x1;
1113 x0*=c2;
1114 return x0;
1115}
1116
1117
1118
1119//_____________________________________________________________________________
829455ad 1120Double_t AliTPCtracker::F2old(Double_t x1,Double_t y1,
91162307 1121 Double_t x2,Double_t y2,
47af7ca4 1122 Double_t x3,Double_t y3) const
1c53abe2 1123{
1124 //-----------------------------------------------------------------
1125 // Initial approximation of the track curvature times center of curvature
1126 //-----------------------------------------------------------------
1127 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1128 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1129 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1130 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1131 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1132
1133 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1134
1135 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1136}
1137
1138//_____________________________________________________________________________
829455ad 1139Double_t AliTPCtracker::F3(Double_t x1,Double_t y1,
1c53abe2 1140 Double_t x2,Double_t y2,
47af7ca4 1141 Double_t z1,Double_t z2) const
1c53abe2 1142{
1143 //-----------------------------------------------------------------
1144 // Initial approximation of the tangent of the track dip angle
1145 //-----------------------------------------------------------------
1146 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1147}
1148
1149
829455ad 1150Double_t AliTPCtracker::F3n(Double_t x1,Double_t y1,
91162307 1151 Double_t x2,Double_t y2,
47af7ca4 1152 Double_t z1,Double_t z2, Double_t c) const
1c53abe2 1153{
91162307 1154 //-----------------------------------------------------------------
1155 // Initial approximation of the tangent of the track dip angle
1156 //-----------------------------------------------------------------
1157
1158 // Double_t angle1;
1159
1160 //angle1 = (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1c53abe2 1161 //
91162307 1162 Double_t d = TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1163 if (TMath::Abs(d*c*0.5)>1) return 0;
1164 // Double_t angle2 = TMath::ASin(d*c*0.5);
b67e07dc 1165 // Double_t angle2 = AliTPCFastMath::FastAsin(d*c*0.5);
1166 Double_t angle2 = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): AliTPCFastMath::FastAsin(d*c*0.5);
91162307 1167
1168 angle2 = (z1-z2)*c/(angle2*2.);
1169 return angle2;
1170}
1171
829455ad 1172Bool_t AliTPCtracker::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
91162307 1173{//-----------------------------------------------------------------
1174 // This function find proloncation of a track to a reference plane x=x2.
1175 //-----------------------------------------------------------------
1176
1177 Double_t dx=x2-x1;
1178
1179 if (TMath::Abs(x[4]*x1 - x[2]) >= 0.999) {
1180 return kFALSE;
1c53abe2 1181 }
f8aae377 1182
bfd20868 1183 Double_t c1=x[4]*x1 - x[2], r1=TMath::Sqrt((1.-c1)*(1.+c1));
1184 Double_t c2=x[4]*x2 - x[2], r2=TMath::Sqrt((1.-c2)*(1.+c2));
91162307 1185 y = x[0];
1186 z = x[1];
1187
1188 Double_t dy = dx*(c1+c2)/(r1+r2);
1189 Double_t dz = 0;
1190 //
1191 Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1192
1193 if (TMath::Abs(delta)>0.01){
1194 dz = x[3]*TMath::ASin(delta)/x[4];
1195 }else{
b67e07dc 1196 dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
91162307 1197 }
1198
b67e07dc 1199 //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
f8aae377 1200
91162307 1201 y+=dy;
1202 z+=dz;
1203
1204 return kTRUE;
1c53abe2 1205}
1206
829455ad 1207Int_t AliTPCtracker::LoadClusters (TTree *const tree)
d26d9159 1208{
544c295f 1209 // load clusters
d26d9159 1210 //
1211 fInput = tree;
1212 return LoadClusters();
1213}
91162307 1214
af86c1fd 1215
829455ad 1216Int_t AliTPCtracker::LoadClusters(const TObjArray *arr)
af86c1fd 1217{
1218 //
1219 // load clusters to the memory
e7de6656 1220 AliTPCClustersRow *clrow = new AliTPCClustersRow("AliTPCclusterMI");
af86c1fd 1221 Int_t lower = arr->LowerBound();
1222 Int_t entries = arr->GetEntriesFast();
77f88633 1223
af86c1fd 1224 for (Int_t i=lower; i<entries; i++) {
1225 clrow = (AliTPCClustersRow*) arr->At(i);
77f88633 1226 if(!clrow) continue;
1227 if(!clrow->GetArray()) continue;
1228
af86c1fd 1229 //
1230 Int_t sec,row;
47af7ca4 1231 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
77f88633 1232
af86c1fd 1233 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1234 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1235 }
1236 //
1237 if (clrow->GetArray()->GetEntriesFast()<=0) continue;
bd26fa83 1238 AliTPCtrackerRow * tpcrow=0;
af86c1fd 1239 Int_t left=0;
1240 if (sec<fkNIS*2){
1241 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1242 left = sec/fkNIS;
1243 }
1244 else{
1245 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1246 left = (sec-fkNIS*2)/fkNOS;
1247 }
1248 if (left ==0){
1249 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
77f88633 1250 for (Int_t j=0;j<tpcrow->GetN1();++j)
1251 tpcrow->SetCluster1(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
af86c1fd 1252 }
1253 if (left ==1){
1254 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
77f88633 1255 for (Int_t j=0;j<tpcrow->GetN2();++j)
bfa00fba 1256 tpcrow->SetCluster2(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
af86c1fd 1257 }
e7de6656 1258 clrow->GetArray()->Clear("C");
af86c1fd 1259 }
1260 //
1261 delete clrow;
1262 LoadOuterSectors();
1263 LoadInnerSectors();
1264 return 0;
1265}
1266
829455ad 1267Int_t AliTPCtracker::LoadClusters(const TClonesArray *arr)
aa7f1a5a 1268{
1269 //
1270 // load clusters to the memory from one
1271 // TClonesArray
1272 //
1273 AliTPCclusterMI *clust=0;
98ee6d31 1274 Int_t count[72][96] = { {0} , {0} };
aa7f1a5a 1275
1276 // loop over clusters
1277 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1278 clust = (AliTPCclusterMI*)arr->At(icl);
1279 if(!clust) continue;
1280 //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
1281
1282 // transform clusters
1283 Transform(clust);
1284
1285 // count clusters per pad row
1286 count[clust->GetDetector()][clust->GetRow()]++;
1287 }
1288
1289 // insert clusters to sectors
1290 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1291 clust = (AliTPCclusterMI*)arr->At(icl);
1292 if(!clust) continue;
1293
1294 Int_t sec = clust->GetDetector();
1295 Int_t row = clust->GetRow();
98ee6d31 1296
1297 // filter overlapping pad rows needed by HLT
1298 if(sec<fkNIS*2) { //IROCs
1299 if(row == 30) continue;
1300 }
1301 else { // OROCs
1302 if(row == 27 || row == 76) continue;
1303 }
1304
2a97785a 1305 // Int_t left=0;
aa7f1a5a 1306 if (sec<fkNIS*2){
2a97785a 1307 // left = sec/fkNIS;
47af7ca4 1308 fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fkParam);
aa7f1a5a 1309 }
1310 else{
2a97785a 1311 // left = (sec-fkNIS*2)/fkNOS;
47af7ca4 1312 fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fkParam);
aa7f1a5a 1313 }
1314 }
1315
98ee6d31 1316 // Load functions must be called behind LoadCluster(TClonesArray*)
1317 // needed by HLT
1318 //LoadOuterSectors();
1319 //LoadInnerSectors();
aa7f1a5a 1320
1321 return 0;
1322}
1323
af86c1fd 1324
829455ad 1325Int_t AliTPCtracker::LoadClusters()
1c53abe2 1326{
1327 //
1328 // load clusters to the memory
bfa00fba 1329 static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
91162307 1330 //
1331 // TTree * tree = fClustersArray.GetTree();
9a836cc2 1332 AliInfo("LoadClusters()\n");
91162307 1333
1334 TTree * tree = fInput;
1335 TBranch * br = tree->GetBranch("Segment");
1336 br->SetAddress(&clrow);
bad6eb00 1337
1338 // Conversion of pad, row coordinates in local tracking coords.
1339 // Could be skipped here; is already done in clusterfinder
1340
91162307 1341 Int_t j=Int_t(tree->GetEntries());
1c53abe2 1342 for (Int_t i=0; i<j; i++) {
91162307 1343 br->GetEntry(i);
1344 //
1345 Int_t sec,row;
47af7ca4 1346 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
0201b65c 1347 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
75fb37cc 1348 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
0201b65c 1349 }
91162307 1350 //
bd26fa83 1351 AliTPCtrackerRow * tpcrow=0;
91162307 1352 Int_t left=0;
1353 if (sec<fkNIS*2){
1354 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1355 left = sec/fkNIS;
1356 }
1357 else{
1358 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1359 left = (sec-fkNIS*2)/fkNOS;
1360 }
1361 if (left ==0){
b9671574 1362 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
77f88633 1363 for (Int_t k=0;k<tpcrow->GetN1();++k)
1364 tpcrow->SetCluster1(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
91162307 1365 }
1366 if (left ==1){
b9671574 1367 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
77f88633 1368 for (Int_t k=0;k<tpcrow->GetN2();++k)
bfa00fba 1369 tpcrow->SetCluster2(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
91162307 1370 }
1c53abe2 1371 }
91162307 1372 //
bfa00fba 1373 clrow->Clear("C");
91162307 1374 LoadOuterSectors();
1375 LoadInnerSectors();
832977ba 1376 if (AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection()) ApplyTailCancellation();
91162307 1377 return 0;
1c53abe2 1378}
1379
1380
829455ad 1381void AliTPCtracker::UnloadClusters()
91162307 1382{
1383 //
1384 // unload clusters from the memory
1385 //
1386 Int_t nrows = fOuterSec->GetNRows();
1387 for (Int_t sec = 0;sec<fkNOS;sec++)
1388 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1389 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
982aff31 1390 // if (tpcrow){
1391 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1392 // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1393 //}
1394 tpcrow->ResetClusters();
1c53abe2 1395 }
91162307 1396 //
1397 nrows = fInnerSec->GetNRows();
1398 for (Int_t sec = 0;sec<fkNIS;sec++)
1399 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1400 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
982aff31 1401 //if (tpcrow){
1402 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1403 //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1404 //}
1405 tpcrow->ResetClusters();
91162307 1406 }
1407
1408 return ;
1c53abe2 1409}
1410
829455ad 1411void AliTPCtracker::FillClusterArray(TObjArray* array) const{
002af263 1412 //
1413 // Filling cluster to the array - For visualization purposes
1414 //
1415 Int_t nrows=0;
1416 nrows = fOuterSec->GetNRows();
1417 for (Int_t sec = 0;sec<fkNOS;sec++)
1418 for (Int_t row = 0;row<nrows;row++){
1419 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1420 if (!tpcrow) continue;
1421 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1422 array->AddLast((TObject*)((*tpcrow)[icl]));
1423 }
1424 }
1425 nrows = fInnerSec->GetNRows();
1426 for (Int_t sec = 0;sec<fkNIS;sec++)
1427 for (Int_t row = 0;row<nrows;row++){
1428 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1429 if (!tpcrow) continue;
1430 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1431 array->AddLast((TObject*)(*tpcrow)[icl]);
1432 }
1433 }
1434}
1435
1436
829455ad 1437void AliTPCtracker::Transform(AliTPCclusterMI * cluster){
893468d9 1438 //
544c295f 1439 // transformation
893468d9 1440 //
3f3549a3 1441 AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1442 AliTPCTransform *transform = calibDB->GetTransform() ;
24db6af7 1443 if (!transform) {
1444 AliFatal("Tranformations not in calibDB");
ec26e231 1445 return;
24db6af7 1446 }
239f39b1 1447 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
2942f542 1448 Double_t x[3]={static_cast<Double_t>(cluster->GetRow()),static_cast<Double_t>(cluster->GetPad()),static_cast<Double_t>(cluster->GetTimeBin())};
24db6af7 1449 Int_t i[1]={cluster->GetDetector()};
022ee144 1450 transform->Transform(x,i,0,1);
afbaa016 1451 // if (cluster->GetDetector()%36>17){
1452 // x[1]*=-1;
1453 //}
022ee144 1454
24db6af7 1455 //
1456 // in debug mode check the transformation
1457 //
16299eac 1458 if (AliTPCReconstructor::StreamLevel()>2) {
af86c1fd 1459 Float_t gx[3];
1460 cluster->GetGlobalXYZ(gx);
002af263 1461 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
24db6af7 1462 TTreeSRedirector &cstream = *fDebugStreamer;
1463 cstream<<"Transform"<<
002af263 1464 "event="<<event<<
24db6af7 1465 "x0="<<x[0]<<
1466 "x1="<<x[1]<<
1467 "x2="<<x[2]<<
af86c1fd 1468 "gx0="<<gx[0]<<
1469 "gx1="<<gx[1]<<
1470 "gx2="<<gx[2]<<
24db6af7 1471 "Cl.="<<cluster<<
1472 "\n";
1473 }
1474 cluster->SetX(x[0]);
1475 cluster->SetY(x[1]);
1476 cluster->SetZ(x[2]);
19b00333 1477 // The old stuff:
0201b65c 1478 //
1479 //
1480 //
47af7ca4 1481 //if (!fkParam->IsGeoRead()) fkParam->ReadGeoMatrices();
3f3549a3 1482 if (AliTPCReconstructor::GetRecoParam()->GetUseSectorAlignment() && (!calibDB->HasAlignmentOCDB())){
1483 TGeoHMatrix *mat = fkParam->GetClusterMatrix(cluster->GetDetector());
1484 //TGeoHMatrix mat;
1485 Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1486 Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1487 if (mat) mat->LocalToMaster(pos,posC);
1488 else{
1489 // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
1490 }
1491 cluster->SetX(posC[0]);
1492 cluster->SetY(posC[1]);
1493 cluster->SetZ(posC[2]);
a7760332 1494 }
0201b65c 1495}
1c53abe2 1496
9a836cc2 1497void AliTPCtracker::ApplyTailCancellation(){
7bc5f28b 1498 //
9a836cc2 1499 // Correct the cluster charge for the ion tail effect
7bc5f28b 1500 // The TimeResponse function accessed via AliTPCcalibDB (TPC/Calib/IonTail)
1501 //
7bc5f28b 1502
9a836cc2 1503 // Retrieve
1504 TObjArray *ionTailArr = (TObjArray*)AliTPCcalibDB::Instance()->GetIonTailArray();
1505 if (!ionTailArr) {AliFatal("TPC - Missing IonTail OCDB object");}
1506 TObject *rocFactorIROC = ionTailArr->FindObject("factorIROC");
1507 TObject *rocFactorOROC = ionTailArr->FindObject("factorOROC");
1508 Float_t factorIROC = (atof(rocFactorIROC->GetTitle()));
1509 Float_t factorOROC = (atof(rocFactorOROC->GetTitle()));
1510
1511 // find the number of clusters for the whole TPC (nclALL)
1512 Int_t nclALL=0;
1513 for (Int_t isector=0; isector<36; isector++){
1514 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1515 nclALL += sector.GetNClInSector(0);
1516 nclALL += sector.GetNClInSector(1);
1517 }
1518
1519 // start looping over all clusters
1520 for (Int_t iside=0; iside<2; iside++){ // loop over sides
7bc5f28b 1521 //
1522 //
9a836cc2 1523 for (Int_t secType=0; secType<2; secType++){ //loop over inner or outer sector
1524 // cache experimantal tuning factor for the different chamber type
1525 const Float_t ampfactor = (secType==0)?factorIROC:factorOROC;
1526 std::cout << " ampfactor = " << ampfactor << std::endl;
7bc5f28b 1527 //
9a836cc2 1528 for (Int_t sec = 0;sec<fkNOS;sec++){ //loop overs sectors
1529 //
1530 //
1531 // Cache time response functions and their positons to COG of the cluster
1532 TGraphErrors ** graphRes = new TGraphErrors *[20];
1533 Float_t * indexAmpGraphs = new Float_t[20];
1534 for (Int_t icache=0; icache<20; icache++)
1535 {
1536 graphRes[icache] = NULL;
1537 indexAmpGraphs[icache] = 0;
1538 }
1539 ///////////////////////////// --> position fo sie loop
d4559772 1540 if (!AliTPCcalibDB::Instance()->GetTailcancelationGraphs(sec+36*secType+18*iside,graphRes,indexAmpGraphs))
1541 {
1542 continue;
1543 }
9a836cc2 1544
1545 AliTPCtrackerSector &sector= (secType==0)?fInnerSec[sec]:fOuterSec[sec];
1546 Int_t nrows = sector.GetNRows(); // number of rows
1547 Int_t nclSector = sector.GetNClInSector(iside); // ncl per sector to be used for debugging
1548
1549 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1550
1551 AliTPCtrackerRow& tpcrow = sector[row]; // row object
1552 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1553 if (iside>0) ncl=tpcrow.GetN2();
1554
1555 // Order clusters in time for the proper correction of ion tail
1556 Float_t qTotArray[ncl]; // arrays to be filled with modified Qtot and Qmax values in order to avoid float->int conversion
1557 Float_t qMaxArray[ncl];
1558 Int_t sortedClusterIndex[ncl];
1559 Float_t sortedClusterTimeBin[ncl];
1560 TObjArray *rowClusterArray = new TObjArray(ncl); // cache clusters for each row
1561 for (Int_t i=0;i<ncl;i++)
1562 {
1563 qTotArray[i]=0;
1564 qMaxArray[i]=0;
1565 sortedClusterIndex[i]=i;
1566 AliTPCclusterMI *rowcl= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1567 if (rowcl) {
1568 rowClusterArray->AddAt(rowcl,i);
1569 } else {
1570 rowClusterArray->RemoveAt(i);
1571 }
1572 // Fill the timebin info to the array in order to sort wrt tb
1573 if (!rowcl) {
1574 sortedClusterTimeBin[i]=0.0;
1575 } else {
1576 sortedClusterTimeBin[i] = rowcl->GetTimeBin();
1577 }
1578
1579 }
1580 TMath::Sort(ncl,sortedClusterTimeBin,sortedClusterIndex,kFALSE); // sort clusters in time
1581
1582 // Main cluster correction loops over clusters
1583 for (Int_t icl0=0; icl0<ncl;icl0++){ // first loop over clusters
1584
1585 AliTPCclusterMI *cl0= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl0]));
1586
1587 if (!cl0) continue;
1588 Int_t nclPad=0;
1589 for (Int_t icl1=0; icl1<ncl;icl1++){ // second loop over clusters
1590
1591 AliTPCclusterMI *cl1= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl1]));
1592 if (!cl1) continue;
1593 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())>4) continue; // no contribution if far away in pad direction
1594 if (cl0->GetTimeBin()<= cl1->GetTimeBin()) continue; // no contibution to the tail if later
1595 if (TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin())>600) continue; // out of the range of response function
1596
1597 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())<4) nclPad++; // count ncl for every pad for debugging
1598
1599 // Get the correction values for Qmax and Qtot and find total correction for a given cluster
1600 Double_t ionTailMax=0.;
1601 Double_t ionTailTotal=0.;
1602 GetTailValue(ampfactor,ionTailMax,ionTailTotal,graphRes,indexAmpGraphs,cl0,cl1);
1603 ionTailMax=TMath::Abs(ionTailMax);
1604 ionTailTotal=TMath::Abs(ionTailTotal);
1605 qTotArray[icl0]+=ionTailTotal;
1606 qMaxArray[icl0]+=ionTailMax;
1607
1608 // Dump some info for debugging while clusters are being corrected
518f85b7 1609 if (AliTPCReconstructor::StreamLevel()>2) {
9a836cc2 1610 TTreeSRedirector &cstream = *fDebugStreamer;
1611 if (gRandom->Rndm() > 0.999){
1612 cstream<<"IonTail"<<
1613 "cl0.=" <<cl0 << // cluster 0 (to be corrected)
1614 "cl1.=" <<cl1 << // cluster 1 (previous cluster)
1615 "ionTailTotal=" <<ionTailTotal << // ion Tail from cluster 1 contribution to cluster0
1616 "ionTailMax=" <<ionTailMax << // ion Tail from cluster 1 contribution to cluster0
1617 "\n";
1618 }
1619 }// dump the results to the debug streamer if in debug mode
1620
1621 }//end of second loop over clusters
1622
1623 // Set corrected values of the corrected cluster
1624 cl0->SetQ(TMath::Nint(Float_t(cl0->GetQ())+Float_t(qTotArray[icl0])));
1625 cl0->SetMax(TMath::Nint(Float_t(cl0->GetMax())+qMaxArray[icl0]));
1626
1627 // Dump some info for debugging after clusters are corrected
518f85b7 1628 if (AliTPCReconstructor::StreamLevel()>2) {
9a836cc2 1629 TTreeSRedirector &cstream = *fDebugStreamer;
1630 if (gRandom->Rndm() > 0.999){
1631 cstream<<"IonTailCorrected"<<
1632 "cl0.=" << cl0 << // cluster 0 with huge Qmax
1633 "ionTailTotalPerCluster=" << qTotArray[icl0] <<
1634 "ionTailMaxPerCluster=" << qMaxArray[icl0] <<
1635 "nclALL=" << nclALL <<
1636 "nclSector=" << nclSector <<
1637 "nclRow=" << ncl <<
1638 "nclPad=" << nclPad <<
1639 "row=" << row <<
1640 "sector=" << sec <<
1641 "icl0=" << icl0 <<
1642 "\n";
1643 }
1644 }// dump the results to the debug streamer if in debug mode
1645
1646 }//end of first loop over cluster
1647 delete rowClusterArray;
1648 }//end of loop over rows
1649 for (int i=0; i<20; i++) delete graphRes[i];
1650 delete [] graphRes;
1651 delete [] indexAmpGraphs;
1652
1653 }//end of loop over sectors
1654 }//end of loop over IROC/OROC
1655 }// end of side loop
7bc5f28b 1656}
9a836cc2 1657//_____________________________________________________________________________
5a516e0a 1658void AliTPCtracker::GetTailValue(Float_t ampfactor,Double_t &ionTailMax, Double_t &ionTailTotal,TGraphErrors **graphRes,Float_t *indexAmpGraphs,AliTPCclusterMI *cl0,AliTPCclusterMI *cl1){
9a836cc2 1659
1660 //
1661 // Function in order to calculate the amount of the correction to be added for a given cluster, return values are ionTailTaoltal and ionTailMax
1662 //
7bc5f28b 1663
9a836cc2 1664 const Double_t kMinPRF = 0.5; // minimal PRF width
1665 ionTailTotal = 0.; // correction value to be added to Qtot of cl0
1666 ionTailMax = 0.; // correction value to be added to Qmax of cl0
1667
1668 Float_t qTot0 = cl0->GetQ(); // cl0 Qtot info
1669 Float_t qTot1 = cl1->GetQ(); // cl1 Qtot info
1670 Int_t sectorPad = cl1->GetDetector(); // sector number
1671 Int_t padcl0 = TMath::Nint(cl0->GetPad()); // pad0
1672 Int_t padcl1 = TMath::Nint(cl1->GetPad()); // pad1
1673 Float_t padWidth = (sectorPad < 36)?0.4:0.6; // pad width in cm
1674 const Int_t deltaTimebin = TMath::Nint(TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin()))+12; //distance between pads of cl1 and cl0 increased by 12 bins
1675 Double_t rmsPad1 = (cl1->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl1->GetSigmaY2())/padWidth);
1676 Double_t rmsPad0 = (cl0->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl0->GetSigmaY2())/padWidth);
1677
a3986da2 1678
9a836cc2 1679 Double_t sumAmp1=0.;
1680 for (Int_t idelta =-2; idelta<=2;idelta++){
1681 sumAmp1+=TMath::Exp(-idelta*idelta/(2*rmsPad1));
1682 }
7bc5f28b 1683
9a836cc2 1684 Double_t sumAmp0=0.;
1685 for (Int_t idelta =-2; idelta<=2;idelta++){
1686 sumAmp0+=TMath::Exp(-idelta*idelta/(2*rmsPad0));
1687 }
7bc5f28b 1688
9a836cc2 1689 // Apply the correction --> cl1 corrects cl0 (loop over cl1's pads and find which pads of cl0 are going to be corrected)
1690 Int_t padScan=2; // +-2 pad-timebin window will be scanned
1691 for (Int_t ipad1=padcl1-padScan; ipad1<=padcl1+padScan; ipad1++) {
1692 //
1693 //
1694 Float_t deltaPad1 = TMath::Abs(cl1->GetPad()-(Float_t)ipad1);
1695 Double_t amp1 = (TMath::Exp(-(deltaPad1*deltaPad1)/(2*rmsPad1)))/sumAmp1; // normalized pad response function
1696 Float_t qTotPad1 = amp1*qTot1; // used as a factor to multipliy the response function
1697
1698 // find closest value of cl1 to COG (among the time response functions' amplitude array --> to select proper t.r.f.)
1699 Int_t ampIndex = 0;
1700 Float_t diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[0]);
1701 for (Int_t j=0;j<20;j++) {
1702 if (diffAmp > TMath::Abs(deltaPad1-indexAmpGraphs[j]) && indexAmpGraphs[j]!=0)
1703 {
1704 diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[j]);
1705 ampIndex = j;
1706 }
1707 }
1708 if (!graphRes[ampIndex]) continue;
b4742ddd 1709 if (deltaTimebin+2 >= graphRes[ampIndex]->GetN()) continue;
9a836cc2 1710 if (graphRes[ampIndex]->GetY()[deltaTimebin+2]>=0) continue;
1711
1712 for (Int_t ipad0=padcl0-padScan; ipad0<=padcl0+padScan; ipad0++) {
1713 //
1714 //
1715 if (ipad1!=ipad0) continue; // check if ipad1 channel sees ipad0 channel, if not no correction to be applied.
1716
1717 Float_t deltaPad0 = TMath::Abs(cl0->GetPad()-(Float_t)ipad0);
1718 Double_t amp0 = (TMath::Exp(-(deltaPad0*deltaPad0)/(2*rmsPad0)))/sumAmp0; // normalized pad resp function
1719 Float_t qMaxPad0 = amp0*qTot0;
1720
1721 // Add 5 timebin range contribution around the max peak (-+2 tb window)
1722 for (Int_t itb=deltaTimebin-2; itb<=deltaTimebin+2; itb++) {
1723
1724 if (itb<0) continue;
1725 if (itb>=graphRes[ampIndex]->GetN()) continue;
1726
1727 // calculate contribution to qTot
1728 Float_t tailCorr = TMath::Abs((qTotPad1*ampfactor)*(graphRes[ampIndex])->GetY()[itb]);
1729 if (ipad1!=padcl0) {
1730 ionTailTotal += TMath::Min(qMaxPad0,tailCorr); // for side pad
1731 } else {
1732 ionTailTotal += tailCorr; // for center pad
1733 }
1734 // calculate contribution to qMax
1735 if (itb == deltaTimebin && ipad1 == padcl0) ionTailMax += tailCorr;
1736
1737 } // end of tb correction loop which is applied over 5 tb range
1738
1739 } // end of cl0 loop
1740 } // end of cl1 loop
1741
1742}
7bc5f28b 1743
1c53abe2 1744//_____________________________________________________________________________
829455ad 1745Int_t AliTPCtracker::LoadOuterSectors() {
1c53abe2 1746 //-----------------------------------------------------------------
91162307 1747 // This function fills outer TPC sectors with clusters.
1c53abe2 1748 //-----------------------------------------------------------------
91162307 1749 Int_t nrows = fOuterSec->GetNRows();
1750 UInt_t index=0;
1751 for (Int_t sec = 0;sec<fkNOS;sec++)
1752 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1753 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
91162307 1754 Int_t sec2 = sec+2*fkNIS;
1755 //left
b9671574 1756 Int_t ncl = tpcrow->GetN1();
91162307 1757 while (ncl--) {
b9671574 1758 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
91162307 1759 index=(((sec2<<8)+row)<<16)+ncl;
1760 tpcrow->InsertCluster(c,index);
1761 }
1762 //right
b9671574 1763 ncl = tpcrow->GetN2();
91162307 1764 while (ncl--) {
b9671574 1765 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
91162307 1766 index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
1767 tpcrow->InsertCluster(c,index);
1768 }
1769 //
1770 // write indexes for fast acces
1771 //
1772 for (Int_t i=0;i<510;i++)
b9671574 1773 tpcrow->SetFastCluster(i,-1);
91162307 1774 for (Int_t i=0;i<tpcrow->GetN();i++){
1775 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
b9671574 1776 tpcrow->SetFastCluster(zi,i); // write index
91162307 1777 }
1778 Int_t last = 0;
1779 for (Int_t i=0;i<510;i++){
b9671574 1780 if (tpcrow->GetFastCluster(i)<0)
1781 tpcrow->SetFastCluster(i,last);
91162307 1782 else
b9671574 1783 last = tpcrow->GetFastCluster(i);
91162307 1784 }
1785 }
1786 fN=fkNOS;
1787 fSectors=fOuterSec;
1788 return 0;
1789}
1790
1791
1792//_____________________________________________________________________________
829455ad 1793Int_t AliTPCtracker::LoadInnerSectors() {
91162307 1794 //-----------------------------------------------------------------
1795 // This function fills inner TPC sectors with clusters.
1796 //-----------------------------------------------------------------
1797 Int_t nrows = fInnerSec->GetNRows();
1798 UInt_t index=0;
1799 for (Int_t sec = 0;sec<fkNIS;sec++)
1800 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1801 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
91162307 1802 //
1803 //left
b9671574 1804 Int_t ncl = tpcrow->GetN1();
91162307 1805 while (ncl--) {
b9671574 1806 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
91162307 1807 index=(((sec<<8)+row)<<16)+ncl;
1808 tpcrow->InsertCluster(c,index);
1809 }
1810 //right
b9671574 1811 ncl = tpcrow->GetN2();
91162307 1812 while (ncl--) {
b9671574 1813 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
91162307 1814 index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
1815 tpcrow->InsertCluster(c,index);
1816 }
1817 //
1818 // write indexes for fast acces
1819 //
1820 for (Int_t i=0;i<510;i++)
b9671574 1821 tpcrow->SetFastCluster(i,-1);
91162307 1822 for (Int_t i=0;i<tpcrow->GetN();i++){
1823 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
b9671574 1824 tpcrow->SetFastCluster(zi,i); // write index
91162307 1825 }
1826 Int_t last = 0;
1827 for (Int_t i=0;i<510;i++){
b9671574 1828 if (tpcrow->GetFastCluster(i)<0)
1829 tpcrow->SetFastCluster(i,last);
91162307 1830 else
b9671574 1831 last = tpcrow->GetFastCluster(i);
91162307 1832 }
1c53abe2 1833
91162307 1834 }
1835
1c53abe2 1836 fN=fkNIS;
1837 fSectors=fInnerSec;
91162307 1838 return 0;
1839}
1840
1841
1842
1843//_________________________________________________________________________
829455ad 1844AliTPCclusterMI *AliTPCtracker::GetClusterMI(Int_t index) const {
91162307 1845 //--------------------------------------------------------------------
1846 // Return pointer to a given cluster
1847 //--------------------------------------------------------------------
e7eb17e4 1848 if (index<0) return 0; // no cluster
91162307 1849 Int_t sec=(index&0xff000000)>>24;
1850 Int_t row=(index&0x00ff0000)>>16;
d26d9159 1851 Int_t ncl=(index&0x00007fff)>>00;
91162307 1852
bd26fa83 1853 const AliTPCtrackerRow * tpcrow=0;
bfa00fba 1854 TClonesArray * clrow =0;
3da363a1 1855
ad23441a 1856 if (sec<0 || sec>=fkNIS*4) {
1857 AliWarning(Form("Wrong sector %d",sec));
1858 return 0x0;
1859 }
1860
91162307 1861 if (sec<fkNIS*2){
462fb6e0 1862 AliTPCtrackerSector& tracksec = fInnerSec[sec%fkNIS];
1863 if (tracksec.GetNRows()<=row) return 0;
1864 tpcrow = &(tracksec[row]);
3da363a1 1865 if (tpcrow==0) return 0;
1866
1867 if (sec<fkNIS) {
b9671574 1868 if (tpcrow->GetN1()<=ncl) return 0;
1869 clrow = tpcrow->GetClusters1();
3da363a1 1870 }
1871 else {
b9671574 1872 if (tpcrow->GetN2()<=ncl) return 0;
1873 clrow = tpcrow->GetClusters2();
3da363a1 1874 }
91162307 1875 }
3da363a1 1876 else {
462fb6e0 1877 AliTPCtrackerSector& tracksec = fOuterSec[(sec-fkNIS*2)%fkNOS];
1878 if (tracksec.GetNRows()<=row) return 0;
1879 tpcrow = &(tracksec[row]);
3da363a1 1880 if (tpcrow==0) return 0;
1881
1882 if (sec-2*fkNIS<fkNOS) {
b9671574 1883 if (tpcrow->GetN1()<=ncl) return 0;
1884 clrow = tpcrow->GetClusters1();
3da363a1 1885 }
1886 else {
b9671574 1887 if (tpcrow->GetN2()<=ncl) return 0;
1888 clrow = tpcrow->GetClusters2();
3da363a1 1889 }
91162307 1890 }
3da363a1 1891
bfa00fba 1892 return (AliTPCclusterMI*)clrow->At(ncl);
91162307 1893
1c53abe2 1894}
1895
91162307 1896
1897
829455ad 1898Int_t AliTPCtracker::FollowToNext(AliTPCseed& t, Int_t nr) {
1c53abe2 1899 //-----------------------------------------------------------------
1900 // This function tries to find a track prolongation to next pad row
1901 //-----------------------------------------------------------------
1c53abe2 1902 //
91162307 1903 Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
76d56fd6 1904 //
1905 //
4d158c36 1906 AliTPCclusterMI *cl=0;
1907 Int_t tpcindex= t.GetClusterIndex2(nr);
1908 //
1909 // update current shape info every 5 pad-row
1910 // if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
1911 GetShape(&t,nr);
1912 //}
1913 //
1914 if (fIteration>0 && tpcindex>=-1){ //if we have already clusters
1915 //
1916 if (tpcindex==-1) return 0; //track in dead zone
f124f8bf 1917 if (tpcindex >= 0){ //
b9671574 1918 cl = t.GetClusterPointer(nr);
97d77e7a 1919 //if (cl==0) cl = GetClusterMI(tpcindex);
1920 if (!cl) cl = GetClusterMI(tpcindex);
b9671574 1921 t.SetCurrentClusterIndex1(tpcindex);
4d158c36 1922 }
1923 if (cl){
1924 Int_t relativesector = ((tpcindex&0xff000000)>>24)%18; // if previously accepted cluster in different sector
1925 Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
1926 //
1927 if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
1928 if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
1929
1930 if (TMath::Abs(angle-t.GetAlpha())>0.001){
1931 Double_t rotation = angle-t.GetAlpha();
b9671574 1932 t.SetRelativeSector(relativesector);
1791d824 1933 if (!t.Rotate(rotation)) {
1934 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
1935 return 0;
1936 }
1937 }
1938 if (!t.PropagateTo(x)) {
1939 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
1940 return 0;
4d158c36 1941 }
4d158c36 1942 //
b9671574 1943 t.SetCurrentCluster(cl);
1944 t.SetRow(nr);
00055a22 1945 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
4d158c36 1946 if ((tpcindex&0x8000)==0) accept =0;
1947 if (accept<3) {
1948 //if founded cluster is acceptible
1949 if (cl->IsUsed(11)) { // id cluster is shared inrease uncertainty
b9671574 1950 t.SetErrorY2(t.GetErrorY2()+0.03);
1951 t.SetErrorZ2(t.GetErrorZ2()+0.03);
1952 t.SetErrorY2(t.GetErrorY2()*3);
1953 t.SetErrorZ2(t.GetErrorZ2()*3);
4d158c36 1954 }
b9671574 1955 t.SetNFoundable(t.GetNFoundable()+1);
4d158c36 1956 UpdateTrack(&t,accept);
1957 return 1;
f124f8bf 1958 }
1959 else { // Remove old cluster from track
1960 t.SetClusterIndex(nr, -3);
1961 t.SetClusterPointer(nr, 0);
1962 }
4d158c36 1963 }
1627d1c4 1964 }
3f82c4f2 1965 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0; // cut on angle
76d56fd6 1966 if (fIteration>1 && IsFindable(t)){
3f82c4f2 1967 // not look for new cluster during refitting
b9671574 1968 t.SetNFoundable(t.GetNFoundable()+1);
3f82c4f2 1969 return 0;
1970 }
91162307 1971 //
4d158c36 1972 UInt_t index=0;
ca142b1f 1973 // if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
f124f8bf 1974 if (!t.PropagateTo(x)) {
1975 if (fIteration==0) t.SetRemoval(10);
1976 return 0;
1977 }
1978 Double_t y = t.GetY();
91162307 1979 if (TMath::Abs(y)>ymax){
1980 if (y > ymax) {
b9671574 1981 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
91162307 1982 if (!t.Rotate(fSectors->GetAlpha()))
1983 return 0;
1984 } else if (y <-ymax) {
b9671574 1985 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
91162307 1986 if (!t.Rotate(-fSectors->GetAlpha()))
1987 return 0;
1988 }
f124f8bf 1989 if (!t.PropagateTo(x)) {
1990 if (fIteration==0) t.SetRemoval(10);
1991 return 0;
1992 }
1993 y = t.GetY();
91162307 1994 }
1995 //
4d158c36 1996 Double_t z=t.GetZ();
1997 //
a3232aae 1998
b9671574 1999 if (!IsActive(t.GetRelativeSector(),nr)) {
2000 t.SetInDead(kTRUE);
a3232aae 2001 t.SetClusterIndex2(nr,-1);
2002 return 0;
2003 }
2004 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
b9671574 2005 Bool_t isActive = IsActive(t.GetRelativeSector(),nr);
2006 Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
a3232aae 2007
2008 if (!isActive || !isActive2) return 0;
2009
bd26fa83 2010 const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
91162307 2011 if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
2012 Double_t roady =1.;
2013 Double_t roadz = 1.;
2014 //
b9671574 2015 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
2016 t.SetInDead(kTRUE);
91162307 2017 t.SetClusterIndex2(nr,-1);
1c53abe2 2018 return 0;
2019 }
2020 else
2021 {
76d56fd6 2022 if (IsFindable(t))
47af7ca4 2023 // if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fkParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
b9671574 2024 t.SetNFoundable(t.GetNFoundable()+1);
1627d1c4 2025 else
2026 return 0;
1c53abe2 2027 }
2028 //calculate
91162307 2029 if (krow) {
2030 // cl = krow.FindNearest2(y+10.,z,roady,roadz,index);
2031 cl = krow.FindNearest2(y,z,roady,roadz,index);
b9671574 2032 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
91162307 2033 }
91162307 2034 if (cl) {
b9671574 2035 t.SetCurrentCluster(cl);
2036 t.SetRow(nr);
4d158c36 2037 if (fIteration==2&&cl->IsUsed(10)) return 0;
00055a22 2038 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
4d158c36 2039 if (fIteration==2&&cl->IsUsed(11)) {
b9671574 2040 t.SetErrorY2(t.GetErrorY2()+0.03);
2041 t.SetErrorZ2(t.GetErrorZ2()+0.03);
2042 t.SetErrorY2(t.GetErrorY2()*3);
2043 t.SetErrorZ2(t.GetErrorZ2()*3);
4d158c36 2044 }
d26d9159 2045 /*
91162307 2046 if (t.fCurrentCluster->IsUsed(10)){
2047 //
2048 //
c9427e08 2049
91162307 2050 t.fNShared++;
2051 if (t.fNShared>0.7*t.GetNumberOfClusters()) {
2052 t.fRemoval =10;
2053 return 0;
2054 }
2055 }
d26d9159 2056 */
91162307 2057 if (accept<3) UpdateTrack(&t,accept);
c9427e08 2058
91162307 2059 } else {
b9671574 2060 if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
91162307 2061
2062 }
2063 return 1;
2064}
c9427e08 2065
1c53abe2 2066
91162307 2067
5d837844 2068//_________________________________________________________________________
829455ad 2069Bool_t AliTPCtracker::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
5d837844 2070{
2071 // Get track space point by index
2072 // return false in case the cluster doesn't exist
2073 AliTPCclusterMI *cl = GetClusterMI(index);
2074 if (!cl) return kFALSE;
2075 Int_t sector = (index&0xff000000)>>24;
0201b65c 2076 // Int_t row = (index&0x00ff0000)>>16;
5d837844 2077 Float_t xyz[3];
47af7ca4 2078 // xyz[0] = fkParam->GetPadRowRadii(sector,row);
0201b65c 2079 xyz[0] = cl->GetX();
5d837844 2080 xyz[1] = cl->GetY();
2081 xyz[2] = cl->GetZ();
2082 Float_t sin,cos;
47af7ca4 2083 fkParam->AdjustCosSin(sector,cos,sin);
5d837844 2084 Float_t x = cos*xyz[0]-sin*xyz[1];
2085 Float_t y = cos*xyz[1]+sin*xyz[0];
2086 Float_t cov[6];
2087 Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
47af7ca4 2088 if (sector < fkParam->GetNInnerSector()) sigmaY2 *= 2.07;
5d837844 2089 Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
47af7ca4 2090 if (sector < fkParam->GetNInnerSector()) sigmaZ2 *= 1.77;
5d837844 2091 cov[0] = sin*sin*sigmaY2;
2092 cov[1] = -sin*cos*sigmaY2;
2093 cov[2] = 0.;
2094 cov[3] = cos*cos*sigmaY2;
2095 cov[4] = 0.;
2096 cov[5] = sigmaZ2;
2097 p.SetXYZ(x,y,xyz[2],cov);
ae079791 2098 AliGeomManager::ELayerID iLayer;
5d837844 2099 Int_t idet;
47af7ca4 2100 if (sector < fkParam->GetNInnerSector()) {
ae079791 2101 iLayer = AliGeomManager::kTPC1;
5d837844 2102 idet = sector;
2103 }
2104 else {
ae079791 2105 iLayer = AliGeomManager::kTPC2;
47af7ca4 2106 idet = sector - fkParam->GetNInnerSector();
5d837844 2107 }
ae079791 2108 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
5d837844 2109 p.SetVolumeID(volid);
2110 return kTRUE;
2111}
2112
2113
2114
829455ad 2115Int_t AliTPCtracker::UpdateClusters(AliTPCseed& t, Int_t nr) {
1c53abe2 2116 //-----------------------------------------------------------------
2117 // This function tries to find a track prolongation to next pad row
2118 //-----------------------------------------------------------------
b9671574 2119 t.SetCurrentCluster(0);
f124f8bf 2120 t.SetCurrentClusterIndex1(-3);
1c53abe2 2121
2122 Double_t xt=t.GetX();
91162307 2123 Int_t row = GetRowNumber(xt)-1;
2124 Double_t ymax= GetMaxY(nr);
2125
1c53abe2 2126 if (row < nr) return 1; // don't prolongate if not information until now -
ca142b1f 2127// if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
2128// t.fRemoval =10;
2129// return 0; // not prolongate strongly inclined tracks
2130// }
2131// if (TMath::Abs(t.GetSnp())>0.95) {
2132// t.fRemoval =10;
2133// return 0; // not prolongate strongly inclined tracks
2134// }// patch 28 fev 06
91162307 2135
2136 Double_t x= GetXrow(nr);
2137 Double_t y,z;
2138 //t.PropagateTo(x+0.02);
2139 //t.PropagateTo(x+0.01);
1627d1c4 2140 if (!t.PropagateTo(x)){
1627d1c4 2141 return 0;
2142 }
1c53abe2 2143 //
91162307 2144 y=t.GetY();
2145 z=t.GetZ();
1c53abe2 2146
91162307 2147 if (TMath::Abs(y)>ymax){
2148 if (y > ymax) {
b9671574 2149 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
91162307 2150 if (!t.Rotate(fSectors->GetAlpha()))
2151 return 0;
2152 } else if (y <-ymax) {
b9671574 2153 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
91162307 2154 if (!t.Rotate(-fSectors->GetAlpha()))
2155 return 0;
2156 }
982aff31 2157 // if (!t.PropagateTo(x)){
2158 // return 0;
2159 //}
2160 return 1;
2161 //y = t.GetY();
1c53abe2 2162 }
91162307 2163 //
3f82c4f2 2164 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
a3232aae 2165
b9671574 2166 if (!IsActive(t.GetRelativeSector(),nr)) {
2167 t.SetInDead(kTRUE);
a3232aae 2168 t.SetClusterIndex2(nr,-1);
2169 return 0;
2170 }
2171 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
2172
bd26fa83 2173 AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1c53abe2 2174
b9671574 2175 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
2176 t.SetInDead(kTRUE);
91162307 2177 t.SetClusterIndex2(nr,-1);
1c53abe2 2178 return 0;
2179 }
2180 else
2181 {
76d56fd6 2182
2183 // if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
2184 if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
1627d1c4 2185 else
2186 return 0;
1c53abe2 2187 }
1c53abe2 2188
91162307 2189 // update current
42aec1f1 2190 if ( (nr%2==0) || t.GetNumberOfClusters()<2){
91162307 2191 // t.fCurrentSigmaY = GetSigmaY(&t);
2192 //t.fCurrentSigmaZ = GetSigmaZ(&t);
2193 GetShape(&t,nr);
2194 }
1c53abe2 2195
91162307 2196 AliTPCclusterMI *cl=0;
d184f295 2197 Int_t index=0;
91162307 2198 //
2199 Double_t roady = 1.;
2200 Double_t roadz = 1.;
2201 //
d26d9159 2202
2203 if (!cl){
2204 index = t.GetClusterIndex2(nr);
bad6eb00 2205 if ( (index >= 0) && (index&0x8000)==0){
b9671574 2206 cl = t.GetClusterPointer(nr);
bad6eb00 2207 if ( (cl==0) && (index >= 0)) cl = GetClusterMI(index);
b9671574 2208 t.SetCurrentClusterIndex1(index);
d26d9159 2209 if (cl) {
b9671574 2210 t.SetCurrentCluster(cl);
d26d9159 2211 return 1;
2212 }
2213 }
2214 }
2215
3d172d79 2216 // if (index<0) return 0;
2217 UInt_t uindex = TMath::Abs(index);
d184f295 2218
91162307 2219 if (krow) {
d184f295 2220 //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
2221 cl = krow.FindNearest2(y,z,roady,roadz,uindex);
91162307 2222 }
d26d9159 2223
b9671574 2224 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));
2225 t.SetCurrentCluster(cl);
d26d9159 2226
91162307 2227 return 1;
2228}
1c53abe2 2229
1c53abe2 2230
829455ad 2231Int_t AliTPCtracker::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
91162307 2232 //-----------------------------------------------------------------
2233 // This function tries to find a track prolongation to next pad row
2234 //-----------------------------------------------------------------
1c53abe2 2235
91162307 2236 //update error according neighborhoud
1c53abe2 2237
b9671574 2238 if (t.GetCurrentCluster()) {
2239 t.SetRow(nr);
00055a22 2240 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
91162307 2241
b9671574 2242 if (t.GetCurrentCluster()->IsUsed(10)){
91162307 2243 //
2244 //
2245 // t.fErrorZ2*=2;
2246 // t.fErrorY2*=2;
b9671574 2247 t.SetNShared(t.GetNShared()+1);
2248 if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
2249 t.SetRemoval(10);
91162307 2250 return 0;
2251 }
b364ca79 2252 }
d26d9159 2253 if (fIteration>0) accept = 0;
b364ca79 2254 if (accept<3) UpdateTrack(&t,accept);
2255
1c53abe2 2256 } else {
91162307 2257 if (fIteration==0){
f124f8bf 2258 if ( t.GetNumberOfClusters()>18 && ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)) t.SetRemoval(10);
2259 if ( t.GetNumberOfClusters()>18 && t.GetChi2()/t.GetNumberOfClusters()>6 ) t.SetRemoval(10);
91162307 2260
b9671574 2261 if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
1c53abe2 2262 }
2263 }
2264 return 1;
2265}
2266
2267
2268
91162307 2269//_____________________________________________________________________________
829455ad 2270Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step, Bool_t fromSeeds) {
1c53abe2 2271 //-----------------------------------------------------------------
91162307 2272 // This function tries to find a track prolongation.
1c53abe2 2273 //-----------------------------------------------------------------
2274 Double_t xt=t.GetX();
2275 //
f124f8bf 2276 Double_t alpha=t.GetAlpha();
1c53abe2 2277 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2278 if (alpha < 0. ) alpha += 2.*TMath::Pi();
91162307 2279 //
a3f36f42 2280 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1c53abe2 2281
f124f8bf 2282 Int_t first = GetRowNumber(xt);
2283 if (!fromSeeds)
2284 first -= step;
a3f36f42 2285 if (first < 0)
2286 first = 0;
51ad6848 2287 for (Int_t nr= first; nr>=rf; nr-=step) {
2288 // update kink info
2289 if (t.GetKinkIndexes()[0]>0){
2290 for (Int_t i=0;i<3;i++){
2291 Int_t index = t.GetKinkIndexes()[i];
2292 if (index==0) break;
2293 if (index<0) continue;
2294 //
6c94f330 2295 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
51ad6848 2296 if (!kink){
2297 printf("PROBLEM\n");
2298 }
2299 else{
eea478d3 2300 Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
51ad6848 2301 if (kinkrow==nr){
2302 AliExternalTrackParam paramd(t);
2303 kink->SetDaughter(paramd);
eea478d3 2304 kink->SetStatus(2,5);
51ad6848 2305 kink->Update();
51ad6848 2306 }
2307 }
2308 }
2309 }
2310
2311 if (nr==80) t.UpdateReference();
982aff31 2312 if (nr<fInnerSec->GetNRows())
2313 fSectors = fInnerSec;
2314 else
2315 fSectors = fOuterSec;
91162307 2316 if (FollowToNext(t,nr)==0)
4d158c36 2317 if (!t.IsActive())
2318 return 0;
91162307 2319
2320 }
2321 return 1;
2322}
2323
1c53abe2 2324
1c53abe2 2325
91162307 2326
2327
2328
829455ad 2329Int_t AliTPCtracker::FollowBackProlongation(AliTPCseed& t, Int_t rf, Bool_t fromSeeds) {
1c53abe2 2330 //-----------------------------------------------------------------
2331 // This function tries to find a track prolongation.
2332 //-----------------------------------------------------------------
1c53abe2 2333 //
eea478d3 2334 Double_t xt=t.GetX();
f124f8bf 2335 Double_t alpha=t.GetAlpha();
1c53abe2 2336 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2337 if (alpha < 0. ) alpha += 2.*TMath::Pi();
bad6eb00 2338 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1c53abe2 2339
b9671574 2340 Int_t first = t.GetFirstPoint();
f124f8bf 2341 Int_t ri = GetRowNumber(xt);
2342 if (!fromSeeds)
2343 ri += 1;
2344
2345 if (first<ri) first = ri;
91162307 2346 //
2347 if (first<0) first=0;
4d158c36 2348 for (Int_t nr=first; nr<=rf; nr++) {
ca142b1f 2349 // if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
51ad6848 2350 if (t.GetKinkIndexes()[0]<0){
2351 for (Int_t i=0;i<3;i++){
2352 Int_t index = t.GetKinkIndexes()[i];
2353 if (index==0) break;
2354 if (index>0) continue;
2355 index = TMath::Abs(index);
6c94f330 2356 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
51ad6848 2357 if (!kink){
2358 printf("PROBLEM\n");
2359 }
2360 else{
eea478d3 2361 Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
51ad6848 2362 if (kinkrow==nr){
2363 AliExternalTrackParam paramm(t);
2364 kink->SetMother(paramm);
eea478d3 2365 kink->SetStatus(2,1);
51ad6848 2366 kink->Update();
51ad6848 2367 }
2368 }
eea478d3 2369 }
51ad6848 2370 }
eea478d3 2371 //
d26d9159 2372 if (nr<fInnerSec->GetNRows())
2373 fSectors = fInnerSec;
2374 else
2375 fSectors = fOuterSec;
c274e255 2376
d26d9159 2377 FollowToNext(t,nr);
1c53abe2 2378 }
2379 return 1;
2380}
2381
2382
2383
2384
2385
829455ad 2386Float_t AliTPCtracker::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
1c53abe2 2387{
544c295f 2388 // overlapping factor
1c53abe2 2389 //
2390 sum1=0;
2391 sum2=0;
2392 Int_t sum=0;
1c53abe2 2393 //
2394 Float_t dz2 =(s1->GetZ() - s2->GetZ());
c9427e08 2395 dz2*=dz2;
91162307 2396
c9427e08 2397 Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
1c53abe2 2398 dy2*=dy2;
2399 Float_t distance = TMath::Sqrt(dz2+dy2);
c9427e08 2400 if (distance>4.) return 0; // if there are far away - not overlap - to reduce combinatorics
1c53abe2 2401
91162307 2402 // Int_t offset =0;
b9671574 2403 Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
2404 Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
c9427e08 2405 if (lastpoint>160)
2406 lastpoint =160;
2407 if (firstpoint<0)
2408 firstpoint = 0;
91162307 2409 if (firstpoint>lastpoint) {
2410 firstpoint =lastpoint;
2411 // lastpoint =160;
c9427e08 2412 }
2413
2414
91162307 2415 for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
2416 if (s1->GetClusterIndex2(i)>0) sum1++;
2417 if (s2->GetClusterIndex2(i)>0) sum2++;
2418 if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
1c53abe2 2419 sum++;
2420 }
2421 }
91162307 2422 if (sum<5) return 0;
2423
1627d1c4 2424 Float_t summin = TMath::Min(sum1+1,sum2+1);
2425 Float_t ratio = (sum+1)/Float_t(summin);
1c53abe2 2426 return ratio;
2427}
2428
829455ad 2429void AliTPCtracker::SignShared(AliTPCseed * s1, AliTPCseed * s2)
1c53abe2 2430{
544c295f 2431 // shared clusters
1c53abe2 2432 //
a0f4d6a6 2433 Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
2434 if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
2435 Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
2436 Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
91162307 2437
1c53abe2 2438 //
91162307 2439 Int_t sumshared=0;
2440 //
a0f4d6a6 2441 //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
2442 //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
2443 Int_t firstpoint = 0;
2444 Int_t lastpoint = 160;
91162307 2445 //
a0f4d6a6 2446 // if (firstpoint>=lastpoint-5) return;;
1af5da7e 2447
91162307 2448 for (Int_t i=firstpoint;i<lastpoint;i++){
2449 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2450 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2451 sumshared++;
2452 }
2453 }
a0f4d6a6 2454 if (sumshared>cutN0){
91162307 2455 // sign clusters
2456 //
2457 for (Int_t i=firstpoint;i<lastpoint;i++){
2458 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2459 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2460 AliTPCTrackerPoint *p1 = s1->GetTrackPoint(i);
2461 AliTPCTrackerPoint *p2 = s2->GetTrackPoint(i);;
2462 if (s1->IsActive()&&s2->IsActive()){
b9671574 2463 p1->SetShared(kTRUE);
2464 p2->SetShared(kTRUE);
91162307 2465 }
2466 }
2467 }
2468 }
2469 //
a0f4d6a6 2470 if (sumshared>cutN0){
91162307 2471 for (Int_t i=0;i<4;i++){
b9671574 2472 if (s1->GetOverlapLabel(3*i)==0){
2473 s1->SetOverlapLabel(3*i, s2->GetLabel());
2474 s1->SetOverlapLabel(3*i+1,sumshared);
2475 s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
91162307 2476 break;
2477 }
2478 }
2479 for (Int_t i=0;i<4;i++){
b9671574 2480 if (s2->GetOverlapLabel(3*i)==0){
2481 s2->SetOverlapLabel(3*i, s1->GetLabel());
2482 s2->SetOverlapLabel(3*i+1,sumshared);
2483 s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
91162307 2484 break;
2485 }
2486 }
2487 }
91162307 2488}
1c53abe2 2489
829455ad 2490void AliTPCtracker::SignShared(TObjArray * arr)
91162307 2491{
1c53abe2 2492 //
91162307 2493 //sort trackss according sectors
2494 //
c9427e08 2495 for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2496 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 2497 if (!pt) continue;
2498 //if (pt) RotateToLocal(pt);
b9671574 2499 pt->SetSort(0);
c9427e08 2500 }
91162307 2501 arr->UnSort();
6d493ea0 2502 arr->Sort(); // sorting according relative sectors
1c53abe2 2503 arr->Expand(arr->GetEntries());
91162307 2504 //
2505 //
1c53abe2 2506 Int_t nseed=arr->GetEntriesFast();
1c53abe2 2507 for (Int_t i=0; i<nseed; i++) {
2508 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 2509 if (!pt) continue;
ec26e231 2510 for (Int_t j=0;j<12;j++){
b9671574 2511 pt->SetOverlapLabel(j,0);
1c53abe2 2512 }
91162307 2513 }
2514 for (Int_t i=0; i<nseed; i++) {
2515 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2516 if (!pt) continue;
b9671574 2517 if (pt->GetRemoval()>10) continue;
1c53abe2 2518 for (Int_t j=i+1; j<nseed; j++){
2519 AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
1af5da7e 2520 if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
91162307 2521 // if (pt2){
b9671574 2522 if (pt2->GetRemoval()<=10) {
6d493ea0 2523 //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
91162307 2524 SignShared(pt,pt2);
c9427e08 2525 }
91162307 2526 }
2527 }
2528}
2529
91162307 2530
829455ad 2531void AliTPCtracker::SortTracks(TObjArray * arr, Int_t mode) const
91162307 2532{
2533 //
2534 //sort tracks in array according mode criteria
2535 Int_t nseed = arr->GetEntriesFast();
2536 for (Int_t i=0; i<nseed; i++) {
2537 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2538 if (!pt) {
2539 continue;
2540 }
b9671574 2541 pt->SetSort(mode);
91162307 2542 }
2543 arr->UnSort();
2544 arr->Sort();
1c53abe2 2545}
c9427e08 2546
51ad6848 2547
829455ad 2548void AliTPCtracker::RemoveUsed2(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t minimal)
51ad6848 2549{
51ad6848 2550 //
6d493ea0 2551 // Loop over all tracks and remove overlaped tracks (with lower quality)
2552 // Algorithm:
2553 // 1. Unsign clusters
2554 // 2. Sort tracks according quality
2555 // Quality is defined by the number of cluster between first and last points
2556 //
2557 // 3. Loop over tracks - decreasing quality order
2558 // a.) remove - If the fraction of shared cluster less than factor (1- n or 2)
2559 // b.) remove - If the minimal number of clusters less than minimal and not ITS
2560 // c.) if track accepted - sign clusters
51ad6848 2561 //
829455ad 2562 //Called in - AliTPCtracker::Clusters2Tracks()
2563 // - AliTPCtracker::PropagateBack()
2564 // - AliTPCtracker::RefitInward()
6d493ea0 2565 //
be34cb88 2566 // Arguments:
2567 // factor1 - factor for constrained
2568 // factor2 - for non constrained tracks
2569 // if (Float_t(shared+1)/Float_t(found+1)>factor) - DELETE
2570 //
51ad6848 2571 UnsignClusters();
2572 //
2573 Int_t nseed = arr->GetEntriesFast();
2574 Float_t * quality = new Float_t[nseed];
2575 Int_t * indexes = new Int_t[nseed];
2576 Int_t good =0;
2577 //
2578 //
2579 for (Int_t i=0; i<nseed; i++) {
2580 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2581 if (!pt){
2582 quality[i]=-1;
2583 continue;
2584 }
2585 pt->UpdatePoints(); //select first last max dens points
2586 Float_t * points = pt->GetPoints();
2587 if (points[3]<0.8) quality[i] =-1;
51ad6848 2588 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
6d493ea0 2589 //prefer high momenta tracks if overlaps
2590 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
51ad6848 2591 }
2592 TMath::Sort(nseed,quality,indexes);
2593 //
2594 //
2595 for (Int_t itrack=0; itrack<nseed; itrack++) {
2596 Int_t trackindex = indexes[itrack];
6d493ea0 2597 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);
2598 if (!pt) continue;
2599 //
51ad6848 2600 if (quality[trackindex]<0){
ddfbc51a 2601 MarkSeedFree( arr->RemoveAt(trackindex) );
f06a1ff6 2602 continue;
51ad6848 2603 }
2604 //
6d493ea0 2605 //
51ad6848 2606 Int_t first = Int_t(pt->GetPoints()[0]);
2607 Int_t last = Int_t(pt->GetPoints()[2]);
b9671574 2608 Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
51ad6848 2609 //
2610 Int_t found,foundable,shared;
6d493ea0 2611 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
2612 // pt->GetClusterStatistic(0,160, found, foundable,shared,kFALSE);
b406fdb0 2613 Bool_t itsgold =kFALSE;
b9671574 2614 if (pt->GetESD()){
ef7253ac 2615 Int_t dummy[12];
b9671574 2616 if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
51ad6848 2617 }
b406fdb0 2618 if (!itsgold){
2619 //
2620 if (Float_t(shared+1)/Float_t(found+1)>factor){
2621 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
16299eac 2622 if( AliTPCReconstructor::StreamLevel()>3){
be34cb88 2623 TTreeSRedirector &cstream = *fDebugStreamer;
2624 cstream<<"RemoveUsed"<<
2625 "iter="<<fIteration<<
2626 "pt.="<<pt<<
2627 "\n";
2628 }
ddfbc51a 2629 MarkSeedFree( arr->RemoveAt(trackindex) );
b406fdb0 2630 continue;
2631 }
2632 if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){ //remove short tracks
2633 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
16299eac 2634 if( AliTPCReconstructor::StreamLevel()>3){
be34cb88 2635 TTreeSRedirector &cstream = *fDebugStreamer;
2636 cstream<<"RemoveShort"<<
2637 "iter="<<fIteration<<
2638 "pt.="<<pt<<
2639 "\n";
2640 }
ddfbc51a 2641 MarkSeedFree( arr->RemoveAt(trackindex) );
b406fdb0 2642 continue;
2643 }
51ad6848 2644 }
2645
2646 good++;
6d493ea0 2647 //if (sharedfactor>0.4) continue;
b406fdb0 2648 if (pt->GetKinkIndexes()[0]>0) continue;
6d493ea0 2649 //Remove tracks with undefined properties - seems
2650 if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ?
2651 //
51ad6848 2652 for (Int_t i=first; i<last; i++) {
2653 Int_t index=pt->GetClusterIndex2(i);
2654 // if (index<0 || index&0x8000 ) continue;
2655 if (index<0 || index&0x8000 ) continue;
b9671574 2656 AliTPCclusterMI *c= pt->GetClusterPointer(i);
51ad6848 2657 if (!c) continue;
2658 c->Use(10);
2659 }
2660 }
2661 fNtracks = good;
2662 if (fDebug>0){
2663 Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
2664 }
2665 delete []quality;
2666 delete []indexes;
2667}
2668
829455ad 2669void AliTPCtracker::DumpClusters(Int_t iter, TObjArray *trackArray)
f47588e0 2670{
2671 //
2672 // Dump clusters after reco
2673 // signed and unsigned cluster can be visualized
2674 // 1. Unsign all cluster
2675 // 2. Sign all used clusters
2676 // 3. Dump clusters
2677 UnsignClusters();
2678 Int_t nseed = trackArray->GetEntries();
2679 for (Int_t i=0; i<nseed; i++){
2680 AliTPCseed *pt=(AliTPCseed*)trackArray->UncheckedAt(i);
2681 if (!pt) {
2682 continue;
2683 }
2684 Bool_t isKink=pt->GetKinkIndex(0)!=0;
2685 for (Int_t j=0; j<160; ++j) {
2686 Int_t index=pt->GetClusterIndex2(j);
2687 if (index<0) continue;
2688 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2689 if (!c) continue;
2690 if (isKink) c->Use(100); // kink
2691 c->Use(10); // by default usage 10
2692 }
2693 }
2694 //
2695
2696 for (Int_t sec=0;sec<fkNIS;sec++){
2697 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
bfa00fba 2698 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
f47588e0 2699 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++){
bfa00fba 2700 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
2701 Float_t gx[3]; cl->GetGlobalXYZ(gx);
f47588e0 2702 (*fDebugStreamer)<<"clDump"<<
2703 "iter="<<iter<<
bfa00fba 2704 "cl.="<<cl<<
f47588e0 2705 "gx0="<<gx[0]<<
2706 "gx1="<<gx[1]<<
2707 "gx2="<<gx[2]<<
2708 "\n";
2709 }
bfa00fba 2710 cla = fInnerSec[sec][row].GetClusters2();
f47588e0 2711 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++){
bfa00fba 2712 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
2713 Float_t gx[3]; cl->GetGlobalXYZ(gx);
f47588e0 2714 (*fDebugStreamer)<<"clDump"<<
2715 "iter="<<iter<<
bfa00fba 2716 "cl.="<<cl<<
f47588e0 2717 "gx0="<<gx[0]<<
2718 "gx1="<<gx[1]<<
2719 "gx2="<<gx[2]<<
2720 "\n";
2721 }
2722 }
2723 }
2724
2725 for (Int_t sec=0;sec<fkNOS;sec++){
2726 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
bfa00fba 2727 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
f47588e0 2728 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++){
bfa00fba 2729 Float_t gx[3];
2730 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
2731 cl->GetGlobalXYZ(gx);
f47588e0 2732 (*fDebugStreamer)<<"clDump"<<
2733 "iter="<<iter<<
bfa00fba 2734 "cl.="<<cl<<
f47588e0 2735 "gx0="<<gx[0]<<
2736 "gx1="<<gx[1]<<
2737 "gx2="<<gx[2]<<
2738 "\n";
2739 }
bfa00fba 2740 cla = fOuterSec[sec][row].GetClusters2();
f47588e0 2741 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++){
bfa00fba 2742 Float_t gx[3];
2743 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
2744 cl->GetGlobalXYZ(gx);
f47588e0 2745 (*fDebugStreamer)<<"clDump"<<
2746 "iter="<<iter<<
bfa00fba 2747 "cl.="<<cl<<
f47588e0 2748 "gx0="<<gx[0]<<
2749 "gx1="<<gx[1]<<
2750 "gx2="<<gx[2]<<
2751 "\n";
2752 }
2753 }
2754 }
2755
2756}
829455ad 2757void AliTPCtracker::UnsignClusters()
1c53abe2 2758{
91162307 2759 //
2760 // loop over all clusters and unsign them
2761 //
2762
2763 for (Int_t sec=0;sec<fkNIS;sec++){
2764 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
bfa00fba 2765 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
b9671574 2766 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
91162307 2767 // if (cl[icl].IsUsed(10))
bfa00fba 2768 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2769 cla = fInnerSec[sec][row].GetClusters2();
b9671574 2770 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
91162307 2771 //if (cl[icl].IsUsed(10))
bfa00fba 2772 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
91162307 2773 }
2774 }
2775
2776 for (Int_t sec=0;sec<fkNOS;sec++){
2777 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
bfa00fba 2778 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
b9671574 2779 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
91162307 2780 //if (cl[icl].IsUsed(10))
bfa00fba 2781 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2782 cla = fOuterSec[sec][row].GetClusters2();
b9671574 2783 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
91162307 2784 //if (cl[icl].IsUsed(10))
bfa00fba 2785 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
91162307 2786 }
2787 }
2788
1c53abe2 2789}
2790
91162307 2791
2792
829455ad 2793void AliTPCtracker::SignClusters(const TObjArray * arr, Float_t fnumber, Float_t fdensity)
1c53abe2 2794{
2795 //
91162307 2796 //sign clusters to be "used"
2797 //
2798 // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
2799 // loop over "primaries"
2800
2801 Float_t sumdens=0;
2802 Float_t sumdens2=0;
2803 Float_t sumn =0;
2804 Float_t sumn2 =0;
2805 Float_t sumchi =0;
2806 Float_t sumchi2 =0;
2807
2808 Float_t sum =0;
2809
1c53abe2 2810 TStopwatch timer;
91162307 2811 timer.Start();
1c53abe2 2812
91162307 2813 Int_t nseed = arr->GetEntriesFast();
2814 for (Int_t i=0; i<nseed; i++) {
2815 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2816 if (!pt) {
2817 continue;
2818 }
2819 if (!(pt->IsActive())) continue;
b9671574 2820 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
91162307 2821 if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
2822 sumdens += dens;
2823 sumdens2+= dens*dens;
2824 sumn += pt->GetNumberOfClusters();
2825 sumn2 += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
2826 Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
2827 if (chi2>5) chi2=5;
2828 sumchi +=chi2;
2829 sumchi2 +=chi2*chi2;
2830 sum++;
2831 }
1627d1c4 2832 }
91162307 2833
2834 Float_t mdensity = 0.9;
2835 Float_t meann = 130;
2836 Float_t meanchi = 1;
2837 Float_t sdensity = 0.1;
2838 Float_t smeann = 10;
2839 Float_t smeanchi =0.4;
1627d1c4 2840
91162307 2841
2842 if (sum>20){
2843 mdensity = sumdens/sum;
2844 meann = sumn/sum;
2845 meanchi = sumchi/sum;
2846 //
2847 sdensity = sumdens2/sum-mdensity*mdensity;
c1ea348f 2848 if (sdensity >= 0)
2849 sdensity = TMath::Sqrt(sdensity);
2850 else
2851 sdensity = 0.1;
91162307 2852 //
2853 smeann = sumn2/sum-meann*meann;
c1ea348f 2854 if (smeann >= 0)
2855 smeann = TMath::Sqrt(smeann);
2856 else
2857 smeann = 10;
91162307 2858 //
2859 smeanchi = sumchi2/sum - meanchi*meanchi;
c1ea348f 2860 if (smeanchi >= 0)
2861 smeanchi = TMath::Sqrt(smeanchi);
2862 else
2863 smeanchi = 0.4;
91162307 2864 }
2865
2866
2867 //REMOVE SHORT DELTAS or tracks going out of sensitive volume of TPC
2868 //
2869 for (Int_t i=0; i<nseed; i++) {
2870 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2871 if (!pt) {
2872 continue;
1c53abe2 2873 }
b9671574 2874 if (pt->GetBSigned()) continue;
2875 if (pt->GetBConstrain()) continue;
91162307 2876 //if (!(pt->IsActive())) continue;
2877 /*
2878 Int_t found,foundable,shared;
2879 pt->GetClusterStatistic(0,160,found, foundable,shared);
2880 if (shared/float(found)>0.3) {
2881 if (shared/float(found)>0.9 ){
ddfbc51a 2882 //MarkSeedFree( arr->RemoveAt(i) );
91162307 2883 }
2884 continue;
c9427e08 2885 }
91162307 2886 */
2887 Bool_t isok =kFALSE;
b9671574 2888 if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
91162307 2889 isok = kTRUE;
b9671574 2890 if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
91162307 2891 isok =kTRUE;
2892 if (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
2893 isok =kTRUE;
2894 if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
2895 isok =kTRUE;
2896
2897 if (isok)
77f88633 2898 for (Int_t j=0; j<160; ++j) {
2899 Int_t index=pt->GetClusterIndex2(j);
91162307 2900 if (index<0) continue;
77f88633 2901 AliTPCclusterMI *c= pt->GetClusterPointer(j);
91162307 2902 if (!c) continue;
2903 //if (!(c->IsUsed(10))) c->Use();
2904 c->Use(10);
2905 }
2906 }
2907
c9427e08 2908
1c53abe2 2909 //
91162307 2910 Double_t maxchi = meanchi+2.*smeanchi;
2911
2912 for (Int_t i=0; i<nseed; i++) {
2913 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2914 if (!pt) {
1c53abe2 2915 continue;
91162307 2916 }
2917 //if (!(pt->IsActive())) continue;
b9671574 2918 if (pt->GetBSigned()) continue;
91162307 2919 Double_t chi = pt->GetChi2()/pt->GetNumberOfClusters();
2920 if (chi>maxchi) continue;
2921
2922 Float_t bfactor=1;
b9671574 2923 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
91162307 2924
2925 //sign only tracks with enoug big density at the beginning
2926
2927 if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue;
2928
2929
3e5d0aa2 2930 Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
91162307 2931 Double_t minn = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
2932
2933 // if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
b9671574 2934 if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
91162307 2935 minn=0;
2936
2937 if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
2938 //Int_t noc=pt->GetNumberOfClusters();
b9671574 2939 pt->SetBSigned(kTRUE);
77f88633 2940 for (Int_t j=0; j<160; ++j) {
91162307 2941
77f88633 2942 Int_t index=pt->GetClusterIndex2(j);
91162307 2943 if (index<0) continue;
77f88633 2944 AliTPCclusterMI *c= pt->GetClusterPointer(j);
91162307 2945 if (!c) continue;
2946 // if (!(c->IsUsed(10))) c->Use();
2947 c->Use(10);
2948 }
1c53abe2 2949 }
91162307 2950 }
2951 // gLastCheck = nseed;
2952 // arr->Compress();
2953 if (fDebug>0){
2954 timer.Print();
2955 }
1c53abe2 2956}
2957
2958
1c53abe2 2959
829455ad 2960Int_t AliTPCtracker::RefitInward(AliESDEvent *event)
d26d9159 2961{
2962 //
2963 // back propagation of ESD tracks
2964 //
2965 //return 0;
ec26e231 2966 if (!event) return 0;
6d493ea0 2967 const Int_t kMaxFriendTracks=2000;
d26d9159 2968 fEvent = event;
72e25240 2969 fEventHLT = 0;
6d64657a 2970 // extract correction object for multiplicity dependence of dEdx
2971 TObjArray * gainCalibArray = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(event->GetRunNumber());
23728788 2972
2973 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
2974 if (!transform) {
2975 AliFatal("Tranformations not in RefitInward");
2976 return 0;
2977 }
2978 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
6d64657a 2979 const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
012c4694 2980 Int_t nContribut = event->GetNumberOfTracks();
6d64657a 2981 TGraphErrors * graphMultDependenceDeDx = 0x0;
23728788 2982 if (recoParam && recoParam->GetUseMultiplicityCorrectionDedx() && gainCalibArray) {
6d64657a 2983 if (recoParam->GetUseTotCharge()) {
2984 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2985 } else {
2986 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2987 }
2988 }
2989 //
d26d9159 2990 ReadSeeds(event,2);
2991 fIteration=2;
982aff31 2992 //PrepareForProlongation(fSeeds,1);
2993 PropagateForward2(fSeeds);
6d493ea0 2994 RemoveUsed2(fSeeds,0.4,0.4,20);
1af5da7e 2995
bda5ad6d 2996 Int_t entriesSeed=fSeeds->GetEntries();
2997 TObjArray arraySeed(entriesSeed);
2998 for (Int_t i=0;i<entriesSeed;i++) {
a0f4d6a6 2999 arraySeed.AddAt(fSeeds->At(i),i);
3000 }
3001 SignShared(&arraySeed);
6d493ea0 3002 // FindCurling(fSeeds, event,2); // find multi found tracks
1af5da7e 3003 FindSplitted(fSeeds, event,2); // find multi found tracks
16299eac 3004 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,2); // find multi found tracks
af32720d 3005
4d158c36 3006 Int_t ntracks=0;
d26d9159 3007 Int_t nseed = fSeeds->GetEntriesFast();
3008 for (Int_t i=0;i<nseed;i++){
3009 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
4d158c36 3010 if (!seed) continue;
eea478d3 3011 if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
be34cb88 3012 AliESDtrack *esd=event->GetTrack(i);
3013
3014 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
3015 AliExternalTrackParam paramIn;
3016 AliExternalTrackParam paramOut;
3017 Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
16299eac 3018 if (AliTPCReconstructor::StreamLevel()>2) {
0e90d29a 3019 (*fDebugStreamer)<<"RecoverIn"<<
3020 "seed.="<<seed<<
3021 "esd.="<<esd<<
3022 "pin.="<<&paramIn<<
3023 "pout.="<<&paramOut<<
3024 "ncl="<<ncl<<
3025 "\n";
3026 }
be34cb88 3027 if (ncl>15) {
3028 seed->Set(paramIn.GetX(),paramIn.GetAlpha(),paramIn.GetParameter(),paramIn.GetCovariance());
3029 seed->SetNumberOfClusters(ncl);
3030 }
3031 }
eea478d3 3032
47af7ca4 3033 seed->PropagateTo(fkParam->GetInnerRadiusLow());
51ad6848 3034 seed->UpdatePoints();
92f513f5 3035 AddCovariance(seed);
bad6eb00 3036 MakeESDBitmaps(seed, esd);
d26d9159 3037 seed->CookdEdx(0.02,0.6);
3038 CookLabel(seed,0.1); //For comparison only
af32720d 3039 //
ec26e231 3040 if (AliTPCReconstructor::StreamLevel()>1 && seed!=0) {
af32720d 3041 TTreeSRedirector &cstream = *fDebugStreamer;
3042 cstream<<"Crefit"<<
3043 "Esd.="<<esd<<
3044 "Track.="<<seed<<
3045 "\n";
3046 }
c274e255 3047
51ad6848 3048 if (seed->GetNumberOfClusters()>15){
4d158c36 3049 esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
51ad6848 3050 esd->SetTPCPoints(seed->GetPoints());
b9671574 3051 esd->SetTPCPointsF(seed->GetNFoundable());
83afd539 3052 Int_t ndedx = seed->GetNCDEDX(0);
3053 Float_t sdedx = seed->GetSDEDX(0);
b406fdb0 3054 Float_t dedx = seed->GetdEdx();
6d64657a 3055 // apply mutliplicity dependent dEdx correction if available
3056 if (graphMultDependenceDeDx) {
6d64657a 3057 Double_t corrGain = AliTPCcalibDButil::EvalGraphConst(graphMultDependenceDeDx, nContribut);
012c4694 3058 dedx += (1 - corrGain)*50.; // MIP is normalized to 50
6d64657a 3059 }
b406fdb0 3060 esd->SetTPCsignal(dedx, sdedx, ndedx);
fdedfdec 3061 //
64bf5ca0 3062 // fill new dEdx information
3063 //
3064 Double32_t signal[4];
dee67df8 3065 Double32_t signalMax[4];
64bf5ca0 3066 Char_t ncl[3];
3067 Char_t nrows[3];
3068 //
3069 for(Int_t iarr=0;iarr<3;iarr++) {
fb57da8a 3070 signal[iarr] = seed->GetDEDXregion(iarr+1);
dee67df8 3071 signalMax[iarr] = seed->GetDEDXregion(iarr+5);
fb57da8a 3072 ncl[iarr] = seed->GetNCDEDX(iarr+1);
3073 nrows[iarr] = seed->GetNCDEDXInclThres(iarr+1);
64bf5ca0 3074 }
3075 signal[3] = seed->GetDEDXregion(4);
dee67df8 3076 signalMax[3] = seed->GetDEDXregion(8);
3077
64bf5ca0 3078 //
ddfbc51a 3079 AliTPCdEdxInfo * infoTpcPid = new AliTPCdEdxInfo();
64bf5ca0 3080 infoTpcPid->SetTPCSignalRegionInfo(signal, ncl, nrows);
dee67df8 3081 infoTpcPid->SetTPCSignalsQmax(signalMax);
64bf5ca0 3082 esd->SetTPCdEdxInfo(infoTpcPid);
3083 //
fdedfdec 3084 // add seed to the esd track in Calib level
3085 //
6d493ea0 3086 Bool_t storeFriend = gRandom->Rndm()<(kMaxFriendTracks)/Float_t(nseed);
ddfbc51a 3087 if (AliTPCReconstructor::StreamLevel()>0 &&storeFriend){
3088 // RS: this is the only place where the seed is created not in the pool,
3089 // since it should belong to ESDevent
3090 AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE);
fdedfdec 3091 esd->AddCalibObject(seedCopy);
3092 }
4d158c36 3093 ntracks++;
d26d9159 3094 }
3095 else{
3096 //printf("problem\n");
3097 }
3098 }
51ad6848 3099 //FindKinks(fSeeds,event);
f47588e0 3100 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(2,fSeeds);
4d158c36 3101 Info("RefitInward","Number of refitted tracks %d",ntracks);
3aa6a136 3102
3103 AliCosmicTracker::FindCosmic(event, kTRUE);
3104
5576d489 3105 FillClusterOccupancyInfo();
3106
d26d9159 3107 return 0;
3108}
3109
1c53abe2 3110
829455ad 3111Int_t AliTPCtracker::PropagateBack(AliESDEvent *event)
91162307 3112{
3113 //
3114 // back propagation of ESD tracks
3115 //
ec26e231 3116 if (!event) return 0;
91162307 3117 fEvent = event;
72e25240 3118 fEventHLT = 0;
d26d9159 3119 fIteration = 1;
5d837844 3120 ReadSeeds(event,1);
b406fdb0 3121 PropagateBack(fSeeds);
3122 RemoveUsed2(fSeeds,0.4,0.4,20);
6d493ea0 3123 //FindCurling(fSeeds, fEvent,1);
1af5da7e 3124 FindSplitted(fSeeds, event,1); // find multi found tracks
16299eac 3125 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,1); // find multi found tracks
1af5da7e 3126
b406fdb0 3127 //
91162307 3128 Int_t nseed = fSeeds->GetEntriesFast();
4d158c36 3129 Int_t ntracks=0;
91162307 3130 for (Int_t i=0;i<nseed;i++){
3131 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
d9e62e7e 3132 if (!seed) continue;
51ad6848 3133 if (seed->GetKinkIndex(0)<0) UpdateKinkQualityM(seed); // update quality informations for kinks
3134 seed->UpdatePoints();
92f513f5 3135 AddCovariance(seed);
91162307 3136 AliESDtrack *esd=event->GetTrack(i);
e1dadcd0 3137 if (!esd) continue; //never happen
be34cb88 3138 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
3139 AliExternalTrackParam paramIn;
3140 AliExternalTrackParam paramOut;
3141 Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
16299eac 3142 if (AliTPCReconstructor::StreamLevel()>2) {
ca449e98 3143 (*fDebugStreamer)<<"RecoverBack"<<
3144 "seed.="<<seed<<
3145 "esd.="<<esd<<
3146 "pin.="<<&paramIn<<
3147 "pout.="<<&paramOut<<
3148 "ncl="<<ncl<<
3149 "\n";
3150 }
be34cb88 3151 if (ncl>15) {
3152 seed->Set(paramOut.GetX(),paramOut.GetAlpha(),paramOut.GetParameter(),paramOut.GetCovariance());
3153 seed->SetNumberOfClusters(ncl);
3154 }
3155 }
d26d9159 3156 seed->CookdEdx(0.02,0.6);
91162307 3157 CookLabel(seed,0.1); //For comparison only
51ad6848 3158 if (seed->GetNumberOfClusters()>15){
4d158c36 3159 esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
51ad6848 3160 esd->SetTPCPoints(seed->GetPoints());
b9671574 3161 esd->SetTPCPointsF(seed->GetNFoundable());
83afd539 3162 Int_t ndedx = seed->GetNCDEDX(0);
3163 Float_t sdedx = seed->GetSDEDX(0);
167c41ab 3164 Float_t dedx = seed->GetdEdx();
3165 esd->SetTPCsignal(dedx, sdedx, ndedx);
4d158c36 3166 ntracks++;
31fd97b2 3167 Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
3168 // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
8cecaa87 3169 if (AliTPCReconstructor::StreamLevel()>1 && esd) {
6d493ea0 3170 (*fDebugStreamer)<<"Cback"<<
3171 "Tr0.="<<seed<<
8cecaa87 3172 "esd.="<<esd<<
6d493ea0 3173 "EventNrInFile="<<eventnumber<<
8cecaa87 3174 "\n";
6d493ea0 3175 }
4d158c36 3176 }
91162307 3177 }
f47588e0 3178 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(1,fSeeds);
51ad6848 3179 //FindKinks(fSeeds,event);
4d158c36 3180 Info("PropagateBack","Number of back propagated tracks %d",ntracks);
91162307 3181 fEvent =0;
72e25240 3182 fEventHLT = 0;
3183
91162307 3184 return 0;
3185}
3186
3187
829455ad 3188Int_t AliTPCtracker::PostProcess(AliESDEvent *event)
ec7e4ad6 3189{
3190 //
3191 // Post process events
3192 //
3193 if (!event) return 0;
3194
3195 //
3196 // Set TPC event status
3197 //
3198
3199 // event affected by HV dip
3200 // reset TPC status
3201 if(IsTPCHVDipEvent(event)) {
3202 event->ResetDetectorStatus(AliDAQ::kTPC);
3203 }
3204
3205 //printf("Status %d \n", event->IsDetectorOn(AliDAQ::kTPC));
3206
3207 return 0;
3208}
3209
3210
829455ad 3211 void AliTPCtracker::DeleteSeeds()
91162307 3212{
b67e07dc 3213 //
f06a1ff6 3214 fSeeds->Clear();
ddfbc51a 3215 ResetSeedsPool();
91162307 3216 delete fSeeds;
3217 fSeeds =0;
3218}
3219
829455ad 3220void AliTPCtracker::ReadSeeds(const AliESDEvent *const event, Int_t direction)
91162307 3221{
3222 //
3223 //read seeds from the event
3224
3225 Int_t nentr=event->GetNumberOfTracks();
6bdc18d6 3226 if (fDebug>0){
3227 Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
3228 }
91162307 3229 if (fSeeds)
3230 DeleteSeeds();
3231 if (!fSeeds){
4d158c36 3232 fSeeds = new TObjArray(nentr);
91162307 3233 }
4d158c36 3234 UnsignClusters();
3235 // Int_t ntrk=0;
91162307 3236 for (Int_t i=0; i<nentr; i++) {
3237 AliESDtrack *esd=event->GetTrack(i);
51ad6848 3238 ULong_t status=esd->GetStatus();
3239 if (!(status&AliESDtrack::kTPCin)) continue;
1af5da7e 3240 AliTPCtrack t(*esd);
5d837844 3241 t.SetNumberOfClusters(0);
eea478d3 3242 // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
ddfbc51a 3243 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(t/*,t.GetAlpha()*/);
3244 seed->SetPoolID(fLastSeedID);
a0f4d6a6 3245 seed->SetUniqueID(esd->GetID());
92f513f5 3246 AddCovariance(seed); //add systematic ucertainty
eea478d3 3247 for (Int_t ikink=0;ikink<3;ikink++) {
3248 Int_t index = esd->GetKinkIndex(ikink);
3249 seed->GetKinkIndexes()[ikink] = index;
3250 if (index==0) continue;
3251 index = TMath::Abs(index);
3252 AliESDkink * kink = fEvent->GetKink(index-1);
3253 if (kink&&esd->GetKinkIndex(ikink)<0){
3254 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
3255 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,0);
3256 }
3257 if (kink&&esd->GetKinkIndex(ikink)>0){
3258 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
3259 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,4);
3260 }
3261
3262 }
6c94f330 3263 if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.);
3264 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
be34cb88 3265 //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
3266 // fSeeds->AddAt(0,i);
ddfbc51a 3267 // MarkSeedFree( seed );
be34cb88 3268 // continue;
3269 //}
a3986da2 3270
91162307 3271 //
3272 //
3273 // rotate to the local coordinate system
eea478d3 3274 //
3275 fSectors=fInnerSec; fN=fkNIS;
f124f8bf 3276 Double_t alpha=seed->GetAlpha();
91162307 3277 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
3278 if (alpha < 0. ) alpha += 2.*TMath::Pi();
a3f36f42 3279 Int_t ns=Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
91162307 3280 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
f124f8bf 3281 alpha-=seed->GetAlpha();
4d158c36 3282 if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
3283 if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
f124f8bf 3284 if (TMath::Abs(alpha) > 0.001) { // This should not happen normally
3285 AliWarning(Form("Rotating track over %f",alpha));
3286 if (!seed->Rotate(alpha)) {
ddfbc51a 3287 MarkSeedFree( seed );
f124f8bf 3288 continue;
3289 }
d9b8978b 3290 }
b9671574 3291 seed->SetESD(esd);
4d158c36 3292 // sign clusters
b406fdb0 3293 if (esd->GetKinkIndex(0)<=0){
3294 for (Int_t irow=0;irow<160;irow++){
3295 Int_t index = seed->GetClusterIndex2(irow);
bad6eb00 3296 if (index >= 0){
b406fdb0 3297 //
3298 AliTPCclusterMI * cl = GetClusterMI(index);
b9671574 3299 seed->SetClusterPointer(irow,cl);
b406fdb0 3300 if (cl){
3301 if ((index & 0x8000)==0){
3302 cl->Use(10); // accepted cluster
3303 }else{
3304 cl->Use(6); // close cluster not accepted
3305 }
4d158c36 3306 }else{
b406fdb0 3307 Info("ReadSeeds","Not found cluster");
3308 }
4d158c36 3309 }
3310 }
3311 }
3312 fSeeds->AddAt(seed,i);
91162307 3313 }
3314}
3315
3316
3317
3318//_____________________________________________________________________________
829455ad 3319void AliTPCtracker::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
91162307 3320 Float_t deltay, Int_t ddsec) {
3321 //-----------------------------------------------------------------
3322 // This function creates track seeds.
3323 // SEEDING WITH VERTEX CONSTRAIN
3324 //-----------------------------------------------------------------
3325 // cuts[0] - fP4 cut
3326 // cuts[1] - tan(phi) cut
3327 // cuts[2] - zvertex cut
3328 // cuts[3] - fP3 cut
3329 Int_t nin0 = 0;
3330 Int_t nin1 = 0;
3331 Int_t nin2 = 0;
3332 Int_t nin = 0;
3333 Int_t nout1 = 0;
3334 Int_t nout2 = 0;
3335
3336 Double_t x[5], c[15];
3337 // Int_t di = i1-i2;
3338 //
ddfbc51a 3339 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed();
3340 seed->SetPoolID(fLastSeedID);
91162307 3341 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
3342 Double_t cs=cos(alpha), sn=sin(alpha);
d757548f 3343 //
3344 // Double_t x1 =fOuterSec->GetX(i1);
3345 //Double_t xx2=fOuterSec->GetX(i2);
3346
91162307 3347 Double_t x1 =GetXrow(i1);
3348 Double_t xx2=GetXrow(i2);
3349
3350 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
3351
3352 Int_t imiddle = (i2+i1)/2; //middle pad row index
3353 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
bd26fa83 3354 const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
91162307 3355 //
3356 Int_t ns =sec;
3357
bd26fa83 3358 const AliTPCtrackerRow& kr1=GetRow(ns,i1);
b9671574 3359 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
3360 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
91162307 3361
3362 //
3363 // change cut on curvature if it can't reach this layer
3364 // maximal curvature set to reach it
3365 Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
3366 if (dvertexmax*0.5*cuts[0]>0.85){
3367 cuts[0] = 0.85/(dvertexmax*0.5+1.);
3368 }
3369 Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
3370
3371 // Int_t ddsec = 1;
3372 if (deltay>0) ddsec = 0;
3373 // loop over clusters
3374 for (Int_t is=0; is < kr1; is++) {
3375 //
3376 if (kr1[is]->IsUsed(10)) continue;
3377 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3378 //if (TMath::Abs(y1)>ymax) continue;
3379
3380 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3381
3382 // find possible directions
3383 Float_t anglez = (z1-z3)/(x1-x3);
3384 Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
3385 //
3386 //
3387 //find rotation angles relative to line given by vertex and point 1
3388 Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
3389 Double_t dvertex = TMath::Sqrt(dvertex2);
3390 Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
3391 Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
3392
3393 //
3394 // loop over 2 sectors
3395 Int_t dsec1=-ddsec;
3396 Int_t dsec2= ddsec;
3397 if (y1<0) dsec2= 0;
3398 if (y1>0) dsec1= 0;
3399
3400 Double_t dddz1=0; // direction of delta inclination in z axis
3401 Double_t dddz2=0;
3402 if ( (z1-z3)>0)
3403 dddz1 =1;
3404 else
3405 dddz2 =1;
3406 //
3407 for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
3408 Int_t sec2 = sec + dsec;
3409 //
bd26fa83 3410 // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
3411 //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
3412 AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
3413 AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
91162307 3414 Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
3415 Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
3416
3417 // rotation angles to p1-p3
3418 Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
3419 Double_t x2, y2, z2;
3420 //
3421 // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
3422
3423 //
3424 Double_t dxx0 = (xx2-x3)*cs13r;
3425 Double_t dyy0 = (xx2-x3)*sn13r;
3426 for (Int_t js=index1; js < index2; js++) {
3427 const AliTPCclusterMI *kcl = kr2[js];
3428 if (kcl->IsUsed(10)) continue;
3429 //
3430 //calcutate parameters
3431 //
3432 Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
3433 // stright track
3434 if (TMath::Abs(yy0)<0.000001) continue;
3435 Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
3436 Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
3437 Double_t r02 = (0.25+y0*y0)*dvertex2;
3438 //curvature (radius) cut
3439 if (r02<r2min) continue;
3440
3441 nin0++;
3442 //
3443 Double_t c0 = 1/TMath::Sqrt(r02);
3444 if (yy0>0) c0*=-1.;
3445
3446
3447 //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
3448 //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
b67e07dc 3449 Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
3450 Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
91162307 3451 //
3452 //
3453 Double_t z0 = kcl->GetZ();
3454 Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
3455 if (TMath::Abs(zzzz2-z0)>0.5) continue;
3456 nin1++;
3457 //
3458 Double_t dip = (z1-z0)*c0/dfi1;
3459 Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
3460 //
3461 y2 = kcl->GetY();
3462 if (dsec==0){
3463 x2 = xx2;
3464 z2 = kcl->GetZ();
3465 }
3466 else
3467 {
3468 // rotation
3469 z2 = kcl->GetZ();
3470 x2= xx2*cs-y2*sn*dsec;
3471 y2=+xx2*sn*dsec+y2*cs;
3472 }
3473
3474 x[0] = y1;
3475 x[1] = z1;
3476 x[2] = x0;
3477 x[3] = dip;
3478 x[4] = c0;
3479 //
3480 //
3481 // do we have cluster at the middle ?
3482 Double_t ym,zm;
3483 GetProlongation(x1,xm,x,ym,zm);
3484 UInt_t dummy;
3485 AliTPCclusterMI * cm=0;
3486 if (TMath::Abs(ym)-ymaxm<0){
3487 cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3488 if ((!cm) || (cm->IsUsed(10))) {
3489 continue;
3490 }
3491 }
3492 else{
3493 // rotate y1 to system 0
3494 // get state vector in rotated system
3495 Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
3496 Double_t xr2 = x0*cs+yr1*sn*dsec;
3497 Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3498 //
3499 GetProlongation(xx2,xm,xr,ym,zm);
3500 if (TMath::Abs(ym)-ymaxm<0){
3501 cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3502 if ((!cm) || (cm->IsUsed(10))) {
3503 continue;
3504 }
3505 }
3506 }
3507
3508
2a97785a 3509 // Double_t dym = 0;
3510 // Double_t dzm = 0;
3511 // if (cm){
3512 // dym = ym - cm->GetY();
3513 // dzm = zm - cm->GetZ();
3514 // }
91162307 3515 nin2++;
3516
3517
3518 //
3519 //
3520 Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
3521 Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
3522 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
3523 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3524 //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
3525
b67e07dc 3526 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3527 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3528 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3529 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3530 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3531 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
91162307 3532
b67e07dc 3533 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3534 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3535 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3536 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
91162307 3537
1c53abe2 3538 c[0]=sy1;
3539 c[1]=0.; c[2]=sz1;
3540 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3541 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3542 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3543 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3544 c[13]=f30*sy1*f40+f32*sy2*f42;
3545 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
91162307 3546
d757548f 3547 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
91162307 3548
1c53abe2 3549 UInt_t index=kr1.GetIndex(is);
ddfbc51a 3550 if (seed) {MarkSeedFree(seed); seed = 0;}
3551 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, ns*alpha+shift, x, c, index);
3552 seed->SetPoolID(fLastSeedID);
d757548f 3553 track->SetIsSeeding(kTRUE);
3554 track->SetSeed1(i1);
3555 track->SetSeed2(i2);
3556 track->SetSeedType(3);
c9427e08 3557
91162307 3558
3559 //if (dsec==0) {
d757548f 3560 FollowProlongation(*track, (i1+i2)/2,1);
91162307 3561 Int_t foundable,found,shared;
d757548f 3562 track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
3563 if ((found<0.55*foundable) || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
ddfbc51a 3564 MarkSeedFree(seed); seed = 0;
91162307 3565 continue;
3566 }
3567 //}
3568
3569 nin++;
d757548f 3570 FollowProlongation(*track, i2,1);
91162307 3571
3572
3573 //Int_t rc = 1;
d757548f 3574 track->SetBConstrain(1);
91162307 3575 // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
d757548f 3576 track->SetLastPoint(i1); // first cluster in track position
3577 track->SetFirstPoint(track->GetLastPoint());
91162307 3578
d757548f 3579 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3580 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3581 track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
ddfbc51a 3582 MarkSeedFree(seed); seed = 0;
c9427e08 3583 continue;
3584 }
91162307 3585 nout1++;
3586 // Z VERTEX CONDITION
c274e255 3587 Double_t zv, bz=GetBz();
d757548f 3588 if ( !track->GetZAt(0.,bz,zv) ) continue;
91162307 3589 if (TMath::Abs(zv-z3)>cuts[2]) {
d757548f 3590 FollowProlongation(*track, TMath::Max(i2-20,0));
3591 if ( !track->GetZAt(0.,bz,zv) ) continue;
91162307 3592 if (TMath::Abs(zv-z3)>cuts[2]){
d757548f 3593 FollowProlongation(*track, TMath::Max(i2-40,0));
3594 if ( !track->GetZAt(0.,bz,zv) ) continue;
3595 if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
91162307 3596 // make seed without constrain
d757548f 3597 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
91162307 3598 FollowProlongation(*track2, i2,1);
b9671574 3599 track2->SetBConstrain(kFALSE);
3600 track2->SetSeedType(1);
d757548f 3601 arr->AddLast(track2);
ddfbc51a 3602 MarkSeedFree( seed ); seed = 0;
91162307 3603 continue;
3604 }
3605 else{
ddfbc51a 3606 MarkSeedFree( seed ); seed = 0;
91162307 3607 continue;
d757548f 3608
91162307 3609 }
3610 }
c9427e08 3611 }
316c6cd9 3612
d757548f 3613 track->SetSeedType(0);
f06a1ff6 3614 arr->AddLast(track); // note, track is seed, don't free the seed
ddfbc51a 3615 seed = new( NextFreeSeed() ) AliTPCseed;
3616 seed->SetPoolID(fLastSeedID);
91162307 3617 nout2++;
3618 // don't consider other combinations
d757548f 3619 if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
91162307 3620 break;
1c53abe2 3621 }
3622 }
3623 }
6bdc18d6 3624 if (fDebug>3){
3625 Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
91162307 3626 }
ddfbc51a 3627 if (seed) MarkSeedFree( seed );
1c53abe2 3628}
3629
1627d1c4 3630
829455ad 3631void AliTPCtracker::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
91162307 3632 Float_t deltay) {
3633
3634
3635
1627d1c4 3636 //-----------------------------------------------------------------
91162307 3637 // This function creates track seeds.
1627d1c4 3638 //-----------------------------------------------------------------
91162307 3639 // cuts[0] - fP4 cut
3640 // cuts[1] - tan(phi) cut
3641 // cuts[2] - zvertex cut
3642 // cuts[3] - fP3 cut
3643
3644
3645 Int_t nin0 = 0;
3646 Int_t nin1 = 0;
3647 Int_t nin2 = 0;
3648 Int_t nin = 0;
3649 Int_t nout1 = 0;
3650 Int_t nout2 = 0;
3651 Int_t nout3 =0;
3652 Double_t x[5], c[15];
3653 //
3654 // make temporary seed
ddfbc51a 3655 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
3656 seed->SetPoolID(fLastSeedID);
1627d1c4 3657 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3658 // Double_t cs=cos(alpha), sn=sin(alpha);
91162307 3659 //
3660 //
1627d1c4 3661
91162307 3662 // first 3 padrows
3663 Double_t x1 = GetXrow(i1-1);
bd26fa83 3664 const AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
b9671574 3665 Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
91162307 3666 //
3667 Double_t x1p = GetXrow(i1);
bd26fa83 3668 const AliTPCtrackerRow& kr1p=GetRow(sec,i1);
91162307 3669 //
3670 Double_t x1m = GetXrow(i1-2);
bd26fa83 3671 const AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
1627d1c4 3672
91162307 3673 //
3674 //last 3 padrow for seeding
bd26fa83 3675 AliTPCtrackerRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
91162307 3676 Double_t x3 = GetXrow(i1-7);
3677 // Double_t y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;
3678 //
bd26fa83 3679 AliTPCtrackerRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
91162307 3680 Double_t x3p = GetXrow(i1-6);
3681 //
bd26fa83 3682 AliTPCtrackerRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
91162307 3683 Double_t x3m = GetXrow(i1-8);
1627d1c4 3684
91162307 3685 //
3686 //
3687 // middle padrow
3688 Int_t im = i1-4; //middle pad row index
3689 Double_t xm = GetXrow(im); // radius of middle pad-row
bd26fa83 3690 const AliTPCtrackerRow& krm=GetRow(sec,im); //middle pad -row
91162307 3691 // Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;
3692 //
3693 //
3694 Double_t deltax = x1-x3;
3695 Double_t dymax = deltax*cuts[1];
3696 Double_t dzmax = deltax*cuts[3];
3697 //
3698 // loop over clusters
3699 for (Int_t is=0; is < kr1; is++) {
1627d1c4 3700 //
91162307 3701 if (kr1[is]->IsUsed(10)) continue;
3702 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
1627d1c4 3703 //
91162307 3704 if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3705 //
3706 Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
3707 Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
3708 //
3709 Double_t y3, z3;
1627d1c4 3710 //
1627d1c4 3711 //
91162307 3712 UInt_t index;
3713 for (Int_t js=index1; js < index2; js++) {
3714 const AliTPCclusterMI *kcl = kr3[js];
3715 if (kcl->IsUsed(10)) continue;
3716 y3 = kcl->GetY();
3717 // apply angular cuts
3718 if (TMath::Abs(y1-y3)>dymax) continue;
97d77e7a 3719 //x3 = x3;
91162307 3720 z3 = kcl->GetZ();
3721 if (TMath::Abs(z1-z3)>dzmax) continue;
3722 //
3723 Double_t angley = (y1-y3)/(x1-x3);
3724 Double_t anglez = (z1-z3)/(x1-x3);
3725 //
3726 Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
3727 Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
3728 //
3729 Double_t yyym = angley*(xm-x1)+y1;
3730 Double_t zzzm = anglez*(xm-x1)+z1;
3731
3732 const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
3733 if (!kcm) continue;
3734 if (kcm->IsUsed(10)) continue;
3735
3736 erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
3737 errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
3738 //
3739 //
3740 //
3741 Int_t used =0;
3742 Int_t found =0;
3743 //
3744 // look around first
3745 const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
3746 anglez*(x1m-x1)+z1,
3747 erry,errz,index);
3748 //
3749 if (kc1m){
3750 found++;
3751 if (kc1m->IsUsed(10)) used++;
1627d1c4 3752 }
91162307 3753 const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
3754 anglez*(x1p-x1)+z1,
3755 erry,errz,index);
1627d1c4 3756 //
91162307 3757 if (kc1p){
3758 found++;
3759 if (kc1p->IsUsed(10)) used++;
1627d1c4 3760 }
91162307 3761 if (used>1) continue;
3762 if (found<1) continue;
1627d1c4 3763
91162307 3764 //
3765 // look around last
3766 const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
3767 anglez*(x3m-x3)+z3,
3768 erry,errz,index);
3769 //
3770 if (kc3m){
3771 found++;
3772 if (kc3m->IsUsed(10)) used++;
3773 }
3774 else
3775 continue;
3776 const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
3777 anglez*(x3p-x3)+z3,
3778 erry,errz,index);
3779 //
3780 if (kc3p){
3781 found++;
3782 if (kc3p->IsUsed(10)) used++;
3783 }
3784 else
3785 continue;
3786 if (used>1) continue;
3787 if (found<3) continue;
3788 //
3789 Double_t x2,y2,z2;
3790 x2 = xm;
3791 y2 = kcm->GetY();
3792 z2 = kcm->GetZ();
3793 //
3794
1627d1c4 3795 x[0]=y1;
3796 x[1]=z1;
b67e07dc 3797 x[4]=F1(x1,y1,x2,y2,x3,y3);
91162307 3798 //if (TMath::Abs(x[4]) >= cuts[0]) continue;
3799 nin0++;
3800 //
b67e07dc 3801 x[2]=F2(x1,y1,x2,y2,x3,y3);
91162307 3802 nin1++;
3803 //
b67e07dc 3804 x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
91162307 3805 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3806 nin2++;
3807 //
3808 //
3809 Double_t sy1=0.1, sz1=0.1;
3810 Double_t sy2=0.1, sz2=0.1;
3811 Double_t sy3=0.1, sy=0.1, sz=0.1;
1627d1c4 3812
b67e07dc 3813 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3814 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3815 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3816 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3817 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3818 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
91162307 3819
b67e07dc 3820 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3821 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3822 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3823 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
1627d1c4 3824
3825 c[0]=sy1;
91162307 3826 c[1]=0.; c[2]=sz1;
1627d1c4 3827 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3828 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3829 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3830 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3831 c[13]=f30*sy1*f40+f32*sy2*f42;
3832 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3833
91162307 3834 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3835
77f88633 3836 index=kr1.GetIndex(is);
ddfbc51a 3837 if (seed) {MarkSeedFree( seed ); seed = 0;}
3838 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, sec*alpha+shift, x, c, index);
3839 seed->SetPoolID(fLastSeedID);
91162307 3840
b9671574 3841 track->SetIsSeeding(kTRUE);
91162307 3842
3843 nin++;
3844 FollowProlongation(*track, i1-7,1);
b9671574 3845 if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
3846 track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
ddfbc51a 3847 MarkSeedFree( seed ); seed = 0;
91162307 3848 continue;
3849 }
3850 nout1++;
3851 nout2++;
3852 //Int_t rc = 1;
3853 FollowProlongation(*track, i2,1);
b9671574 3854 track->SetBConstrain(0);
3855 track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
3856 track->SetFirstPoint(track->GetLastPoint());
91162307 3857
3858 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 3859 track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
3860 track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
ddfbc51a 3861 MarkSeedFree( seed ); seed = 0;
91162307 3862 continue;
3863 }
3864
3865 {
3866 FollowProlongation(*track, TMath::Max(i2-10,0),1);
3867 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
3868 FollowProlongation(*track2, i2,1);
b9671574 3869 track2->SetBConstrain(kFALSE);
3870 track2->SetSeedType(4);
f06a1ff6 3871 arr->AddLast(track2);
ddfbc51a 3872 MarkSeedFree( seed ); seed = 0;
91162307 3873 }
3874
3875
3876 //arr->AddLast(track);
3877 //seed = new AliTPCseed;
3878 nout3++;
3879 }
3880 }
3881
6bdc18d6 3882 if (fDebug>3){
7d85e147 3883 Info("MakeSeeds5","\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
91162307 3884 }
ddfbc51a 3885 if (seed) MarkSeedFree(seed);
91162307 3886}
3887
3888
3889//_____________________________________________________________________________
829455ad 3890void AliTPCtracker::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
176aff27 3891 Float_t deltay, Bool_t /*bconstrain*/) {
91162307 3892 //-----------------------------------------------------------------
3893 // This function creates track seeds - without vertex constraint
3894 //-----------------------------------------------------------------
3895 // cuts[0] - fP4 cut - not applied
3896 // cuts[1] - tan(phi) cut
3897 // cuts[2] - zvertex cut - not applied
3898 // cuts[3] - fP3 cut
3899 Int_t nin0=0;
3900 Int_t nin1=0;
3901 Int_t nin2=0;
3902 Int_t nin3=0;
3903 // Int_t nin4=0;
3904 //Int_t nin5=0;
3905
3906
3907
3908 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3909 // Double_t cs=cos(alpha), sn=sin(alpha);
3910 Int_t row0 = (i1+i2)/2;
3911 Int_t drow = (i1-i2)/2;
bd26fa83 3912 const AliTPCtrackerRow& kr0=fSectors[sec][row0];
3913 AliTPCtrackerRow * kr=0;
91162307 3914
3915 AliTPCpolyTrack polytrack;
3916 Int_t nclusters=fSectors[sec][row0];
ddfbc51a 3917 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
3918 seed->SetPoolID(fLastSeedID);
91162307 3919
3920 Int_t sumused=0;
3921 Int_t cused=0;
3922 Int_t cnused=0;
3923 for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
3924 Int_t nfound =0;
3925 Int_t nfoundable =0;
3926 for (Int_t iter =1; iter<2; iter++){ //iterations
bd26fa83 3927 const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
3928 const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];
91162307 3929 const AliTPCclusterMI * cl= kr0[is];
3930
3931 if (cl->IsUsed(10)) {
3932 cused++;
3933 }
3934 else{
3935 cnused++;
3936 }
3937 Double_t x = kr0.GetX();
3938 // Initialization of the polytrack
3939 nfound =0;
3940 nfoundable =0;
3941 polytrack.Reset();
3942 //
3943 Double_t y0= cl->GetY();
3944 Double_t z0= cl->GetZ();
3945 Float_t erry = 0;
3946 Float_t errz = 0;
3947
b9671574 3948 Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
91162307 3949 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
3950
3951 erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
3952 errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
3953 polytrack.AddPoint(x,y0,z0,erry, errz);
3954
3955 sumused=0;
3956 if (cl->IsUsed(10)) sumused++;
3957
3958
3959 Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
3960 Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
3961 //
3962 x = krm.GetX();
3963 AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
3964 if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
3965 erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
3966 errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
3967 if (cl1->IsUsed(10)) sumused++;
3968 polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
3969 }
3970 //
3971 x = krp.GetX();
3972 AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
3973 if (cl2) {
3974 erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
3975 errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
3976 if (cl2->IsUsed(10)) sumused++;
3977 polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
3978 }
3979 //
3980 if (sumused>0) continue;
3981 nin0++;
3982 polytrack.UpdateParameters();
3983 // follow polytrack
3984 roadz = 1.2;
3985 roady = 1.2;
3986 //
3987 Double_t yn,zn;
3988 nfoundable = polytrack.GetN();
3989 nfound = nfoundable;
3990 //
3991 for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
3992 Float_t maxdist = 0.8*(1.+3./(ddrow));
3993 for (Int_t delta = -1;delta<=1;delta+=2){
3994 Int_t row = row0+ddrow*delta;
3995 kr = &(fSectors[sec][row]);
3996 Double_t xn = kr->GetX();
77f88633 3997 Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
91162307 3998 polytrack.GetFitPoint(xn,yn,zn);
77f88633 3999 if (TMath::Abs(yn)>ymax1) continue;
91162307 4000 nfoundable++;
4001 AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
4002 if (cln) {
4003 Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
4004 if (dist<maxdist){
4005 /*
4006 erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
4007 errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
4008 if (cln->IsUsed(10)) {
4009 // printf("used\n");
4010 sumused++;
4011 erry*=2;
4012 errz*=2;
4013 }
4014 */
4015 erry=0.1;
4016 errz=0.1;
4017 polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
4018 nfound++;
4019 }
4020 }
4021 }
4022 if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
4023 polytrack.UpdateParameters();
4024 }
4025 }
4026 if ( (sumused>3) || (sumused>0.5*nfound)) {
4027 //printf("sumused %d\n",sumused);
4028 continue;
4029 }
4030 nin1++;
4031 Double_t dy,dz;
4032 polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
4033 AliTPCpolyTrack track2;
4034
4035 polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
4036 if (track2.GetN()<0.5*nfoundable) continue;
4037 nin2++;
4038
4039 if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
4040 //
4041 // test seed with and without constrain
4042 for (Int_t constrain=0; constrain<=0;constrain++){
4043 // add polytrack candidate
4044
4045 Double_t x[5], c[15];
4046 Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
4047 track2.GetBoundaries(x3,x1);
4048 x2 = (x1+x3)/2.;
4049 track2.GetFitPoint(x1,y1,z1);
4050 track2.GetFitPoint(x2,y2,z2);
4051 track2.GetFitPoint(x3,y3,z3);
4052 //
4053 //is track pointing to the vertex ?
4054 Double_t x0,y0,z0;
4055 x0=0;
4056 polytrack.GetFitPoint(x0,y0,z0);
4057
4058 if (constrain) {
4059 x2 = x3;
4060 y2 = y3;
4061 z2 = z3;
4062
4063 x3 = 0;
4064 y3 = 0;
4065 z3 = 0;
4066 }
4067 x[0]=y1;
4068 x[1]=z1;
b67e07dc 4069 x[4]=F1(x1,y1,x2,y2,x3,y3);
91162307 4070
4071 // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
b67e07dc 4072 x[2]=F2(x1,y1,x2,y2,x3,y3);
91162307 4073
4074 //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
b67e07dc 4075 //x[3]=F3(x1,y1,x2,y2,z1,z2);
4076 x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
91162307 4077 //if (TMath::Abs(x[3]) > cuts[3]) continue;
4078
4079
4080 Double_t sy =0.1, sz =0.1;
4081 Double_t sy1=0.02, sz1=0.02;
4082 Double_t sy2=0.02, sz2=0.02;
4083 Double_t sy3=0.02;
4084
4085 if (constrain){
4086 sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
4087 }
4088
b67e07dc 4089 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
4090 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
4091 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
4092 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
4093 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
4094 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
4095
4096 Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
4097 Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
4098 Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
4099 Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
91162307 4100
4101
4102 c[0]=sy1;
4103 c[1]=0.; c[2]=sz1;
4104 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4105 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4106 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4107 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4108 c[13]=f30*sy1*f40+f32*sy2*f42;
4109 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4110
4111 //Int_t row1 = fSectors->GetRowNumber(x1);
4112 Int_t row1 = GetRowNumber(x1);
4113
4114 UInt_t index=0;
4115 //kr0.GetIndex(is);
ddfbc51a 4116 if (seed) {MarkSeedFree( seed ); seed = 0;}
4117 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1,sec*alpha+shift,x,c,index);
4118 seed->SetPoolID(fLastSeedID);
b9671574 4119 track->SetIsSeeding(kTRUE);
91162307 4120 Int_t rc=FollowProlongation(*track, i2);
b9671574 4121 if (constrain) track->SetBConstrain(1);
91162307 4122 else
b9671574 4123 track->SetBConstrain(0);
4124 track->SetLastPoint(row1+fInnerSec->GetNRows()); // first cluster in track position
4125 track->SetFirstPoint(track->GetLastPoint());
91162307 4126
4127 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 4128 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
4129 track->GetNShared()>0.4*track->GetNumberOfClusters()) {
ddfbc51a 4130 MarkSeedFree( seed ); seed = 0;
91162307 4131 }
4132 else {
f06a1ff6 4133 arr->AddLast(track); // track IS seed, don't free seed
ddfbc51a 4134 seed = new( NextFreeSeed() ) AliTPCseed;
4135 seed->SetPoolID(fLastSeedID);
91162307 4136 }
4137 nin3++;
4138 }
4139 } // if accepted seed
4140 }
6bdc18d6 4141 if (fDebug>3){
4142 Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
91162307 4143 }
ddfbc51a 4144 if (seed) MarkSeedFree( seed );
91162307 4145}
4146
4147
829455ad 4148AliTPCseed *AliTPCtracker::MakeSeed(AliTPCseed *const track, Float_t r0, Float_t r1, Float_t r2)
91162307 4149{
4150 //
4151 //
d26d9159 4152 //reseed using track points
91162307 4153 Int_t p0 = int(r0*track->GetNumberOfClusters()); // point 0
4154 Int_t p1 = int(r1*track->GetNumberOfClusters());
4155 Int_t p2 = int(r2*track->GetNumberOfClusters()); // last point
176aff27 4156 Int_t pp2=0;
91162307 4157 Double_t x0[3],x1[3],x2[3];
89e09524 4158 for (Int_t i=0;i<3;i++){
4159 x0[i]=-1;
4160 x1[i]=-1;
4161 x2[i]=-1;
4162 }
91162307 4163
4164 // find track position at given ratio of the length
89e09524 4165 Int_t sec0=0, sec1=0, sec2=0;
91162307 4166 Int_t index=-1;
4167 Int_t clindex;
4168 for (Int_t i=0;i<160;i++){
b9671574 4169 if (track->GetClusterPointer(i)){
91162307 4170 index++;
4171 AliTPCTrackerPoint *trpoint =track->GetTrackPoint(i);
4172 if ( (index<p0) || x0[0]<0 ){
4173 if (trpoint->GetX()>1){
4174 clindex = track->GetClusterIndex2(i);
bad6eb00 4175 if (clindex >= 0){
91162307 4176 x0[0] = trpoint->GetX();
4177 x0[1] = trpoint->GetY();
4178 x0[2] = trpoint->GetZ();
4179 sec0 = ((clindex&0xff000000)>>24)%18;
4180 }
4181 }
4182 }
4183
4184 if ( (index<p1) &&(trpoint->GetX()>1)){
4185 clindex = track->GetClusterIndex2(i);
bad6eb00 4186 if (clindex >= 0){
91162307 4187 x1[0] = trpoint->GetX();
4188 x1[1] = trpoint->GetY();
4189 x1[2] = trpoint->GetZ();
4190 sec1 = ((clindex&0xff000000)>>24)%18;
4191 }
4192 }
4193 if ( (index<p2) &&(trpoint->GetX()>1)){
4194 clindex = track->GetClusterIndex2(i);
bad6eb00 4195 if (clindex >= 0){
91162307 4196 x2[0] = trpoint->GetX();
4197 x2[1] = trpoint->GetY();
4198 x2[2] = trpoint->GetZ();
4199 sec2 = ((clindex&0xff000000)>>24)%18;
4200 pp2 = i;
4201 }
4202 }
4203 }
4204 }
4205
4206 Double_t alpha, cs,sn, xx2,yy2;
4207 //
4208 alpha = (sec1-sec2)*fSectors->GetAlpha();
4209 cs = TMath::Cos(alpha);
4210 sn = TMath::Sin(alpha);
4211 xx2= x1[0]*cs-x1[1]*sn;
4212 yy2= x1[0]*sn+x1[1]*cs;
4213 x1[0] = xx2;
4214 x1[1] = yy2;
4215 //
4216 alpha = (sec0-sec2)*fSectors->GetAlpha();
4217 cs = TMath::Cos(alpha);
4218 sn = TMath::Sin(alpha);
4219 xx2= x0[0]*cs-x0[1]*sn;
4220 yy2= x0[0]*sn+x0[1]*cs;
4221 x0[0] = xx2;
4222 x0[1] = yy2;
4223 //
4224 //
4225 //
4226 Double_t x[5],c[15];
4227 //
4228 x[0]=x2[1];
4229 x[1]=x2[2];
b67e07dc 4230 x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
91162307 4231 // if (x[4]>1) return 0;
b67e07dc 4232 x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
4233 x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
91162307 4234 //if (TMath::Abs(x[3]) > 2.2) return 0;
4235 //if (TMath::Abs(x[2]) > 1.99) return 0;
4236 //
4237 Double_t sy =0.1, sz =0.1;
4238 //
4239 Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
4240 Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
4241 Double_t sy3=0.01+track->GetSigmaY2();
4242 //
b67e07dc 4243 Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
4244 Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
4245 Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
4246 Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
4247 Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
4248 Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
4249 //
4250 Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
4251 Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
4252 Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
4253 Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
91162307 4254
4255
4256 c[0]=sy1;
4257 c[1]=0.; c[2]=sz1;
4258 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4259 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4260 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4261 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4262 c[13]=f30*sy1*f40+f32*sy2*f42;
4263 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4264
4265 // Int_t row1 = fSectors->GetRowNumber(x2[0]);
ddfbc51a 4266 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4267 seed->SetPoolID(fLastSeedID);
91162307 4268 // Double_t y0,z0,y1,z1, y2,z2;
4269 //seed->GetProlongation(x0[0],y0,z0);
4270 // seed->GetProlongation(x1[0],y1,z1);
4271 //seed->GetProlongation(x2[0],y2,z2);
4272 // seed =0;
b9671574 4273 seed->SetLastPoint(pp2);
4274 seed->SetFirstPoint(pp2);
91162307 4275
4276
4277 return seed;
4278}
4279
d26d9159 4280
829455ad 4281AliTPCseed *AliTPCtracker::ReSeed(const AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
d26d9159 4282{
4283 //
4284 //
4285 //reseed using founded clusters
4286 //
4287 // Find the number of clusters
4288 Int_t nclusters = 0;
4289 for (Int_t irow=0;irow<160;irow++){
4290 if (track->GetClusterIndex(irow)>0) nclusters++;
4291 }
4292 //
4293 Int_t ipos[3];
4294 ipos[0] = TMath::Max(int(r0*nclusters),0); // point 0 cluster
4295 ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1); //
4296 ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1); // last point
4297 //
4298 //
ec26e231 4299 Double_t xyz[3][3]={{0}};
4300 Int_t row[3]={0},sec[3]={0,0,0};
d26d9159 4301 //
4302 // find track row position at given ratio of the length
4303 Int_t index=-1;
4304 for (Int_t irow=0;irow<160;irow++){
4305 if (track->GetClusterIndex2(irow)<0) continue;
4306 index++;
4307 for (Int_t ipoint=0;ipoint<3;ipoint++){
4308 if (index<=ipos[ipoint]) row[ipoint] = irow;
4309 }
4310 }
4311 //
4312 //Get cluster and sector position
4313 for (Int_t ipoint=0;ipoint<3;ipoint++){
4314 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4315 AliTPCclusterMI * cl = GetClusterMI(clindex);
4316 if (cl==0) {
6bdc18d6 4317 //Error("Bug\n");
47966a6d 4318 // AliTPCclusterMI * cl = GetClusterMI(clindex);
d26d9159 4319 return 0;
4320 }
4321 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4322 xyz[ipoint][0] = GetXrow(row[ipoint]);
4323 xyz[ipoint][1] = cl->GetY();
4324 xyz[ipoint][2] = cl->GetZ();
4325 }
4326 //
4327 //
4328 // Calculate seed state vector and covariance matrix
4329
4330 Double_t alpha, cs,sn, xx2,yy2;
4331 //
4332 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4333 cs = TMath::Cos(alpha);
4334 sn = TMath::Sin(alpha);
4335 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4336 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4337 xyz[1][0] = xx2;
4338 xyz[1][1] = yy2;
4339 //
4340 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4341 cs = TMath::Cos(alpha);
4342 sn = TMath::Sin(alpha);
4343 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4344 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4345 xyz[0][0] = xx2;
4346 xyz[0][1] = yy2;
4347 //
4348 //
4349 //
4350 Double_t x[5],c[15];
4351 //
4352 x[0]=xyz[2][1];
4353 x[1]=xyz[2][2];
4354 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4355 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4356 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4357 //
4358 Double_t sy =0.1, sz =0.1;
4359 //
4360 Double_t sy1=0.2, sz1=0.2;
4361 Double_t sy2=0.2, sz2=0.2;
4362 Double_t sy3=0.2;
4363 //
4364 Double_t f40=(F1(xyz[2][0],xyz[2][1]+sy,xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1])-x[4])/sy;
4365 Double_t f42=(F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1]+sy,xyz[0][0],xyz[0][1])-x[4])/sy;
4366 Double_t f43=(F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]+sy)-x[4])/sy;
4367 Double_t f20=(F2(xyz[2][0],xyz[2][1]+sy,xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1])-x[2])/sy;
4368 Double_t f22=(F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1]+sy,xyz[0][0],xyz[0][1])-x[2])/sy;
4369 Double_t f23=(F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]+sy)-x[2])/sy;
4370 //
4371 Double_t f30=(F3(xyz[2][0],xyz[2][1]+sy,xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2])-x[3])/sy;
4372 Double_t f31=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2]+sz,xyz[0][2])-x[3])/sz;
4373 Double_t f32=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1]+sy,xyz[2][2],xyz[0][2])-x[3])/sy;
4374 Double_t f34=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2]+sz)-x[3])/sz;
4375
4376
4377 c[0]=sy1;
4378 c[1]=0.; c[2]=sz1;
4379 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4380 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4381 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4382 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4383 c[13]=f30*sy1*f40+f32*sy2*f42;
4384 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4385
4386 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
ddfbc51a 4387 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4388 seed->SetPoolID(fLastSeedID);
b9671574 4389 seed->SetLastPoint(row[2]);
4390 seed->SetFirstPoint(row[2]);
d26d9159 4391 return seed;
4392}
4393
eea478d3 4394
829455ad 4395AliTPCseed *AliTPCtracker::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
eea478d3 4396{
4397 //
4398 //
4399 //reseed using founded clusters
4400 //
4401 Double_t xyz[3][3];
4a12af72 4402 Int_t row[3]={0,0,0};
4403 Int_t sec[3]={0,0,0};
eea478d3 4404 //
4405 // forward direction
4406 if (forward){
4407 for (Int_t irow=r0;irow<160;irow++){
4408 if (track->GetClusterIndex(irow)>0){
4409 row[0] = irow;
4410 break;
4411 }
4412 }
4413 for (Int_t irow=160;irow>r0;irow--){
4414 if (track->GetClusterIndex(irow)>0){
4415 row[2] = irow;
4416 break;
4417 }
4418 }
4419 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4420 if (track->GetClusterIndex(irow)>0){
4421 row[1] = irow;
4422 break;
4423 }
4424 }
4425 //
4426 }
4427 if (!forward){
4428 for (Int_t irow=0;irow<r0;irow++){
4429 if (track->GetClusterIndex(irow)>0){
4430 row[0] = irow;
4431 break;
4432 }
4433 }
4434 for (Int_t irow=r0;irow>0;irow--){
4435 if (track->GetClusterIndex(irow)>0){
4436 row[2] = irow;
4437 break;
4438 }
4439 }
4440 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4441 if (track->GetClusterIndex(irow)>0){
4442 row[1] = irow;
4443 break;
4444 }
4445 }
4446 }
4447 //
4448 if ((row[2]-row[0])<20) return 0;
4449 if (row[1]==0) return 0;
4450 //
4451 //
4452 //Get cluster and sector position
4453 for (Int_t ipoint=0;ipoint<3;ipoint++){
4454 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4455 AliTPCclusterMI * cl = GetClusterMI(clindex);
4456 if (cl==0) {
4457 //Error("Bug\n");
4458 // AliTPCclusterMI * cl = GetClusterMI(clindex);
4459 return 0;
4460 }
4461 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4462 xyz[ipoint][0] = GetXrow(row[ipoint]);
4463 AliTPCTrackerPoint * point = track->GetTrackPoint(row[ipoint]);
4464 if (point&&ipoint<2){
4465 //
4466 xyz[ipoint][1] = point->GetY();
4467 xyz[ipoint][2] = point->GetZ();
4468 }
4469 else{
4470 xyz[ipoint][1] = cl->GetY();
4471 xyz[ipoint][2] = cl->GetZ();
4472 }
4473 }
4474 //
4475 //
4476 //
4477 //
4478 // Calculate seed state vector and covariance matrix
4479
4480 Double_t alpha, cs,sn, xx2,yy2;
4481 //
4482 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4483 cs = TMath::Cos(alpha);
4484 sn = TMath::Sin(alpha);
4485 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4486 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4487 xyz[1][0] = xx2;
4488 xyz[1][1] = yy2;
4489 //
4490 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4491 cs = TMath::Cos(alpha);
4492 sn = TMath::Sin(alpha);
4493 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4494 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4495 xyz[0][0] = xx2;
4496 xyz[0][1] = yy2;
4497 //
4498 //
4499 //
4500 Double_t x[5],c[15];
4501 //
4502 x[0]=xyz[2][1];
4503 x[1]=xyz[2][2];
4504 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4505 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4506 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4507 //
4508 Double_t sy =0.1, sz =0.1;
4509 //
4510 Double_t sy1=0.2, sz1=0.2;
4511 Double_t sy2=0.2, sz2=0.2;
4512 Double_t sy3=0.2;
4513 //
4514 Double_t f40=(F1(xyz[2][0],xyz[2][1]+sy,xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1])-x[4])/sy;
4515 Double_t f42=(F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1]+sy,xyz[0][0],xyz[0][1])-x[4])/sy;
4516 Double_t f43=(F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]+sy)-x[4])/sy;
4517 Double_t f20=(F2(xyz[2][0],xyz[2][1]+sy,xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1])-x[2])/sy;
4518 Double_t f22=(F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1]+sy,xyz[0][0],xyz[0][1])-x[2])/sy;
4519 Double_t f23=(F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]+sy)-x[2])/sy;
4520 //
4521 Double_t f30=(F3(xyz[2][0],xyz[2][1]+sy,xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2])-x[3])/sy;
4522 Double_t f31=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2]+sz,xyz[0][2])-x[3])/sz;
4523 Double_t f32=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1]+sy,xyz[2][2],xyz[0][2])-x[3])/sy;
4524 Double_t f34=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2]+sz)-x[3])/sz;
4525
4526
4527 c[0]=sy1;
4528 c[1]=0.; c[2]=sz1;
4529 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4530 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4531 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4532 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4533 c[13]=f30*sy1*f40+f32*sy2*f42;
4534 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4535
4536 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
ddfbc51a 4537 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4538 seed->SetPoolID(fLastSeedID);
b9671574 4539 seed->SetLastPoint(row[2]);
4540 seed->SetFirstPoint(row[2]);
eea478d3 4541 for (Int_t i=row[0];i<row[2];i++){
b9671574 4542 seed->SetClusterIndex(i, track->GetClusterIndex(i));
eea478d3 4543 }
4544
4545 return seed;
4546}
4547
6d493ea0 4548
4549
829455ad 4550void AliTPCtracker::FindMultiMC(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
6d493ea0 4551{
4552 //
4553 // find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
4554 // USES MC LABELS
4555 // Use AliTPCReconstructor::StreamLevel()>2 if you want to tune parameters - cuts
4556 //
4557 // Two reasons to have multiple find tracks
4558 // 1. Curling tracks can be find more than once
4559 // 2. Splitted tracks
4560 // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
4561 // b.) Edge effect on the sector boundaries
4562 //
4563 //
4564 // Algorithm done in 2 phases - because of CPU consumption
4565 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4566 //
4567 // Algorihm for curling tracks sign:
4568 // 1 phase -makes a very rough fast cuts to minimize combinatorics
4569 // a.) opposite sign
4570 // b.) one of the tracks - not pointing to the primary vertex -
4571 // c.) delta tan(theta)
4572 // d.) delta phi
4573 // 2 phase - calculates DCA between tracks - time consument
4574
4575 //
4576 // fast cuts
4577 //
4578 // General cuts - for splitted tracks and for curling tracks
4579 //
4580 const Float_t kMaxdPhi = 0.2; // maximal distance in phi
4581 //
4582 // Curling tracks cuts
4583 //
4584 //
4585 //
4586 //
4587 Int_t nentries = array->GetEntriesFast();
4588 AliHelix *helixes = new AliHelix[nentries];
4589 Float_t *xm = new Float_t[nentries];
4590 Float_t *dz0 = new Float_t[nentries];
4591 Float_t *dz1 = new Float_t[nentries];
4592 //
4593 //
4594 TStopwatch timer;
4595 timer.Start();
4596 //
4597 // Find track COG in x direction - point with best defined parameters
4598 //
4599 for (Int_t i=0;i<nentries;i++){
4600 AliTPCseed* track = (AliTPCseed*)array->At(i);
4601 if (!track) continue;
4602 track->SetCircular(0);
4603 new (&helixes[i]) AliHelix(*track);
4604 Int_t ncl=0;
4605 xm[i]=0;
4606 Float_t dz[2];
4607 track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
4608 dz0[i]=dz[0];
4609 dz1[i]=dz[1];
4610 for (Int_t icl=0; icl<160; icl++){
4611 AliTPCclusterMI * cl = track->GetClusterPointer(icl);
4612 if (cl) {
4613 xm[i]+=cl->GetX();
4614 ncl++;
4615 }
4616 }
4617 if (ncl>0) xm[i]/=Float_t(ncl);
4618 }
6d493ea0 4619 //
4620 for (Int_t i0=0;i0<nentries;i0++){
4621 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4622 if (!track0) continue;
4623 Float_t xc0 = helixes[i0].GetHelix(6);
4624 Float_t yc0 = helixes[i0].GetHelix(7);
4625 Float_t r0 = helixes[i0].GetHelix(8);
4626 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4627 Float_t fi0 = TMath::ATan2(yc0,xc0);
4628
4629 for (Int_t i1=i0+1;i1<nentries;i1++){
4630 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4631 if (!track1) continue;
4632 Int_t lab0=track0->GetLabel();
4633 Int_t lab1=track1->GetLabel();
4634 if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
4635 //
4636 Float_t xc1 = helixes[i1].GetHelix(6);
4637 Float_t yc1 = helixes[i1].GetHelix(7);
4638 Float_t r1 = helixes[i1].GetHelix(8);
4639 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4640 Float_t fi1 = TMath::ATan2(yc1,xc1);
4641 //
4642 Float_t dfi = fi0-fi1;
4643 //
4644 //
4645 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
4646 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
4647 if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
4648 //
4649 // if short tracks with undefined sign
4650 fi1 = -TMath::ATan2(yc1,-xc1);
4651 dfi = fi0-fi1;
4652 }
4653 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4654
4655 //
4656 // debug stream to tune "fast cuts"
4657 //
4658 Double_t dist[3]; // distance at X
4659 Double_t mdist[3]={0,0,0}; // mean distance X+-40cm
4660 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
4661 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4662 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
4663 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4664 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
4665 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4666 for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
4667
4668 Float_t sum =0;
4669 Float_t sums=0;
4670 for (Int_t icl=0; icl<160; icl++){
4671 AliTPCclusterMI * cl0 = track0->GetClusterPointer(icl);
4672 AliTPCclusterMI * cl1 = track1->GetClusterPointer(icl);
4673 if (cl0&&cl1) {
4674 sum++;
4675 if (cl0==cl1) sums++;
4676 }
4677 }
4678 //
16299eac 4679 if (AliTPCReconstructor::StreamLevel()>5) {
b194b32c 4680 TTreeSRedirector &cstream = *fDebugStreamer;
6d493ea0 4681 cstream<<"Multi"<<
4682 "iter="<<iter<<
4683 "lab0="<<lab0<<
4684 "lab1="<<lab1<<
4685 "Tr0.="<<track0<< // seed0
4686 "Tr1.="<<track1<< // seed1
4687 "h0.="<<&helixes[i0]<<
4688 "h1.="<<&helixes[i1]<<
4689 //
4690 "sum="<<sum<< //the sum of rows with cl in both
4691 "sums="<<sums<< //the sum of shared clusters
4692 "xm0="<<xm[i0]<< // the center of track
4693 "xm1="<<xm[i1]<< // the x center of track
4694 // General cut variables
4695 "dfi="<<dfi<< // distance in fi angle
4696 "dtheta="<<dtheta<< // distance int theta angle
4697 //
4698 "dz00="<<dz0[i0]<<
4699 "dz01="<<dz0[i1]<<
4700 "dz10="<<dz1[i1]<<
4701 "dz11="<<dz1[i1]<<
4702 "dist0="<<dist[0]<< //distance x
4703 "dist1="<<dist[1]<< //distance y
4704 "dist2="<<dist[2]<< //distance z
4705 "mdist0="<<mdist[0]<< //distance x
4706 "mdist1="<<mdist[1]<< //distance y
4707 "mdist2="<<mdist[2]<< //distance z
4708 //
4709 "r0="<<r0<<
4710 "rc0="<<rc0<<
4711 "fi0="<<fi0<<
4712 "fi1="<<fi1<<
4713 "r1="<<r1<<
4714 "rc1="<<rc1<<
4715 "\n";
b194b32c 4716 }
6d493ea0 4717 }
4718 }
4719 delete [] helixes;
4720 delete [] xm;
ec26e231 4721 delete [] dz0;
4722 delete [] dz1;
6d493ea0 4723 if (AliTPCReconstructor::StreamLevel()>1) {
4724 AliInfo("Time for curling tracks removal DEBUGGING MC");
4725 timer.Print();
4726 }
4727}
4728
4729
1af5da7e 4730
829455ad 4731void AliTPCtracker::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t /*iter*/){
6d493ea0 4732 //
6fbe1e5c 4733 // Find Splitted tracks and remove the one with worst quality
4734 // Corresponding debug streamer to tune selections - "Splitted2"
4735 // Algorithm:
4736 // 0. Sort tracks according quility
4737 // 1. Propagate the tracks to the reference radius
4738 // 2. Double_t loop to select close tracks (only to speed up process)
4739 // 3. Calculate cluster overlap ratio - and remove the track if bigger than a threshold
4740 // 4. Delete temporary parameters
4741 //
4742 const Double_t xref=GetXrow(63); // reference radius -IROC/OROC boundary
4743 // rough cuts
4744 const Double_t kCutP1=10; // delta Z cut 10 cm
4745 const Double_t kCutP2=0.15; // delta snp(fi) cut 0.15
4746 const Double_t kCutP3=0.15; // delta tgl(theta) cut 0.15
4747 const Double_t kCutAlpha=0.15; // delta alpha cut
4748 Int_t firstpoint = 0;
4749 Int_t lastpoint = 160;
6d493ea0 4750 //
4751 Int_t nentries = array->GetEntriesFast();
6fbe1e5c 4752 AliExternalTrackParam *params = new AliExternalTrackParam[nentries];
6d493ea0 4753 //
4754 //
4755 TStopwatch timer;
4756 timer.Start();
4757 //
6fbe1e5c 4758 //0. Sort tracks according quality
4759 //1. Propagate the ext. param to reference radius
6d493ea0 4760 Int_t nseed = array->GetEntriesFast();
6e23caff 4761 if (nseed<=0) return;
6d493ea0 4762 Float_t * quality = new Float_t[nseed];
4763 Int_t * indexes = new Int_t[nseed];
4764 for (Int_t i=0; i<nseed; i++) {
4765 AliTPCseed *pt=(AliTPCseed*)array->UncheckedAt(i);
4766 if (!pt){
4767 quality[i]=-1;
4768 continue;
4769 }
4770 pt->UpdatePoints(); //select first last max dens points
4771 Float_t * points = pt->GetPoints();
4772 if (points[3]<0.8) quality[i] =-1;
4773 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
1af5da7e 4774 //prefer high momenta tracks if overlaps
4775 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
6fbe1e5c 4776 params[i]=(*pt);
4777 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),5.,kTRUE);
4778 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),1.,kTRUE);
6d493ea0 4779 }
4780 TMath::Sort(nseed,quality,indexes);
6d493ea0 4781 //
6fbe1e5c 4782 // 3. Loop over pair of tracks
4783 //
4784 for (Int_t i0=0; i0<nseed; i0++) {
4785 Int_t index0=indexes[i0];
4786 if (!(array->UncheckedAt(index0))) continue;
4787 AliTPCseed *s1 = (AliTPCseed*)array->UncheckedAt(index0);
4788 if (!s1->IsActive()) continue;
4789 AliExternalTrackParam &par0=params[index0];
4790 for (Int_t i1=i0+1; i1<nseed; i1++) {
4791 Int_t index1=indexes[i1];
4792 if (!(array->UncheckedAt(index1))) continue;
4793 AliTPCseed *s2 = (AliTPCseed*)array->UncheckedAt(index1);
4794 if (!s2->IsActive()) continue;
4795 if (s2->GetKinkIndexes()[0]!=0)
4796 if (s2->GetKinkIndexes()[0] == -s1->GetKinkIndexes()[0]) continue;
4797 AliExternalTrackParam &par1=params[index1];
4798 if (TMath::Abs(par0.GetParameter()[3]-par1.GetParameter()[3])>kCutP3) continue;
4799 if (TMath::Abs(par0.GetParameter()[1]-par1.GetParameter()[1])>kCutP1) continue;
4800 if (TMath::Abs(par0.GetParameter()[2]-par1.GetParameter()[2])>kCutP2) continue;
4801 Double_t dAlpha= TMath::Abs(par0.GetAlpha()-par1.GetAlpha());
4802 if (dAlpha>TMath::Pi()) dAlpha-=TMath::Pi();
4803 if (TMath::Abs(dAlpha)>kCutAlpha) continue;
6d493ea0 4804 //
6fbe1e5c 4805 Int_t sumShared=0;
4806 Int_t nall0=0;
4807 Int_t nall1=0;
4808 Int_t firstShared=lastpoint, lastShared=firstpoint;
4809 Int_t firstRow=lastpoint, lastRow=firstpoint;
6d493ea0 4810 //
6fbe1e5c 4811 for (Int_t i=firstpoint;i<lastpoint;i++){
4812 if (s1->GetClusterIndex2(i)>0) nall0++;
4813 if (s2->GetClusterIndex2(i)>0) nall1++;
4814 if (s1->GetClusterIndex2(i)>0 && s2->GetClusterIndex2(i)>0) {
4815 if (i<firstRow) firstRow=i;
4816 if (i>lastRow) lastRow=i;
4817 }
4818 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
4819 if (i<firstShared) firstShared=i;
4820 if (i>lastShared) lastShared=i;
4821 sumShared++;
4822 }
4823 }
4824 Double_t ratio0 = Float_t(sumShared)/Float_t(TMath::Min(nall0+1,nall1+1));
4825 Double_t ratio1 = Float_t(sumShared)/Float_t(TMath::Max(nall0+1,nall1+1));
4826
16299eac 4827 if( AliTPCReconstructor::StreamLevel()>1){
6fbe1e5c 4828 TTreeSRedirector &cstream = *fDebugStreamer;
4829 Int_t n0=s1->GetNumberOfClusters();
4830 Int_t n1=s2->GetNumberOfClusters();
4831 Int_t n0F=s1->GetNFoundable();
4832 Int_t n1F=s2->GetNFoundable();
4833 Int_t lab0=s1->GetLabel();
4834 Int_t lab1=s2->GetLabel();
4835
4836 cstream<<"Splitted2"<<
4837 "iter="<<fIteration<<
4838 "lab0="<<lab0<< // MC label if exist
4839 "lab1="<<lab1<< // MC label if exist
4840 "index0="<<index0<<
4841 "index1="<<index1<<
4842 "ratio0="<<ratio0<< // shared ratio
4843 "ratio1="<<ratio1<< // shared ratio
4844 "p0.="<<&par0<< // track parameters
4845 "p1.="<<&par1<<
4846 "s0.="<<s1<< // full seed
4847 "s1.="<<s2<<
4848 "n0="<<n0<< // number of clusters track 0
4849 "n1="<<n1<< // number of clusters track 1
4850 "nall0="<<nall0<< // number of clusters track 0
4851 "nall1="<<nall1<< // number of clusters track 1
4852 "n0F="<<n0F<< // number of findable
4853 "n1F="<<n1F<< // number of findable
4854 "shared="<<sumShared<< // number of shared clusters
4855 "firstS="<<firstShared<< // first and the last shared row
4856 "lastS="<<lastShared<<
4857 "firstRow="<<firstRow<< // first and the last row with cluster
4858 "lastRow="<<lastRow<< //
4859 "\n";
6d493ea0 4860 }
6d493ea0 4861 //
6fbe1e5c 4862 // remove track with lower quality
6d493ea0 4863 //
6fbe1e5c 4864 if (ratio0>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(0) ||
4865 ratio1>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(1)){
4866 //
4867 //
4868 //
ddfbc51a 4869 MarkSeedFree( array->RemoveAt(index1) );
44adbd4b 4870 }
6d493ea0 4871 }
6fbe1e5c 4872 }
4873 //
4874 // 4. Delete temporary array
4875 //
4876 delete [] params;
6e23caff 4877 delete [] quality;
4878 delete [] indexes;
4879
6d493ea0 4880}
4881
4882
4883
829455ad 4884void AliTPCtracker::FindCurling(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
6d493ea0 4885{
4886 //
4887 // find Curling tracks
4888 // Use AliTPCReconstructor::StreamLevel()>1 if you want to tune parameters - cuts
4889 //
4890 //
4891 // Algorithm done in 2 phases - because of CPU consumption
4892 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4893 // see detal in MC part what can be used to cut
4894 //
4895 //
4896 //
4897 const Float_t kMaxC = 400; // maximal curvature to of the track
4898 const Float_t kMaxdTheta = 0.15; // maximal distance in theta
4899 const Float_t kMaxdPhi = 0.15; // maximal distance in phi
4900 const Float_t kPtRatio = 0.3; // ratio between pt
4901 const Float_t kMinDCAR = 2.; // distance to the primary vertex in r - see cpipe cut
4902
4903 //
4904 // Curling tracks cuts
4905 //
4906 //
4907 const Float_t kMaxDeltaRMax = 40; // distance in outer radius
4908 const Float_t kMaxDeltaRMin = 5.; // distance in lower radius - see cpipe cut
4909 const Float_t kMinAngle = 2.9; // angle between tracks
4910 const Float_t kMaxDist = 5; // biggest distance
4911 //
4912 // The cuts can be tuned using the "MC information stored in Multi tree ==> see FindMultiMC
4913 /*
4914 Fast cuts:
4915 TCut csign("csign","Tr0.fP[4]*Tr1.fP[4]<0"); //opposite sign
4916 TCut cmax("cmax","abs(Tr0.GetC())>1/400");
4917 TCut cda("cda","sqrt(dtheta^2+dfi^2)<0.15");
4918 TCut ccratio("ccratio","abs((Tr0.fP[4]+Tr1.fP[4])/(abs(Tr0.fP[4])+abs(Tr1.fP[4])))<0.3");
4919 TCut cpipe("cpipe", "min(abs(r0-rc0),abs(r1-rc1))>5");
4920 //
4921 TCut cdrmax("cdrmax","abs(abs(rc0+r0)-abs(rc1+r1))<40")
4922 TCut cdrmin("cdrmin","abs(abs(rc0+r0)-abs(rc1+r1))<10")
4923 //
4924 Multi->Draw("dfi","iter==0"+csign+cmax+cda+ccratio); ~94% of curling tracks fulfill
4925 Multi->Draw("min(abs(r0-rc0),abs(r1-rc1))","iter==0&&abs(lab1)==abs(lab0)"+csign+cmax+cda+ccratio+cpipe+cdrmin+cdrmax); //80%
4926 //
4927 Curling2->Draw("dfi","iter==0&&abs(lab0)==abs(lab1)"+csign+cmax+cdtheta+cdfi+ccratio)
4928
4929 */
4930 //
4931 //
4932 //
4933 Int_t nentries = array->GetEntriesFast();
4934 AliHelix *helixes = new AliHelix[nentries];
4935 for (Int_t i=0;i<nentries;i++){
4936 AliTPCseed* track = (AliTPCseed*)array->At(i);
4937 if (!track) continue;
4938 track->SetCircular(0);
4939 new (&helixes[i]) AliHelix(*track);
4940 }
4941 //
4942 //
4943 TStopwatch timer;
4944 timer.Start();
ec26e231 4945 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
4946
6d493ea0 4947 //
4948 // Find tracks
4949 //
6d493ea0 4950 //
4951 for (Int_t i0=0;i0<nentries;i0++){
4952 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4953 if (!track0) continue;
4954 if (TMath::Abs(track0->GetC())<1/kMaxC) continue;
4955 Float_t xc0 = helixes[i0].GetHelix(6);
4956 Float_t yc0 = helixes[i0].GetHelix(7);
4957 Float_t r0 = helixes[i0].GetHelix(8);
4958 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4959 Float_t fi0 = TMath::ATan2(yc0,xc0);
4960
4961 for (Int_t i1=i0+1;i1<nentries;i1++){
4962 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4963 if (!track1) continue;
4964 if (TMath::Abs(track1->GetC())<1/kMaxC) continue;
4965 Float_t xc1 = helixes[i1].GetHelix(6);
4966 Float_t yc1 = helixes[i1].GetHelix(7);
4967 Float_t r1 = helixes[i1].GetHelix(8);
4968 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4969 Float_t fi1 = TMath::ATan2(yc1,xc1);
4970 //
4971 Float_t dfi = fi0-fi1;
4972 //
4973 //
4974 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
4975 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
4976 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4977 //
4978 //
4979 // FIRST fast cuts
4980 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue; // not constrained
4981 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue; // not the same sign
4982 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>kMaxdTheta) continue; //distance in the Theta
4983 if ( TMath::Abs(dfi)>kMaxdPhi) continue; //distance in phi
4984 if ( TMath::Sqrt(dfi*dfi+dtheta*dtheta)>kMaxdPhi) continue; //common angular offset
4985 //
4986 Float_t pt0 = track0->GetSignedPt();
4987 Float_t pt1 = track1->GetSignedPt();
4988 if ((TMath::Abs(pt0+pt1)/(TMath::Abs(pt0)+TMath::Abs(pt1)))>kPtRatio) continue;
4989 if ((iter==1) && TMath::Abs(TMath::Abs(rc0+r0)-TMath::Abs(rc1+r1))>kMaxDeltaRMax) continue;
4990 if ((iter!=1) &&TMath::Abs(TMath::Abs(rc0-r0)-TMath::Abs(rc1-r1))>kMaxDeltaRMin) continue;
4991 if (TMath::Min(TMath::Abs(rc0-r0),TMath::Abs(rc1-r1))<kMinDCAR) continue;
4992 //
4993 //
4994 // Now find closest approach
4995 //
4996 //
4997 //
4998 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4999 if (npoints==0) continue;
5000 helixes[i0].GetClosestPhases(helixes[i1], phase);
5001 //
5002 Double_t xyz0[3];
5003 Double_t xyz1[3];
5004 Double_t hangles[3];
5005 helixes[i0].Evaluate(phase[0][0],xyz0);
5006 helixes[i1].Evaluate(phase[0][1],xyz1);
5007
5008 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5009 Double_t deltah[2],deltabest;
5010 if (TMath::Abs(hangles[2])<kMinAngle) continue;
5011
5012 if (npoints>0){
5013 Int_t ibest=0;
5014 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
5015 if (npoints==2){
5016 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
5017 if (deltah[1]<deltah[0]) ibest=1;
5018 }
5019 deltabest = TMath::Sqrt(deltah[ibest]);
5020 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5021 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5022 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5023 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5024 //
5025 if (deltabest>kMaxDist) continue;
5026 // if (mindcar+mindcaz<40 && (TMath::Abs(hangles[2])<kMinAngle ||deltabest>3)) continue;
5027 Bool_t sign =kFALSE;
5028 if (hangles[2]>kMinAngle) sign =kTRUE;
5029 //
5030 if (sign){
5031 // circular[i0] = kTRUE;
5032 // circular[i1] = kTRUE;
5033 if (track0->OneOverPt()<track1->OneOverPt()){
5034 track0->SetCircular(track0->GetCircular()+1);
5035 track1->SetCircular(track1->GetCircular()+2);
5036 }
5037 else{
5038 track1->SetCircular(track1->GetCircular()+1);
5039 track0->SetCircular(track0->GetCircular()+2);
5040 }
5041 }
16299eac 5042 if (AliTPCReconstructor::StreamLevel()>2){
6d493ea0 5043 //
5044 //debug stream to tune "fine" cuts
5045 Int_t lab0=track0->GetLabel();
5046 Int_t lab1=track1->GetLabel();
b194b32c 5047 TTreeSRedirector &cstream = *fDebugStreamer;
6d493ea0 5048 cstream<<"Curling2"<<
5049 "iter="<<iter<<
5050 "lab0="<<lab0<<
5051 "lab1="<<lab1<<
5052 "Tr0.="<<track0<<
5053 "Tr1.="<<track1<<
5054 //
5055 "r0="<<r0<<
5056 "rc0="<<rc0<<
5057 "fi0="<<fi0<<
5058 "r1="<<r1<<
5059 "rc1="<<rc1<<
5060 "fi1="<<fi1<<
5061 "dfi="<<dfi<<
5062 "dtheta="<<dtheta<<
5063 //
5064 "npoints="<<npoints<<
5065 "hangles0="<<hangles[0]<<
5066 "hangles1="<<hangles[1]<<
5067 "hangles2="<<hangles[2]<<
5068 "xyz0="<<xyz0[2]<<
5069 "xyzz1="<<xyz1[2]<<
5070 "radius="<<radiusbest<<
5071 "deltabest="<<deltabest<<
5072 "phase0="<<phase[ibest][0]<<
5073 "phase1="<<phase[ibest][1]<<
5074 "\n";
5075
5076 }
5077 }
5078 }
5079 }
5080 delete [] helixes;
5081 if (AliTPCReconstructor::StreamLevel()>1) {
5082 AliInfo("Time for curling tracks removal");
5083 timer.Print();
5084 }
5085}
5086
5087
829455ad 5088void AliTPCtracker::FindKinks(TObjArray * array, AliESDEvent *esd)
51ad6848 5089{
5090 //
5091 // find kinks
5092 //
5093 //
f06a1ff6 5094 // RS something is wrong in this routine: not all seeds are assigned to daughters and mothers array, but they all are queried
5095 // to check later
ddfbc51a 5096
5097 TObjArray *kinks= new TObjArray(10000);
81e97e0d 5098 // TObjArray *v0s= new TObjArray(10000);
51ad6848 5099 Int_t nentries = array->GetEntriesFast();
ddfbc51a 5100 AliHelix *helixes = new AliHelix[nentries];
5101 Int_t *sign = new Int_t[nentries];
5102 Int_t *nclusters = new Int_t[nentries];
5103 Float_t *alpha = new Float_t[nentries];
5104 AliKink *kink = new AliKink();
5105 Int_t * usage = new Int_t[nentries];
5106 Float_t *zm = new Float_t[nentries];
5107 Float_t *z0 = new Float_t[nentries];
5108 Float_t *fim = new Float_t[nentries];
5109 Float_t *shared = new Float_t[nentries];
5110 Bool_t *circular = new Bool_t[nentries];
5111 Float_t *dca = new Float_t[nentries];
81e97e0d 5112 //const AliESDVertex * primvertex = esd->GetVertex();
eea478d3 5113 //
5114 // nentries = array->GetEntriesFast();
ddfbc51a 5115 //
5116
51ad6848 5117 //
5118 //
5119 for (Int_t i=0;i<nentries;i++){
5120 sign[i]=0;
5121 usage[i]=0;
5122 AliTPCseed* track = (AliTPCseed*)array->At(i);
5123 if (!track) continue;
b9671574 5124 track->SetCircular(0);
eea478d3 5125 shared[i] = kFALSE;
51ad6848 5126 track->UpdatePoints();
5127 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
51ad6848 5128 }
eea478d3 5129 nclusters[i]=track->GetNumberOfClusters();
5130 alpha[i] = track->GetAlpha();
5131 new (&helixes[i]) AliHelix(*track);
5132 Double_t xyz[3];
5133 helixes[i].Evaluate(0,xyz);
5134 sign[i] = (track->GetC()>0) ? -1:1;
5135 Double_t x,y,z;
5136 x=160;
5137 if (track->GetProlongation(x,y,z)){
5138 zm[i] = z;
5139 fim[i] = alpha[i]+TMath::ATan2(y,x);
5140 }
5141 else{
5142 zm[i] = track->GetZ();
5143 fim[i] = alpha[i];
5144 }
5145 z0[i]=1000;
5146 circular[i]= kFALSE;
81e97e0d 5147 if (track->GetProlongation(0,y,z)) z0[i] = z;
5148 dca[i] = track->GetD(0,0);
51ad6848 5149 }
5150 //
5151 //
5152 TStopwatch timer;
5153 timer.Start();
5154 Int_t ncandidates =0;
5155 Int_t nall =0;
5156 Int_t ntracks=0;
ec26e231 5157 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
eea478d3 5158
5159 //
5160 // Find circling track
eea478d3 5161 //
5162 for (Int_t i0=0;i0<nentries;i0++){
5163 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5164 if (!track0) continue;
b9671574 5165 if (track0->GetNumberOfClusters()<40) continue;
6c94f330 5166 if (TMath::Abs(1./track0->GetC())>200) continue;
eea478d3 5167 for (Int_t i1=i0+1;i1<nentries;i1++){
5168 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5169 if (!track1) continue;
b9671574 5170 if (track1->GetNumberOfClusters()<40) continue;
6c94f330 5171 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
b9671574 5172 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
6c94f330 5173 if (TMath::Abs(1./track1->GetC())>200) continue;
8467b758 5174 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
6c94f330 5175 if (track1->GetTgl()*track0->GetTgl()>0) continue;
1b36647b 5176 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
8467b758 5177 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
5178 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
eea478d3 5179 //
81e97e0d 5180 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
5181 if (mindcar<5) continue;
5182 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
5183 if (mindcaz<5) continue;
5184 if (mindcar+mindcaz<20) continue;
5185 //
5186 //
eea478d3 5187 Float_t xc0 = helixes[i0].GetHelix(6);
5188 Float_t yc0 = helixes[i0].GetHelix(7);
5189 Float_t r0 = helixes[i0].GetHelix(8);
5190 Float_t xc1 = helixes[i1].GetHelix(6);
5191 Float_t yc1 = helixes[i1].GetHelix(7);
5192 Float_t r1 = helixes[i1].GetHelix(8);
5193
5194 Float_t rmean = (r0+r1)*0.5;
5195 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
81e97e0d 5196 //if (delta>30) continue;
eea478d3 5197 if (delta>rmean*0.25) continue;
5198 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
5199 //
5200 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5201 if (npoints==0) continue;
5202 helixes[i0].GetClosestPhases(helixes[i1], phase);
5203 //
5204 Double_t xyz0[3];
5205 Double_t xyz1[3];
5206 Double_t hangles[3];
5207 helixes[i0].Evaluate(phase[0][0],xyz0);
5208 helixes[i1].Evaluate(phase[0][1],xyz1);
5209
5210 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5211 Double_t deltah[2],deltabest;
5212 if (hangles[2]<2.8) continue;
eea478d3 5213 if (npoints>0){
5214 Int_t ibest=0;
81e97e0d 5215 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
eea478d3 5216 if (npoints==2){
81e97e0d 5217 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
eea478d3 5218 if (deltah[1]<deltah[0]) ibest=1;
5219 }
5220 deltabest = TMath::Sqrt(deltah[ibest]);
5221 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5222 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5223 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
81e97e0d 5224 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
eea478d3 5225 //
81e97e0d 5226 if (deltabest>6) continue;
5227 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
77f88633 5228 Bool_t lsign =kFALSE;
5229 if (hangles[2]>3.06) lsign =kTRUE;
81e97e0d 5230 //
77f88633 5231 if (lsign){
eea478d3 5232 circular[i0] = kTRUE;
81e97e0d 5233 circular[i1] = kTRUE;
8467b758 5234 if (track0->OneOverPt()<track1->OneOverPt()){
b9671574 5235 track0->SetCircular(track0->GetCircular()+1);
5236 track1->SetCircular(track1->GetCircular()+2);
81e97e0d 5237 }
5238 else{
b9671574 5239 track1->SetCircular(track1->GetCircular()+1);
5240 track0->SetCircular(track0->GetCircular()+2);
81e97e0d 5241 }
5242 }
77f88633 5243 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
34acb742 5244 //debug stream
b9671574 5245 Int_t lab0=track0->GetLabel();
5246 Int_t lab1=track1->GetLabel();
b194b32c 5247 TTreeSRedirector &cstream = *fDebugStreamer;
81e97e0d 5248 cstream<<"Curling"<<
b9671574 5249 "lab0="<<lab0<<
5250 "lab1="<<lab1<<
81e97e0d 5251 "Tr0.="<<track0<<
5252 "Tr1.="<<track1<<
5253 "dca0="<<dca[i0]<<
5254 "dca1="<<dca[i1]<<
5255 "mindcar="<<mindcar<<
5256 "mindcaz="<<mindcaz<<
5257 "delta="<<delta<<
5258 "rmean="<<rmean<<
5259 "npoints="<<npoints<<
5260 "hangles0="<<hangles[0]<<
5261 "hangles2="<<hangles[2]<<
5262 "xyz0="<<xyz0[2]<<
5263 "xyzz1="<<xyz1[2]<<
5264 "z0="<<z0[i0]<<
5265 "z1="<<z0[i1]<<
5266 "radius="<<radiusbest<<
5267 "deltabest="<<deltabest<<
5268 "phase0="<<phase[ibest][0]<<
5269 "phase1="<<phase[ibest][1]<<
5270 "\n";
eea478d3 5271 }
5272 }
5273 }
5274 }
5275 //
ddfbc51a 5276 // Finf kinks loop
81e97e0d 5277 //
51ad6848 5278 //
5279 for (Int_t i =0;i<nentries;i++){
5280 if (sign[i]==0) continue;
5281 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
c1ea348f 5282 if (track0==0) {
5283 AliInfo("seed==0");
5284 continue;
5285 }
51ad6848 5286 ntracks++;
5287 //
5288 Double_t cradius0 = 40*40;
5289 Double_t cradius1 = 270*270;
5290 Double_t cdist1=8.;
5291 Double_t cdist2=8.;
5292 Double_t cdist3=0.55;
5293 for (Int_t j =i+1;j<nentries;j++){
5294 nall++;
5295 if (sign[j]*sign[i]<1) continue;
5296 if ( (nclusters[i]+nclusters[j])>200) continue;
5297 if ( (nclusters[i]+nclusters[j])<80) continue;
5298 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
5299 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
5300 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
5301 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5302 if (npoints<1) continue;
5303 // cuts on radius
5304 if (npoints==1){
5305 if (radius[0]<cradius0||radius[0]>cradius1) continue;
5306 }
5307 else{
5308 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
5309 }
5310 //
5311 Double_t delta1=10000,delta2=10000;
5312 // cuts on the intersection radius
5313 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5314 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5315 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5316 if (npoints==2){
5317 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5318 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5319 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5320 }
5321 //
5322 Double_t distance1 = TMath::Min(delta1,delta2);
5323 if (distance1>cdist1) continue; // cut on DCA linear approximation
5324 //
5325 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5326 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5327 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5328 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5329 //
5330 if (npoints==2){
5331 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5332 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5333 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5334 }
5335 distance1 = TMath::Min(delta1,delta2);
5336 Float_t rkink =0;
5337 if (delta1<delta2){
5338 rkink = TMath::Sqrt(radius[0]);
5339 }
5340 else{
5341 rkink = TMath::Sqrt(radius[1]);
5342 }
5343 if (distance1>cdist2) continue;
5344 //
5345 //
5346 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5347 //
5348 //
5349 Int_t row0 = GetRowNumber(rkink);
5350 if (row0<10) continue;
5351 if (row0>150) continue;
5352 //
5353 //
5354 Float_t dens00=-1,dens01=-1;
5355 Float_t dens10=-1,dens11=-1;
5356 //
77f88633 5357 Int_t found,foundable,ishared;
5358 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
51ad6848 5359 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
77f88633 5360 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
51ad6848 5361 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
5362 //
77f88633 5363 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
51ad6848 5364 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
77f88633 5365 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
51ad6848 5366 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
eea478d3 5367 //
51ad6848 5368 if (dens00<dens10 && dens01<dens11) continue;
5369 if (dens00>dens10 && dens01>dens11) continue;
5370 if (TMath::Max(dens00,dens10)<0.1) continue;
5371 if (TMath::Max(dens01,dens11)<0.3) continue;
5372 //
5373 if (TMath::Min(dens00,dens10)>0.6) continue;
5374 if (TMath::Min(dens01,dens11)>0.6) continue;
5375
5376 //
5377 AliTPCseed * ktrack0, *ktrack1;
5378 if (dens00>dens10){
5379 ktrack0 = track0;
5380 ktrack1 = track1;
5381 }
5382 else{
5383 ktrack0 = track1;
5384 ktrack1 = track0;
5385 }
5386 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
5387 AliExternalTrackParam paramm(*ktrack0);
5388 AliExternalTrackParam paramd(*ktrack1);
316c6cd9 5389 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
51ad6848 5390 //
5391 //
5392 kink->SetMother(paramm);
5393 kink->SetDaughter(paramd);
5394 kink->Update();
5395
2942f542 5396 Float_t x[3] = { static_cast<Float_t>(kink->GetPosition()[0]),static_cast<Float_t>(kink->GetPosition()[1]),static_cast<Float_t>(kink->GetPosition()[2])};
51ad6848 5397 Int_t index[4];
47af7ca4 5398 fkParam->Transform0to1(x,index);
5399 fkParam->Transform1to2(x,index);
51ad6848 5400 row0 = GetRowNumber(x[0]);
5401
eea478d3 5402 if (kink->GetR()<100) continue;
5403 if (kink->GetR()>240) continue;
5404 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
5405 if (kink->GetDistance()>cdist3) continue;
5406 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
51ad6848 5407 if (dird<0) continue;
5408
eea478d3 5409 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
51ad6848 5410 if (dirm<0) continue;
eea478d3 5411 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
51ad6848 5412 if (mpt<0.2) continue;
5413
eea478d3 5414 if (mpt<1){
5415 //for high momenta momentum not defined well in first iteration
6c94f330 5416 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
eea478d3 5417 if (qt>0.35) continue;
5418 }
51ad6848 5419
eea478d3 5420 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
5421 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
51ad6848 5422 if (dens00>dens10){
eea478d3 5423 kink->SetTPCDensity(dens00,0,0);
5424 kink->SetTPCDensity(dens01,0,1);
5425 kink->SetTPCDensity(dens10,1,0);
5426 kink->SetTPCDensity(dens11,1,1);
5427 kink->SetIndex(i,0);
5428 kink->SetIndex(j,1);
51ad6848 5429 }
5430 else{
eea478d3 5431 kink->SetTPCDensity(dens10,0,0);
5432 kink->SetTPCDensity(dens11,0,1);
5433 kink->SetTPCDensity(dens00,1,0);
5434 kink->SetTPCDensity(dens01,1,1);
5435 kink->SetIndex(j,0);
5436 kink->SetIndex(i,1);
51ad6848 5437 }
51ad6848 5438
eea478d3 5439 if (mpt<1||kink->GetAngle(2)>0.1){
5440 // angle and densities not defined yet
5441 if (kink->GetTPCDensityFactor()<0.8) continue;
5442 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
6c94f330 5443 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
eea478d3 5444 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5445 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5446
6c94f330 5447 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5448 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
eea478d3 5449 criticalangle= 3*TMath::Sqrt(criticalangle);
5450 if (criticalangle>0.02) criticalangle=0.02;
5451 if (kink->GetAngle(2)<criticalangle) continue;
5452 }
51ad6848 5453 //
eea478d3 5454 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
51ad6848 5455 Float_t shapesum =0;
5456 Float_t sum = 0;
5457 for ( Int_t row = row0-drow; row<row0+drow;row++){
5458 if (row<0) continue;
5459 if (row>155) continue;
b9671574 5460 if (ktrack0->GetClusterPointer(row)){
51ad6848 5461 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5462 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5463 sum++;
5464 }
b9671574 5465 if (ktrack1->GetClusterPointer(row)){
51ad6848 5466 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5467 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5468 sum++;
5469 }
5470 }
5471 if (sum<4){
eea478d3 5472 kink->SetShapeFactor(-1.);
51ad6848 5473 }
5474 else{
eea478d3 5475 kink->SetShapeFactor(shapesum/sum);
5476 }
51ad6848 5477 // esd->AddKink(kink);
16299eac 5478 //
5479 // kink->SetMother(paramm);
5480 //kink->SetDaughter(paramd);
5481
5482 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
5483 chi2P2*=chi2P2;
5484 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
5485 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
5486 chi2P3*=chi2P3;
5487 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
5488 //
5489 if (AliTPCReconstructor::StreamLevel()>1) {
5490 (*fDebugStreamer)<<"kinkLpt"<<
5491 "chi2P2="<<chi2P2<<
5492 "chi2P3="<<chi2P3<<
5493 "p0.="<<&paramm<<
5494 "p1.="<<&paramd<<
5495 "k.="<<kink<<
5496 "\n";
5497 }
5498 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
5499 continue;
5500 }
5501 //
ddfbc51a 5502 kinks->AddLast(kink);
5503 kink = new AliKink;
51ad6848 5504 ncandidates++;
5505 }
5506 }
ddfbc51a 5507 //
eea478d3 5508 // sort the kinks according quality - and refit them towards vertex
5509 //
ddfbc51a 5510 Int_t nkinks = kinks->GetEntriesFast();
5511 Float_t *quality = new Float_t[nkinks];
5512 Int_t *indexes = new Int_t[nkinks];
5513 AliTPCseed *mothers = new AliTPCseed[nkinks];
5514 AliTPCseed *daughters = new AliTPCseed[nkinks];
eea478d3 5515 //
5516 //
51ad6848 5517 for (Int_t i=0;i<nkinks;i++){
5518 quality[i] =100000;
ddfbc51a 5519 AliKink *kinkl = (AliKink*)kinks->At(i);
eea478d3 5520 //
5521 // refit kinks towards vertex
5522 //
77f88633 5523 Int_t index0 = kinkl->GetIndex(0);
5524 Int_t index1 = kinkl->GetIndex(1);
eea478d3 5525 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5526 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5527 //
b9671574 5528 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
eea478d3 5529 //
5530 // Refit Kink under if too small angle
5531 //
77f88633 5532 if (kinkl->GetAngle(2)<0.05){
5533 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5534 Int_t row0 = kinkl->GetTPCRow0();
5535 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
eea478d3 5536 //
5537 //
5538 Int_t last = row0-drow;
5539 if (last<40) last=40;
b9671574 5540 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
eea478d3 5541 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
5542 //
5543 //
5544 Int_t first = row0+drow;
5545 if (first>130) first=130;
b9671574 5546 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
eea478d3 5547 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
5548 //
ddfbc51a 5549 if (seed0 && seed1){
77f88633 5550 kinkl->SetStatus(1,8);
5551 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
5552 row0 = GetRowNumber(kinkl->GetR());
b9671574 5553 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
ddfbc51a 5554 mothers[i] = *seed0;
5555 daughters[i] = *seed1;
eea478d3 5556 }
ddfbc51a 5557 else{
5558 delete kinks->RemoveAt(i);
5559 if (seed0) MarkSeedFree( seed0 );
5560 if (seed1) MarkSeedFree( seed1 );
eea478d3 5561 continue;
5562 }
77f88633 5563 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
ddfbc51a 5564 delete kinks->RemoveAt(i);
5565 if (seed0) MarkSeedFree( seed0 );
5566 if (seed1) MarkSeedFree( seed1 );
eea478d3 5567 continue;
5568 }
ddfbc51a 5569 //
5570 MarkSeedFree( seed0 );
5571 MarkSeedFree( seed1 );
eea478d3 5572 }
5573 //
77f88633 5574 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
51ad6848 5575 }
5576 TMath::Sort(nkinks,quality,indexes,kFALSE);
eea478d3 5577 //
5578 //remove double find kinks
5579 //
5580 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
ddfbc51a 5581 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
eea478d3 5582 if (!kink0) continue;
5583 //
6a6ba9a2 5584 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
ddfbc51a 5585 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
5586 if (!kink0) continue;
5587 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
eea478d3 5588 if (!kink1) continue;
5589 // if not close kink continue
5590 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
5591 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
5592 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
5593 //
ddfbc51a 5594 AliTPCseed &mother0 = mothers[indexes[ikink0]];
5595 AliTPCseed &daughter0 = daughters[indexes[ikink0]];
5596 AliTPCseed &mother1 = mothers[indexes[ikink1]];
5597 AliTPCseed &daughter1 = daughters[indexes[ikink1]];
eea478d3 5598 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
5599 //
5600 Int_t same = 0;
5601 Int_t both = 0;
5602 Int_t samem = 0;
5603 Int_t bothm = 0;
5604 Int_t samed = 0;
5605 Int_t bothd = 0;
5606 //
5607 for (Int_t i=0;i<row0;i++){
ddfbc51a 5608 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
eea478d3 5609 both++;
5610 bothm++;
ddfbc51a 5611 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
eea478d3 5612 same++;
5613 samem++;
5614 }
5615 }
5616 }
5617
5618 for (Int_t i=row0;i<158;i++){
f06a1ff6 5619 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
ddfbc51a 5620 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
eea478d3 5621 both++;
5622 bothd++;
ddfbc51a 5623 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
eea478d3 5624 same++;
5625 samed++;
5626 }
5627 }
5628 }
5629 Float_t ratio = Float_t(same+1)/Float_t(both+1);
5630 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
5631 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
5632 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
ddfbc51a 5633 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
5634 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
eea478d3 5635 if (sum1>sum0){
5636 shared[kink0->GetIndex(0)]= kTRUE;
5637 shared[kink0->GetIndex(1)]= kTRUE;
ddfbc51a 5638 delete kinks->RemoveAt(indexes[ikink0]);
b3659bad 5639 break;
eea478d3 5640 }
5641 else{
5642 shared[kink1->GetIndex(0)]= kTRUE;
5643 shared[kink1->GetIndex(1)]= kTRUE;
ddfbc51a 5644 delete kinks->RemoveAt(indexes[ikink1]);
eea478d3 5645 }
5646 }
5647 }
5648 }
5649
5650
51ad6848 5651 for (Int_t i=0;i<nkinks;i++){
ddfbc51a 5652 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
77f88633 5653 if (!kinkl) continue;
5654 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5655 Int_t index0 = kinkl->GetIndex(0);
5656 Int_t index1 = kinkl->GetIndex(1);
5657 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
5658 kinkl->SetMultiple(usage[index0],0);
5659 kinkl->SetMultiple(usage[index1],1);
5660 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
5661 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
5662 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
5663 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
51ad6848 5664
51ad6848 5665 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5666 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
eea478d3 5667 if (!ktrack0 || !ktrack1) continue;
77f88633 5668 Int_t index = esd->AddKink(kinkl);
eea478d3 5669 //
5670 //
b9671574 5671 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
ddfbc51a 5672 if (mothers[indexes[i]].GetNumberOfClusters()>20 && daughters[indexes[i]].GetNumberOfClusters()>20 && (mothers[indexes[i]].GetNumberOfClusters()+daughters[indexes[i]].GetNumberOfClusters())>100){
5673 *ktrack0 = mothers[indexes[i]];
5674 *ktrack1 = daughters[indexes[i]];
eea478d3 5675 }
5676 }
5677 //
b9671574 5678 ktrack0->SetKinkIndex(usage[index0],-(index+1));
5679 ktrack1->SetKinkIndex(usage[index1], (index+1));
51ad6848 5680 usage[index0]++;
5681 usage[index1]++;
5682 }
eea478d3 5683 //
5684 // Remove tracks corresponding to shared kink's
5685 //
5686 for (Int_t i=0;i<nentries;i++){
5687 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5688 if (!track0) continue;
b9671574 5689 if (track0->GetKinkIndex(0)!=0) continue;
ddfbc51a 5690 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
eea478d3 5691 }
ddfbc51a 5692
eea478d3 5693 //
5694 //
5695 RemoveUsed2(array,0.5,0.4,30);
5696 UnsignClusters();
81e97e0d 5697 for (Int_t i=0;i<nentries;i++){
5698 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5699 if (!track0) continue;
5700 track0->CookdEdx(0.02,0.6);
5701 track0->CookPID();
5702 }
eea478d3 5703 //
5704 for (Int_t i=0;i<nentries;i++){
5705 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5706 if (!track0) continue;
8467b758 5707 if (track0->Pt()<1.4) continue;
eea478d3 5708 //remove double high momenta tracks - overlapped with kink candidates
77f88633 5709 Int_t ishared=0;
eea478d3 5710 Int_t all =0;
b9671574 5711 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
5712 if (track0->GetClusterPointer(icl)!=0){
eea478d3 5713 all++;
77f88633 5714 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
eea478d3 5715 }
5716 }
77f88633 5717 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
ddfbc51a 5718 MarkSeedFree( array->RemoveAt(i) );
f99dc368 5719 continue;
eea478d3 5720 }
5721 //
b9671574 5722 if (track0->GetKinkIndex(0)!=0) continue;
eea478d3 5723 if (track0->GetNumberOfClusters()<80) continue;
4a12af72 5724
ddfbc51a 5725 AliTPCseed *pmother = new AliTPCseed();
5726 AliTPCseed *pdaughter = new AliTPCseed();
5727 AliKink *pkink = new AliKink;
5728
4a12af72 5729 AliTPCseed & mother = *pmother;
5730 AliTPCseed & daughter = *pdaughter;
77f88633 5731 AliKink & kinkl = *pkink;
5732 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
b9671574 5733 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
ddfbc51a 5734 delete pmother;
5735 delete pdaughter;
5736 delete pkink;
4a12af72 5737 continue; //too short tracks
5738 }
8467b758 5739 if (mother.Pt()<1.4) {
ddfbc51a 5740 delete pmother;
5741 delete pdaughter;
5742 delete pkink;
4a12af72 5743 continue;
5744 }
77f88633 5745 Int_t row0= kinkl.GetTPCRow0();
5746 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
ddfbc51a 5747 delete pmother;
5748 delete pdaughter;
5749 delete pkink;
eea478d3 5750 continue;
5751 }
5752 //
77f88633 5753 Int_t index = esd->AddKink(&kinkl);
b9671574 5754 mother.SetKinkIndex(0,-(index+1));
5755 daughter.SetKinkIndex(0,index+1);
5756 if (mother.GetNumberOfClusters()>50) {
ddfbc51a 5757 MarkSeedFree( array->RemoveAt(i) );
5758 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
5759 mtc->SetPoolID(fLastSeedID);
f06a1ff6 5760 array->AddAt(mtc,i);
eea478d3 5761 }
5762 else{
ddfbc51a 5763 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
5764 mtc->SetPoolID(fLastSeedID);
f06a1ff6 5765 array->AddLast(mtc);
eea478d3 5766 }
ddfbc51a 5767 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
5768 dtc->SetPoolID(fLastSeedID);
f06a1ff6 5769 array->AddLast(dtc);
eea478d3 5770 for (Int_t icl=0;icl<row0;icl++) {
b9671574 5771 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
eea478d3 5772 }
5773 //
5774 for (Int_t icl=row0;icl<158;icl++) {
b9671574 5775 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
eea478d3 5776 }
5777 //
5778 }
ddfbc51a 5779 delete pmother;
5780 delete pdaughter;
5781 delete pkink;
eea478d3 5782 }
ddfbc51a 5783
5784 delete [] daughters;
5785 delete [] mothers;
eea478d3 5786 //
eea478d3 5787 //
ddfbc51a 5788 delete [] dca;
5789 delete []circular;
5790 delete []shared;
5791 delete []quality;
5792 delete []indexes;
5793 //
5794 delete kink;
5795 delete[]fim;
5796 delete[] zm;
5797 delete[] z0;
5798 delete [] usage;
5799 delete[] alpha;
5800 delete[] nclusters;
5801 delete[] sign;
bfa00fba 5802 delete[] helixes;
ddfbc51a 5803 kinks->Delete();
5804 delete kinks;
5805
7b9ce4fd 5806 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
51ad6848 5807 timer.Print();
5808}
5809
81e97e0d 5810
ddfbc51a 5811/*
829455ad 5812void AliTPCtracker::FindKinks(TObjArray * array, AliESDEvent *esd)
eea478d3 5813{
5814 //
ddfbc51a 5815 // find kinks
eea478d3 5816 //
5817 //
6c94f330 5818
ddfbc51a 5819 TObjArray *kinks= new TObjArray(10000);
5820 // TObjArray *v0s= new TObjArray(10000);
5821 Int_t nentries = array->GetEntriesFast();
5822 AliHelix *helixes = new AliHelix[nentries];
5823 Int_t *sign = new Int_t[nentries];
5824 Int_t *nclusters = new Int_t[nentries];
5825 Float_t *alpha = new Float_t[nentries];
5826 AliKink *kink = new AliKink();
5827 Int_t * usage = new Int_t[nentries];
5828 Float_t *zm = new Float_t[nentries];
5829 Float_t *z0 = new Float_t[nentries];
5830 Float_t *fim = new Float_t[nentries];
5831 Float_t *shared = new Float_t[nentries];
5832 Bool_t *circular = new Bool_t[nentries];
5833 Float_t *dca = new Float_t[nentries];
5834 //const AliESDVertex * primvertex = esd->GetVertex();
eea478d3 5835 //
ddfbc51a 5836 // nentries = array->GetEntriesFast();
eea478d3 5837 //
ddfbc51a 5838
e546b023 5839 //
e546b023 5840 //
ddfbc51a 5841 for (Int_t i=0;i<nentries;i++){
5842 sign[i]=0;
5843 usage[i]=0;
5844 AliTPCseed* track = (AliTPCseed*)array->At(i);
5845 if (!track) continue;
5846 track->SetCircular(0);
5847 shared[i] = kFALSE;
5848 track->UpdatePoints();
5849 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
5850 }
5851 nclusters[i]=track->GetNumberOfClusters();
5852 alpha[i] = track->GetAlpha();
5853 new (&helixes[i]) AliHelix(*track);
5854 Double_t xyz[3];
5855 helixes[i].Evaluate(0,xyz);
5856 sign[i] = (track->GetC()>0) ? -1:1;
5857 Double_t x,y,z;
5858 x=160;
5859 if (track->GetProlongation(x,y,z)){
5860 zm[i] = z;
5861 fim[i] = alpha[i]+TMath::ATan2(y,x);
eea478d3 5862 }
ddfbc51a 5863 else{
5864 zm[i] = track->GetZ();
5865 fim[i] = alpha[i];
5866 }
5867 z0[i]=1000;
5868 circular[i]= kFALSE;
5869 if (track->GetProlongation(0,y,z)) z0[i] = z;
5870 dca[i] = track->GetD(0,0);
eea478d3 5871 }
5872 //
eea478d3 5873 //
ddfbc51a 5874 TStopwatch timer;
5875 timer.Start();
5876 Int_t ncandidates =0;
5877 Int_t nall =0;
5878 Int_t ntracks=0;
5879 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
5880
eea478d3 5881 //
ddfbc51a 5882 // Find circling track
e546b023 5883 //
ddfbc51a 5884 for (Int_t i0=0;i0<nentries;i0++){
5885 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5886 if (!track0) continue;
5887 if (track0->GetNumberOfClusters()<40) continue;
5888 if (TMath::Abs(1./track0->GetC())>200) continue;
5889 for (Int_t i1=i0+1;i1<nentries;i1++){
5890 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5891 if (!track1) continue;
5892 if (track1->GetNumberOfClusters()<40) continue;
5893 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
5894 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
5895 if (TMath::Abs(1./track1->GetC())>200) continue;
5896 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
5897 if (track1->GetTgl()*track0->GetTgl()>0) continue;
5898 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
5899 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
5900 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
5901 //
5902 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
5903 if (mindcar<5) continue;
5904 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
5905 if (mindcaz<5) continue;
5906 if (mindcar+mindcaz<20) continue;
5907 //
5908 //
5909 Float_t xc0 = helixes[i0].GetHelix(6);
5910 Float_t yc0 = helixes[i0].GetHelix(7);
5911 Float_t r0 = helixes[i0].GetHelix(8);
5912 Float_t xc1 = helixes[i1].GetHelix(6);
5913 Float_t yc1 = helixes[i1].GetHelix(7);
5914 Float_t r1 = helixes[i1].GetHelix(8);
5915
5916 Float_t rmean = (r0+r1)*0.5;
5917 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
5918 //if (delta>30) continue;
5919 if (delta>rmean*0.25) continue;
5920 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
5921 //
5922 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5923 if (npoints==0) continue;
5924 helixes[i0].GetClosestPhases(helixes[i1], phase);
5925 //
5926 Double_t xyz0[3];
5927 Double_t xyz1[3];
5928 Double_t hangles[3];
5929 helixes[i0].Evaluate(phase[0][0],xyz0);
5930 helixes[i1].Evaluate(phase[0][1],xyz1);
e546b023 5931
ddfbc51a 5932 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5933 Double_t deltah[2],deltabest;
5934 if (hangles[2]<2.8) continue;
5935 if (npoints>0){
5936 Int_t ibest=0;
5937 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
5938 if (npoints==2){
5939 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
5940 if (deltah[1]<deltah[0]) ibest=1;
5941 }
5942 deltabest = TMath::Sqrt(deltah[ibest]);
5943 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5944 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5945 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5946 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5947 //
5948 if (deltabest>6) continue;
5949 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
5950 Bool_t lsign =kFALSE;
5951 if (hangles[2]>3.06) lsign =kTRUE;
5952 //
5953 if (lsign){
5954 circular[i0] = kTRUE;
5955 circular[i1] = kTRUE;
5956 if (track0->OneOverPt()<track1->OneOverPt()){
5957 track0->SetCircular(track0->GetCircular()+1);
5958 track1->SetCircular(track1->GetCircular()+2);
5959 }
5960 else{
5961 track1->SetCircular(track1->GetCircular()+1);
5962 track0->SetCircular(track0->GetCircular()+2);
5963 }
5964 }
5965 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
5966 //debug stream
5967 Int_t lab0=track0->GetLabel();
5968 Int_t lab1=track1->GetLabel();
5969 TTreeSRedirector &cstream = *fDebugStreamer;
5970 cstream<<"Curling"<<
5971 "lab0="<<lab0<<
5972 "lab1="<<lab1<<
5973 "Tr0.="<<track0<<
5974 "Tr1.="<<track1<<
5975 "dca0="<<dca[i0]<<
5976 "dca1="<<dca[i1]<<
5977 "mindcar="<<mindcar<<
5978 "mindcaz="<<mindcaz<<
5979 "delta="<<delta<<
5980 "rmean="<<rmean<<
5981 "npoints="<<npoints<<
5982 "hangles0="<<hangles[0]<<
5983 "hangles2="<<hangles[2]<<
5984 "xyz0="<<xyz0[2]<<
5985 "xyzz1="<<xyz1[2]<<
5986 "z0="<<z0[i0]<<
5987 "z1="<<z0[i1]<<
5988 "radius="<<radiusbest<<
5989 "deltabest="<<deltabest<<
5990 "phase0="<<phase[ibest][0]<<
5991 "phase1="<<phase[ibest][1]<<
5992 "\n";
5993 }
5994 }
5995 }
5996 }
51ad6848 5997 //
ddfbc51a 5998 // Finf kinks loop
5999 //
f06a1ff6 6000 //
ddfbc51a 6001 for (Int_t i =0;i<nentries;i++){
6002 if (sign[i]==0) continue;
6003 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6004 if (track0==0) {
6005 AliInfo("seed==0");
6006 continue;
6007 }
6008 ntracks++;
6009 //
6010 Double_t cradius0 = 40*40;
6011 Double_t cradius1 = 270*270;
6012 Double_t cdist1=8.;
6013 Double_t cdist2=8.;
6014 Double_t cdist3=0.55;
6015 for (Int_t j =i+1;j<nentries;j++){
6016 nall++;
6017 if (sign[j]*sign[i]<1) continue;
6018 if ( (nclusters[i]+nclusters[j])>200) continue;
6019 if ( (nclusters[i]+nclusters[j])<80) continue;
6020 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
6021 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
6022 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
6023 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
6024 if (npoints<1) continue;
6025 // cuts on radius
6026 if (npoints==1){
6027 if (radius[0]<cradius0||radius[0]>cradius1) continue;
6028 }
6029 else{
6030 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
6031 }
6032 //
6033 Double_t delta1=10000,delta2=10000;
6034 // cuts on the intersection radius
6035 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
6036 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
6037 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
6038 if (npoints==2){
6039 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
6040 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
6041 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
6042 }
6043 //
6044 Double_t distance1 = TMath::Min(delta1,delta2);
6045 if (distance1>cdist1) continue; // cut on DCA linear approximation
6046 //
6047 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
6048 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
6049 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
6050 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
6051 //
6052 if (npoints==2){
6053 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
6054 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
6055 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
6056 }
6057 distance1 = TMath::Min(delta1,delta2);
6058 Float_t rkink =0;
6059 if (delta1<delta2){
6060 rkink = TMath::Sqrt(radius[0]);
6061 }
6062 else{
6063 rkink = TMath::Sqrt(radius[1]);
6064 }
6065 if (distance1>cdist2) continue;
6066 //
6067 //
6068 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
6069 //
6070 //
6071 Int_t row0 = GetRowNumber(rkink);
6072 if (row0<10) continue;
6073 if (row0>150) continue;
6074 //
6075 //
6076 Float_t dens00=-1,dens01=-1;
6077 Float_t dens10=-1,dens11=-1;
6078 //
6079 Int_t found,foundable,ishared;
6080 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
6081 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
6082 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
6083 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
6084 //
6085 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
6086 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
6087 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
6088 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
6089 //
6090 if (dens00<dens10 && dens01<dens11) continue;
6091 if (dens00>dens10 && dens01>dens11) continue;
6092 if (TMath::Max(dens00,dens10)<0.1) continue;
6093 if (TMath::Max(dens01,dens11)<0.3) continue;
6094 //
6095 if (TMath::Min(dens00,dens10)>0.6) continue;
6096 if (TMath::Min(dens01,dens11)>0.6) continue;
6097
6098 //
6099 AliTPCseed * ktrack0, *ktrack1;
6100 if (dens00>dens10){
6101 ktrack0 = track0;
6102 ktrack1 = track1;
6103 }
6104 else{
6105 ktrack0 = track1;
6106 ktrack1 = track0;
6107 }
6108 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
6109 AliExternalTrackParam paramm(*ktrack0);
6110 AliExternalTrackParam paramd(*ktrack1);
6111 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
6112 //
6113 //
6114 kink->SetMother(paramm);
6115 kink->SetDaughter(paramd);
6116 kink->Update();
6117
2942f542 6118 Float_t x[3] = { static_cast<Float_t>(kink->GetPosition()[0]),static_cast<Float_t>(kink->GetPosition()[1]),static_cast<Float_t>(kink->GetPosition()[2])};
ddfbc51a 6119 Int_t index[4];
6120 fkParam->Transform0to1(x,index);
6121 fkParam->Transform1to2(x,index);
6122 row0 = GetRowNumber(x[0]);
6123
6124 if (kink->GetR()<100) continue;
6125 if (kink->GetR()>240) continue;
6126 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
6127 if (kink->GetDistance()>cdist3) continue;
6128 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
6129 if (dird<0) continue;
6130
6131 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
6132 if (dirm<0) continue;
6133 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
6134 if (mpt<0.2) continue;
6135
6136 if (mpt<1){
6137 //for high momenta momentum not defined well in first iteration
6138 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
6139 if (qt>0.35) continue;
6140 }
6141
6142 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
6143 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
6144 if (dens00>dens10){
6145 kink->SetTPCDensity(dens00,0,0);
6146 kink->SetTPCDensity(dens01,0,1);
6147 kink->SetTPCDensity(dens10,1,0);
6148 kink->SetTPCDensity(dens11,1,1);
6149 kink->SetIndex(i,0);
6150 kink->SetIndex(j,1);
6151 }
6152 else{
6153 kink->SetTPCDensity(dens10,0,0);
6154 kink->SetTPCDensity(dens11,0,1);
6155 kink->SetTPCDensity(dens00,1,0);
6156 kink->SetTPCDensity(dens01,1,1);
6157 kink->SetIndex(j,0);
6158 kink->SetIndex(i,1);
6159 }
6160
6161 if (mpt<1||kink->GetAngle(2)>0.1){
6162 // angle and densities not defined yet
6163 if (kink->GetTPCDensityFactor()<0.8) continue;
6164 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
6165 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
6166 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
6167 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
6168
6169 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
6170 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
6171 criticalangle= 3*TMath::Sqrt(criticalangle);
6172 if (criticalangle>0.02) criticalangle=0.02;
6173 if (kink->GetAngle(2)<criticalangle) continue;
6174 }
6175 //
6176 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
6177 Float_t shapesum =0;
6178 Float_t sum = 0;
6179 for ( Int_t row = row0-drow; row<row0+drow;row++){
6180 if (row<0) continue;
6181 if (row>155) continue;
6182 if (ktrack0->GetClusterPointer(row)){
6183 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
6184 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
6185 sum++;
6186 }
6187 if (ktrack1->GetClusterPointer(row)){
6188 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
6189 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
6190 sum++;
6191 }
6192 }
6193 if (sum<4){
6194 kink->SetShapeFactor(-1.);
6195 }
6196 else{
6197 kink->SetShapeFactor(shapesum/sum);
6198 }
6199 // esd->AddKink(kink);
6200 //
6201 // kink->SetMother(paramm);
6202 //kink->SetDaughter(paramd);
6203
6204 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
6205 chi2P2*=chi2P2;
6206 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
6207 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
6208 chi2P3*=chi2P3;
6209 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
6210 //
6211 if (AliTPCReconstructor::StreamLevel()>1) {
6212 (*fDebugStreamer)<<"kinkLpt"<<
6213 "chi2P2="<<chi2P2<<
6214 "chi2P3="<<chi2P3<<
6215 "p0.="<<&paramm<<
6216 "p1.="<<&paramd<<
6217 "k.="<<kink<<
6218 "\n";
6219 }
6220 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
6221 continue;
6222 }
6223 //
6224 kinks->AddLast(kink);
6225 kink = new AliKink;
6226 ncandidates++;
6227 }
6228 }
6229 //
6230 // sort the kinks according quality - and refit them towards vertex
6231 //
6232 Int_t nkinks = kinks->GetEntriesFast();
6233 Float_t *quality = new Float_t[nkinks];
6234 Int_t *indexes = new Int_t[nkinks];
6235 AliTPCseed **mothers = new AliTPCseed*[nkinks]; memset(mothers, 0, nkinks*sizeof(AliTPCseed*));
6236 AliTPCseed **daughters = new AliTPCseed*[nkinks]; memset(daughters, 0, nkinks*sizeof(AliTPCseed*));
6237 //
6238 //
6239 for (Int_t i=0;i<nkinks;i++){
6240 quality[i] =100000;
6241 AliKink *kinkl = (AliKink*)kinks->At(i);
6242 //
6243 // refit kinks towards vertex
6244 //
6245 Int_t index0 = kinkl->GetIndex(0);
6246 Int_t index1 = kinkl->GetIndex(1);
6247 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6248 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6249 //
6250 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
6251 //
6252 // Refit Kink under if too small angle
6253 //
6254 if (kinkl->GetAngle(2)<0.05){
6255 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6256 Int_t row0 = kinkl->GetTPCRow0();
6257 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
6258 //
6259 //
6260 Int_t last = row0-drow;
6261 if (last<40) last=40;
6262 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
6263 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
6264 //
6265 //
6266 Int_t first = row0+drow;
6267 if (first>130) first=130;
6268 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
6269 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
6270 //
6271 if (seed0 && seed1){
6272 kinkl->SetStatus(1,8);
6273 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
6274 row0 = GetRowNumber(kinkl->GetR());
6275 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
6276 mothers[i] = new ( NextFreeSeed() ) AliTPCseed(*seed0);
6277 mothers[i]->SetPoolID(fLastSeedID);
6278 daughters[i] = new (NextFreeSeed() ) AliTPCseed(*seed1);
6279 daughters[i]->SetPoolID(fLastSeedID);
6280 }
6281 else{
6282 delete kinks->RemoveAt(i);
6283 if (seed0) MarkSeedFree( seed0 );
6284 if (seed1) MarkSeedFree( seed1 );
6285 continue;
6286 }
6287 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
6288 delete kinks->RemoveAt(i);
6289 if (seed0) MarkSeedFree( seed0 );
6290 if (seed1) MarkSeedFree( seed1 );
6291 continue;
6292 }
6293 //
6294 MarkSeedFree( seed0 );
6295 MarkSeedFree( seed1 );
6296 }
6297 //
6298 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
6299 }
6300 TMath::Sort(nkinks,quality,indexes,kFALSE);
6301 //
6302 //remove double find kinks
6303 //
6304 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
6305 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6306 if (!kink0) continue;
6307 //
6308 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
6309 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6310 if (!kink0) continue;
6311 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
6312 if (!kink1) continue;
6313 // if not close kink continue
6314 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
6315 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
6316 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
6317 //
6318 AliTPCseed &mother0 = *mothers[indexes[ikink0]];
6319 AliTPCseed &daughter0 = *daughters[indexes[ikink0]];
6320 AliTPCseed &mother1 = *mothers[indexes[ikink1]];
6321 AliTPCseed &daughter1 = *daughters[indexes[ikink1]];
6322 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
6323 //
6324 Int_t same = 0;
6325 Int_t both = 0;
6326 Int_t samem = 0;
6327 Int_t bothm = 0;
6328 Int_t samed = 0;
6329 Int_t bothd = 0;
6330 //
6331 for (Int_t i=0;i<row0;i++){
6332 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
6333 both++;
6334 bothm++;
6335 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6336 same++;
6337 samem++;
6338 }
6339 }
6340 }
6341
6342 for (Int_t i=row0;i<158;i++){
6343 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
6344 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
6345 both++;
6346 bothd++;
6347 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6348 same++;
6349 samed++;
6350 }
6351 }
6352 }
6353 Float_t ratio = Float_t(same+1)/Float_t(both+1);
6354 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
6355 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
6356 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
6357 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
6358 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
6359 if (sum1>sum0){
6360 shared[kink0->GetIndex(0)]= kTRUE;
6361 shared[kink0->GetIndex(1)]= kTRUE;
6362 delete kinks->RemoveAt(indexes[ikink0]);
6363 break;
6364 }
6365 else{
6366 shared[kink1->GetIndex(0)]= kTRUE;
6367 shared[kink1->GetIndex(1)]= kTRUE;
6368 delete kinks->RemoveAt(indexes[ikink1]);
6369 }
6370 }
6371 }
6372 }
6373
6374
6375 for (Int_t i=0;i<nkinks;i++){
6376 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
6377 if (!kinkl) continue;
6378 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6379 Int_t index0 = kinkl->GetIndex(0);
6380 Int_t index1 = kinkl->GetIndex(1);
6381 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
6382 kinkl->SetMultiple(usage[index0],0);
6383 kinkl->SetMultiple(usage[index1],1);
6384 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
6385 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
6386 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
6387 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
6388
6389 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6390 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6391 if (!ktrack0 || !ktrack1) continue;
6392 Int_t index = esd->AddKink(kinkl);
6393 //
6394 //
6395 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
6396 if (mothers[indexes[i]]->GetNumberOfClusters()>20 && daughters[indexes[i]]->GetNumberOfClusters()>20 &&
6397 (mothers[indexes[i]]->GetNumberOfClusters()+daughters[indexes[i]]->GetNumberOfClusters())>100){
6398 *ktrack0 = *mothers[indexes[i]];
6399 *ktrack1 = *daughters[indexes[i]];
6400 }
6401 }
6402 //
6403 ktrack0->SetKinkIndex(usage[index0],-(index+1));
6404 ktrack1->SetKinkIndex(usage[index1], (index+1));
6405 usage[index0]++;
6406 usage[index1]++;
6407 }
6408 //
6409 // Remove tracks corresponding to shared kink's
6410 //
6411 for (Int_t i=0;i<nentries;i++){
6412 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6413 if (!track0) continue;
6414 if (track0->GetKinkIndex(0)!=0) continue;
6415 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
6416 }
6417
6418 //
6419 //
6420 RemoveUsed2(array,0.5,0.4,30);
6421 UnsignClusters();
6422 for (Int_t i=0;i<nentries;i++){
6423 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6424 if (!track0) continue;
6425 track0->CookdEdx(0.02,0.6);
6426 track0->CookPID();
6427 }
6428 //
6429 for (Int_t i=0;i<nentries;i++){
6430 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6431 if (!track0) continue;
6432 if (track0->Pt()<1.4) continue;
6433 //remove double high momenta tracks - overlapped with kink candidates
6434 Int_t ishared=0;
6435 Int_t all =0;
6436 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
6437 if (track0->GetClusterPointer(icl)!=0){
6438 all++;
6439 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
6440 }
6441 }
6442 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
6443 MarkSeedFree( array->RemoveAt(i) );
6444 continue;
6445 }
6446 //
6447 if (track0->GetKinkIndex(0)!=0) continue;
6448 if (track0->GetNumberOfClusters()<80) continue;
6449
6450 AliTPCseed *pmother = new( NextFreeSeed() ) AliTPCseed();
6451 pmother->SetPoolID(fLastSeedID);
6452 AliTPCseed *pdaughter = new( NextFreeSeed() ) AliTPCseed();
6453 pdaughter->SetPoolID(fLastSeedID);
6454 AliKink *pkink = new AliKink;
6455
6456 AliTPCseed & mother = *pmother;
6457 AliTPCseed & daughter = *pdaughter;
6458 AliKink & kinkl = *pkink;
6459 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
6460 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
6461 MarkSeedFree( pmother );
6462 MarkSeedFree( pdaughter );
6463 delete pkink;
6464 continue; //too short tracks
6465 }
6466 if (mother.Pt()<1.4) {
6467 MarkSeedFree( pmother );
6468 MarkSeedFree( pdaughter );
6469 delete pkink;
6470 continue;
6471 }
6472 Int_t row0= kinkl.GetTPCRow0();
6473 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
6474 MarkSeedFree( pmother );
6475 MarkSeedFree( pdaughter );
6476 delete pkink;
6477 continue;
6478 }
6479 //
6480 Int_t index = esd->AddKink(&kinkl);
6481 mother.SetKinkIndex(0,-(index+1));
6482 daughter.SetKinkIndex(0,index+1);
6483 if (mother.GetNumberOfClusters()>50) {
6484 MarkSeedFree( array->RemoveAt(i) );
6485 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6486 mtc->SetPoolID(fLastSeedID);
6487 array->AddAt(mtc,i);
6488 }
6489 else{
6490 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6491 mtc->SetPoolID(fLastSeedID);
6492 array->AddLast(mtc);
6493 }
6494 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
6495 dtc->SetPoolID(fLastSeedID);
6496 array->AddLast(dtc);
6497 for (Int_t icl=0;icl<row0;icl++) {
6498 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
6499 }
6500 //
6501 for (Int_t icl=row0;icl<158;icl++) {
6502 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
6503 }
6504 //
6505 }
6506 MarkSeedFree( pmother );
6507 MarkSeedFree( pdaughter );
6508 delete pkink;
6509 }
6510
6511 delete [] daughters;
6512 delete [] mothers;
6513 //
6514 //
6515 delete [] dca;
6516 delete []circular;
6517 delete []shared;
6518 delete []quality;
6519 delete []indexes;
6520 //
6521 delete kink;
6522 delete[]fim;
6523 delete[] zm;
6524 delete[] z0;
6525 delete [] usage;
6526 delete[] alpha;
6527 delete[] nclusters;
6528 delete[] sign;
6529 delete[] helixes;
6530 kinks->Delete();
6531 delete kinks;
6532
6533 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
6534 timer.Print();
6535}
6536*/
6537
829455ad 6538Int_t AliTPCtracker::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
ddfbc51a 6539{
6540 //
6541 // refit kink towards to the vertex
6542 //
6543 //
6544 AliKink &kink=(AliKink &)knk;
6545
6546 Int_t row0 = GetRowNumber(kink.GetR());
6547 FollowProlongation(mother,0);
6548 mother.Reset(kFALSE);
6549 //
6550 FollowProlongation(daughter,row0);
6551 daughter.Reset(kFALSE);
6552 FollowBackProlongation(daughter,158);
6553 daughter.Reset(kFALSE);
6554 Int_t first = TMath::Max(row0-20,30);
6555 Int_t last = TMath::Min(row0+20,140);
6556 //
6557 const Int_t kNdiv =5;
6558 AliTPCseed param0[kNdiv]; // parameters along the track
6559 AliTPCseed param1[kNdiv]; // parameters along the track
6560 AliKink kinks[kNdiv]; // corresponding kink parameters
6561 //
6562 Int_t rows[kNdiv];
6563 for (Int_t irow=0; irow<kNdiv;irow++){
6564 rows[irow] = first +((last-first)*irow)/(kNdiv-1);
6565 }
6566 // store parameters along the track
6567 //
6568 for (Int_t irow=0;irow<kNdiv;irow++){
6569 FollowBackProlongation(mother, rows[irow]);
6570 FollowProlongation(daughter,rows[kNdiv-1-irow]);
6571 param0[irow] = mother;
6572 param1[kNdiv-1-irow] = daughter;
6573 }
6574 //
6575 // define kinks
6576 for (Int_t irow=0; irow<kNdiv-1;irow++){
6577 if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
6578 kinks[irow].SetMother(param0[irow]);
6579 kinks[irow].SetDaughter(param1[irow]);
6580 kinks[irow].Update();
6581 }
6582 //
6583 // choose kink with best "quality"
6584 Int_t index =-1;
6585 Double_t mindist = 10000;
6586 for (Int_t irow=0;irow<kNdiv;irow++){
6587 if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
6588 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
6589 if (TMath::Abs(kinks[irow].GetR())<100.) continue;
6590 //
6591 Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
6592 normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
6593 if (normdist < mindist){
6594 mindist = normdist;
6595 index = irow;
6596 }
6597 }
6598 //
6599 if (index==-1) return 0;
6600 //
6601 //
6602 param0[index].Reset(kTRUE);
6603 FollowProlongation(param0[index],0);
6604 //
6605 mother = param0[index];
6606 daughter = param1[index]; // daughter in vertex
6607 //
6608 kink.SetMother(mother);
6609 kink.SetDaughter(daughter);
6610 kink.Update();
6611 kink.SetTPCRow0(GetRowNumber(kink.GetR()));
6612 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
6613 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
6614 kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
6615 kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
6616 mother.SetLabel(kink.GetLabel(0));
6617 daughter.SetLabel(kink.GetLabel(1));
6618
6619 return 1;
6620}
6621
6622
829455ad 6623void AliTPCtracker::UpdateKinkQualityM(AliTPCseed * seed){
ddfbc51a 6624 //
6625 // update Kink quality information for mother after back propagation
6626 //
6627 if (seed->GetKinkIndex(0)>=0) return;
6628 for (Int_t ikink=0;ikink<3;ikink++){
6629 Int_t index = seed->GetKinkIndex(ikink);
6630 if (index>=0) break;
51ad6848 6631 index = TMath::Abs(index)-1;
6632 AliESDkink * kink = fEvent->GetKink(index);
f941f7fa 6633 kink->SetTPCDensity(-1,0,0);
6634 kink->SetTPCDensity(1,0,1);
51ad6848 6635 //
eea478d3 6636 Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 6637 if (row0<15) row0=15;
6638 //
eea478d3 6639 Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 6640 if (row1>145) row1=145;
6641 //
6642 Int_t found,foundable,shared;
6643 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
f941f7fa 6644 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,0);
51ad6848 6645 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
f941f7fa 6646 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,1);
51ad6848 6647 }
6648
6649}
6650
829455ad 6651void AliTPCtracker::UpdateKinkQualityD(AliTPCseed * seed){
91162307 6652 //
eea478d3 6653 // update Kink quality information for daughter after refit
91162307 6654 //
eea478d3 6655 if (seed->GetKinkIndex(0)<=0) return;
6656 for (Int_t ikink=0;ikink<3;ikink++){
6657 Int_t index = seed->GetKinkIndex(ikink);
6658 if (index<=0) break;
6659 index = TMath::Abs(index)-1;
6660 AliESDkink * kink = fEvent->GetKink(index);
f941f7fa 6661 kink->SetTPCDensity(-1,1,0);
6662 kink->SetTPCDensity(-1,1,1);
91162307 6663 //
eea478d3 6664 Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6665 if (row0<15) row0=15;
6666 //
6667 Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6668 if (row1>145) row1=145;
6669 //
6670 Int_t found,foundable,shared;
6671 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
f941f7fa 6672 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,0);
eea478d3 6673 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
f941f7fa 6674 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,1);
91162307 6675 }
eea478d3 6676
6677}
6678
6679
829455ad 6680Int_t AliTPCtracker::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
eea478d3 6681{
91162307 6682 //
eea478d3 6683 // check kink point for given track
6684 // if return value=0 kink point not found
6685 // otherwise seed0 correspond to mother particle
6686 // seed1 correspond to daughter particle
6687 // kink parameter of kink point
6c94f330 6688 AliKink &kink=(AliKink &)knk;
91162307 6689
b9671574 6690 Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
6691 Int_t first = seed->GetFirstPoint();
6692 Int_t last = seed->GetLastPoint();
eea478d3 6693 if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
91162307 6694
eea478d3 6695
6696 AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
6697 if (!seed1) return 0;
b9671574 6698 FollowProlongation(*seed1,seed->GetLastPoint()-20);
eea478d3 6699 seed1->Reset(kTRUE);
6700 FollowProlongation(*seed1,158);
6701 seed1->Reset(kTRUE);
b9671574 6702 last = seed1->GetLastPoint();
eea478d3 6703 //
ddfbc51a 6704 AliTPCseed *seed0 = new( NextFreeSeed() ) AliTPCseed(*seed);
6705 seed0->SetPoolID(fLastSeedID);
eea478d3 6706 seed0->Reset(kFALSE);
6707 seed0->Reset();
6708 //
6709 AliTPCseed param0[20]; // parameters along the track
6710 AliTPCseed param1[20]; // parameters along the track
6c94f330 6711 AliKink kinks[20]; // corresponding kink parameters
eea478d3 6712 Int_t rows[20];
6713 for (Int_t irow=0; irow<20;irow++){
6714 rows[irow] = first +((last-first)*irow)/19;
6715 }
6716 // store parameters along the track
6717 //
6718 for (Int_t irow=0;irow<20;irow++){
6719 FollowBackProlongation(*seed0, rows[irow]);
6720 FollowProlongation(*seed1,rows[19-irow]);
316c6cd9 6721 param0[irow] = *seed0;
6722 param1[19-irow] = *seed1;
eea478d3 6723 }
6724 //
6725 // define kinks
6726 for (Int_t irow=0; irow<19;irow++){
6727 kinks[irow].SetMother(param0[irow]);
6728 kinks[irow].SetDaughter(param1[irow]);
6729 kinks[irow].Update();
6730 }
6731 //
6732 // choose kink with biggest change of angle
6733 Int_t index =-1;
6734 Double_t maxchange= 0;
6735 for (Int_t irow=1;irow<19;irow++){
6736 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
6737 if (TMath::Abs(kinks[irow].GetR())<110.) continue;
6c94f330 6738 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 6739 if ( quality > maxchange){
6740 maxchange = quality;
6741 index = irow;
6742 //
91162307 6743 }
6744 }
ddfbc51a 6745 MarkSeedFree( seed0 );
6746 MarkSeedFree( seed1 );
eea478d3 6747 if (index<0) return 0;
6748 //
6749 Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
ddfbc51a 6750 seed0 = new( NextFreeSeed() ) AliTPCseed(param0[index]);
6751 seed0->SetPoolID(fLastSeedID);
6752 seed1 = new( NextFreeSeed() ) AliTPCseed(param1[index]);
6753 seed1->SetPoolID(fLastSeedID);
eea478d3 6754 seed0->Reset(kFALSE);
6755 seed1->Reset(kFALSE);
6c94f330 6756 seed0->ResetCovariance(10.);
6757 seed1->ResetCovariance(10.);
eea478d3 6758 FollowProlongation(*seed0,0);
6759 FollowBackProlongation(*seed1,158);
316c6cd9 6760 mother = *seed0; // backup mother at position 0
eea478d3 6761 seed0->Reset(kFALSE);
6762 seed1->Reset(kFALSE);
6c94f330 6763 seed0->ResetCovariance(10.);
6764 seed1->ResetCovariance(10.);
eea478d3 6765 //
6766 first = TMath::Max(row0-20,0);
6767 last = TMath::Min(row0+20,158);
6768 //
6769 for (Int_t irow=0; irow<20;irow++){
6770 rows[irow] = first +((last-first)*irow)/19;
6771 }
6772 // store parameters along the track
6773 //
6774 for (Int_t irow=0;irow<20;irow++){
6775 FollowBackProlongation(*seed0, rows[irow]);
6776 FollowProlongation(*seed1,rows[19-irow]);
316c6cd9 6777 param0[irow] = *seed0;
6778 param1[19-irow] = *seed1;
eea478d3 6779 }
6780 //
6781 // define kinks
6782 for (Int_t irow=0; irow<19;irow++){
6783 kinks[irow].SetMother(param0[irow]);
6784 kinks[irow].SetDaughter(param1[irow]);
6785 // param0[irow].Dump();
6786 //param1[irow].Dump();
6787 kinks[irow].Update();
6788 }
6789 //
6790 // choose kink with biggest change of angle
6791 index =-1;
6792 maxchange= 0;
6793 for (Int_t irow=0;irow<20;irow++){
6794 if (TMath::Abs(kinks[irow].GetR())>250.) continue;
6795 if (TMath::Abs(kinks[irow].GetR())<90.) continue;
6c94f330 6796 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 6797 if ( quality > maxchange){
6798 maxchange = quality;
6799 index = irow;
6800 //
91162307 6801 }
6802 }
6803 //
6804 //
b9671574 6805 if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
ddfbc51a 6806 MarkSeedFree( seed0 );
6807 MarkSeedFree( seed1 );
eea478d3 6808 return 0;
1627d1c4 6809 }
16299eac 6810
eea478d3 6811 // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
1627d1c4 6812
eea478d3 6813 kink.SetMother(param0[index]);
6814 kink.SetDaughter(param1[index]);
6815 kink.Update();
16299eac 6816
6817 Double_t chi2P2 = param0[index].GetParameter()[2]-param1[index].GetParameter()[2];
6818 chi2P2*=chi2P2;
6819 chi2P2/=param0[index].GetCovariance()[5]+param1[index].GetCovariance()[5];
6820 Double_t chi2P3 = param0[index].GetParameter()[3]-param1[index].GetParameter()[3];
6821 chi2P3*=chi2P3;
6822 chi2P3/=param0[index].GetCovariance()[9]+param1[index].GetCovariance()[9];
6823 //
6824 if (AliTPCReconstructor::StreamLevel()>1) {
6825 (*fDebugStreamer)<<"kinkHpt"<<
6826 "chi2P2="<<chi2P2<<
6827 "chi2P3="<<chi2P3<<
6828 "p0.="<<&param0[index]<<
6829 "p1.="<<&param1[index]<<
6830 "k.="<<&kink<<
6831 "\n";
6832 }
6833 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
ddfbc51a 6834 MarkSeedFree( seed0 );
6835 MarkSeedFree( seed1 );
16299eac 6836 return 0;
6837 }
6838
6839
eea478d3 6840 row0 = GetRowNumber(kink.GetR());
6841 kink.SetTPCRow0(row0);
6842 kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
6843 kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
6844 kink.SetIndex(-10,0);
b9671574 6845 kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
6846 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
6847 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
eea478d3 6848 //
6849 //
6850 // new (&mother) AliTPCseed(param0[index]);
316c6cd9 6851 daughter = param1[index];
eea478d3 6852 daughter.SetLabel(kink.GetLabel(1));
6853 param0[index].Reset(kTRUE);
16299eac 6854 FollowProlongation(param0[index],0);
316c6cd9 6855 mother = param0[index];
eea478d3 6856 mother.SetLabel(kink.GetLabel(0));
16299eac 6857 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(1)){
6858 mother=*seed;
6859 }
ddfbc51a 6860 MarkSeedFree( seed0 );
6861 MarkSeedFree( seed1 );
eea478d3 6862 //
6863 return 1;
1627d1c4 6864}
6865
6866
6867
6868
829455ad 6869AliTPCseed* AliTPCtracker::ReSeed(AliTPCseed *t)
91162307 6870{
6871 //
6872 // reseed - refit - track
6873 //
6874 Int_t first = 0;
6875 // Int_t last = fSectors->GetNRows()-1;
6876 //
6877 if (fSectors == fOuterSec){
b9671574 6878 first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
91162307 6879 //last =
6880 }
6881 else
b9671574 6882 first = t->GetFirstPoint();
91162307 6883 //
6884 AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
6885 FollowBackProlongation(*t,fSectors->GetNRows()-1);
6886 t->Reset(kFALSE);
6887 FollowProlongation(*t,first);
6888 return seed;
6889}
6890
6891
6892
6893
6894
6895
6896
1c53abe2 6897//_____________________________________________________________________________
829455ad 6898Int_t AliTPCtracker::ReadSeeds(const TFile *inp) {
1c53abe2 6899 //-----------------------------------------------------------------
6900 // This function reades track seeds.
6901 //-----------------------------------------------------------------
6902 TDirectory *savedir=gDirectory;
6903
6904 TFile *in=(TFile*)inp;
6905 if (!in->IsOpen()) {
829455ad 6906 cerr<<"AliTPCtracker::ReadSeeds(): input file is not open !\n";
1c53abe2 6907 return 1;
6908 }
6909
6910 in->cd();
6911 TTree *seedTree=(TTree*)in->Get("Seeds");
6912 if (!seedTree) {
829455ad 6913 cerr<<"AliTPCtracker::ReadSeeds(): ";
1c53abe2 6914 cerr<<"can't get a tree with track seeds !\n";
6915 return 2;
6916 }
6917 AliTPCtrack *seed=new AliTPCtrack;
6918 seedTree->SetBranchAddress("tracks",&seed);
6919
6920 if (fSeeds==0) fSeeds=new TObjArray(15000);
6921
6922 Int_t n=(Int_t)seedTree->GetEntries();
6923 for (Int_t i=0; i<n; i++) {
6924 seedTree->GetEvent(i);
ddfbc51a 6925 AliTPCseed* sdc = new( NextFreeSeed() ) AliTPCseed(*seed/*,seed->GetAlpha()*/);
6926 sdc->SetPoolID(fLastSeedID);
f06a1ff6 6927 fSeeds->AddLast(sdc);
1c53abe2 6928 }
6929
f06a1ff6 6930 delete seed; // RS: this seed is not from the pool, delete it !!!
1c53abe2 6931 delete seedTree;
6932 savedir->cd();
6933 return 0;
6934}
6935
829455ad 6936Int_t AliTPCtracker::Clusters2TracksHLT (AliESDEvent *const esd, const AliESDEvent *hltEvent)
d26d9159 6937{
6938 //
544c295f 6939 // clusters to tracks
d9b8978b 6940 if (fSeeds) DeleteSeeds();
ddfbc51a 6941 else ResetSeedsPool();
e1dadcd0 6942 fEvent = esd;
72e25240 6943 fEventHLT = hltEvent;
e1dadcd0 6944
6945 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
6946 transform->SetCurrentTimeStamp( esd->GetTimeStamp());
6947 transform->SetCurrentRun(esd->GetRunNumber());
6948
d26d9159 6949 Clusters2Tracks();
72e25240 6950 fEventHLT = 0;
d26d9159 6951 if (!fSeeds) return 1;
6952 FillESD(fSeeds);
f47588e0 6953 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(0,fSeeds);
d26d9159 6954 return 0;
6955 //
6956}
6957
829455ad 6958Int_t AliTPCtracker::Clusters2Tracks(AliESDEvent *const esd)
72e25240 6959{
6960 //
6961 // clusters to tracks
6962 return Clusters2TracksHLT( esd, 0);
6963}
d26d9159 6964
1c53abe2 6965//_____________________________________________________________________________
829455ad 6966Int_t AliTPCtracker::Clusters2Tracks() {
1c53abe2 6967 //-----------------------------------------------------------------
6968 // This is a track finder.
6969 //-----------------------------------------------------------------
91162307 6970 TDirectory *savedir=gDirectory;
1c53abe2 6971 TStopwatch timer;
d26d9159 6972
91162307 6973 fIteration = 0;
6974 fSeeds = Tracking();
1c53abe2 6975
6bdc18d6 6976 if (fDebug>0){
6977 Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
6978 }
91162307 6979 //activate again some tracks
6980 for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
6981 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6982 if (!pt) continue;
6983 Int_t nc=t.GetNumberOfClusters();
6984 if (nc<20) {
ddfbc51a 6985 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 6986 continue;
eea478d3 6987 }
f5cbf2ef 6988 CookLabel(pt,0.1);
b9671574 6989 if (pt->GetRemoval()==10) {
91162307 6990 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
bad6eb00 6991 pt->Desactivate(10); // make track again active // MvL: should be 0 ?
91162307 6992 else{
6993 pt->Desactivate(20);
ddfbc51a 6994 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 6995 }
6996 }
6997 }
51ad6848 6998 //
6999 RemoveUsed2(fSeeds,0.85,0.85,0);
a3232aae 7000 if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
6d493ea0 7001 //FindCurling(fSeeds, fEvent,0);
16299eac 7002 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,-1); // find multi found tracks
81e97e0d 7003 RemoveUsed2(fSeeds,0.5,0.4,20);
1af5da7e 7004 FindSplitted(fSeeds, fEvent,0); // find multi found tracks
16299eac 7005 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
6d493ea0 7006
81e97e0d 7007 // //
7008// // refit short tracks
7009// //
7010 Int_t nseed=fSeeds->GetEntriesFast();
1c53abe2 7011 //
91162307 7012 Int_t found = 0;
7013 for (Int_t i=0; i<nseed; i++) {
7014 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7015 if (!pt) continue;
7016 Int_t nc=t.GetNumberOfClusters();
7017 if (nc<15) {
ddfbc51a 7018 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7019 continue;
7020 }
7021 CookLabel(pt,0.1); //For comparison only
7022 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 7023 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
d9b8978b 7024 found++;
7025 if (fDebug>0) cerr<<found<<'\r';
b9671574 7026 pt->SetLab2(i);
91162307 7027 }
7028 else
ddfbc51a 7029 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7030 }
7031
7032
7033 //RemoveOverlap(fSeeds,0.99,7,kTRUE);
7034 SignShared(fSeeds);
7035 //RemoveUsed(fSeeds,0.9,0.9,6);
1c53abe2 7036 //
91162307 7037 nseed=fSeeds->GetEntriesFast();
7038 found = 0;
7039 for (Int_t i=0; i<nseed; i++) {
7040 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7041 if (!pt) continue;
7042 Int_t nc=t.GetNumberOfClusters();
7043 if (nc<15) {
ddfbc51a 7044 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7045 continue;
7046 }
7047 t.SetUniqueID(i);
7048 t.CookdEdx(0.02,0.6);
7049 // CheckKinkPoint(&t,0.05);
7050 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 7051 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6bdc18d6 7052 found++;
7053 if (fDebug>0){
7054 cerr<<found<<'\r';
7055 }
b9671574 7056 pt->SetLab2(i);
91162307 7057 }
7058 else
ddfbc51a 7059 MarkSeedFree( fSeeds->RemoveAt(i) );
d26d9159 7060 //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
7061 //if (seed1){
7062 // FollowProlongation(*seed1,0);
7063 // Int_t n = seed1->GetNumberOfClusters();
7064 // printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
7065 // printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
7066 //
7067 //}
7068 //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
7069
91162307 7070 }
7071
7072 SortTracks(fSeeds, 1);
1c53abe2 7073
982aff31 7074 /*
91162307 7075 fIteration = 1;
982aff31 7076 PrepareForBackProlongation(fSeeds,5.);
91162307 7077 PropagateBack(fSeeds);
7078 printf("Time for back propagation: \t");timer.Print();timer.Start();
7079
7080 fIteration = 2;
1c53abe2 7081
982aff31 7082 PrepareForProlongation(fSeeds,5.);
f124f8bf 7083 PropagateForard2(fSeeds);
d26d9159 7084
91162307 7085 printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
7086 // RemoveUsed(fSeeds,0.7,0.7,6);
7087 //RemoveOverlap(fSeeds,0.9,7,kTRUE);
d26d9159 7088
1c53abe2 7089 nseed=fSeeds->GetEntriesFast();
91162307 7090 found = 0;
7091 for (Int_t i=0; i<nseed; i++) {
1c53abe2 7092 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7093 if (!pt) continue;
7094 Int_t nc=t.GetNumberOfClusters();
91162307 7095 if (nc<15) {
ddfbc51a 7096 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7097 continue;
7098 }
1c53abe2 7099 t.CookdEdx(0.02,0.6);
91162307 7100 // CookLabel(pt,0.1); //For comparison only
7101 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
7102 if ((pt->IsActive() || (pt->fRemoval==10) )){
7103 cerr<<found++<<'\r';
7104 }
7105 else
ddfbc51a 7106 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7107 pt->fLab2 = i;
1c53abe2 7108 }
91162307 7109 */
7110
c9427e08 7111 // fNTracks = found;
6bdc18d6 7112 if (fDebug>0){
7113 Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
7114 }
91162307 7115 //
6bdc18d6 7116 // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
7117 Info("Clusters2Tracks","Number of found tracks %d",found);
91162307 7118 savedir->cd();
91162307 7119 // UnloadClusters();
d26d9159 7120 //
1c53abe2 7121 return 0;
7122}
7123
829455ad 7124void AliTPCtracker::Tracking(TObjArray * arr)
91162307 7125{
7126 //
7127 // tracking of the seeds
7128 //
7129
7130 fSectors = fOuterSec;
7131 ParallelTracking(arr,150,63);
7132 fSectors = fOuterSec;
7133 ParallelTracking(arr,63,0);
7134}
7135
829455ad 7136TObjArray * AliTPCtracker::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
91162307 7137{
7138 //
7139 //
7140 //tracking routine
f06a1ff6 7141 static TObjArray arrTracks;
7142 TObjArray * arr = &arrTracks;
91162307 7143 //
7144 fSectors = fOuterSec;
7145 TStopwatch timer;
7146 timer.Start();
7147 for (Int_t sec=0;sec<fkNOS;sec++){
7148 if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
7149 if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);
7150 if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
7151 }
7152 if (fDebug>0){
6bdc18d6 7153 Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
91162307 7154 timer.Print();
7155 timer.Start();
7156 }
7157 Tracking(arr);
7158 if (fDebug>0){
7159 timer.Print();
7160 }
7161
7162 return arr;
7163}
7164
829455ad 7165TObjArray * AliTPCtracker::Tracking()
91162307 7166{
544c295f 7167 // tracking
91162307 7168 //
a3232aae 7169 if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
91162307 7170 TStopwatch timer;
7171 timer.Start();
7172 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7173
7174 TObjArray * seeds = new TObjArray;
7175 TObjArray * arr=0;
6d1424d5 7176 Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
7177 Int_t gapPrim = AliTPCReconstructor::GetRecoParam()->GetSeedGapPrim();
7178 Int_t gapSec = AliTPCReconstructor::GetRecoParam()->GetSeedGapSec();
91162307 7179
7180 Int_t gap =20;
7181 Float_t cuts[4];
7182 cuts[0] = 0.002;
7183 cuts[1] = 1.5;
7184 cuts[2] = 3.;
7185 cuts[3] = 3.;
7186 Float_t fnumber = 3.0;
7187 Float_t fdensity = 3.0;
72e25240 7188
7189 // make HLT seeds
fa90aa2b 7190 if (AliTPCReconstructor::GetRecoParam()->GetUseHLTPreSeeding()) {
72e25240 7191 arr = MakeSeedsHLT( fEventHLT );
7192 if( arr ){
7193 SumTracks(seeds,arr);
7194 delete arr;
7195 arr=0;
7196 //cout<<"HLT tracks left after sorting: "<<seeds->GetEntriesFast()<<endl;
7197 //SignClusters(seeds,fnumber,fdensity);
7198 }
7199 }
91162307 7200
7201 //
7202 //find primaries
7203 cuts[0]=0.0066;
6d1424d5 7204 for (Int_t delta = 0; delta<18; delta+=gapPrim){
91162307 7205 //
7206 cuts[0]=0.0070;
7207 cuts[1] = 1.5;
7208 arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
7209 SumTracks(seeds,arr);
7210 SignClusters(seeds,fnumber,fdensity);
7211 //
7212 for (Int_t i=2;i<6;i+=2){
7213 // seed high pt tracks
7214 cuts[0]=0.0022;
7215 cuts[1]=0.3;
7216 arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
7217 SumTracks(seeds,arr);
7218 SignClusters(seeds,fnumber,fdensity);
7219 }
7220 }
7221 fnumber = 4;
7222 fdensity = 4.;
7223 // RemoveUsed(seeds,0.9,0.9,1);
7224 // UnsignClusters();
7225 // SignClusters(seeds,fnumber,fdensity);
7226
7227 //find primaries
7228 cuts[0]=0.0077;
6d1424d5 7229 for (Int_t delta = 20; delta<120; delta+=gapPrim){
91162307 7230 //
7231 // seed high pt tracks
7232 cuts[0]=0.0060;
7233 cuts[1]=0.3;
7234 cuts[2]=6.;
7235 arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
7236 SumTracks(seeds,arr);
7237 SignClusters(seeds,fnumber,fdensity);
7238
7239 cuts[0]=0.003;
7240 cuts[1]=0.3;
7241 cuts[2]=6.;
7242 arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
7243 SumTracks(seeds,arr);
7244 SignClusters(seeds,fnumber,fdensity);
7245 }
7246
7247 cuts[0] = 0.01;
7248 cuts[1] = 2.0;
7249 cuts[2] = 3.;
7250 cuts[3] = 2.0;
7251 fnumber = 2.;
7252 fdensity = 2.;
7253
7254 if (fDebug>0){
6bdc18d6 7255 Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 7256 timer.Print();
7257 timer.Start();
7258 }
7259 // RemoveUsed(seeds,0.75,0.75,1);
7260 //UnsignClusters();
7261 //SignClusters(seeds,fnumber,fdensity);
7262
7263 // find secondaries
7264
7265 cuts[0] = 0.3;
7266 cuts[1] = 1.5;
7267 cuts[2] = 3.;
7268 cuts[3] = 1.5;
7269
7270 arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
7271 SumTracks(seeds,arr);
7272 SignClusters(seeds,fnumber,fdensity);
7273 //
7274 arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
7275 SumTracks(seeds,arr);
7276 SignClusters(seeds,fnumber,fdensity);
7277 //
7278 arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
7279 SumTracks(seeds,arr);
7280 SignClusters(seeds,fnumber,fdensity);
7281 //
6d1424d5 7282 arr = Tracking(4,nup-5,nup-5-gap,cuts,-1);
7283 SumTracks(seeds,arr);
7284 SignClusters(seeds,fnumber,fdensity);
7285 //
7286 arr = Tracking(4,nup-7,nup-7-gap,cuts,-1);
7287 SumTracks(seeds,arr);
7288 SignClusters(seeds,fnumber,fdensity);
7289 //
7290 //
7291 arr = Tracking(4,nup-9,nup-9-gap,cuts,-1);
7292 SumTracks(seeds,arr);
7293 SignClusters(seeds,fnumber,fdensity);
7294 //
91162307 7295
7296
6d1424d5 7297 for (Int_t delta = 9; delta<30; delta+=gapSec){
91162307 7298 //
7299 cuts[0] = 0.3;
7300 cuts[1] = 1.5;
7301 cuts[2] = 3.;
7302 cuts[3] = 1.5;
7303 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7304 SumTracks(seeds,arr);
7305 SignClusters(seeds,fnumber,fdensity);
7306 //
7307 arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
7308 SumTracks(seeds,arr);
7309 SignClusters(seeds,fnumber,fdensity);
7310 //
7311 }
7312 fnumber = 1;
7313 fdensity = 1;
7314 //
7315 // change cuts
7316 fnumber = 2.;
7317 fdensity = 2.;
7318 cuts[0]=0.0080;
7319
7d27c1df 7320
91162307 7321 // find secondaries
6d1424d5 7322 for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=gapSec){
91162307 7323 //
7324 cuts[0] = 0.3;
2bd61959 7325 cuts[1] = 3.5;
91162307 7326 cuts[2] = 3.;
2bd61959 7327 cuts[3] = 3.5;
91162307 7328 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7329 SumTracks(seeds,arr);
7330 SignClusters(seeds,fnumber,fdensity);
7331 //
7332 arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
7333 SumTracks(seeds,arr);
7334 SignClusters(seeds,fnumber,fdensity);
7335 }
7336
7337 if (fDebug>0){
6bdc18d6 7338 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 7339 timer.Print();
7340 timer.Start();
7341 }
7342
7343 return seeds;
7344 //
7345
7346}
7347
7348
829455ad 7349TObjArray * AliTPCtracker::TrackingSpecial()
a3232aae 7350{
7351 //
7352 // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
7353 // no primary vertex seeding tried
7354 //
7355 TStopwatch timer;
7356 timer.Start();
7357 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7358
7359 TObjArray * seeds = new TObjArray;
7360 TObjArray * arr=0;
7361
7362 Int_t gap = 15;
7363 Float_t cuts[4];
7364 Float_t fnumber = 3.0;
7365 Float_t fdensity = 3.0;
7366
7367 // find secondaries
7368 cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC(); // max curvature
7369 cuts[1] = 3.5; // max tan(phi) angle for seeding
7370 cuts[2] = 3.; // not used (cut on z primary vertex)
7371 cuts[3] = 3.5; // max tan(theta) angle for seeding
7372
7373 for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
7374 //
7375 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7376 SumTracks(seeds,arr);
7377 SignClusters(seeds,fnumber,fdensity);
7378 }
7379
7380 if (fDebug>0){
7381 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
7382 timer.Print();
7383 timer.Start();
7384 }
7385
7386 return seeds;
7387 //
7388
7389}
7390
7391
829455ad 7392void AliTPCtracker::SumTracks(TObjArray *arr1,TObjArray *&arr2)
91162307 7393{
7394 //
7395 //sum tracks to common container
7396 //remove suspicious tracks
f06a1ff6 7397 // RS: Attention: supplied tracks come in the static array, don't delete them
91162307 7398 Int_t nseed = arr2->GetEntriesFast();
7399 for (Int_t i=0;i<nseed;i++){
7400 AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);
7401 if (pt){
a3232aae 7402 //
7403 // remove tracks with too big curvature
7404 //
7405 if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
ddfbc51a 7406 MarkSeedFree( arr2->RemoveAt(i) );
a3232aae 7407 continue;
7408 }
ca142b1f 7409 // REMOVE VERY SHORT TRACKS
7410 if (pt->GetNumberOfClusters()<20){
ddfbc51a 7411 MarkSeedFree( arr2->RemoveAt(i) );
ca142b1f 7412 continue;
7413 }// patch 28 fev06
91162307 7414 // NORMAL ACTIVE TRACK
7415 if (pt->IsActive()){
7416 arr1->AddLast(arr2->RemoveAt(i));
7417 continue;
7418 }
7419 //remove not usable tracks
b9671574 7420 if (pt->GetRemoval()!=10){
ddfbc51a 7421 MarkSeedFree( arr2->RemoveAt(i) );
91162307 7422 continue;
7423 }
ca142b1f 7424
91162307 7425 // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
7426 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
7427 arr1->AddLast(arr2->RemoveAt(i));
7428 else{
ddfbc51a 7429 MarkSeedFree( arr2->RemoveAt(i) );
91162307 7430 }
7431 }
7432 }
f06a1ff6 7433 // delete arr2; arr2 = 0; // RS: this is static array, don't delete it
91162307 7434}
7435
7436
1c53abe2 7437
829455ad 7438void AliTPCtracker::ParallelTracking(TObjArray *const arr, Int_t rfirst, Int_t rlast)
1c53abe2 7439{
7440 //
7441 // try to track in parralel
7442
91162307 7443 Int_t nseed=arr->GetEntriesFast();
1c53abe2 7444 //prepare seeds for tracking
7445 for (Int_t i=0; i<nseed; i++) {
91162307 7446 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 7447 if (!pt) continue;
7448 if (!t.IsActive()) continue;
7449 // follow prolongation to the first layer
47af7ca4 7450 if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fkParam->GetNRowLow()>rfirst+1) )
c9427e08 7451 FollowProlongation(t, rfirst+1);
1c53abe2 7452 }
7453
7454
7455 //
982aff31 7456 for (Int_t nr=rfirst; nr>=rlast; nr--){
7457 if (nr<fInnerSec->GetNRows())
7458 fSectors = fInnerSec;
7459 else
7460 fSectors = fOuterSec;
1c53abe2 7461 // make indexes with the cluster tracks for given
1c53abe2 7462
7463 // find nearest cluster
7464 for (Int_t i=0; i<nseed; i++) {
91162307 7465 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 7466 if (!pt) continue;
51ad6848 7467 if (nr==80) pt->UpdateReference();
1c53abe2 7468 if (!pt->IsActive()) continue;
47af7ca4 7469 // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
b9671574 7470 if (pt->GetRelativeSector()>17) {
1627d1c4 7471 continue;
7472 }
91162307 7473 UpdateClusters(t,nr);
1c53abe2 7474 }
7475 // prolonagate to the nearest cluster - if founded
7476 for (Int_t i=0; i<nseed; i++) {
91162307 7477 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
1c53abe2 7478 if (!pt) continue;
1627d1c4 7479 if (!pt->IsActive()) continue;
47af7ca4 7480 // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
b9671574 7481 if (pt->GetRelativeSector()>17) {
1627d1c4 7482 continue;
7483 }
91162307 7484 FollowToNextCluster(*pt,nr);
1c53abe2 7485 }
91162307 7486 }
7487}
7488
829455ad 7489void AliTPCtracker::PrepareForBackProlongation(const TObjArray *const arr,Float_t fac) const
91162307 7490{
7491 //
7492 //
7493 // if we use TPC track itself we have to "update" covariance
7494 //
7495 Int_t nseed= arr->GetEntriesFast();
7496 for (Int_t i=0;i<nseed;i++){
7497 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7498 if (pt) {
7499 pt->Modify(fac);
7500 //
7501 //rotate to current local system at first accepted point
b9671574 7502 Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
91162307 7503 Int_t sec = (index&0xff000000)>>24;
7504 sec = sec%18;
7505 Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
7506 if (angle1>TMath::Pi())
7507 angle1-=2.*TMath::Pi();
7508 Float_t angle2 = pt->GetAlpha();
7509
7510 if (TMath::Abs(angle1-angle2)>0.001){
17abbffb 7511 if (!pt->Rotate(angle1-angle2)) return;
91162307 7512 //angle2 = pt->GetAlpha();
7513 //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
7514 //if (pt->GetAlpha()<0)
7515 // pt->fRelativeSector+=18;
7516 //sec = pt->fRelativeSector;
7517 }
7518
7519 }
7520
7521 }
7522
7523
7524}
829455ad 7525void AliTPCtracker::PrepareForProlongation(TObjArray *const arr, Float_t fac) const
91162307 7526{
7527 //
7528 //
7529 // if we use TPC track itself we have to "update" covariance
7530 //
7531 Int_t nseed= arr->GetEntriesFast();
7532 for (Int_t i=0;i<nseed;i++){
7533 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7534 if (pt) {
7535 pt->Modify(fac);
b9671574 7536 pt->SetFirstPoint(pt->GetLastPoint());
91162307 7537 }
7538
7539 }
7540
7541
7542}
7543
829455ad 7544Int_t AliTPCtracker::PropagateBack(const TObjArray *const arr)
91162307 7545{
7546 //
7547 // make back propagation
7548 //
7549 Int_t nseed= arr->GetEntriesFast();
7550 for (Int_t i=0;i<nseed;i++){
7551 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
51ad6848 7552 if (pt&& pt->GetKinkIndex(0)<=0) {
d9b8978b 7553 //AliTPCseed *pt2 = new AliTPCseed(*pt);
91162307 7554 fSectors = fInnerSec;
d26d9159 7555 //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
7556 //fSectors = fOuterSec;
f124f8bf 7557 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
4d158c36 7558 //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
d9b8978b 7559 // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
4d158c36 7560 // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
d9b8978b 7561 //}
51ad6848 7562 }
7563 if (pt&& pt->GetKinkIndex(0)>0) {
7564 AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
b9671574 7565 pt->SetFirstPoint(kink->GetTPCRow0());
51ad6848 7566 fSectors = fInnerSec;
f124f8bf 7567 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
51ad6848 7568 }
6d493ea0 7569 CookLabel(pt,0.3);
91162307 7570 }
7571 return 0;
7572}
7573
7574
829455ad 7575Int_t AliTPCtracker::PropagateForward2(const TObjArray *const arr)
91162307 7576{
7577 //
7578 // make forward propagation
7579 //
7580 Int_t nseed= arr->GetEntriesFast();
4d158c36 7581 //
91162307 7582 for (Int_t i=0;i<nseed;i++){
7583 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7584 if (pt) {
f124f8bf 7585 FollowProlongation(*pt,0,1,1);
6d493ea0 7586 CookLabel(pt,0.3);
4d158c36 7587 }
6d493ea0 7588
91162307 7589 }
f124f8bf 7590 return 0;
91162307 7591}
7592
7593
829455ad 7594Int_t AliTPCtracker::PropagateForward()
91162307 7595{
b67e07dc 7596 //
7597 // propagate track forward
4d158c36 7598 //UnsignClusters();
d26d9159 7599 Int_t nseed = fSeeds->GetEntriesFast();
7600 for (Int_t i=0;i<nseed;i++){
7601 AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
7602 if (pt){
7603 AliTPCseed &t = *pt;
7604 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
7605 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
7606 if (alpha < 0. ) alpha += 2.*TMath::Pi();
b9671574 7607 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
d26d9159 7608 }
7609 }
7610
91162307 7611 fSectors = fOuterSec;
d26d9159 7612 ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
91162307 7613 fSectors = fInnerSec;
d26d9159 7614 ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
91162307 7615 return 1;
7616}
7617
7618
7619
7620
7621
7622
829455ad 7623Int_t AliTPCtracker::PropagateBack(AliTPCseed *const pt, Int_t row0, Int_t row1)
91162307 7624{
7625 //
7626 // make back propagation, in between row0 and row1
7627 //
1c53abe2 7628
91162307 7629 if (pt) {
7630 fSectors = fInnerSec;
7631 Int_t r1;
7632 //
7633 if (row1<fSectors->GetNRows())
7634 r1 = row1;
7635 else
7636 r1 = fSectors->GetNRows()-1;
7637
7638 if (row0<fSectors->GetNRows()&& r1>0 )
7639 FollowBackProlongation(*pt,r1);
7640 if (row1<=fSectors->GetNRows())
7641 return 0;
7642 //
7643 r1 = row1 - fSectors->GetNRows();
7644 if (r1<=0) return 0;
7645 if (r1>=fOuterSec->GetNRows()) return 0;
7646 fSectors = fOuterSec;
7647 return FollowBackProlongation(*pt,r1);
7648 }
7649 return 0;
7650}
7651
7652
7653
7654
829455ad 7655void AliTPCtracker::GetShape(AliTPCseed * seed, Int_t row)
91162307 7656{
544c295f 7657 // gets cluster shape
fd065ea2 7658 //
7659 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
47af7ca4 7660 Float_t zdrift = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())));
7661 Int_t type = (seed->GetSector() < fkParam->GetNSector()/2) ? 0: (row>126) ? 1:2;
3f82c4f2 7662 Double_t angulary = seed->GetSnp();
feed67f9 7663
7664 if (TMath::Abs(angulary)>AliTPCReconstructor::GetMaxSnpTracker()) {
7665 angulary = TMath::Sign(AliTPCReconstructor::GetMaxSnpTracker(),angulary);
7666 }
7667
bfd20868 7668 angulary = angulary*angulary/((1.-angulary)*(1.+angulary));
fd065ea2 7669 Double_t angularz = seed->GetTgl()*seed->GetTgl()*(1.+angulary);
7670
e0e13b88 7671 Double_t sigmay = clparam->GetRMS0(0,type,zdrift,TMath::Sqrt(TMath::Abs(angulary)));
7672 Double_t sigmaz = clparam->GetRMS0(1,type,zdrift,TMath::Sqrt(TMath::Abs(angularz)));
fd065ea2 7673 seed->SetCurrentSigmaY2(sigmay*sigmay);
7674 seed->SetCurrentSigmaZ2(sigmaz*sigmaz);
47af7ca4 7675 // Float_t sd2 = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fkParam->GetDiffL()*fkParam->GetDiffL();
7676// // Float_t padlength = fkParam->GetPadPitchLength(seed->fSector);
fd065ea2 7677// Float_t padlength = GetPadPitchLength(row);
7678// //
47af7ca4 7679// Float_t sresy = (seed->GetSector() < fkParam->GetNSector()/2) ? 0.2 :0.3;
fd065ea2 7680// seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
7681// //
47af7ca4 7682// Float_t sresz = fkParam->GetZSigma();
fd065ea2 7683// seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
91162307 7684 /*
7685 Float_t wy = GetSigmaY(seed);
7686 Float_t wz = GetSigmaZ(seed);
7687 wy*=wy;
7688 wz*=wz;
7689 if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
7690 printf("problem\n");
7691 }
7692 */
1c53abe2 7693}
7694
91162307 7695
1c53abe2 7696
1c53abe2 7697//__________________________________________________________________________
829455ad 7698void AliTPCtracker::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
1c53abe2 7699 //--------------------------------------------------------------------
7700 //This function "cooks" a track label. If label<0, this track is fake.
7701 //--------------------------------------------------------------------
316c6cd9 7702 AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
7703 if(!t){
7704 printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
7705 return;
7706 }
7707
1c53abe2 7708 Int_t noc=t->GetNumberOfClusters();
91162307 7709 if (noc<10){
d26d9159 7710 //printf("\nnot founded prolongation\n\n\n");
7711 //t->Dump();
91162307 7712 return ;
7713 }
7714 Int_t lb[160];
7715 Int_t mx[160];
7716 AliTPCclusterMI *clusters[160];
7717 //
7718 for (Int_t i=0;i<160;i++) {
7719 clusters[i]=0;
7720 lb[i]=mx[i]=0;
7721 }
1c53abe2 7722
7723 Int_t i;
91162307 7724 Int_t current=0;
7725 for (i=0; i<160 && current<noc; i++) {
7726
7727 Int_t index=t->GetClusterIndex2(i);
7728 if (index<=0) continue;
7729 if (index&0x8000) continue;
7730 //
7731 //clusters[current]=GetClusterMI(index);
b9671574 7732 if (t->GetClusterPointer(i)){
7733 clusters[current]=t->GetClusterPointer(i);
91162307 7734 current++;
7735 }
1c53abe2 7736 }
91162307 7737 noc = current;
1c53abe2 7738
7739 Int_t lab=123456789;
7740 for (i=0; i<noc; i++) {
7741 AliTPCclusterMI *c=clusters[i];
91162307 7742 if (!c) continue;
1c53abe2 7743 lab=TMath::Abs(c->GetLabel(0));
7744 Int_t j;
7745 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
7746 lb[j]=lab;
7747 (mx[j])++;
7748 }
7749
7750 Int_t max=0;
7751 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
7752
7753 for (i=0; i<noc; i++) {
9918f10a 7754 AliTPCclusterMI *c=clusters[i];
91162307 7755 if (!c) continue;
1c53abe2 7756 if (TMath::Abs(c->GetLabel(1)) == lab ||
7757 TMath::Abs(c->GetLabel(2)) == lab ) max++;
7758 }
52033b55 7759 if (noc<=0) { lab=-1; return;}
7760 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
1c53abe2 7761
7762 else {
7763 Int_t tail=Int_t(0.10*noc);
7764 max=0;
91162307 7765 Int_t ind=0;
ec26e231 7766 for (i=1; i<160&&ind<tail; i++) {
91162307 7767 // AliTPCclusterMI *c=clusters[noc-i];
7768 AliTPCclusterMI *c=clusters[i];
7769 if (!c) continue;
1c53abe2 7770 if (lab == TMath::Abs(c->GetLabel(0)) ||
7771 lab == TMath::Abs(c->GetLabel(1)) ||
7772 lab == TMath::Abs(c->GetLabel(2))) max++;
91162307 7773 ind++;
1c53abe2 7774 }
7775 if (max < Int_t(0.5*tail)) lab=-lab;
7776 }
7777
7778 t->SetLabel(lab);
7779
91162307 7780 // delete[] lb;
7781 //delete[] mx;
7782 //delete[] clusters;
1c53abe2 7783}
7784
47966a6d 7785
51ad6848 7786//__________________________________________________________________________
829455ad 7787Int_t AliTPCtracker::CookLabel(AliTPCseed *const t, Float_t wrong,Int_t first, Int_t last) const {
51ad6848 7788 //--------------------------------------------------------------------
7789 //This function "cooks" a track label. If label<0, this track is fake.
7790 //--------------------------------------------------------------------
7791 Int_t noc=t->GetNumberOfClusters();
7792 if (noc<10){
7793 //printf("\nnot founded prolongation\n\n\n");
7794 //t->Dump();
7795 return -1;
7796 }
7797 Int_t lb[160];
7798 Int_t mx[160];
7799 AliTPCclusterMI *clusters[160];
7800 //
7801 for (Int_t i=0;i<160;i++) {
7802 clusters[i]=0;
7803 lb[i]=mx[i]=0;
7804 }
7805
7806 Int_t i;
7807 Int_t current=0;
7808 for (i=0; i<160 && current<noc; i++) {
7809 if (i<first) continue;
7810 if (i>last) continue;
7811 Int_t index=t->GetClusterIndex2(i);
7812 if (index<=0) continue;
7813 if (index&0x8000) continue;
7814 //
7815 //clusters[current]=GetClusterMI(index);
b9671574 7816 if (t->GetClusterPointer(i)){
7817 clusters[current]=t->GetClusterPointer(i);
51ad6848 7818 current++;
7819 }
7820 }
7821 noc = current;
17abbffb 7822 //if (noc<5) return -1;
51ad6848 7823 Int_t lab=123456789;
7824 for (i=0; i<noc; i++) {
7825 AliTPCclusterMI *c=clusters[i];
7826 if (!c) continue;
7827 lab=TMath::Abs(c->GetLabel(0));
7828 Int_t j;
7829 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
7830 lb[j]=lab;
7831 (mx[j])++;
7832 }
7833
7834 Int_t max=0;
7835 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
7836
7837 for (i=0; i<noc; i++) {
7838 AliTPCclusterMI *c=clusters[i];
7839 if (!c) continue;
7840 if (TMath::Abs(c->GetLabel(1)) == lab ||
7841 TMath::Abs(c->GetLabel(2)) == lab ) max++;
7842 }
52033b55 7843 if (noc<=0) { lab=-1; return -1;}
7844 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
51ad6848 7845
7846 else {
7847 Int_t tail=Int_t(0.10*noc);
7848 max=0;
7849 Int_t ind=0;
ec26e231 7850 for (i=1; i<160&&ind<tail; i++) {
51ad6848 7851 // AliTPCclusterMI *c=clusters[noc-i];
7852 AliTPCclusterMI *c=clusters[i];
7853 if (!c) continue;
7854 if (lab == TMath::Abs(c->GetLabel(0)) ||
7855 lab == TMath::Abs(c->GetLabel(1)) ||
7856 lab == TMath::Abs(c->GetLabel(2))) max++;
7857 ind++;
7858 }
7859 if (max < Int_t(0.5*tail)) lab=-lab;
7860 }
7861
7862 // t->SetLabel(lab);
7863 return lab;
7864 // delete[] lb;
7865 //delete[] mx;
7866 //delete[] clusters;
7867}
7868
7869
829455ad 7870Int_t AliTPCtracker::GetRowNumber(Double_t x[3]) const
eea478d3 7871{
7872 //return pad row number for given x vector
7873 Float_t phi = TMath::ATan2(x[1],x[0]);
7874 if(phi<0) phi=2.*TMath::Pi()+phi;
7875 // Get the local angle in the sector philoc
7876 const Float_t kRaddeg = 180/3.14159265358979312;
7877 Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
7878 Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
7879 return GetRowNumber(localx);
7880}
7881
91162307 7882
91162307 7883
829455ad 7884void AliTPCtracker::MakeESDBitmaps(AliTPCseed *t, AliESDtrack *esd)
19b00333 7885{
7886 //-----------------------------------------------------------------------
7887 // Fill the cluster and sharing bitmaps of the track
7888 //-----------------------------------------------------------------------
7889
7890 Int_t firstpoint = 0;
7891 Int_t lastpoint = 159;
7892 AliTPCTrackerPoint *point;
52c51057 7893 AliTPCclusterMI *cluster;
19b00333 7894
bad6eb00 7895 Int_t nclsf = 0;
7896 TBits clusterMap(159);
7897 TBits sharedMap(159);
7898 TBits fitMap(159);
19b00333 7899 for (int iter=firstpoint; iter<lastpoint; iter++) {
52c51057 7900 // Change to cluster pointers to see if we have a cluster at given padrow
bad6eb00 7901
52c51057 7902 cluster = t->GetClusterPointer(iter);
7903 if (cluster) {
bad6eb00 7904 clusterMap.SetBitNumber(iter, kTRUE);
52c51057 7905 point = t->GetTrackPoint(iter);
19b00333 7906 if (point->IsShared())
bad6eb00 7907 sharedMap.SetBitNumber(iter,kTRUE);
19b00333 7908 }
bad6eb00 7909 if (t->GetClusterIndex(iter) >= 0 && (t->GetClusterIndex(iter) & 0x8000) == 0) {
7910 fitMap.SetBitNumber(iter, kTRUE);
7911 nclsf++;
19b00333 7912 }
7913 }
bad6eb00 7914 esd->SetTPCClusterMap(clusterMap);
7915 esd->SetTPCSharedMap(sharedMap);
7916 esd->SetTPCFitMap(fitMap);
7917 if (nclsf != t->GetNumberOfClusters())
27540e35 7918 AliDebug(3,Form("Inconsistency between ncls %d and indices %d (found %d)",t->GetNumberOfClusters(),nclsf,esd->GetTPCClusterMap().CountBits()));
19b00333 7919}
92f513f5 7920
829455ad 7921Bool_t AliTPCtracker::IsFindable(AliTPCseed & track){
76d56fd6 7922 //
7923 // return flag if there is findable cluster at given position
7924 //
7925 Float_t kDeltaZ=10;
7926 Float_t z = track.GetZ();
7927
7928 if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*track.GetX()+kDeltaZ) &&
47af7ca4 7929 TMath::Abs(z)<fkParam->GetZLength(0) &&
76d56fd6 7930 (TMath::Abs(track.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
7931 return kTRUE;
7932 return kFALSE;
7933}
92f513f5 7934
7935
829455ad 7936void AliTPCtracker::AddCovariance(AliTPCseed * seed){
92f513f5 7937 //
e1dadcd0 7938 // Adding systematic error estimate to the covariance matrix
b87c2bbc 7939 // !!!! the systematic error for element 4 is in 1/GeV
7940 // 03.03.2012 MI changed in respect to the previous versions
e1dadcd0 7941 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
7942 //
7943 // use only the diagonal part if not specified otherwise
7944 if (!AliTPCReconstructor::GetRecoParam()->GetUseSystematicCorrelation()) return AddCovarianceAdd(seed);
7945 //
7946 Double_t *covarS= (Double_t*)seed->GetCovariance();
7947 Double_t factor[5]={1,1,1,1,1};
e1dadcd0 7948 factor[0]= TMath::Sqrt(TMath::Abs((covarS[0] + param[0]*param[0])/covarS[0]));
7949 factor[1]= TMath::Sqrt(TMath::Abs((covarS[2] + param[1]*param[1])/covarS[2]));
7950 factor[2]= TMath::Sqrt(TMath::Abs((covarS[5] + param[2]*param[2])/covarS[5]));
7951 factor[3]= TMath::Sqrt(TMath::Abs((covarS[9] + param[3]*param[3])/covarS[9]));
b87c2bbc 7952 factor[4]= TMath::Sqrt(TMath::Abs((covarS[14] +param[4]*param[4])/covarS[14]));
9b550f87 7953 //
7954 factor[0]=factor[2];
7955 factor[4]=factor[2];
e1dadcd0 7956 // 0
7957 // 1 2
7958 // 3 4 5
7959 // 6 7 8 9
7960 // 10 11 12 13 14
7961 for (Int_t i=0; i<5; i++){
7962 for (Int_t j=i; j<5; j++){
7963 Int_t index=seed->GetIndex(i,j);
7964 covarS[index]*=factor[i]*factor[j];
7965 }
7966 }
7967}
7968
92f513f5 7969
829455ad 7970void AliTPCtracker::AddCovarianceAdd(AliTPCseed * seed){
e1dadcd0 7971 //
7972 // Adding systematic error - as additive factor without correlation
7973 //
b87c2bbc 7974 // !!!! the systematic error for element 4 is in 1/GeV
7975 // 03.03.2012 MI changed in respect to the previous versions
7976
92f513f5 7977 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
f47588e0 7978 Double_t *covarIn= (Double_t*)seed->GetCovariance();
92f513f5 7979 Double_t covar[15];
7980 for (Int_t i=0;i<15;i++) covar[i]=0;
7981 // 0
7982 // 1 2
7983 // 3 4 5
7984 // 6 7 8 9
7985 // 10 11 12 13 14
7986 covar[0] = param[0]*param[0];
7987 covar[2] = param[1]*param[1];
7988 covar[5] = param[2]*param[2];
7989 covar[9] = param[3]*param[3];
b87c2bbc 7990 covar[14]= param[4]*param[4];
f47588e0 7991 //
7992 covar[1]=TMath::Sqrt((covar[0]*covar[2]))*covarIn[1]/TMath::Sqrt((covarIn[0]*covarIn[2]));
7993 //
7994 covar[3]=TMath::Sqrt((covar[0]*covar[5]))*covarIn[3]/TMath::Sqrt((covarIn[0]*covarIn[5]));
7995 covar[4]=TMath::Sqrt((covar[2]*covar[5]))*covarIn[4]/TMath::Sqrt((covarIn[2]*covarIn[5]));
7996 //
7997 covar[6]=TMath::Sqrt((covar[0]*covar[9]))*covarIn[6]/TMath::Sqrt((covarIn[0]*covarIn[9]));
7998 covar[7]=TMath::Sqrt((covar[2]*covar[9]))*covarIn[7]/TMath::Sqrt((covarIn[2]*covarIn[9]));
7999 covar[8]=TMath::Sqrt((covar[5]*covar[9]))*covarIn[8]/TMath::Sqrt((covarIn[5]*covarIn[9]));
8000 //
8001 covar[10]=TMath::Sqrt((covar[0]*covar[14]))*covarIn[10]/TMath::Sqrt((covarIn[0]*covarIn[14]));
8002 covar[11]=TMath::Sqrt((covar[2]*covar[14]))*covarIn[11]/TMath::Sqrt((covarIn[2]*covarIn[14]));
8003 covar[12]=TMath::Sqrt((covar[5]*covar[14]))*covarIn[12]/TMath::Sqrt((covarIn[5]*covarIn[14]));
8004 covar[13]=TMath::Sqrt((covar[9]*covar[14]))*covarIn[13]/TMath::Sqrt((covarIn[9]*covarIn[14]));
8005 //
92f513f5 8006 seed->AddCovariance(covar);
8007}
f06a1ff6 8008
ec7e4ad6 8009//_____________________________________________________________________________
829455ad 8010Bool_t AliTPCtracker::IsTPCHVDipEvent(AliESDEvent const *esdEvent)
661f340b 8011{
8012 //
8013 // check events affected by TPC HV dip
8014 //
8015 if(!esdEvent) return kFALSE;
ec7e4ad6 8016
661f340b 8017 // Init TPC OCDB
8018 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
8019 if(!db) return kFALSE;
8020 db->SetRun(esdEvent->GetRunNumber());
ec7e4ad6 8021
661f340b 8022 // maximum allowed voltage before an event is identified as a dip event
8023 // and scanning period
8024 const Double_t kTPCHVdip = db->GetParameters()->GetMaxDipVoltage();
8025 const Double_t dipEventScanPeriod = db->GetParameters()->GetVoltageDipScanPeriod();
8026 const Double_t tevSec = esdEvent->GetTimeStamp();
8027
ec7e4ad6 8028 for(Int_t sector=0; sector<72; sector++)
8029 {
661f340b 8030 // don't use excluded chambers, since the state is not defined at all
8031 if (!db->GetChamberHVStatus(sector)) continue;
8032
8033 // get hv sensor of the chamber
8034 AliDCSSensor *sensor = db->GetChamberHVSensor(sector);
8035 if (!sensor) continue;
8036 TGraph *grSensor=sensor->GetGraph();
8037 if (!grSensor) continue;
8038 if (grSensor->GetN()<1) continue;
ec7e4ad6 8039
661f340b 8040 // get median
8041 const Double_t median = db->GetChamberHighVoltageMedian(sector);
8042 if(median < 1.) continue;
ec7e4ad6 8043
661f340b 8044 for (Int_t ipoint=0; ipoint<grSensor->GetN()-1; ++ipoint){
8045 Double_t nextTime=grSensor->GetX()[ipoint+1]*3600+sensor->GetStartTime();
8046 if (tevSec-dipEventScanPeriod>nextTime) continue;
8047 const Float_t deltaV=TMath::Abs(grSensor->GetY()[ipoint]-median);
8048 if (deltaV>kTPCHVdip) {
8049 AliDebug(3,Form("HV dip detected in ROC '%02d' with dV '%.2f' at time stamp '%.0f'",sector,deltaV,tevSec));
8050 return kTRUE;
8051 }
8052 if (nextTime>tevSec+dipEventScanPeriod) break;
ec7e4ad6 8053 }
661f340b 8054 }
8055
8056 return kFALSE;
8057}
ddfbc51a 8058
8059//________________________________________
829455ad 8060void AliTPCtracker::MarkSeedFree(TObject *sd)
ddfbc51a 8061{
8062 // account that this seed is "deleted"
8063 AliTPCseed* seed = dynamic_cast<AliTPCseed*>(sd);
88492b27 8064 if (!seed) {
b6565e28 8065 AliError(Form("Freeing of non-AliTPCseed %p from the pool is requested",sd));
8066 return;
8067 }
88492b27 8068 int id = seed->GetPoolID();
b6565e28 8069 if (id<0) {
8070 AliError(Form("Freeing of seed %p NOT from the pool is requested",sd));
8071 return;
8072 }
ddfbc51a 8073 // AliInfo(Form("%d %p",id, seed));
8074 fSeedsPool->RemoveAt(id);
8075 if (fFreeSeedsID.GetSize()<=fNFreeSeeds) fFreeSeedsID.Set( 2*fNFreeSeeds + 100 );
8076 fFreeSeedsID.GetArray()[fNFreeSeeds++] = id;
8077}
8078
8079//________________________________________
829455ad 8080TObject *&AliTPCtracker::NextFreeSeed()
ddfbc51a 8081{
8082 // return next free slot where the seed can be created
8083 fLastSeedID = fNFreeSeeds ? fFreeSeedsID.GetArray()[--fNFreeSeeds] : fSeedsPool->GetEntriesFast();
8084 // AliInfo(Form("%d",fLastSeedID));
8085 return (*fSeedsPool)[ fLastSeedID ];
8086 //
8087}
8088
8089//________________________________________
829455ad 8090void AliTPCtracker::ResetSeedsPool()
ddfbc51a 8091{
8092 // mark all seeds in the pool as unused
8093 AliInfo(Form("CurrentSize: %d, BookedUpTo: %d, free: %d",fSeedsPool->GetSize(),fSeedsPool->GetEntriesFast(),fNFreeSeeds));
8094 fNFreeSeeds = 0;
8095 fSeedsPool->Clear("C"); // RS: nominally the seeds may allocate memory...
8096}
72e25240 8097
829455ad 8098Int_t AliTPCtracker::PropagateToRowHLT(AliTPCseed *pt, int nrow)
72e25240 8099{
8100 AliTPCseed &t=*pt;
8101 Double_t x= GetXrow(nrow);
8102 Double_t ymax= GetMaxY(nrow);
8103 Int_t rotate = 0;
8104 Int_t nRotations=0;
8105 int ret = 1;
8106 do{
8107 rotate = 0;
8108 if (!t.PropagateTo(x) ){
8109 //cout<<"can't propagate to row "<<nrow<<", x="<<t.GetX()<<" -> "<<x<<endl;
8110 //t.Print();
8111 ret = 0;
8112 break;
8113 }
8114 t.SetRow(nrow);
8115 Double_t y = t.GetY();
8116 if( y > ymax ) {
8117 if( rotate!=-1 ) rotate=1;
8118 } else if (y <-ymax) {
8119 if( rotate!=1 ) rotate = -1;
8120 }
8121 if( rotate==0 ) break;
8122 //cout<<"rotate at row "<<nrow<<": "<<rotate<<endl;
8123 if (!t.Rotate( rotate==1 ?fSectors->GetAlpha() :-fSectors->GetAlpha())) {
8124 //cout<<"can't rotate "<<endl;
8125 ret=0;
8126 break;
8127 }
8128 nRotations+= rotate;
8129 }while(rotate!=0);
8130 if( nRotations!=0 ){
8131 int newSec= t.GetRelativeSector()+nRotations;
8132 if( newSec>=fN ) newSec-=fN;
8133 else if( newSec<0 ) newSec +=fN;
8134 //cout<<"rotate at row "<<nrow<<": "<<nRotations<<" times "<<" sec "
8135 //<< t.GetRelativeSector()<<" -> "<<newSec<<endl;
8136 t.SetRelativeSector(newSec);
8137 }
8138 return ret;
8139}
8140
829455ad 8141void AliTPCtracker::TrackFollowingHLT(TObjArray *const arr )
72e25240 8142{
8143 //
8144 // try to track in parralel
8145
8146 Int_t nRows=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8147 fSectors=fInnerSec;
8148
8149 Int_t nseed=arr->GetEntriesFast();
8150 //cout<<"Parallel tracking My.."<<endl;
8151 double shapeY2[160], shapeZ2[160];
8152 Int_t clusterIndex[160];
8153
8154 for (Int_t iSeed=0; iSeed<nseed; iSeed++) {
8155 //if( iSeed!=1 ) continue;
8156 AliTPCseed *pt=(AliTPCseed*) (arr->UncheckedAt(iSeed));
8157 if (!pt) continue;
8158 AliTPCseed &t=*pt;
8159
8160 //cout <<"Pt "<<t.GetSigned1Pt()<<endl;
8161
8162 // t.Print();
8163
8164 for( int iter=0; iter<3; iter++ ){
8165
8166 t.Reset();
8167 t.SetLastPoint(0); // first cluster in track position
8168 t.SetFirstPoint(nRows-1);
8169 t.ResetCovariance(.1);
8170 t.SetNumberOfClusters(0);
8171 for( int i=0; i<nRows; i++ ){
8172 shapeY2[i]=1.;
8173 shapeZ2[i]=1.;
8174 clusterIndex[i]=-1;
8175 t.SetClusterIndex2(i,-1);
8176 t.SetClusterIndex(i,-1);
8177 }
8178
8179 // pick up the clusters
8180
8181 Double_t roady = 20.;
8182 Double_t roadz = 20.;
8183 double roadr = 5;
8184
8185 AliTPCseed t0(t);
8186 t0.Reset();
8187 int nClusters = 0;
8188 {
8189 t0.SetRelativeSector(t.GetRelativeSector());
8190 t0.SetLastPoint(0); // first cluster in track position
8191 t0.SetFirstPoint(159);
8192 for (Int_t nr=0; nr<nRows; nr++){
8193 if( nr<fInnerSec->GetNRows() ) fSectors=fInnerSec;
8194 else fSectors=fOuterSec;
8195
8196 if( !PropagateToRowHLT(&t0, nr ) ){ break; }
8197 if (TMath::Abs(t0.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8198 //cout<<"Snp is too big: "<<t0.GetSnp()<<endl;
8199 continue;
8200 }
8201 if (!IsActive(t0.GetRelativeSector(),nr)) {
8202 continue;
8203 }
8204
8205 if( iter==0 ){
8206 GetShape(&t0,nr);
8207 shapeY2[nr]=t0.GetCurrentSigmaY2();
8208 shapeZ2[nr]=t0.GetCurrentSigmaZ2();
8209 }
8210
8211 AliTPCtrackerRow &krow=GetRow(t0.GetRelativeSector(),nr);
8212 if( !krow ) continue;
8213
8214 t.SetClusterIndex2(nr,-3); // foundable
8215 t.SetClusterIndex(nr,-3);
8216
8217 AliTPCclusterMI *cl=0;
8218 UInt_t uindex = 0;
8219 cl = krow.FindNearest2(t0.GetY(),t0.GetZ(),roady,roadz,uindex);
8220 if (!cl ) continue;
8221 double dy = cl->GetY()-t0.GetY();
8222 double dz = cl->GetZ()-t0.GetZ();
8223 double dr = sqrt(dy*dy+dz*dz);
8224 if( dr>roadr ){
8225 //cout<<"row "<<nr<<", best cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8226 continue;
8227 }
8228 //cout<<"row "<<nr<<", found cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8229
8230 t0.SetClusterPointer(nr, cl);
8231 clusterIndex[nr] = krow.GetIndex(uindex);
8232 if( t0.GetFirstPoint()>nr ) t0.SetFirstPoint(nr);
8233 t0.SetLastPoint(nr);
8234 nClusters++;
8235 }
8236 }
8237
8238 if( nClusters <3 ){
8239 //cout<<"NOT ENOUGTH CLUSTERS: "<<nClusters<<endl;
8240 break;
8241 }
8242 Int_t basePoints[3] = {t0.GetFirstPoint(),t0.GetFirstPoint(),t0.GetLastPoint()};
8243
8244 // find midpoint
8245 {
8246 Int_t midRow = (t0.GetLastPoint()-t0.GetFirstPoint())/2;
8247 int dist=200;
8248 for( int nr=t0.GetFirstPoint()+1; nr< t0.GetLastPoint(); nr++){
8249 if( !t0.GetClusterPointer(nr) ) continue;
8250 int d = TMath::Abs(nr-midRow);
8251 if( d < dist ){
8252 dist = d;
8253 basePoints[1] = nr;
8254 }
8255 }
8256 }
8257
8258 // first fit 3 base points
8259 if( 1||iter<2 ){
8260 //cout<<"Fit3: "<<endl;
8261 for( int icl=0; icl<3; icl++){
8262 int nr = basePoints[icl];
8263 int lr=nr;
8264 if( nr>=fInnerSec->GetNRows()){
8265 lr = nr - fInnerSec->GetNRows();
8266 fSectors=fOuterSec;
8267 } else fSectors=fInnerSec;
8268
8269 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8270 if(!cl){
8271 //cout<<"WRONG!!!!"<<endl;
8272 continue;
8273 }
8274 int iSec = cl->GetDetector() %fkNIS;
8275 int rotate = iSec - t.GetRelativeSector();
8276 if( rotate!=0 ){
8277 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8278 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8279 //cout<<"can't rotate "<<endl;
8280 break;
8281 }
8282 t.SetRelativeSector(iSec);
8283 }
8284 Double_t x= cl->GetX();
8285 if (!t.PropagateTo(x)){
8286 //cout<<"can't propagate to x="<<x<<endl;
8287 break;
8288 }
8289
8290 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8291 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8292 break;
8293 }
8294 //cout<<"fit3 : row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8295
8296 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8297 t.SetCurrentCluster(cl);
8298 t.SetRow(lr);
8299
8300 t.SetErrorY2(shapeY2[nr]);
8301 t.SetErrorZ2(shapeZ2[nr]);
8302 if( icl==0 ){
8303 double cov[15];
8304 for( int j=0; j<15; j++ ) cov[j]=0;
8305 cov[0]=10;
8306 cov[2]=10;
8307 cov[5]=.5;
8308 cov[9]=.5;
8309 cov[14]=1.;
8310 t.AliExternalTrackParam::AddCovariance(cov);
8311 }
8312 if( !UpdateTrack(&t,0) ){
8313 //cout<<"Can not update"<<endl;
8314 //t.Print();
8315 t.SetClusterIndex2(nr,-1);
8316 t.SetClusterIndex(nr,-1);
8317 t.SetClusterPointer(nr,0);
8318 break;
8319 }
8320 //t.SetClusterPointer(nr, cl);
8321 }
8322
8323 //t.SetLastPoint(t0.GetLastPoint());
8324 //t.SetFirstPoint(t0.GetFirstPoint());
8325
8326 //cout<<"Fit: "<<endl;
8327 for (Int_t nr=t0.GetLastPoint(); nr>=t0.GetFirstPoint(); nr-- ){
8328 int lr=nr;
8329 if( nr>=fInnerSec->GetNRows()){
8330 lr = nr - fInnerSec->GetNRows();
8331 fSectors=fOuterSec;
8332 } else fSectors=fInnerSec;
8333
8334 if(1|| iter<2 ){
8335 if( nr == basePoints[0] ) continue;
8336 if( nr == basePoints[1] ) continue;
8337 if( nr == basePoints[2] ) continue;
8338 }
8339 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8340 if(!cl) continue;
8341
8342 int iSec = cl->GetDetector() %fkNIS;
8343 int rotate = iSec - t.GetRelativeSector();
8344 if( rotate!=0 ){
8345 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8346 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8347 //cout<<"can't rotate "<<endl;
8348 break;
8349 }
8350 t.SetRelativeSector(iSec);
8351 }
8352 Double_t x= cl->GetX();
8353 if (!t.PropagateTo(x)){
8354 //cout<<"can't propagate to x="<<x<<endl;
8355 break;
8356 }
8357 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8358 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8359 break;
8360 }
8361
8362 //cout<<"fit: row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8363
8364 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8365 t.SetCurrentCluster(cl);
8366 t.SetRow(lr);
8367 t.SetErrorY2(shapeY2[nr]);
8368 t.SetErrorZ2(shapeZ2[nr]);
8369
8370 if( !UpdateTrack(&t,0) ){
8371 //cout<<"Can not update"<<endl;
8372 //t.Print();
8373 t.SetClusterIndex2(nr,-1);
8374 t.SetClusterIndex(nr,-1);
8375 break;
8376 }
8377 //t.SetClusterPointer(nr, cl);
8378 }
8379 }
8380 //cout<<"After iter "<<iter<<": N clusters="<<t.GetNumberOfClusters()<<" : "<<nClusters<<endl;
8381 }
8382
8383 //cout<<"fitted track"<<iSeed<<endl;
8384 //t.Print();
8385 //cout<<"Statistics: "<<endl;
8386 Int_t foundable,found,shared;
8387 t.GetClusterStatistic(0,nRows, found, foundable, shared, kTRUE);
8388 t.SetNFoundable(foundable);
8389 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8390
8391 }
8392}
8393
8394
829455ad 8395TObjArray * AliTPCtracker::MakeSeedsHLT(const AliESDEvent *hltEvent)
72e25240 8396{
8397 // tracking
8398 //
8399
8400 if( !hltEvent ) return 0;
8401
8402
8403 Int_t nentr=hltEvent->GetNumberOfTracks();
8404
8405 AliInfo(Form("Using %d HLT tracks for seeding",nentr));
8406
8407 TObjArray * seeds = new TObjArray(nentr);
8408
8409 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8410 Int_t index = 0;
8411
8412 Int_t nTr=hltEvent->GetNumberOfTracks();
8413
8414 for( int itr=0; itr<nTr; itr++ ){
8415 //if( itr!=97 ) continue;
8416 const AliExternalTrackParam *param = hltEvent->GetTrack(itr)->GetTPCInnerParam();
8417 if( !param ) continue;
8418 //if( TMath::Abs(esdTr->GetSigned1Pt())>1 ) continue;
8419 //if( TMath::Abs(esdTr->GetTgl())>1. ) continue;
8420 AliTPCtrack tr;
8421 tr.Set(param->GetX(),param->GetAlpha(),param->GetParameter(),param->GetCovariance());
8422 tr.SetNumberOfClusters(0);
8423 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed(tr);
8424
8425 Double_t alpha=seed->GetAlpha();// - fSectors->GetAlphaShift();
8426 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
8427 if (alpha < 0. ) alpha += 2.*TMath::Pi();
8428 //
8429 seed->SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
8430 Double_t alphaSec = fSectors->GetAlpha() * seed->GetRelativeSector() + fSectors->GetAlphaShift();
8431
8432 if (alphaSec >= TMath::Pi()) alphaSec -= 2.*TMath::Pi();
8433 if (alphaSec < -TMath::Pi()) alphaSec += 2.*TMath::Pi();
8434
8435 seed->Rotate(alphaSec - alpha);
8436
8437 seed->SetPoolID(fLastSeedID);
8438 seed->SetIsSeeding(kTRUE);
8439 seed->SetSeed1(nup-1);
8440 seed->SetSeed2(nup-2);
8441 seed->SetSeedType(0);
8442 seed->SetFirstPoint(-1);
8443 seed->SetLastPoint(-1);
8444 seeds->AddLast(seed); // note, track is seed, don't free the seed
8445 index++;
8446 //if( index>3 ) break;
8447 }
8448
8449
8450 fSectors = fOuterSec;
8451
8452 TrackFollowingHLT(seeds );
8453
8454 nTr = seeds->GetEntriesFast();
8455 for( int itr=0; itr<nTr; itr++ ){
8456 AliTPCseed * seed = (AliTPCseed*) seeds->UncheckedAt(itr);
8457 if( !seed ) continue;
8458 //FollowBackProlongation(*seed,0);
8459 // cout<<seed->GetNumberOfClusters()<<endl;
8460 Int_t foundable,found,shared;
8461 seed->GetClusterStatistic(0,nup, found, foundable, shared, kTRUE);
8462 seed->SetNFoundable(foundable);
8463 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8464 //if ((found<0.55*foundable) || shared>0.5*found ){// || (seed->GetSigmaY2()+seed->GetSigmaZ2())>0.5){
8465 //MarkSeedFree(seeds->RemoveAt(itr));
8466 //continue;
8467 //}
8468 if (seed->GetNumberOfClusters()<30 ||
8469 seed->GetNumberOfClusters() < seed->GetNFoundable()*0.6 ||
8470 seed->GetNShared()>0.4*seed->GetNumberOfClusters() ) {
8471 MarkSeedFree(seeds->RemoveAt(itr));
8472 continue;
8473 }
8474
8475 for( int ir=0; ir<nup; ir++){
8476 AliTPCclusterMI *c = seed->GetClusterPointer(ir);
8477 if( c ) c->Use(10);
8478 }
8479 }
492a4365 8480 std::cout<<"\n\nHLT tracks left: "<<seeds->GetEntries()<<" out of "<<hltEvent->GetNumberOfTracks()<<endl<<endl;
72e25240 8481 return seeds;
8482}
5576d489 8483
8484void AliTPCtracker::FillClusterOccupancyInfo()
8485{
8486 //fill the cluster occupancy info into the ESD friend
8487 AliESDfriend* esdFriend = static_cast<AliESDfriend*>(fEvent->FindListObject("AliESDfriend"));
8488 if (!esdFriend) return;
8489
8490 for (Int_t isector=0; isector<18; isector++){
8491 AliTPCtrackerSector &iroc = fInnerSec[isector];
8492 AliTPCtrackerSector &oroc = fOuterSec[isector];
8493 //all clusters
8494 esdFriend->SetNclustersTPC(isector, iroc.GetNClInSector(0));
8495 esdFriend->SetNclustersTPC(isector+18,iroc.GetNClInSector(1));
8496 esdFriend->SetNclustersTPC(isector+36,oroc.GetNClInSector(0));
8497 esdFriend->SetNclustersTPC(isector+54,oroc.GetNClInSector(1));
8498 //clusters used in tracking
8499 esdFriend->SetNclustersTPCused(isector, iroc.GetNClUsedInSector(0));
8500 esdFriend->SetNclustersTPCused(isector+18, iroc.GetNClUsedInSector(1));
8501 esdFriend->SetNclustersTPCused(isector+36, oroc.GetNClUsedInSector(0));
8502 esdFriend->SetNclustersTPCused(isector+54, oroc.GetNClUsedInSector(1));
8503 }
8504}