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