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