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