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