]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/Rec/AliTPCtracker.cxx
commit to clean dev branch
[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.);
2c4acef0 3243 //RS if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
6c94f330 3244 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
be34cb88 3245 //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
3246 // fSeeds->AddAt(0,i);
ddfbc51a 3247 // MarkSeedFree( seed );
be34cb88 3248 // continue;
3249 //}
a3986da2 3250
91162307 3251 //
3252 //
3253 // rotate to the local coordinate system
eea478d3 3254 //
3255 fSectors=fInnerSec; fN=fkNIS;
f124f8bf 3256 Double_t alpha=seed->GetAlpha();
91162307 3257 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
3258 if (alpha < 0. ) alpha += 2.*TMath::Pi();
a3f36f42 3259 Int_t ns=Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
91162307 3260 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
f124f8bf 3261 alpha-=seed->GetAlpha();
4d158c36 3262 if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
3263 if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
f124f8bf 3264 if (TMath::Abs(alpha) > 0.001) { // This should not happen normally
3265 AliWarning(Form("Rotating track over %f",alpha));
3266 if (!seed->Rotate(alpha)) {
ddfbc51a 3267 MarkSeedFree( seed );
f124f8bf 3268 continue;
3269 }
d9b8978b 3270 }
b9671574 3271 seed->SetESD(esd);
4d158c36 3272 // sign clusters
b406fdb0 3273 if (esd->GetKinkIndex(0)<=0){
3274 for (Int_t irow=0;irow<160;irow++){
3275 Int_t index = seed->GetClusterIndex2(irow);
bad6eb00 3276 if (index >= 0){
b406fdb0 3277 //
3278 AliTPCclusterMI * cl = GetClusterMI(index);
b9671574 3279 seed->SetClusterPointer(irow,cl);
b406fdb0 3280 if (cl){
3281 if ((index & 0x8000)==0){
3282 cl->Use(10); // accepted cluster
3283 }else{
3284 cl->Use(6); // close cluster not accepted
3285 }
4d158c36 3286 }else{
b406fdb0 3287 Info("ReadSeeds","Not found cluster");
3288 }
4d158c36 3289 }
3290 }
3291 }
3292 fSeeds->AddAt(seed,i);
91162307 3293 }
3294}
3295
3296
3297
3298//_____________________________________________________________________________
829455ad 3299void AliTPCtracker::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
91162307 3300 Float_t deltay, Int_t ddsec) {
3301 //-----------------------------------------------------------------
3302 // This function creates track seeds.
3303 // SEEDING WITH VERTEX CONSTRAIN
3304 //-----------------------------------------------------------------
3305 // cuts[0] - fP4 cut
3306 // cuts[1] - tan(phi) cut
3307 // cuts[2] - zvertex cut
3308 // cuts[3] - fP3 cut
3309 Int_t nin0 = 0;
3310 Int_t nin1 = 0;
3311 Int_t nin2 = 0;
3312 Int_t nin = 0;
3313 Int_t nout1 = 0;
3314 Int_t nout2 = 0;
3315
3316 Double_t x[5], c[15];
3317 // Int_t di = i1-i2;
3318 //
ddfbc51a 3319 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed();
3320 seed->SetPoolID(fLastSeedID);
91162307 3321 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
3322 Double_t cs=cos(alpha), sn=sin(alpha);
d757548f 3323 //
3324 // Double_t x1 =fOuterSec->GetX(i1);
3325 //Double_t xx2=fOuterSec->GetX(i2);
3326
91162307 3327 Double_t x1 =GetXrow(i1);
3328 Double_t xx2=GetXrow(i2);
3329
3330 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
3331
3332 Int_t imiddle = (i2+i1)/2; //middle pad row index
3333 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
bd26fa83 3334 const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
91162307 3335 //
3336 Int_t ns =sec;
3337
bd26fa83 3338 const AliTPCtrackerRow& kr1=GetRow(ns,i1);
b9671574 3339 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
3340 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
91162307 3341
3342 //
3343 // change cut on curvature if it can't reach this layer
3344 // maximal curvature set to reach it
3345 Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
3346 if (dvertexmax*0.5*cuts[0]>0.85){
3347 cuts[0] = 0.85/(dvertexmax*0.5+1.);
3348 }
3349 Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
3350
3351 // Int_t ddsec = 1;
3352 if (deltay>0) ddsec = 0;
3353 // loop over clusters
3354 for (Int_t is=0; is < kr1; is++) {
3355 //
3356 if (kr1[is]->IsUsed(10)) continue;
3357 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3358 //if (TMath::Abs(y1)>ymax) continue;
3359
3360 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3361
3362 // find possible directions
3363 Float_t anglez = (z1-z3)/(x1-x3);
3364 Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
3365 //
3366 //
3367 //find rotation angles relative to line given by vertex and point 1
3368 Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
3369 Double_t dvertex = TMath::Sqrt(dvertex2);
3370 Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
3371 Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
3372
3373 //
3374 // loop over 2 sectors
3375 Int_t dsec1=-ddsec;
3376 Int_t dsec2= ddsec;
3377 if (y1<0) dsec2= 0;
3378 if (y1>0) dsec1= 0;
3379
3380 Double_t dddz1=0; // direction of delta inclination in z axis
3381 Double_t dddz2=0;
3382 if ( (z1-z3)>0)
3383 dddz1 =1;
3384 else
3385 dddz2 =1;
3386 //
3387 for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
3388 Int_t sec2 = sec + dsec;
3389 //
bd26fa83 3390 // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
3391 //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
3392 AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
3393 AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
91162307 3394 Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
3395 Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
3396
3397 // rotation angles to p1-p3
3398 Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
3399 Double_t x2, y2, z2;
3400 //
3401 // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
3402
3403 //
3404 Double_t dxx0 = (xx2-x3)*cs13r;
3405 Double_t dyy0 = (xx2-x3)*sn13r;
3406 for (Int_t js=index1; js < index2; js++) {
3407 const AliTPCclusterMI *kcl = kr2[js];
3408 if (kcl->IsUsed(10)) continue;
3409 //
3410 //calcutate parameters
3411 //
3412 Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
3413 // stright track
3414 if (TMath::Abs(yy0)<0.000001) continue;
3415 Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
3416 Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
3417 Double_t r02 = (0.25+y0*y0)*dvertex2;
3418 //curvature (radius) cut
3419 if (r02<r2min) continue;
3420
3421 nin0++;
3422 //
3423 Double_t c0 = 1/TMath::Sqrt(r02);
3424 if (yy0>0) c0*=-1.;
3425
3426
3427 //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
3428 //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
b67e07dc 3429 Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
3430 Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
91162307 3431 //
3432 //
3433 Double_t z0 = kcl->GetZ();
3434 Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
3435 if (TMath::Abs(zzzz2-z0)>0.5) continue;
3436 nin1++;
3437 //
3438 Double_t dip = (z1-z0)*c0/dfi1;
3439 Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
3440 //
3441 y2 = kcl->GetY();
3442 if (dsec==0){
3443 x2 = xx2;
3444 z2 = kcl->GetZ();
3445 }
3446 else
3447 {
3448 // rotation
3449 z2 = kcl->GetZ();
3450 x2= xx2*cs-y2*sn*dsec;
3451 y2=+xx2*sn*dsec+y2*cs;
3452 }
3453
3454 x[0] = y1;
3455 x[1] = z1;
3456 x[2] = x0;
3457 x[3] = dip;
3458 x[4] = c0;
3459 //
3460 //
3461 // do we have cluster at the middle ?
3462 Double_t ym,zm;
3463 GetProlongation(x1,xm,x,ym,zm);
3464 UInt_t dummy;
3465 AliTPCclusterMI * cm=0;
3466 if (TMath::Abs(ym)-ymaxm<0){
3467 cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3468 if ((!cm) || (cm->IsUsed(10))) {
3469 continue;
3470 }
3471 }
3472 else{
3473 // rotate y1 to system 0
3474 // get state vector in rotated system
3475 Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
3476 Double_t xr2 = x0*cs+yr1*sn*dsec;
3477 Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3478 //
3479 GetProlongation(xx2,xm,xr,ym,zm);
3480 if (TMath::Abs(ym)-ymaxm<0){
3481 cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3482 if ((!cm) || (cm->IsUsed(10))) {
3483 continue;
3484 }
3485 }
3486 }
3487
3488
2a97785a 3489 // Double_t dym = 0;
3490 // Double_t dzm = 0;
3491 // if (cm){
3492 // dym = ym - cm->GetY();
3493 // dzm = zm - cm->GetZ();
3494 // }
91162307 3495 nin2++;
3496
3497
3498 //
3499 //
3500 Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
3501 Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
3502 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
3503 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3504 //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
3505
b67e07dc 3506 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3507 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3508 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3509 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3510 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3511 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
91162307 3512
b67e07dc 3513 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3514 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3515 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3516 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
91162307 3517
1c53abe2 3518 c[0]=sy1;
3519 c[1]=0.; c[2]=sz1;
3520 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3521 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3522 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3523 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3524 c[13]=f30*sy1*f40+f32*sy2*f42;
3525 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
91162307 3526
d757548f 3527 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
91162307 3528
1c53abe2 3529 UInt_t index=kr1.GetIndex(is);
ddfbc51a 3530 if (seed) {MarkSeedFree(seed); seed = 0;}
3531 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, ns*alpha+shift, x, c, index);
3532 seed->SetPoolID(fLastSeedID);
d757548f 3533 track->SetIsSeeding(kTRUE);
3534 track->SetSeed1(i1);
3535 track->SetSeed2(i2);
3536 track->SetSeedType(3);
c9427e08 3537
91162307 3538
3539 //if (dsec==0) {
d757548f 3540 FollowProlongation(*track, (i1+i2)/2,1);
91162307 3541 Int_t foundable,found,shared;
d757548f 3542 track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
3543 if ((found<0.55*foundable) || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
ddfbc51a 3544 MarkSeedFree(seed); seed = 0;
91162307 3545 continue;
3546 }
3547 //}
3548
3549 nin++;
d757548f 3550 FollowProlongation(*track, i2,1);
91162307 3551
3552
3553 //Int_t rc = 1;
d757548f 3554 track->SetBConstrain(1);
91162307 3555 // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
d757548f 3556 track->SetLastPoint(i1); // first cluster in track position
3557 track->SetFirstPoint(track->GetLastPoint());
91162307 3558
d757548f 3559 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3560 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3561 track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
ddfbc51a 3562 MarkSeedFree(seed); seed = 0;
c9427e08 3563 continue;
3564 }
91162307 3565 nout1++;
3566 // Z VERTEX CONDITION
c274e255 3567 Double_t zv, bz=GetBz();
d757548f 3568 if ( !track->GetZAt(0.,bz,zv) ) continue;
91162307 3569 if (TMath::Abs(zv-z3)>cuts[2]) {
d757548f 3570 FollowProlongation(*track, TMath::Max(i2-20,0));
3571 if ( !track->GetZAt(0.,bz,zv) ) continue;
91162307 3572 if (TMath::Abs(zv-z3)>cuts[2]){
d757548f 3573 FollowProlongation(*track, TMath::Max(i2-40,0));
3574 if ( !track->GetZAt(0.,bz,zv) ) continue;
3575 if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
91162307 3576 // make seed without constrain
d757548f 3577 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
91162307 3578 FollowProlongation(*track2, i2,1);
b9671574 3579 track2->SetBConstrain(kFALSE);
3580 track2->SetSeedType(1);
d757548f 3581 arr->AddLast(track2);
ddfbc51a 3582 MarkSeedFree( seed ); seed = 0;
91162307 3583 continue;
3584 }
3585 else{
ddfbc51a 3586 MarkSeedFree( seed ); seed = 0;
91162307 3587 continue;
d757548f 3588
91162307 3589 }
3590 }
c9427e08 3591 }
316c6cd9 3592
d757548f 3593 track->SetSeedType(0);
f06a1ff6 3594 arr->AddLast(track); // note, track is seed, don't free the seed
ddfbc51a 3595 seed = new( NextFreeSeed() ) AliTPCseed;
3596 seed->SetPoolID(fLastSeedID);
91162307 3597 nout2++;
3598 // don't consider other combinations
d757548f 3599 if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
91162307 3600 break;
1c53abe2 3601 }
3602 }
3603 }
6bdc18d6 3604 if (fDebug>3){
3605 Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
91162307 3606 }
ddfbc51a 3607 if (seed) MarkSeedFree( seed );
1c53abe2 3608}
3609
1627d1c4 3610
829455ad 3611void AliTPCtracker::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
91162307 3612 Float_t deltay) {
3613
3614
3615
1627d1c4 3616 //-----------------------------------------------------------------
91162307 3617 // This function creates track seeds.
1627d1c4 3618 //-----------------------------------------------------------------
91162307 3619 // cuts[0] - fP4 cut
3620 // cuts[1] - tan(phi) cut
3621 // cuts[2] - zvertex cut
3622 // cuts[3] - fP3 cut
3623
3624
3625 Int_t nin0 = 0;
3626 Int_t nin1 = 0;
3627 Int_t nin2 = 0;
3628 Int_t nin = 0;
3629 Int_t nout1 = 0;
3630 Int_t nout2 = 0;
3631 Int_t nout3 =0;
3632 Double_t x[5], c[15];
3633 //
3634 // make temporary seed
ddfbc51a 3635 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
3636 seed->SetPoolID(fLastSeedID);
1627d1c4 3637 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3638 // Double_t cs=cos(alpha), sn=sin(alpha);
91162307 3639 //
3640 //
1627d1c4 3641
91162307 3642 // first 3 padrows
3643 Double_t x1 = GetXrow(i1-1);
bd26fa83 3644 const AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
b9671574 3645 Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
91162307 3646 //
3647 Double_t x1p = GetXrow(i1);
bd26fa83 3648 const AliTPCtrackerRow& kr1p=GetRow(sec,i1);
91162307 3649 //
3650 Double_t x1m = GetXrow(i1-2);
bd26fa83 3651 const AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
1627d1c4 3652
91162307 3653 //
3654 //last 3 padrow for seeding
bd26fa83 3655 AliTPCtrackerRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
91162307 3656 Double_t x3 = GetXrow(i1-7);
3657 // Double_t y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;
3658 //
bd26fa83 3659 AliTPCtrackerRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
91162307 3660 Double_t x3p = GetXrow(i1-6);
3661 //
bd26fa83 3662 AliTPCtrackerRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
91162307 3663 Double_t x3m = GetXrow(i1-8);
1627d1c4 3664
91162307 3665 //
3666 //
3667 // middle padrow
3668 Int_t im = i1-4; //middle pad row index
3669 Double_t xm = GetXrow(im); // radius of middle pad-row
bd26fa83 3670 const AliTPCtrackerRow& krm=GetRow(sec,im); //middle pad -row
91162307 3671 // Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;
3672 //
3673 //
3674 Double_t deltax = x1-x3;
3675 Double_t dymax = deltax*cuts[1];
3676 Double_t dzmax = deltax*cuts[3];
3677 //
3678 // loop over clusters
3679 for (Int_t is=0; is < kr1; is++) {
1627d1c4 3680 //
91162307 3681 if (kr1[is]->IsUsed(10)) continue;
3682 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
1627d1c4 3683 //
91162307 3684 if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3685 //
3686 Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
3687 Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
3688 //
3689 Double_t y3, z3;
1627d1c4 3690 //
1627d1c4 3691 //
91162307 3692 UInt_t index;
3693 for (Int_t js=index1; js < index2; js++) {
3694 const AliTPCclusterMI *kcl = kr3[js];
3695 if (kcl->IsUsed(10)) continue;
3696 y3 = kcl->GetY();
3697 // apply angular cuts
3698 if (TMath::Abs(y1-y3)>dymax) continue;
97d77e7a 3699 //x3 = x3;
91162307 3700 z3 = kcl->GetZ();
3701 if (TMath::Abs(z1-z3)>dzmax) continue;
3702 //
3703 Double_t angley = (y1-y3)/(x1-x3);
3704 Double_t anglez = (z1-z3)/(x1-x3);
3705 //
3706 Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
3707 Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
3708 //
3709 Double_t yyym = angley*(xm-x1)+y1;
3710 Double_t zzzm = anglez*(xm-x1)+z1;
3711
3712 const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
3713 if (!kcm) continue;
3714 if (kcm->IsUsed(10)) continue;
3715
3716 erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
3717 errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
3718 //
3719 //
3720 //
3721 Int_t used =0;
3722 Int_t found =0;
3723 //
3724 // look around first
3725 const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
3726 anglez*(x1m-x1)+z1,
3727 erry,errz,index);
3728 //
3729 if (kc1m){
3730 found++;
3731 if (kc1m->IsUsed(10)) used++;
1627d1c4 3732 }
91162307 3733 const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
3734 anglez*(x1p-x1)+z1,
3735 erry,errz,index);
1627d1c4 3736 //
91162307 3737 if (kc1p){
3738 found++;
3739 if (kc1p->IsUsed(10)) used++;
1627d1c4 3740 }
91162307 3741 if (used>1) continue;
3742 if (found<1) continue;
1627d1c4 3743
91162307 3744 //
3745 // look around last
3746 const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
3747 anglez*(x3m-x3)+z3,
3748 erry,errz,index);
3749 //
3750 if (kc3m){
3751 found++;
3752 if (kc3m->IsUsed(10)) used++;
3753 }
3754 else
3755 continue;
3756 const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
3757 anglez*(x3p-x3)+z3,
3758 erry,errz,index);
3759 //
3760 if (kc3p){
3761 found++;
3762 if (kc3p->IsUsed(10)) used++;
3763 }
3764 else
3765 continue;
3766 if (used>1) continue;
3767 if (found<3) continue;
3768 //
3769 Double_t x2,y2,z2;
3770 x2 = xm;
3771 y2 = kcm->GetY();
3772 z2 = kcm->GetZ();
3773 //
3774
1627d1c4 3775 x[0]=y1;
3776 x[1]=z1;
b67e07dc 3777 x[4]=F1(x1,y1,x2,y2,x3,y3);
91162307 3778 //if (TMath::Abs(x[4]) >= cuts[0]) continue;
3779 nin0++;
3780 //
b67e07dc 3781 x[2]=F2(x1,y1,x2,y2,x3,y3);
91162307 3782 nin1++;
3783 //
b67e07dc 3784 x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
91162307 3785 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3786 nin2++;
3787 //
3788 //
3789 Double_t sy1=0.1, sz1=0.1;
3790 Double_t sy2=0.1, sz2=0.1;
3791 Double_t sy3=0.1, sy=0.1, sz=0.1;
1627d1c4 3792
b67e07dc 3793 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3794 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3795 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3796 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3797 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3798 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
91162307 3799
b67e07dc 3800 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3801 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3802 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3803 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
1627d1c4 3804
3805 c[0]=sy1;
91162307 3806 c[1]=0.; c[2]=sz1;
1627d1c4 3807 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3808 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3809 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3810 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3811 c[13]=f30*sy1*f40+f32*sy2*f42;
3812 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3813
91162307 3814 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3815
77f88633 3816 index=kr1.GetIndex(is);
ddfbc51a 3817 if (seed) {MarkSeedFree( seed ); seed = 0;}
3818 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, sec*alpha+shift, x, c, index);
3819 seed->SetPoolID(fLastSeedID);
91162307 3820
b9671574 3821 track->SetIsSeeding(kTRUE);
91162307 3822
3823 nin++;
3824 FollowProlongation(*track, i1-7,1);
b9671574 3825 if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
3826 track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
ddfbc51a 3827 MarkSeedFree( seed ); seed = 0;
91162307 3828 continue;
3829 }
3830 nout1++;
3831 nout2++;
3832 //Int_t rc = 1;
3833 FollowProlongation(*track, i2,1);
b9671574 3834 track->SetBConstrain(0);
3835 track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
3836 track->SetFirstPoint(track->GetLastPoint());
91162307 3837
3838 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 3839 track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
3840 track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
ddfbc51a 3841 MarkSeedFree( seed ); seed = 0;
91162307 3842 continue;
3843 }
3844
3845 {
3846 FollowProlongation(*track, TMath::Max(i2-10,0),1);
3847 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
3848 FollowProlongation(*track2, i2,1);
b9671574 3849 track2->SetBConstrain(kFALSE);
3850 track2->SetSeedType(4);
f06a1ff6 3851 arr->AddLast(track2);
ddfbc51a 3852 MarkSeedFree( seed ); seed = 0;
91162307 3853 }
3854
3855
3856 //arr->AddLast(track);
3857 //seed = new AliTPCseed;
3858 nout3++;
3859 }
3860 }
3861
6bdc18d6 3862 if (fDebug>3){
7d85e147 3863 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 3864 }
ddfbc51a 3865 if (seed) MarkSeedFree(seed);
91162307 3866}
3867
3868
3869//_____________________________________________________________________________
829455ad 3870void AliTPCtracker::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
176aff27 3871 Float_t deltay, Bool_t /*bconstrain*/) {
91162307 3872 //-----------------------------------------------------------------
3873 // This function creates track seeds - without vertex constraint
3874 //-----------------------------------------------------------------
3875 // cuts[0] - fP4 cut - not applied
3876 // cuts[1] - tan(phi) cut
3877 // cuts[2] - zvertex cut - not applied
3878 // cuts[3] - fP3 cut
3879 Int_t nin0=0;
3880 Int_t nin1=0;
3881 Int_t nin2=0;
3882 Int_t nin3=0;
3883 // Int_t nin4=0;
3884 //Int_t nin5=0;
3885
3886
3887
3888 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3889 // Double_t cs=cos(alpha), sn=sin(alpha);
3890 Int_t row0 = (i1+i2)/2;
3891 Int_t drow = (i1-i2)/2;
bd26fa83 3892 const AliTPCtrackerRow& kr0=fSectors[sec][row0];
3893 AliTPCtrackerRow * kr=0;
91162307 3894
3895 AliTPCpolyTrack polytrack;
3896 Int_t nclusters=fSectors[sec][row0];
ddfbc51a 3897 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
3898 seed->SetPoolID(fLastSeedID);
91162307 3899
3900 Int_t sumused=0;
3901 Int_t cused=0;
3902 Int_t cnused=0;
3903 for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
3904 Int_t nfound =0;
3905 Int_t nfoundable =0;
3906 for (Int_t iter =1; iter<2; iter++){ //iterations
bd26fa83 3907 const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
3908 const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];
91162307 3909 const AliTPCclusterMI * cl= kr0[is];
3910
3911 if (cl->IsUsed(10)) {
3912 cused++;
3913 }
3914 else{
3915 cnused++;
3916 }
3917 Double_t x = kr0.GetX();
3918 // Initialization of the polytrack
3919 nfound =0;
3920 nfoundable =0;
3921 polytrack.Reset();
3922 //
3923 Double_t y0= cl->GetY();
3924 Double_t z0= cl->GetZ();
3925 Float_t erry = 0;
3926 Float_t errz = 0;
3927
b9671574 3928 Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
91162307 3929 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
3930
3931 erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
3932 errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
3933 polytrack.AddPoint(x,y0,z0,erry, errz);
3934
3935 sumused=0;
3936 if (cl->IsUsed(10)) sumused++;
3937
3938
3939 Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
3940 Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
3941 //
3942 x = krm.GetX();
3943 AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
3944 if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
3945 erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
3946 errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
3947 if (cl1->IsUsed(10)) sumused++;
3948 polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
3949 }
3950 //
3951 x = krp.GetX();
3952 AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
3953 if (cl2) {
3954 erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
3955 errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
3956 if (cl2->IsUsed(10)) sumused++;
3957 polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
3958 }
3959 //
3960 if (sumused>0) continue;
3961 nin0++;
3962 polytrack.UpdateParameters();
3963 // follow polytrack
3964 roadz = 1.2;
3965 roady = 1.2;
3966 //
3967 Double_t yn,zn;
3968 nfoundable = polytrack.GetN();
3969 nfound = nfoundable;
3970 //
3971 for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
3972 Float_t maxdist = 0.8*(1.+3./(ddrow));
3973 for (Int_t delta = -1;delta<=1;delta+=2){
3974 Int_t row = row0+ddrow*delta;
3975 kr = &(fSectors[sec][row]);
3976 Double_t xn = kr->GetX();
77f88633 3977 Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
91162307 3978 polytrack.GetFitPoint(xn,yn,zn);
77f88633 3979 if (TMath::Abs(yn)>ymax1) continue;
91162307 3980 nfoundable++;
3981 AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
3982 if (cln) {
3983 Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
3984 if (dist<maxdist){
3985 /*
3986 erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3987 errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3988 if (cln->IsUsed(10)) {
3989 // printf("used\n");
3990 sumused++;
3991 erry*=2;
3992 errz*=2;
3993 }
3994 */
3995 erry=0.1;
3996 errz=0.1;
3997 polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
3998 nfound++;
3999 }
4000 }
4001 }
4002 if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
4003 polytrack.UpdateParameters();
4004 }
4005 }
4006 if ( (sumused>3) || (sumused>0.5*nfound)) {
4007 //printf("sumused %d\n",sumused);
4008 continue;
4009 }
4010 nin1++;
4011 Double_t dy,dz;
4012 polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
4013 AliTPCpolyTrack track2;
4014
4015 polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
4016 if (track2.GetN()<0.5*nfoundable) continue;
4017 nin2++;
4018
4019 if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
4020 //
4021 // test seed with and without constrain
4022 for (Int_t constrain=0; constrain<=0;constrain++){
4023 // add polytrack candidate
4024
4025 Double_t x[5], c[15];
4026 Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
4027 track2.GetBoundaries(x3,x1);
4028 x2 = (x1+x3)/2.;
4029 track2.GetFitPoint(x1,y1,z1);
4030 track2.GetFitPoint(x2,y2,z2);
4031 track2.GetFitPoint(x3,y3,z3);
4032 //
4033 //is track pointing to the vertex ?
4034 Double_t x0,y0,z0;
4035 x0=0;
4036 polytrack.GetFitPoint(x0,y0,z0);
4037
4038 if (constrain) {
4039 x2 = x3;
4040 y2 = y3;
4041 z2 = z3;
4042
4043 x3 = 0;
4044 y3 = 0;
4045 z3 = 0;
4046 }
4047 x[0]=y1;
4048 x[1]=z1;
b67e07dc 4049 x[4]=F1(x1,y1,x2,y2,x3,y3);
91162307 4050
4051 // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
b67e07dc 4052 x[2]=F2(x1,y1,x2,y2,x3,y3);
91162307 4053
4054 //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
b67e07dc 4055 //x[3]=F3(x1,y1,x2,y2,z1,z2);
4056 x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
91162307 4057 //if (TMath::Abs(x[3]) > cuts[3]) continue;
4058
4059
4060 Double_t sy =0.1, sz =0.1;
4061 Double_t sy1=0.02, sz1=0.02;
4062 Double_t sy2=0.02, sz2=0.02;
4063 Double_t sy3=0.02;
4064
4065 if (constrain){
4066 sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
4067 }
4068
b67e07dc 4069 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
4070 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
4071 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
4072 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
4073 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
4074 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
4075
4076 Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
4077 Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
4078 Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
4079 Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
91162307 4080
4081
4082 c[0]=sy1;
4083 c[1]=0.; c[2]=sz1;
4084 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4085 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4086 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4087 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4088 c[13]=f30*sy1*f40+f32*sy2*f42;
4089 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4090
4091 //Int_t row1 = fSectors->GetRowNumber(x1);
4092 Int_t row1 = GetRowNumber(x1);
4093
4094 UInt_t index=0;
4095 //kr0.GetIndex(is);
ddfbc51a 4096 if (seed) {MarkSeedFree( seed ); seed = 0;}
4097 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1,sec*alpha+shift,x,c,index);
4098 seed->SetPoolID(fLastSeedID);
b9671574 4099 track->SetIsSeeding(kTRUE);
91162307 4100 Int_t rc=FollowProlongation(*track, i2);
b9671574 4101 if (constrain) track->SetBConstrain(1);
91162307 4102 else
b9671574 4103 track->SetBConstrain(0);
4104 track->SetLastPoint(row1+fInnerSec->GetNRows()); // first cluster in track position
4105 track->SetFirstPoint(track->GetLastPoint());
91162307 4106
4107 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 4108 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
4109 track->GetNShared()>0.4*track->GetNumberOfClusters()) {
ddfbc51a 4110 MarkSeedFree( seed ); seed = 0;
91162307 4111 }
4112 else {
f06a1ff6 4113 arr->AddLast(track); // track IS seed, don't free seed
ddfbc51a 4114 seed = new( NextFreeSeed() ) AliTPCseed;
4115 seed->SetPoolID(fLastSeedID);
91162307 4116 }
4117 nin3++;
4118 }
4119 } // if accepted seed
4120 }
6bdc18d6 4121 if (fDebug>3){
4122 Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
91162307 4123 }
ddfbc51a 4124 if (seed) MarkSeedFree( seed );
91162307 4125}
4126
4127
829455ad 4128AliTPCseed *AliTPCtracker::MakeSeed(AliTPCseed *const track, Float_t r0, Float_t r1, Float_t r2)
91162307 4129{
4130 //
4131 //
d26d9159 4132 //reseed using track points
91162307 4133 Int_t p0 = int(r0*track->GetNumberOfClusters()); // point 0
4134 Int_t p1 = int(r1*track->GetNumberOfClusters());
4135 Int_t p2 = int(r2*track->GetNumberOfClusters()); // last point
176aff27 4136 Int_t pp2=0;
91162307 4137 Double_t x0[3],x1[3],x2[3];
89e09524 4138 for (Int_t i=0;i<3;i++){
4139 x0[i]=-1;
4140 x1[i]=-1;
4141 x2[i]=-1;
4142 }
91162307 4143
4144 // find track position at given ratio of the length
89e09524 4145 Int_t sec0=0, sec1=0, sec2=0;
91162307 4146 Int_t index=-1;
4147 Int_t clindex;
4148 for (Int_t i=0;i<160;i++){
b9671574 4149 if (track->GetClusterPointer(i)){
91162307 4150 index++;
4151 AliTPCTrackerPoint *trpoint =track->GetTrackPoint(i);
4152 if ( (index<p0) || x0[0]<0 ){
4153 if (trpoint->GetX()>1){
4154 clindex = track->GetClusterIndex2(i);
bad6eb00 4155 if (clindex >= 0){
91162307 4156 x0[0] = trpoint->GetX();
4157 x0[1] = trpoint->GetY();
4158 x0[2] = trpoint->GetZ();
4159 sec0 = ((clindex&0xff000000)>>24)%18;
4160 }
4161 }
4162 }
4163
4164 if ( (index<p1) &&(trpoint->GetX()>1)){
4165 clindex = track->GetClusterIndex2(i);
bad6eb00 4166 if (clindex >= 0){
91162307 4167 x1[0] = trpoint->GetX();
4168 x1[1] = trpoint->GetY();
4169 x1[2] = trpoint->GetZ();
4170 sec1 = ((clindex&0xff000000)>>24)%18;
4171 }
4172 }
4173 if ( (index<p2) &&(trpoint->GetX()>1)){
4174 clindex = track->GetClusterIndex2(i);
bad6eb00 4175 if (clindex >= 0){
91162307 4176 x2[0] = trpoint->GetX();
4177 x2[1] = trpoint->GetY();
4178 x2[2] = trpoint->GetZ();
4179 sec2 = ((clindex&0xff000000)>>24)%18;
4180 pp2 = i;
4181 }
4182 }
4183 }
4184 }
4185
4186 Double_t alpha, cs,sn, xx2,yy2;
4187 //
4188 alpha = (sec1-sec2)*fSectors->GetAlpha();
4189 cs = TMath::Cos(alpha);
4190 sn = TMath::Sin(alpha);
4191 xx2= x1[0]*cs-x1[1]*sn;
4192 yy2= x1[0]*sn+x1[1]*cs;
4193 x1[0] = xx2;
4194 x1[1] = yy2;
4195 //
4196 alpha = (sec0-sec2)*fSectors->GetAlpha();
4197 cs = TMath::Cos(alpha);
4198 sn = TMath::Sin(alpha);
4199 xx2= x0[0]*cs-x0[1]*sn;
4200 yy2= x0[0]*sn+x0[1]*cs;
4201 x0[0] = xx2;
4202 x0[1] = yy2;
4203 //
4204 //
4205 //
4206 Double_t x[5],c[15];
4207 //
4208 x[0]=x2[1];
4209 x[1]=x2[2];
b67e07dc 4210 x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
91162307 4211 // if (x[4]>1) return 0;
b67e07dc 4212 x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
4213 x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
91162307 4214 //if (TMath::Abs(x[3]) > 2.2) return 0;
4215 //if (TMath::Abs(x[2]) > 1.99) return 0;
4216 //
4217 Double_t sy =0.1, sz =0.1;
4218 //
4219 Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
4220 Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
4221 Double_t sy3=0.01+track->GetSigmaY2();
4222 //
b67e07dc 4223 Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
4224 Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
4225 Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
4226 Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
4227 Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
4228 Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
4229 //
4230 Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
4231 Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
4232 Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
4233 Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
91162307 4234
4235
4236 c[0]=sy1;
4237 c[1]=0.; c[2]=sz1;
4238 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4239 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4240 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4241 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4242 c[13]=f30*sy1*f40+f32*sy2*f42;
4243 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4244
4245 // Int_t row1 = fSectors->GetRowNumber(x2[0]);
ddfbc51a 4246 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4247 seed->SetPoolID(fLastSeedID);
91162307 4248 // Double_t y0,z0,y1,z1, y2,z2;
4249 //seed->GetProlongation(x0[0],y0,z0);
4250 // seed->GetProlongation(x1[0],y1,z1);
4251 //seed->GetProlongation(x2[0],y2,z2);
4252 // seed =0;
b9671574 4253 seed->SetLastPoint(pp2);
4254 seed->SetFirstPoint(pp2);
91162307 4255
4256
4257 return seed;
4258}
4259
d26d9159 4260
829455ad 4261AliTPCseed *AliTPCtracker::ReSeed(const AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
d26d9159 4262{
4263 //
4264 //
4265 //reseed using founded clusters
4266 //
4267 // Find the number of clusters
4268 Int_t nclusters = 0;
4269 for (Int_t irow=0;irow<160;irow++){
4270 if (track->GetClusterIndex(irow)>0) nclusters++;
4271 }
4272 //
4273 Int_t ipos[3];
4274 ipos[0] = TMath::Max(int(r0*nclusters),0); // point 0 cluster
4275 ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1); //
4276 ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1); // last point
4277 //
4278 //
ec26e231 4279 Double_t xyz[3][3]={{0}};
4280 Int_t row[3]={0},sec[3]={0,0,0};
d26d9159 4281 //
4282 // find track row position at given ratio of the length
4283 Int_t index=-1;
4284 for (Int_t irow=0;irow<160;irow++){
4285 if (track->GetClusterIndex2(irow)<0) continue;
4286 index++;
4287 for (Int_t ipoint=0;ipoint<3;ipoint++){
4288 if (index<=ipos[ipoint]) row[ipoint] = irow;
4289 }
4290 }
4291 //
4292 //Get cluster and sector position
4293 for (Int_t ipoint=0;ipoint<3;ipoint++){
4294 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4295 AliTPCclusterMI * cl = GetClusterMI(clindex);
4296 if (cl==0) {
6bdc18d6 4297 //Error("Bug\n");
47966a6d 4298 // AliTPCclusterMI * cl = GetClusterMI(clindex);
d26d9159 4299 return 0;
4300 }
4301 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4302 xyz[ipoint][0] = GetXrow(row[ipoint]);
4303 xyz[ipoint][1] = cl->GetY();
4304 xyz[ipoint][2] = cl->GetZ();
4305 }
4306 //
4307 //
4308 // Calculate seed state vector and covariance matrix
4309
4310 Double_t alpha, cs,sn, xx2,yy2;
4311 //
4312 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4313 cs = TMath::Cos(alpha);
4314 sn = TMath::Sin(alpha);
4315 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4316 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4317 xyz[1][0] = xx2;
4318 xyz[1][1] = yy2;
4319 //
4320 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4321 cs = TMath::Cos(alpha);
4322 sn = TMath::Sin(alpha);
4323 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4324 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4325 xyz[0][0] = xx2;
4326 xyz[0][1] = yy2;
4327 //
4328 //
4329 //
4330 Double_t x[5],c[15];
4331 //
4332 x[0]=xyz[2][1];
4333 x[1]=xyz[2][2];
4334 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4335 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4336 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4337 //
4338 Double_t sy =0.1, sz =0.1;
4339 //
4340 Double_t sy1=0.2, sz1=0.2;
4341 Double_t sy2=0.2, sz2=0.2;
4342 Double_t sy3=0.2;
4343 //
4344 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;
4345 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;
4346 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;
4347 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;
4348 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;
4349 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;
4350 //
4351 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;
4352 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;
4353 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;
4354 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;
4355
4356
4357 c[0]=sy1;
4358 c[1]=0.; c[2]=sz1;
4359 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4360 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4361 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4362 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4363 c[13]=f30*sy1*f40+f32*sy2*f42;
4364 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4365
4366 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
ddfbc51a 4367 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4368 seed->SetPoolID(fLastSeedID);
b9671574 4369 seed->SetLastPoint(row[2]);
4370 seed->SetFirstPoint(row[2]);
d26d9159 4371 return seed;
4372}
4373
eea478d3 4374
829455ad 4375AliTPCseed *AliTPCtracker::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
eea478d3 4376{
4377 //
4378 //
4379 //reseed using founded clusters
4380 //
4381 Double_t xyz[3][3];
4a12af72 4382 Int_t row[3]={0,0,0};
4383 Int_t sec[3]={0,0,0};
eea478d3 4384 //
4385 // forward direction
4386 if (forward){
4387 for (Int_t irow=r0;irow<160;irow++){
4388 if (track->GetClusterIndex(irow)>0){
4389 row[0] = irow;
4390 break;
4391 }
4392 }
4393 for (Int_t irow=160;irow>r0;irow--){
4394 if (track->GetClusterIndex(irow)>0){
4395 row[2] = irow;
4396 break;
4397 }
4398 }
4399 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4400 if (track->GetClusterIndex(irow)>0){
4401 row[1] = irow;
4402 break;
4403 }
4404 }
4405 //
4406 }
4407 if (!forward){
4408 for (Int_t irow=0;irow<r0;irow++){
4409 if (track->GetClusterIndex(irow)>0){
4410 row[0] = irow;
4411 break;
4412 }
4413 }
4414 for (Int_t irow=r0;irow>0;irow--){
4415 if (track->GetClusterIndex(irow)>0){
4416 row[2] = irow;
4417 break;
4418 }
4419 }
4420 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4421 if (track->GetClusterIndex(irow)>0){
4422 row[1] = irow;
4423 break;
4424 }
4425 }
4426 }
4427 //
4428 if ((row[2]-row[0])<20) return 0;
4429 if (row[1]==0) return 0;
4430 //
4431 //
4432 //Get cluster and sector position
4433 for (Int_t ipoint=0;ipoint<3;ipoint++){
4434 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4435 AliTPCclusterMI * cl = GetClusterMI(clindex);
4436 if (cl==0) {
4437 //Error("Bug\n");
4438 // AliTPCclusterMI * cl = GetClusterMI(clindex);
4439 return 0;
4440 }
4441 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4442 xyz[ipoint][0] = GetXrow(row[ipoint]);
4443 AliTPCTrackerPoint * point = track->GetTrackPoint(row[ipoint]);
4444 if (point&&ipoint<2){
4445 //
4446 xyz[ipoint][1] = point->GetY();
4447 xyz[ipoint][2] = point->GetZ();
4448 }
4449 else{
4450 xyz[ipoint][1] = cl->GetY();
4451 xyz[ipoint][2] = cl->GetZ();
4452 }
4453 }
4454 //
4455 //
4456 //
4457 //
4458 // Calculate seed state vector and covariance matrix
4459
4460 Double_t alpha, cs,sn, xx2,yy2;
4461 //
4462 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4463 cs = TMath::Cos(alpha);
4464 sn = TMath::Sin(alpha);
4465 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4466 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4467 xyz[1][0] = xx2;
4468 xyz[1][1] = yy2;
4469 //
4470 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4471 cs = TMath::Cos(alpha);
4472 sn = TMath::Sin(alpha);
4473 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4474 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4475 xyz[0][0] = xx2;
4476 xyz[0][1] = yy2;
4477 //
4478 //
4479 //
4480 Double_t x[5],c[15];
4481 //
4482 x[0]=xyz[2][1];
4483 x[1]=xyz[2][2];
4484 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4485 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4486 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4487 //
4488 Double_t sy =0.1, sz =0.1;
4489 //
4490 Double_t sy1=0.2, sz1=0.2;
4491 Double_t sy2=0.2, sz2=0.2;
4492 Double_t sy3=0.2;
4493 //
4494 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;
4495 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;
4496 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;
4497 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;
4498 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;
4499 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;
4500 //
4501 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;
4502 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;
4503 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;
4504 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;
4505
4506
4507 c[0]=sy1;
4508 c[1]=0.; c[2]=sz1;
4509 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4510 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4511 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4512 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4513 c[13]=f30*sy1*f40+f32*sy2*f42;
4514 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4515
4516 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
ddfbc51a 4517 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4518 seed->SetPoolID(fLastSeedID);
b9671574 4519 seed->SetLastPoint(row[2]);
4520 seed->SetFirstPoint(row[2]);
eea478d3 4521 for (Int_t i=row[0];i<row[2];i++){
b9671574 4522 seed->SetClusterIndex(i, track->GetClusterIndex(i));
eea478d3 4523 }
4524
4525 return seed;
4526}
4527
6d493ea0 4528
4529
829455ad 4530void AliTPCtracker::FindMultiMC(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
6d493ea0 4531{
4532 //
4533 // find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
4534 // USES MC LABELS
4535 // Use AliTPCReconstructor::StreamLevel()>2 if you want to tune parameters - cuts
4536 //
4537 // Two reasons to have multiple find tracks
4538 // 1. Curling tracks can be find more than once
4539 // 2. Splitted tracks
4540 // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
4541 // b.) Edge effect on the sector boundaries
4542 //
4543 //
4544 // Algorithm done in 2 phases - because of CPU consumption
4545 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4546 //
4547 // Algorihm for curling tracks sign:
4548 // 1 phase -makes a very rough fast cuts to minimize combinatorics
4549 // a.) opposite sign
4550 // b.) one of the tracks - not pointing to the primary vertex -
4551 // c.) delta tan(theta)
4552 // d.) delta phi
4553 // 2 phase - calculates DCA between tracks - time consument
4554
4555 //
4556 // fast cuts
4557 //
4558 // General cuts - for splitted tracks and for curling tracks
4559 //
4560 const Float_t kMaxdPhi = 0.2; // maximal distance in phi
4561 //
4562 // Curling tracks cuts
4563 //
4564 //
4565 //
4566 //
4567 Int_t nentries = array->GetEntriesFast();
4568 AliHelix *helixes = new AliHelix[nentries];
4569 Float_t *xm = new Float_t[nentries];
4570 Float_t *dz0 = new Float_t[nentries];
4571 Float_t *dz1 = new Float_t[nentries];
4572 //
4573 //
4574 TStopwatch timer;
4575 timer.Start();
4576 //
4577 // Find track COG in x direction - point with best defined parameters
4578 //
4579 for (Int_t i=0;i<nentries;i++){
4580 AliTPCseed* track = (AliTPCseed*)array->At(i);
4581 if (!track) continue;
4582 track->SetCircular(0);
4583 new (&helixes[i]) AliHelix(*track);
4584 Int_t ncl=0;
4585 xm[i]=0;
4586 Float_t dz[2];
4587 track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
4588 dz0[i]=dz[0];
4589 dz1[i]=dz[1];
4590 for (Int_t icl=0; icl<160; icl++){
4591 AliTPCclusterMI * cl = track->GetClusterPointer(icl);
4592 if (cl) {
4593 xm[i]+=cl->GetX();
4594 ncl++;
4595 }
4596 }
4597 if (ncl>0) xm[i]/=Float_t(ncl);
4598 }
6d493ea0 4599 //
4600 for (Int_t i0=0;i0<nentries;i0++){
4601 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4602 if (!track0) continue;
4603 Float_t xc0 = helixes[i0].GetHelix(6);
4604 Float_t yc0 = helixes[i0].GetHelix(7);
4605 Float_t r0 = helixes[i0].GetHelix(8);
4606 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4607 Float_t fi0 = TMath::ATan2(yc0,xc0);
4608
4609 for (Int_t i1=i0+1;i1<nentries;i1++){
4610 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4611 if (!track1) continue;
4612 Int_t lab0=track0->GetLabel();
4613 Int_t lab1=track1->GetLabel();
4614 if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
4615 //
4616 Float_t xc1 = helixes[i1].GetHelix(6);
4617 Float_t yc1 = helixes[i1].GetHelix(7);
4618 Float_t r1 = helixes[i1].GetHelix(8);
4619 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4620 Float_t fi1 = TMath::ATan2(yc1,xc1);
4621 //
4622 Float_t dfi = fi0-fi1;
4623 //
4624 //
4625 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
4626 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
4627 if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
4628 //
4629 // if short tracks with undefined sign
4630 fi1 = -TMath::ATan2(yc1,-xc1);
4631 dfi = fi0-fi1;
4632 }
4633 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4634
4635 //
4636 // debug stream to tune "fast cuts"
4637 //
4638 Double_t dist[3]; // distance at X
4639 Double_t mdist[3]={0,0,0}; // mean distance X+-40cm
4640 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
4641 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4642 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
4643 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4644 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
4645 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4646 for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
4647
4648 Float_t sum =0;
4649 Float_t sums=0;
4650 for (Int_t icl=0; icl<160; icl++){
4651 AliTPCclusterMI * cl0 = track0->GetClusterPointer(icl);
4652 AliTPCclusterMI * cl1 = track1->GetClusterPointer(icl);
4653 if (cl0&&cl1) {
4654 sum++;
4655 if (cl0==cl1) sums++;
4656 }
4657 }
4658 //
16299eac 4659 if (AliTPCReconstructor::StreamLevel()>5) {
b194b32c 4660 TTreeSRedirector &cstream = *fDebugStreamer;
6d493ea0 4661 cstream<<"Multi"<<
4662 "iter="<<iter<<
4663 "lab0="<<lab0<<
4664 "lab1="<<lab1<<
4665 "Tr0.="<<track0<< // seed0
4666 "Tr1.="<<track1<< // seed1
4667 "h0.="<<&helixes[i0]<<
4668 "h1.="<<&helixes[i1]<<
4669 //
4670 "sum="<<sum<< //the sum of rows with cl in both
4671 "sums="<<sums<< //the sum of shared clusters
4672 "xm0="<<xm[i0]<< // the center of track
4673 "xm1="<<xm[i1]<< // the x center of track
4674 // General cut variables
4675 "dfi="<<dfi<< // distance in fi angle
4676 "dtheta="<<dtheta<< // distance int theta angle
4677 //
4678 "dz00="<<dz0[i0]<<
4679 "dz01="<<dz0[i1]<<
4680 "dz10="<<dz1[i1]<<
4681 "dz11="<<dz1[i1]<<
4682 "dist0="<<dist[0]<< //distance x
4683 "dist1="<<dist[1]<< //distance y
4684 "dist2="<<dist[2]<< //distance z
4685 "mdist0="<<mdist[0]<< //distance x
4686 "mdist1="<<mdist[1]<< //distance y
4687 "mdist2="<<mdist[2]<< //distance z
4688 //
4689 "r0="<<r0<<
4690 "rc0="<<rc0<<
4691 "fi0="<<fi0<<
4692 "fi1="<<fi1<<
4693 "r1="<<r1<<
4694 "rc1="<<rc1<<
4695 "\n";
b194b32c 4696 }
6d493ea0 4697 }
4698 }
4699 delete [] helixes;
4700 delete [] xm;
ec26e231 4701 delete [] dz0;
4702 delete [] dz1;
6d493ea0 4703 if (AliTPCReconstructor::StreamLevel()>1) {
4704 AliInfo("Time for curling tracks removal DEBUGGING MC");
4705 timer.Print();
4706 }
4707}
4708
4709
1af5da7e 4710
829455ad 4711void AliTPCtracker::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t /*iter*/){
6d493ea0 4712 //
6fbe1e5c 4713 // Find Splitted tracks and remove the one with worst quality
4714 // Corresponding debug streamer to tune selections - "Splitted2"
4715 // Algorithm:
4716 // 0. Sort tracks according quility
4717 // 1. Propagate the tracks to the reference radius
4718 // 2. Double_t loop to select close tracks (only to speed up process)
4719 // 3. Calculate cluster overlap ratio - and remove the track if bigger than a threshold
4720 // 4. Delete temporary parameters
4721 //
4722 const Double_t xref=GetXrow(63); // reference radius -IROC/OROC boundary
4723 // rough cuts
4724 const Double_t kCutP1=10; // delta Z cut 10 cm
4725 const Double_t kCutP2=0.15; // delta snp(fi) cut 0.15
4726 const Double_t kCutP3=0.15; // delta tgl(theta) cut 0.15
4727 const Double_t kCutAlpha=0.15; // delta alpha cut
4728 Int_t firstpoint = 0;
4729 Int_t lastpoint = 160;
6d493ea0 4730 //
4731 Int_t nentries = array->GetEntriesFast();
6fbe1e5c 4732 AliExternalTrackParam *params = new AliExternalTrackParam[nentries];
6d493ea0 4733 //
4734 //
4735 TStopwatch timer;
4736 timer.Start();
4737 //
6fbe1e5c 4738 //0. Sort tracks according quality
4739 //1. Propagate the ext. param to reference radius
6d493ea0 4740 Int_t nseed = array->GetEntriesFast();
6e23caff 4741 if (nseed<=0) return;
6d493ea0 4742 Float_t * quality = new Float_t[nseed];
4743 Int_t * indexes = new Int_t[nseed];
4744 for (Int_t i=0; i<nseed; i++) {
4745 AliTPCseed *pt=(AliTPCseed*)array->UncheckedAt(i);
4746 if (!pt){
4747 quality[i]=-1;
4748 continue;
4749 }
4750 pt->UpdatePoints(); //select first last max dens points
4751 Float_t * points = pt->GetPoints();
4752 if (points[3]<0.8) quality[i] =-1;
4753 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
1af5da7e 4754 //prefer high momenta tracks if overlaps
4755 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
6fbe1e5c 4756 params[i]=(*pt);
4757 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),5.,kTRUE);
4758 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),1.,kTRUE);
6d493ea0 4759 }
4760 TMath::Sort(nseed,quality,indexes);
6d493ea0 4761 //
6fbe1e5c 4762 // 3. Loop over pair of tracks
4763 //
4764 for (Int_t i0=0; i0<nseed; i0++) {
4765 Int_t index0=indexes[i0];
4766 if (!(array->UncheckedAt(index0))) continue;
4767 AliTPCseed *s1 = (AliTPCseed*)array->UncheckedAt(index0);
4768 if (!s1->IsActive()) continue;
4769 AliExternalTrackParam &par0=params[index0];
4770 for (Int_t i1=i0+1; i1<nseed; i1++) {
4771 Int_t index1=indexes[i1];
4772 if (!(array->UncheckedAt(index1))) continue;
4773 AliTPCseed *s2 = (AliTPCseed*)array->UncheckedAt(index1);
4774 if (!s2->IsActive()) continue;
4775 if (s2->GetKinkIndexes()[0]!=0)
4776 if (s2->GetKinkIndexes()[0] == -s1->GetKinkIndexes()[0]) continue;
4777 AliExternalTrackParam &par1=params[index1];
4778 if (TMath::Abs(par0.GetParameter()[3]-par1.GetParameter()[3])>kCutP3) continue;
4779 if (TMath::Abs(par0.GetParameter()[1]-par1.GetParameter()[1])>kCutP1) continue;
4780 if (TMath::Abs(par0.GetParameter()[2]-par1.GetParameter()[2])>kCutP2) continue;
4781 Double_t dAlpha= TMath::Abs(par0.GetAlpha()-par1.GetAlpha());
4782 if (dAlpha>TMath::Pi()) dAlpha-=TMath::Pi();
4783 if (TMath::Abs(dAlpha)>kCutAlpha) continue;
6d493ea0 4784 //
6fbe1e5c 4785 Int_t sumShared=0;
4786 Int_t nall0=0;
4787 Int_t nall1=0;
4788 Int_t firstShared=lastpoint, lastShared=firstpoint;
4789 Int_t firstRow=lastpoint, lastRow=firstpoint;
6d493ea0 4790 //
6fbe1e5c 4791 for (Int_t i=firstpoint;i<lastpoint;i++){
4792 if (s1->GetClusterIndex2(i)>0) nall0++;
4793 if (s2->GetClusterIndex2(i)>0) nall1++;
4794 if (s1->GetClusterIndex2(i)>0 && s2->GetClusterIndex2(i)>0) {
4795 if (i<firstRow) firstRow=i;
4796 if (i>lastRow) lastRow=i;
4797 }
4798 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
4799 if (i<firstShared) firstShared=i;
4800 if (i>lastShared) lastShared=i;
4801 sumShared++;
4802 }
4803 }
4804 Double_t ratio0 = Float_t(sumShared)/Float_t(TMath::Min(nall0+1,nall1+1));
4805 Double_t ratio1 = Float_t(sumShared)/Float_t(TMath::Max(nall0+1,nall1+1));
4806
16299eac 4807 if( AliTPCReconstructor::StreamLevel()>1){
6fbe1e5c 4808 TTreeSRedirector &cstream = *fDebugStreamer;
4809 Int_t n0=s1->GetNumberOfClusters();
4810 Int_t n1=s2->GetNumberOfClusters();
4811 Int_t n0F=s1->GetNFoundable();
4812 Int_t n1F=s2->GetNFoundable();
4813 Int_t lab0=s1->GetLabel();
4814 Int_t lab1=s2->GetLabel();
4815
4816 cstream<<"Splitted2"<<
4817 "iter="<<fIteration<<
4818 "lab0="<<lab0<< // MC label if exist
4819 "lab1="<<lab1<< // MC label if exist
4820 "index0="<<index0<<
4821 "index1="<<index1<<
4822 "ratio0="<<ratio0<< // shared ratio
4823 "ratio1="<<ratio1<< // shared ratio
4824 "p0.="<<&par0<< // track parameters
4825 "p1.="<<&par1<<
4826 "s0.="<<s1<< // full seed
4827 "s1.="<<s2<<
4828 "n0="<<n0<< // number of clusters track 0
4829 "n1="<<n1<< // number of clusters track 1
4830 "nall0="<<nall0<< // number of clusters track 0
4831 "nall1="<<nall1<< // number of clusters track 1
4832 "n0F="<<n0F<< // number of findable
4833 "n1F="<<n1F<< // number of findable
4834 "shared="<<sumShared<< // number of shared clusters
4835 "firstS="<<firstShared<< // first and the last shared row
4836 "lastS="<<lastShared<<
4837 "firstRow="<<firstRow<< // first and the last row with cluster
4838 "lastRow="<<lastRow<< //
4839 "\n";
6d493ea0 4840 }
6d493ea0 4841 //
6fbe1e5c 4842 // remove track with lower quality
6d493ea0 4843 //
6fbe1e5c 4844 if (ratio0>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(0) ||
4845 ratio1>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(1)){
4846 //
4847 //
4848 //
ddfbc51a 4849 MarkSeedFree( array->RemoveAt(index1) );
44adbd4b 4850 }
6d493ea0 4851 }
6fbe1e5c 4852 }
4853 //
4854 // 4. Delete temporary array
4855 //
4856 delete [] params;
6e23caff 4857 delete [] quality;
4858 delete [] indexes;
4859
6d493ea0 4860}
4861
4862
4863
829455ad 4864void AliTPCtracker::FindCurling(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
6d493ea0 4865{
4866 //
4867 // find Curling tracks
4868 // Use AliTPCReconstructor::StreamLevel()>1 if you want to tune parameters - cuts
4869 //
4870 //
4871 // Algorithm done in 2 phases - because of CPU consumption
4872 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4873 // see detal in MC part what can be used to cut
4874 //
4875 //
4876 //
4877 const Float_t kMaxC = 400; // maximal curvature to of the track
4878 const Float_t kMaxdTheta = 0.15; // maximal distance in theta
4879 const Float_t kMaxdPhi = 0.15; // maximal distance in phi
4880 const Float_t kPtRatio = 0.3; // ratio between pt
4881 const Float_t kMinDCAR = 2.; // distance to the primary vertex in r - see cpipe cut
4882
4883 //
4884 // Curling tracks cuts
4885 //
4886 //
4887 const Float_t kMaxDeltaRMax = 40; // distance in outer radius
4888 const Float_t kMaxDeltaRMin = 5.; // distance in lower radius - see cpipe cut
4889 const Float_t kMinAngle = 2.9; // angle between tracks
4890 const Float_t kMaxDist = 5; // biggest distance
4891 //
4892 // The cuts can be tuned using the "MC information stored in Multi tree ==> see FindMultiMC
4893 /*
4894 Fast cuts:
4895 TCut csign("csign","Tr0.fP[4]*Tr1.fP[4]<0"); //opposite sign
4896 TCut cmax("cmax","abs(Tr0.GetC())>1/400");
4897 TCut cda("cda","sqrt(dtheta^2+dfi^2)<0.15");
4898 TCut ccratio("ccratio","abs((Tr0.fP[4]+Tr1.fP[4])/(abs(Tr0.fP[4])+abs(Tr1.fP[4])))<0.3");
4899 TCut cpipe("cpipe", "min(abs(r0-rc0),abs(r1-rc1))>5");
4900 //
4901 TCut cdrmax("cdrmax","abs(abs(rc0+r0)-abs(rc1+r1))<40")
4902 TCut cdrmin("cdrmin","abs(abs(rc0+r0)-abs(rc1+r1))<10")
4903 //
4904 Multi->Draw("dfi","iter==0"+csign+cmax+cda+ccratio); ~94% of curling tracks fulfill
4905 Multi->Draw("min(abs(r0-rc0),abs(r1-rc1))","iter==0&&abs(lab1)==abs(lab0)"+csign+cmax+cda+ccratio+cpipe+cdrmin+cdrmax); //80%
4906 //
4907 Curling2->Draw("dfi","iter==0&&abs(lab0)==abs(lab1)"+csign+cmax+cdtheta+cdfi+ccratio)
4908
4909 */
4910 //
4911 //
4912 //
4913 Int_t nentries = array->GetEntriesFast();
4914 AliHelix *helixes = new AliHelix[nentries];
4915 for (Int_t i=0;i<nentries;i++){
4916 AliTPCseed* track = (AliTPCseed*)array->At(i);
4917 if (!track) continue;
4918 track->SetCircular(0);
4919 new (&helixes[i]) AliHelix(*track);
4920 }
4921 //
4922 //
4923 TStopwatch timer;
4924 timer.Start();
ec26e231 4925 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
4926
6d493ea0 4927 //
4928 // Find tracks
4929 //
6d493ea0 4930 //
4931 for (Int_t i0=0;i0<nentries;i0++){
4932 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4933 if (!track0) continue;
4934 if (TMath::Abs(track0->GetC())<1/kMaxC) continue;
4935 Float_t xc0 = helixes[i0].GetHelix(6);
4936 Float_t yc0 = helixes[i0].GetHelix(7);
4937 Float_t r0 = helixes[i0].GetHelix(8);
4938 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4939 Float_t fi0 = TMath::ATan2(yc0,xc0);
4940
4941 for (Int_t i1=i0+1;i1<nentries;i1++){
4942 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4943 if (!track1) continue;
4944 if (TMath::Abs(track1->GetC())<1/kMaxC) continue;
4945 Float_t xc1 = helixes[i1].GetHelix(6);
4946 Float_t yc1 = helixes[i1].GetHelix(7);
4947 Float_t r1 = helixes[i1].GetHelix(8);
4948 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4949 Float_t fi1 = TMath::ATan2(yc1,xc1);
4950 //
4951 Float_t dfi = fi0-fi1;
4952 //
4953 //
4954 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
4955 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
4956 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4957 //
4958 //
4959 // FIRST fast cuts
4960 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue; // not constrained
4961 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue; // not the same sign
4962 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>kMaxdTheta) continue; //distance in the Theta
4963 if ( TMath::Abs(dfi)>kMaxdPhi) continue; //distance in phi
4964 if ( TMath::Sqrt(dfi*dfi+dtheta*dtheta)>kMaxdPhi) continue; //common angular offset
4965 //
4966 Float_t pt0 = track0->GetSignedPt();
4967 Float_t pt1 = track1->GetSignedPt();
4968 if ((TMath::Abs(pt0+pt1)/(TMath::Abs(pt0)+TMath::Abs(pt1)))>kPtRatio) continue;
4969 if ((iter==1) && TMath::Abs(TMath::Abs(rc0+r0)-TMath::Abs(rc1+r1))>kMaxDeltaRMax) continue;
4970 if ((iter!=1) &&TMath::Abs(TMath::Abs(rc0-r0)-TMath::Abs(rc1-r1))>kMaxDeltaRMin) continue;
4971 if (TMath::Min(TMath::Abs(rc0-r0),TMath::Abs(rc1-r1))<kMinDCAR) continue;
4972 //
4973 //
4974 // Now find closest approach
4975 //
4976 //
4977 //
4978 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4979 if (npoints==0) continue;
4980 helixes[i0].GetClosestPhases(helixes[i1], phase);
4981 //
4982 Double_t xyz0[3];
4983 Double_t xyz1[3];
4984 Double_t hangles[3];
4985 helixes[i0].Evaluate(phase[0][0],xyz0);
4986 helixes[i1].Evaluate(phase[0][1],xyz1);
4987
4988 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
4989 Double_t deltah[2],deltabest;
4990 if (TMath::Abs(hangles[2])<kMinAngle) continue;
4991
4992 if (npoints>0){
4993 Int_t ibest=0;
4994 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
4995 if (npoints==2){
4996 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
4997 if (deltah[1]<deltah[0]) ibest=1;
4998 }
4999 deltabest = TMath::Sqrt(deltah[ibest]);
5000 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5001 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5002 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5003 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5004 //
5005 if (deltabest>kMaxDist) continue;
5006 // if (mindcar+mindcaz<40 && (TMath::Abs(hangles[2])<kMinAngle ||deltabest>3)) continue;
5007 Bool_t sign =kFALSE;
5008 if (hangles[2]>kMinAngle) sign =kTRUE;
5009 //
5010 if (sign){
5011 // circular[i0] = kTRUE;
5012 // circular[i1] = kTRUE;
5013 if (track0->OneOverPt()<track1->OneOverPt()){
5014 track0->SetCircular(track0->GetCircular()+1);
5015 track1->SetCircular(track1->GetCircular()+2);
5016 }
5017 else{
5018 track1->SetCircular(track1->GetCircular()+1);
5019 track0->SetCircular(track0->GetCircular()+2);
5020 }
5021 }
16299eac 5022 if (AliTPCReconstructor::StreamLevel()>2){
6d493ea0 5023 //
5024 //debug stream to tune "fine" cuts
5025 Int_t lab0=track0->GetLabel();
5026 Int_t lab1=track1->GetLabel();
b194b32c 5027 TTreeSRedirector &cstream = *fDebugStreamer;
6d493ea0 5028 cstream<<"Curling2"<<
5029 "iter="<<iter<<
5030 "lab0="<<lab0<<
5031 "lab1="<<lab1<<
5032 "Tr0.="<<track0<<
5033 "Tr1.="<<track1<<
5034 //
5035 "r0="<<r0<<
5036 "rc0="<<rc0<<
5037 "fi0="<<fi0<<
5038 "r1="<<r1<<
5039 "rc1="<<rc1<<
5040 "fi1="<<fi1<<
5041 "dfi="<<dfi<<
5042 "dtheta="<<dtheta<<
5043 //
5044 "npoints="<<npoints<<
5045 "hangles0="<<hangles[0]<<
5046 "hangles1="<<hangles[1]<<
5047 "hangles2="<<hangles[2]<<
5048 "xyz0="<<xyz0[2]<<
5049 "xyzz1="<<xyz1[2]<<
5050 "radius="<<radiusbest<<
5051 "deltabest="<<deltabest<<
5052 "phase0="<<phase[ibest][0]<<
5053 "phase1="<<phase[ibest][1]<<
5054 "\n";
5055
5056 }
5057 }
5058 }
5059 }
5060 delete [] helixes;
5061 if (AliTPCReconstructor::StreamLevel()>1) {
5062 AliInfo("Time for curling tracks removal");
5063 timer.Print();
5064 }
5065}
5066
5067
829455ad 5068void AliTPCtracker::FindKinks(TObjArray * array, AliESDEvent *esd)
51ad6848 5069{
5070 //
5071 // find kinks
5072 //
5073 //
f06a1ff6 5074 // RS something is wrong in this routine: not all seeds are assigned to daughters and mothers array, but they all are queried
5075 // to check later
ddfbc51a 5076
5077 TObjArray *kinks= new TObjArray(10000);
81e97e0d 5078 // TObjArray *v0s= new TObjArray(10000);
51ad6848 5079 Int_t nentries = array->GetEntriesFast();
ddfbc51a 5080 AliHelix *helixes = new AliHelix[nentries];
5081 Int_t *sign = new Int_t[nentries];
5082 Int_t *nclusters = new Int_t[nentries];
5083 Float_t *alpha = new Float_t[nentries];
5084 AliKink *kink = new AliKink();
5085 Int_t * usage = new Int_t[nentries];
5086 Float_t *zm = new Float_t[nentries];
5087 Float_t *z0 = new Float_t[nentries];
5088 Float_t *fim = new Float_t[nentries];
5089 Float_t *shared = new Float_t[nentries];
5090 Bool_t *circular = new Bool_t[nentries];
5091 Float_t *dca = new Float_t[nentries];
81e97e0d 5092 //const AliESDVertex * primvertex = esd->GetVertex();
eea478d3 5093 //
5094 // nentries = array->GetEntriesFast();
ddfbc51a 5095 //
5096
51ad6848 5097 //
5098 //
5099 for (Int_t i=0;i<nentries;i++){
5100 sign[i]=0;
5101 usage[i]=0;
5102 AliTPCseed* track = (AliTPCseed*)array->At(i);
5103 if (!track) continue;
b9671574 5104 track->SetCircular(0);
eea478d3 5105 shared[i] = kFALSE;
51ad6848 5106 track->UpdatePoints();
5107 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
51ad6848 5108 }
eea478d3 5109 nclusters[i]=track->GetNumberOfClusters();
5110 alpha[i] = track->GetAlpha();
5111 new (&helixes[i]) AliHelix(*track);
5112 Double_t xyz[3];
5113 helixes[i].Evaluate(0,xyz);
5114 sign[i] = (track->GetC()>0) ? -1:1;
5115 Double_t x,y,z;
5116 x=160;
5117 if (track->GetProlongation(x,y,z)){
5118 zm[i] = z;
5119 fim[i] = alpha[i]+TMath::ATan2(y,x);
5120 }
5121 else{
5122 zm[i] = track->GetZ();
5123 fim[i] = alpha[i];
5124 }
5125 z0[i]=1000;
5126 circular[i]= kFALSE;
81e97e0d 5127 if (track->GetProlongation(0,y,z)) z0[i] = z;
5128 dca[i] = track->GetD(0,0);
51ad6848 5129 }
5130 //
5131 //
5132 TStopwatch timer;
5133 timer.Start();
5134 Int_t ncandidates =0;
5135 Int_t nall =0;
5136 Int_t ntracks=0;
ec26e231 5137 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
eea478d3 5138
5139 //
5140 // Find circling track
eea478d3 5141 //
5142 for (Int_t i0=0;i0<nentries;i0++){
5143 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5144 if (!track0) continue;
b9671574 5145 if (track0->GetNumberOfClusters()<40) continue;
6c94f330 5146 if (TMath::Abs(1./track0->GetC())>200) continue;
eea478d3 5147 for (Int_t i1=i0+1;i1<nentries;i1++){
5148 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5149 if (!track1) continue;
b9671574 5150 if (track1->GetNumberOfClusters()<40) continue;
6c94f330 5151 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
b9671574 5152 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
6c94f330 5153 if (TMath::Abs(1./track1->GetC())>200) continue;
8467b758 5154 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
6c94f330 5155 if (track1->GetTgl()*track0->GetTgl()>0) continue;
1b36647b 5156 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
8467b758 5157 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
5158 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
eea478d3 5159 //
81e97e0d 5160 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
5161 if (mindcar<5) continue;
5162 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
5163 if (mindcaz<5) continue;
5164 if (mindcar+mindcaz<20) continue;
5165 //
5166 //
eea478d3 5167 Float_t xc0 = helixes[i0].GetHelix(6);
5168 Float_t yc0 = helixes[i0].GetHelix(7);
5169 Float_t r0 = helixes[i0].GetHelix(8);
5170 Float_t xc1 = helixes[i1].GetHelix(6);
5171 Float_t yc1 = helixes[i1].GetHelix(7);
5172 Float_t r1 = helixes[i1].GetHelix(8);
5173
5174 Float_t rmean = (r0+r1)*0.5;
5175 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
81e97e0d 5176 //if (delta>30) continue;
eea478d3 5177 if (delta>rmean*0.25) continue;
5178 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
5179 //
5180 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5181 if (npoints==0) continue;
5182 helixes[i0].GetClosestPhases(helixes[i1], phase);
5183 //
5184 Double_t xyz0[3];
5185 Double_t xyz1[3];
5186 Double_t hangles[3];
5187 helixes[i0].Evaluate(phase[0][0],xyz0);
5188 helixes[i1].Evaluate(phase[0][1],xyz1);
5189
5190 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5191 Double_t deltah[2],deltabest;
5192 if (hangles[2]<2.8) continue;
eea478d3 5193 if (npoints>0){
5194 Int_t ibest=0;
81e97e0d 5195 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
eea478d3 5196 if (npoints==2){
81e97e0d 5197 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
eea478d3 5198 if (deltah[1]<deltah[0]) ibest=1;
5199 }
5200 deltabest = TMath::Sqrt(deltah[ibest]);
5201 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5202 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5203 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
81e97e0d 5204 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
eea478d3 5205 //
81e97e0d 5206 if (deltabest>6) continue;
5207 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
77f88633 5208 Bool_t lsign =kFALSE;
5209 if (hangles[2]>3.06) lsign =kTRUE;
81e97e0d 5210 //
77f88633 5211 if (lsign){
eea478d3 5212 circular[i0] = kTRUE;
81e97e0d 5213 circular[i1] = kTRUE;
8467b758 5214 if (track0->OneOverPt()<track1->OneOverPt()){
b9671574 5215 track0->SetCircular(track0->GetCircular()+1);
5216 track1->SetCircular(track1->GetCircular()+2);
81e97e0d 5217 }
5218 else{
b9671574 5219 track1->SetCircular(track1->GetCircular()+1);
5220 track0->SetCircular(track0->GetCircular()+2);
81e97e0d 5221 }
5222 }
77f88633 5223 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
34acb742 5224 //debug stream
b9671574 5225 Int_t lab0=track0->GetLabel();
5226 Int_t lab1=track1->GetLabel();
b194b32c 5227 TTreeSRedirector &cstream = *fDebugStreamer;
81e97e0d 5228 cstream<<"Curling"<<
b9671574 5229 "lab0="<<lab0<<
5230 "lab1="<<lab1<<
81e97e0d 5231 "Tr0.="<<track0<<
5232 "Tr1.="<<track1<<
5233 "dca0="<<dca[i0]<<
5234 "dca1="<<dca[i1]<<
5235 "mindcar="<<mindcar<<
5236 "mindcaz="<<mindcaz<<
5237 "delta="<<delta<<
5238 "rmean="<<rmean<<
5239 "npoints="<<npoints<<
5240 "hangles0="<<hangles[0]<<
5241 "hangles2="<<hangles[2]<<
5242 "xyz0="<<xyz0[2]<<
5243 "xyzz1="<<xyz1[2]<<
5244 "z0="<<z0[i0]<<
5245 "z1="<<z0[i1]<<
5246 "radius="<<radiusbest<<
5247 "deltabest="<<deltabest<<
5248 "phase0="<<phase[ibest][0]<<
5249 "phase1="<<phase[ibest][1]<<
5250 "\n";
eea478d3 5251 }
5252 }
5253 }
5254 }
5255 //
ddfbc51a 5256 // Finf kinks loop
81e97e0d 5257 //
51ad6848 5258 //
5259 for (Int_t i =0;i<nentries;i++){
5260 if (sign[i]==0) continue;
5261 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
c1ea348f 5262 if (track0==0) {
5263 AliInfo("seed==0");
5264 continue;
5265 }
51ad6848 5266 ntracks++;
5267 //
5268 Double_t cradius0 = 40*40;
5269 Double_t cradius1 = 270*270;
5270 Double_t cdist1=8.;
5271 Double_t cdist2=8.;
5272 Double_t cdist3=0.55;
5273 for (Int_t j =i+1;j<nentries;j++){
5274 nall++;
5275 if (sign[j]*sign[i]<1) continue;
5276 if ( (nclusters[i]+nclusters[j])>200) continue;
5277 if ( (nclusters[i]+nclusters[j])<80) continue;
5278 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
5279 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
5280 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
5281 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5282 if (npoints<1) continue;
5283 // cuts on radius
5284 if (npoints==1){
5285 if (radius[0]<cradius0||radius[0]>cradius1) continue;
5286 }
5287 else{
5288 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
5289 }
5290 //
5291 Double_t delta1=10000,delta2=10000;
5292 // cuts on the intersection radius
5293 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5294 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5295 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5296 if (npoints==2){
5297 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5298 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5299 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5300 }
5301 //
5302 Double_t distance1 = TMath::Min(delta1,delta2);
5303 if (distance1>cdist1) continue; // cut on DCA linear approximation
5304 //
5305 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5306 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5307 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5308 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5309 //
5310 if (npoints==2){
5311 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5312 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5313 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5314 }
5315 distance1 = TMath::Min(delta1,delta2);
5316 Float_t rkink =0;
5317 if (delta1<delta2){
5318 rkink = TMath::Sqrt(radius[0]);
5319 }
5320 else{
5321 rkink = TMath::Sqrt(radius[1]);
5322 }
5323 if (distance1>cdist2) continue;
5324 //
5325 //
5326 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5327 //
5328 //
5329 Int_t row0 = GetRowNumber(rkink);
5330 if (row0<10) continue;
5331 if (row0>150) continue;
5332 //
5333 //
5334 Float_t dens00=-1,dens01=-1;
5335 Float_t dens10=-1,dens11=-1;
5336 //
77f88633 5337 Int_t found,foundable,ishared;
5338 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
51ad6848 5339 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
77f88633 5340 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
51ad6848 5341 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
5342 //
77f88633 5343 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
51ad6848 5344 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
77f88633 5345 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
51ad6848 5346 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
eea478d3 5347 //
51ad6848 5348 if (dens00<dens10 && dens01<dens11) continue;
5349 if (dens00>dens10 && dens01>dens11) continue;
5350 if (TMath::Max(dens00,dens10)<0.1) continue;
5351 if (TMath::Max(dens01,dens11)<0.3) continue;
5352 //
5353 if (TMath::Min(dens00,dens10)>0.6) continue;
5354 if (TMath::Min(dens01,dens11)>0.6) continue;
5355
5356 //
5357 AliTPCseed * ktrack0, *ktrack1;
5358 if (dens00>dens10){
5359 ktrack0 = track0;
5360 ktrack1 = track1;
5361 }
5362 else{
5363 ktrack0 = track1;
5364 ktrack1 = track0;
5365 }
5366 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
5367 AliExternalTrackParam paramm(*ktrack0);
5368 AliExternalTrackParam paramd(*ktrack1);
316c6cd9 5369 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
51ad6848 5370 //
5371 //
5372 kink->SetMother(paramm);
5373 kink->SetDaughter(paramd);
5374 kink->Update();
5375
eea478d3 5376 Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
51ad6848 5377 Int_t index[4];
47af7ca4 5378 fkParam->Transform0to1(x,index);
5379 fkParam->Transform1to2(x,index);
51ad6848 5380 row0 = GetRowNumber(x[0]);
5381
eea478d3 5382 if (kink->GetR()<100) continue;
5383 if (kink->GetR()>240) continue;
5384 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
5385 if (kink->GetDistance()>cdist3) continue;
5386 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
51ad6848 5387 if (dird<0) continue;
5388
eea478d3 5389 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
51ad6848 5390 if (dirm<0) continue;
eea478d3 5391 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
51ad6848 5392 if (mpt<0.2) continue;
5393
eea478d3 5394 if (mpt<1){
5395 //for high momenta momentum not defined well in first iteration
6c94f330 5396 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
eea478d3 5397 if (qt>0.35) continue;
5398 }
51ad6848 5399
eea478d3 5400 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
5401 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
51ad6848 5402 if (dens00>dens10){
eea478d3 5403 kink->SetTPCDensity(dens00,0,0);
5404 kink->SetTPCDensity(dens01,0,1);
5405 kink->SetTPCDensity(dens10,1,0);
5406 kink->SetTPCDensity(dens11,1,1);
5407 kink->SetIndex(i,0);
5408 kink->SetIndex(j,1);
51ad6848 5409 }
5410 else{
eea478d3 5411 kink->SetTPCDensity(dens10,0,0);
5412 kink->SetTPCDensity(dens11,0,1);
5413 kink->SetTPCDensity(dens00,1,0);
5414 kink->SetTPCDensity(dens01,1,1);
5415 kink->SetIndex(j,0);
5416 kink->SetIndex(i,1);
51ad6848 5417 }
51ad6848 5418
eea478d3 5419 if (mpt<1||kink->GetAngle(2)>0.1){
5420 // angle and densities not defined yet
5421 if (kink->GetTPCDensityFactor()<0.8) continue;
5422 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
6c94f330 5423 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
eea478d3 5424 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5425 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5426
6c94f330 5427 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5428 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
eea478d3 5429 criticalangle= 3*TMath::Sqrt(criticalangle);
5430 if (criticalangle>0.02) criticalangle=0.02;
5431 if (kink->GetAngle(2)<criticalangle) continue;
5432 }
51ad6848 5433 //
eea478d3 5434 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
51ad6848 5435 Float_t shapesum =0;
5436 Float_t sum = 0;
5437 for ( Int_t row = row0-drow; row<row0+drow;row++){
5438 if (row<0) continue;
5439 if (row>155) continue;
b9671574 5440 if (ktrack0->GetClusterPointer(row)){
51ad6848 5441 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5442 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5443 sum++;
5444 }
b9671574 5445 if (ktrack1->GetClusterPointer(row)){
51ad6848 5446 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5447 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5448 sum++;
5449 }
5450 }
5451 if (sum<4){
eea478d3 5452 kink->SetShapeFactor(-1.);
51ad6848 5453 }
5454 else{
eea478d3 5455 kink->SetShapeFactor(shapesum/sum);
5456 }
51ad6848 5457 // esd->AddKink(kink);
16299eac 5458 //
5459 // kink->SetMother(paramm);
5460 //kink->SetDaughter(paramd);
5461
5462 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
5463 chi2P2*=chi2P2;
5464 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
5465 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
5466 chi2P3*=chi2P3;
5467 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
5468 //
5469 if (AliTPCReconstructor::StreamLevel()>1) {
5470 (*fDebugStreamer)<<"kinkLpt"<<
5471 "chi2P2="<<chi2P2<<
5472 "chi2P3="<<chi2P3<<
5473 "p0.="<<&paramm<<
5474 "p1.="<<&paramd<<
5475 "k.="<<kink<<
5476 "\n";
5477 }
5478 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
5479 continue;
5480 }
5481 //
ddfbc51a 5482 kinks->AddLast(kink);
5483 kink = new AliKink;
51ad6848 5484 ncandidates++;
5485 }
5486 }
ddfbc51a 5487 //
eea478d3 5488 // sort the kinks according quality - and refit them towards vertex
5489 //
ddfbc51a 5490 Int_t nkinks = kinks->GetEntriesFast();
5491 Float_t *quality = new Float_t[nkinks];
5492 Int_t *indexes = new Int_t[nkinks];
5493 AliTPCseed *mothers = new AliTPCseed[nkinks];
5494 AliTPCseed *daughters = new AliTPCseed[nkinks];
eea478d3 5495 //
5496 //
51ad6848 5497 for (Int_t i=0;i<nkinks;i++){
5498 quality[i] =100000;
ddfbc51a 5499 AliKink *kinkl = (AliKink*)kinks->At(i);
eea478d3 5500 //
5501 // refit kinks towards vertex
5502 //
77f88633 5503 Int_t index0 = kinkl->GetIndex(0);
5504 Int_t index1 = kinkl->GetIndex(1);
eea478d3 5505 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5506 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5507 //
b9671574 5508 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
eea478d3 5509 //
5510 // Refit Kink under if too small angle
5511 //
77f88633 5512 if (kinkl->GetAngle(2)<0.05){
5513 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5514 Int_t row0 = kinkl->GetTPCRow0();
5515 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
eea478d3 5516 //
5517 //
5518 Int_t last = row0-drow;
5519 if (last<40) last=40;
b9671574 5520 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
eea478d3 5521 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
5522 //
5523 //
5524 Int_t first = row0+drow;
5525 if (first>130) first=130;
b9671574 5526 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
eea478d3 5527 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
5528 //
ddfbc51a 5529 if (seed0 && seed1){
77f88633 5530 kinkl->SetStatus(1,8);
5531 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
5532 row0 = GetRowNumber(kinkl->GetR());
b9671574 5533 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
ddfbc51a 5534 mothers[i] = *seed0;
5535 daughters[i] = *seed1;
eea478d3 5536 }
ddfbc51a 5537 else{
5538 delete kinks->RemoveAt(i);
5539 if (seed0) MarkSeedFree( seed0 );
5540 if (seed1) MarkSeedFree( seed1 );
eea478d3 5541 continue;
5542 }
77f88633 5543 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
ddfbc51a 5544 delete kinks->RemoveAt(i);
5545 if (seed0) MarkSeedFree( seed0 );
5546 if (seed1) MarkSeedFree( seed1 );
eea478d3 5547 continue;
5548 }
ddfbc51a 5549 //
5550 MarkSeedFree( seed0 );
5551 MarkSeedFree( seed1 );
eea478d3 5552 }
5553 //
77f88633 5554 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
51ad6848 5555 }
5556 TMath::Sort(nkinks,quality,indexes,kFALSE);
eea478d3 5557 //
5558 //remove double find kinks
5559 //
5560 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
ddfbc51a 5561 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
eea478d3 5562 if (!kink0) continue;
5563 //
6a6ba9a2 5564 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
ddfbc51a 5565 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
5566 if (!kink0) continue;
5567 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
eea478d3 5568 if (!kink1) continue;
5569 // if not close kink continue
5570 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
5571 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
5572 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
5573 //
ddfbc51a 5574 AliTPCseed &mother0 = mothers[indexes[ikink0]];
5575 AliTPCseed &daughter0 = daughters[indexes[ikink0]];
5576 AliTPCseed &mother1 = mothers[indexes[ikink1]];
5577 AliTPCseed &daughter1 = daughters[indexes[ikink1]];
eea478d3 5578 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
5579 //
5580 Int_t same = 0;
5581 Int_t both = 0;
5582 Int_t samem = 0;
5583 Int_t bothm = 0;
5584 Int_t samed = 0;
5585 Int_t bothd = 0;
5586 //
5587 for (Int_t i=0;i<row0;i++){
ddfbc51a 5588 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
eea478d3 5589 both++;
5590 bothm++;
ddfbc51a 5591 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
eea478d3 5592 same++;
5593 samem++;
5594 }
5595 }
5596 }
5597
5598 for (Int_t i=row0;i<158;i++){
f06a1ff6 5599 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
ddfbc51a 5600 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
eea478d3 5601 both++;
5602 bothd++;
ddfbc51a 5603 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
eea478d3 5604 same++;
5605 samed++;
5606 }
5607 }
5608 }
5609 Float_t ratio = Float_t(same+1)/Float_t(both+1);
5610 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
5611 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
5612 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
ddfbc51a 5613 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
5614 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
eea478d3 5615 if (sum1>sum0){
5616 shared[kink0->GetIndex(0)]= kTRUE;
5617 shared[kink0->GetIndex(1)]= kTRUE;
ddfbc51a 5618 delete kinks->RemoveAt(indexes[ikink0]);
b3659bad 5619 break;
eea478d3 5620 }
5621 else{
5622 shared[kink1->GetIndex(0)]= kTRUE;
5623 shared[kink1->GetIndex(1)]= kTRUE;
ddfbc51a 5624 delete kinks->RemoveAt(indexes[ikink1]);
eea478d3 5625 }
5626 }
5627 }
5628 }
5629
5630
51ad6848 5631 for (Int_t i=0;i<nkinks;i++){
ddfbc51a 5632 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
77f88633 5633 if (!kinkl) continue;
5634 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5635 Int_t index0 = kinkl->GetIndex(0);
5636 Int_t index1 = kinkl->GetIndex(1);
5637 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
5638 kinkl->SetMultiple(usage[index0],0);
5639 kinkl->SetMultiple(usage[index1],1);
5640 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
5641 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
5642 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
5643 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
51ad6848 5644
51ad6848 5645 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5646 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
eea478d3 5647 if (!ktrack0 || !ktrack1) continue;
77f88633 5648 Int_t index = esd->AddKink(kinkl);
eea478d3 5649 //
5650 //
b9671574 5651 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
ddfbc51a 5652 if (mothers[indexes[i]].GetNumberOfClusters()>20 && daughters[indexes[i]].GetNumberOfClusters()>20 && (mothers[indexes[i]].GetNumberOfClusters()+daughters[indexes[i]].GetNumberOfClusters())>100){
5653 *ktrack0 = mothers[indexes[i]];
5654 *ktrack1 = daughters[indexes[i]];
eea478d3 5655 }
5656 }
5657 //
b9671574 5658 ktrack0->SetKinkIndex(usage[index0],-(index+1));
5659 ktrack1->SetKinkIndex(usage[index1], (index+1));
51ad6848 5660 usage[index0]++;
5661 usage[index1]++;
5662 }
eea478d3 5663 //
5664 // Remove tracks corresponding to shared kink's
5665 //
5666 for (Int_t i=0;i<nentries;i++){
5667 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5668 if (!track0) continue;
b9671574 5669 if (track0->GetKinkIndex(0)!=0) continue;
ddfbc51a 5670 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
eea478d3 5671 }
ddfbc51a 5672
eea478d3 5673 //
5674 //
5675 RemoveUsed2(array,0.5,0.4,30);
5676 UnsignClusters();
81e97e0d 5677 for (Int_t i=0;i<nentries;i++){
5678 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5679 if (!track0) continue;
5680 track0->CookdEdx(0.02,0.6);
5681 track0->CookPID();
5682 }
eea478d3 5683 //
5684 for (Int_t i=0;i<nentries;i++){
5685 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5686 if (!track0) continue;
8467b758 5687 if (track0->Pt()<1.4) continue;
eea478d3 5688 //remove double high momenta tracks - overlapped with kink candidates
77f88633 5689 Int_t ishared=0;
eea478d3 5690 Int_t all =0;
b9671574 5691 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
5692 if (track0->GetClusterPointer(icl)!=0){
eea478d3 5693 all++;
77f88633 5694 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
eea478d3 5695 }
5696 }
77f88633 5697 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
ddfbc51a 5698 MarkSeedFree( array->RemoveAt(i) );
f99dc368 5699 continue;
eea478d3 5700 }
5701 //
b9671574 5702 if (track0->GetKinkIndex(0)!=0) continue;
eea478d3 5703 if (track0->GetNumberOfClusters()<80) continue;
4a12af72 5704
ddfbc51a 5705 AliTPCseed *pmother = new AliTPCseed();
5706 AliTPCseed *pdaughter = new AliTPCseed();
5707 AliKink *pkink = new AliKink;
5708
4a12af72 5709 AliTPCseed & mother = *pmother;
5710 AliTPCseed & daughter = *pdaughter;
77f88633 5711 AliKink & kinkl = *pkink;
5712 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
b9671574 5713 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
ddfbc51a 5714 delete pmother;
5715 delete pdaughter;
5716 delete pkink;
4a12af72 5717 continue; //too short tracks
5718 }
8467b758 5719 if (mother.Pt()<1.4) {
ddfbc51a 5720 delete pmother;
5721 delete pdaughter;
5722 delete pkink;
4a12af72 5723 continue;
5724 }
77f88633 5725 Int_t row0= kinkl.GetTPCRow0();
5726 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
ddfbc51a 5727 delete pmother;
5728 delete pdaughter;
5729 delete pkink;
eea478d3 5730 continue;
5731 }
5732 //
77f88633 5733 Int_t index = esd->AddKink(&kinkl);
b9671574 5734 mother.SetKinkIndex(0,-(index+1));
5735 daughter.SetKinkIndex(0,index+1);
5736 if (mother.GetNumberOfClusters()>50) {
ddfbc51a 5737 MarkSeedFree( array->RemoveAt(i) );
5738 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
5739 mtc->SetPoolID(fLastSeedID);
f06a1ff6 5740 array->AddAt(mtc,i);
eea478d3 5741 }
5742 else{
ddfbc51a 5743 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
5744 mtc->SetPoolID(fLastSeedID);
f06a1ff6 5745 array->AddLast(mtc);
eea478d3 5746 }
ddfbc51a 5747 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
5748 dtc->SetPoolID(fLastSeedID);
f06a1ff6 5749 array->AddLast(dtc);
eea478d3 5750 for (Int_t icl=0;icl<row0;icl++) {
b9671574 5751 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
eea478d3 5752 }
5753 //
5754 for (Int_t icl=row0;icl<158;icl++) {
b9671574 5755 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
eea478d3 5756 }
5757 //
5758 }
ddfbc51a 5759 delete pmother;
5760 delete pdaughter;
5761 delete pkink;
eea478d3 5762 }
ddfbc51a 5763
5764 delete [] daughters;
5765 delete [] mothers;
eea478d3 5766 //
eea478d3 5767 //
ddfbc51a 5768 delete [] dca;
5769 delete []circular;
5770 delete []shared;
5771 delete []quality;
5772 delete []indexes;
5773 //
5774 delete kink;
5775 delete[]fim;
5776 delete[] zm;
5777 delete[] z0;
5778 delete [] usage;
5779 delete[] alpha;
5780 delete[] nclusters;
5781 delete[] sign;
bfa00fba 5782 delete[] helixes;
ddfbc51a 5783 kinks->Delete();
5784 delete kinks;
5785
7b9ce4fd 5786 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
51ad6848 5787 timer.Print();
5788}
5789
81e97e0d 5790
ddfbc51a 5791/*
829455ad 5792void AliTPCtracker::FindKinks(TObjArray * array, AliESDEvent *esd)
eea478d3 5793{
5794 //
ddfbc51a 5795 // find kinks
eea478d3 5796 //
5797 //
6c94f330 5798
ddfbc51a 5799 TObjArray *kinks= new TObjArray(10000);
5800 // TObjArray *v0s= new TObjArray(10000);
5801 Int_t nentries = array->GetEntriesFast();
5802 AliHelix *helixes = new AliHelix[nentries];
5803 Int_t *sign = new Int_t[nentries];
5804 Int_t *nclusters = new Int_t[nentries];
5805 Float_t *alpha = new Float_t[nentries];
5806 AliKink *kink = new AliKink();
5807 Int_t * usage = new Int_t[nentries];
5808 Float_t *zm = new Float_t[nentries];
5809 Float_t *z0 = new Float_t[nentries];
5810 Float_t *fim = new Float_t[nentries];
5811 Float_t *shared = new Float_t[nentries];
5812 Bool_t *circular = new Bool_t[nentries];
5813 Float_t *dca = new Float_t[nentries];
5814 //const AliESDVertex * primvertex = esd->GetVertex();
eea478d3 5815 //
ddfbc51a 5816 // nentries = array->GetEntriesFast();
eea478d3 5817 //
ddfbc51a 5818
e546b023 5819 //
e546b023 5820 //
ddfbc51a 5821 for (Int_t i=0;i<nentries;i++){
5822 sign[i]=0;
5823 usage[i]=0;
5824 AliTPCseed* track = (AliTPCseed*)array->At(i);
5825 if (!track) continue;
5826 track->SetCircular(0);
5827 shared[i] = kFALSE;
5828 track->UpdatePoints();
5829 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
5830 }
5831 nclusters[i]=track->GetNumberOfClusters();
5832 alpha[i] = track->GetAlpha();
5833 new (&helixes[i]) AliHelix(*track);
5834 Double_t xyz[3];
5835 helixes[i].Evaluate(0,xyz);
5836 sign[i] = (track->GetC()>0) ? -1:1;
5837 Double_t x,y,z;
5838 x=160;
5839 if (track->GetProlongation(x,y,z)){
5840 zm[i] = z;
5841 fim[i] = alpha[i]+TMath::ATan2(y,x);
eea478d3 5842 }
ddfbc51a 5843 else{
5844 zm[i] = track->GetZ();
5845 fim[i] = alpha[i];
5846 }
5847 z0[i]=1000;
5848 circular[i]= kFALSE;
5849 if (track->GetProlongation(0,y,z)) z0[i] = z;
5850 dca[i] = track->GetD(0,0);
eea478d3 5851 }
5852 //
eea478d3 5853 //
ddfbc51a 5854 TStopwatch timer;
5855 timer.Start();
5856 Int_t ncandidates =0;
5857 Int_t nall =0;
5858 Int_t ntracks=0;
5859 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
5860
eea478d3 5861 //
ddfbc51a 5862 // Find circling track
e546b023 5863 //
ddfbc51a 5864 for (Int_t i0=0;i0<nentries;i0++){
5865 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5866 if (!track0) continue;
5867 if (track0->GetNumberOfClusters()<40) continue;
5868 if (TMath::Abs(1./track0->GetC())>200) continue;
5869 for (Int_t i1=i0+1;i1<nentries;i1++){
5870 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5871 if (!track1) continue;
5872 if (track1->GetNumberOfClusters()<40) continue;
5873 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
5874 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
5875 if (TMath::Abs(1./track1->GetC())>200) continue;
5876 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
5877 if (track1->GetTgl()*track0->GetTgl()>0) continue;
5878 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
5879 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
5880 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
5881 //
5882 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
5883 if (mindcar<5) continue;
5884 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
5885 if (mindcaz<5) continue;
5886 if (mindcar+mindcaz<20) continue;
5887 //
5888 //
5889 Float_t xc0 = helixes[i0].GetHelix(6);
5890 Float_t yc0 = helixes[i0].GetHelix(7);
5891 Float_t r0 = helixes[i0].GetHelix(8);
5892 Float_t xc1 = helixes[i1].GetHelix(6);
5893 Float_t yc1 = helixes[i1].GetHelix(7);
5894 Float_t r1 = helixes[i1].GetHelix(8);
5895
5896 Float_t rmean = (r0+r1)*0.5;
5897 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
5898 //if (delta>30) continue;
5899 if (delta>rmean*0.25) continue;
5900 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
5901 //
5902 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5903 if (npoints==0) continue;
5904 helixes[i0].GetClosestPhases(helixes[i1], phase);
5905 //
5906 Double_t xyz0[3];
5907 Double_t xyz1[3];
5908 Double_t hangles[3];
5909 helixes[i0].Evaluate(phase[0][0],xyz0);
5910 helixes[i1].Evaluate(phase[0][1],xyz1);
e546b023 5911
ddfbc51a 5912 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5913 Double_t deltah[2],deltabest;
5914 if (hangles[2]<2.8) continue;
5915 if (npoints>0){
5916 Int_t ibest=0;
5917 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
5918 if (npoints==2){
5919 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
5920 if (deltah[1]<deltah[0]) ibest=1;
5921 }
5922 deltabest = TMath::Sqrt(deltah[ibest]);
5923 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5924 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5925 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5926 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5927 //
5928 if (deltabest>6) continue;
5929 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
5930 Bool_t lsign =kFALSE;
5931 if (hangles[2]>3.06) lsign =kTRUE;
5932 //
5933 if (lsign){
5934 circular[i0] = kTRUE;
5935 circular[i1] = kTRUE;
5936 if (track0->OneOverPt()<track1->OneOverPt()){
5937 track0->SetCircular(track0->GetCircular()+1);
5938 track1->SetCircular(track1->GetCircular()+2);
5939 }
5940 else{
5941 track1->SetCircular(track1->GetCircular()+1);
5942 track0->SetCircular(track0->GetCircular()+2);
5943 }
5944 }
5945 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
5946 //debug stream
5947 Int_t lab0=track0->GetLabel();
5948 Int_t lab1=track1->GetLabel();
5949 TTreeSRedirector &cstream = *fDebugStreamer;
5950 cstream<<"Curling"<<
5951 "lab0="<<lab0<<
5952 "lab1="<<lab1<<
5953 "Tr0.="<<track0<<
5954 "Tr1.="<<track1<<
5955 "dca0="<<dca[i0]<<
5956 "dca1="<<dca[i1]<<
5957 "mindcar="<<mindcar<<
5958 "mindcaz="<<mindcaz<<
5959 "delta="<<delta<<
5960 "rmean="<<rmean<<
5961 "npoints="<<npoints<<
5962 "hangles0="<<hangles[0]<<
5963 "hangles2="<<hangles[2]<<
5964 "xyz0="<<xyz0[2]<<
5965 "xyzz1="<<xyz1[2]<<
5966 "z0="<<z0[i0]<<
5967 "z1="<<z0[i1]<<
5968 "radius="<<radiusbest<<
5969 "deltabest="<<deltabest<<
5970 "phase0="<<phase[ibest][0]<<
5971 "phase1="<<phase[ibest][1]<<
5972 "\n";
5973 }
5974 }
5975 }
5976 }
51ad6848 5977 //
ddfbc51a 5978 // Finf kinks loop
5979 //
f06a1ff6 5980 //
ddfbc51a 5981 for (Int_t i =0;i<nentries;i++){
5982 if (sign[i]==0) continue;
5983 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5984 if (track0==0) {
5985 AliInfo("seed==0");
5986 continue;
5987 }
5988 ntracks++;
5989 //
5990 Double_t cradius0 = 40*40;
5991 Double_t cradius1 = 270*270;
5992 Double_t cdist1=8.;
5993 Double_t cdist2=8.;
5994 Double_t cdist3=0.55;
5995 for (Int_t j =i+1;j<nentries;j++){
5996 nall++;
5997 if (sign[j]*sign[i]<1) continue;
5998 if ( (nclusters[i]+nclusters[j])>200) continue;
5999 if ( (nclusters[i]+nclusters[j])<80) continue;
6000 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
6001 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
6002 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
6003 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
6004 if (npoints<1) continue;
6005 // cuts on radius
6006 if (npoints==1){
6007 if (radius[0]<cradius0||radius[0]>cradius1) continue;
6008 }
6009 else{
6010 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
6011 }
6012 //
6013 Double_t delta1=10000,delta2=10000;
6014 // cuts on the intersection radius
6015 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
6016 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
6017 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
6018 if (npoints==2){
6019 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
6020 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
6021 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
6022 }
6023 //
6024 Double_t distance1 = TMath::Min(delta1,delta2);
6025 if (distance1>cdist1) continue; // cut on DCA linear approximation
6026 //
6027 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
6028 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
6029 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
6030 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
6031 //
6032 if (npoints==2){
6033 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
6034 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
6035 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
6036 }
6037 distance1 = TMath::Min(delta1,delta2);
6038 Float_t rkink =0;
6039 if (delta1<delta2){
6040 rkink = TMath::Sqrt(radius[0]);
6041 }
6042 else{
6043 rkink = TMath::Sqrt(radius[1]);
6044 }
6045 if (distance1>cdist2) continue;
6046 //
6047 //
6048 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
6049 //
6050 //
6051 Int_t row0 = GetRowNumber(rkink);
6052 if (row0<10) continue;
6053 if (row0>150) continue;
6054 //
6055 //
6056 Float_t dens00=-1,dens01=-1;
6057 Float_t dens10=-1,dens11=-1;
6058 //
6059 Int_t found,foundable,ishared;
6060 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
6061 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
6062 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
6063 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
6064 //
6065 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
6066 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
6067 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
6068 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
6069 //
6070 if (dens00<dens10 && dens01<dens11) continue;
6071 if (dens00>dens10 && dens01>dens11) continue;
6072 if (TMath::Max(dens00,dens10)<0.1) continue;
6073 if (TMath::Max(dens01,dens11)<0.3) continue;
6074 //
6075 if (TMath::Min(dens00,dens10)>0.6) continue;
6076 if (TMath::Min(dens01,dens11)>0.6) continue;
6077
6078 //
6079 AliTPCseed * ktrack0, *ktrack1;
6080 if (dens00>dens10){
6081 ktrack0 = track0;
6082 ktrack1 = track1;
6083 }
6084 else{
6085 ktrack0 = track1;
6086 ktrack1 = track0;
6087 }
6088 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
6089 AliExternalTrackParam paramm(*ktrack0);
6090 AliExternalTrackParam paramd(*ktrack1);
6091 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
6092 //
6093 //
6094 kink->SetMother(paramm);
6095 kink->SetDaughter(paramd);
6096 kink->Update();
6097
6098 Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
6099 Int_t index[4];
6100 fkParam->Transform0to1(x,index);
6101 fkParam->Transform1to2(x,index);
6102 row0 = GetRowNumber(x[0]);
6103
6104 if (kink->GetR()<100) continue;
6105 if (kink->GetR()>240) continue;
6106 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
6107 if (kink->GetDistance()>cdist3) continue;
6108 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
6109 if (dird<0) continue;
6110
6111 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
6112 if (dirm<0) continue;
6113 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
6114 if (mpt<0.2) continue;
6115
6116 if (mpt<1){
6117 //for high momenta momentum not defined well in first iteration
6118 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
6119 if (qt>0.35) continue;
6120 }
6121
6122 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
6123 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
6124 if (dens00>dens10){
6125 kink->SetTPCDensity(dens00,0,0);
6126 kink->SetTPCDensity(dens01,0,1);
6127 kink->SetTPCDensity(dens10,1,0);
6128 kink->SetTPCDensity(dens11,1,1);
6129 kink->SetIndex(i,0);
6130 kink->SetIndex(j,1);
6131 }
6132 else{
6133 kink->SetTPCDensity(dens10,0,0);
6134 kink->SetTPCDensity(dens11,0,1);
6135 kink->SetTPCDensity(dens00,1,0);
6136 kink->SetTPCDensity(dens01,1,1);
6137 kink->SetIndex(j,0);
6138 kink->SetIndex(i,1);
6139 }
6140
6141 if (mpt<1||kink->GetAngle(2)>0.1){
6142 // angle and densities not defined yet
6143 if (kink->GetTPCDensityFactor()<0.8) continue;
6144 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
6145 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
6146 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
6147 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
6148
6149 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
6150 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
6151 criticalangle= 3*TMath::Sqrt(criticalangle);
6152 if (criticalangle>0.02) criticalangle=0.02;
6153 if (kink->GetAngle(2)<criticalangle) continue;
6154 }
6155 //
6156 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
6157 Float_t shapesum =0;
6158 Float_t sum = 0;
6159 for ( Int_t row = row0-drow; row<row0+drow;row++){
6160 if (row<0) continue;
6161 if (row>155) continue;
6162 if (ktrack0->GetClusterPointer(row)){
6163 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
6164 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
6165 sum++;
6166 }
6167 if (ktrack1->GetClusterPointer(row)){
6168 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
6169 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
6170 sum++;
6171 }
6172 }
6173 if (sum<4){
6174 kink->SetShapeFactor(-1.);
6175 }
6176 else{
6177 kink->SetShapeFactor(shapesum/sum);
6178 }
6179 // esd->AddKink(kink);
6180 //
6181 // kink->SetMother(paramm);
6182 //kink->SetDaughter(paramd);
6183
6184 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
6185 chi2P2*=chi2P2;
6186 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
6187 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
6188 chi2P3*=chi2P3;
6189 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
6190 //
6191 if (AliTPCReconstructor::StreamLevel()>1) {
6192 (*fDebugStreamer)<<"kinkLpt"<<
6193 "chi2P2="<<chi2P2<<
6194 "chi2P3="<<chi2P3<<
6195 "p0.="<<&paramm<<
6196 "p1.="<<&paramd<<
6197 "k.="<<kink<<
6198 "\n";
6199 }
6200 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
6201 continue;
6202 }
6203 //
6204 kinks->AddLast(kink);
6205 kink = new AliKink;
6206 ncandidates++;
6207 }
6208 }
6209 //
6210 // sort the kinks according quality - and refit them towards vertex
6211 //
6212 Int_t nkinks = kinks->GetEntriesFast();
6213 Float_t *quality = new Float_t[nkinks];
6214 Int_t *indexes = new Int_t[nkinks];
6215 AliTPCseed **mothers = new AliTPCseed*[nkinks]; memset(mothers, 0, nkinks*sizeof(AliTPCseed*));
6216 AliTPCseed **daughters = new AliTPCseed*[nkinks]; memset(daughters, 0, nkinks*sizeof(AliTPCseed*));
6217 //
6218 //
6219 for (Int_t i=0;i<nkinks;i++){
6220 quality[i] =100000;
6221 AliKink *kinkl = (AliKink*)kinks->At(i);
6222 //
6223 // refit kinks towards vertex
6224 //
6225 Int_t index0 = kinkl->GetIndex(0);
6226 Int_t index1 = kinkl->GetIndex(1);
6227 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6228 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6229 //
6230 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
6231 //
6232 // Refit Kink under if too small angle
6233 //
6234 if (kinkl->GetAngle(2)<0.05){
6235 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6236 Int_t row0 = kinkl->GetTPCRow0();
6237 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
6238 //
6239 //
6240 Int_t last = row0-drow;
6241 if (last<40) last=40;
6242 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
6243 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
6244 //
6245 //
6246 Int_t first = row0+drow;
6247 if (first>130) first=130;
6248 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
6249 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
6250 //
6251 if (seed0 && seed1){
6252 kinkl->SetStatus(1,8);
6253 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
6254 row0 = GetRowNumber(kinkl->GetR());
6255 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
6256 mothers[i] = new ( NextFreeSeed() ) AliTPCseed(*seed0);
6257 mothers[i]->SetPoolID(fLastSeedID);
6258 daughters[i] = new (NextFreeSeed() ) AliTPCseed(*seed1);
6259 daughters[i]->SetPoolID(fLastSeedID);
6260 }
6261 else{
6262 delete kinks->RemoveAt(i);
6263 if (seed0) MarkSeedFree( seed0 );
6264 if (seed1) MarkSeedFree( seed1 );
6265 continue;
6266 }
6267 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
6268 delete kinks->RemoveAt(i);
6269 if (seed0) MarkSeedFree( seed0 );
6270 if (seed1) MarkSeedFree( seed1 );
6271 continue;
6272 }
6273 //
6274 MarkSeedFree( seed0 );
6275 MarkSeedFree( seed1 );
6276 }
6277 //
6278 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
6279 }
6280 TMath::Sort(nkinks,quality,indexes,kFALSE);
6281 //
6282 //remove double find kinks
6283 //
6284 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
6285 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6286 if (!kink0) continue;
6287 //
6288 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
6289 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6290 if (!kink0) continue;
6291 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
6292 if (!kink1) continue;
6293 // if not close kink continue
6294 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
6295 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
6296 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
6297 //
6298 AliTPCseed &mother0 = *mothers[indexes[ikink0]];
6299 AliTPCseed &daughter0 = *daughters[indexes[ikink0]];
6300 AliTPCseed &mother1 = *mothers[indexes[ikink1]];
6301 AliTPCseed &daughter1 = *daughters[indexes[ikink1]];
6302 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
6303 //
6304 Int_t same = 0;
6305 Int_t both = 0;
6306 Int_t samem = 0;
6307 Int_t bothm = 0;
6308 Int_t samed = 0;
6309 Int_t bothd = 0;
6310 //
6311 for (Int_t i=0;i<row0;i++){
6312 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
6313 both++;
6314 bothm++;
6315 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6316 same++;
6317 samem++;
6318 }
6319 }
6320 }
6321
6322 for (Int_t i=row0;i<158;i++){
6323 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
6324 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
6325 both++;
6326 bothd++;
6327 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6328 same++;
6329 samed++;
6330 }
6331 }
6332 }
6333 Float_t ratio = Float_t(same+1)/Float_t(both+1);
6334 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
6335 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
6336 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
6337 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
6338 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
6339 if (sum1>sum0){
6340 shared[kink0->GetIndex(0)]= kTRUE;
6341 shared[kink0->GetIndex(1)]= kTRUE;
6342 delete kinks->RemoveAt(indexes[ikink0]);
6343 break;
6344 }
6345 else{
6346 shared[kink1->GetIndex(0)]= kTRUE;
6347 shared[kink1->GetIndex(1)]= kTRUE;
6348 delete kinks->RemoveAt(indexes[ikink1]);
6349 }
6350 }
6351 }
6352 }
6353
6354
6355 for (Int_t i=0;i<nkinks;i++){
6356 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
6357 if (!kinkl) continue;
6358 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6359 Int_t index0 = kinkl->GetIndex(0);
6360 Int_t index1 = kinkl->GetIndex(1);
6361 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
6362 kinkl->SetMultiple(usage[index0],0);
6363 kinkl->SetMultiple(usage[index1],1);
6364 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
6365 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
6366 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
6367 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
6368
6369 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6370 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6371 if (!ktrack0 || !ktrack1) continue;
6372 Int_t index = esd->AddKink(kinkl);
6373 //
6374 //
6375 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
6376 if (mothers[indexes[i]]->GetNumberOfClusters()>20 && daughters[indexes[i]]->GetNumberOfClusters()>20 &&
6377 (mothers[indexes[i]]->GetNumberOfClusters()+daughters[indexes[i]]->GetNumberOfClusters())>100){
6378 *ktrack0 = *mothers[indexes[i]];
6379 *ktrack1 = *daughters[indexes[i]];
6380 }
6381 }
6382 //
6383 ktrack0->SetKinkIndex(usage[index0],-(index+1));
6384 ktrack1->SetKinkIndex(usage[index1], (index+1));
6385 usage[index0]++;
6386 usage[index1]++;
6387 }
6388 //
6389 // Remove tracks corresponding to shared kink's
6390 //
6391 for (Int_t i=0;i<nentries;i++){
6392 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6393 if (!track0) continue;
6394 if (track0->GetKinkIndex(0)!=0) continue;
6395 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
6396 }
6397
6398 //
6399 //
6400 RemoveUsed2(array,0.5,0.4,30);
6401 UnsignClusters();
6402 for (Int_t i=0;i<nentries;i++){
6403 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6404 if (!track0) continue;
6405 track0->CookdEdx(0.02,0.6);
6406 track0->CookPID();
6407 }
6408 //
6409 for (Int_t i=0;i<nentries;i++){
6410 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6411 if (!track0) continue;
6412 if (track0->Pt()<1.4) continue;
6413 //remove double high momenta tracks - overlapped with kink candidates
6414 Int_t ishared=0;
6415 Int_t all =0;
6416 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
6417 if (track0->GetClusterPointer(icl)!=0){
6418 all++;
6419 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
6420 }
6421 }
6422 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
6423 MarkSeedFree( array->RemoveAt(i) );
6424 continue;
6425 }
6426 //
6427 if (track0->GetKinkIndex(0)!=0) continue;
6428 if (track0->GetNumberOfClusters()<80) continue;
6429
6430 AliTPCseed *pmother = new( NextFreeSeed() ) AliTPCseed();
6431 pmother->SetPoolID(fLastSeedID);
6432 AliTPCseed *pdaughter = new( NextFreeSeed() ) AliTPCseed();
6433 pdaughter->SetPoolID(fLastSeedID);
6434 AliKink *pkink = new AliKink;
6435
6436 AliTPCseed & mother = *pmother;
6437 AliTPCseed & daughter = *pdaughter;
6438 AliKink & kinkl = *pkink;
6439 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
6440 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
6441 MarkSeedFree( pmother );
6442 MarkSeedFree( pdaughter );
6443 delete pkink;
6444 continue; //too short tracks
6445 }
6446 if (mother.Pt()<1.4) {
6447 MarkSeedFree( pmother );
6448 MarkSeedFree( pdaughter );
6449 delete pkink;
6450 continue;
6451 }
6452 Int_t row0= kinkl.GetTPCRow0();
6453 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
6454 MarkSeedFree( pmother );
6455 MarkSeedFree( pdaughter );
6456 delete pkink;
6457 continue;
6458 }
6459 //
6460 Int_t index = esd->AddKink(&kinkl);
6461 mother.SetKinkIndex(0,-(index+1));
6462 daughter.SetKinkIndex(0,index+1);
6463 if (mother.GetNumberOfClusters()>50) {
6464 MarkSeedFree( array->RemoveAt(i) );
6465 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6466 mtc->SetPoolID(fLastSeedID);
6467 array->AddAt(mtc,i);
6468 }
6469 else{
6470 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6471 mtc->SetPoolID(fLastSeedID);
6472 array->AddLast(mtc);
6473 }
6474 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
6475 dtc->SetPoolID(fLastSeedID);
6476 array->AddLast(dtc);
6477 for (Int_t icl=0;icl<row0;icl++) {
6478 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
6479 }
6480 //
6481 for (Int_t icl=row0;icl<158;icl++) {
6482 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
6483 }
6484 //
6485 }
6486 MarkSeedFree( pmother );
6487 MarkSeedFree( pdaughter );
6488 delete pkink;
6489 }
6490
6491 delete [] daughters;
6492 delete [] mothers;
6493 //
6494 //
6495 delete [] dca;
6496 delete []circular;
6497 delete []shared;
6498 delete []quality;
6499 delete []indexes;
6500 //
6501 delete kink;
6502 delete[]fim;
6503 delete[] zm;
6504 delete[] z0;
6505 delete [] usage;
6506 delete[] alpha;
6507 delete[] nclusters;
6508 delete[] sign;
6509 delete[] helixes;
6510 kinks->Delete();
6511 delete kinks;
6512
6513 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
6514 timer.Print();
6515}
6516*/
6517
829455ad 6518Int_t AliTPCtracker::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
ddfbc51a 6519{
6520 //
6521 // refit kink towards to the vertex
6522 //
6523 //
6524 AliKink &kink=(AliKink &)knk;
6525
6526 Int_t row0 = GetRowNumber(kink.GetR());
6527 FollowProlongation(mother,0);
6528 mother.Reset(kFALSE);
6529 //
6530 FollowProlongation(daughter,row0);
6531 daughter.Reset(kFALSE);
6532 FollowBackProlongation(daughter,158);
6533 daughter.Reset(kFALSE);
6534 Int_t first = TMath::Max(row0-20,30);
6535 Int_t last = TMath::Min(row0+20,140);
6536 //
6537 const Int_t kNdiv =5;
6538 AliTPCseed param0[kNdiv]; // parameters along the track
6539 AliTPCseed param1[kNdiv]; // parameters along the track
6540 AliKink kinks[kNdiv]; // corresponding kink parameters
6541 //
6542 Int_t rows[kNdiv];
6543 for (Int_t irow=0; irow<kNdiv;irow++){
6544 rows[irow] = first +((last-first)*irow)/(kNdiv-1);
6545 }
6546 // store parameters along the track
6547 //
6548 for (Int_t irow=0;irow<kNdiv;irow++){
6549 FollowBackProlongation(mother, rows[irow]);
6550 FollowProlongation(daughter,rows[kNdiv-1-irow]);
6551 param0[irow] = mother;
6552 param1[kNdiv-1-irow] = daughter;
6553 }
6554 //
6555 // define kinks
6556 for (Int_t irow=0; irow<kNdiv-1;irow++){
6557 if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
6558 kinks[irow].SetMother(param0[irow]);
6559 kinks[irow].SetDaughter(param1[irow]);
6560 kinks[irow].Update();
6561 }
6562 //
6563 // choose kink with best "quality"
6564 Int_t index =-1;
6565 Double_t mindist = 10000;
6566 for (Int_t irow=0;irow<kNdiv;irow++){
6567 if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
6568 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
6569 if (TMath::Abs(kinks[irow].GetR())<100.) continue;
6570 //
6571 Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
6572 normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
6573 if (normdist < mindist){
6574 mindist = normdist;
6575 index = irow;
6576 }
6577 }
6578 //
6579 if (index==-1) return 0;
6580 //
6581 //
6582 param0[index].Reset(kTRUE);
6583 FollowProlongation(param0[index],0);
6584 //
6585 mother = param0[index];
6586 daughter = param1[index]; // daughter in vertex
6587 //
6588 kink.SetMother(mother);
6589 kink.SetDaughter(daughter);
6590 kink.Update();
6591 kink.SetTPCRow0(GetRowNumber(kink.GetR()));
6592 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
6593 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
6594 kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
6595 kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
6596 mother.SetLabel(kink.GetLabel(0));
6597 daughter.SetLabel(kink.GetLabel(1));
6598
6599 return 1;
6600}
6601
6602
829455ad 6603void AliTPCtracker::UpdateKinkQualityM(AliTPCseed * seed){
ddfbc51a 6604 //
6605 // update Kink quality information for mother after back propagation
6606 //
6607 if (seed->GetKinkIndex(0)>=0) return;
6608 for (Int_t ikink=0;ikink<3;ikink++){
6609 Int_t index = seed->GetKinkIndex(ikink);
6610 if (index>=0) break;
51ad6848 6611 index = TMath::Abs(index)-1;
6612 AliESDkink * kink = fEvent->GetKink(index);
f941f7fa 6613 kink->SetTPCDensity(-1,0,0);
6614 kink->SetTPCDensity(1,0,1);
51ad6848 6615 //
eea478d3 6616 Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 6617 if (row0<15) row0=15;
6618 //
eea478d3 6619 Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 6620 if (row1>145) row1=145;
6621 //
6622 Int_t found,foundable,shared;
6623 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
f941f7fa 6624 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,0);
51ad6848 6625 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
f941f7fa 6626 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,1);
51ad6848 6627 }
6628
6629}
6630
829455ad 6631void AliTPCtracker::UpdateKinkQualityD(AliTPCseed * seed){
91162307 6632 //
eea478d3 6633 // update Kink quality information for daughter after refit
91162307 6634 //
eea478d3 6635 if (seed->GetKinkIndex(0)<=0) return;
6636 for (Int_t ikink=0;ikink<3;ikink++){
6637 Int_t index = seed->GetKinkIndex(ikink);
6638 if (index<=0) break;
6639 index = TMath::Abs(index)-1;
6640 AliESDkink * kink = fEvent->GetKink(index);
f941f7fa 6641 kink->SetTPCDensity(-1,1,0);
6642 kink->SetTPCDensity(-1,1,1);
91162307 6643 //
eea478d3 6644 Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6645 if (row0<15) row0=15;
6646 //
6647 Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6648 if (row1>145) row1=145;
6649 //
6650 Int_t found,foundable,shared;
6651 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
f941f7fa 6652 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,0);
eea478d3 6653 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
f941f7fa 6654 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,1);
91162307 6655 }
eea478d3 6656
6657}
6658
6659
829455ad 6660Int_t AliTPCtracker::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
eea478d3 6661{
91162307 6662 //
eea478d3 6663 // check kink point for given track
6664 // if return value=0 kink point not found
6665 // otherwise seed0 correspond to mother particle
6666 // seed1 correspond to daughter particle
6667 // kink parameter of kink point
6c94f330 6668 AliKink &kink=(AliKink &)knk;
91162307 6669
b9671574 6670 Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
6671 Int_t first = seed->GetFirstPoint();
6672 Int_t last = seed->GetLastPoint();
eea478d3 6673 if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
91162307 6674
eea478d3 6675
6676 AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
6677 if (!seed1) return 0;
b9671574 6678 FollowProlongation(*seed1,seed->GetLastPoint()-20);
eea478d3 6679 seed1->Reset(kTRUE);
6680 FollowProlongation(*seed1,158);
6681 seed1->Reset(kTRUE);
b9671574 6682 last = seed1->GetLastPoint();
eea478d3 6683 //
ddfbc51a 6684 AliTPCseed *seed0 = new( NextFreeSeed() ) AliTPCseed(*seed);
6685 seed0->SetPoolID(fLastSeedID);
eea478d3 6686 seed0->Reset(kFALSE);
6687 seed0->Reset();
6688 //
6689 AliTPCseed param0[20]; // parameters along the track
6690 AliTPCseed param1[20]; // parameters along the track
6c94f330 6691 AliKink kinks[20]; // corresponding kink parameters
eea478d3 6692 Int_t rows[20];
6693 for (Int_t irow=0; irow<20;irow++){
6694 rows[irow] = first +((last-first)*irow)/19;
6695 }
6696 // store parameters along the track
6697 //
6698 for (Int_t irow=0;irow<20;irow++){
6699 FollowBackProlongation(*seed0, rows[irow]);
6700 FollowProlongation(*seed1,rows[19-irow]);
316c6cd9 6701 param0[irow] = *seed0;
6702 param1[19-irow] = *seed1;
eea478d3 6703 }
6704 //
6705 // define kinks
6706 for (Int_t irow=0; irow<19;irow++){
6707 kinks[irow].SetMother(param0[irow]);
6708 kinks[irow].SetDaughter(param1[irow]);
6709 kinks[irow].Update();
6710 }
6711 //
6712 // choose kink with biggest change of angle
6713 Int_t index =-1;
6714 Double_t maxchange= 0;
6715 for (Int_t irow=1;irow<19;irow++){
6716 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
6717 if (TMath::Abs(kinks[irow].GetR())<110.) continue;
6c94f330 6718 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 6719 if ( quality > maxchange){
6720 maxchange = quality;
6721 index = irow;
6722 //
91162307 6723 }
6724 }
ddfbc51a 6725 MarkSeedFree( seed0 );
6726 MarkSeedFree( seed1 );
eea478d3 6727 if (index<0) return 0;
6728 //
6729 Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
ddfbc51a 6730 seed0 = new( NextFreeSeed() ) AliTPCseed(param0[index]);
6731 seed0->SetPoolID(fLastSeedID);
6732 seed1 = new( NextFreeSeed() ) AliTPCseed(param1[index]);
6733 seed1->SetPoolID(fLastSeedID);
eea478d3 6734 seed0->Reset(kFALSE);
6735 seed1->Reset(kFALSE);
6c94f330 6736 seed0->ResetCovariance(10.);
6737 seed1->ResetCovariance(10.);
eea478d3 6738 FollowProlongation(*seed0,0);
6739 FollowBackProlongation(*seed1,158);
316c6cd9 6740 mother = *seed0; // backup mother at position 0
eea478d3 6741 seed0->Reset(kFALSE);
6742 seed1->Reset(kFALSE);
6c94f330 6743 seed0->ResetCovariance(10.);
6744 seed1->ResetCovariance(10.);
eea478d3 6745 //
6746 first = TMath::Max(row0-20,0);
6747 last = TMath::Min(row0+20,158);
6748 //
6749 for (Int_t irow=0; irow<20;irow++){
6750 rows[irow] = first +((last-first)*irow)/19;
6751 }
6752 // store parameters along the track
6753 //
6754 for (Int_t irow=0;irow<20;irow++){
6755 FollowBackProlongation(*seed0, rows[irow]);
6756 FollowProlongation(*seed1,rows[19-irow]);
316c6cd9 6757 param0[irow] = *seed0;
6758 param1[19-irow] = *seed1;
eea478d3 6759 }
6760 //
6761 // define kinks
6762 for (Int_t irow=0; irow<19;irow++){
6763 kinks[irow].SetMother(param0[irow]);
6764 kinks[irow].SetDaughter(param1[irow]);
6765 // param0[irow].Dump();
6766 //param1[irow].Dump();
6767 kinks[irow].Update();
6768 }
6769 //
6770 // choose kink with biggest change of angle
6771 index =-1;
6772 maxchange= 0;
6773 for (Int_t irow=0;irow<20;irow++){
6774 if (TMath::Abs(kinks[irow].GetR())>250.) continue;
6775 if (TMath::Abs(kinks[irow].GetR())<90.) continue;
6c94f330 6776 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 6777 if ( quality > maxchange){
6778 maxchange = quality;
6779 index = irow;
6780 //
91162307 6781 }
6782 }
6783 //
6784 //
b9671574 6785 if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
ddfbc51a 6786 MarkSeedFree( seed0 );
6787 MarkSeedFree( seed1 );
eea478d3 6788 return 0;
1627d1c4 6789 }
16299eac 6790
eea478d3 6791 // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
1627d1c4 6792
eea478d3 6793 kink.SetMother(param0[index]);
6794 kink.SetDaughter(param1[index]);
6795 kink.Update();
16299eac 6796
6797 Double_t chi2P2 = param0[index].GetParameter()[2]-param1[index].GetParameter()[2];
6798 chi2P2*=chi2P2;
6799 chi2P2/=param0[index].GetCovariance()[5]+param1[index].GetCovariance()[5];
6800 Double_t chi2P3 = param0[index].GetParameter()[3]-param1[index].GetParameter()[3];
6801 chi2P3*=chi2P3;
6802 chi2P3/=param0[index].GetCovariance()[9]+param1[index].GetCovariance()[9];
6803 //
6804 if (AliTPCReconstructor::StreamLevel()>1) {
6805 (*fDebugStreamer)<<"kinkHpt"<<
6806 "chi2P2="<<chi2P2<<
6807 "chi2P3="<<chi2P3<<
6808 "p0.="<<&param0[index]<<
6809 "p1.="<<&param1[index]<<
6810 "k.="<<&kink<<
6811 "\n";
6812 }
6813 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
ddfbc51a 6814 MarkSeedFree( seed0 );
6815 MarkSeedFree( seed1 );
16299eac 6816 return 0;
6817 }
6818
6819
eea478d3 6820 row0 = GetRowNumber(kink.GetR());
6821 kink.SetTPCRow0(row0);
6822 kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
6823 kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
6824 kink.SetIndex(-10,0);
b9671574 6825 kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
6826 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
6827 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
eea478d3 6828 //
6829 //
6830 // new (&mother) AliTPCseed(param0[index]);
316c6cd9 6831 daughter = param1[index];
eea478d3 6832 daughter.SetLabel(kink.GetLabel(1));
6833 param0[index].Reset(kTRUE);
16299eac 6834 FollowProlongation(param0[index],0);
316c6cd9 6835 mother = param0[index];
eea478d3 6836 mother.SetLabel(kink.GetLabel(0));
16299eac 6837 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(1)){
6838 mother=*seed;
6839 }
ddfbc51a 6840 MarkSeedFree( seed0 );
6841 MarkSeedFree( seed1 );
eea478d3 6842 //
6843 return 1;
1627d1c4 6844}
6845
6846
6847
6848
829455ad 6849AliTPCseed* AliTPCtracker::ReSeed(AliTPCseed *t)
91162307 6850{
6851 //
6852 // reseed - refit - track
6853 //
6854 Int_t first = 0;
6855 // Int_t last = fSectors->GetNRows()-1;
6856 //
6857 if (fSectors == fOuterSec){
b9671574 6858 first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
91162307 6859 //last =
6860 }
6861 else
b9671574 6862 first = t->GetFirstPoint();
91162307 6863 //
6864 AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
6865 FollowBackProlongation(*t,fSectors->GetNRows()-1);
6866 t->Reset(kFALSE);
6867 FollowProlongation(*t,first);
6868 return seed;
6869}
6870
6871
6872
6873
6874
6875
6876
1c53abe2 6877//_____________________________________________________________________________
829455ad 6878Int_t AliTPCtracker::ReadSeeds(const TFile *inp) {
1c53abe2 6879 //-----------------------------------------------------------------
6880 // This function reades track seeds.
6881 //-----------------------------------------------------------------
6882 TDirectory *savedir=gDirectory;
6883
6884 TFile *in=(TFile*)inp;
6885 if (!in->IsOpen()) {
829455ad 6886 cerr<<"AliTPCtracker::ReadSeeds(): input file is not open !\n";
1c53abe2 6887 return 1;
6888 }
6889
6890 in->cd();
6891 TTree *seedTree=(TTree*)in->Get("Seeds");
6892 if (!seedTree) {
829455ad 6893 cerr<<"AliTPCtracker::ReadSeeds(): ";
1c53abe2 6894 cerr<<"can't get a tree with track seeds !\n";
6895 return 2;
6896 }
6897 AliTPCtrack *seed=new AliTPCtrack;
6898 seedTree->SetBranchAddress("tracks",&seed);
6899
6900 if (fSeeds==0) fSeeds=new TObjArray(15000);
6901
6902 Int_t n=(Int_t)seedTree->GetEntries();
6903 for (Int_t i=0; i<n; i++) {
6904 seedTree->GetEvent(i);
ddfbc51a 6905 AliTPCseed* sdc = new( NextFreeSeed() ) AliTPCseed(*seed/*,seed->GetAlpha()*/);
6906 sdc->SetPoolID(fLastSeedID);
f06a1ff6 6907 fSeeds->AddLast(sdc);
1c53abe2 6908 }
6909
f06a1ff6 6910 delete seed; // RS: this seed is not from the pool, delete it !!!
1c53abe2 6911 delete seedTree;
6912 savedir->cd();
6913 return 0;
6914}
6915
829455ad 6916Int_t AliTPCtracker::Clusters2TracksHLT (AliESDEvent *const esd, const AliESDEvent *hltEvent)
d26d9159 6917{
6918 //
544c295f 6919 // clusters to tracks
d9b8978b 6920 if (fSeeds) DeleteSeeds();
ddfbc51a 6921 else ResetSeedsPool();
e1dadcd0 6922 fEvent = esd;
72e25240 6923 fEventHLT = hltEvent;
e1dadcd0 6924
6925 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
6926 transform->SetCurrentTimeStamp( esd->GetTimeStamp());
6927 transform->SetCurrentRun(esd->GetRunNumber());
6928
d26d9159 6929 Clusters2Tracks();
72e25240 6930 fEventHLT = 0;
d26d9159 6931 if (!fSeeds) return 1;
6932 FillESD(fSeeds);
f47588e0 6933 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(0,fSeeds);
d26d9159 6934 return 0;
6935 //
6936}
6937
829455ad 6938Int_t AliTPCtracker::Clusters2Tracks(AliESDEvent *const esd)
72e25240 6939{
6940 //
6941 // clusters to tracks
6942 return Clusters2TracksHLT( esd, 0);
6943}
d26d9159 6944
1c53abe2 6945//_____________________________________________________________________________
829455ad 6946Int_t AliTPCtracker::Clusters2Tracks() {
1c53abe2 6947 //-----------------------------------------------------------------
6948 // This is a track finder.
6949 //-----------------------------------------------------------------
91162307 6950 TDirectory *savedir=gDirectory;
1c53abe2 6951 TStopwatch timer;
d26d9159 6952
91162307 6953 fIteration = 0;
6954 fSeeds = Tracking();
1c53abe2 6955
6bdc18d6 6956 if (fDebug>0){
6957 Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
6958 }
91162307 6959 //activate again some tracks
6960 for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
6961 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6962 if (!pt) continue;
6963 Int_t nc=t.GetNumberOfClusters();
6964 if (nc<20) {
ddfbc51a 6965 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 6966 continue;
eea478d3 6967 }
f5cbf2ef 6968 CookLabel(pt,0.1);
b9671574 6969 if (pt->GetRemoval()==10) {
91162307 6970 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
bad6eb00 6971 pt->Desactivate(10); // make track again active // MvL: should be 0 ?
91162307 6972 else{
6973 pt->Desactivate(20);
ddfbc51a 6974 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 6975 }
6976 }
6977 }
51ad6848 6978 //
6979 RemoveUsed2(fSeeds,0.85,0.85,0);
a3232aae 6980 if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
6d493ea0 6981 //FindCurling(fSeeds, fEvent,0);
16299eac 6982 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,-1); // find multi found tracks
81e97e0d 6983 RemoveUsed2(fSeeds,0.5,0.4,20);
1af5da7e 6984 FindSplitted(fSeeds, fEvent,0); // find multi found tracks
16299eac 6985 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
6d493ea0 6986
81e97e0d 6987 // //
6988// // refit short tracks
6989// //
6990 Int_t nseed=fSeeds->GetEntriesFast();
1c53abe2 6991 //
91162307 6992 Int_t found = 0;
6993 for (Int_t i=0; i<nseed; i++) {
6994 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6995 if (!pt) continue;
6996 Int_t nc=t.GetNumberOfClusters();
6997 if (nc<15) {
ddfbc51a 6998 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 6999 continue;
7000 }
7001 CookLabel(pt,0.1); //For comparison only
7002 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 7003 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
d9b8978b 7004 found++;
7005 if (fDebug>0) cerr<<found<<'\r';
b9671574 7006 pt->SetLab2(i);
91162307 7007 }
7008 else
ddfbc51a 7009 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7010 }
7011
7012
7013 //RemoveOverlap(fSeeds,0.99,7,kTRUE);
7014 SignShared(fSeeds);
7015 //RemoveUsed(fSeeds,0.9,0.9,6);
1c53abe2 7016 //
91162307 7017 nseed=fSeeds->GetEntriesFast();
7018 found = 0;
7019 for (Int_t i=0; i<nseed; i++) {
7020 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7021 if (!pt) continue;
7022 Int_t nc=t.GetNumberOfClusters();
7023 if (nc<15) {
ddfbc51a 7024 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7025 continue;
7026 }
7027 t.SetUniqueID(i);
7028 t.CookdEdx(0.02,0.6);
7029 // CheckKinkPoint(&t,0.05);
7030 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 7031 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6bdc18d6 7032 found++;
7033 if (fDebug>0){
7034 cerr<<found<<'\r';
7035 }
b9671574 7036 pt->SetLab2(i);
91162307 7037 }
7038 else
ddfbc51a 7039 MarkSeedFree( fSeeds->RemoveAt(i) );
d26d9159 7040 //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
7041 //if (seed1){
7042 // FollowProlongation(*seed1,0);
7043 // Int_t n = seed1->GetNumberOfClusters();
7044 // printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
7045 // printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
7046 //
7047 //}
7048 //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
7049
91162307 7050 }
7051
7052 SortTracks(fSeeds, 1);
1c53abe2 7053
982aff31 7054 /*
91162307 7055 fIteration = 1;
982aff31 7056 PrepareForBackProlongation(fSeeds,5.);
91162307 7057 PropagateBack(fSeeds);
7058 printf("Time for back propagation: \t");timer.Print();timer.Start();
7059
7060 fIteration = 2;
1c53abe2 7061
982aff31 7062 PrepareForProlongation(fSeeds,5.);
f124f8bf 7063 PropagateForard2(fSeeds);
d26d9159 7064
91162307 7065 printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
7066 // RemoveUsed(fSeeds,0.7,0.7,6);
7067 //RemoveOverlap(fSeeds,0.9,7,kTRUE);
d26d9159 7068
1c53abe2 7069 nseed=fSeeds->GetEntriesFast();
91162307 7070 found = 0;
7071 for (Int_t i=0; i<nseed; i++) {
1c53abe2 7072 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7073 if (!pt) continue;
7074 Int_t nc=t.GetNumberOfClusters();
91162307 7075 if (nc<15) {
ddfbc51a 7076 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7077 continue;
7078 }
1c53abe2 7079 t.CookdEdx(0.02,0.6);
91162307 7080 // CookLabel(pt,0.1); //For comparison only
7081 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
7082 if ((pt->IsActive() || (pt->fRemoval==10) )){
7083 cerr<<found++<<'\r';
7084 }
7085 else
ddfbc51a 7086 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7087 pt->fLab2 = i;
1c53abe2 7088 }
91162307 7089 */
7090
c9427e08 7091 // fNTracks = found;
6bdc18d6 7092 if (fDebug>0){
7093 Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
7094 }
91162307 7095 //
6bdc18d6 7096 // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
7097 Info("Clusters2Tracks","Number of found tracks %d",found);
91162307 7098 savedir->cd();
91162307 7099 // UnloadClusters();
d26d9159 7100 //
1c53abe2 7101 return 0;
7102}
7103
829455ad 7104void AliTPCtracker::Tracking(TObjArray * arr)
91162307 7105{
7106 //
7107 // tracking of the seeds
7108 //
7109
7110 fSectors = fOuterSec;
7111 ParallelTracking(arr,150,63);
7112 fSectors = fOuterSec;
7113 ParallelTracking(arr,63,0);
7114}
7115
829455ad 7116TObjArray * AliTPCtracker::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
91162307 7117{
7118 //
7119 //
7120 //tracking routine
f06a1ff6 7121 static TObjArray arrTracks;
7122 TObjArray * arr = &arrTracks;
91162307 7123 //
7124 fSectors = fOuterSec;
7125 TStopwatch timer;
7126 timer.Start();
7127 for (Int_t sec=0;sec<fkNOS;sec++){
7128 if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
7129 if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);
7130 if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
7131 }
7132 if (fDebug>0){
6bdc18d6 7133 Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
91162307 7134 timer.Print();
7135 timer.Start();
7136 }
7137 Tracking(arr);
7138 if (fDebug>0){
7139 timer.Print();
7140 }
7141
7142 return arr;
7143}
7144
829455ad 7145TObjArray * AliTPCtracker::Tracking()
91162307 7146{
544c295f 7147 // tracking
91162307 7148 //
a3232aae 7149 if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
91162307 7150 TStopwatch timer;
7151 timer.Start();
7152 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7153
7154 TObjArray * seeds = new TObjArray;
7155 TObjArray * arr=0;
6d1424d5 7156 Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
7157 Int_t gapPrim = AliTPCReconstructor::GetRecoParam()->GetSeedGapPrim();
7158 Int_t gapSec = AliTPCReconstructor::GetRecoParam()->GetSeedGapSec();
91162307 7159
7160 Int_t gap =20;
7161 Float_t cuts[4];
7162 cuts[0] = 0.002;
7163 cuts[1] = 1.5;
7164 cuts[2] = 3.;
7165 cuts[3] = 3.;
7166 Float_t fnumber = 3.0;
7167 Float_t fdensity = 3.0;
72e25240 7168
7169 // make HLT seeds
fa90aa2b 7170 if (AliTPCReconstructor::GetRecoParam()->GetUseHLTPreSeeding()) {
72e25240 7171 arr = MakeSeedsHLT( fEventHLT );
7172 if( arr ){
7173 SumTracks(seeds,arr);
7174 delete arr;
7175 arr=0;
7176 //cout<<"HLT tracks left after sorting: "<<seeds->GetEntriesFast()<<endl;
7177 //SignClusters(seeds,fnumber,fdensity);
7178 }
7179 }
91162307 7180
7181 //
7182 //find primaries
7183 cuts[0]=0.0066;
6d1424d5 7184 for (Int_t delta = 0; delta<18; delta+=gapPrim){
91162307 7185 //
7186 cuts[0]=0.0070;
7187 cuts[1] = 1.5;
7188 arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
7189 SumTracks(seeds,arr);
7190 SignClusters(seeds,fnumber,fdensity);
7191 //
7192 for (Int_t i=2;i<6;i+=2){
7193 // seed high pt tracks
7194 cuts[0]=0.0022;
7195 cuts[1]=0.3;
7196 arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
7197 SumTracks(seeds,arr);
7198 SignClusters(seeds,fnumber,fdensity);
7199 }
7200 }
7201 fnumber = 4;
7202 fdensity = 4.;
7203 // RemoveUsed(seeds,0.9,0.9,1);
7204 // UnsignClusters();
7205 // SignClusters(seeds,fnumber,fdensity);
7206
7207 //find primaries
7208 cuts[0]=0.0077;
6d1424d5 7209 for (Int_t delta = 20; delta<120; delta+=gapPrim){
91162307 7210 //
7211 // seed high pt tracks
7212 cuts[0]=0.0060;
7213 cuts[1]=0.3;
7214 cuts[2]=6.;
7215 arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
7216 SumTracks(seeds,arr);
7217 SignClusters(seeds,fnumber,fdensity);
7218
7219 cuts[0]=0.003;
7220 cuts[1]=0.3;
7221 cuts[2]=6.;
7222 arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
7223 SumTracks(seeds,arr);
7224 SignClusters(seeds,fnumber,fdensity);
7225 }
7226
7227 cuts[0] = 0.01;
7228 cuts[1] = 2.0;
7229 cuts[2] = 3.;
7230 cuts[3] = 2.0;
7231 fnumber = 2.;
7232 fdensity = 2.;
7233
7234 if (fDebug>0){
6bdc18d6 7235 Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 7236 timer.Print();
7237 timer.Start();
7238 }
7239 // RemoveUsed(seeds,0.75,0.75,1);
7240 //UnsignClusters();
7241 //SignClusters(seeds,fnumber,fdensity);
7242
7243 // find secondaries
7244
7245 cuts[0] = 0.3;
7246 cuts[1] = 1.5;
7247 cuts[2] = 3.;
7248 cuts[3] = 1.5;
7249
7250 arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
7251 SumTracks(seeds,arr);
7252 SignClusters(seeds,fnumber,fdensity);
7253 //
7254 arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
7255 SumTracks(seeds,arr);
7256 SignClusters(seeds,fnumber,fdensity);
7257 //
7258 arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
7259 SumTracks(seeds,arr);
7260 SignClusters(seeds,fnumber,fdensity);
7261 //
6d1424d5 7262 arr = Tracking(4,nup-5,nup-5-gap,cuts,-1);
7263 SumTracks(seeds,arr);
7264 SignClusters(seeds,fnumber,fdensity);
7265 //
7266 arr = Tracking(4,nup-7,nup-7-gap,cuts,-1);
7267 SumTracks(seeds,arr);
7268 SignClusters(seeds,fnumber,fdensity);
7269 //
7270 //
7271 arr = Tracking(4,nup-9,nup-9-gap,cuts,-1);
7272 SumTracks(seeds,arr);
7273 SignClusters(seeds,fnumber,fdensity);
7274 //
91162307 7275
7276
6d1424d5 7277 for (Int_t delta = 9; delta<30; delta+=gapSec){
91162307 7278 //
7279 cuts[0] = 0.3;
7280 cuts[1] = 1.5;
7281 cuts[2] = 3.;
7282 cuts[3] = 1.5;
7283 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7284 SumTracks(seeds,arr);
7285 SignClusters(seeds,fnumber,fdensity);
7286 //
7287 arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
7288 SumTracks(seeds,arr);
7289 SignClusters(seeds,fnumber,fdensity);
7290 //
7291 }
7292 fnumber = 1;
7293 fdensity = 1;
7294 //
7295 // change cuts
7296 fnumber = 2.;
7297 fdensity = 2.;
7298 cuts[0]=0.0080;
7299
7d27c1df 7300
91162307 7301 // find secondaries
6d1424d5 7302 for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=gapSec){
91162307 7303 //
7304 cuts[0] = 0.3;
2bd61959 7305 cuts[1] = 3.5;
91162307 7306 cuts[2] = 3.;
2bd61959 7307 cuts[3] = 3.5;
91162307 7308 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7309 SumTracks(seeds,arr);
7310 SignClusters(seeds,fnumber,fdensity);
7311 //
7312 arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
7313 SumTracks(seeds,arr);
7314 SignClusters(seeds,fnumber,fdensity);
7315 }
7316
7317 if (fDebug>0){
6bdc18d6 7318 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 7319 timer.Print();
7320 timer.Start();
7321 }
7322
7323 return seeds;
7324 //
7325
7326}
7327
7328
829455ad 7329TObjArray * AliTPCtracker::TrackingSpecial()
a3232aae 7330{
7331 //
7332 // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
7333 // no primary vertex seeding tried
7334 //
7335 TStopwatch timer;
7336 timer.Start();
7337 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7338
7339 TObjArray * seeds = new TObjArray;
7340 TObjArray * arr=0;
7341
7342 Int_t gap = 15;
7343 Float_t cuts[4];
7344 Float_t fnumber = 3.0;
7345 Float_t fdensity = 3.0;
7346
7347 // find secondaries
7348 cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC(); // max curvature
7349 cuts[1] = 3.5; // max tan(phi) angle for seeding
7350 cuts[2] = 3.; // not used (cut on z primary vertex)
7351 cuts[3] = 3.5; // max tan(theta) angle for seeding
7352
7353 for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
7354 //
7355 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7356 SumTracks(seeds,arr);
7357 SignClusters(seeds,fnumber,fdensity);
7358 }
7359
7360 if (fDebug>0){
7361 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
7362 timer.Print();
7363 timer.Start();
7364 }
7365
7366 return seeds;
7367 //
7368
7369}
7370
7371
829455ad 7372void AliTPCtracker::SumTracks(TObjArray *arr1,TObjArray *&arr2)
91162307 7373{
7374 //
7375 //sum tracks to common container
7376 //remove suspicious tracks
f06a1ff6 7377 // RS: Attention: supplied tracks come in the static array, don't delete them
91162307 7378 Int_t nseed = arr2->GetEntriesFast();
7379 for (Int_t i=0;i<nseed;i++){
7380 AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);
7381 if (pt){
a3232aae 7382 //
7383 // remove tracks with too big curvature
7384 //
7385 if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
ddfbc51a 7386 MarkSeedFree( arr2->RemoveAt(i) );
a3232aae 7387 continue;
7388 }
ca142b1f 7389 // REMOVE VERY SHORT TRACKS
7390 if (pt->GetNumberOfClusters()<20){
ddfbc51a 7391 MarkSeedFree( arr2->RemoveAt(i) );
ca142b1f 7392 continue;
7393 }// patch 28 fev06
91162307 7394 // NORMAL ACTIVE TRACK
7395 if (pt->IsActive()){
7396 arr1->AddLast(arr2->RemoveAt(i));
7397 continue;
7398 }
7399 //remove not usable tracks
b9671574 7400 if (pt->GetRemoval()!=10){
ddfbc51a 7401 MarkSeedFree( arr2->RemoveAt(i) );
91162307 7402 continue;
7403 }
ca142b1f 7404
91162307 7405 // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
7406 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
7407 arr1->AddLast(arr2->RemoveAt(i));
7408 else{
ddfbc51a 7409 MarkSeedFree( arr2->RemoveAt(i) );
91162307 7410 }
7411 }
7412 }
f06a1ff6 7413 // delete arr2; arr2 = 0; // RS: this is static array, don't delete it
91162307 7414}
7415
7416
1c53abe2 7417
829455ad 7418void AliTPCtracker::ParallelTracking(TObjArray *const arr, Int_t rfirst, Int_t rlast)
1c53abe2 7419{
7420 //
7421 // try to track in parralel
7422
91162307 7423 Int_t nseed=arr->GetEntriesFast();
1c53abe2 7424 //prepare seeds for tracking
7425 for (Int_t i=0; i<nseed; i++) {
91162307 7426 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 7427 if (!pt) continue;
7428 if (!t.IsActive()) continue;
7429 // follow prolongation to the first layer
47af7ca4 7430 if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fkParam->GetNRowLow()>rfirst+1) )
c9427e08 7431 FollowProlongation(t, rfirst+1);
1c53abe2 7432 }
7433
7434
7435 //
982aff31 7436 for (Int_t nr=rfirst; nr>=rlast; nr--){
7437 if (nr<fInnerSec->GetNRows())
7438 fSectors = fInnerSec;
7439 else
7440 fSectors = fOuterSec;
1c53abe2 7441 // make indexes with the cluster tracks for given
1c53abe2 7442
7443 // find nearest cluster
7444 for (Int_t i=0; i<nseed; i++) {
91162307 7445 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 7446 if (!pt) continue;
51ad6848 7447 if (nr==80) pt->UpdateReference();
1c53abe2 7448 if (!pt->IsActive()) continue;
47af7ca4 7449 // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
b9671574 7450 if (pt->GetRelativeSector()>17) {
1627d1c4 7451 continue;
7452 }
91162307 7453 UpdateClusters(t,nr);
1c53abe2 7454 }
7455 // prolonagate to the nearest cluster - if founded
7456 for (Int_t i=0; i<nseed; i++) {
91162307 7457 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
1c53abe2 7458 if (!pt) continue;
1627d1c4 7459 if (!pt->IsActive()) continue;
47af7ca4 7460 // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
b9671574 7461 if (pt->GetRelativeSector()>17) {
1627d1c4 7462 continue;
7463 }
91162307 7464 FollowToNextCluster(*pt,nr);
1c53abe2 7465 }
91162307 7466 }
7467}
7468
829455ad 7469void AliTPCtracker::PrepareForBackProlongation(const TObjArray *const arr,Float_t fac) const
91162307 7470{
7471 //
7472 //
7473 // if we use TPC track itself we have to "update" covariance
7474 //
7475 Int_t nseed= arr->GetEntriesFast();
7476 for (Int_t i=0;i<nseed;i++){
7477 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7478 if (pt) {
7479 pt->Modify(fac);
7480 //
7481 //rotate to current local system at first accepted point
b9671574 7482 Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
91162307 7483 Int_t sec = (index&0xff000000)>>24;
7484 sec = sec%18;
7485 Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
7486 if (angle1>TMath::Pi())
7487 angle1-=2.*TMath::Pi();
7488 Float_t angle2 = pt->GetAlpha();
7489
7490 if (TMath::Abs(angle1-angle2)>0.001){
17abbffb 7491 if (!pt->Rotate(angle1-angle2)) return;
91162307 7492 //angle2 = pt->GetAlpha();
7493 //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
7494 //if (pt->GetAlpha()<0)
7495 // pt->fRelativeSector+=18;
7496 //sec = pt->fRelativeSector;
7497 }
7498
7499 }
7500
7501 }
7502
7503
7504}
829455ad 7505void AliTPCtracker::PrepareForProlongation(TObjArray *const arr, Float_t fac) const
91162307 7506{
7507 //
7508 //
7509 // if we use TPC track itself we have to "update" covariance
7510 //
7511 Int_t nseed= arr->GetEntriesFast();
7512 for (Int_t i=0;i<nseed;i++){
7513 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7514 if (pt) {
7515 pt->Modify(fac);
b9671574 7516 pt->SetFirstPoint(pt->GetLastPoint());
91162307 7517 }
7518
7519 }
7520
7521
7522}
7523
829455ad 7524Int_t AliTPCtracker::PropagateBack(const TObjArray *const arr)
91162307 7525{
7526 //
7527 // make back propagation
7528 //
7529 Int_t nseed= arr->GetEntriesFast();
7530 for (Int_t i=0;i<nseed;i++){
7531 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
51ad6848 7532 if (pt&& pt->GetKinkIndex(0)<=0) {
d9b8978b 7533 //AliTPCseed *pt2 = new AliTPCseed(*pt);
91162307 7534 fSectors = fInnerSec;
d26d9159 7535 //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
7536 //fSectors = fOuterSec;
f124f8bf 7537 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
4d158c36 7538 //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
d9b8978b 7539 // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
4d158c36 7540 // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
d9b8978b 7541 //}
51ad6848 7542 }
7543 if (pt&& pt->GetKinkIndex(0)>0) {
7544 AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
b9671574 7545 pt->SetFirstPoint(kink->GetTPCRow0());
51ad6848 7546 fSectors = fInnerSec;
f124f8bf 7547 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
51ad6848 7548 }
6d493ea0 7549 CookLabel(pt,0.3);
91162307 7550 }
7551 return 0;
7552}
7553
7554
829455ad 7555Int_t AliTPCtracker::PropagateForward2(const TObjArray *const arr)
91162307 7556{
7557 //
7558 // make forward propagation
7559 //
7560 Int_t nseed= arr->GetEntriesFast();
4d158c36 7561 //
91162307 7562 for (Int_t i=0;i<nseed;i++){
7563 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7564 if (pt) {
f124f8bf 7565 FollowProlongation(*pt,0,1,1);
6d493ea0 7566 CookLabel(pt,0.3);
4d158c36 7567 }
6d493ea0 7568
91162307 7569 }
f124f8bf 7570 return 0;
91162307 7571}
7572
7573
829455ad 7574Int_t AliTPCtracker::PropagateForward()
91162307 7575{
b67e07dc 7576 //
7577 // propagate track forward
4d158c36 7578 //UnsignClusters();
d26d9159 7579 Int_t nseed = fSeeds->GetEntriesFast();
7580 for (Int_t i=0;i<nseed;i++){
7581 AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
7582 if (pt){
7583 AliTPCseed &t = *pt;
7584 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
7585 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
7586 if (alpha < 0. ) alpha += 2.*TMath::Pi();
b9671574 7587 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
d26d9159 7588 }
7589 }
7590
91162307 7591 fSectors = fOuterSec;
d26d9159 7592 ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
91162307 7593 fSectors = fInnerSec;
d26d9159 7594 ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
91162307 7595 return 1;
7596}
7597
7598
7599
7600
7601
7602
829455ad 7603Int_t AliTPCtracker::PropagateBack(AliTPCseed *const pt, Int_t row0, Int_t row1)
91162307 7604{
7605 //
7606 // make back propagation, in between row0 and row1
7607 //
1c53abe2 7608
91162307 7609 if (pt) {
7610 fSectors = fInnerSec;
7611 Int_t r1;
7612 //
7613 if (row1<fSectors->GetNRows())
7614 r1 = row1;
7615 else
7616 r1 = fSectors->GetNRows()-1;
7617
7618 if (row0<fSectors->GetNRows()&& r1>0 )
7619 FollowBackProlongation(*pt,r1);
7620 if (row1<=fSectors->GetNRows())
7621 return 0;
7622 //
7623 r1 = row1 - fSectors->GetNRows();
7624 if (r1<=0) return 0;
7625 if (r1>=fOuterSec->GetNRows()) return 0;
7626 fSectors = fOuterSec;
7627 return FollowBackProlongation(*pt,r1);
7628 }
7629 return 0;
7630}
7631
7632
7633
7634
829455ad 7635void AliTPCtracker::GetShape(AliTPCseed * seed, Int_t row)
91162307 7636{
544c295f 7637 // gets cluster shape
fd065ea2 7638 //
7639 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
47af7ca4 7640 Float_t zdrift = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())));
7641 Int_t type = (seed->GetSector() < fkParam->GetNSector()/2) ? 0: (row>126) ? 1:2;
3f82c4f2 7642 Double_t angulary = seed->GetSnp();
feed67f9 7643
7644 if (TMath::Abs(angulary)>AliTPCReconstructor::GetMaxSnpTracker()) {
7645 angulary = TMath::Sign(AliTPCReconstructor::GetMaxSnpTracker(),angulary);
7646 }
7647
bfd20868 7648 angulary = angulary*angulary/((1.-angulary)*(1.+angulary));
fd065ea2 7649 Double_t angularz = seed->GetTgl()*seed->GetTgl()*(1.+angulary);
7650
e0e13b88 7651 Double_t sigmay = clparam->GetRMS0(0,type,zdrift,TMath::Sqrt(TMath::Abs(angulary)));
7652 Double_t sigmaz = clparam->GetRMS0(1,type,zdrift,TMath::Sqrt(TMath::Abs(angularz)));
fd065ea2 7653 seed->SetCurrentSigmaY2(sigmay*sigmay);
7654 seed->SetCurrentSigmaZ2(sigmaz*sigmaz);
47af7ca4 7655 // Float_t sd2 = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fkParam->GetDiffL()*fkParam->GetDiffL();
7656// // Float_t padlength = fkParam->GetPadPitchLength(seed->fSector);
fd065ea2 7657// Float_t padlength = GetPadPitchLength(row);
7658// //
47af7ca4 7659// Float_t sresy = (seed->GetSector() < fkParam->GetNSector()/2) ? 0.2 :0.3;
fd065ea2 7660// seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
7661// //
47af7ca4 7662// Float_t sresz = fkParam->GetZSigma();
fd065ea2 7663// seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
91162307 7664 /*
7665 Float_t wy = GetSigmaY(seed);
7666 Float_t wz = GetSigmaZ(seed);
7667 wy*=wy;
7668 wz*=wz;
7669 if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
7670 printf("problem\n");
7671 }
7672 */
1c53abe2 7673}
7674
91162307 7675
1c53abe2 7676
1c53abe2 7677//__________________________________________________________________________
829455ad 7678void AliTPCtracker::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
1c53abe2 7679 //--------------------------------------------------------------------
7680 //This function "cooks" a track label. If label<0, this track is fake.
7681 //--------------------------------------------------------------------
316c6cd9 7682 AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
7683 if(!t){
7684 printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
7685 return;
7686 }
7687
1c53abe2 7688 Int_t noc=t->GetNumberOfClusters();
91162307 7689 if (noc<10){
d26d9159 7690 //printf("\nnot founded prolongation\n\n\n");
7691 //t->Dump();
91162307 7692 return ;
7693 }
7694 Int_t lb[160];
7695 Int_t mx[160];
7696 AliTPCclusterMI *clusters[160];
7697 //
7698 for (Int_t i=0;i<160;i++) {
7699 clusters[i]=0;
7700 lb[i]=mx[i]=0;
7701 }
1c53abe2 7702
7703 Int_t i;
91162307 7704 Int_t current=0;
7705 for (i=0; i<160 && current<noc; i++) {
7706
7707 Int_t index=t->GetClusterIndex2(i);
7708 if (index<=0) continue;
7709 if (index&0x8000) continue;
7710 //
7711 //clusters[current]=GetClusterMI(index);
b9671574 7712 if (t->GetClusterPointer(i)){
7713 clusters[current]=t->GetClusterPointer(i);
91162307 7714 current++;
7715 }
1c53abe2 7716 }
91162307 7717 noc = current;
1c53abe2 7718
7719 Int_t lab=123456789;
7720 for (i=0; i<noc; i++) {
7721 AliTPCclusterMI *c=clusters[i];
91162307 7722 if (!c) continue;
1c53abe2 7723 lab=TMath::Abs(c->GetLabel(0));
7724 Int_t j;
7725 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
7726 lb[j]=lab;
7727 (mx[j])++;
7728 }
7729
7730 Int_t max=0;
7731 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
7732
7733 for (i=0; i<noc; i++) {
9918f10a 7734 AliTPCclusterMI *c=clusters[i];
91162307 7735 if (!c) continue;
1c53abe2 7736 if (TMath::Abs(c->GetLabel(1)) == lab ||
7737 TMath::Abs(c->GetLabel(2)) == lab ) max++;
7738 }
52033b55 7739 if (noc<=0) { lab=-1; return;}
7740 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
1c53abe2 7741
7742 else {
7743 Int_t tail=Int_t(0.10*noc);
7744 max=0;
91162307 7745 Int_t ind=0;
ec26e231 7746 for (i=1; i<160&&ind<tail; i++) {
91162307 7747 // AliTPCclusterMI *c=clusters[noc-i];
7748 AliTPCclusterMI *c=clusters[i];
7749 if (!c) continue;
1c53abe2 7750 if (lab == TMath::Abs(c->GetLabel(0)) ||
7751 lab == TMath::Abs(c->GetLabel(1)) ||
7752 lab == TMath::Abs(c->GetLabel(2))) max++;
91162307 7753 ind++;
1c53abe2 7754 }
7755 if (max < Int_t(0.5*tail)) lab=-lab;
7756 }
7757
7758 t->SetLabel(lab);
7759
91162307 7760 // delete[] lb;
7761 //delete[] mx;
7762 //delete[] clusters;
1c53abe2 7763}
7764
47966a6d 7765
51ad6848 7766//__________________________________________________________________________
829455ad 7767Int_t AliTPCtracker::CookLabel(AliTPCseed *const t, Float_t wrong,Int_t first, Int_t last) const {
51ad6848 7768 //--------------------------------------------------------------------
7769 //This function "cooks" a track label. If label<0, this track is fake.
7770 //--------------------------------------------------------------------
7771 Int_t noc=t->GetNumberOfClusters();
7772 if (noc<10){
7773 //printf("\nnot founded prolongation\n\n\n");
7774 //t->Dump();
7775 return -1;
7776 }
7777 Int_t lb[160];
7778 Int_t mx[160];
7779 AliTPCclusterMI *clusters[160];
7780 //
7781 for (Int_t i=0;i<160;i++) {
7782 clusters[i]=0;
7783 lb[i]=mx[i]=0;
7784 }
7785
7786 Int_t i;
7787 Int_t current=0;
7788 for (i=0; i<160 && current<noc; i++) {
7789 if (i<first) continue;
7790 if (i>last) continue;
7791 Int_t index=t->GetClusterIndex2(i);
7792 if (index<=0) continue;
7793 if (index&0x8000) continue;
7794 //
7795 //clusters[current]=GetClusterMI(index);
b9671574 7796 if (t->GetClusterPointer(i)){
7797 clusters[current]=t->GetClusterPointer(i);
51ad6848 7798 current++;
7799 }
7800 }
7801 noc = current;
17abbffb 7802 //if (noc<5) return -1;
51ad6848 7803 Int_t lab=123456789;
7804 for (i=0; i<noc; i++) {
7805 AliTPCclusterMI *c=clusters[i];
7806 if (!c) continue;
7807 lab=TMath::Abs(c->GetLabel(0));
7808 Int_t j;
7809 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
7810 lb[j]=lab;
7811 (mx[j])++;
7812 }
7813
7814 Int_t max=0;
7815 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
7816
7817 for (i=0; i<noc; i++) {
7818 AliTPCclusterMI *c=clusters[i];
7819 if (!c) continue;
7820 if (TMath::Abs(c->GetLabel(1)) == lab ||
7821 TMath::Abs(c->GetLabel(2)) == lab ) max++;
7822 }
52033b55 7823 if (noc<=0) { lab=-1; return -1;}
7824 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
51ad6848 7825
7826 else {
7827 Int_t tail=Int_t(0.10*noc);
7828 max=0;
7829 Int_t ind=0;
ec26e231 7830 for (i=1; i<160&&ind<tail; i++) {
51ad6848 7831 // AliTPCclusterMI *c=clusters[noc-i];
7832 AliTPCclusterMI *c=clusters[i];
7833 if (!c) continue;
7834 if (lab == TMath::Abs(c->GetLabel(0)) ||
7835 lab == TMath::Abs(c->GetLabel(1)) ||
7836 lab == TMath::Abs(c->GetLabel(2))) max++;
7837 ind++;
7838 }
7839 if (max < Int_t(0.5*tail)) lab=-lab;
7840 }
7841
7842 // t->SetLabel(lab);
7843 return lab;
7844 // delete[] lb;
7845 //delete[] mx;
7846 //delete[] clusters;
7847}
7848
7849
829455ad 7850Int_t AliTPCtracker::GetRowNumber(Double_t x[3]) const
eea478d3 7851{
7852 //return pad row number for given x vector
7853 Float_t phi = TMath::ATan2(x[1],x[0]);
7854 if(phi<0) phi=2.*TMath::Pi()+phi;
7855 // Get the local angle in the sector philoc
7856 const Float_t kRaddeg = 180/3.14159265358979312;
7857 Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
7858 Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
7859 return GetRowNumber(localx);
7860}
7861
91162307 7862
91162307 7863
829455ad 7864void AliTPCtracker::MakeESDBitmaps(AliTPCseed *t, AliESDtrack *esd)
19b00333 7865{
7866 //-----------------------------------------------------------------------
7867 // Fill the cluster and sharing bitmaps of the track
7868 //-----------------------------------------------------------------------
7869
7870 Int_t firstpoint = 0;
7871 Int_t lastpoint = 159;
7872 AliTPCTrackerPoint *point;
52c51057 7873 AliTPCclusterMI *cluster;
19b00333 7874
bad6eb00 7875 Int_t nclsf = 0;
7876 TBits clusterMap(159);
7877 TBits sharedMap(159);
7878 TBits fitMap(159);
19b00333 7879 for (int iter=firstpoint; iter<lastpoint; iter++) {
52c51057 7880 // Change to cluster pointers to see if we have a cluster at given padrow
bad6eb00 7881
52c51057 7882 cluster = t->GetClusterPointer(iter);
7883 if (cluster) {
bad6eb00 7884 clusterMap.SetBitNumber(iter, kTRUE);
52c51057 7885 point = t->GetTrackPoint(iter);
19b00333 7886 if (point->IsShared())
bad6eb00 7887 sharedMap.SetBitNumber(iter,kTRUE);
19b00333 7888 }
bad6eb00 7889 if (t->GetClusterIndex(iter) >= 0 && (t->GetClusterIndex(iter) & 0x8000) == 0) {
7890 fitMap.SetBitNumber(iter, kTRUE);
7891 nclsf++;
19b00333 7892 }
7893 }
bad6eb00 7894 esd->SetTPCClusterMap(clusterMap);
7895 esd->SetTPCSharedMap(sharedMap);
7896 esd->SetTPCFitMap(fitMap);
7897 if (nclsf != t->GetNumberOfClusters())
27540e35 7898 AliDebug(3,Form("Inconsistency between ncls %d and indices %d (found %d)",t->GetNumberOfClusters(),nclsf,esd->GetTPCClusterMap().CountBits()));
19b00333 7899}
92f513f5 7900
829455ad 7901Bool_t AliTPCtracker::IsFindable(AliTPCseed & track){
76d56fd6 7902 //
7903 // return flag if there is findable cluster at given position
7904 //
7905 Float_t kDeltaZ=10;
7906 Float_t z = track.GetZ();
7907
7908 if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*track.GetX()+kDeltaZ) &&
47af7ca4 7909 TMath::Abs(z)<fkParam->GetZLength(0) &&
76d56fd6 7910 (TMath::Abs(track.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
7911 return kTRUE;
7912 return kFALSE;
7913}
92f513f5 7914
7915
829455ad 7916void AliTPCtracker::AddCovariance(AliTPCseed * seed){
92f513f5 7917 //
2c4acef0 7918 return;
e1dadcd0 7919 // Adding systematic error estimate to the covariance matrix
b87c2bbc 7920 // !!!! the systematic error for element 4 is in 1/GeV
7921 // 03.03.2012 MI changed in respect to the previous versions
e1dadcd0 7922 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
7923 //
7924 // use only the diagonal part if not specified otherwise
7925 if (!AliTPCReconstructor::GetRecoParam()->GetUseSystematicCorrelation()) return AddCovarianceAdd(seed);
7926 //
7927 Double_t *covarS= (Double_t*)seed->GetCovariance();
7928 Double_t factor[5]={1,1,1,1,1};
e1dadcd0 7929 factor[0]= TMath::Sqrt(TMath::Abs((covarS[0] + param[0]*param[0])/covarS[0]));
7930 factor[1]= TMath::Sqrt(TMath::Abs((covarS[2] + param[1]*param[1])/covarS[2]));
7931 factor[2]= TMath::Sqrt(TMath::Abs((covarS[5] + param[2]*param[2])/covarS[5]));
7932 factor[3]= TMath::Sqrt(TMath::Abs((covarS[9] + param[3]*param[3])/covarS[9]));
b87c2bbc 7933 factor[4]= TMath::Sqrt(TMath::Abs((covarS[14] +param[4]*param[4])/covarS[14]));
9b550f87 7934 //
7935 factor[0]=factor[2];
7936 factor[4]=factor[2];
e1dadcd0 7937 // 0
7938 // 1 2
7939 // 3 4 5
7940 // 6 7 8 9
7941 // 10 11 12 13 14
7942 for (Int_t i=0; i<5; i++){
7943 for (Int_t j=i; j<5; j++){
7944 Int_t index=seed->GetIndex(i,j);
7945 covarS[index]*=factor[i]*factor[j];
7946 }
7947 }
7948}
7949
92f513f5 7950
829455ad 7951void AliTPCtracker::AddCovarianceAdd(AliTPCseed * seed){
e1dadcd0 7952 //
7953 // Adding systematic error - as additive factor without correlation
7954 //
b87c2bbc 7955 // !!!! the systematic error for element 4 is in 1/GeV
7956 // 03.03.2012 MI changed in respect to the previous versions
7957
92f513f5 7958 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
f47588e0 7959 Double_t *covarIn= (Double_t*)seed->GetCovariance();
92f513f5 7960 Double_t covar[15];
7961 for (Int_t i=0;i<15;i++) covar[i]=0;
7962 // 0
7963 // 1 2
7964 // 3 4 5
7965 // 6 7 8 9
7966 // 10 11 12 13 14
7967 covar[0] = param[0]*param[0];
7968 covar[2] = param[1]*param[1];
7969 covar[5] = param[2]*param[2];
7970 covar[9] = param[3]*param[3];
b87c2bbc 7971 covar[14]= param[4]*param[4];
f47588e0 7972 //
7973 covar[1]=TMath::Sqrt((covar[0]*covar[2]))*covarIn[1]/TMath::Sqrt((covarIn[0]*covarIn[2]));
7974 //
7975 covar[3]=TMath::Sqrt((covar[0]*covar[5]))*covarIn[3]/TMath::Sqrt((covarIn[0]*covarIn[5]));
7976 covar[4]=TMath::Sqrt((covar[2]*covar[5]))*covarIn[4]/TMath::Sqrt((covarIn[2]*covarIn[5]));
7977 //
7978 covar[6]=TMath::Sqrt((covar[0]*covar[9]))*covarIn[6]/TMath::Sqrt((covarIn[0]*covarIn[9]));
7979 covar[7]=TMath::Sqrt((covar[2]*covar[9]))*covarIn[7]/TMath::Sqrt((covarIn[2]*covarIn[9]));
7980 covar[8]=TMath::Sqrt((covar[5]*covar[9]))*covarIn[8]/TMath::Sqrt((covarIn[5]*covarIn[9]));
7981 //
7982 covar[10]=TMath::Sqrt((covar[0]*covar[14]))*covarIn[10]/TMath::Sqrt((covarIn[0]*covarIn[14]));
7983 covar[11]=TMath::Sqrt((covar[2]*covar[14]))*covarIn[11]/TMath::Sqrt((covarIn[2]*covarIn[14]));
7984 covar[12]=TMath::Sqrt((covar[5]*covar[14]))*covarIn[12]/TMath::Sqrt((covarIn[5]*covarIn[14]));
7985 covar[13]=TMath::Sqrt((covar[9]*covar[14]))*covarIn[13]/TMath::Sqrt((covarIn[9]*covarIn[14]));
7986 //
92f513f5 7987 seed->AddCovariance(covar);
7988}
f06a1ff6 7989
ec7e4ad6 7990//_____________________________________________________________________________
829455ad 7991Bool_t AliTPCtracker::IsTPCHVDipEvent(AliESDEvent const *esdEvent)
661f340b 7992{
7993 //
7994 // check events affected by TPC HV dip
7995 //
7996 if(!esdEvent) return kFALSE;
ec7e4ad6 7997
661f340b 7998 // Init TPC OCDB
7999 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
8000 if(!db) return kFALSE;
8001 db->SetRun(esdEvent->GetRunNumber());
ec7e4ad6 8002
661f340b 8003 // maximum allowed voltage before an event is identified as a dip event
8004 // and scanning period
8005 const Double_t kTPCHVdip = db->GetParameters()->GetMaxDipVoltage();
8006 const Double_t dipEventScanPeriod = db->GetParameters()->GetVoltageDipScanPeriod();
8007 const Double_t tevSec = esdEvent->GetTimeStamp();
8008
ec7e4ad6 8009 for(Int_t sector=0; sector<72; sector++)
8010 {
661f340b 8011 // don't use excluded chambers, since the state is not defined at all
8012 if (!db->GetChamberHVStatus(sector)) continue;
8013
8014 // get hv sensor of the chamber
8015 AliDCSSensor *sensor = db->GetChamberHVSensor(sector);
8016 if (!sensor) continue;
8017 TGraph *grSensor=sensor->GetGraph();
8018 if (!grSensor) continue;
8019 if (grSensor->GetN()<1) continue;
ec7e4ad6 8020
661f340b 8021 // get median
8022 const Double_t median = db->GetChamberHighVoltageMedian(sector);
8023 if(median < 1.) continue;
ec7e4ad6 8024
661f340b 8025 for (Int_t ipoint=0; ipoint<grSensor->GetN()-1; ++ipoint){
8026 Double_t nextTime=grSensor->GetX()[ipoint+1]*3600+sensor->GetStartTime();
8027 if (tevSec-dipEventScanPeriod>nextTime) continue;
8028 const Float_t deltaV=TMath::Abs(grSensor->GetY()[ipoint]-median);
8029 if (deltaV>kTPCHVdip) {
8030 AliDebug(3,Form("HV dip detected in ROC '%02d' with dV '%.2f' at time stamp '%.0f'",sector,deltaV,tevSec));
8031 return kTRUE;
8032 }
8033 if (nextTime>tevSec+dipEventScanPeriod) break;
ec7e4ad6 8034 }
661f340b 8035 }
8036
8037 return kFALSE;
8038}
ddfbc51a 8039
8040//________________________________________
829455ad 8041void AliTPCtracker::MarkSeedFree(TObject *sd)
ddfbc51a 8042{
8043 // account that this seed is "deleted"
8044 AliTPCseed* seed = dynamic_cast<AliTPCseed*>(sd);
88492b27 8045 if (!seed) {
b6565e28 8046 AliError(Form("Freeing of non-AliTPCseed %p from the pool is requested",sd));
8047 return;
8048 }
88492b27 8049 int id = seed->GetPoolID();
b6565e28 8050 if (id<0) {
8051 AliError(Form("Freeing of seed %p NOT from the pool is requested",sd));
8052 return;
8053 }
ddfbc51a 8054 // AliInfo(Form("%d %p",id, seed));
8055 fSeedsPool->RemoveAt(id);
8056 if (fFreeSeedsID.GetSize()<=fNFreeSeeds) fFreeSeedsID.Set( 2*fNFreeSeeds + 100 );
8057 fFreeSeedsID.GetArray()[fNFreeSeeds++] = id;
8058}
8059
8060//________________________________________
829455ad 8061TObject *&AliTPCtracker::NextFreeSeed()
ddfbc51a 8062{
8063 // return next free slot where the seed can be created
8064 fLastSeedID = fNFreeSeeds ? fFreeSeedsID.GetArray()[--fNFreeSeeds] : fSeedsPool->GetEntriesFast();
8065 // AliInfo(Form("%d",fLastSeedID));
8066 return (*fSeedsPool)[ fLastSeedID ];
8067 //
8068}
8069
8070//________________________________________
829455ad 8071void AliTPCtracker::ResetSeedsPool()
ddfbc51a 8072{
8073 // mark all seeds in the pool as unused
8074 AliInfo(Form("CurrentSize: %d, BookedUpTo: %d, free: %d",fSeedsPool->GetSize(),fSeedsPool->GetEntriesFast(),fNFreeSeeds));
8075 fNFreeSeeds = 0;
8076 fSeedsPool->Clear("C"); // RS: nominally the seeds may allocate memory...
8077}
72e25240 8078
829455ad 8079Int_t AliTPCtracker::PropagateToRowHLT(AliTPCseed *pt, int nrow)
72e25240 8080{
8081 AliTPCseed &t=*pt;
8082 Double_t x= GetXrow(nrow);
8083 Double_t ymax= GetMaxY(nrow);
8084 Int_t rotate = 0;
8085 Int_t nRotations=0;
8086 int ret = 1;
8087 do{
8088 rotate = 0;
8089 if (!t.PropagateTo(x) ){
8090 //cout<<"can't propagate to row "<<nrow<<", x="<<t.GetX()<<" -> "<<x<<endl;
8091 //t.Print();
8092 ret = 0;
8093 break;
8094 }
8095 t.SetRow(nrow);
8096 Double_t y = t.GetY();
8097 if( y > ymax ) {
8098 if( rotate!=-1 ) rotate=1;
8099 } else if (y <-ymax) {
8100 if( rotate!=1 ) rotate = -1;
8101 }
8102 if( rotate==0 ) break;
8103 //cout<<"rotate at row "<<nrow<<": "<<rotate<<endl;
8104 if (!t.Rotate( rotate==1 ?fSectors->GetAlpha() :-fSectors->GetAlpha())) {
8105 //cout<<"can't rotate "<<endl;
8106 ret=0;
8107 break;
8108 }
8109 nRotations+= rotate;
8110 }while(rotate!=0);
8111 if( nRotations!=0 ){
8112 int newSec= t.GetRelativeSector()+nRotations;
8113 if( newSec>=fN ) newSec-=fN;
8114 else if( newSec<0 ) newSec +=fN;
8115 //cout<<"rotate at row "<<nrow<<": "<<nRotations<<" times "<<" sec "
8116 //<< t.GetRelativeSector()<<" -> "<<newSec<<endl;
8117 t.SetRelativeSector(newSec);
8118 }
8119 return ret;
8120}
8121
829455ad 8122void AliTPCtracker::TrackFollowingHLT(TObjArray *const arr )
72e25240 8123{
8124 //
8125 // try to track in parralel
8126
8127 Int_t nRows=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8128 fSectors=fInnerSec;
8129
8130 Int_t nseed=arr->GetEntriesFast();
8131 //cout<<"Parallel tracking My.."<<endl;
8132 double shapeY2[160], shapeZ2[160];
8133 Int_t clusterIndex[160];
8134
8135 for (Int_t iSeed=0; iSeed<nseed; iSeed++) {
8136 //if( iSeed!=1 ) continue;
8137 AliTPCseed *pt=(AliTPCseed*) (arr->UncheckedAt(iSeed));
8138 if (!pt) continue;
8139 AliTPCseed &t=*pt;
8140
8141 //cout <<"Pt "<<t.GetSigned1Pt()<<endl;
8142
8143 // t.Print();
8144
8145 for( int iter=0; iter<3; iter++ ){
8146
8147 t.Reset();
8148 t.SetLastPoint(0); // first cluster in track position
8149 t.SetFirstPoint(nRows-1);
8150 t.ResetCovariance(.1);
8151 t.SetNumberOfClusters(0);
8152 for( int i=0; i<nRows; i++ ){
8153 shapeY2[i]=1.;
8154 shapeZ2[i]=1.;
8155 clusterIndex[i]=-1;
8156 t.SetClusterIndex2(i,-1);
8157 t.SetClusterIndex(i,-1);
8158 }
8159
8160 // pick up the clusters
8161
8162 Double_t roady = 20.;
8163 Double_t roadz = 20.;
8164 double roadr = 5;
8165
8166 AliTPCseed t0(t);
8167 t0.Reset();
8168 int nClusters = 0;
8169 {
8170 t0.SetRelativeSector(t.GetRelativeSector());
8171 t0.SetLastPoint(0); // first cluster in track position
8172 t0.SetFirstPoint(159);
8173 for (Int_t nr=0; nr<nRows; nr++){
8174 if( nr<fInnerSec->GetNRows() ) fSectors=fInnerSec;
8175 else fSectors=fOuterSec;
8176
8177 if( !PropagateToRowHLT(&t0, nr ) ){ break; }
8178 if (TMath::Abs(t0.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8179 //cout<<"Snp is too big: "<<t0.GetSnp()<<endl;
8180 continue;
8181 }
8182 if (!IsActive(t0.GetRelativeSector(),nr)) {
8183 continue;
8184 }
8185
8186 if( iter==0 ){
8187 GetShape(&t0,nr);
8188 shapeY2[nr]=t0.GetCurrentSigmaY2();
8189 shapeZ2[nr]=t0.GetCurrentSigmaZ2();
8190 }
8191
8192 AliTPCtrackerRow &krow=GetRow(t0.GetRelativeSector(),nr);
8193 if( !krow ) continue;
8194
8195 t.SetClusterIndex2(nr,-3); // foundable
8196 t.SetClusterIndex(nr,-3);
8197
8198 AliTPCclusterMI *cl=0;
8199 UInt_t uindex = 0;
8200 cl = krow.FindNearest2(t0.GetY(),t0.GetZ(),roady,roadz,uindex);
8201 if (!cl ) continue;
8202 double dy = cl->GetY()-t0.GetY();
8203 double dz = cl->GetZ()-t0.GetZ();
8204 double dr = sqrt(dy*dy+dz*dz);
8205 if( dr>roadr ){
8206 //cout<<"row "<<nr<<", best cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8207 continue;
8208 }
8209 //cout<<"row "<<nr<<", found cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8210
8211 t0.SetClusterPointer(nr, cl);
8212 clusterIndex[nr] = krow.GetIndex(uindex);
8213 if( t0.GetFirstPoint()>nr ) t0.SetFirstPoint(nr);
8214 t0.SetLastPoint(nr);
8215 nClusters++;
8216 }
8217 }
8218
8219 if( nClusters <3 ){
8220 //cout<<"NOT ENOUGTH CLUSTERS: "<<nClusters<<endl;
8221 break;
8222 }
8223 Int_t basePoints[3] = {t0.GetFirstPoint(),t0.GetFirstPoint(),t0.GetLastPoint()};
8224
8225 // find midpoint
8226 {
8227 Int_t midRow = (t0.GetLastPoint()-t0.GetFirstPoint())/2;
8228 int dist=200;
8229 for( int nr=t0.GetFirstPoint()+1; nr< t0.GetLastPoint(); nr++){
8230 if( !t0.GetClusterPointer(nr) ) continue;
8231 int d = TMath::Abs(nr-midRow);
8232 if( d < dist ){
8233 dist = d;
8234 basePoints[1] = nr;
8235 }
8236 }
8237 }
8238
8239 // first fit 3 base points
8240 if( 1||iter<2 ){
8241 //cout<<"Fit3: "<<endl;
8242 for( int icl=0; icl<3; icl++){
8243 int nr = basePoints[icl];
8244 int lr=nr;
8245 if( nr>=fInnerSec->GetNRows()){
8246 lr = nr - fInnerSec->GetNRows();
8247 fSectors=fOuterSec;
8248 } else fSectors=fInnerSec;
8249
8250 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8251 if(!cl){
8252 //cout<<"WRONG!!!!"<<endl;
8253 continue;
8254 }
8255 int iSec = cl->GetDetector() %fkNIS;
8256 int rotate = iSec - t.GetRelativeSector();
8257 if( rotate!=0 ){
8258 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8259 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8260 //cout<<"can't rotate "<<endl;
8261 break;
8262 }
8263 t.SetRelativeSector(iSec);
8264 }
8265 Double_t x= cl->GetX();
8266 if (!t.PropagateTo(x)){
8267 //cout<<"can't propagate to x="<<x<<endl;
8268 break;
8269 }
8270
8271 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8272 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8273 break;
8274 }
8275 //cout<<"fit3 : row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8276
8277 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8278 t.SetCurrentCluster(cl);
8279 t.SetRow(lr);
8280
8281 t.SetErrorY2(shapeY2[nr]);
8282 t.SetErrorZ2(shapeZ2[nr]);
8283 if( icl==0 ){
8284 double cov[15];
8285 for( int j=0; j<15; j++ ) cov[j]=0;
8286 cov[0]=10;
8287 cov[2]=10;
8288 cov[5]=.5;
8289 cov[9]=.5;
8290 cov[14]=1.;
8291 t.AliExternalTrackParam::AddCovariance(cov);
8292 }
8293 if( !UpdateTrack(&t,0) ){
8294 //cout<<"Can not update"<<endl;
8295 //t.Print();
8296 t.SetClusterIndex2(nr,-1);
8297 t.SetClusterIndex(nr,-1);
8298 t.SetClusterPointer(nr,0);
8299 break;
8300 }
8301 //t.SetClusterPointer(nr, cl);
8302 }
8303
8304 //t.SetLastPoint(t0.GetLastPoint());
8305 //t.SetFirstPoint(t0.GetFirstPoint());
8306
8307 //cout<<"Fit: "<<endl;
8308 for (Int_t nr=t0.GetLastPoint(); nr>=t0.GetFirstPoint(); nr-- ){
8309 int lr=nr;
8310 if( nr>=fInnerSec->GetNRows()){
8311 lr = nr - fInnerSec->GetNRows();
8312 fSectors=fOuterSec;
8313 } else fSectors=fInnerSec;
8314
8315 if(1|| iter<2 ){
8316 if( nr == basePoints[0] ) continue;
8317 if( nr == basePoints[1] ) continue;
8318 if( nr == basePoints[2] ) continue;
8319 }
8320 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8321 if(!cl) continue;
8322
8323 int iSec = cl->GetDetector() %fkNIS;
8324 int rotate = iSec - t.GetRelativeSector();
8325 if( rotate!=0 ){
8326 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8327 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8328 //cout<<"can't rotate "<<endl;
8329 break;
8330 }
8331 t.SetRelativeSector(iSec);
8332 }
8333 Double_t x= cl->GetX();
8334 if (!t.PropagateTo(x)){
8335 //cout<<"can't propagate to x="<<x<<endl;
8336 break;
8337 }
8338 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8339 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8340 break;
8341 }
8342
8343 //cout<<"fit: row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8344
8345 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8346 t.SetCurrentCluster(cl);
8347 t.SetRow(lr);
8348 t.SetErrorY2(shapeY2[nr]);
8349 t.SetErrorZ2(shapeZ2[nr]);
8350
8351 if( !UpdateTrack(&t,0) ){
8352 //cout<<"Can not update"<<endl;
8353 //t.Print();
8354 t.SetClusterIndex2(nr,-1);
8355 t.SetClusterIndex(nr,-1);
8356 break;
8357 }
8358 //t.SetClusterPointer(nr, cl);
8359 }
8360 }
8361 //cout<<"After iter "<<iter<<": N clusters="<<t.GetNumberOfClusters()<<" : "<<nClusters<<endl;
8362 }
8363
8364 //cout<<"fitted track"<<iSeed<<endl;
8365 //t.Print();
8366 //cout<<"Statistics: "<<endl;
8367 Int_t foundable,found,shared;
8368 t.GetClusterStatistic(0,nRows, found, foundable, shared, kTRUE);
8369 t.SetNFoundable(foundable);
8370 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8371
8372 }
8373}
8374
8375
829455ad 8376TObjArray * AliTPCtracker::MakeSeedsHLT(const AliESDEvent *hltEvent)
72e25240 8377{
8378 // tracking
8379 //
8380
8381 if( !hltEvent ) return 0;
8382
8383
8384 Int_t nentr=hltEvent->GetNumberOfTracks();
8385
8386 AliInfo(Form("Using %d HLT tracks for seeding",nentr));
8387
8388 TObjArray * seeds = new TObjArray(nentr);
8389
8390 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8391 Int_t index = 0;
8392
8393 Int_t nTr=hltEvent->GetNumberOfTracks();
8394
8395 for( int itr=0; itr<nTr; itr++ ){
8396 //if( itr!=97 ) continue;
8397 const AliExternalTrackParam *param = hltEvent->GetTrack(itr)->GetTPCInnerParam();
8398 if( !param ) continue;
8399 //if( TMath::Abs(esdTr->GetSigned1Pt())>1 ) continue;
8400 //if( TMath::Abs(esdTr->GetTgl())>1. ) continue;
8401 AliTPCtrack tr;
8402 tr.Set(param->GetX(),param->GetAlpha(),param->GetParameter(),param->GetCovariance());
8403 tr.SetNumberOfClusters(0);
8404 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed(tr);
8405
8406 Double_t alpha=seed->GetAlpha();// - fSectors->GetAlphaShift();
8407 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
8408 if (alpha < 0. ) alpha += 2.*TMath::Pi();
8409 //
8410 seed->SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
8411 Double_t alphaSec = fSectors->GetAlpha() * seed->GetRelativeSector() + fSectors->GetAlphaShift();
8412
8413 if (alphaSec >= TMath::Pi()) alphaSec -= 2.*TMath::Pi();
8414 if (alphaSec < -TMath::Pi()) alphaSec += 2.*TMath::Pi();
8415
8416 seed->Rotate(alphaSec - alpha);
8417
8418 seed->SetPoolID(fLastSeedID);
8419 seed->SetIsSeeding(kTRUE);
8420 seed->SetSeed1(nup-1);
8421 seed->SetSeed2(nup-2);
8422 seed->SetSeedType(0);
8423 seed->SetFirstPoint(-1);
8424 seed->SetLastPoint(-1);
8425 seeds->AddLast(seed); // note, track is seed, don't free the seed
8426 index++;
8427 //if( index>3 ) break;
8428 }
8429
8430
8431 fSectors = fOuterSec;
8432
8433 TrackFollowingHLT(seeds );
8434
8435 nTr = seeds->GetEntriesFast();
8436 for( int itr=0; itr<nTr; itr++ ){
8437 AliTPCseed * seed = (AliTPCseed*) seeds->UncheckedAt(itr);
8438 if( !seed ) continue;
8439 //FollowBackProlongation(*seed,0);
8440 // cout<<seed->GetNumberOfClusters()<<endl;
8441 Int_t foundable,found,shared;
8442 seed->GetClusterStatistic(0,nup, found, foundable, shared, kTRUE);
8443 seed->SetNFoundable(foundable);
8444 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8445 //if ((found<0.55*foundable) || shared>0.5*found ){// || (seed->GetSigmaY2()+seed->GetSigmaZ2())>0.5){
8446 //MarkSeedFree(seeds->RemoveAt(itr));
8447 //continue;
8448 //}
8449 if (seed->GetNumberOfClusters()<30 ||
8450 seed->GetNumberOfClusters() < seed->GetNFoundable()*0.6 ||
8451 seed->GetNShared()>0.4*seed->GetNumberOfClusters() ) {
8452 MarkSeedFree(seeds->RemoveAt(itr));
8453 continue;
8454 }
8455
8456 for( int ir=0; ir<nup; ir++){
8457 AliTPCclusterMI *c = seed->GetClusterPointer(ir);
8458 if( c ) c->Use(10);
8459 }
8460 }
492a4365 8461 std::cout<<"\n\nHLT tracks left: "<<seeds->GetEntries()<<" out of "<<hltEvent->GetNumberOfTracks()<<endl<<endl;
72e25240 8462 return seeds;
8463}
5576d489 8464
8465void AliTPCtracker::FillClusterOccupancyInfo()
8466{
8467 //fill the cluster occupancy info into the ESD friend
8468 AliESDfriend* esdFriend = static_cast<AliESDfriend*>(fEvent->FindListObject("AliESDfriend"));
8469 if (!esdFriend) return;
8470
8471 for (Int_t isector=0; isector<18; isector++){
8472 AliTPCtrackerSector &iroc = fInnerSec[isector];
8473 AliTPCtrackerSector &oroc = fOuterSec[isector];
8474 //all clusters
8475 esdFriend->SetNclustersTPC(isector, iroc.GetNClInSector(0));
8476 esdFriend->SetNclustersTPC(isector+18,iroc.GetNClInSector(1));
8477 esdFriend->SetNclustersTPC(isector+36,oroc.GetNClInSector(0));
8478 esdFriend->SetNclustersTPC(isector+54,oroc.GetNClInSector(1));
8479 //clusters used in tracking
8480 esdFriend->SetNclustersTPCused(isector, iroc.GetNClUsedInSector(0));
8481 esdFriend->SetNclustersTPCused(isector+18, iroc.GetNClUsedInSector(1));
8482 esdFriend->SetNclustersTPCused(isector+36, oroc.GetNClUsedInSector(0));
8483 esdFriend->SetNclustersTPCused(isector+54, oroc.GetNClUsedInSector(1));
8484 }
8485}