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