]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/Rec/AliTPCtracker.cxx
PWGPP-71 - Adding ncluster statistic to optional streamers. Print additional inform...
[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// The track finding steps:
26// 1. Seeding - with and without vertex constraint
27// - seeding with vertex constain done at first n^2 proble
28// - seeding without vertex constraint n^3 problem
29// 2. Tracking - follow prolongation road - find cluster - update kalman track
6d493ea0 30// The seeding and tracking is repeated several times, in different seeding region.
31// This approach enables to find the track which cannot be seeded in some region of TPC
32// 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) ...
33
34// With this approach we reach almost 100 % efficiency also for high occupancy events.
35// (If the seeding efficiency in a region is about 90 % than with logical or of several
36// regions we will reach 100% (in theory - supposing independence)
37
38// Repeating several seeding - tracking procedures some of the tracks can be find
39// several times.
40
41// The procedures to remove multi find tacks are impremented:
42// RemoveUsed2 - fast procedure n problem -
43// Algorithm - Sorting tracks according quality
44// remove tracks with some shared fraction
45// Sharing in respect to all tacks
46// Signing clusters in gold region
47// FindSplitted - slower algorithm n^2
48// Sort the tracks according quality
49// Loop over pair of tracks
50// If overlap with other track bigger than threshold - remove track
51//
52// FindCurling - Finds the pair of tracks which are curling
53// - About 10% of tracks can be find with this procedure
54// The combinatorial background is too big to be used in High
55// multiplicity environment
56// - n^2 problem - Slow procedure - currently it is disabled because of
57// low efficiency
58//
59// The number of splitted tracks can be reduced disabling the sharing of the cluster.
60// tpcRecoParam-> SetClusterSharing(kFALSE);
61// IT IS HIGHLY non recomended to use it in high flux enviroonment
62// Even using this switch some tracks can be found more than once
63// (because of multiple seeding and low quality tracks which will not cross full chamber)
64//
65//
66// The tracker itself can be debugged - the information about tracks can be stored in several // phases of the reconstruction
67// To enable storage of the TPC tracks in the ESD friend track
16299eac 68// use AliTPCReconstructor::SetStreamLevel(n);
6d493ea0 69//
65e67c9c 70// The debug level - different procedure produce tree for numerical debugging of code and data (see comments foEStreamFlags in AliTPCtracker.h )
6d493ea0 71//
92f513f5 72
73//
74// Adding systematic errors to the covariance:
75//
76// The systematic errors due to the misalignment and miscalibration are added to the covariance matrix
77// of the tracks (not to the clusters as they are dependent):
78// The parameters form AliTPCRecoParam are used AliTPCRecoParam::GetSystematicError
b87c2bbc 79// The systematic errors are expressed there in RMS - position (cm), angle (rad), curvature (1/GeV)
92f513f5 80// The default values are 0.
81//
65e67c9c 82// The systematic errors are added to the covariance matrix in following places:
92f513f5 83//
829455ad 84// 1. During fisrt itteration - AliTPCtracker::FillESD
92f513f5 85// 2. Second iteration -
829455ad 86// 2.a ITS->TPC - AliTPCtracker::ReadSeeds
87// 2.b TPC->TRD - AliTPCtracker::PropagateBack
92f513f5 88// 3. Third iteration -
829455ad 89// 3.a TRD->TPC - AliTPCtracker::ReadSeeds
90// 3.b TPC->ITS - AliTPCtracker::RefitInward
92f513f5 91//
47966a6d 92
93/* $Id$ */
94
cc5e9db0 95#include "Riostream.h"
6d171107 96#include <TClonesArray.h>
97#include <TFile.h>
98#include <TObjArray.h>
99#include <TTree.h>
8cc1870a 100#include <TMatrixD.h>
6d64657a 101#include <TGraphErrors.h>
661f340b 102#include <TTimeStamp.h>
a3232aae 103#include "AliLog.h"
47966a6d 104#include "AliComplexCluster.h"
af885e0f 105#include "AliESDEvent.h"
aad72f45 106#include "AliESDtrack.h"
107#include "AliESDVertex.h"
6c94f330 108#include "AliKink.h"
109#include "AliV0.h"
91162307 110#include "AliHelix.h"
91162307 111#include "AliRunLoader.h"
6d171107 112#include "AliTPCClustersRow.h"
113#include "AliTPCParam.h"
9996a03b 114#include "AliTPCReconstructor.h"
6d171107 115#include "AliTPCpolyTrack.h"
81e97e0d 116#include "AliTPCreco.h"
9350f379 117#include "AliTPCseed.h"
118
119#include "AliTPCtrackerSector.h"
829455ad 120#include "AliTPCtracker.h"
6d171107 121#include "TStopwatch.h"
81e97e0d 122#include "AliTPCReconstructor.h"
5d837844 123#include "AliAlignObj.h"
124#include "AliTrackPointArray.h"
6d493ea0 125#include "TRandom.h"
24db6af7 126#include "AliTPCcalibDB.h"
6d64657a 127#include "AliTPCcalibDButil.h"
24db6af7 128#include "AliTPCTransform.h"
fd065ea2 129#include "AliTPCClusterParam.h"
64bf5ca0 130#include "AliTPCdEdxInfo.h"
ec7e4ad6 131#include "AliDCSSensorArray.h"
132#include "AliDCSSensor.h"
133#include "AliDAQ.h"
3aa6a136 134#include "AliCosmicTracker.h"
44ca7282 135#include "AliTPCROC.h"
e731a3f8 136#include "AliMathBase.h"
6d171107 137//
c9427e08 138
a11596ad 139using std::cerr;
140using std::endl;
829455ad 141ClassImp(AliTPCtracker)
c9427e08 142
143
002af263 144
b67e07dc 145class AliTPCFastMath {
91162307 146public:
b67e07dc 147 AliTPCFastMath();
91162307 148 static Double_t FastAsin(Double_t x);
149 private:
b67e07dc 150 static Double_t fgFastAsin[20000]; //lookup table for fast asin computation
91162307 151};
c9427e08 152
b67e07dc 153Double_t AliTPCFastMath::fgFastAsin[20000];
2274b54b 154AliTPCFastMath gAliTPCFastMath; // needed to fill the LUT
c9427e08 155
b67e07dc 156AliTPCFastMath::AliTPCFastMath(){
157 //
158 // initialized lookup table;
91162307 159 for (Int_t i=0;i<10000;i++){
160 fgFastAsin[2*i] = TMath::ASin(i/10000.);
161 fgFastAsin[2*i+1] = (TMath::ASin((i+1)/10000.)-fgFastAsin[2*i]);
162 }
c9427e08 163}
164
b67e07dc 165Double_t AliTPCFastMath::FastAsin(Double_t x){
166 //
167 // return asin using lookup table
91162307 168 if (x>0){
169 Int_t index = int(x*10000);
170 return fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1];
171 }
172 x*=-1;
173 Int_t index = int(x*10000);
174 return -(fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1]);
1c53abe2 175}
e046d791 176//__________________________________________________________________
829455ad 177AliTPCtracker::AliTPCtracker()
e046d791 178 :AliTracker(),
179 fkNIS(0),
180 fInnerSec(0),
181 fkNOS(0),
182 fOuterSec(0),
183 fN(0),
184 fSectors(0),
185 fInput(0),
186 fOutput(0),
187 fSeedTree(0),
188 fTreeDebug(0),
189 fEvent(0),
72e25240 190 fEventHLT(0),
e046d791 191 fDebug(0),
192 fNewIO(kFALSE),
193 fNtracks(0),
194 fSeeds(0),
195 fIteration(0),
47af7ca4 196 fkParam(0),
1598ba75 197 fDebugStreamer(0),
f06a1ff6 198 fUseHLTClusters(4),
8cc1870a 199 fCrossTalkSignalArray(0),
f06a1ff6 200 fSeedsPool(0),
ddfbc51a 201 fFreeSeedsID(500),
202 fNFreeSeeds(0),
203 fLastSeedID(-1)
e046d791 204{
205 //
206 // default constructor
207 //
0f923679 208 for (Int_t irow=0; irow<200; irow++){
209 fXRow[irow]=0;
210 fYMax[irow]=0;
211 fPadLength[irow]=0;
212 }
e046d791 213}
214//_____________________________________________________________________
1c53abe2 215
216
217
829455ad 218Int_t AliTPCtracker::UpdateTrack(AliTPCseed * track, Int_t accept){
b67e07dc 219 //
220 //update track information using current cluster - track->fCurrentCluster
221
1c53abe2 222
b9671574 223 AliTPCclusterMI* c =track->GetCurrentCluster();
f124f8bf 224 if (accept > 0) //sign not accepted clusters
225 track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() | 0x8000);
226 else // unsign accpeted clusters
227 track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() & 0xffff7fff);
b9671574 228 UInt_t i = track->GetCurrentClusterIndex1();
1c53abe2 229
230 Int_t sec=(i&0xff000000)>>24;
91162307 231 //Int_t row = (i&0x00ff0000)>>16;
b9671574 232 track->SetRow((i&0x00ff0000)>>16);
233 track->SetSector(sec);
1c53abe2 234 // Int_t index = i&0xFFFF;
47af7ca4 235 if (sec>=fkParam->GetNInnerSector()) track->SetRow(track->GetRow()+fkParam->GetNRowLow());
b9671574 236 track->SetClusterIndex2(track->GetRow(), i);
91162307 237 //track->fFirstPoint = row;
238 //if ( track->fLastPoint<row) track->fLastPoint =row;
239 // if (track->fRow<0 || track->fRow>160) {
240 // printf("problem\n");
241 //}
b9671574 242 if (track->GetFirstPoint()>track->GetRow())
243 track->SetFirstPoint(track->GetRow());
244 if (track->GetLastPoint()<track->GetRow())
245 track->SetLastPoint(track->GetRow());
91162307 246
247
b9671574 248 track->SetClusterPointer(track->GetRow(),c);
1c53abe2 249 //
250
3f82c4f2 251 Double_t angle2 = track->GetSnp()*track->GetSnp();
1c53abe2 252 //
253 //SET NEW Track Point
254 //
85e2b57d 255 if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
91162307 256 {
85e2b57d 257 angle2 = TMath::Sqrt(angle2/(1-angle2));
b9671574 258 AliTPCTrackerPoint &point =*(track->GetTrackPoint(track->GetRow()));
1c53abe2 259 //
b9671574 260 point.SetSigmaY(c->GetSigmaY2()/track->GetCurrentSigmaY2());
261 point.SetSigmaZ(c->GetSigmaZ2()/track->GetCurrentSigmaZ2());
262 point.SetErrY(sqrt(track->GetErrorY2()));
263 point.SetErrZ(sqrt(track->GetErrorZ2()));
1c53abe2 264 //
91162307 265 point.SetX(track->GetX());
266 point.SetY(track->GetY());
267 point.SetZ(track->GetZ());
268 point.SetAngleY(angle2);
269 point.SetAngleZ(track->GetTgl());
b9671574 270 if (point.IsShared()){
271 track->SetErrorY2(track->GetErrorY2()*4);
272 track->SetErrorZ2(track->GetErrorZ2()*4);
91162307 273 }
274 }
275
b9671574 276 Double_t chi2 = track->GetPredictedChi2(track->GetCurrentCluster());
91162307 277 //
1d91d749 278// track->SetErrorY2(track->GetErrorY2()*1.3);
279// track->SetErrorY2(track->GetErrorY2()+0.01);
280// track->SetErrorZ2(track->GetErrorZ2()*1.3);
281// track->SetErrorZ2(track->GetErrorZ2()+0.005);
91162307 282 //}
283 if (accept>0) return 0;
284 if (track->GetNumberOfClusters()%20==0){
285 // if (track->fHelixIn){
286 // TClonesArray & larr = *(track->fHelixIn);
287 // Int_t ihelix = larr.GetEntriesFast();
288 // new(larr[ihelix]) AliHelix(*track) ;
289 //}
1c53abe2 290 }
65e67c9c 291 if (AliTPCReconstructor::StreamLevel()&kStreamUpdateTrack) {
bda5ad6d 292 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
293 AliExternalTrackParam param(*track);
294 TTreeSRedirector &cstream = *fDebugStreamer;
65e67c9c 295 cstream<<"UpdateTrack"<<
bda5ad6d 296 "cl.="<<c<<
265b5e37 297 "event="<<event<<
bda5ad6d 298 "track.="<<&param<<
299 "\n";
300 }
b9671574 301 track->SetNoCluster(0);
91162307 302 return track->Update(c,chi2,i);
303}
304
305
306
829455ad 307Int_t AliTPCtracker::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster)
91162307 308{
1c53abe2 309 //
91162307 310 // decide according desired precision to accept given
311 // cluster for tracking
6fbe1e5c 312 Double_t yt=0,zt=0;
313 seed->GetProlongation(cluster->GetX(),yt,zt);
00055a22 314 Double_t sy2=ErrY2(seed,cluster);
315 Double_t sz2=ErrZ2(seed,cluster);
1c53abe2 316
91162307 317 Double_t sdistancey2 = sy2+seed->GetSigmaY2();
318 Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
6fbe1e5c 319 Double_t dy=seed->GetCurrentCluster()->GetY()-yt;
f47588e0 320 Double_t dz=seed->GetCurrentCluster()->GetZ()-zt;
6fbe1e5c 321 Double_t rdistancey2 = (seed->GetCurrentCluster()->GetY()-yt)*
322 (seed->GetCurrentCluster()->GetY()-yt)/sdistancey2;
323 Double_t rdistancez2 = (seed->GetCurrentCluster()->GetZ()-zt)*
324 (seed->GetCurrentCluster()->GetZ()-zt)/sdistancez2;
91162307 325
326 Double_t rdistance2 = rdistancey2+rdistancez2;
327 //Int_t accept =0;
1c53abe2 328
f5a565c3 329 if (AliTPCReconstructor::StreamLevel()>2 && ( (fIteration>0)|| (seed->GetNumberOfClusters()>20))) {
a9ff2f09 330 // if (AliTPCReconstructor::StreamLevel()>2 && seed->GetNumberOfClusters()>20) {
fd065ea2 331 Float_t rmsy2 = seed->GetCurrentSigmaY2();
332 Float_t rmsz2 = seed->GetCurrentSigmaZ2();
e0e13b88 333 Float_t rmsy2p30 = seed->GetCMeanSigmaY2p30();
334 Float_t rmsz2p30 = seed->GetCMeanSigmaZ2p30();
42aec1f1 335 Float_t rmsy2p30R = seed->GetCMeanSigmaY2p30R();
336 Float_t rmsz2p30R = seed->GetCMeanSigmaZ2p30R();
6fbe1e5c 337 AliExternalTrackParam param(*seed);
eea6b724 338 static TVectorD gcl(3),gtr(3);
339 Float_t gclf[3];
340 param.GetXYZ(gcl.GetMatrixArray());
341 cluster->GetGlobalXYZ(gclf);
342 gcl[0]=gclf[0]; gcl[1]=gclf[1]; gcl[2]=gclf[2];
a9ff2f09 343 Int_t nclSeed=seed->GetNumberOfClusters();
b194b32c 344
65e67c9c 345 if (AliTPCReconstructor::StreamLevel()&kStreamErrParam) { // flag:stream in debug mode cluster and track extrapolation at given row together with error nad shape estimate
fd065ea2 346 (*fDebugStreamer)<<"ErrParam"<<
498b9441 347 "iter="<<fIteration<<
e0e13b88 348 "Cl.="<<cluster<<
a9ff2f09 349 "nclSeed="<<nclSeed<<
e0e13b88 350 "T.="<<&param<<
6fbe1e5c 351 "dy="<<dy<<
352 "dz="<<dz<<
353 "yt="<<yt<<
354 "zt="<<zt<<
eea6b724 355 "gcl.="<<&gcl<<
356 "gtr.="<<&gtr<<
e0e13b88 357 "erry2="<<sy2<<
358 "errz2="<<sz2<<
359 "rmsy2="<<rmsy2<<
360 "rmsz2="<<rmsz2<<
361 "rmsy2p30="<<rmsy2p30<<
362 "rmsz2p30="<<rmsz2p30<<
42aec1f1 363 "rmsy2p30R="<<rmsy2p30R<<
364 "rmsz2p30R="<<rmsz2p30R<<
f47588e0 365 // normalize distance -
366 "rdisty="<<rdistancey2<<
367 "rdistz="<<rdistancez2<<
368 "rdist="<<rdistance2<< //
e0e13b88 369 "\n";
b194b32c 370 }
fd065ea2 371 }
6fbe1e5c 372 //return 0; // temporary
373 if (rdistance2>32) return 3;
91162307 374
375
00055a22 376 if ((rdistancey2>9. || rdistancez2>9.) && cluster->GetType()==0)
91162307 377 return 2; //suspisiouce - will be changed
378
00055a22 379 if ((rdistancey2>6.25 || rdistancez2>6.25) && cluster->GetType()>0)
91162307 380 // strict cut on overlaped cluster
381 return 2; //suspisiouce - will be changed
382
00055a22 383 if ( (rdistancey2>1. || rdistancez2>6.25 )
91162307 384 && cluster->GetType()<0){
b9671574 385 seed->SetNFoundable(seed->GetNFoundable()-1);
91162307 386 return 2;
1c53abe2 387 }
19dcf504 388
1598ba75 389 if (fUseHLTClusters == 3 || fUseHLTClusters == 4) {
36b89541 390 if (fIteration==2){
391 if(!AliTPCReconstructor::GetRecoParam()->GetUseHLTOnePadCluster()) {
392 if (TMath::Abs(cluster->GetSigmaY2()) < kAlmost0)
393 return 2;
394 }
1598ba75 395 }
19dcf504 396 }
1598ba75 397
91162307 398 return 0;
399}
400
401
1c53abe2 402
1c53abe2 403
1af5da7e 404
1c53abe2 405//_____________________________________________________________________________
829455ad 406AliTPCtracker::AliTPCtracker(const AliTPCParam *par):
e046d791 407AliTracker(),
408 fkNIS(par->GetNInnerSector()/2),
409 fInnerSec(0),
410 fkNOS(par->GetNOuterSector()/2),
411 fOuterSec(0),
412 fN(0),
413 fSectors(0),
414 fInput(0),
415 fOutput(0),
416 fSeedTree(0),
417 fTreeDebug(0),
418 fEvent(0),
72e25240 419 fEventHLT(0),
e046d791 420 fDebug(0),
421 fNewIO(0),
422 fNtracks(0),
423 fSeeds(0),
424 fIteration(0),
47af7ca4 425 fkParam(0),
8cc1870a 426 fDebugStreamer(0),
427 fUseHLTClusters(4),
428 fCrossTalkSignalArray(0),
8cc1870a 429 fSeedsPool(0),
ddfbc51a 430 fFreeSeedsID(500),
431 fNFreeSeeds(0),
432 fLastSeedID(-1)
1c53abe2 433{
434 //---------------------------------------------------------------------
435 // The main TPC tracker constructor
436 //---------------------------------------------------------------------
9350f379 437 fInnerSec=new AliTPCtrackerSector[fkNIS];
438 fOuterSec=new AliTPCtrackerSector[fkNOS];
91162307 439
1c53abe2 440 Int_t i;
441 for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
442 for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
443
47af7ca4 444 fkParam = par;
91162307 445 Int_t nrowlow = par->GetNRowLow();
446 Int_t nrowup = par->GetNRowUp();
447
448
77f88633 449 for (i=0;i<nrowlow;i++){
91162307 450 fXRow[i] = par->GetPadRowRadiiLow(i);
451 fPadLength[i]= par->GetPadPitchLength(0,i);
452 fYMax[i] = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
453 }
454
455
77f88633 456 for (i=0;i<nrowup;i++){
91162307 457 fXRow[i+nrowlow] = par->GetPadRowRadiiUp(i);
458 fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
459 fYMax[i+nrowlow] = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
460 }
e046d791 461
b194b32c 462 if (AliTPCReconstructor::StreamLevel()>0) {
3d674021 463 fDebugStreamer = new TTreeSRedirector("TPCdebug.root","recreate");
b194b32c 464 }
f06a1ff6 465 //
ddfbc51a 466 fSeedsPool = new TClonesArray("AliTPCseed",1000);
265b5e37 467
468 // crosstalk array and matrix initialization
469 Int_t nROCs = 72;
470 Int_t nTimeBinsAll = par->GetMaxTBin();
471 Int_t nWireSegments = 11;
434cdbe1 472 fCrossTalkSignalArray = new TObjArray(nROCs*2); //
265b5e37 473 fCrossTalkSignalArray->SetOwner(kTRUE);
434cdbe1 474 for (Int_t isector=0; isector<2*nROCs; isector++){
39240815 475 TMatrixD * crossTalkSignal = new TMatrixD(nWireSegments,nTimeBinsAll);
265b5e37 476 for (Int_t imatrix = 0; imatrix<11; imatrix++)
477 for (Int_t jmatrix = 0; jmatrix<nTimeBinsAll; jmatrix++){
39240815 478 (*crossTalkSignal)[imatrix][jmatrix]=0.;
265b5e37 479 }
39240815 480 fCrossTalkSignalArray->AddAt(crossTalkSignal,isector);
265b5e37 481 }
482
1c53abe2 483}
2fc0c115 484//________________________________________________________________________
829455ad 485AliTPCtracker::AliTPCtracker(const AliTPCtracker &t):
58251ea0 486 AliTracker(t),
e046d791 487 fkNIS(t.fkNIS),
488 fInnerSec(0),
489 fkNOS(t.fkNOS),
490 fOuterSec(0),
491 fN(0),
492 fSectors(0),
493 fInput(0),
494 fOutput(0),
495 fSeedTree(0),
496 fTreeDebug(0),
497 fEvent(0),
72e25240 498 fEventHLT(0),
e046d791 499 fDebug(0),
500 fNewIO(kFALSE),
501 fNtracks(0),
502 fSeeds(0),
503 fIteration(0),
47af7ca4 504 fkParam(0),
8cc1870a 505 fDebugStreamer(0),
506 fUseHLTClusters(4),
507 fCrossTalkSignalArray(0),
8cc1870a 508 fSeedsPool(0),
ddfbc51a 509 fFreeSeedsID(500),
510 fNFreeSeeds(0),
511 fLastSeedID(-1)
58251ea0 512{
2fc0c115 513 //------------------------------------
514 // dummy copy constructor
515 //------------------------------------------------------------------
e046d791 516 fOutput=t.fOutput;
17abbffb 517 for (Int_t irow=0; irow<200; irow++){
518 fXRow[irow]=0;
519 fYMax[irow]=0;
520 fPadLength[irow]=0;
521 }
522
2fc0c115 523}
829455ad 524AliTPCtracker & AliTPCtracker::operator=(const AliTPCtracker& /*r*/)
47af7ca4 525{
2fc0c115 526 //------------------------------
527 // dummy
528 //--------------------------------------------------------------
529 return *this;
530}
1c53abe2 531//_____________________________________________________________________________
829455ad 532AliTPCtracker::~AliTPCtracker() {
1c53abe2 533 //------------------------------------------------------------------
534 // TPC tracker destructor
535 //------------------------------------------------------------------
536 delete[] fInnerSec;
537 delete[] fOuterSec;
538 if (fSeeds) {
f06a1ff6 539 fSeeds->Clear();
1c53abe2 540 delete fSeeds;
541 }
8cc1870a 542 if (fCrossTalkSignalArray) delete fCrossTalkSignalArray;
81e97e0d 543 if (fDebugStreamer) delete fDebugStreamer;
ddfbc51a 544 if (fSeedsPool) delete fSeedsPool;
1c53abe2 545}
546
1c53abe2 547
829455ad 548void AliTPCtracker::FillESD(const TObjArray* arr)
91162307 549{
47966a6d 550 //
551 //
552 //fill esds using updated tracks
ada522d7 553
ec26e231 554 if (!fEvent) return;
ada522d7 555
556 AliESDtrack iotrack;
ec26e231 557
91162307 558 // write tracks to the event
559 // store index of the track
d26d9159 560 Int_t nseed=arr->GetEntriesFast();
51ad6848 561 //FindKinks(arr,fEvent);
91162307 562 for (Int_t i=0; i<nseed; i++) {
d26d9159 563 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 564 if (!pt) continue;
51ad6848 565 pt->UpdatePoints();
92f513f5 566 AddCovariance(pt);
65e67c9c 567 if (AliTPCReconstructor::StreamLevel()&kStreamFillESD) {
568 (*fDebugStreamer)<<"FillESD"<< // flag: stream track information in FillESD function (after track Iteration 0)
8cecaa87 569 "Tr0.="<<pt<<
570 "\n";
571 }
47af7ca4 572 // pt->PropagateTo(fkParam->GetInnerRadiusLow());
eea478d3 573 if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
47af7ca4 574 pt->PropagateTo(fkParam->GetInnerRadiusLow());
eea478d3 575 }
51ad6848 576
577 if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
ada522d7 578 iotrack.~AliESDtrack();
579 new(&iotrack) AliESDtrack;
51ad6848 580 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 581 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 582 iotrack.SetTPCPoints(pt->GetPoints());
583 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 584 iotrack.SetV0Indexes(pt->GetV0Indexes());
585 // iotrack.SetTPCpid(pt->fTPCr);
f5cbf2ef 586 //iotrack.SetTPCindex(i);
587 MakeESDBitmaps(pt, &iotrack);
51ad6848 588 fEvent->AddTrack(&iotrack);
589 continue;
590 }
591
b9671574 592 if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
ada522d7 593 iotrack.~AliESDtrack();
594 new(&iotrack) AliESDtrack;
51ad6848 595 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 596 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 597 iotrack.SetTPCPoints(pt->GetPoints());
d26d9159 598 //iotrack.SetTPCindex(i);
51ad6848 599 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 600 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 601 MakeESDBitmaps(pt, &iotrack);
81e97e0d 602 // iotrack.SetTPCpid(pt->fTPCr);
d26d9159 603 fEvent->AddTrack(&iotrack);
a42a6bae 604 continue;
605 }
51ad6848 606 //
607 // short tracks - maybe decays
608
b9671574 609 if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
a42a6bae 610 Int_t found,foundable,shared;
611 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
b9671574 612 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
ada522d7 613 iotrack.~AliESDtrack();
614 new(&iotrack) AliESDtrack;
a42a6bae 615 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 616 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
a42a6bae 617 //iotrack.SetTPCindex(i);
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);
a42a6bae 623 fEvent->AddTrack(&iotrack);
624 continue;
625 }
626 }
627
b9671574 628 if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
a42a6bae 629 Int_t found,foundable,shared;
630 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
631 if (found<20) continue;
b9671574 632 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
a42a6bae 633 //
ada522d7 634 iotrack.~AliESDtrack();
635 new(&iotrack) AliESDtrack;
a42a6bae 636 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 637 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 638 iotrack.SetTPCPoints(pt->GetPoints());
639 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 640 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 641 MakeESDBitmaps(pt, &iotrack);
81e97e0d 642 //iotrack.SetTPCpid(pt->fTPCr);
51ad6848 643 //iotrack.SetTPCindex(i);
644 fEvent->AddTrack(&iotrack);
645 continue;
646 }
647 // short tracks - secondaties
648 //
649 if ( (pt->GetNumberOfClusters()>30) ) {
650 Int_t found,foundable,shared;
651 pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
b9671574 652 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
ada522d7 653 iotrack.~AliESDtrack();
654 new(&iotrack) AliESDtrack;
51ad6848 655 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 656 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 657 iotrack.SetTPCPoints(pt->GetPoints());
658 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 659 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 660 MakeESDBitmaps(pt, &iotrack);
81e97e0d 661 //iotrack.SetTPCpid(pt->fTPCr);
51ad6848 662 //iotrack.SetTPCindex(i);
663 fEvent->AddTrack(&iotrack);
664 continue;
665 }
666 }
667
668 if ( (pt->GetNumberOfClusters()>15)) {
669 Int_t found,foundable,shared;
670 pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
671 if (found<15) continue;
e7eb17e4 672 if (foundable<=0) continue;
b9671574 673 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
51ad6848 674 if (float(found)/float(foundable)<0.8) continue;
675 //
ada522d7 676 iotrack.~AliESDtrack();
677 new(&iotrack) AliESDtrack;
51ad6848 678 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 679 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 680 iotrack.SetTPCPoints(pt->GetPoints());
681 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 682 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 683 MakeESDBitmaps(pt, &iotrack);
81e97e0d 684 // iotrack.SetTPCpid(pt->fTPCr);
a42a6bae 685 //iotrack.SetTPCindex(i);
686 fEvent->AddTrack(&iotrack);
687 continue;
688 }
91162307 689 }
6fbe1e5c 690 // >> account for suppressed tracks in the kink indices (RS)
691 int nESDtracks = fEvent->GetNumberOfTracks();
692 for (int it=nESDtracks;it--;) {
693 AliESDtrack* esdTr = fEvent->GetTrack(it);
694 if (!esdTr || !esdTr->GetKinkIndex(0)) continue;
695 for (int ik=0;ik<3;ik++) {
696 int knkId=0;
697 if (!(knkId=esdTr->GetKinkIndex(ik))) break; // no more kinks for this track
698 AliESDkink* kink = fEvent->GetKink(TMath::Abs(knkId)-1);
699 if (!kink) {
700 AliError(Form("ESDTrack%d refers to non-existing kink %d",it,TMath::Abs(knkId)-1));
701 continue;
702 }
703 kink->SetIndex(it, knkId<0 ? 0:1); // update track index of the kink: mother at 0, daughter at 1
704 }
705 }
ada522d7 706
ec26e231 707 // << account for suppressed tracks in the kink indices (RS)
708 AliInfo(Form("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks()));
709
d26d9159 710}
711
d26d9159 712
1c53abe2 713
1c53abe2 714
715
829455ad 716Double_t AliTPCtracker::ErrY2(AliTPCseed* seed, const AliTPCclusterMI * cl){
91162307 717 //
718 //
fd065ea2 719 // Use calibrated cluster error from OCDB
91162307 720 //
fd065ea2 721 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
91162307 722 //
47af7ca4 723 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
91162307 724 Int_t ctype = cl->GetType();
fd065ea2 725 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
726 Double_t angle = seed->GetSnp()*seed->GetSnp();
e0e13b88 727 angle = TMath::Sqrt(TMath::Abs(angle/(1.-angle)));
fd065ea2 728 Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
729 if (ctype<0) {
730 erry2+=0.5; // edge cluster
731 }
732 erry2*=erry2;
0b2c141b 733 Double_t addErr=0;
734 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
f858edae 735 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
0b2c141b 736 erry2+=addErr*addErr;
44ca7282 737 const Double_t *errCluster = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorCluster();
738 erry2+=errCluster[0]*errCluster[0];
fd065ea2 739 seed->SetErrorY2(erry2);
740 //
741 return erry2;
742
743//calculate look-up table at the beginning
744// static Bool_t ginit = kFALSE;
745// static Float_t gnoise1,gnoise2,gnoise3;
746// static Float_t ggg1[10000];
747// static Float_t ggg2[10000];
748// static Float_t ggg3[10000];
749// static Float_t glandau1[10000];
750// static Float_t glandau2[10000];
751// static Float_t glandau3[10000];
752// //
753// static Float_t gcor01[500];
754// static Float_t gcor02[500];
755// static Float_t gcorp[500];
756// //
1c53abe2 757
fd065ea2 758// //
759// if (ginit==kFALSE){
760// for (Int_t i=1;i<500;i++){
761// Float_t rsigma = float(i)/100.;
762// gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
763// gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
764// gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
765// }
766
767// //
768// for (Int_t i=3;i<10000;i++){
769// //
770// //
771// // inner sector
772// Float_t amp = float(i);
773// Float_t padlength =0.75;
774// gnoise1 = 0.0004/padlength;
775// Float_t nel = 0.268*amp;
776// Float_t nprim = 0.155*amp;
47af7ca4 777// ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
fd065ea2 778// glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
779// if (glandau1[i]>1) glandau1[i]=1;
780// glandau1[i]*=padlength*padlength/12.;
781// //
782// // outer short
783// padlength =1.;
784// gnoise2 = 0.0004/padlength;
785// nel = 0.3*amp;
786// nprim = 0.133*amp;
47af7ca4 787// ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 788// glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
789// if (glandau2[i]>1) glandau2[i]=1;
790// glandau2[i]*=padlength*padlength/12.;
791// //
792// //
793// // outer long
794// padlength =1.5;
795// gnoise3 = 0.0004/padlength;
796// nel = 0.3*amp;
797// nprim = 0.133*amp;
47af7ca4 798// ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 799// glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
800// if (glandau3[i]>1) glandau3[i]=1;
801// glandau3[i]*=padlength*padlength/12.;
802// //
803// }
804// ginit = kTRUE;
805// }
806// //
807// //
808// //
809// Int_t amp = int(TMath::Abs(cl->GetQ()));
810// if (amp>9999) {
811// seed->SetErrorY2(1.);
812// return 1.;
813// }
814// Float_t snoise2;
47af7ca4 815// Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
fd065ea2 816// Int_t ctype = cl->GetType();
817// Float_t padlength= GetPadPitchLength(seed->GetRow());
818// Double_t angle2 = seed->GetSnp()*seed->GetSnp();
819// angle2 = angle2/(1-angle2);
820// //
821// //cluster "quality"
822// Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
823// Float_t res;
824// //
825// if (fSectors==fInnerSec){
826// snoise2 = gnoise1;
827// res = ggg1[amp]*z+glandau1[amp]*angle2;
828// if (ctype==0) res *= gcor01[rsigmay];
829// if ((ctype>0)){
830// res+=0.002;
831// res*= gcorp[rsigmay];
832// }
833// }
834// else {
835// if (padlength<1.1){
836// snoise2 = gnoise2;
837// res = ggg2[amp]*z+glandau2[amp]*angle2;
838// if (ctype==0) res *= gcor02[rsigmay];
839// if ((ctype>0)){
840// res+=0.002;
841// res*= gcorp[rsigmay];
842// }
843// }
844// else{
845// snoise2 = gnoise3;
846// res = ggg3[amp]*z+glandau3[amp]*angle2;
847// if (ctype==0) res *= gcor02[rsigmay];
848// if ((ctype>0)){
849// res+=0.002;
850// res*= gcorp[rsigmay];
851// }
852// }
853// }
854
855// if (ctype<0){
856// res+=0.005;
857// res*=2.4; // overestimate error 2 times
858// }
859// res+= snoise2;
91162307 860
fd065ea2 861// if (res<2*snoise2)
862// res = 2*snoise2;
91162307 863
fd065ea2 864// seed->SetErrorY2(res);
865// return res;
1c53abe2 866
867
91162307 868}
c9427e08 869
870
871
829455ad 872Double_t AliTPCtracker::ErrZ2(AliTPCseed* seed, const AliTPCclusterMI * cl){
91162307 873 //
874 //
fd065ea2 875 // Use calibrated cluster error from OCDB
91162307 876 //
fd065ea2 877 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
91162307 878 //
47af7ca4 879 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
91162307 880 Int_t ctype = cl->GetType();
fd065ea2 881 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
91162307 882 //
3f82c4f2 883 Double_t angle2 = seed->GetSnp()*seed->GetSnp();
91162307 884 angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
e0e13b88 885 Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
fd065ea2 886 Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
887 if (ctype<0) {
888 errz2+=0.5; // edge cluster
91162307 889 }
1af5da7e 890 errz2*=errz2;
0b2c141b 891 Double_t addErr=0;
892 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
f858edae 893 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
0b2c141b 894 errz2+=addErr*addErr;
44ca7282 895 const Double_t *errCluster = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorCluster();
896 errz2+=errCluster[1]*errCluster[1];
fd065ea2 897 seed->SetErrorZ2(errz2);
898 //
899 return errz2;
91162307 900
fd065ea2 901
902
903// //seed->SetErrorY2(0.1);
904// //return 0.1;
905// //calculate look-up table at the beginning
906// static Bool_t ginit = kFALSE;
907// static Float_t gnoise1,gnoise2,gnoise3;
908// static Float_t ggg1[10000];
909// static Float_t ggg2[10000];
910// static Float_t ggg3[10000];
911// static Float_t glandau1[10000];
912// static Float_t glandau2[10000];
913// static Float_t glandau3[10000];
914// //
915// static Float_t gcor01[1000];
916// static Float_t gcor02[1000];
917// static Float_t gcorp[1000];
918// //
919
920// //
921// if (ginit==kFALSE){
922// for (Int_t i=1;i<1000;i++){
923// Float_t rsigma = float(i)/100.;
924// gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
925// gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
926// gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
927// }
928
929// //
930// for (Int_t i=3;i<10000;i++){
931// //
932// //
933// // inner sector
934// Float_t amp = float(i);
935// Float_t padlength =0.75;
936// gnoise1 = 0.0004/padlength;
937// Float_t nel = 0.268*amp;
938// Float_t nprim = 0.155*amp;
47af7ca4 939// ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
fd065ea2 940// glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
941// if (glandau1[i]>1) glandau1[i]=1;
942// glandau1[i]*=padlength*padlength/12.;
943// //
944// // outer short
945// padlength =1.;
946// gnoise2 = 0.0004/padlength;
947// nel = 0.3*amp;
948// nprim = 0.133*amp;
47af7ca4 949// ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 950// glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
951// if (glandau2[i]>1) glandau2[i]=1;
952// glandau2[i]*=padlength*padlength/12.;
953// //
954// //
955// // outer long
956// padlength =1.5;
957// gnoise3 = 0.0004/padlength;
958// nel = 0.3*amp;
959// nprim = 0.133*amp;
47af7ca4 960// ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 961// glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
962// if (glandau3[i]>1) glandau3[i]=1;
963// glandau3[i]*=padlength*padlength/12.;
964// //
965// }
966// ginit = kTRUE;
967// }
968// //
969// //
970// //
971// Int_t amp = int(TMath::Abs(cl->GetQ()));
972// if (amp>9999) {
973// seed->SetErrorY2(1.);
974// return 1.;
975// }
976// Float_t snoise2;
47af7ca4 977// Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
fd065ea2 978// Int_t ctype = cl->GetType();
979// Float_t padlength= GetPadPitchLength(seed->GetRow());
980// //
981// Double_t angle2 = seed->GetSnp()*seed->GetSnp();
982// // if (angle2<0.6) angle2 = 0.6;
983// angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
984// //
985// //cluster "quality"
986// Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
987// Float_t res;
988// //
989// if (fSectors==fInnerSec){
990// snoise2 = gnoise1;
991// res = ggg1[amp]*z+glandau1[amp]*angle2;
992// if (ctype==0) res *= gcor01[rsigmaz];
993// if ((ctype>0)){
994// res+=0.002;
995// res*= gcorp[rsigmaz];
996// }
997// }
998// else {
999// if (padlength<1.1){
1000// snoise2 = gnoise2;
1001// res = ggg2[amp]*z+glandau2[amp]*angle2;
1002// if (ctype==0) res *= gcor02[rsigmaz];
1003// if ((ctype>0)){
1004// res+=0.002;
1005// res*= gcorp[rsigmaz];
1006// }
1007// }
1008// else{
1009// snoise2 = gnoise3;
1010// res = ggg3[amp]*z+glandau3[amp]*angle2;
1011// if (ctype==0) res *= gcor02[rsigmaz];
1012// if ((ctype>0)){
1013// res+=0.002;
1014// res*= gcorp[rsigmaz];
1015// }
1016// }
1017// }
1018
1019// if (ctype<0){
1020// res+=0.002;
1021// res*=1.3;
1022// }
1023// if ((ctype<0) &&amp<70){
1024// res+=0.002;
1025// res*=1.3;
1026// }
1027// res += snoise2;
1028// if (res<2*snoise2)
1029// res = 2*snoise2;
1030// if (res>3) res =3;
1031// seed->SetErrorZ2(res);
1032// return res;
91162307 1033}
1034
1035
1036
91162307 1037
1c53abe2 1038
829455ad 1039void AliTPCtracker::RotateToLocal(AliTPCseed *seed)
c9427e08 1040{
1041 //rotate to track "local coordinata
1042 Float_t x = seed->GetX();
1043 Float_t y = seed->GetY();
1044 Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
91162307 1045
c9427e08 1046 if (y > ymax) {
b9671574 1047 seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
c9427e08 1048 if (!seed->Rotate(fSectors->GetAlpha()))
1049 return;
1050 } else if (y <-ymax) {
b9671574 1051 seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
c9427e08 1052 if (!seed->Rotate(-fSectors->GetAlpha()))
1053 return;
1054 }
1c53abe2 1055
c9427e08 1056}
1c53abe2 1057
1058
1059
1c53abe2 1060//_____________________________________________________________________________
829455ad 1061Double_t AliTPCtracker::F1old(Double_t x1,Double_t y1,
1c53abe2 1062 Double_t x2,Double_t y2,
47af7ca4 1063 Double_t x3,Double_t y3) const
1c53abe2 1064{
1065 //-----------------------------------------------------------------
1066 // Initial approximation of the track curvature
1067 //-----------------------------------------------------------------
1068 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1069 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1070 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1071 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1072 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1073
1074 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
91162307 1075 if ( xr*xr+yr*yr<=0.00000000000001) return 100;
1c53abe2 1076 return -xr*yr/sqrt(xr*xr+yr*yr);
1077}
1078
1079
91162307 1080
1c53abe2 1081//_____________________________________________________________________________
829455ad 1082Double_t AliTPCtracker::F1(Double_t x1,Double_t y1,
91162307 1083 Double_t x2,Double_t y2,
47af7ca4 1084 Double_t x3,Double_t y3) const
91162307 1085{
1086 //-----------------------------------------------------------------
1087 // Initial approximation of the track curvature
1088 //-----------------------------------------------------------------
1089 x3 -=x1;
1090 x2 -=x1;
1091 y3 -=y1;
1092 y2 -=y1;
1093 //
1094 Double_t det = x3*y2-x2*y3;
6e23caff 1095 if (TMath::Abs(det)<1e-10){
91162307 1096 return 100;
1097 }
1098 //
1099 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1100 Double_t x0 = x3*0.5-y3*u;
1101 Double_t y0 = y3*0.5+x3*u;
1102 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1103 if (det<0) c2*=-1;
1104 return c2;
1105}
1106
1107
829455ad 1108Double_t AliTPCtracker::F2(Double_t x1,Double_t y1,
1c53abe2 1109 Double_t x2,Double_t y2,
47af7ca4 1110 Double_t x3,Double_t y3) const
91162307 1111{
1112 //-----------------------------------------------------------------
1113 // Initial approximation of the track curvature
1114 //-----------------------------------------------------------------
1115 x3 -=x1;
1116 x2 -=x1;
1117 y3 -=y1;
1118 y2 -=y1;
1119 //
1120 Double_t det = x3*y2-x2*y3;
6e23caff 1121 if (TMath::Abs(det)<1e-10) {
91162307 1122 return 100;
1123 }
1124 //
1125 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1126 Double_t x0 = x3*0.5-y3*u;
1127 Double_t y0 = y3*0.5+x3*u;
1128 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1129 if (det<0) c2*=-1;
1130 x0+=x1;
1131 x0*=c2;
1132 return x0;
1133}
1134
1135
1136
1137//_____________________________________________________________________________
829455ad 1138Double_t AliTPCtracker::F2old(Double_t x1,Double_t y1,
91162307 1139 Double_t x2,Double_t y2,
47af7ca4 1140 Double_t x3,Double_t y3) const
1c53abe2 1141{
1142 //-----------------------------------------------------------------
1143 // Initial approximation of the track curvature times center of curvature
1144 //-----------------------------------------------------------------
1145 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1146 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1147 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1148 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1149 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1150
1151 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1152
1153 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1154}
1155
1156//_____________________________________________________________________________
829455ad 1157Double_t AliTPCtracker::F3(Double_t x1,Double_t y1,
1c53abe2 1158 Double_t x2,Double_t y2,
47af7ca4 1159 Double_t z1,Double_t z2) const
1c53abe2 1160{
1161 //-----------------------------------------------------------------
1162 // Initial approximation of the tangent of the track dip angle
1163 //-----------------------------------------------------------------
1164 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1165}
1166
1167
829455ad 1168Double_t AliTPCtracker::F3n(Double_t x1,Double_t y1,
91162307 1169 Double_t x2,Double_t y2,
47af7ca4 1170 Double_t z1,Double_t z2, Double_t c) const
1c53abe2 1171{
91162307 1172 //-----------------------------------------------------------------
1173 // Initial approximation of the tangent of the track dip angle
1174 //-----------------------------------------------------------------
1175
1176 // Double_t angle1;
1177
1178 //angle1 = (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1c53abe2 1179 //
91162307 1180 Double_t d = TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1181 if (TMath::Abs(d*c*0.5)>1) return 0;
1182 // Double_t angle2 = TMath::ASin(d*c*0.5);
b67e07dc 1183 // Double_t angle2 = AliTPCFastMath::FastAsin(d*c*0.5);
1184 Double_t angle2 = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): AliTPCFastMath::FastAsin(d*c*0.5);
91162307 1185
1186 angle2 = (z1-z2)*c/(angle2*2.);
1187 return angle2;
1188}
1189
829455ad 1190Bool_t AliTPCtracker::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
91162307 1191{//-----------------------------------------------------------------
1192 // This function find proloncation of a track to a reference plane x=x2.
1193 //-----------------------------------------------------------------
1194
1195 Double_t dx=x2-x1;
1196
1197 if (TMath::Abs(x[4]*x1 - x[2]) >= 0.999) {
1198 return kFALSE;
1c53abe2 1199 }
f8aae377 1200
bfd20868 1201 Double_t c1=x[4]*x1 - x[2], r1=TMath::Sqrt((1.-c1)*(1.+c1));
1202 Double_t c2=x[4]*x2 - x[2], r2=TMath::Sqrt((1.-c2)*(1.+c2));
91162307 1203 y = x[0];
1204 z = x[1];
1205
1206 Double_t dy = dx*(c1+c2)/(r1+r2);
1207 Double_t dz = 0;
1208 //
1209 Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1210
1211 if (TMath::Abs(delta)>0.01){
1212 dz = x[3]*TMath::ASin(delta)/x[4];
1213 }else{
b67e07dc 1214 dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
91162307 1215 }
1216
b67e07dc 1217 //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
f8aae377 1218
91162307 1219 y+=dy;
1220 z+=dz;
1221
1222 return kTRUE;
1c53abe2 1223}
1224
829455ad 1225Int_t AliTPCtracker::LoadClusters (TTree *const tree)
d26d9159 1226{
544c295f 1227 // load clusters
d26d9159 1228 //
1229 fInput = tree;
1230 return LoadClusters();
1231}
91162307 1232
af86c1fd 1233
829455ad 1234Int_t AliTPCtracker::LoadClusters(const TObjArray *arr)
af86c1fd 1235{
1236 //
1237 // load clusters to the memory
e7de6656 1238 AliTPCClustersRow *clrow = new AliTPCClustersRow("AliTPCclusterMI");
af86c1fd 1239 Int_t lower = arr->LowerBound();
1240 Int_t entries = arr->GetEntriesFast();
77f88633 1241
af86c1fd 1242 for (Int_t i=lower; i<entries; i++) {
1243 clrow = (AliTPCClustersRow*) arr->At(i);
77f88633 1244 if(!clrow) continue;
1245 if(!clrow->GetArray()) continue;
1246
af86c1fd 1247 //
1248 Int_t sec,row;
47af7ca4 1249 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
77f88633 1250
af86c1fd 1251 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1252 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1253 }
1254 //
1255 if (clrow->GetArray()->GetEntriesFast()<=0) continue;
bd26fa83 1256 AliTPCtrackerRow * tpcrow=0;
af86c1fd 1257 Int_t left=0;
1258 if (sec<fkNIS*2){
1259 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1260 left = sec/fkNIS;
1261 }
1262 else{
1263 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1264 left = (sec-fkNIS*2)/fkNOS;
1265 }
1266 if (left ==0){
1267 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
77f88633 1268 for (Int_t j=0;j<tpcrow->GetN1();++j)
1269 tpcrow->SetCluster1(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
af86c1fd 1270 }
1271 if (left ==1){
1272 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
77f88633 1273 for (Int_t j=0;j<tpcrow->GetN2();++j)
bfa00fba 1274 tpcrow->SetCluster2(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
af86c1fd 1275 }
e7de6656 1276 clrow->GetArray()->Clear("C");
af86c1fd 1277 }
1278 //
1279 delete clrow;
1280 LoadOuterSectors();
1281 LoadInnerSectors();
1282 return 0;
1283}
1284
829455ad 1285Int_t AliTPCtracker::LoadClusters(const TClonesArray *arr)
aa7f1a5a 1286{
1287 //
1288 // load clusters to the memory from one
1289 // TClonesArray
1290 //
1291 AliTPCclusterMI *clust=0;
98ee6d31 1292 Int_t count[72][96] = { {0} , {0} };
aa7f1a5a 1293
1294 // loop over clusters
1295 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1296 clust = (AliTPCclusterMI*)arr->At(icl);
1297 if(!clust) continue;
1298 //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
1299
1300 // transform clusters
1301 Transform(clust);
1302
1303 // count clusters per pad row
1304 count[clust->GetDetector()][clust->GetRow()]++;
1305 }
1306
1307 // insert clusters to sectors
1308 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1309 clust = (AliTPCclusterMI*)arr->At(icl);
1310 if(!clust) continue;
1311
1312 Int_t sec = clust->GetDetector();
1313 Int_t row = clust->GetRow();
98ee6d31 1314
1315 // filter overlapping pad rows needed by HLT
1316 if(sec<fkNIS*2) { //IROCs
1317 if(row == 30) continue;
1318 }
1319 else { // OROCs
1320 if(row == 27 || row == 76) continue;
1321 }
1322
2a97785a 1323 // Int_t left=0;
aa7f1a5a 1324 if (sec<fkNIS*2){
2a97785a 1325 // left = sec/fkNIS;
47af7ca4 1326 fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fkParam);
aa7f1a5a 1327 }
1328 else{
2a97785a 1329 // left = (sec-fkNIS*2)/fkNOS;
47af7ca4 1330 fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fkParam);
aa7f1a5a 1331 }
1332 }
1333
98ee6d31 1334 // Load functions must be called behind LoadCluster(TClonesArray*)
1335 // needed by HLT
1336 //LoadOuterSectors();
1337 //LoadInnerSectors();
aa7f1a5a 1338
1339 return 0;
1340}
1341
af86c1fd 1342
829455ad 1343Int_t AliTPCtracker::LoadClusters()
1c53abe2 1344{
1345 //
434cdbe1 1346 // load clusters to the memory
1347 Int_t nROCs = 72;
bfa00fba 1348 static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
91162307 1349 //
1350 // TTree * tree = fClustersArray.GetTree();
9a836cc2 1351 AliInfo("LoadClusters()\n");
39240815 1352 // reset crosstalk matrix
1353 //
434cdbe1 1354 for (Int_t isector=0; isector<nROCs*2; isector++){ //set all ellemts of crosstalk matrix to 0
39240815 1355 TMatrixD * crossTalkMatrix = (TMatrixD*)fCrossTalkSignalArray->At(isector);
1356 if (crossTalkMatrix)(*crossTalkMatrix)*=0;
1357 }
91162307 1358
1359 TTree * tree = fInput;
1360 TBranch * br = tree->GetBranch("Segment");
1361 br->SetAddress(&clrow);
bad6eb00 1362
1363 // Conversion of pad, row coordinates in local tracking coords.
1364 // Could be skipped here; is already done in clusterfinder
1365
6f8ff889 1366
91162307 1367 Int_t j=Int_t(tree->GetEntries());
1c53abe2 1368 for (Int_t i=0; i<j; i++) {
91162307 1369 br->GetEntry(i);
1370 //
1371 Int_t sec,row;
47af7ca4 1372 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
8cc1870a 1373
1374 // wire segmentID and nPadsPerSegment to be used for Xtalk calculation
1375 Int_t wireSegmentID = fkParam->GetWireSegment(sec,row);
1376 Float_t nPadsPerSegment = (Float_t)(fkParam->GetNPadsPerSegment(wireSegmentID));
1377 TMatrixD &crossTalkSignal = *((TMatrixD*)fCrossTalkSignalArray->At(sec));
434cdbe1 1378 TMatrixD &crossTalkSignalBelow = *((TMatrixD*)fCrossTalkSignalArray->At(sec+nROCs));
265b5e37 1379 Int_t nCols=crossTalkSignal.GetNcols();
3449a97c 1380 Double_t missingChargeFactor= AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrectionMissingCharge();
0201b65c 1381 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
8cc1870a 1382 AliTPCclusterMI *clXtalk= static_cast<AliTPCclusterMI*>(clrow->GetArray()->At(icl));
8cc1870a 1383 Transform((AliTPCclusterMI*)(clXtalk));
434cdbe1 1384 Int_t timeBinXtalk = clXtalk->GetTimeBin();
1385 Double_t rmsPadMin2=0.5*0.5+(fkParam->GetDiffT()*fkParam->GetDiffT())*(TMath::Abs((clXtalk->GetZ()-fkParam->GetZLength())))/(fkParam->GetPadPitchWidth(sec)*fkParam->GetPadPitchWidth(sec)); // minimal PRF width - 0.5 is the PRF in the pad units - we should et it from fkparam getters
1386 Double_t rmsTimeMin2=1+(fkParam->GetDiffL()*fkParam->GetDiffL())*(TMath::Abs((clXtalk->GetZ()-fkParam->GetZLength())))/(fkParam->GetZWidth()*fkParam->GetZWidth()); // minimal PRF width - 1 is the TRF in the time bin units - we should et it from fkParam getters
6f8ff889 1387 Double_t rmsTime2 = clXtalk->GetSigmaZ2()/(fkParam->GetZWidth()*fkParam->GetZWidth());
3449a97c 1388 Double_t rmsPad2 = clXtalk->GetSigmaY2()/(fkParam->GetPadPitchWidth(sec)*fkParam->GetPadPitchWidth(sec));
434cdbe1 1389 if (rmsPadMin2>rmsPad2){
1390 rmsPad2=rmsPadMin2;
1391 }
1392 if (rmsTimeMin2>rmsTime2){
1393 rmsTime2=rmsTimeMin2;
1394 }
3449a97c 1395
6f8ff889 1396 Double_t norm= 2.*TMath::Exp(-1.0/(2.*rmsTime2))+2.*TMath::Exp(-4.0/(2.*rmsTime2))+1.;
434cdbe1 1397 Double_t qTotXtalk = 0.;
1398 Double_t qTotXtalkMissing = 0.;
6f8ff889 1399 for (Int_t itb=timeBinXtalk-2, idelta=-2; itb<=timeBinXtalk+2; itb++,idelta++) {
265b5e37 1400 if (itb<0 || itb>=nCols) continue;
3449a97c 1401 Double_t missingCharge=0;
1402 Double_t trf= TMath::Exp(-idelta*idelta/(2.*rmsTime2));
434cdbe1 1403 if (missingChargeFactor>0) {
1404 for (Int_t dpad=-2; dpad<=2; dpad++){
1405 Double_t qPad = clXtalk->GetMax()*TMath::Exp(-dpad*dpad/(2.*rmsPad2))*trf;
1406 qPad-=2.*crossTalkSignal[wireSegmentID][itb]; // missing part due crosttalk - feedback part - factor 2 used
1407 if (TMath::Nint(qPad)<=fkParam->GetZeroSup()){
1408 missingCharge+=qPad+2.*crossTalkSignal[wireSegmentID][itb];
1409 }else{
1410 missingCharge+=2.*crossTalkSignal[wireSegmentID][itb];
1411 }
3449a97c 1412 }
1413 }
434cdbe1 1414 qTotXtalk = clXtalk->GetQ()*trf/norm+missingCharge*missingChargeFactor;
1415 qTotXtalkMissing = missingCharge;
1416 crossTalkSignal[wireSegmentID][itb]+= qTotXtalk/nPadsPerSegment;
1417 crossTalkSignalBelow[wireSegmentID][itb]+= qTotXtalkMissing/nPadsPerSegment;
1418 }
0201b65c 1419 }
434cdbe1 1420
91162307 1421 //
bd26fa83 1422 AliTPCtrackerRow * tpcrow=0;
91162307 1423 Int_t left=0;
1424 if (sec<fkNIS*2){
1425 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1426 left = sec/fkNIS;
1427 }
1428 else{
1429 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1430 left = (sec-fkNIS*2)/fkNOS;
1431 }
1432 if (left ==0){
b9671574 1433 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
77f88633 1434 for (Int_t k=0;k<tpcrow->GetN1();++k)
1435 tpcrow->SetCluster1(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
91162307 1436 }
1437 if (left ==1){
b9671574 1438 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
77f88633 1439 for (Int_t k=0;k<tpcrow->GetN2();++k)
bfa00fba 1440 tpcrow->SetCluster2(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
91162307 1441 }
1c53abe2 1442 }
65e67c9c 1443 if (AliTPCReconstructor::StreamLevel()&kStreamCrosstalkMatrix) {
434cdbe1 1444 //
1445 // dump the crosstalk matrices to tree for further investigation
1446 // a.) to estimate fluctuation of pedestal in indiviula wire segments
1447 // b.) to check correlation between regions
1448 // c.) to check relative conribution of signal below threshold to crosstalk
1449 for (Int_t isector=0; isector<nROCs; isector++){ //set all ellemts of crosstalk matrix to 0
1450 TMatrixD * crossTalkMatrix = (TMatrixD*)fCrossTalkSignalArray->At(isector);
1451 TMatrixD * crossTalkMatrixBelow = (TMatrixD*)fCrossTalkSignalArray->At(isector+nROCs);
1452 TVectorD vecAll(crossTalkMatrix->GetNrows());
1453 TVectorD vecBelow(crossTalkMatrix->GetNrows());
1454 //
1455 for (Int_t itime=0; itime<crossTalkMatrix->GetNcols(); itime++){
1456 for (Int_t iwire=0; iwire<crossTalkMatrix->GetNrows(); iwire++){
1457 vecAll[iwire]=(*crossTalkMatrix)(iwire,itime);
1458 vecBelow[iwire]=(*crossTalkMatrixBelow)(iwire,itime);
1459 }
1460 (*fDebugStreamer)<<"crosstalkMatrix"<<
1461 "sector="<<isector<<
1462 "itime="<<itime<<
1463 "vecAll.="<<&vecAll<< // crosstalk charge + charge below threshold
1464 "vecBelow.="<<&vecBelow<< // crosstalk contribution from signal below threshold
1465 "\n";
1466 }
1467 }
1468 }
1469
1470
91162307 1471 //
bfa00fba 1472 clrow->Clear("C");
91162307 1473 LoadOuterSectors();
1474 LoadInnerSectors();
6f8ff889 1475
1476 cout << " =================================================================================================================================== " << endl;
1477 cout << " AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection() = " << AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection() << endl;
1478 cout << " AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection() = " << AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection() << endl;
1479 cout << " =================================================================================================================================== " << endl;
1480
832977ba 1481 if (AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection()) ApplyTailCancellation();
265b5e37 1482 if (AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection()!=0.) ApplyXtalkCorrection();
65e67c9c 1483 //if (AliTPCReconstructor::GetRecoParam()->GetUseOulierClusterFilter()) FilterOutlierClusters();
91162307 1484 return 0;
1c53abe2 1485}
1486
eea44233 1487void AliTPCtracker::FilterOutlierClusters(){
1488 //
1489 // filter outlier clusters
1490 //
1491 /*
1492 1.)..... booking part
1493 nSectors=72;
1494 nTimeBins=fParam->Get....
1495 TH2F hisTime("","", sector,0,sector, nTimeBins,0,nTimeBins);
1496 TH2F hisPadRow("","", sector,0,sector, nPadRows,0,nPadRows);
1497 2.) .... filling part
1498 .... cluster loop { hisTime.Fill(cluster->GetDetector(),cluster->GetTimeBin()); }
1499
1500 3.) ...filtering part
1501 sector loop { calculate median,mean80 and rms80 of the nclusters per time bin; calculate median,mean80 and rms80 of the nclusters per par row; .... export values to the debug streamers - to decide which threshold to be used... }
1502
1503 sector loop
1504 { disable clusters in time bins > mean+ n rms80+ offsetTime disable clusters in padRow > mean+ n rms80+ offsetPadRow // how to dislable clusters? - new bit to introduce }
1505 //
1506 4. Disabling clusters
1507
1508 */
1509
1510 //
1511 // 1.) booking part
e731a3f8 1512 //
3e1f1ce7 1513 // AliTPCcalibDB *db=AliTPCcalibDB::Instance();
e731a3f8 1514 Int_t nSectors=AliTPCROC::Instance()->GetNSectors();
3e1f1ce7 1515 Int_t nTimeBins= 1100; // *Bug here - we should get NTimeBins from ALTRO - Parameters not relyable
1516 Int_t nPadRows=(AliTPCROC::Instance()->GetNRows(0) + AliTPCROC::Instance()->GetNRows(36));
e731a3f8 1517 // parameters for filtering
1518 const Double_t nSigmaCut=9.; // should be in recoParam ?
1519 const Double_t offsetTime=100; // should be in RecoParam ? -
1520 const Double_t offsetPadRow=300; // should be in RecoParam ?
1521 const Double_t offsetTimeAccept=8; // should be in RecoParam ? - obtained as mean +1 rms in high IR pp
eea44233 1522 TH2F hisTime("hisSectorTime","hisSectorTime", nSectors,0,nSectors, nTimeBins,0,nTimeBins);
1523 TH2F hisPadRow("hisSectorRow","hisSectorRow", nSectors,0,nSectors, nPadRows,0,nPadRows);
1524 //
1525 // 2.) Filling part -- loop over clusters
1526 //
44ca7282 1527 for (Int_t isector=0; isector<36; isector++){ // loop over sectors
1528 for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1529 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1530 Int_t nrows = sector.GetNRows();
1531 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1532 AliTPCtrackerRow& tpcrow = sector[row];
1533 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1534 if (iside>0) ncl=tpcrow.GetN2();
1535 for (Int_t i=0;i<ncl;i++) { // loop over clusters
1536 AliTPCclusterMI *cluster= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1537 hisTime.Fill(cluster->GetDetector(),cluster->GetTimeBin());
1538 hisPadRow.Fill(cluster->GetDetector(),cluster->GetRow());
1539 }
1540 }
1541 }
1542 }
44ca7282 1543
eea44233 1544 //
1545 // 3. Filtering part
1546 //
1547 TVectorD vecTime(nTimeBins);
44ca7282 1548 TVectorD vecPadRow(nPadRows);
c5dce091 1549 TVectorD vecMedianSectorTime(nSectors);
44ca7282 1550 TVectorD vecRMSSectorTime(nSectors);
c5dce091 1551 TVectorD vecMedianSectorTimeOut6(nSectors);
1552 TVectorD vecMedianSectorTimeOut9(nSectors);//
3e1f1ce7 1553 TVectorD vecMedianSectorTimeOut(nSectors);//
c5dce091 1554 TVectorD vecMedianSectorPadRow(nSectors);
44ca7282 1555 TVectorD vecRMSSectorPadRow(nSectors);
c5dce091 1556 TVectorD vecMedianSectorPadRowOut6(nSectors);
1557 TVectorD vecMedianSectorPadRowOut9(nSectors);
3e1f1ce7 1558 TVectorD vecMedianSectorPadRowOut(nSectors);
e731a3f8 1559 TVectorD vecSectorOut6(nSectors);
1560 TVectorD vecSectorOut9(nSectors);
3e1f1ce7 1561 TMatrixD matSectorCluster(nSectors,2);
e731a3f8 1562 //
1563 // 3.a) median, rms calculations for hisTime
1564 //
eea44233 1565 for (Int_t isec=0; isec<nSectors; isec++){
c5dce091 1566 vecMedianSectorTimeOut6[isec]=0;
1567 vecMedianSectorTimeOut9[isec]=0;
eea44233 1568 for (Int_t itime=0; itime<nTimeBins; itime++){
1569 vecTime[itime]=hisTime.GetBinContent(isec+1, itime+1);
1570 }
3e1f1ce7 1571 Double_t median= TMath::Mean(nTimeBins,vecTime.GetMatrixArray());
c5dce091 1572 Double_t rms= TMath::RMS(nTimeBins,vecTime.GetMatrixArray());
1573 vecMedianSectorTime[isec]=median;
44ca7282 1574 vecRMSSectorTime[isec]=rms;
3e1f1ce7 1575 if ((AliTPCReconstructor::StreamLevel()&kStreamFilterClusterInfo)>0) AliInfo(TString::Format("Sector TimeStat: %d\t%8.0f\t%8.0f",isec,median,rms).Data());
eea44233 1576 //
1577 // declare outliers
1578 for (Int_t itime=0; itime<nTimeBins; itime++){
1579 Double_t entries= hisTime.GetBinContent(isec+1, itime+1);
44ca7282 1580 if (entries>median+6.*rms+offsetTime) {
c5dce091 1581 vecMedianSectorTimeOut6[isec]+=1;
1582 }
44ca7282 1583 if (entries>median+9.*rms+offsetTime) {
c5dce091 1584 vecMedianSectorTimeOut9[isec]+=1;
eea44233 1585 }
1586 }
c5dce091 1587 }
e731a3f8 1588 //
1589 // 3.b) median, rms calculations for hisPadRow
1590 //
44ca7282 1591 for (Int_t isec=0; isec<nSectors; isec++){
1592 vecMedianSectorPadRowOut6[isec]=0;
1593 vecMedianSectorPadRowOut9[isec]=0;
1594 for (Int_t ipadrow=0; ipadrow<nPadRows; ipadrow++){
1595 vecPadRow[ipadrow]=hisPadRow.GetBinContent(isec+1, ipadrow+1);
1596 }
3e1f1ce7 1597 Int_t nPadRowsSector= AliTPCROC::Instance()->GetNRows(isec);
1598 Double_t median= TMath::Mean(nPadRowsSector,vecPadRow.GetMatrixArray());
1599 Double_t rms= TMath::RMS(nPadRowsSector,vecPadRow.GetMatrixArray());
44ca7282 1600 vecMedianSectorPadRow[isec]=median;
1601 vecRMSSectorPadRow[isec]=rms;
3e1f1ce7 1602 if ((AliTPCReconstructor::StreamLevel()&kStreamFilterClusterInfo)>0) AliInfo(TString::Format("Sector PadRowStat: %d\t%8.0f\t%8.0f",isec,median,rms).Data());
44ca7282 1603 //
1604 // declare outliers
1605 for (Int_t ipadrow=0; ipadrow<nPadRows; ipadrow++){
1606 Double_t entries= hisPadRow.GetBinContent(isec+1, ipadrow+1);
1607 if (entries>median+6.*rms+offsetPadRow) {
1608 vecMedianSectorPadRowOut6[isec]+=1;
1609 }
1610 if (entries>median+9.*rms+offsetPadRow) {
1611 vecMedianSectorPadRowOut9[isec]+=1;
1612 }
1613 }
1614 }
1615 //
e731a3f8 1616 // 3.c) filter outlier sectors
1617 //
1618 Double_t medianSectorTime = TMath::Median(nSectors, vecTime.GetMatrixArray());
1619 Double_t mean69SectorTime, rms69SectorTime=0;
1620 AliMathBase::EvaluateUni(nSectors, vecTime.GetMatrixArray(), mean69SectorTime,rms69SectorTime,69);
1621 for (Int_t isec=0; isec<nSectors; isec++){
1622 vecSectorOut6[isec]=0;
1623 vecSectorOut9[isec]=0;
3e1f1ce7 1624 matSectorCluster(isec,0)=0;
1625 matSectorCluster(isec,1)=0;
65e67c9c 1626 if (TMath::Abs(vecMedianSectorTime[isec])>(mean69SectorTime+6.*(rms69SectorTime+ offsetTimeAccept))) {
1627 vecSectorOut6[isec]=1;
1628 }
1629 if (TMath::Abs(vecMedianSectorTime[isec])>(mean69SectorTime+9.*(rms69SectorTime+ offsetTimeAccept))){
1630 vecSectorOut9[isec]=1;
1631 }
e731a3f8 1632 }
1633 // light version of export variable
1634 Int_t filteredSector= vecSectorOut9.Sum(); // light version of export variable
1635 Int_t filteredSectorTime= vecMedianSectorTimeOut9.Sum();
1636 Int_t filteredSectorPadRow= vecMedianSectorPadRowOut9.Sum();
65e67c9c 1637 if (fEvent){
1638 fEvent->SetTPCNoiseFilterCounter(0,TMath::Min(filteredSector,255));
1639 fEvent->SetTPCNoiseFilterCounter(1,TMath::Min(filteredSectorTime,255));
1640 fEvent->SetTPCNoiseFilterCounter(2,TMath::Min(filteredSectorPadRow,255));
eea44233 1641 }
65e67c9c 1642
44ca7282 1643 //
1644 // 4. Disabling clusters in outlier layers
1645 //
65e67c9c 1646 Int_t counterAll=0;
1647 Int_t counterOut=0;
44ca7282 1648 for (Int_t isector=0; isector<36; isector++){ // loop over sectors
1649 for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1650 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1651 Int_t nrows = sector.GetNRows();
1652 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1653 AliTPCtrackerRow& tpcrow = sector[row];
1654 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1655 if (iside>0) ncl=tpcrow.GetN2();
1656 for (Int_t i=0;i<ncl;i++) { // loop over clusters
1657 AliTPCclusterMI *cluster= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1658 Double_t medianTime=vecMedianSectorTime[cluster->GetDetector()];
1659 Double_t medianPadRow=vecMedianSectorPadRow[cluster->GetDetector()];
1660 Double_t rmsTime=vecRMSSectorTime[cluster->GetDetector()];
1661 Double_t rmsPadRow=vecRMSSectorPadRow[cluster->GetDetector()];
1662 Int_t entriesPadRow=hisPadRow.GetBinContent(cluster->GetDetector()+1, cluster->GetRow()+1);
1663 Int_t entriesTime=hisTime.GetBinContent(cluster->GetDetector()+1, cluster->GetTimeBin()+1);
1664 Bool_t isOut=kFALSE;
65e67c9c 1665 if (vecSectorOut9[cluster->GetDetector()]>0.5) {
1666 isOut=kTRUE;
1667 }
e731a3f8 1668
3e1f1ce7 1669 if (entriesTime>medianTime+nSigmaCut*rmsTime+offsetTime) {
1670 isOut=kTRUE;
1671 vecMedianSectorTimeOut[cluster->GetDetector()]++;
1672 }
1673 if (entriesPadRow>medianPadRow+nSigmaCut*rmsPadRow+offsetPadRow) {
1674 isOut=kTRUE;
1675 vecMedianSectorPadRowOut[cluster->GetDetector()]++;
1676 }
65e67c9c 1677 counterAll++;
3e1f1ce7 1678 matSectorCluster(cluster->GetDetector(),0)+=1;
44ca7282 1679 if (isOut){
1680 cluster->Disable();
65e67c9c 1681 counterOut++;
3e1f1ce7 1682 matSectorCluster(cluster->GetDetector(),1)+=1;
44ca7282 1683 }
1684 }
1685 }
1686 }
1687 }
3e1f1ce7 1688 for (Int_t isec=0; isec<nSectors; isec++){
1689 if ((AliTPCReconstructor::StreamLevel()&kStreamFilterClusterInfo)>0) AliInfo(TString::Format("Sector Stat: %d\t%8.0f\t%8.0f",isec,matSectorCluster(isec,1),matSectorCluster(isec,0)).Data());
1690 }
65e67c9c 1691 //
1692 // dump info to streamer - for later tuning of cuts
1693 //
1694 if ((AliTPCReconstructor::StreamLevel()&kStreamFilterClusterInfo)>0) { // stream TPC data ouliers filtering infomation
3e1f1ce7 1695 AliLog::Flush();
1696 AliInfo(TString::Format("Cluster counter: (%d/%d) (Filtered/All)",counterOut,counterAll).Data());
1697 for (Int_t iSec=0; iSec<nSectors; iSec++){
1698 if (vecSectorOut9[iSec]>0 || matSectorCluster(iSec,1)>0) {
1699 AliInfo(TString::Format("Filtered sector\t%d",iSec).Data());
1700 Double_t vecMedTime =TMath::Median(72,vecMedianSectorTime.GetMatrixArray());
1701 Double_t vecMedPadRow =TMath::Median(72,vecMedianSectorPadRow.GetMatrixArray());
1702 Double_t vecMedCluster=(counterAll-counterOut)/72;
1703 AliInfo(TString::Format("VecMedianSectorTime\t(%4.4f/%4.4f/%4.4f)", vecMedianSectorTimeOut[iSec],vecMedianSectorTime[iSec],vecMedTime).Data());
1704 AliInfo(TString::Format("VecMedianSectorPadRow\t(%4.4f/%4.4f/%4.4f)", vecMedianSectorPadRowOut[iSec],vecMedianSectorPadRow[iSec],vecMedPadRow).Data());
1705 AliInfo(TString::Format("MatSectorCluster\t(%4.4f/%4.4f/%4.4f)\n", matSectorCluster(iSec,1), matSectorCluster(iSec,0), vecMedCluster).Data());
1706 AliLog::Flush();
1707 }
1708 }
1709 AliLog::Flush();
1710 Int_t eventNr = fEvent->GetEventNumberInFile();
65e67c9c 1711 (*fDebugStreamer)<<"filterClusterInfo"<<
1712 // minimal set variables for the ESDevent
3e1f1ce7 1713 "eventNr="<<eventNr<<
65e67c9c 1714 "counterAll="<<counterAll<<
1715 "counterOut="<<counterOut<<
1716 //
1717 "filteredSector="<<filteredSector<< // counter filtered sectors
1718 "filteredSectorTime="<<filteredSectorTime<< // counter filtered time bins
1719 "filteredSectorPadRow="<<filteredSectorPadRow<< // counter filtered pad-rows
1720 // per sector outlier information
1721 "medianSectorTime="<<medianSectorTime<< // median number of clusters per sector/timebin
1722 "mean69SectorTime="<<mean69SectorTime<< // LTM statistic mean of clusters per sector/timebin
1723 "rms69SectorTime="<<rms69SectorTime<< // LTM statistic RMS of clusters per sector/timebin
1724 "vecSectorOut6.="<<&vecSectorOut6<< // flag array sector - 6 sigma +accept margin outlier
1725 "vecSectorOut9.="<<&vecSectorOut9<< // flag array sector - 9 sigma + accept margin outlier
1726 // per sector/timebin outlier detection
1727 "vecMedianSectorTime.="<<&vecMedianSectorTime<<
1728 "vecRMSSectorTime.="<<&vecRMSSectorTime<<
1729 "vecMedianSectorTimeOut6.="<<&vecMedianSectorTimeOut6<<
1730 "vecMedianSectorTimeOut9.="<<&vecMedianSectorTimeOut9<<
3e1f1ce7 1731 "vecMedianSectorTimeOut0.="<<&vecMedianSectorTimeOut<<
65e67c9c 1732 // per sector/pad-row outlier detection
1733 "vecMedianSectorPadRow.="<<&vecMedianSectorPadRow<<
1734 "vecRMSSectorPadRow.="<<&vecRMSSectorPadRow<<
1735 "vecMedianSectorPadRowOut6.="<<&vecMedianSectorPadRowOut6<<
1736 "vecMedianSectorPadRowOut9.="<<&vecMedianSectorPadRowOut9<<
3e1f1ce7 1737 "vecMedianSectorPadRowOut9.="<<&vecMedianSectorPadRowOut<<
65e67c9c 1738 "\n";
1739 ((*fDebugStreamer)<<"filterClusterInfo").GetTree()->Write();
1740 fDebugStreamer->GetFile()->Flush();
1741 }
eea44233 1742}
1743
829455ad 1744void AliTPCtracker::UnloadClusters()
91162307 1745{
1746 //
1747 // unload clusters from the memory
1748 //
1749 Int_t nrows = fOuterSec->GetNRows();
1750 for (Int_t sec = 0;sec<fkNOS;sec++)
1751 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1752 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
982aff31 1753 // if (tpcrow){
1754 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1755 // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1756 //}
1757 tpcrow->ResetClusters();
1c53abe2 1758 }
91162307 1759 //
1760 nrows = fInnerSec->GetNRows();
1761 for (Int_t sec = 0;sec<fkNIS;sec++)
1762 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1763 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
982aff31 1764 //if (tpcrow){
1765 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1766 //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1767 //}
1768 tpcrow->ResetClusters();
91162307 1769 }
1770
1771 return ;
1c53abe2 1772}
1773
829455ad 1774void AliTPCtracker::FillClusterArray(TObjArray* array) const{
002af263 1775 //
1776 // Filling cluster to the array - For visualization purposes
1777 //
1778 Int_t nrows=0;
1779 nrows = fOuterSec->GetNRows();
1780 for (Int_t sec = 0;sec<fkNOS;sec++)
1781 for (Int_t row = 0;row<nrows;row++){
1782 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1783 if (!tpcrow) continue;
1784 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1785 array->AddLast((TObject*)((*tpcrow)[icl]));
1786 }
1787 }
1788 nrows = fInnerSec->GetNRows();
1789 for (Int_t sec = 0;sec<fkNIS;sec++)
1790 for (Int_t row = 0;row<nrows;row++){
1791 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1792 if (!tpcrow) continue;
1793 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1794 array->AddLast((TObject*)(*tpcrow)[icl]);
1795 }
1796 }
1797}
1798
1799
829455ad 1800void AliTPCtracker::Transform(AliTPCclusterMI * cluster){
893468d9 1801 //
544c295f 1802 // transformation
893468d9 1803 //
3f3549a3 1804 AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1805 AliTPCTransform *transform = calibDB->GetTransform() ;
24db6af7 1806 if (!transform) {
1807 AliFatal("Tranformations not in calibDB");
ec26e231 1808 return;
24db6af7 1809 }
239f39b1 1810 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
2942f542 1811 Double_t x[3]={static_cast<Double_t>(cluster->GetRow()),static_cast<Double_t>(cluster->GetPad()),static_cast<Double_t>(cluster->GetTimeBin())};
24db6af7 1812 Int_t i[1]={cluster->GetDetector()};
022ee144 1813 transform->Transform(x,i,0,1);
afbaa016 1814 // if (cluster->GetDetector()%36>17){
1815 // x[1]*=-1;
1816 //}
022ee144 1817
24db6af7 1818 //
1819 // in debug mode check the transformation
1820 //
65e67c9c 1821 if ((AliTPCReconstructor::StreamLevel()&kStreamTransform)>0) {
af86c1fd 1822 Float_t gx[3];
1823 cluster->GetGlobalXYZ(gx);
002af263 1824 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
24db6af7 1825 TTreeSRedirector &cstream = *fDebugStreamer;
65e67c9c 1826 cstream<<"Transform"<< // needed for debugging of the cluster transformation, resp. used for later visualization
002af263 1827 "event="<<event<<
24db6af7 1828 "x0="<<x[0]<<
1829 "x1="<<x[1]<<
1830 "x2="<<x[2]<<
af86c1fd 1831 "gx0="<<gx[0]<<
1832 "gx1="<<gx[1]<<
1833 "gx2="<<gx[2]<<
24db6af7 1834 "Cl.="<<cluster<<
1835 "\n";
1836 }
1837 cluster->SetX(x[0]);
1838 cluster->SetY(x[1]);
1839 cluster->SetZ(x[2]);
19b00333 1840 // The old stuff:
0201b65c 1841 //
1842 //
1843 //
47af7ca4 1844 //if (!fkParam->IsGeoRead()) fkParam->ReadGeoMatrices();
3f3549a3 1845 if (AliTPCReconstructor::GetRecoParam()->GetUseSectorAlignment() && (!calibDB->HasAlignmentOCDB())){
1846 TGeoHMatrix *mat = fkParam->GetClusterMatrix(cluster->GetDetector());
1847 //TGeoHMatrix mat;
1848 Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1849 Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1850 if (mat) mat->LocalToMaster(pos,posC);
1851 else{
1852 // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
1853 }
1854 cluster->SetX(posC[0]);
1855 cluster->SetY(posC[1]);
1856 cluster->SetZ(posC[2]);
a7760332 1857 }
0201b65c 1858}
1c53abe2 1859
265b5e37 1860void AliTPCtracker::ApplyXtalkCorrection(){
1861 //
1862 // ApplyXtalk correction
1863 // Loop over all clusters
1864 // add to each cluster signal corresponding to common Xtalk mode for given time bin at given wire segment
265b5e37 1865 // cluster loop
1866 for (Int_t isector=0; isector<36; isector++){ //loop tracking sectors
1867 for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1868 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1869 Int_t nrows = sector.GetNRows();
1870 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1871 AliTPCtrackerRow& tpcrow = sector[row]; // row object
1872 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1873 if (iside>0) ncl=tpcrow.GetN2();
1874 Int_t xSector=0; // sector number in the TPC convention 0-72
1875 if (isector<18){ //if IROC
1876 xSector=isector+(iside>0)*18;
1877 }else{
1878 xSector=isector+18; // isector -18 +36
1879 if (iside>0) xSector+=18;
1880 }
1881 TMatrixD &crossTalkMatrix= *((TMatrixD*)fCrossTalkSignalArray->At(xSector));
1882 Int_t wireSegmentID = fkParam->GetWireSegment(xSector,row);
1883 for (Int_t i=0;i<ncl;i++) {
1884 AliTPCclusterMI *cluster= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1885 Int_t iTimeBin=TMath::Nint(cluster->GetTimeBin());
1886 Double_t xTalk= crossTalkMatrix[wireSegmentID][iTimeBin];
1887 cluster->SetMax(cluster->GetMax()+xTalk);
6f8ff889 1888 const Double_t kDummy=4;
265b5e37 1889 Double_t sumxTalk=xTalk*kDummy; // should be calculated via time response function
1890 cluster->SetQ(cluster->GetQ()+sumxTalk);
6f8ff889 1891
1892
65e67c9c 1893 if ((AliTPCReconstructor::StreamLevel()&kStreamXtalk)>0) { // flag: stream crosstalk correctio as applied to cluster
6f8ff889 1894 TTreeSRedirector &cstream = *fDebugStreamer;
1895 if (gRandom->Rndm() > 0.){
1896 cstream<<"Xtalk"<<
1897 "isector=" << isector << // sector [0,36]
1898 "iside=" << iside << // side A or C
1899 "row=" << row << // padrow
1900 "i=" << i << // index of the cluster
1901 "xSector=" << xSector << // sector [0,72]
1902 "wireSegmentID=" << wireSegmentID << // anode wire segment id [0,10]
1903 "iTimeBin=" << iTimeBin << // timebin of the corrected cluster
1904 "xTalk=" << xTalk << // Xtalk contribution added to Qmax
1905 "sumxTalk=" << sumxTalk << // Xtalk contribution added to Qtot (roughly 3*Xtalk)
1906 "cluster.=" << cluster << // corrected cluster object
1907 "\n";
1908 }
1909 }// dump the results to the debug streamer if in debug mode
1910
1911
1912
1913
1914
265b5e37 1915 }
1916 }
1917 }
1918 }
1919}
1920
9a836cc2 1921void AliTPCtracker::ApplyTailCancellation(){
7bc5f28b 1922 //
9a836cc2 1923 // Correct the cluster charge for the ion tail effect
7bc5f28b 1924 // The TimeResponse function accessed via AliTPCcalibDB (TPC/Calib/IonTail)
1925 //
7bc5f28b 1926
9a836cc2 1927 // Retrieve
1928 TObjArray *ionTailArr = (TObjArray*)AliTPCcalibDB::Instance()->GetIonTailArray();
1929 if (!ionTailArr) {AliFatal("TPC - Missing IonTail OCDB object");}
1930 TObject *rocFactorIROC = ionTailArr->FindObject("factorIROC");
1931 TObject *rocFactorOROC = ionTailArr->FindObject("factorOROC");
1932 Float_t factorIROC = (atof(rocFactorIROC->GetTitle()));
1933 Float_t factorOROC = (atof(rocFactorOROC->GetTitle()));
1934
1935 // find the number of clusters for the whole TPC (nclALL)
1936 Int_t nclALL=0;
1937 for (Int_t isector=0; isector<36; isector++){
1938 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1939 nclALL += sector.GetNClInSector(0);
1940 nclALL += sector.GetNClInSector(1);
1941 }
1942
1943 // start looping over all clusters
1944 for (Int_t iside=0; iside<2; iside++){ // loop over sides
7bc5f28b 1945 //
1946 //
9a836cc2 1947 for (Int_t secType=0; secType<2; secType++){ //loop over inner or outer sector
1948 // cache experimantal tuning factor for the different chamber type
1949 const Float_t ampfactor = (secType==0)?factorIROC:factorOROC;
1950 std::cout << " ampfactor = " << ampfactor << std::endl;
7bc5f28b 1951 //
9a836cc2 1952 for (Int_t sec = 0;sec<fkNOS;sec++){ //loop overs sectors
1953 //
1954 //
1955 // Cache time response functions and their positons to COG of the cluster
1956 TGraphErrors ** graphRes = new TGraphErrors *[20];
1957 Float_t * indexAmpGraphs = new Float_t[20];
1958 for (Int_t icache=0; icache<20; icache++)
1959 {
1960 graphRes[icache] = NULL;
1961 indexAmpGraphs[icache] = 0;
1962 }
1963 ///////////////////////////// --> position fo sie loop
d4559772 1964 if (!AliTPCcalibDB::Instance()->GetTailcancelationGraphs(sec+36*secType+18*iside,graphRes,indexAmpGraphs))
1965 {
1966 continue;
1967 }
9a836cc2 1968
1969 AliTPCtrackerSector &sector= (secType==0)?fInnerSec[sec]:fOuterSec[sec];
1970 Int_t nrows = sector.GetNRows(); // number of rows
1971 Int_t nclSector = sector.GetNClInSector(iside); // ncl per sector to be used for debugging
1972
1973 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1974
1975 AliTPCtrackerRow& tpcrow = sector[row]; // row object
1976 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1977 if (iside>0) ncl=tpcrow.GetN2();
1978
1979 // Order clusters in time for the proper correction of ion tail
1980 Float_t qTotArray[ncl]; // arrays to be filled with modified Qtot and Qmax values in order to avoid float->int conversion
1981 Float_t qMaxArray[ncl];
1982 Int_t sortedClusterIndex[ncl];
1983 Float_t sortedClusterTimeBin[ncl];
1984 TObjArray *rowClusterArray = new TObjArray(ncl); // cache clusters for each row
1985 for (Int_t i=0;i<ncl;i++)
1986 {
1987 qTotArray[i]=0;
1988 qMaxArray[i]=0;
1989 sortedClusterIndex[i]=i;
1990 AliTPCclusterMI *rowcl= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1991 if (rowcl) {
1992 rowClusterArray->AddAt(rowcl,i);
1993 } else {
1994 rowClusterArray->RemoveAt(i);
1995 }
1996 // Fill the timebin info to the array in order to sort wrt tb
1997 if (!rowcl) {
1998 sortedClusterTimeBin[i]=0.0;
1999 } else {
2000 sortedClusterTimeBin[i] = rowcl->GetTimeBin();
2001 }
2002
2003 }
2004 TMath::Sort(ncl,sortedClusterTimeBin,sortedClusterIndex,kFALSE); // sort clusters in time
2005
2006 // Main cluster correction loops over clusters
2007 for (Int_t icl0=0; icl0<ncl;icl0++){ // first loop over clusters
2008
2009 AliTPCclusterMI *cl0= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl0]));
2010
2011 if (!cl0) continue;
2012 Int_t nclPad=0;
265b5e37 2013 for (Int_t icl1=0; icl1<ncl;icl1++){ // second loop over clusters
9a836cc2 2014 AliTPCclusterMI *cl1= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl1]));
2015 if (!cl1) continue;
2016 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())>4) continue; // no contribution if far away in pad direction
2017 if (cl0->GetTimeBin()<= cl1->GetTimeBin()) continue; // no contibution to the tail if later
2018 if (TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin())>600) continue; // out of the range of response function
2019
2020 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())<4) nclPad++; // count ncl for every pad for debugging
2021
2022 // Get the correction values for Qmax and Qtot and find total correction for a given cluster
2023 Double_t ionTailMax=0.;
2024 Double_t ionTailTotal=0.;
2025 GetTailValue(ampfactor,ionTailMax,ionTailTotal,graphRes,indexAmpGraphs,cl0,cl1);
2026 ionTailMax=TMath::Abs(ionTailMax);
2027 ionTailTotal=TMath::Abs(ionTailTotal);
2028 qTotArray[icl0]+=ionTailTotal;
2029 qMaxArray[icl0]+=ionTailMax;
2030
2031 // Dump some info for debugging while clusters are being corrected
65e67c9c 2032 if ((AliTPCReconstructor::StreamLevel()&kStreamIonTail)>0) { // flag: stream ion tail correction as applied to cluster
9a836cc2 2033 TTreeSRedirector &cstream = *fDebugStreamer;
2034 if (gRandom->Rndm() > 0.999){
2035 cstream<<"IonTail"<<
2036 "cl0.=" <<cl0 << // cluster 0 (to be corrected)
2037 "cl1.=" <<cl1 << // cluster 1 (previous cluster)
2038 "ionTailTotal=" <<ionTailTotal << // ion Tail from cluster 1 contribution to cluster0
2039 "ionTailMax=" <<ionTailMax << // ion Tail from cluster 1 contribution to cluster0
2040 "\n";
2041 }
2042 }// dump the results to the debug streamer if in debug mode
2043
2044 }//end of second loop over clusters
2045
2046 // Set corrected values of the corrected cluster
2047 cl0->SetQ(TMath::Nint(Float_t(cl0->GetQ())+Float_t(qTotArray[icl0])));
2048 cl0->SetMax(TMath::Nint(Float_t(cl0->GetMax())+qMaxArray[icl0]));
2049
2050 // Dump some info for debugging after clusters are corrected
65e67c9c 2051 if ((AliTPCReconstructor::StreamLevel()&kStreamIonTail)>0) {
9a836cc2 2052 TTreeSRedirector &cstream = *fDebugStreamer;
2053 if (gRandom->Rndm() > 0.999){
2054 cstream<<"IonTailCorrected"<<
2055 "cl0.=" << cl0 << // cluster 0 with huge Qmax
2056 "ionTailTotalPerCluster=" << qTotArray[icl0] <<
2057 "ionTailMaxPerCluster=" << qMaxArray[icl0] <<
2058 "nclALL=" << nclALL <<
2059 "nclSector=" << nclSector <<
2060 "nclRow=" << ncl <<
2061 "nclPad=" << nclPad <<
2062 "row=" << row <<
2063 "sector=" << sec <<
2064 "icl0=" << icl0 <<
2065 "\n";
2066 }
2067 }// dump the results to the debug streamer if in debug mode
2068
2069 }//end of first loop over cluster
2070 delete rowClusterArray;
2071 }//end of loop over rows
2072 for (int i=0; i<20; i++) delete graphRes[i];
2073 delete [] graphRes;
2074 delete [] indexAmpGraphs;
2075
2076 }//end of loop over sectors
2077 }//end of loop over IROC/OROC
2078 }// end of side loop
7bc5f28b 2079}
9a836cc2 2080//_____________________________________________________________________________
5a516e0a 2081void AliTPCtracker::GetTailValue(Float_t ampfactor,Double_t &ionTailMax, Double_t &ionTailTotal,TGraphErrors **graphRes,Float_t *indexAmpGraphs,AliTPCclusterMI *cl0,AliTPCclusterMI *cl1){
9a836cc2 2082
2083 //
2084 // Function in order to calculate the amount of the correction to be added for a given cluster, return values are ionTailTaoltal and ionTailMax
265b5e37 2085 // Parameters:
2086 // cl0 - cluster to be modified
2087 // cl1 - source cluster ion tail of this cluster will be added to the cl0 (accroding time and pad response function)
9a836cc2 2088 //
9a836cc2 2089 const Double_t kMinPRF = 0.5; // minimal PRF width
2090 ionTailTotal = 0.; // correction value to be added to Qtot of cl0
2091 ionTailMax = 0.; // correction value to be added to Qmax of cl0
2092
2093 Float_t qTot0 = cl0->GetQ(); // cl0 Qtot info
2094 Float_t qTot1 = cl1->GetQ(); // cl1 Qtot info
2095 Int_t sectorPad = cl1->GetDetector(); // sector number
2096 Int_t padcl0 = TMath::Nint(cl0->GetPad()); // pad0
2097 Int_t padcl1 = TMath::Nint(cl1->GetPad()); // pad1
2098 Float_t padWidth = (sectorPad < 36)?0.4:0.6; // pad width in cm
2099 const Int_t deltaTimebin = TMath::Nint(TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin()))+12; //distance between pads of cl1 and cl0 increased by 12 bins
2100 Double_t rmsPad1 = (cl1->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl1->GetSigmaY2())/padWidth);
2101 Double_t rmsPad0 = (cl0->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl0->GetSigmaY2())/padWidth);
265b5e37 2102
2103
a3986da2 2104
9a836cc2 2105 Double_t sumAmp1=0.;
2106 for (Int_t idelta =-2; idelta<=2;idelta++){
2107 sumAmp1+=TMath::Exp(-idelta*idelta/(2*rmsPad1));
2108 }
7bc5f28b 2109
9a836cc2 2110 Double_t sumAmp0=0.;
2111 for (Int_t idelta =-2; idelta<=2;idelta++){
2112 sumAmp0+=TMath::Exp(-idelta*idelta/(2*rmsPad0));
2113 }
7bc5f28b 2114
9a836cc2 2115 // Apply the correction --> cl1 corrects cl0 (loop over cl1's pads and find which pads of cl0 are going to be corrected)
2116 Int_t padScan=2; // +-2 pad-timebin window will be scanned
2117 for (Int_t ipad1=padcl1-padScan; ipad1<=padcl1+padScan; ipad1++) {
2118 //
2119 //
2120 Float_t deltaPad1 = TMath::Abs(cl1->GetPad()-(Float_t)ipad1);
2121 Double_t amp1 = (TMath::Exp(-(deltaPad1*deltaPad1)/(2*rmsPad1)))/sumAmp1; // normalized pad response function
2122 Float_t qTotPad1 = amp1*qTot1; // used as a factor to multipliy the response function
2123
2124 // find closest value of cl1 to COG (among the time response functions' amplitude array --> to select proper t.r.f.)
2125 Int_t ampIndex = 0;
2126 Float_t diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[0]);
2127 for (Int_t j=0;j<20;j++) {
2128 if (diffAmp > TMath::Abs(deltaPad1-indexAmpGraphs[j]) && indexAmpGraphs[j]!=0)
2129 {
2130 diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[j]);
2131 ampIndex = j;
2132 }
2133 }
2134 if (!graphRes[ampIndex]) continue;
b4742ddd 2135 if (deltaTimebin+2 >= graphRes[ampIndex]->GetN()) continue;
9a836cc2 2136 if (graphRes[ampIndex]->GetY()[deltaTimebin+2]>=0) continue;
2137
2138 for (Int_t ipad0=padcl0-padScan; ipad0<=padcl0+padScan; ipad0++) {
2139 //
2140 //
2141 if (ipad1!=ipad0) continue; // check if ipad1 channel sees ipad0 channel, if not no correction to be applied.
2142
2143 Float_t deltaPad0 = TMath::Abs(cl0->GetPad()-(Float_t)ipad0);
2144 Double_t amp0 = (TMath::Exp(-(deltaPad0*deltaPad0)/(2*rmsPad0)))/sumAmp0; // normalized pad resp function
2145 Float_t qMaxPad0 = amp0*qTot0;
2146
2147 // Add 5 timebin range contribution around the max peak (-+2 tb window)
2148 for (Int_t itb=deltaTimebin-2; itb<=deltaTimebin+2; itb++) {
2149
2150 if (itb<0) continue;
2151 if (itb>=graphRes[ampIndex]->GetN()) continue;
2152
2153 // calculate contribution to qTot
2154 Float_t tailCorr = TMath::Abs((qTotPad1*ampfactor)*(graphRes[ampIndex])->GetY()[itb]);
2155 if (ipad1!=padcl0) {
2156 ionTailTotal += TMath::Min(qMaxPad0,tailCorr); // for side pad
2157 } else {
2158 ionTailTotal += tailCorr; // for center pad
2159 }
2160 // calculate contribution to qMax
2161 if (itb == deltaTimebin && ipad1 == padcl0) ionTailMax += tailCorr;
2162
2163 } // end of tb correction loop which is applied over 5 tb range
2164
2165 } // end of cl0 loop
2166 } // end of cl1 loop
2167
2168}
7bc5f28b 2169
1c53abe2 2170//_____________________________________________________________________________
829455ad 2171Int_t AliTPCtracker::LoadOuterSectors() {
1c53abe2 2172 //-----------------------------------------------------------------
91162307 2173 // This function fills outer TPC sectors with clusters.
1c53abe2 2174 //-----------------------------------------------------------------
91162307 2175 Int_t nrows = fOuterSec->GetNRows();
2176 UInt_t index=0;
2177 for (Int_t sec = 0;sec<fkNOS;sec++)
2178 for (Int_t row = 0;row<nrows;row++){
bd26fa83 2179 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
91162307 2180 Int_t sec2 = sec+2*fkNIS;
2181 //left
b9671574 2182 Int_t ncl = tpcrow->GetN1();
91162307 2183 while (ncl--) {
b9671574 2184 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
91162307 2185 index=(((sec2<<8)+row)<<16)+ncl;
2186 tpcrow->InsertCluster(c,index);
2187 }
2188 //right
b9671574 2189 ncl = tpcrow->GetN2();
91162307 2190 while (ncl--) {
b9671574 2191 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
91162307 2192 index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
2193 tpcrow->InsertCluster(c,index);
2194 }
2195 //
2196 // write indexes for fast acces
2197 //
2198 for (Int_t i=0;i<510;i++)
b9671574 2199 tpcrow->SetFastCluster(i,-1);
91162307 2200 for (Int_t i=0;i<tpcrow->GetN();i++){
2201 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
b9671574 2202 tpcrow->SetFastCluster(zi,i); // write index
91162307 2203 }
2204 Int_t last = 0;
2205 for (Int_t i=0;i<510;i++){
b9671574 2206 if (tpcrow->GetFastCluster(i)<0)
2207 tpcrow->SetFastCluster(i,last);
91162307 2208 else
b9671574 2209 last = tpcrow->GetFastCluster(i);
91162307 2210 }
2211 }
2212 fN=fkNOS;
2213 fSectors=fOuterSec;
2214 return 0;
2215}
2216
2217
2218//_____________________________________________________________________________
829455ad 2219Int_t AliTPCtracker::LoadInnerSectors() {
91162307 2220 //-----------------------------------------------------------------
2221 // This function fills inner TPC sectors with clusters.
2222 //-----------------------------------------------------------------
2223 Int_t nrows = fInnerSec->GetNRows();
2224 UInt_t index=0;
2225 for (Int_t sec = 0;sec<fkNIS;sec++)
2226 for (Int_t row = 0;row<nrows;row++){
bd26fa83 2227 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
91162307 2228 //
2229 //left
b9671574 2230 Int_t ncl = tpcrow->GetN1();
91162307 2231 while (ncl--) {
b9671574 2232 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
91162307 2233 index=(((sec<<8)+row)<<16)+ncl;
2234 tpcrow->InsertCluster(c,index);
2235 }
2236 //right
b9671574 2237 ncl = tpcrow->GetN2();
91162307 2238 while (ncl--) {
b9671574 2239 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
91162307 2240 index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
2241 tpcrow->InsertCluster(c,index);
2242 }
2243 //
2244 // write indexes for fast acces
2245 //
2246 for (Int_t i=0;i<510;i++)
b9671574 2247 tpcrow->SetFastCluster(i,-1);
91162307 2248 for (Int_t i=0;i<tpcrow->GetN();i++){
2249 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
b9671574 2250 tpcrow->SetFastCluster(zi,i); // write index
91162307 2251 }
2252 Int_t last = 0;
2253 for (Int_t i=0;i<510;i++){
b9671574 2254 if (tpcrow->GetFastCluster(i)<0)
2255 tpcrow->SetFastCluster(i,last);
91162307 2256 else
b9671574 2257 last = tpcrow->GetFastCluster(i);
91162307 2258 }
1c53abe2 2259
91162307 2260 }
2261
1c53abe2 2262 fN=fkNIS;
2263 fSectors=fInnerSec;
91162307 2264 return 0;
2265}
2266
2267
2268
2269//_________________________________________________________________________
829455ad 2270AliTPCclusterMI *AliTPCtracker::GetClusterMI(Int_t index) const {
91162307 2271 //--------------------------------------------------------------------
2272 // Return pointer to a given cluster
2273 //--------------------------------------------------------------------
e7eb17e4 2274 if (index<0) return 0; // no cluster
91162307 2275 Int_t sec=(index&0xff000000)>>24;
2276 Int_t row=(index&0x00ff0000)>>16;
d26d9159 2277 Int_t ncl=(index&0x00007fff)>>00;
91162307 2278
bd26fa83 2279 const AliTPCtrackerRow * tpcrow=0;
bfa00fba 2280 TClonesArray * clrow =0;
3da363a1 2281
ad23441a 2282 if (sec<0 || sec>=fkNIS*4) {
2283 AliWarning(Form("Wrong sector %d",sec));
2284 return 0x0;
2285 }
2286
91162307 2287 if (sec<fkNIS*2){
462fb6e0 2288 AliTPCtrackerSector& tracksec = fInnerSec[sec%fkNIS];
2289 if (tracksec.GetNRows()<=row) return 0;
2290 tpcrow = &(tracksec[row]);
3da363a1 2291 if (tpcrow==0) return 0;
2292
2293 if (sec<fkNIS) {
b9671574 2294 if (tpcrow->GetN1()<=ncl) return 0;
2295 clrow = tpcrow->GetClusters1();
3da363a1 2296 }
2297 else {
b9671574 2298 if (tpcrow->GetN2()<=ncl) return 0;
2299 clrow = tpcrow->GetClusters2();
3da363a1 2300 }
91162307 2301 }
3da363a1 2302 else {
462fb6e0 2303 AliTPCtrackerSector& tracksec = fOuterSec[(sec-fkNIS*2)%fkNOS];
2304 if (tracksec.GetNRows()<=row) return 0;
2305 tpcrow = &(tracksec[row]);
3da363a1 2306 if (tpcrow==0) return 0;
2307
2308 if (sec-2*fkNIS<fkNOS) {
b9671574 2309 if (tpcrow->GetN1()<=ncl) return 0;
2310 clrow = tpcrow->GetClusters1();
3da363a1 2311 }
2312 else {
b9671574 2313 if (tpcrow->GetN2()<=ncl) return 0;
2314 clrow = tpcrow->GetClusters2();
3da363a1 2315 }
91162307 2316 }
3da363a1 2317
bfa00fba 2318 return (AliTPCclusterMI*)clrow->At(ncl);
91162307 2319
1c53abe2 2320}
2321
91162307 2322
2323
829455ad 2324Int_t AliTPCtracker::FollowToNext(AliTPCseed& t, Int_t nr) {
1c53abe2 2325 //-----------------------------------------------------------------
2326 // This function tries to find a track prolongation to next pad row
2327 //-----------------------------------------------------------------
1c53abe2 2328 //
91162307 2329 Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
76d56fd6 2330 //
2331 //
4d158c36 2332 AliTPCclusterMI *cl=0;
2333 Int_t tpcindex= t.GetClusterIndex2(nr);
2334 //
2335 // update current shape info every 5 pad-row
2336 // if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
2337 GetShape(&t,nr);
2338 //}
2339 //
2340 if (fIteration>0 && tpcindex>=-1){ //if we have already clusters
2341 //
2342 if (tpcindex==-1) return 0; //track in dead zone
f124f8bf 2343 if (tpcindex >= 0){ //
b9671574 2344 cl = t.GetClusterPointer(nr);
97d77e7a 2345 //if (cl==0) cl = GetClusterMI(tpcindex);
2346 if (!cl) cl = GetClusterMI(tpcindex);
b9671574 2347 t.SetCurrentClusterIndex1(tpcindex);
4d158c36 2348 }
2349 if (cl){
2350 Int_t relativesector = ((tpcindex&0xff000000)>>24)%18; // if previously accepted cluster in different sector
2351 Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
2352 //
2353 if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
2354 if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
2355
2356 if (TMath::Abs(angle-t.GetAlpha())>0.001){
2357 Double_t rotation = angle-t.GetAlpha();
b9671574 2358 t.SetRelativeSector(relativesector);
1791d824 2359 if (!t.Rotate(rotation)) {
2360 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
2361 return 0;
2362 }
2363 }
2364 if (!t.PropagateTo(x)) {
2365 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
2366 return 0;
4d158c36 2367 }
4d158c36 2368 //
b9671574 2369 t.SetCurrentCluster(cl);
2370 t.SetRow(nr);
00055a22 2371 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
4d158c36 2372 if ((tpcindex&0x8000)==0) accept =0;
2373 if (accept<3) {
2374 //if founded cluster is acceptible
2375 if (cl->IsUsed(11)) { // id cluster is shared inrease uncertainty
b9671574 2376 t.SetErrorY2(t.GetErrorY2()+0.03);
2377 t.SetErrorZ2(t.GetErrorZ2()+0.03);
2378 t.SetErrorY2(t.GetErrorY2()*3);
2379 t.SetErrorZ2(t.GetErrorZ2()*3);
4d158c36 2380 }
b9671574 2381 t.SetNFoundable(t.GetNFoundable()+1);
4d158c36 2382 UpdateTrack(&t,accept);
2383 return 1;
f124f8bf 2384 }
2385 else { // Remove old cluster from track
2386 t.SetClusterIndex(nr, -3);
2387 t.SetClusterPointer(nr, 0);
2388 }
4d158c36 2389 }
1627d1c4 2390 }
3f82c4f2 2391 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0; // cut on angle
76d56fd6 2392 if (fIteration>1 && IsFindable(t)){
3f82c4f2 2393 // not look for new cluster during refitting
b9671574 2394 t.SetNFoundable(t.GetNFoundable()+1);
3f82c4f2 2395 return 0;
2396 }
91162307 2397 //
4d158c36 2398 UInt_t index=0;
ca142b1f 2399 // if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
f124f8bf 2400 if (!t.PropagateTo(x)) {
2401 if (fIteration==0) t.SetRemoval(10);
2402 return 0;
2403 }
2404 Double_t y = t.GetY();
91162307 2405 if (TMath::Abs(y)>ymax){
2406 if (y > ymax) {
b9671574 2407 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
91162307 2408 if (!t.Rotate(fSectors->GetAlpha()))
2409 return 0;
2410 } else if (y <-ymax) {
b9671574 2411 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
91162307 2412 if (!t.Rotate(-fSectors->GetAlpha()))
2413 return 0;
2414 }
f124f8bf 2415 if (!t.PropagateTo(x)) {
2416 if (fIteration==0) t.SetRemoval(10);
2417 return 0;
2418 }
2419 y = t.GetY();
91162307 2420 }
2421 //
4d158c36 2422 Double_t z=t.GetZ();
2423 //
a3232aae 2424
b9671574 2425 if (!IsActive(t.GetRelativeSector(),nr)) {
2426 t.SetInDead(kTRUE);
a3232aae 2427 t.SetClusterIndex2(nr,-1);
2428 return 0;
2429 }
2430 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
b9671574 2431 Bool_t isActive = IsActive(t.GetRelativeSector(),nr);
2432 Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
a3232aae 2433
2434 if (!isActive || !isActive2) return 0;
2435
bd26fa83 2436 const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
91162307 2437 if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
2438 Double_t roady =1.;
2439 Double_t roadz = 1.;
2440 //
b9671574 2441 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
2442 t.SetInDead(kTRUE);
91162307 2443 t.SetClusterIndex2(nr,-1);
1c53abe2 2444 return 0;
2445 }
2446 else
2447 {
76d56fd6 2448 if (IsFindable(t))
47af7ca4 2449 // if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fkParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
b9671574 2450 t.SetNFoundable(t.GetNFoundable()+1);
1627d1c4 2451 else
2452 return 0;
1c53abe2 2453 }
2454 //calculate
91162307 2455 if (krow) {
2456 // cl = krow.FindNearest2(y+10.,z,roady,roadz,index);
2457 cl = krow.FindNearest2(y,z,roady,roadz,index);
b9671574 2458 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
91162307 2459 }
91162307 2460 if (cl) {
b9671574 2461 t.SetCurrentCluster(cl);
2462 t.SetRow(nr);
4d158c36 2463 if (fIteration==2&&cl->IsUsed(10)) return 0;
00055a22 2464 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
4d158c36 2465 if (fIteration==2&&cl->IsUsed(11)) {
b9671574 2466 t.SetErrorY2(t.GetErrorY2()+0.03);
2467 t.SetErrorZ2(t.GetErrorZ2()+0.03);
2468 t.SetErrorY2(t.GetErrorY2()*3);
2469 t.SetErrorZ2(t.GetErrorZ2()*3);
4d158c36 2470 }
d26d9159 2471 /*
91162307 2472 if (t.fCurrentCluster->IsUsed(10)){
2473 //
2474 //
c9427e08 2475
91162307 2476 t.fNShared++;
2477 if (t.fNShared>0.7*t.GetNumberOfClusters()) {
2478 t.fRemoval =10;
2479 return 0;
2480 }
2481 }
d26d9159 2482 */
91162307 2483 if (accept<3) UpdateTrack(&t,accept);
c9427e08 2484
91162307 2485 } else {
b9671574 2486 if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
91162307 2487
2488 }
2489 return 1;
2490}
c9427e08 2491
1c53abe2 2492
91162307 2493
5d837844 2494//_________________________________________________________________________
829455ad 2495Bool_t AliTPCtracker::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
5d837844 2496{
2497 // Get track space point by index
2498 // return false in case the cluster doesn't exist
2499 AliTPCclusterMI *cl = GetClusterMI(index);
2500 if (!cl) return kFALSE;
2501 Int_t sector = (index&0xff000000)>>24;
0201b65c 2502 // Int_t row = (index&0x00ff0000)>>16;
5d837844 2503 Float_t xyz[3];
47af7ca4 2504 // xyz[0] = fkParam->GetPadRowRadii(sector,row);
0201b65c 2505 xyz[0] = cl->GetX();
5d837844 2506 xyz[1] = cl->GetY();
2507 xyz[2] = cl->GetZ();
2508 Float_t sin,cos;
47af7ca4 2509 fkParam->AdjustCosSin(sector,cos,sin);
5d837844 2510 Float_t x = cos*xyz[0]-sin*xyz[1];
2511 Float_t y = cos*xyz[1]+sin*xyz[0];
2512 Float_t cov[6];
2513 Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
47af7ca4 2514 if (sector < fkParam->GetNInnerSector()) sigmaY2 *= 2.07;
5d837844 2515 Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
47af7ca4 2516 if (sector < fkParam->GetNInnerSector()) sigmaZ2 *= 1.77;
5d837844 2517 cov[0] = sin*sin*sigmaY2;
2518 cov[1] = -sin*cos*sigmaY2;
2519 cov[2] = 0.;
2520 cov[3] = cos*cos*sigmaY2;
2521 cov[4] = 0.;
2522 cov[5] = sigmaZ2;
2523 p.SetXYZ(x,y,xyz[2],cov);
ae079791 2524 AliGeomManager::ELayerID iLayer;
5d837844 2525 Int_t idet;
47af7ca4 2526 if (sector < fkParam->GetNInnerSector()) {
ae079791 2527 iLayer = AliGeomManager::kTPC1;
5d837844 2528 idet = sector;
2529 }
2530 else {
ae079791 2531 iLayer = AliGeomManager::kTPC2;
47af7ca4 2532 idet = sector - fkParam->GetNInnerSector();
5d837844 2533 }
ae079791 2534 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
5d837844 2535 p.SetVolumeID(volid);
2536 return kTRUE;
2537}
2538
2539
2540
829455ad 2541Int_t AliTPCtracker::UpdateClusters(AliTPCseed& t, Int_t nr) {
1c53abe2 2542 //-----------------------------------------------------------------
2543 // This function tries to find a track prolongation to next pad row
2544 //-----------------------------------------------------------------
b9671574 2545 t.SetCurrentCluster(0);
f124f8bf 2546 t.SetCurrentClusterIndex1(-3);
1c53abe2 2547
2548 Double_t xt=t.GetX();
91162307 2549 Int_t row = GetRowNumber(xt)-1;
2550 Double_t ymax= GetMaxY(nr);
2551
1c53abe2 2552 if (row < nr) return 1; // don't prolongate if not information until now -
ca142b1f 2553// if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
2554// t.fRemoval =10;
2555// return 0; // not prolongate strongly inclined tracks
2556// }
2557// if (TMath::Abs(t.GetSnp())>0.95) {
2558// t.fRemoval =10;
2559// return 0; // not prolongate strongly inclined tracks
2560// }// patch 28 fev 06
91162307 2561
2562 Double_t x= GetXrow(nr);
2563 Double_t y,z;
2564 //t.PropagateTo(x+0.02);
2565 //t.PropagateTo(x+0.01);
1627d1c4 2566 if (!t.PropagateTo(x)){
1627d1c4 2567 return 0;
2568 }
1c53abe2 2569 //
91162307 2570 y=t.GetY();
2571 z=t.GetZ();
1c53abe2 2572
91162307 2573 if (TMath::Abs(y)>ymax){
2574 if (y > ymax) {
b9671574 2575 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
91162307 2576 if (!t.Rotate(fSectors->GetAlpha()))
2577 return 0;
2578 } else if (y <-ymax) {
b9671574 2579 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
91162307 2580 if (!t.Rotate(-fSectors->GetAlpha()))
2581 return 0;
2582 }
982aff31 2583 // if (!t.PropagateTo(x)){
2584 // return 0;
2585 //}
2586 return 1;
2587 //y = t.GetY();
1c53abe2 2588 }
91162307 2589 //
3f82c4f2 2590 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
a3232aae 2591
b9671574 2592 if (!IsActive(t.GetRelativeSector(),nr)) {
2593 t.SetInDead(kTRUE);
a3232aae 2594 t.SetClusterIndex2(nr,-1);
2595 return 0;
2596 }
2597 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
2598
bd26fa83 2599 AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1c53abe2 2600
b9671574 2601 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
2602 t.SetInDead(kTRUE);
91162307 2603 t.SetClusterIndex2(nr,-1);
1c53abe2 2604 return 0;
2605 }
2606 else
2607 {
76d56fd6 2608
2609 // if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
2610 if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
1627d1c4 2611 else
2612 return 0;
1c53abe2 2613 }
1c53abe2 2614
91162307 2615 // update current
42aec1f1 2616 if ( (nr%2==0) || t.GetNumberOfClusters()<2){
91162307 2617 // t.fCurrentSigmaY = GetSigmaY(&t);
2618 //t.fCurrentSigmaZ = GetSigmaZ(&t);
2619 GetShape(&t,nr);
2620 }
1c53abe2 2621
91162307 2622 AliTPCclusterMI *cl=0;
d184f295 2623 Int_t index=0;
91162307 2624 //
2625 Double_t roady = 1.;
2626 Double_t roadz = 1.;
2627 //
d26d9159 2628
2629 if (!cl){
2630 index = t.GetClusterIndex2(nr);
bad6eb00 2631 if ( (index >= 0) && (index&0x8000)==0){
b9671574 2632 cl = t.GetClusterPointer(nr);
bad6eb00 2633 if ( (cl==0) && (index >= 0)) cl = GetClusterMI(index);
b9671574 2634 t.SetCurrentClusterIndex1(index);
d26d9159 2635 if (cl) {
b9671574 2636 t.SetCurrentCluster(cl);
d26d9159 2637 return 1;
2638 }
2639 }
2640 }
2641
3d172d79 2642 // if (index<0) return 0;
2643 UInt_t uindex = TMath::Abs(index);
d184f295 2644
91162307 2645 if (krow) {
d184f295 2646 //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
2647 cl = krow.FindNearest2(y,z,roady,roadz,uindex);
91162307 2648 }
d26d9159 2649
b9671574 2650 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));
2651 t.SetCurrentCluster(cl);
d26d9159 2652
91162307 2653 return 1;
2654}
1c53abe2 2655
1c53abe2 2656
829455ad 2657Int_t AliTPCtracker::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
91162307 2658 //-----------------------------------------------------------------
2659 // This function tries to find a track prolongation to next pad row
2660 //-----------------------------------------------------------------
1c53abe2 2661
91162307 2662 //update error according neighborhoud
1c53abe2 2663
b9671574 2664 if (t.GetCurrentCluster()) {
2665 t.SetRow(nr);
00055a22 2666 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
91162307 2667
b9671574 2668 if (t.GetCurrentCluster()->IsUsed(10)){
91162307 2669 //
2670 //
2671 // t.fErrorZ2*=2;
2672 // t.fErrorY2*=2;
b9671574 2673 t.SetNShared(t.GetNShared()+1);
2674 if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
2675 t.SetRemoval(10);
91162307 2676 return 0;
2677 }
b364ca79 2678 }
d26d9159 2679 if (fIteration>0) accept = 0;
b364ca79 2680 if (accept<3) UpdateTrack(&t,accept);
2681
1c53abe2 2682 } else {
91162307 2683 if (fIteration==0){
f124f8bf 2684 if ( t.GetNumberOfClusters()>18 && ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)) t.SetRemoval(10);
2685 if ( t.GetNumberOfClusters()>18 && t.GetChi2()/t.GetNumberOfClusters()>6 ) t.SetRemoval(10);
91162307 2686
b9671574 2687 if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
1c53abe2 2688 }
2689 }
2690 return 1;
2691}
2692
2693
2694
91162307 2695//_____________________________________________________________________________
829455ad 2696Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step, Bool_t fromSeeds) {
1c53abe2 2697 //-----------------------------------------------------------------
91162307 2698 // This function tries to find a track prolongation.
1c53abe2 2699 //-----------------------------------------------------------------
2700 Double_t xt=t.GetX();
2701 //
f124f8bf 2702 Double_t alpha=t.GetAlpha();
1c53abe2 2703 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2704 if (alpha < 0. ) alpha += 2.*TMath::Pi();
91162307 2705 //
a3f36f42 2706 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1c53abe2 2707
f124f8bf 2708 Int_t first = GetRowNumber(xt);
2709 if (!fromSeeds)
2710 first -= step;
a3f36f42 2711 if (first < 0)
2712 first = 0;
51ad6848 2713 for (Int_t nr= first; nr>=rf; nr-=step) {
2714 // update kink info
2715 if (t.GetKinkIndexes()[0]>0){
2716 for (Int_t i=0;i<3;i++){
2717 Int_t index = t.GetKinkIndexes()[i];
2718 if (index==0) break;
2719 if (index<0) continue;
2720 //
6c94f330 2721 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
51ad6848 2722 if (!kink){
2723 printf("PROBLEM\n");
2724 }
2725 else{
eea478d3 2726 Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
51ad6848 2727 if (kinkrow==nr){
2728 AliExternalTrackParam paramd(t);
2729 kink->SetDaughter(paramd);
eea478d3 2730 kink->SetStatus(2,5);
51ad6848 2731 kink->Update();
51ad6848 2732 }
2733 }
2734 }
2735 }
2736
2737 if (nr==80) t.UpdateReference();
982aff31 2738 if (nr<fInnerSec->GetNRows())
2739 fSectors = fInnerSec;
2740 else
2741 fSectors = fOuterSec;
91162307 2742 if (FollowToNext(t,nr)==0)
4d158c36 2743 if (!t.IsActive())
2744 return 0;
91162307 2745
2746 }
2747 return 1;
2748}
2749
1c53abe2 2750
1c53abe2 2751
91162307 2752
2753
2754
829455ad 2755Int_t AliTPCtracker::FollowBackProlongation(AliTPCseed& t, Int_t rf, Bool_t fromSeeds) {
1c53abe2 2756 //-----------------------------------------------------------------
2757 // This function tries to find a track prolongation.
2758 //-----------------------------------------------------------------
1c53abe2 2759 //
eea478d3 2760 Double_t xt=t.GetX();
f124f8bf 2761 Double_t alpha=t.GetAlpha();
1c53abe2 2762 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2763 if (alpha < 0. ) alpha += 2.*TMath::Pi();
bad6eb00 2764 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1c53abe2 2765
b9671574 2766 Int_t first = t.GetFirstPoint();
f124f8bf 2767 Int_t ri = GetRowNumber(xt);
2768 if (!fromSeeds)
2769 ri += 1;
2770
2771 if (first<ri) first = ri;
91162307 2772 //
2773 if (first<0) first=0;
4d158c36 2774 for (Int_t nr=first; nr<=rf; nr++) {
ca142b1f 2775 // if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
51ad6848 2776 if (t.GetKinkIndexes()[0]<0){
2777 for (Int_t i=0;i<3;i++){
2778 Int_t index = t.GetKinkIndexes()[i];
2779 if (index==0) break;
2780 if (index>0) continue;
2781 index = TMath::Abs(index);
6c94f330 2782 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
51ad6848 2783 if (!kink){
2784 printf("PROBLEM\n");
2785 }
2786 else{
eea478d3 2787 Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
51ad6848 2788 if (kinkrow==nr){
2789 AliExternalTrackParam paramm(t);
2790 kink->SetMother(paramm);
eea478d3 2791 kink->SetStatus(2,1);
51ad6848 2792 kink->Update();
51ad6848 2793 }
2794 }
eea478d3 2795 }
51ad6848 2796 }
eea478d3 2797 //
d26d9159 2798 if (nr<fInnerSec->GetNRows())
2799 fSectors = fInnerSec;
2800 else
2801 fSectors = fOuterSec;
c274e255 2802
d26d9159 2803 FollowToNext(t,nr);
1c53abe2 2804 }
2805 return 1;
2806}
2807
2808
2809
2810
2811
829455ad 2812Float_t AliTPCtracker::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
1c53abe2 2813{
544c295f 2814 // overlapping factor
1c53abe2 2815 //
2816 sum1=0;
2817 sum2=0;
2818 Int_t sum=0;
1c53abe2 2819 //
2820 Float_t dz2 =(s1->GetZ() - s2->GetZ());
c9427e08 2821 dz2*=dz2;
91162307 2822
c9427e08 2823 Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
1c53abe2 2824 dy2*=dy2;
2825 Float_t distance = TMath::Sqrt(dz2+dy2);
c9427e08 2826 if (distance>4.) return 0; // if there are far away - not overlap - to reduce combinatorics
1c53abe2 2827
91162307 2828 // Int_t offset =0;
b9671574 2829 Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
2830 Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
c9427e08 2831 if (lastpoint>160)
2832 lastpoint =160;
2833 if (firstpoint<0)
2834 firstpoint = 0;
91162307 2835 if (firstpoint>lastpoint) {
2836 firstpoint =lastpoint;
2837 // lastpoint =160;
c9427e08 2838 }
2839
2840
91162307 2841 for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
2842 if (s1->GetClusterIndex2(i)>0) sum1++;
2843 if (s2->GetClusterIndex2(i)>0) sum2++;
2844 if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
1c53abe2 2845 sum++;
2846 }
2847 }
91162307 2848 if (sum<5) return 0;
2849
1627d1c4 2850 Float_t summin = TMath::Min(sum1+1,sum2+1);
2851 Float_t ratio = (sum+1)/Float_t(summin);
1c53abe2 2852 return ratio;
2853}
2854
829455ad 2855void AliTPCtracker::SignShared(AliTPCseed * s1, AliTPCseed * s2)
1c53abe2 2856{
544c295f 2857 // shared clusters
1c53abe2 2858 //
a0f4d6a6 2859 Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
2860 if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
2861 Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
2862 Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
91162307 2863
1c53abe2 2864 //
91162307 2865 Int_t sumshared=0;
2866 //
a0f4d6a6 2867 //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
2868 //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
2869 Int_t firstpoint = 0;
2870 Int_t lastpoint = 160;
91162307 2871 //
a0f4d6a6 2872 // if (firstpoint>=lastpoint-5) return;;
1af5da7e 2873
91162307 2874 for (Int_t i=firstpoint;i<lastpoint;i++){
2875 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2876 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2877 sumshared++;
2878 }
2879 }
a0f4d6a6 2880 if (sumshared>cutN0){
91162307 2881 // sign clusters
2882 //
2883 for (Int_t i=firstpoint;i<lastpoint;i++){
2884 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2885 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2886 AliTPCTrackerPoint *p1 = s1->GetTrackPoint(i);
2887 AliTPCTrackerPoint *p2 = s2->GetTrackPoint(i);;
2888 if (s1->IsActive()&&s2->IsActive()){
b9671574 2889 p1->SetShared(kTRUE);
2890 p2->SetShared(kTRUE);
91162307 2891 }
2892 }
2893 }
2894 }
2895 //
a0f4d6a6 2896 if (sumshared>cutN0){
91162307 2897 for (Int_t i=0;i<4;i++){
b9671574 2898 if (s1->GetOverlapLabel(3*i)==0){
2899 s1->SetOverlapLabel(3*i, s2->GetLabel());
2900 s1->SetOverlapLabel(3*i+1,sumshared);
2901 s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
91162307 2902 break;
2903 }
2904 }
2905 for (Int_t i=0;i<4;i++){
b9671574 2906 if (s2->GetOverlapLabel(3*i)==0){
2907 s2->SetOverlapLabel(3*i, s1->GetLabel());
2908 s2->SetOverlapLabel(3*i+1,sumshared);
2909 s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
91162307 2910 break;
2911 }
2912 }
2913 }
91162307 2914}
1c53abe2 2915
829455ad 2916void AliTPCtracker::SignShared(TObjArray * arr)
91162307 2917{
1c53abe2 2918 //
91162307 2919 //sort trackss according sectors
2920 //
c9427e08 2921 for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2922 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 2923 if (!pt) continue;
2924 //if (pt) RotateToLocal(pt);
b9671574 2925 pt->SetSort(0);
c9427e08 2926 }
91162307 2927 arr->UnSort();
6d493ea0 2928 arr->Sort(); // sorting according relative sectors
1c53abe2 2929 arr->Expand(arr->GetEntries());
91162307 2930 //
2931 //
1c53abe2 2932 Int_t nseed=arr->GetEntriesFast();
1c53abe2 2933 for (Int_t i=0; i<nseed; i++) {
2934 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 2935 if (!pt) continue;
ec26e231 2936 for (Int_t j=0;j<12;j++){
b9671574 2937 pt->SetOverlapLabel(j,0);
1c53abe2 2938 }
91162307 2939 }
2940 for (Int_t i=0; i<nseed; i++) {
2941 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2942 if (!pt) continue;
b9671574 2943 if (pt->GetRemoval()>10) continue;
1c53abe2 2944 for (Int_t j=i+1; j<nseed; j++){
2945 AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
1af5da7e 2946 if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
91162307 2947 // if (pt2){
b9671574 2948 if (pt2->GetRemoval()<=10) {
6d493ea0 2949 //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
91162307 2950 SignShared(pt,pt2);
c9427e08 2951 }
91162307 2952 }
2953 }
2954}
2955
91162307 2956
829455ad 2957void AliTPCtracker::SortTracks(TObjArray * arr, Int_t mode) const
91162307 2958{
2959 //
2960 //sort tracks in array according mode criteria
2961 Int_t nseed = arr->GetEntriesFast();
2962 for (Int_t i=0; i<nseed; i++) {
2963 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2964 if (!pt) {
2965 continue;
2966 }
b9671574 2967 pt->SetSort(mode);
91162307 2968 }
2969 arr->UnSort();
2970 arr->Sort();
1c53abe2 2971}
c9427e08 2972
51ad6848 2973
829455ad 2974void AliTPCtracker::RemoveUsed2(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t minimal)
51ad6848 2975{
51ad6848 2976 //
6d493ea0 2977 // Loop over all tracks and remove overlaped tracks (with lower quality)
2978 // Algorithm:
2979 // 1. Unsign clusters
2980 // 2. Sort tracks according quality
2981 // Quality is defined by the number of cluster between first and last points
2982 //
2983 // 3. Loop over tracks - decreasing quality order
2984 // a.) remove - If the fraction of shared cluster less than factor (1- n or 2)
2985 // b.) remove - If the minimal number of clusters less than minimal and not ITS
2986 // c.) if track accepted - sign clusters
51ad6848 2987 //
829455ad 2988 //Called in - AliTPCtracker::Clusters2Tracks()
2989 // - AliTPCtracker::PropagateBack()
2990 // - AliTPCtracker::RefitInward()
6d493ea0 2991 //
be34cb88 2992 // Arguments:
2993 // factor1 - factor for constrained
2994 // factor2 - for non constrained tracks
2995 // if (Float_t(shared+1)/Float_t(found+1)>factor) - DELETE
2996 //
51ad6848 2997 UnsignClusters();
2998 //
2999 Int_t nseed = arr->GetEntriesFast();
3000 Float_t * quality = new Float_t[nseed];
3001 Int_t * indexes = new Int_t[nseed];
3002 Int_t good =0;
3003 //
3004 //
3005 for (Int_t i=0; i<nseed; i++) {
3006 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3007 if (!pt){
3008 quality[i]=-1;
3009 continue;
3010 }
3011 pt->UpdatePoints(); //select first last max dens points
3012 Float_t * points = pt->GetPoints();
3013 if (points[3]<0.8) quality[i] =-1;
51ad6848 3014 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
6d493ea0 3015 //prefer high momenta tracks if overlaps
3016 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
51ad6848 3017 }
3018 TMath::Sort(nseed,quality,indexes);
3019 //
3020 //
3021 for (Int_t itrack=0; itrack<nseed; itrack++) {
3022 Int_t trackindex = indexes[itrack];
6d493ea0 3023 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);
3024 if (!pt) continue;
3025 //
51ad6848 3026 if (quality[trackindex]<0){
ddfbc51a 3027 MarkSeedFree( arr->RemoveAt(trackindex) );
f06a1ff6 3028 continue;
51ad6848 3029 }
3030 //
6d493ea0 3031 //
51ad6848 3032 Int_t first = Int_t(pt->GetPoints()[0]);
3033 Int_t last = Int_t(pt->GetPoints()[2]);
b9671574 3034 Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
51ad6848 3035 //
3036 Int_t found,foundable,shared;
6d493ea0 3037 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
3038 // pt->GetClusterStatistic(0,160, found, foundable,shared,kFALSE);
b406fdb0 3039 Bool_t itsgold =kFALSE;
b9671574 3040 if (pt->GetESD()){
ef7253ac 3041 Int_t dummy[12];
b9671574 3042 if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
51ad6848 3043 }
b406fdb0 3044 if (!itsgold){
3045 //
3046 if (Float_t(shared+1)/Float_t(found+1)>factor){
3047 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
65e67c9c 3048 if( (AliTPCReconstructor::StreamLevel()&kStreamRemoveUsed)>0){ // flag:stream information about TPC tracks which were descarded (double track removal)
be34cb88 3049 TTreeSRedirector &cstream = *fDebugStreamer;
3050 cstream<<"RemoveUsed"<<
3051 "iter="<<fIteration<<
3052 "pt.="<<pt<<
3053 "\n";
3054 }
ddfbc51a 3055 MarkSeedFree( arr->RemoveAt(trackindex) );
b406fdb0 3056 continue;
3057 }
3058 if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){ //remove short tracks
3059 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
65e67c9c 3060 if( (AliTPCReconstructor::StreamLevel()&kStreamRemoveShort)>0){ // flag:stream information about TPC tracks which were discarded (short track removal)
be34cb88 3061 TTreeSRedirector &cstream = *fDebugStreamer;
3062 cstream<<"RemoveShort"<<
3063 "iter="<<fIteration<<
3064 "pt.="<<pt<<
3065 "\n";
3066 }
ddfbc51a 3067 MarkSeedFree( arr->RemoveAt(trackindex) );
b406fdb0 3068 continue;
3069 }
51ad6848 3070 }
3071
3072 good++;
6d493ea0 3073 //if (sharedfactor>0.4) continue;
b406fdb0 3074 if (pt->GetKinkIndexes()[0]>0) continue;
6d493ea0 3075 //Remove tracks with undefined properties - seems
3076 if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ?
3077 //
51ad6848 3078 for (Int_t i=first; i<last; i++) {
3079 Int_t index=pt->GetClusterIndex2(i);
3080 // if (index<0 || index&0x8000 ) continue;
3081 if (index<0 || index&0x8000 ) continue;
b9671574 3082 AliTPCclusterMI *c= pt->GetClusterPointer(i);
51ad6848 3083 if (!c) continue;
3084 c->Use(10);
3085 }
3086 }
3087 fNtracks = good;
3088 if (fDebug>0){
3089 Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
3090 }
3091 delete []quality;
3092 delete []indexes;
3093}
3094
829455ad 3095void AliTPCtracker::DumpClusters(Int_t iter, TObjArray *trackArray)
f47588e0 3096{
3097 //
3098 // Dump clusters after reco
3099 // signed and unsigned cluster can be visualized
3100 // 1. Unsign all cluster
3101 // 2. Sign all used clusters
3102 // 3. Dump clusters
3103 UnsignClusters();
3104 Int_t nseed = trackArray->GetEntries();
3105 for (Int_t i=0; i<nseed; i++){
3106 AliTPCseed *pt=(AliTPCseed*)trackArray->UncheckedAt(i);
3107 if (!pt) {
3108 continue;
3109 }
3110 Bool_t isKink=pt->GetKinkIndex(0)!=0;
3111 for (Int_t j=0; j<160; ++j) {
3112 Int_t index=pt->GetClusterIndex2(j);
3113 if (index<0) continue;
3114 AliTPCclusterMI *c= pt->GetClusterPointer(j);
3115 if (!c) continue;
3116 if (isKink) c->Use(100); // kink
3117 c->Use(10); // by default usage 10
3118 }
3119 }
3120 //
3121
3122 for (Int_t sec=0;sec<fkNIS;sec++){
3123 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
bfa00fba 3124 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
f47588e0 3125 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++){
bfa00fba 3126 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
3127 Float_t gx[3]; cl->GetGlobalXYZ(gx);
f47588e0 3128 (*fDebugStreamer)<<"clDump"<<
3129 "iter="<<iter<<
bfa00fba 3130 "cl.="<<cl<<
f47588e0 3131 "gx0="<<gx[0]<<
3132 "gx1="<<gx[1]<<
3133 "gx2="<<gx[2]<<
3134 "\n";
3135 }
bfa00fba 3136 cla = fInnerSec[sec][row].GetClusters2();
f47588e0 3137 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++){
bfa00fba 3138 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
3139 Float_t gx[3]; cl->GetGlobalXYZ(gx);
f47588e0 3140 (*fDebugStreamer)<<"clDump"<<
3141 "iter="<<iter<<
bfa00fba 3142 "cl.="<<cl<<
f47588e0 3143 "gx0="<<gx[0]<<
3144 "gx1="<<gx[1]<<
3145 "gx2="<<gx[2]<<
3146 "\n";
3147 }
3148 }
3149 }
3150
3151 for (Int_t sec=0;sec<fkNOS;sec++){
3152 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
bfa00fba 3153 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
f47588e0 3154 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++){
bfa00fba 3155 Float_t gx[3];
3156 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
3157 cl->GetGlobalXYZ(gx);
f47588e0 3158 (*fDebugStreamer)<<"clDump"<<
3159 "iter="<<iter<<
bfa00fba 3160 "cl.="<<cl<<
f47588e0 3161 "gx0="<<gx[0]<<
3162 "gx1="<<gx[1]<<
3163 "gx2="<<gx[2]<<
3164 "\n";
3165 }
bfa00fba 3166 cla = fOuterSec[sec][row].GetClusters2();
f47588e0 3167 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++){
bfa00fba 3168 Float_t gx[3];
3169 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
3170 cl->GetGlobalXYZ(gx);
f47588e0 3171 (*fDebugStreamer)<<"clDump"<<
3172 "iter="<<iter<<
bfa00fba 3173 "cl.="<<cl<<
f47588e0 3174 "gx0="<<gx[0]<<
3175 "gx1="<<gx[1]<<
3176 "gx2="<<gx[2]<<
3177 "\n";
3178 }
3179 }
3180 }
3181
3182}
829455ad 3183void AliTPCtracker::UnsignClusters()
1c53abe2 3184{
91162307 3185 //
3186 // loop over all clusters and unsign them
3187 //
3188
3189 for (Int_t sec=0;sec<fkNIS;sec++){
3190 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
bfa00fba 3191 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
b9671574 3192 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
91162307 3193 // if (cl[icl].IsUsed(10))
bfa00fba 3194 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
3195 cla = fInnerSec[sec][row].GetClusters2();
b9671574 3196 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
91162307 3197 //if (cl[icl].IsUsed(10))
bfa00fba 3198 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
91162307 3199 }
3200 }
3201
3202 for (Int_t sec=0;sec<fkNOS;sec++){
3203 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
bfa00fba 3204 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
b9671574 3205 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
91162307 3206 //if (cl[icl].IsUsed(10))
bfa00fba 3207 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
3208 cla = fOuterSec[sec][row].GetClusters2();
b9671574 3209 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
91162307 3210 //if (cl[icl].IsUsed(10))
bfa00fba 3211 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
91162307 3212 }
3213 }
3214
1c53abe2 3215}
3216
91162307 3217
3218
829455ad 3219void AliTPCtracker::SignClusters(const TObjArray * arr, Float_t fnumber, Float_t fdensity)
1c53abe2 3220{
3221 //
91162307 3222 //sign clusters to be "used"
3223 //
3224 // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
3225 // loop over "primaries"
3226
3227 Float_t sumdens=0;
3228 Float_t sumdens2=0;
3229 Float_t sumn =0;
3230 Float_t sumn2 =0;
3231 Float_t sumchi =0;
3232 Float_t sumchi2 =0;
3233
3234 Float_t sum =0;
3235
1c53abe2 3236 TStopwatch timer;
91162307 3237 timer.Start();
1c53abe2 3238
91162307 3239 Int_t nseed = arr->GetEntriesFast();
3240 for (Int_t i=0; i<nseed; i++) {
3241 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3242 if (!pt) {
3243 continue;
3244 }
3245 if (!(pt->IsActive())) continue;
b9671574 3246 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
91162307 3247 if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
3248 sumdens += dens;
3249 sumdens2+= dens*dens;
3250 sumn += pt->GetNumberOfClusters();
3251 sumn2 += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
3252 Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
3253 if (chi2>5) chi2=5;
3254 sumchi +=chi2;
3255 sumchi2 +=chi2*chi2;
3256 sum++;
3257 }
1627d1c4 3258 }
91162307 3259
3260 Float_t mdensity = 0.9;
3261 Float_t meann = 130;
3262 Float_t meanchi = 1;
3263 Float_t sdensity = 0.1;
3264 Float_t smeann = 10;
3265 Float_t smeanchi =0.4;
1627d1c4 3266
91162307 3267
3268 if (sum>20){
3269 mdensity = sumdens/sum;
3270 meann = sumn/sum;
3271 meanchi = sumchi/sum;
3272 //
3273 sdensity = sumdens2/sum-mdensity*mdensity;
c1ea348f 3274 if (sdensity >= 0)
3275 sdensity = TMath::Sqrt(sdensity);
3276 else
3277 sdensity = 0.1;
91162307 3278 //
3279 smeann = sumn2/sum-meann*meann;
c1ea348f 3280 if (smeann >= 0)
3281 smeann = TMath::Sqrt(smeann);
3282 else
3283 smeann = 10;
91162307 3284 //
3285 smeanchi = sumchi2/sum - meanchi*meanchi;
c1ea348f 3286 if (smeanchi >= 0)
3287 smeanchi = TMath::Sqrt(smeanchi);
3288 else
3289 smeanchi = 0.4;
91162307 3290 }
3291
3292
3293 //REMOVE SHORT DELTAS or tracks going out of sensitive volume of TPC
3294 //
3295 for (Int_t i=0; i<nseed; i++) {
3296 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3297 if (!pt) {
3298 continue;
1c53abe2 3299 }
b9671574 3300 if (pt->GetBSigned()) continue;
3301 if (pt->GetBConstrain()) continue;
91162307 3302 //if (!(pt->IsActive())) continue;
3303 /*
3304 Int_t found,foundable,shared;
3305 pt->GetClusterStatistic(0,160,found, foundable,shared);
3306 if (shared/float(found)>0.3) {
3307 if (shared/float(found)>0.9 ){
ddfbc51a 3308 //MarkSeedFree( arr->RemoveAt(i) );
91162307 3309 }
3310 continue;
c9427e08 3311 }
91162307 3312 */
3313 Bool_t isok =kFALSE;
b9671574 3314 if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
91162307 3315 isok = kTRUE;
b9671574 3316 if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
91162307 3317 isok =kTRUE;
3318 if (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
3319 isok =kTRUE;
3320 if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
3321 isok =kTRUE;
3322
3323 if (isok)
77f88633 3324 for (Int_t j=0; j<160; ++j) {
3325 Int_t index=pt->GetClusterIndex2(j);
91162307 3326 if (index<0) continue;
77f88633 3327 AliTPCclusterMI *c= pt->GetClusterPointer(j);
91162307 3328 if (!c) continue;
3329 //if (!(c->IsUsed(10))) c->Use();
3330 c->Use(10);
3331 }
3332 }
3333
c9427e08 3334
1c53abe2 3335 //
91162307 3336 Double_t maxchi = meanchi+2.*smeanchi;
3337
3338 for (Int_t i=0; i<nseed; i++) {
3339 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3340 if (!pt) {
1c53abe2 3341 continue;
91162307 3342 }
3343 //if (!(pt->IsActive())) continue;
b9671574 3344 if (pt->GetBSigned()) continue;
91162307 3345 Double_t chi = pt->GetChi2()/pt->GetNumberOfClusters();
3346 if (chi>maxchi) continue;
3347
3348 Float_t bfactor=1;
b9671574 3349 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
91162307 3350
3351 //sign only tracks with enoug big density at the beginning
3352
3353 if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue;
3354
3355
3e5d0aa2 3356 Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
91162307 3357 Double_t minn = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
3358
3359 // if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
b9671574 3360 if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
91162307 3361 minn=0;
3362
3363 if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
3364 //Int_t noc=pt->GetNumberOfClusters();
b9671574 3365 pt->SetBSigned(kTRUE);
77f88633 3366 for (Int_t j=0; j<160; ++j) {
91162307 3367
77f88633 3368 Int_t index=pt->GetClusterIndex2(j);
91162307 3369 if (index<0) continue;
77f88633 3370 AliTPCclusterMI *c= pt->GetClusterPointer(j);
91162307 3371 if (!c) continue;
3372 // if (!(c->IsUsed(10))) c->Use();
3373 c->Use(10);
3374 }
1c53abe2 3375 }
91162307 3376 }
3377 // gLastCheck = nseed;
3378 // arr->Compress();
3379 if (fDebug>0){
3380 timer.Print();
3381 }
1c53abe2 3382}
3383
3384
1c53abe2 3385
829455ad 3386Int_t AliTPCtracker::RefitInward(AliESDEvent *event)
d26d9159 3387{
3388 //
3389 // back propagation of ESD tracks
3390 //
3391 //return 0;
ec26e231 3392 if (!event) return 0;
6d493ea0 3393 const Int_t kMaxFriendTracks=2000;
d26d9159 3394 fEvent = event;
72e25240 3395 fEventHLT = 0;
6d64657a 3396 // extract correction object for multiplicity dependence of dEdx
3397 TObjArray * gainCalibArray = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(event->GetRunNumber());
23728788 3398
3399 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
3400 if (!transform) {
3401 AliFatal("Tranformations not in RefitInward");
3402 return 0;
3403 }
3404 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
6d64657a 3405 const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
012c4694 3406 Int_t nContribut = event->GetNumberOfTracks();
6d64657a 3407 TGraphErrors * graphMultDependenceDeDx = 0x0;
23728788 3408 if (recoParam && recoParam->GetUseMultiplicityCorrectionDedx() && gainCalibArray) {
6d64657a 3409 if (recoParam->GetUseTotCharge()) {
3410 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
3411 } else {
3412 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
3413 }
3414 }
3415 //
d26d9159 3416 ReadSeeds(event,2);
3417 fIteration=2;
982aff31 3418 //PrepareForProlongation(fSeeds,1);
3419 PropagateForward2(fSeeds);
6d493ea0 3420 RemoveUsed2(fSeeds,0.4,0.4,20);
1af5da7e 3421
bda5ad6d 3422 Int_t entriesSeed=fSeeds->GetEntries();
3423 TObjArray arraySeed(entriesSeed);
3424 for (Int_t i=0;i<entriesSeed;i++) {
a0f4d6a6 3425 arraySeed.AddAt(fSeeds->At(i),i);
3426 }
3427 SignShared(&arraySeed);
6d493ea0 3428 // FindCurling(fSeeds, event,2); // find multi found tracks
1af5da7e 3429 FindSplitted(fSeeds, event,2); // find multi found tracks
65e67c9c 3430 if ((AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC)>0) FindMultiMC(fSeeds, fEvent,2); // flag: stream MC infomation about the multiple find track (ONLY for MC data)
af32720d 3431
4d158c36 3432 Int_t ntracks=0;
d26d9159 3433 Int_t nseed = fSeeds->GetEntriesFast();
3434 for (Int_t i=0;i<nseed;i++){
3435 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
4d158c36 3436 if (!seed) continue;
eea478d3 3437 if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
be34cb88 3438 AliESDtrack *esd=event->GetTrack(i);
3439
3440 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
3441 AliExternalTrackParam paramIn;
3442 AliExternalTrackParam paramOut;
3443 Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
65e67c9c 3444 if ((AliTPCReconstructor::StreamLevel() & kStreamRecoverIn)>0) { // flag: stream track information for track failing in RefitInward function and recovered back
3445 (*fDebugStreamer)<<"RecoverIn"<<
0e90d29a 3446 "seed.="<<seed<<
3447 "esd.="<<esd<<
3448 "pin.="<<&paramIn<<
3449 "pout.="<<&paramOut<<
3450 "ncl="<<ncl<<
3451 "\n";
3452 }
be34cb88 3453 if (ncl>15) {
3454 seed->Set(paramIn.GetX(),paramIn.GetAlpha(),paramIn.GetParameter(),paramIn.GetCovariance());
3455 seed->SetNumberOfClusters(ncl);
3456 }
3457 }
eea478d3 3458
47af7ca4 3459 seed->PropagateTo(fkParam->GetInnerRadiusLow());
51ad6848 3460 seed->UpdatePoints();
92f513f5 3461 AddCovariance(seed);
bad6eb00 3462 MakeESDBitmaps(seed, esd);
d26d9159 3463 seed->CookdEdx(0.02,0.6);
3464 CookLabel(seed,0.1); //For comparison only
af32720d 3465 //
65e67c9c 3466 if (((AliTPCReconstructor::StreamLevel()&kStreamRefitInward)>0) && seed!=0) {
af32720d 3467 TTreeSRedirector &cstream = *fDebugStreamer;
65e67c9c 3468 cstream<<"RefitInward"<< // flag: stream track information in RefitInward function (after tracking Iteration 2)
af32720d 3469 "Esd.="<<esd<<
3470 "Track.="<<seed<<
3471 "\n";
3472 }
c274e255 3473
51ad6848 3474 if (seed->GetNumberOfClusters()>15){
4d158c36 3475 esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
51ad6848 3476 esd->SetTPCPoints(seed->GetPoints());
b9671574 3477 esd->SetTPCPointsF(seed->GetNFoundable());
83afd539 3478 Int_t ndedx = seed->GetNCDEDX(0);
3479 Float_t sdedx = seed->GetSDEDX(0);
b406fdb0 3480 Float_t dedx = seed->GetdEdx();
6d64657a 3481 // apply mutliplicity dependent dEdx correction if available
3482 if (graphMultDependenceDeDx) {
6d64657a 3483 Double_t corrGain = AliTPCcalibDButil::EvalGraphConst(graphMultDependenceDeDx, nContribut);
012c4694 3484 dedx += (1 - corrGain)*50.; // MIP is normalized to 50
6d64657a 3485 }
b406fdb0 3486 esd->SetTPCsignal(dedx, sdedx, ndedx);
fdedfdec 3487 //
64bf5ca0 3488 // fill new dEdx information
3489 //
3490 Double32_t signal[4];
dee67df8 3491 Double32_t signalMax[4];
64bf5ca0 3492 Char_t ncl[3];
3493 Char_t nrows[3];
3494 //
3495 for(Int_t iarr=0;iarr<3;iarr++) {
fb57da8a 3496 signal[iarr] = seed->GetDEDXregion(iarr+1);
dee67df8 3497 signalMax[iarr] = seed->GetDEDXregion(iarr+5);
fb57da8a 3498 ncl[iarr] = seed->GetNCDEDX(iarr+1);
3499 nrows[iarr] = seed->GetNCDEDXInclThres(iarr+1);
64bf5ca0 3500 }
3501 signal[3] = seed->GetDEDXregion(4);
dee67df8 3502 signalMax[3] = seed->GetDEDXregion(8);
3503
64bf5ca0 3504 //
ddfbc51a 3505 AliTPCdEdxInfo * infoTpcPid = new AliTPCdEdxInfo();
64bf5ca0 3506 infoTpcPid->SetTPCSignalRegionInfo(signal, ncl, nrows);
dee67df8 3507 infoTpcPid->SetTPCSignalsQmax(signalMax);
64bf5ca0 3508 esd->SetTPCdEdxInfo(infoTpcPid);
3509 //
fdedfdec 3510 // add seed to the esd track in Calib level
3511 //
6d493ea0 3512 Bool_t storeFriend = gRandom->Rndm()<(kMaxFriendTracks)/Float_t(nseed);
ddfbc51a 3513 if (AliTPCReconstructor::StreamLevel()>0 &&storeFriend){
3514 // RS: this is the only place where the seed is created not in the pool,
3515 // since it should belong to ESDevent
3516 AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE);
fdedfdec 3517 esd->AddCalibObject(seedCopy);
3518 }
4d158c36 3519 ntracks++;
d26d9159 3520 }
3521 else{
3522 //printf("problem\n");
3523 }
3524 }
51ad6848 3525 //FindKinks(fSeeds,event);
65e67c9c 3526 if ((AliTPCReconstructor::StreamLevel()&kStreamClDump)>0) DumpClusters(2,fSeeds); // dump clusters at the end of process (signed with useage flags)
4d158c36 3527 Info("RefitInward","Number of refitted tracks %d",ntracks);
3aa6a136 3528
3529 AliCosmicTracker::FindCosmic(event, kTRUE);
3530
5576d489 3531 FillClusterOccupancyInfo();
3532
d26d9159 3533 return 0;
3534}
3535
1c53abe2 3536
829455ad 3537Int_t AliTPCtracker::PropagateBack(AliESDEvent *event)
91162307 3538{
3539 //
3540 // back propagation of ESD tracks
3541 //
ec26e231 3542 if (!event) return 0;
91162307 3543 fEvent = event;
72e25240 3544 fEventHLT = 0;
d26d9159 3545 fIteration = 1;
5d837844 3546 ReadSeeds(event,1);
b406fdb0 3547 PropagateBack(fSeeds);
3548 RemoveUsed2(fSeeds,0.4,0.4,20);
6d493ea0 3549 //FindCurling(fSeeds, fEvent,1);
1af5da7e 3550 FindSplitted(fSeeds, event,1); // find multi found tracks
65e67c9c 3551 if ((AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC)>0) FindMultiMC(fSeeds, fEvent,1); // find multi found tracks
1af5da7e 3552
b406fdb0 3553 //
91162307 3554 Int_t nseed = fSeeds->GetEntriesFast();
4d158c36 3555 Int_t ntracks=0;
91162307 3556 for (Int_t i=0;i<nseed;i++){
3557 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
d9e62e7e 3558 if (!seed) continue;
51ad6848 3559 if (seed->GetKinkIndex(0)<0) UpdateKinkQualityM(seed); // update quality informations for kinks
3560 seed->UpdatePoints();
92f513f5 3561 AddCovariance(seed);
91162307 3562 AliESDtrack *esd=event->GetTrack(i);
e1dadcd0 3563 if (!esd) continue; //never happen
be34cb88 3564 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
3565 AliExternalTrackParam paramIn;
3566 AliExternalTrackParam paramOut;
3567 Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
65e67c9c 3568 if ((AliTPCReconstructor::StreamLevel()&kStreamRecoverBack)>0) { // flag: stream track information for track faling PropagateBack function and recovered back (RefitTrack)
ca449e98 3569 (*fDebugStreamer)<<"RecoverBack"<<
3570 "seed.="<<seed<<
3571 "esd.="<<esd<<
3572 "pin.="<<&paramIn<<
3573 "pout.="<<&paramOut<<
3574 "ncl="<<ncl<<
3575 "\n";
3576 }
be34cb88 3577 if (ncl>15) {
3578 seed->Set(paramOut.GetX(),paramOut.GetAlpha(),paramOut.GetParameter(),paramOut.GetCovariance());
3579 seed->SetNumberOfClusters(ncl);
3580 }
3581 }
d26d9159 3582 seed->CookdEdx(0.02,0.6);
91162307 3583 CookLabel(seed,0.1); //For comparison only
51ad6848 3584 if (seed->GetNumberOfClusters()>15){
4d158c36 3585 esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
51ad6848 3586 esd->SetTPCPoints(seed->GetPoints());
b9671574 3587 esd->SetTPCPointsF(seed->GetNFoundable());
83afd539 3588 Int_t ndedx = seed->GetNCDEDX(0);
3589 Float_t sdedx = seed->GetSDEDX(0);
167c41ab 3590 Float_t dedx = seed->GetdEdx();
3591 esd->SetTPCsignal(dedx, sdedx, ndedx);
4d158c36 3592 ntracks++;
31fd97b2 3593 Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
3594 // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
65e67c9c 3595 if (((AliTPCReconstructor::StreamLevel()&kStreamCPropagateBack)>0) && esd) {
3596 (*fDebugStreamer)<<"PropagateBack"<< // flag: stream track information in PropagateBack function (after tracking Iteration 1)
6d493ea0 3597 "Tr0.="<<seed<<
8cecaa87 3598 "esd.="<<esd<<
6d493ea0 3599 "EventNrInFile="<<eventnumber<<
8cecaa87 3600 "\n";
6d493ea0 3601 }
4d158c36 3602 }
91162307 3603 }
65e67c9c 3604 if (AliTPCReconstructor::StreamLevel()&kStreamClDump) DumpClusters(1,fSeeds); // flag:stream clusters at the end of process (signed with usage flag)
51ad6848 3605 //FindKinks(fSeeds,event);
4d158c36 3606 Info("PropagateBack","Number of back propagated tracks %d",ntracks);
91162307 3607 fEvent =0;
72e25240 3608 fEventHLT = 0;
3609
91162307 3610 return 0;
3611}
3612
3613
829455ad 3614Int_t AliTPCtracker::PostProcess(AliESDEvent *event)
ec7e4ad6 3615{
3616 //
3617 // Post process events
3618 //
3619 if (!event) return 0;
3620
3621 //
3622 // Set TPC event status
3623 //
3624
3625 // event affected by HV dip
3626 // reset TPC status
3627 if(IsTPCHVDipEvent(event)) {
3628 event->ResetDetectorStatus(AliDAQ::kTPC);
3629 }
3630
3631 //printf("Status %d \n", event->IsDetectorOn(AliDAQ::kTPC));
3632
3633 return 0;
3634}
3635
3636
829455ad 3637 void AliTPCtracker::DeleteSeeds()
91162307 3638{
b67e07dc 3639 //
f06a1ff6 3640 fSeeds->Clear();
ddfbc51a 3641 ResetSeedsPool();
91162307 3642 delete fSeeds;
3643 fSeeds =0;
3644}
3645
829455ad 3646void AliTPCtracker::ReadSeeds(const AliESDEvent *const event, Int_t direction)
91162307 3647{
3648 //
3649 //read seeds from the event
3650
3651 Int_t nentr=event->GetNumberOfTracks();
6bdc18d6 3652 if (fDebug>0){
3653 Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
3654 }
91162307 3655 if (fSeeds)
3656 DeleteSeeds();
3657 if (!fSeeds){
4d158c36 3658 fSeeds = new TObjArray(nentr);
91162307 3659 }
4d158c36 3660 UnsignClusters();
3661 // Int_t ntrk=0;
91162307 3662 for (Int_t i=0; i<nentr; i++) {
3663 AliESDtrack *esd=event->GetTrack(i);
51ad6848 3664 ULong_t status=esd->GetStatus();
3665 if (!(status&AliESDtrack::kTPCin)) continue;
1af5da7e 3666 AliTPCtrack t(*esd);
5d837844 3667 t.SetNumberOfClusters(0);
eea478d3 3668 // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
ddfbc51a 3669 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(t/*,t.GetAlpha()*/);
3670 seed->SetPoolID(fLastSeedID);
a0f4d6a6 3671 seed->SetUniqueID(esd->GetID());
92f513f5 3672 AddCovariance(seed); //add systematic ucertainty
eea478d3 3673 for (Int_t ikink=0;ikink<3;ikink++) {
3674 Int_t index = esd->GetKinkIndex(ikink);
3675 seed->GetKinkIndexes()[ikink] = index;
3676 if (index==0) continue;
3677 index = TMath::Abs(index);
3678 AliESDkink * kink = fEvent->GetKink(index-1);
3679 if (kink&&esd->GetKinkIndex(ikink)<0){
3680 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
3681 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,0);
3682 }
3683 if (kink&&esd->GetKinkIndex(ikink)>0){
3684 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
3685 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,4);
3686 }
3687
3688 }
6c94f330 3689 if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.);
2c4acef0 3690 //RS if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
6c94f330 3691 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
be34cb88 3692 //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
3693 // fSeeds->AddAt(0,i);
ddfbc51a 3694 // MarkSeedFree( seed );
be34cb88 3695 // continue;
3696 //}
a3986da2 3697
91162307 3698 //
3699 //
3700 // rotate to the local coordinate system
eea478d3 3701 //
3702 fSectors=fInnerSec; fN=fkNIS;
f124f8bf 3703 Double_t alpha=seed->GetAlpha();
91162307 3704 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
3705 if (alpha < 0. ) alpha += 2.*TMath::Pi();
a3f36f42 3706 Int_t ns=Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
91162307 3707 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
f124f8bf 3708 alpha-=seed->GetAlpha();
4d158c36 3709 if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
3710 if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
f124f8bf 3711 if (TMath::Abs(alpha) > 0.001) { // This should not happen normally
3712 AliWarning(Form("Rotating track over %f",alpha));
3713 if (!seed->Rotate(alpha)) {
ddfbc51a 3714 MarkSeedFree( seed );
f124f8bf 3715 continue;
3716 }
d9b8978b 3717 }
b9671574 3718 seed->SetESD(esd);
4d158c36 3719 // sign clusters
b406fdb0 3720 if (esd->GetKinkIndex(0)<=0){
3721 for (Int_t irow=0;irow<160;irow++){
3722 Int_t index = seed->GetClusterIndex2(irow);
bad6eb00 3723 if (index >= 0){
b406fdb0 3724 //
3725 AliTPCclusterMI * cl = GetClusterMI(index);
b9671574 3726 seed->SetClusterPointer(irow,cl);
b406fdb0 3727 if (cl){
3728 if ((index & 0x8000)==0){
3729 cl->Use(10); // accepted cluster
3730 }else{
3731 cl->Use(6); // close cluster not accepted
3732 }
4d158c36 3733 }else{
b406fdb0 3734 Info("ReadSeeds","Not found cluster");
3735 }
4d158c36 3736 }
3737 }
3738 }
3739 fSeeds->AddAt(seed,i);
91162307 3740 }
3741}
3742
3743
3744
3745//_____________________________________________________________________________
829455ad 3746void AliTPCtracker::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
91162307 3747 Float_t deltay, Int_t ddsec) {
3748 //-----------------------------------------------------------------
3749 // This function creates track seeds.
3750 // SEEDING WITH VERTEX CONSTRAIN
3751 //-----------------------------------------------------------------
3752 // cuts[0] - fP4 cut
3753 // cuts[1] - tan(phi) cut
3754 // cuts[2] - zvertex cut
3755 // cuts[3] - fP3 cut
3756 Int_t nin0 = 0;
3757 Int_t nin1 = 0;
3758 Int_t nin2 = 0;
3759 Int_t nin = 0;
3760 Int_t nout1 = 0;
3761 Int_t nout2 = 0;
3762
3763 Double_t x[5], c[15];
3764 // Int_t di = i1-i2;
3765 //
ddfbc51a 3766 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed();
3767 seed->SetPoolID(fLastSeedID);
91162307 3768 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
3769 Double_t cs=cos(alpha), sn=sin(alpha);
d757548f 3770 //
3771 // Double_t x1 =fOuterSec->GetX(i1);
3772 //Double_t xx2=fOuterSec->GetX(i2);
3773
91162307 3774 Double_t x1 =GetXrow(i1);
3775 Double_t xx2=GetXrow(i2);
3776
3777 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
3778
3779 Int_t imiddle = (i2+i1)/2; //middle pad row index
3780 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
bd26fa83 3781 const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
91162307 3782 //
3783 Int_t ns =sec;
3784
bd26fa83 3785 const AliTPCtrackerRow& kr1=GetRow(ns,i1);
b9671574 3786 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
3787 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
91162307 3788
3789 //
3790 // change cut on curvature if it can't reach this layer
3791 // maximal curvature set to reach it
3792 Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
3793 if (dvertexmax*0.5*cuts[0]>0.85){
3794 cuts[0] = 0.85/(dvertexmax*0.5+1.);
3795 }
3796 Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
3797
3798 // Int_t ddsec = 1;
3799 if (deltay>0) ddsec = 0;
3800 // loop over clusters
3801 for (Int_t is=0; is < kr1; is++) {
3802 //
3803 if (kr1[is]->IsUsed(10)) continue;
3e1f1ce7 3804 if (kr1[is]->IsDisabled()) {
3805 continue;
3806 }
65e67c9c 3807
91162307 3808 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3809 //if (TMath::Abs(y1)>ymax) continue;
3810
3811 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3812
3813 // find possible directions
3814 Float_t anglez = (z1-z3)/(x1-x3);
3815 Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
3816 //
3817 //
3818 //find rotation angles relative to line given by vertex and point 1
3819 Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
3820 Double_t dvertex = TMath::Sqrt(dvertex2);
3821 Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
3822 Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
3823
3824 //
3825 // loop over 2 sectors
3826 Int_t dsec1=-ddsec;
3827 Int_t dsec2= ddsec;
3828 if (y1<0) dsec2= 0;
3829 if (y1>0) dsec1= 0;
3830
3831 Double_t dddz1=0; // direction of delta inclination in z axis
3832 Double_t dddz2=0;
3833 if ( (z1-z3)>0)
3834 dddz1 =1;
3835 else
3836 dddz2 =1;
3837 //
3838 for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
3839 Int_t sec2 = sec + dsec;
3840 //
bd26fa83 3841 // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
3842 //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
3843 AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
3844 AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
91162307 3845 Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
3846 Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
3847
3848 // rotation angles to p1-p3
3849 Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
3850 Double_t x2, y2, z2;
3851 //
3852 // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
3853
3854 //
3855 Double_t dxx0 = (xx2-x3)*cs13r;
3856 Double_t dyy0 = (xx2-x3)*sn13r;
3857 for (Int_t js=index1; js < index2; js++) {
3858 const AliTPCclusterMI *kcl = kr2[js];
65e67c9c 3859 if (kcl->IsUsed(10)) continue;
3e1f1ce7 3860 if (kcl->IsDisabled()) {
3861 continue;
3862 }
91162307 3863 //
3864 //calcutate parameters
3865 //
3866 Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
3867 // stright track
3868 if (TMath::Abs(yy0)<0.000001) continue;
3869 Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
3870 Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
3871 Double_t r02 = (0.25+y0*y0)*dvertex2;
3872 //curvature (radius) cut
3873 if (r02<r2min) continue;
3874
3875 nin0++;
3876 //
3877 Double_t c0 = 1/TMath::Sqrt(r02);
3878 if (yy0>0) c0*=-1.;
3879
3880
3881 //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
3882 //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
b67e07dc 3883 Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
3884 Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
91162307 3885 //
3886 //
3887 Double_t z0 = kcl->GetZ();
3888 Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
3889 if (TMath::Abs(zzzz2-z0)>0.5) continue;
3890 nin1++;
3891 //
3892 Double_t dip = (z1-z0)*c0/dfi1;
3893 Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
3894 //
3895 y2 = kcl->GetY();
3896 if (dsec==0){
3897 x2 = xx2;
3898 z2 = kcl->GetZ();
3899 }
3900 else
3901 {
3902 // rotation
3903 z2 = kcl->GetZ();
3904 x2= xx2*cs-y2*sn*dsec;
3905 y2=+xx2*sn*dsec+y2*cs;
3906 }
3907
3908 x[0] = y1;
3909 x[1] = z1;
3910 x[2] = x0;
3911 x[3] = dip;
3912 x[4] = c0;
3913 //
3914 //
3915 // do we have cluster at the middle ?
3916 Double_t ym,zm;
3917 GetProlongation(x1,xm,x,ym,zm);
3918 UInt_t dummy;
3919 AliTPCclusterMI * cm=0;
3920 if (TMath::Abs(ym)-ymaxm<0){
3921 cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3922 if ((!cm) || (cm->IsUsed(10))) {
3923 continue;
3924 }
3925 }
3926 else{
3927 // rotate y1 to system 0
3928 // get state vector in rotated system
3929 Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
3930 Double_t xr2 = x0*cs+yr1*sn*dsec;
3931 Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3932 //
3933 GetProlongation(xx2,xm,xr,ym,zm);
3934 if (TMath::Abs(ym)-ymaxm<0){
3935 cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3936 if ((!cm) || (cm->IsUsed(10))) {
3937 continue;
3938 }
3939 }
3940 }
3941
3942
2a97785a 3943 // Double_t dym = 0;
3944 // Double_t dzm = 0;
3945 // if (cm){
3946 // dym = ym - cm->GetY();
3947 // dzm = zm - cm->GetZ();
3948 // }
91162307 3949 nin2++;
3950
3951
3952 //
3953 //
3954 Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
3955 Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
3956 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
3957 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3958 //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
3959
b67e07dc 3960 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3961 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3962 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3963 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3964 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3965 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
91162307 3966
b67e07dc 3967 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3968 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3969 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3970 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
91162307 3971
1c53abe2 3972 c[0]=sy1;
3973 c[1]=0.; c[2]=sz1;
3974 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3975 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3976 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3977 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3978 c[13]=f30*sy1*f40+f32*sy2*f42;
3979 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
91162307 3980
d757548f 3981 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
91162307 3982
1c53abe2 3983 UInt_t index=kr1.GetIndex(is);
ddfbc51a 3984 if (seed) {MarkSeedFree(seed); seed = 0;}
3985 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, ns*alpha+shift, x, c, index);
3986 seed->SetPoolID(fLastSeedID);
d757548f 3987 track->SetIsSeeding(kTRUE);
3988 track->SetSeed1(i1);
3989 track->SetSeed2(i2);
3990 track->SetSeedType(3);
c9427e08 3991
91162307 3992
3993 //if (dsec==0) {
d757548f 3994 FollowProlongation(*track, (i1+i2)/2,1);
91162307 3995 Int_t foundable,found,shared;
d757548f 3996 track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
3997 if ((found<0.55*foundable) || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
ddfbc51a 3998 MarkSeedFree(seed); seed = 0;
91162307 3999 continue;
4000 }
4001 //}
4002
4003 nin++;
d757548f 4004 FollowProlongation(*track, i2,1);
91162307 4005
4006
4007 //Int_t rc = 1;
d757548f 4008 track->SetBConstrain(1);
91162307 4009 // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
d757548f 4010 track->SetLastPoint(i1); // first cluster in track position
4011 track->SetFirstPoint(track->GetLastPoint());
91162307 4012
d757548f 4013 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
4014 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
4015 track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
ddfbc51a 4016 MarkSeedFree(seed); seed = 0;
c9427e08 4017 continue;
4018 }
91162307 4019 nout1++;
4020 // Z VERTEX CONDITION
c274e255 4021 Double_t zv, bz=GetBz();
d757548f 4022 if ( !track->GetZAt(0.,bz,zv) ) continue;
91162307 4023 if (TMath::Abs(zv-z3)>cuts[2]) {
d757548f 4024 FollowProlongation(*track, TMath::Max(i2-20,0));
4025 if ( !track->GetZAt(0.,bz,zv) ) continue;
91162307 4026 if (TMath::Abs(zv-z3)>cuts[2]){
d757548f 4027 FollowProlongation(*track, TMath::Max(i2-40,0));
4028 if ( !track->GetZAt(0.,bz,zv) ) continue;
4029 if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
91162307 4030 // make seed without constrain
d757548f 4031 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
91162307 4032 FollowProlongation(*track2, i2,1);
b9671574 4033 track2->SetBConstrain(kFALSE);
4034 track2->SetSeedType(1);
d757548f 4035 arr->AddLast(track2);
ddfbc51a 4036 MarkSeedFree( seed ); seed = 0;
91162307 4037 continue;
4038 }
4039 else{
ddfbc51a 4040 MarkSeedFree( seed ); seed = 0;
91162307 4041 continue;
d757548f 4042
91162307 4043 }
4044 }
c9427e08 4045 }
316c6cd9 4046
d757548f 4047 track->SetSeedType(0);
f06a1ff6 4048 arr->AddLast(track); // note, track is seed, don't free the seed
ddfbc51a 4049 seed = new( NextFreeSeed() ) AliTPCseed;
4050 seed->SetPoolID(fLastSeedID);
91162307 4051 nout2++;
4052 // don't consider other combinations
d757548f 4053 if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
91162307 4054 break;
1c53abe2 4055 }
4056 }
4057 }
6bdc18d6 4058 if (fDebug>3){
4059 Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
91162307 4060 }
ddfbc51a 4061 if (seed) MarkSeedFree( seed );
1c53abe2 4062}
4063
1627d1c4 4064
829455ad 4065void AliTPCtracker::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
91162307 4066 Float_t deltay) {
4067
4068
4069
1627d1c4 4070 //-----------------------------------------------------------------
91162307 4071 // This function creates track seeds.
1627d1c4 4072 //-----------------------------------------------------------------
91162307 4073 // cuts[0] - fP4 cut
4074 // cuts[1] - tan(phi) cut
4075 // cuts[2] - zvertex cut
4076 // cuts[3] - fP3 cut
4077
4078
4079 Int_t nin0 = 0;
4080 Int_t nin1 = 0;
4081 Int_t nin2 = 0;
4082 Int_t nin = 0;
4083 Int_t nout1 = 0;
4084 Int_t nout2 = 0;
4085 Int_t nout3 =0;
4086 Double_t x[5], c[15];
4087 //
4088 // make temporary seed
ddfbc51a 4089 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
4090 seed->SetPoolID(fLastSeedID);
1627d1c4 4091 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
4092 // Double_t cs=cos(alpha), sn=sin(alpha);
91162307 4093 //
4094 //
1627d1c4 4095
91162307 4096 // first 3 padrows
4097 Double_t x1 = GetXrow(i1-1);
bd26fa83 4098 const AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
b9671574 4099 Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
91162307 4100 //
4101 Double_t x1p = GetXrow(i1);
bd26fa83 4102 const AliTPCtrackerRow& kr1p=GetRow(sec,i1);
91162307 4103 //
4104 Double_t x1m = GetXrow(i1-2);
bd26fa83 4105 const AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
1627d1c4 4106
91162307 4107 //
4108 //last 3 padrow for seeding
bd26fa83 4109 AliTPCtrackerRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
91162307 4110 Double_t x3 = GetXrow(i1-7);
4111 // Double_t y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;
4112 //
bd26fa83 4113 AliTPCtrackerRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
91162307 4114 Double_t x3p = GetXrow(i1-6);
4115 //
bd26fa83 4116 AliTPCtrackerRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
91162307 4117 Double_t x3m = GetXrow(i1-8);
1627d1c4 4118
91162307 4119 //
4120 //
4121 // middle padrow
4122 Int_t im = i1-4; //middle pad row index
4123 Double_t xm = GetXrow(im); // radius of middle pad-row
bd26fa83 4124 const AliTPCtrackerRow& krm=GetRow(sec,im); //middle pad -row
91162307 4125 // Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;
4126 //
4127 //
4128 Double_t deltax = x1-x3;
4129 Double_t dymax = deltax*cuts[1];
4130 Double_t dzmax = deltax*cuts[3];
4131 //
4132 // loop over clusters
4133 for (Int_t is=0; is < kr1; is++) {
1627d1c4 4134 //
65e67c9c 4135 if (kr1[is]->IsUsed(10)) continue;
3e1f1ce7 4136 if (kr1[is]->IsDisabled()) {
4137 continue;
4138 }
65e67c9c 4139
91162307 4140 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
1627d1c4 4141 //
91162307 4142 if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
4143 //
4144 Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
4145 Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
4146 //
4147 Double_t y3, z3;
1627d1c4 4148 //
1627d1c4 4149 //
91162307 4150 UInt_t index;
4151 for (Int_t js=index1; js < index2; js++) {
4152 const AliTPCclusterMI *kcl = kr3[js];
3e1f1ce7 4153 if (kcl->IsDisabled()) {
4154 continue;
4155 }
65e67c9c 4156
91162307 4157 if (kcl->IsUsed(10)) continue;
4158 y3 = kcl->GetY();
4159 // apply angular cuts
4160 if (TMath::Abs(y1-y3)>dymax) continue;
97d77e7a 4161 //x3 = x3;
91162307 4162 z3 = kcl->GetZ();
4163 if (TMath::Abs(z1-z3)>dzmax) continue;
4164 //
4165 Double_t angley = (y1-y3)/(x1-x3);
4166 Double_t anglez = (z1-z3)/(x1-x3);
4167 //
4168 Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
4169 Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
4170 //
4171 Double_t yyym = angley*(xm-x1)+y1;
4172 Double_t zzzm = anglez*(xm-x1)+z1;
4173
4174 const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
4175 if (!kcm) continue;
4176 if (kcm->IsUsed(10)) continue;
3e1f1ce7 4177 if (kcm->IsDisabled()) {
4178 continue;
4179 }
65e67c9c 4180
91162307 4181 erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
4182 errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
4183 //
4184 //
4185 //
4186 Int_t used =0;
4187 Int_t found =0;
4188 //
4189 // look around first
4190 const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
4191 anglez*(x1m-x1)+z1,
4192 erry,errz,index);
4193 //
4194 if (kc1m){
4195 found++;
4196 if (kc1m->IsUsed(10)) used++;
1627d1c4 4197 }
91162307 4198 const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
4199 anglez*(x1p-x1)+z1,
4200 erry,errz,index);
1627d1c4 4201 //
91162307 4202 if (kc1p){
4203 found++;
4204 if (kc1p->IsUsed(10)) used++;
1627d1c4 4205 }
91162307 4206 if (used>1) continue;
4207 if (found<1) continue;
1627d1c4 4208
91162307 4209 //
4210 // look around last
4211 const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
4212 anglez*(x3m-x3)+z3,
4213 erry,errz,index);
4214 //
4215 if (kc3m){
4216 found++;
4217 if (kc3m->IsUsed(10)) used++;
4218 }
4219 else
4220 continue;
4221 const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
4222 anglez*(x3p-x3)+z3,
4223 erry,errz,index);
4224 //
4225 if (kc3p){
4226 found++;
4227 if (kc3p->IsUsed(10)) used++;
4228 }
4229 else
4230 continue;
4231 if (used>1) continue;
4232 if (found<3) continue;
4233 //
4234 Double_t x2,y2,z2;
4235 x2 = xm;
4236 y2 = kcm->GetY();
4237 z2 = kcm->GetZ();
4238 //
4239
1627d1c4 4240 x[0]=y1;
4241 x[1]=z1;
b67e07dc 4242 x[4]=F1(x1,y1,x2,y2,x3,y3);
91162307 4243 //if (TMath::Abs(x[4]) >= cuts[0]) continue;
4244 nin0++;
4245 //
b67e07dc 4246 x[2]=F2(x1,y1,x2,y2,x3,y3);
91162307 4247 nin1++;
4248 //
b67e07dc 4249 x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
91162307 4250 //if (TMath::Abs(x[3]) > cuts[3]) continue;
4251 nin2++;
4252 //
4253 //
4254 Double_t sy1=0.1, sz1=0.1;
4255 Double_t sy2=0.1, sz2=0.1;
4256 Double_t sy3=0.1, sy=0.1, sz=0.1;
1627d1c4 4257
b67e07dc 4258 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
4259 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
4260 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
4261 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
4262 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
4263 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
91162307 4264
b67e07dc 4265 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
4266 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
4267 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
4268 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
1627d1c4 4269
4270 c[0]=sy1;
91162307 4271 c[1]=0.; c[2]=sz1;
1627d1c4 4272 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4273 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4274 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4275 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4276 c[13]=f30*sy1*f40+f32*sy2*f42;
4277 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4278
91162307 4279 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
4280
77f88633 4281 index=kr1.GetIndex(is);
ddfbc51a 4282 if (seed) {MarkSeedFree( seed ); seed = 0;}
4283 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, sec*alpha+shift, x, c, index);
4284 seed->SetPoolID(fLastSeedID);
91162307 4285
b9671574 4286 track->SetIsSeeding(kTRUE);
91162307 4287
4288 nin++;
4289 FollowProlongation(*track, i1-7,1);
b9671574 4290 if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
4291 track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
ddfbc51a 4292 MarkSeedFree( seed ); seed = 0;
91162307 4293 continue;
4294 }
4295 nout1++;
4296 nout2++;
4297 //Int_t rc = 1;
4298 FollowProlongation(*track, i2,1);
b9671574 4299 track->SetBConstrain(0);
4300 track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
4301 track->SetFirstPoint(track->GetLastPoint());
91162307 4302
4303 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 4304 track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
4305 track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
ddfbc51a 4306 MarkSeedFree( seed ); seed = 0;
91162307 4307 continue;
4308 }
4309
4310 {
4311 FollowProlongation(*track, TMath::Max(i2-10,0),1);
4312 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
4313 FollowProlongation(*track2, i2,1);
b9671574 4314 track2->SetBConstrain(kFALSE);
4315 track2->SetSeedType(4);
f06a1ff6 4316 arr->AddLast(track2);
ddfbc51a 4317 MarkSeedFree( seed ); seed = 0;
91162307 4318 }
4319
4320
4321 //arr->AddLast(track);
4322 //seed = new AliTPCseed;
4323 nout3++;
4324 }
4325 }
4326
6bdc18d6 4327 if (fDebug>3){
7d85e147 4328 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 4329 }
ddfbc51a 4330 if (seed) MarkSeedFree(seed);
91162307 4331}
4332
4333
4334//_____________________________________________________________________________
829455ad 4335void AliTPCtracker::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
176aff27 4336 Float_t deltay, Bool_t /*bconstrain*/) {
91162307 4337 //-----------------------------------------------------------------
4338 // This function creates track seeds - without vertex constraint
4339 //-----------------------------------------------------------------
4340 // cuts[0] - fP4 cut - not applied
4341 // cuts[1] - tan(phi) cut
4342 // cuts[2] - zvertex cut - not applied
4343 // cuts[3] - fP3 cut
4344 Int_t nin0=0;
4345 Int_t nin1=0;
4346 Int_t nin2=0;
4347 Int_t nin3=0;
4348 // Int_t nin4=0;
4349 //Int_t nin5=0;
4350
4351
4352
4353 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
4354 // Double_t cs=cos(alpha), sn=sin(alpha);
4355 Int_t row0 = (i1+i2)/2;
4356 Int_t drow = (i1-i2)/2;
bd26fa83 4357 const AliTPCtrackerRow& kr0=fSectors[sec][row0];
4358 AliTPCtrackerRow * kr=0;
91162307 4359
4360 AliTPCpolyTrack polytrack;
4361 Int_t nclusters=fSectors[sec][row0];
ddfbc51a 4362 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
4363 seed->SetPoolID(fLastSeedID);
91162307 4364
4365 Int_t sumused=0;
4366 Int_t cused=0;
4367 Int_t cnused=0;
4368 for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
4369 Int_t nfound =0;
4370 Int_t nfoundable =0;
4371 for (Int_t iter =1; iter<2; iter++){ //iterations
bd26fa83 4372 const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
4373 const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];
91162307 4374 const AliTPCclusterMI * cl= kr0[is];
3e1f1ce7 4375 if (cl->IsDisabled()) {
4376 continue;
4377 }
65e67c9c 4378
91162307 4379 if (cl->IsUsed(10)) {
4380 cused++;
4381 }
4382 else{
4383 cnused++;
4384 }
4385 Double_t x = kr0.GetX();
4386 // Initialization of the polytrack
4387 nfound =0;
4388 nfoundable =0;
4389 polytrack.Reset();
4390 //
4391 Double_t y0= cl->GetY();
4392 Double_t z0= cl->GetZ();
4393 Float_t erry = 0;
4394 Float_t errz = 0;
4395
b9671574 4396 Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
91162307 4397 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
4398
4399 erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
4400 errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
4401 polytrack.AddPoint(x,y0,z0,erry, errz);
4402
4403 sumused=0;
4404 if (cl->IsUsed(10)) sumused++;
4405
4406
4407 Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
4408 Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
4409 //
4410 x = krm.GetX();
4411 AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
4412 if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
4413 erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
4414 errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
4415 if (cl1->IsUsed(10)) sumused++;
4416 polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
4417 }
4418 //
4419 x = krp.GetX();
4420 AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
4421 if (cl2) {
4422 erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
4423 errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
4424 if (cl2->IsUsed(10)) sumused++;
4425 polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
4426 }
4427 //
4428 if (sumused>0) continue;
4429 nin0++;
4430 polytrack.UpdateParameters();
4431 // follow polytrack
4432 roadz = 1.2;
4433 roady = 1.2;
4434 //
4435 Double_t yn,zn;
4436 nfoundable = polytrack.GetN();
4437 nfound = nfoundable;
4438 //
4439 for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
4440 Float_t maxdist = 0.8*(1.+3./(ddrow));
4441 for (Int_t delta = -1;delta<=1;delta+=2){
4442 Int_t row = row0+ddrow*delta;
4443 kr = &(fSectors[sec][row]);
4444 Double_t xn = kr->GetX();
77f88633 4445 Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
91162307 4446 polytrack.GetFitPoint(xn,yn,zn);
77f88633 4447 if (TMath::Abs(yn)>ymax1) continue;
91162307 4448 nfoundable++;
4449 AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
4450 if (cln) {
4451 Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
4452 if (dist<maxdist){
4453 /*
4454 erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
4455 errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
4456 if (cln->IsUsed(10)) {
4457 // printf("used\n");
4458 sumused++;
4459 erry*=2;
4460 errz*=2;
4461 }
4462 */
4463 erry=0.1;
4464 errz=0.1;
4465 polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
4466 nfound++;
4467 }
4468 }
4469 }
4470 if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
4471 polytrack.UpdateParameters();
4472 }
4473 }
4474 if ( (sumused>3) || (sumused>0.5*nfound)) {
4475 //printf("sumused %d\n",sumused);
4476 continue;
4477 }
4478 nin1++;
4479 Double_t dy,dz;
4480 polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
4481 AliTPCpolyTrack track2;
4482
4483 polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
4484 if (track2.GetN()<0.5*nfoundable) continue;
4485 nin2++;
4486
4487 if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
4488 //
4489 // test seed with and without constrain
4490 for (Int_t constrain=0; constrain<=0;constrain++){
4491 // add polytrack candidate
4492
4493 Double_t x[5], c[15];
4494 Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
4495 track2.GetBoundaries(x3,x1);
4496 x2 = (x1+x3)/2.;
4497 track2.GetFitPoint(x1,y1,z1);
4498 track2.GetFitPoint(x2,y2,z2);
4499 track2.GetFitPoint(x3,y3,z3);
4500 //
4501 //is track pointing to the vertex ?
4502 Double_t x0,y0,z0;
4503 x0=0;
4504 polytrack.GetFitPoint(x0,y0,z0);
4505
4506 if (constrain) {
4507 x2 = x3;
4508 y2 = y3;
4509 z2 = z3;
4510
4511 x3 = 0;
4512 y3 = 0;
4513 z3 = 0;
4514 }
4515 x[0]=y1;
4516 x[1]=z1;
b67e07dc 4517 x[4]=F1(x1,y1,x2,y2,x3,y3);
91162307 4518
4519 // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
b67e07dc 4520 x[2]=F2(x1,y1,x2,y2,x3,y3);
91162307 4521
4522 //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
b67e07dc 4523 //x[3]=F3(x1,y1,x2,y2,z1,z2);
4524 x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
91162307 4525 //if (TMath::Abs(x[3]) > cuts[3]) continue;
4526
4527
4528 Double_t sy =0.1, sz =0.1;
4529 Double_t sy1=0.02, sz1=0.02;
4530 Double_t sy2=0.02, sz2=0.02;
4531 Double_t sy3=0.02;
4532
4533 if (constrain){
4534 sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
4535 }
4536
b67e07dc 4537 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
4538 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
4539 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
4540 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
4541 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
4542 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
4543
4544 Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
4545 Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
4546 Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
4547 Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
91162307 4548
4549
4550 c[0]=sy1;
4551 c[1]=0.; c[2]=sz1;
4552 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4553 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4554 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4555 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4556 c[13]=f30*sy1*f40+f32*sy2*f42;
4557 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4558
4559 //Int_t row1 = fSectors->GetRowNumber(x1);
4560 Int_t row1 = GetRowNumber(x1);
4561
4562 UInt_t index=0;
4563 //kr0.GetIndex(is);
ddfbc51a 4564 if (seed) {MarkSeedFree( seed ); seed = 0;}
4565 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1,sec*alpha+shift,x,c,index);
4566 seed->SetPoolID(fLastSeedID);
b9671574 4567 track->SetIsSeeding(kTRUE);
91162307 4568 Int_t rc=FollowProlongation(*track, i2);
b9671574 4569 if (constrain) track->SetBConstrain(1);
91162307 4570 else
b9671574 4571 track->SetBConstrain(0);
4572 track->SetLastPoint(row1+fInnerSec->GetNRows()); // first cluster in track position
4573 track->SetFirstPoint(track->GetLastPoint());
91162307 4574
4575 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 4576 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
4577 track->GetNShared()>0.4*track->GetNumberOfClusters()) {
ddfbc51a 4578 MarkSeedFree( seed ); seed = 0;
91162307 4579 }
4580 else {
f06a1ff6 4581 arr->AddLast(track); // track IS seed, don't free seed
ddfbc51a 4582 seed = new( NextFreeSeed() ) AliTPCseed;
4583 seed->SetPoolID(fLastSeedID);
91162307 4584 }
4585 nin3++;
4586 }
4587 } // if accepted seed
4588 }
6bdc18d6 4589 if (fDebug>3){
4590 Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
91162307 4591 }
ddfbc51a 4592 if (seed) MarkSeedFree( seed );
91162307 4593}
4594
4595
829455ad 4596AliTPCseed *AliTPCtracker::MakeSeed(AliTPCseed *const track, Float_t r0, Float_t r1, Float_t r2)
91162307 4597{
4598 //
4599 //
d26d9159 4600 //reseed using track points
91162307 4601 Int_t p0 = int(r0*track->GetNumberOfClusters()); // point 0
4602 Int_t p1 = int(r1*track->GetNumberOfClusters());
4603 Int_t p2 = int(r2*track->GetNumberOfClusters()); // last point
176aff27 4604 Int_t pp2=0;
91162307 4605 Double_t x0[3],x1[3],x2[3];
89e09524 4606 for (Int_t i=0;i<3;i++){
4607 x0[i]=-1;
4608 x1[i]=-1;
4609 x2[i]=-1;
4610 }
91162307 4611
4612 // find track position at given ratio of the length
89e09524 4613 Int_t sec0=0, sec1=0, sec2=0;
91162307 4614 Int_t index=-1;
4615 Int_t clindex;
4616 for (Int_t i=0;i<160;i++){
b9671574 4617 if (track->GetClusterPointer(i)){
91162307 4618 index++;
4619 AliTPCTrackerPoint *trpoint =track->GetTrackPoint(i);
4620 if ( (index<p0) || x0[0]<0 ){
4621 if (trpoint->GetX()>1){
4622 clindex = track->GetClusterIndex2(i);
bad6eb00 4623 if (clindex >= 0){
91162307 4624 x0[0] = trpoint->GetX();
4625 x0[1] = trpoint->GetY();
4626 x0[2] = trpoint->GetZ();
4627 sec0 = ((clindex&0xff000000)>>24)%18;
4628 }
4629 }
4630 }
4631
4632 if ( (index<p1) &&(trpoint->GetX()>1)){
4633 clindex = track->GetClusterIndex2(i);
bad6eb00 4634 if (clindex >= 0){
91162307 4635 x1[0] = trpoint->GetX();
4636 x1[1] = trpoint->GetY();
4637 x1[2] = trpoint->GetZ();
4638 sec1 = ((clindex&0xff000000)>>24)%18;
4639 }
4640 }
4641 if ( (index<p2) &&(trpoint->GetX()>1)){
4642 clindex = track->GetClusterIndex2(i);
bad6eb00 4643 if (clindex >= 0){
91162307 4644 x2[0] = trpoint->GetX();
4645 x2[1] = trpoint->GetY();
4646 x2[2] = trpoint->GetZ();
4647 sec2 = ((clindex&0xff000000)>>24)%18;
4648 pp2 = i;
4649 }
4650 }
4651 }
4652 }
4653
4654 Double_t alpha, cs,sn, xx2,yy2;
4655 //
4656 alpha = (sec1-sec2)*fSectors->GetAlpha();
4657 cs = TMath::Cos(alpha);
4658 sn = TMath::Sin(alpha);
4659 xx2= x1[0]*cs-x1[1]*sn;
4660 yy2= x1[0]*sn+x1[1]*cs;
4661 x1[0] = xx2;
4662 x1[1] = yy2;
4663 //
4664 alpha = (sec0-sec2)*fSectors->GetAlpha();
4665 cs = TMath::Cos(alpha);
4666 sn = TMath::Sin(alpha);
4667 xx2= x0[0]*cs-x0[1]*sn;
4668 yy2= x0[0]*sn+x0[1]*cs;
4669 x0[0] = xx2;
4670 x0[1] = yy2;
4671 //
4672 //
4673 //
4674 Double_t x[5],c[15];
4675 //
4676 x[0]=x2[1];
4677 x[1]=x2[2];
b67e07dc 4678 x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
91162307 4679 // if (x[4]>1) return 0;
b67e07dc 4680 x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
4681 x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
91162307 4682 //if (TMath::Abs(x[3]) > 2.2) return 0;
4683 //if (TMath::Abs(x[2]) > 1.99) return 0;
4684 //
4685 Double_t sy =0.1, sz =0.1;
4686 //
4687 Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
4688 Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
4689 Double_t sy3=0.01+track->GetSigmaY2();
4690 //
b67e07dc 4691 Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
4692 Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
4693 Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
4694 Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
4695 Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
4696 Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
4697 //
4698 Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
4699 Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
4700 Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
4701 Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
91162307 4702
4703
4704 c[0]=sy1;
4705 c[1]=0.; c[2]=sz1;
4706 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4707 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4708 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4709 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4710 c[13]=f30*sy1*f40+f32*sy2*f42;
4711 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4712
4713 // Int_t row1 = fSectors->GetRowNumber(x2[0]);
ddfbc51a 4714 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4715 seed->SetPoolID(fLastSeedID);
91162307 4716 // Double_t y0,z0,y1,z1, y2,z2;
4717 //seed->GetProlongation(x0[0],y0,z0);
4718 // seed->GetProlongation(x1[0],y1,z1);
4719 //seed->GetProlongation(x2[0],y2,z2);
4720 // seed =0;
b9671574 4721 seed->SetLastPoint(pp2);
4722 seed->SetFirstPoint(pp2);
91162307 4723
4724
4725 return seed;
4726}
4727
d26d9159 4728
829455ad 4729AliTPCseed *AliTPCtracker::ReSeed(const AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
d26d9159 4730{
4731 //
4732 //
4733 //reseed using founded clusters
4734 //
4735 // Find the number of clusters
4736 Int_t nclusters = 0;
4737 for (Int_t irow=0;irow<160;irow++){
4738 if (track->GetClusterIndex(irow)>0) nclusters++;
4739 }
4740 //
4741 Int_t ipos[3];
4742 ipos[0] = TMath::Max(int(r0*nclusters),0); // point 0 cluster
4743 ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1); //
4744 ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1); // last point
4745 //
4746 //
ec26e231 4747 Double_t xyz[3][3]={{0}};
4748 Int_t row[3]={0},sec[3]={0,0,0};
d26d9159 4749 //
4750 // find track row position at given ratio of the length
4751 Int_t index=-1;
4752 for (Int_t irow=0;irow<160;irow++){
4753 if (track->GetClusterIndex2(irow)<0) continue;
4754 index++;
4755 for (Int_t ipoint=0;ipoint<3;ipoint++){
4756 if (index<=ipos[ipoint]) row[ipoint] = irow;
4757 }
4758 }
4759 //
4760 //Get cluster and sector position
4761 for (Int_t ipoint=0;ipoint<3;ipoint++){
4762 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4763 AliTPCclusterMI * cl = GetClusterMI(clindex);
4764 if (cl==0) {
6bdc18d6 4765 //Error("Bug\n");
47966a6d 4766 // AliTPCclusterMI * cl = GetClusterMI(clindex);
d26d9159 4767 return 0;
4768 }
4769 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4770 xyz[ipoint][0] = GetXrow(row[ipoint]);
4771 xyz[ipoint][1] = cl->GetY();
4772 xyz[ipoint][2] = cl->GetZ();
4773 }
4774 //
4775 //
4776 // Calculate seed state vector and covariance matrix
4777
4778 Double_t alpha, cs,sn, xx2,yy2;
4779 //
4780 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4781 cs = TMath::Cos(alpha);
4782 sn = TMath::Sin(alpha);
4783 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4784 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4785 xyz[1][0] = xx2;
4786 xyz[1][1] = yy2;
4787 //
4788 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4789 cs = TMath::Cos(alpha);
4790 sn = TMath::Sin(alpha);
4791 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4792 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4793 xyz[0][0] = xx2;
4794 xyz[0][1] = yy2;
4795 //
4796 //
4797 //
4798 Double_t x[5],c[15];
4799 //
4800 x[0]=xyz[2][1];
4801 x[1]=xyz[2][2];
4802 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4803 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4804 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4805 //
4806 Double_t sy =0.1, sz =0.1;
4807 //
4808 Double_t sy1=0.2, sz1=0.2;
4809 Double_t sy2=0.2, sz2=0.2;
4810 Double_t sy3=0.2;
4811 //
4812 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;
4813 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;
4814 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;
4815 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;
4816 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;
4817 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;
4818 //
4819 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;
4820 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;
4821 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;
4822 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;
4823
4824
4825 c[0]=sy1;
4826 c[1]=0.; c[2]=sz1;
4827 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4828 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4829 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4830 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4831 c[13]=f30*sy1*f40+f32*sy2*f42;
4832 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4833
4834 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
ddfbc51a 4835 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4836 seed->SetPoolID(fLastSeedID);
b9671574 4837 seed->SetLastPoint(row[2]);
4838 seed->SetFirstPoint(row[2]);
d26d9159 4839 return seed;
4840}
4841
eea478d3 4842
829455ad 4843AliTPCseed *AliTPCtracker::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
eea478d3 4844{
4845 //
4846 //
4847 //reseed using founded clusters
4848 //
4849 Double_t xyz[3][3];
4a12af72 4850 Int_t row[3]={0,0,0};
4851 Int_t sec[3]={0,0,0};
eea478d3 4852 //
4853 // forward direction
4854 if (forward){
4855 for (Int_t irow=r0;irow<160;irow++){
4856 if (track->GetClusterIndex(irow)>0){
4857 row[0] = irow;
4858 break;
4859 }
4860 }
4861 for (Int_t irow=160;irow>r0;irow--){
4862 if (track->GetClusterIndex(irow)>0){
4863 row[2] = irow;
4864 break;
4865 }
4866 }
4867 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4868 if (track->GetClusterIndex(irow)>0){
4869 row[1] = irow;
4870 break;
4871 }
4872 }
4873 //
4874 }
4875 if (!forward){
4876 for (Int_t irow=0;irow<r0;irow++){
4877 if (track->GetClusterIndex(irow)>0){
4878 row[0] = irow;
4879 break;
4880 }
4881 }
4882 for (Int_t irow=r0;irow>0;irow--){
4883 if (track->GetClusterIndex(irow)>0){
4884 row[2] = irow;
4885 break;
4886 }
4887 }
4888 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4889 if (track->GetClusterIndex(irow)>0){
4890 row[1] = irow;
4891 break;
4892 }
4893 }
4894 }
4895 //
4896 if ((row[2]-row[0])<20) return 0;
4897 if (row[1]==0) return 0;
4898 //
4899 //
4900 //Get cluster and sector position
4901 for (Int_t ipoint=0;ipoint<3;ipoint++){
4902 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4903 AliTPCclusterMI * cl = GetClusterMI(clindex);
4904 if (cl==0) {
4905 //Error("Bug\n");
4906 // AliTPCclusterMI * cl = GetClusterMI(clindex);
4907 return 0;
4908 }
4909 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4910 xyz[ipoint][0] = GetXrow(row[ipoint]);
4911 AliTPCTrackerPoint * point = track->GetTrackPoint(row[ipoint]);
4912 if (point&&ipoint<2){
4913 //
4914 xyz[ipoint][1] = point->GetY();
4915 xyz[ipoint][2] = point->GetZ();
4916 }
4917 else{
4918 xyz[ipoint][1] = cl->GetY();
4919 xyz[ipoint][2] = cl->GetZ();
4920 }
4921 }
4922 //
4923 //
4924 //
4925 //
4926 // Calculate seed state vector and covariance matrix
4927
4928 Double_t alpha, cs,sn, xx2,yy2;
4929 //
4930 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4931 cs = TMath::Cos(alpha);
4932 sn = TMath::Sin(alpha);
4933 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4934 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4935 xyz[1][0] = xx2;
4936 xyz[1][1] = yy2;
4937 //
4938 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4939 cs = TMath::Cos(alpha);
4940 sn = TMath::Sin(alpha);
4941 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4942 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4943 xyz[0][0] = xx2;
4944 xyz[0][1] = yy2;
4945 //
4946 //
4947 //
4948 Double_t x[5],c[15];
4949 //
4950 x[0]=xyz[2][1];
4951 x[1]=xyz[2][2];
4952 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4953 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4954 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4955 //
4956 Double_t sy =0.1, sz =0.1;
4957 //
4958 Double_t sy1=0.2, sz1=0.2;
4959 Double_t sy2=0.2, sz2=0.2;
4960 Double_t sy3=0.2;
4961 //
4962 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;
4963 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;
4964 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;
4965 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;
4966 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;
4967 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;
4968 //
4969 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;
4970 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;
4971 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;
4972 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;
4973
4974
4975 c[0]=sy1;
4976 c[1]=0.; c[2]=sz1;
4977 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4978 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4979 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4980 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4981 c[13]=f30*sy1*f40+f32*sy2*f42;
4982 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4983
4984 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
ddfbc51a 4985 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4986 seed->SetPoolID(fLastSeedID);
b9671574 4987 seed->SetLastPoint(row[2]);
4988 seed->SetFirstPoint(row[2]);
eea478d3 4989 for (Int_t i=row[0];i<row[2];i++){
b9671574 4990 seed->SetClusterIndex(i, track->GetClusterIndex(i));
eea478d3 4991 }
4992
4993 return seed;
4994}
4995
6d493ea0 4996
4997
829455ad 4998void AliTPCtracker::FindMultiMC(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
6d493ea0 4999{
5000 //
5001 // find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
5002 // USES MC LABELS
65e67c9c 5003 // Use AliTPCReconstructor::StreamLevel()& kStreamFindMultiMC if you want to tune parameters - cuts
6d493ea0 5004 //
5005 // Two reasons to have multiple find tracks
5006 // 1. Curling tracks can be find more than once
5007 // 2. Splitted tracks
5008 // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
5009 // b.) Edge effect on the sector boundaries
5010 //
5011 //
5012 // Algorithm done in 2 phases - because of CPU consumption
5013 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
5014 //
5015 // Algorihm for curling tracks sign:
5016 // 1 phase -makes a very rough fast cuts to minimize combinatorics
5017 // a.) opposite sign
5018 // b.) one of the tracks - not pointing to the primary vertex -
5019 // c.) delta tan(theta)
5020 // d.) delta phi
5021 // 2 phase - calculates DCA between tracks - time consument
5022
5023 //
5024 // fast cuts
5025 //
5026 // General cuts - for splitted tracks and for curling tracks
5027 //
5028 const Float_t kMaxdPhi = 0.2; // maximal distance in phi
5029 //
5030 // Curling tracks cuts
5031 //
5032 //
5033 //
5034 //
5035 Int_t nentries = array->GetEntriesFast();
5036 AliHelix *helixes = new AliHelix[nentries];
5037 Float_t *xm = new Float_t[nentries];
5038 Float_t *dz0 = new Float_t[nentries];
5039 Float_t *dz1 = new Float_t[nentries];
5040 //
5041 //
5042 TStopwatch timer;
5043 timer.Start();
5044 //
5045 // Find track COG in x direction - point with best defined parameters
5046 //
5047 for (Int_t i=0;i<nentries;i++){
5048 AliTPCseed* track = (AliTPCseed*)array->At(i);
5049 if (!track) continue;
5050 track->SetCircular(0);
5051 new (&helixes[i]) AliHelix(*track);
5052 Int_t ncl=0;
5053 xm[i]=0;
5054 Float_t dz[2];
5055 track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
5056 dz0[i]=dz[0];
5057 dz1[i]=dz[1];
5058 for (Int_t icl=0; icl<160; icl++){
5059 AliTPCclusterMI * cl = track->GetClusterPointer(icl);
5060 if (cl) {
5061 xm[i]+=cl->GetX();
5062 ncl++;
5063 }
5064 }
5065 if (ncl>0) xm[i]/=Float_t(ncl);
5066 }
6d493ea0 5067 //
5068 for (Int_t i0=0;i0<nentries;i0++){
5069 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5070 if (!track0) continue;
5071 Float_t xc0 = helixes[i0].GetHelix(6);
5072 Float_t yc0 = helixes[i0].GetHelix(7);
5073 Float_t r0 = helixes[i0].GetHelix(8);
5074 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
5075 Float_t fi0 = TMath::ATan2(yc0,xc0);
5076
5077 for (Int_t i1=i0+1;i1<nentries;i1++){
5078 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5079 if (!track1) continue;
5080 Int_t lab0=track0->GetLabel();
5081 Int_t lab1=track1->GetLabel();
5082 if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
5083 //
5084 Float_t xc1 = helixes[i1].GetHelix(6);
5085 Float_t yc1 = helixes[i1].GetHelix(7);
5086 Float_t r1 = helixes[i1].GetHelix(8);
5087 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
5088 Float_t fi1 = TMath::ATan2(yc1,xc1);
5089 //
5090 Float_t dfi = fi0-fi1;
5091 //
5092 //
5093 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
5094 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
5095 if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
5096 //
5097 // if short tracks with undefined sign
5098 fi1 = -TMath::ATan2(yc1,-xc1);
5099 dfi = fi0-fi1;
5100 }
5101 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
5102
5103 //
5104 // debug stream to tune "fast cuts"
5105 //
5106 Double_t dist[3]; // distance at X
5107 Double_t mdist[3]={0,0,0}; // mean distance X+-40cm
5108 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
5109 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
5110 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
5111 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
5112 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
5113 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
5114 for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
5115
5116 Float_t sum =0;
5117 Float_t sums=0;
5118 for (Int_t icl=0; icl<160; icl++){
5119 AliTPCclusterMI * cl0 = track0->GetClusterPointer(icl);
5120 AliTPCclusterMI * cl1 = track1->GetClusterPointer(icl);
5121 if (cl0&&cl1) {
5122 sum++;
5123 if (cl0==cl1) sums++;
5124 }
5125 }
5126 //
65e67c9c 5127 if ((AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC)>0) { // flag: stream MC infomation about the multiple find track (ONLY for MC data)
b194b32c 5128 TTreeSRedirector &cstream = *fDebugStreamer;
6d493ea0 5129 cstream<<"Multi"<<
5130 "iter="<<iter<<
5131 "lab0="<<lab0<<
5132 "lab1="<<lab1<<
5133 "Tr0.="<<track0<< // seed0
5134 "Tr1.="<<track1<< // seed1
5135 "h0.="<<&helixes[i0]<<
5136 "h1.="<<&helixes[i1]<<
5137 //
5138 "sum="<<sum<< //the sum of rows with cl in both
5139 "sums="<<sums<< //the sum of shared clusters
5140 "xm0="<<xm[i0]<< // the center of track
5141 "xm1="<<xm[i1]<< // the x center of track
5142 // General cut variables
5143 "dfi="<<dfi<< // distance in fi angle
5144 "dtheta="<<dtheta<< // distance int theta angle
5145 //
5146 "dz00="<<dz0[i0]<<
5147 "dz01="<<dz0[i1]<<
5148 "dz10="<<dz1[i1]<<
5149 "dz11="<<dz1[i1]<<
5150 "dist0="<<dist[0]<< //distance x
5151 "dist1="<<dist[1]<< //distance y
5152 "dist2="<<dist[2]<< //distance z
5153 "mdist0="<<mdist[0]<< //distance x
5154 "mdist1="<<mdist[1]<< //distance y
5155 "mdist2="<<mdist[2]<< //distance z
5156 //
5157 "r0="<<r0<<
5158 "rc0="<<rc0<<
5159 "fi0="<<fi0<<
5160 "fi1="<<fi1<<
5161 "r1="<<r1<<
5162 "rc1="<<rc1<<
5163 "\n";
b194b32c 5164 }
6d493ea0 5165 }
5166 }
5167 delete [] helixes;
5168 delete [] xm;
ec26e231 5169 delete [] dz0;
5170 delete [] dz1;
65e67c9c 5171 if (AliTPCReconstructor::StreamLevel()>0) {
6d493ea0 5172 AliInfo("Time for curling tracks removal DEBUGGING MC");
5173 timer.Print();
5174 }
5175}
5176
5177
1af5da7e 5178
829455ad 5179void AliTPCtracker::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t /*iter*/){
6d493ea0 5180 //
6fbe1e5c 5181 // Find Splitted tracks and remove the one with worst quality
5182 // Corresponding debug streamer to tune selections - "Splitted2"
5183 // Algorithm:
65e67c9c 5184 // 0. Sort tracks according quality
6fbe1e5c 5185 // 1. Propagate the tracks to the reference radius
5186 // 2. Double_t loop to select close tracks (only to speed up process)
5187 // 3. Calculate cluster overlap ratio - and remove the track if bigger than a threshold
5188 // 4. Delete temporary parameters
5189 //
5190 const Double_t xref=GetXrow(63); // reference radius -IROC/OROC boundary
5191 // rough cuts
5192 const Double_t kCutP1=10; // delta Z cut 10 cm
5193 const Double_t kCutP2=0.15; // delta snp(fi) cut 0.15
5194 const Double_t kCutP3=0.15; // delta tgl(theta) cut 0.15
5195 const Double_t kCutAlpha=0.15; // delta alpha cut
5196 Int_t firstpoint = 0;
5197 Int_t lastpoint = 160;
6d493ea0 5198 //
5199 Int_t nentries = array->GetEntriesFast();
6fbe1e5c 5200 AliExternalTrackParam *params = new AliExternalTrackParam[nentries];
6d493ea0 5201 //
5202 //
5203 TStopwatch timer;
5204 timer.Start();
5205 //
6fbe1e5c 5206 //0. Sort tracks according quality
5207 //1. Propagate the ext. param to reference radius
6d493ea0 5208 Int_t nseed = array->GetEntriesFast();
6e23caff 5209 if (nseed<=0) return;
6d493ea0 5210 Float_t * quality = new Float_t[nseed];
5211 Int_t * indexes = new Int_t[nseed];
5212 for (Int_t i=0; i<nseed; i++) {
5213 AliTPCseed *pt=(AliTPCseed*)array->UncheckedAt(i);
5214 if (!pt){
5215 quality[i]=-1;
5216 continue;
5217 }
5218 pt->UpdatePoints(); //select first last max dens points
5219 Float_t * points = pt->GetPoints();
5220 if (points[3]<0.8) quality[i] =-1;
5221 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
1af5da7e 5222 //prefer high momenta tracks if overlaps
5223 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
6fbe1e5c 5224 params[i]=(*pt);
5225 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),5.,kTRUE);
5226 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),1.,kTRUE);
6d493ea0 5227 }
5228 TMath::Sort(nseed,quality,indexes);
6d493ea0 5229 //
6fbe1e5c 5230 // 3. Loop over pair of tracks
5231 //
5232 for (Int_t i0=0; i0<nseed; i0++) {
5233 Int_t index0=indexes[i0];
5234 if (!(array->UncheckedAt(index0))) continue;
5235 AliTPCseed *s1 = (AliTPCseed*)array->UncheckedAt(index0);
5236 if (!s1->IsActive()) continue;
5237 AliExternalTrackParam &par0=params[index0];
5238 for (Int_t i1=i0+1; i1<nseed; i1++) {
5239 Int_t index1=indexes[i1];
5240 if (!(array->UncheckedAt(index1))) continue;
5241 AliTPCseed *s2 = (AliTPCseed*)array->UncheckedAt(index1);
5242 if (!s2->IsActive()) continue;
5243 if (s2->GetKinkIndexes()[0]!=0)
5244 if (s2->GetKinkIndexes()[0] == -s1->GetKinkIndexes()[0]) continue;
5245 AliExternalTrackParam &par1=params[index1];
5246 if (TMath::Abs(par0.GetParameter()[3]-par1.GetParameter()[3])>kCutP3) continue;
5247 if (TMath::Abs(par0.GetParameter()[1]-par1.GetParameter()[1])>kCutP1) continue;
5248 if (TMath::Abs(par0.GetParameter()[2]-par1.GetParameter()[2])>kCutP2) continue;
5249 Double_t dAlpha= TMath::Abs(par0.GetAlpha()-par1.GetAlpha());
5250 if (dAlpha>TMath::Pi()) dAlpha-=TMath::Pi();
5251 if (TMath::Abs(dAlpha)>kCutAlpha) continue;
6d493ea0 5252 //
6fbe1e5c 5253 Int_t sumShared=0;
5254 Int_t nall0=0;
5255 Int_t nall1=0;
5256 Int_t firstShared=lastpoint, lastShared=firstpoint;
5257 Int_t firstRow=lastpoint, lastRow=firstpoint;
6d493ea0 5258 //
6fbe1e5c 5259 for (Int_t i=firstpoint;i<lastpoint;i++){
5260 if (s1->GetClusterIndex2(i)>0) nall0++;
5261 if (s2->GetClusterIndex2(i)>0) nall1++;
5262 if (s1->GetClusterIndex2(i)>0 && s2->GetClusterIndex2(i)>0) {
5263 if (i<firstRow) firstRow=i;
5264 if (i>lastRow) lastRow=i;
5265 }
5266 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
5267 if (i<firstShared) firstShared=i;
5268 if (i>lastShared) lastShared=i;
5269 sumShared++;
5270 }
5271 }
5272 Double_t ratio0 = Float_t(sumShared)/Float_t(TMath::Min(nall0+1,nall1+1));
5273 Double_t ratio1 = Float_t(sumShared)/Float_t(TMath::Max(nall0+1,nall1+1));
5274
65e67c9c 5275 if ((AliTPCReconstructor::StreamLevel()&kStreamSplitted2)>0){ // flag:stream information about discarded TPC tracks pair algorithm
6fbe1e5c 5276 TTreeSRedirector &cstream = *fDebugStreamer;
5277 Int_t n0=s1->GetNumberOfClusters();
5278 Int_t n1=s2->GetNumberOfClusters();
5279 Int_t n0F=s1->GetNFoundable();
5280 Int_t n1F=s2->GetNFoundable();
5281 Int_t lab0=s1->GetLabel();
5282 Int_t lab1=s2->GetLabel();
5283
65e67c9c 5284 cstream<<"Splitted2"<< // flag:stream information about discarded TPC tracks pair algorithm
6fbe1e5c 5285 "iter="<<fIteration<<
5286 "lab0="<<lab0<< // MC label if exist
5287 "lab1="<<lab1<< // MC label if exist
5288 "index0="<<index0<<
5289 "index1="<<index1<<
5290 "ratio0="<<ratio0<< // shared ratio
5291 "ratio1="<<ratio1<< // shared ratio
5292 "p0.="<<&par0<< // track parameters
5293 "p1.="<<&par1<<
5294 "s0.="<<s1<< // full seed
5295 "s1.="<<s2<<
5296 "n0="<<n0<< // number of clusters track 0
5297 "n1="<<n1<< // number of clusters track 1
5298 "nall0="<<nall0<< // number of clusters track 0
5299 "nall1="<<nall1<< // number of clusters track 1
5300 "n0F="<<n0F<< // number of findable
5301 "n1F="<<n1F<< // number of findable
5302 "shared="<<sumShared<< // number of shared clusters
5303 "firstS="<<firstShared<< // first and the last shared row
5304 "lastS="<<lastShared<<
5305 "firstRow="<<firstRow<< // first and the last row with cluster
5306 "lastRow="<<lastRow<< //
5307 "\n";
6d493ea0 5308 }
6d493ea0 5309 //
6fbe1e5c 5310 // remove track with lower quality
6d493ea0 5311 //
6fbe1e5c 5312 if (ratio0>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(0) ||
5313 ratio1>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(1)){
5314 //
5315 //
5316 //
ddfbc51a 5317 MarkSeedFree( array->RemoveAt(index1) );
44adbd4b 5318 }
6d493ea0 5319 }
6fbe1e5c 5320 }
5321 //
5322 // 4. Delete temporary array
5323 //
5324 delete [] params;
6e23caff 5325 delete [] quality;
5326 delete [] indexes;
5327
6d493ea0 5328}
5329
5330
5331
829455ad 5332void AliTPCtracker::FindCurling(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
6d493ea0 5333{
5334 //
5335 // find Curling tracks
65e67c9c 5336 // Use AliTPCReconstructor::StreamLevel()&kStreamFindCurling if you want to tune parameters - cuts
6d493ea0 5337 //
5338 //
5339 // Algorithm done in 2 phases - because of CPU consumption
5340 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
5341 // see detal in MC part what can be used to cut
5342 //
5343 //
5344 //
5345 const Float_t kMaxC = 400; // maximal curvature to of the track
5346 const Float_t kMaxdTheta = 0.15; // maximal distance in theta
5347 const Float_t kMaxdPhi = 0.15; // maximal distance in phi
5348 const Float_t kPtRatio = 0.3; // ratio between pt
5349 const Float_t kMinDCAR = 2.; // distance to the primary vertex in r - see cpipe cut
5350
5351 //
5352 // Curling tracks cuts
5353 //
5354 //
5355 const Float_t kMaxDeltaRMax = 40; // distance in outer radius
5356 const Float_t kMaxDeltaRMin = 5.; // distance in lower radius - see cpipe cut
5357 const Float_t kMinAngle = 2.9; // angle between tracks
5358 const Float_t kMaxDist = 5; // biggest distance
5359 //
5360 // The cuts can be tuned using the "MC information stored in Multi tree ==> see FindMultiMC
5361 /*
5362 Fast cuts:
5363 TCut csign("csign","Tr0.fP[4]*Tr1.fP[4]<0"); //opposite sign
5364 TCut cmax("cmax","abs(Tr0.GetC())>1/400");
5365 TCut cda("cda","sqrt(dtheta^2+dfi^2)<0.15");
5366 TCut ccratio("ccratio","abs((Tr0.fP[4]+Tr1.fP[4])/(abs(Tr0.fP[4])+abs(Tr1.fP[4])))<0.3");
5367 TCut cpipe("cpipe", "min(abs(r0-rc0),abs(r1-rc1))>5");
5368 //
5369 TCut cdrmax("cdrmax","abs(abs(rc0+r0)-abs(rc1+r1))<40")
5370 TCut cdrmin("cdrmin","abs(abs(rc0+r0)-abs(rc1+r1))<10")
5371 //
5372 Multi->Draw("dfi","iter==0"+csign+cmax+cda+ccratio); ~94% of curling tracks fulfill
5373 Multi->Draw("min(abs(r0-rc0),abs(r1-rc1))","iter==0&&abs(lab1)==abs(lab0)"+csign+cmax+cda+ccratio+cpipe+cdrmin+cdrmax); //80%
5374 //
5375 Curling2->Draw("dfi","iter==0&&abs(lab0)==abs(lab1)"+csign+cmax+cdtheta+cdfi+ccratio)
5376
5377 */
5378 //
5379 //
5380 //
5381 Int_t nentries = array->GetEntriesFast();
5382 AliHelix *helixes = new AliHelix[nentries];
5383 for (Int_t i=0;i<nentries;i++){
5384 AliTPCseed* track = (AliTPCseed*)array->At(i);
5385 if (!track) continue;
5386 track->SetCircular(0);
5387 new (&helixes[i]) AliHelix(*track);
5388 }
5389 //
5390 //
5391 TStopwatch timer;
5392 timer.Start();
ec26e231 5393 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
5394
6d493ea0 5395 //
5396 // Find tracks
5397 //
6d493ea0 5398 //
5399 for (Int_t i0=0;i0<nentries;i0++){
5400 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5401 if (!track0) continue;
5402 if (TMath::Abs(track0->GetC())<1/kMaxC) continue;
5403 Float_t xc0 = helixes[i0].GetHelix(6);
5404 Float_t yc0 = helixes[i0].GetHelix(7);
5405 Float_t r0 = helixes[i0].GetHelix(8);
5406 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
5407 Float_t fi0 = TMath::ATan2(yc0,xc0);
5408
5409 for (Int_t i1=i0+1;i1<nentries;i1++){
5410 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5411 if (!track1) continue;
5412 if (TMath::Abs(track1->GetC())<1/kMaxC) continue;
5413 Float_t xc1 = helixes[i1].GetHelix(6);
5414 Float_t yc1 = helixes[i1].GetHelix(7);
5415 Float_t r1 = helixes[i1].GetHelix(8);
5416 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
5417 Float_t fi1 = TMath::ATan2(yc1,xc1);
5418 //
5419 Float_t dfi = fi0-fi1;
5420 //
5421 //
5422 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
5423 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
5424 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
5425 //
5426 //
5427 // FIRST fast cuts
5428 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue; // not constrained
5429 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue; // not the same sign
5430 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>kMaxdTheta) continue; //distance in the Theta
5431 if ( TMath::Abs(dfi)>kMaxdPhi) continue; //distance in phi
5432 if ( TMath::Sqrt(dfi*dfi+dtheta*dtheta)>kMaxdPhi) continue; //common angular offset
5433 //
5434 Float_t pt0 = track0->GetSignedPt();
5435 Float_t pt1 = track1->GetSignedPt();
5436 if ((TMath::Abs(pt0+pt1)/(TMath::Abs(pt0)+TMath::Abs(pt1)))>kPtRatio) continue;
5437 if ((iter==1) && TMath::Abs(TMath::Abs(rc0+r0)-TMath::Abs(rc1+r1))>kMaxDeltaRMax) continue;
5438 if ((iter!=1) &&TMath::Abs(TMath::Abs(rc0-r0)-TMath::Abs(rc1-r1))>kMaxDeltaRMin) continue;
5439 if (TMath::Min(TMath::Abs(rc0-r0),TMath::Abs(rc1-r1))<kMinDCAR) continue;
5440 //
5441 //
5442 // Now find closest approach
5443 //
5444 //
5445 //
5446 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5447 if (npoints==0) continue;
5448 helixes[i0].GetClosestPhases(helixes[i1], phase);
5449 //
5450 Double_t xyz0[3];
5451 Double_t xyz1[3];
5452 Double_t hangles[3];
5453 helixes[i0].Evaluate(phase[0][0],xyz0);
5454 helixes[i1].Evaluate(phase[0][1],xyz1);
5455
5456 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5457 Double_t deltah[2],deltabest;
5458 if (TMath::Abs(hangles[2])<kMinAngle) continue;
5459
5460 if (npoints>0){
5461 Int_t ibest=0;
5462 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
5463 if (npoints==2){
5464 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
5465 if (deltah[1]<deltah[0]) ibest=1;
5466 }
5467 deltabest = TMath::Sqrt(deltah[ibest]);
5468 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5469 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5470 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5471 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5472 //
5473 if (deltabest>kMaxDist) continue;
5474 // if (mindcar+mindcaz<40 && (TMath::Abs(hangles[2])<kMinAngle ||deltabest>3)) continue;
5475 Bool_t sign =kFALSE;
5476 if (hangles[2]>kMinAngle) sign =kTRUE;
5477 //
5478 if (sign){
5479 // circular[i0] = kTRUE;
5480 // circular[i1] = kTRUE;
5481 if (track0->OneOverPt()<track1->OneOverPt()){
5482 track0->SetCircular(track0->GetCircular()+1);
5483 track1->SetCircular(track1->GetCircular()+2);
5484 }
5485 else{
5486 track1->SetCircular(track1->GetCircular()+1);
5487 track0->SetCircular(track0->GetCircular()+2);
5488 }
5489 }
65e67c9c 5490 if ((AliTPCReconstructor::StreamLevel()&kStreamFindCurling)>0){ // flag: stream track infroamtion if the FindCurling tracks method
6d493ea0 5491 //
5492 //debug stream to tune "fine" cuts
5493 Int_t lab0=track0->GetLabel();
5494 Int_t lab1=track1->GetLabel();
b194b32c 5495 TTreeSRedirector &cstream = *fDebugStreamer;
6d493ea0 5496 cstream<<"Curling2"<<
5497 "iter="<<iter<<
5498 "lab0="<<lab0<<
5499 "lab1="<<lab1<<
5500 "Tr0.="<<track0<<
5501 "Tr1.="<<track1<<
5502 //
5503 "r0="<<r0<<
5504 "rc0="<<rc0<<
5505 "fi0="<<fi0<<
5506 "r1="<<r1<<
5507 "rc1="<<rc1<<
5508 "fi1="<<fi1<<
5509 "dfi="<<dfi<<
5510 "dtheta="<<dtheta<<
5511 //
5512 "npoints="<<npoints<<
5513 "hangles0="<<hangles[0]<<
5514 "hangles1="<<hangles[1]<<
5515 "hangles2="<<hangles[2]<<
5516 "xyz0="<<xyz0[2]<<
5517 "xyzz1="<<xyz1[2]<<
5518 "radius="<<radiusbest<<
5519 "deltabest="<<deltabest<<
5520 "phase0="<<phase[ibest][0]<<
5521 "phase1="<<phase[ibest][1]<<
5522 "\n";
5523
5524 }
5525 }
5526 }
5527 }
5528 delete [] helixes;
5529 if (AliTPCReconstructor::StreamLevel()>1) {
5530 AliInfo("Time for curling tracks removal");
5531 timer.Print();
5532 }
5533}
5534
5535
829455ad 5536void AliTPCtracker::FindKinks(TObjArray * array, AliESDEvent *esd)
51ad6848 5537{
5538 //
5539 // find kinks
5540 //
5541 //
f06a1ff6 5542 // RS something is wrong in this routine: not all seeds are assigned to daughters and mothers array, but they all are queried
5543 // to check later
ddfbc51a 5544
5545 TObjArray *kinks= new TObjArray(10000);
81e97e0d 5546 // TObjArray *v0s= new TObjArray(10000);
51ad6848 5547 Int_t nentries = array->GetEntriesFast();
ddfbc51a 5548 AliHelix *helixes = new AliHelix[nentries];
5549 Int_t *sign = new Int_t[nentries];
5550 Int_t *nclusters = new Int_t[nentries];
5551 Float_t *alpha = new Float_t[nentries];
5552 AliKink *kink = new AliKink();
5553 Int_t * usage = new Int_t[nentries];
5554 Float_t *zm = new Float_t[nentries];
5555 Float_t *z0 = new Float_t[nentries];
5556 Float_t *fim = new Float_t[nentries];
5557 Float_t *shared = new Float_t[nentries];
5558 Bool_t *circular = new Bool_t[nentries];
5559 Float_t *dca = new Float_t[nentries];
81e97e0d 5560 //const AliESDVertex * primvertex = esd->GetVertex();
eea478d3 5561 //
5562 // nentries = array->GetEntriesFast();
ddfbc51a 5563 //
5564
51ad6848 5565 //
5566 //
5567 for (Int_t i=0;i<nentries;i++){
5568 sign[i]=0;
5569 usage[i]=0;
5570 AliTPCseed* track = (AliTPCseed*)array->At(i);
5571 if (!track) continue;
b9671574 5572 track->SetCircular(0);
eea478d3 5573 shared[i] = kFALSE;
51ad6848 5574 track->UpdatePoints();
5575 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
51ad6848 5576 }
eea478d3 5577 nclusters[i]=track->GetNumberOfClusters();
5578 alpha[i] = track->GetAlpha();
5579 new (&helixes[i]) AliHelix(*track);
5580 Double_t xyz[3];
5581 helixes[i].Evaluate(0,xyz);
5582 sign[i] = (track->GetC()>0) ? -1:1;
5583 Double_t x,y,z;
5584 x=160;
5585 if (track->GetProlongation(x,y,z)){
5586 zm[i] = z;
5587 fim[i] = alpha[i]+TMath::ATan2(y,x);
5588 }
5589 else{
5590 zm[i] = track->GetZ();
5591 fim[i] = alpha[i];
5592 }
5593 z0[i]=1000;
5594 circular[i]= kFALSE;
81e97e0d 5595 if (track->GetProlongation(0,y,z)) z0[i] = z;
5596 dca[i] = track->GetD(0,0);
51ad6848 5597 }
5598 //
5599 //
5600 TStopwatch timer;
5601 timer.Start();
5602 Int_t ncandidates =0;
5603 Int_t nall =0;
5604 Int_t ntracks=0;
ec26e231 5605 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
eea478d3 5606
5607 //
5608 // Find circling track
eea478d3 5609 //
5610 for (Int_t i0=0;i0<nentries;i0++){
5611 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5612 if (!track0) continue;
b9671574 5613 if (track0->GetNumberOfClusters()<40) continue;
6c94f330 5614 if (TMath::Abs(1./track0->GetC())>200) continue;
eea478d3 5615 for (Int_t i1=i0+1;i1<nentries;i1++){
5616 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5617 if (!track1) continue;
b9671574 5618 if (track1->GetNumberOfClusters()<40) continue;
6c94f330 5619 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
b9671574 5620 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
6c94f330 5621 if (TMath::Abs(1./track1->GetC())>200) continue;
8467b758 5622 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
6c94f330 5623 if (track1->GetTgl()*track0->GetTgl()>0) continue;
1b36647b 5624 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
8467b758 5625 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
5626 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
eea478d3 5627 //
81e97e0d 5628 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
5629 if (mindcar<5) continue;
5630 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
5631 if (mindcaz<5) continue;
5632 if (mindcar+mindcaz<20) continue;
5633 //
5634 //
eea478d3 5635 Float_t xc0 = helixes[i0].GetHelix(6);
5636 Float_t yc0 = helixes[i0].GetHelix(7);
5637 Float_t r0 = helixes[i0].GetHelix(8);
5638 Float_t xc1 = helixes[i1].GetHelix(6);
5639 Float_t yc1 = helixes[i1].GetHelix(7);
5640 Float_t r1 = helixes[i1].GetHelix(8);
5641
5642 Float_t rmean = (r0+r1)*0.5;
5643 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
81e97e0d 5644 //if (delta>30) continue;
eea478d3 5645 if (delta>rmean*0.25) continue;
5646 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
5647 //
5648 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5649 if (npoints==0) continue;
5650 helixes[i0].GetClosestPhases(helixes[i1], phase);
5651 //
5652 Double_t xyz0[3];
5653 Double_t xyz1[3];
5654 Double_t hangles[3];
5655 helixes[i0].Evaluate(phase[0][0],xyz0);
5656 helixes[i1].Evaluate(phase[0][1],xyz1);
5657
5658 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5659 Double_t deltah[2],deltabest;
5660 if (hangles[2]<2.8) continue;
eea478d3 5661 if (npoints>0){
5662 Int_t ibest=0;
81e97e0d 5663 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
eea478d3 5664 if (npoints==2){
81e97e0d 5665 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
eea478d3 5666 if (deltah[1]<deltah[0]) ibest=1;
5667 }
5668 deltabest = TMath::Sqrt(deltah[ibest]);
5669 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5670 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5671 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
81e97e0d 5672 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
eea478d3 5673 //
81e97e0d 5674 if (deltabest>6) continue;
5675 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
77f88633 5676 Bool_t lsign =kFALSE;
5677 if (hangles[2]>3.06) lsign =kTRUE;
81e97e0d 5678 //
77f88633 5679 if (lsign){
eea478d3 5680 circular[i0] = kTRUE;
81e97e0d 5681 circular[i1] = kTRUE;
8467b758 5682 if (track0->OneOverPt()<track1->OneOverPt()){
b9671574 5683 track0->SetCircular(track0->GetCircular()+1);
5684 track1->SetCircular(track1->GetCircular()+2);
81e97e0d 5685 }
5686 else{
b9671574 5687 track1->SetCircular(track1->GetCircular()+1);
5688 track0->SetCircular(track0->GetCircular()+2);
81e97e0d 5689 }
5690 }
65e67c9c 5691 if (lsign&&((AliTPCReconstructor::StreamLevel()&kStreamFindCurling)>0)){
34acb742 5692 //debug stream
b9671574 5693 Int_t lab0=track0->GetLabel();
5694 Int_t lab1=track1->GetLabel();
b194b32c 5695 TTreeSRedirector &cstream = *fDebugStreamer;
81e97e0d 5696 cstream<<"Curling"<<
b9671574 5697 "lab0="<<lab0<<
5698 "lab1="<<lab1<<
81e97e0d 5699 "Tr0.="<<track0<<
5700 "Tr1.="<<track1<<
5701 "dca0="<<dca[i0]<<
5702 "dca1="<<dca[i1]<<
5703 "mindcar="<<mindcar<<
5704 "mindcaz="<<mindcaz<<
5705 "delta="<<delta<<
5706 "rmean="<<rmean<<
5707 "npoints="<<npoints<<
5708 "hangles0="<<hangles[0]<<
5709 "hangles2="<<hangles[2]<<
5710 "xyz0="<<xyz0[2]<<
5711 "xyzz1="<<xyz1[2]<<
5712 "z0="<<z0[i0]<<
5713 "z1="<<z0[i1]<<
5714 "radius="<<radiusbest<<
5715 "deltabest="<<deltabest<<
5716 "phase0="<<phase[ibest][0]<<
5717 "phase1="<<phase[ibest][1]<<
5718 "\n";
eea478d3 5719 }
5720 }
5721 }
5722 }
5723 //
ddfbc51a 5724 // Finf kinks loop
81e97e0d 5725 //
51ad6848 5726 //
5727 for (Int_t i =0;i<nentries;i++){
5728 if (sign[i]==0) continue;
5729 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
c1ea348f 5730 if (track0==0) {
5731 AliInfo("seed==0");
5732 continue;
5733 }
51ad6848 5734 ntracks++;
5735 //
5736 Double_t cradius0 = 40*40;
5737 Double_t cradius1 = 270*270;
5738 Double_t cdist1=8.;
5739 Double_t cdist2=8.;
5740 Double_t cdist3=0.55;
5741 for (Int_t j =i+1;j<nentries;j++){
5742 nall++;
5743 if (sign[j]*sign[i]<1) continue;
5744 if ( (nclusters[i]+nclusters[j])>200) continue;
5745 if ( (nclusters[i]+nclusters[j])<80) continue;
5746 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
5747 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
5748 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
5749 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5750 if (npoints<1) continue;
5751 // cuts on radius
5752 if (npoints==1){
5753 if (radius[0]<cradius0||radius[0]>cradius1) continue;
5754 }
5755 else{
5756 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
5757 }
5758 //
5759 Double_t delta1=10000,delta2=10000;
5760 // cuts on the intersection radius
5761 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5762 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5763 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5764 if (npoints==2){
5765 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5766 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5767 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5768 }
5769 //
5770 Double_t distance1 = TMath::Min(delta1,delta2);
5771 if (distance1>cdist1) continue; // cut on DCA linear approximation
5772 //
5773 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5774 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5775 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5776 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5777 //
5778 if (npoints==2){
5779 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5780 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5781 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5782 }
5783 distance1 = TMath::Min(delta1,delta2);
5784 Float_t rkink =0;
5785 if (delta1<delta2){
5786 rkink = TMath::Sqrt(radius[0]);
5787 }
5788 else{
5789 rkink = TMath::Sqrt(radius[1]);
5790 }
5791 if (distance1>cdist2) continue;
5792 //
5793 //
5794 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5795 //
5796 //
5797 Int_t row0 = GetRowNumber(rkink);
5798 if (row0<10) continue;
5799 if (row0>150) continue;
5800 //
5801 //
5802 Float_t dens00=-1,dens01=-1;
5803 Float_t dens10=-1,dens11=-1;
5804 //
77f88633 5805 Int_t found,foundable,ishared;
5806 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
51ad6848 5807 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
77f88633 5808 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
51ad6848 5809 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
5810 //
77f88633 5811 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
51ad6848 5812 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
77f88633 5813 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
51ad6848 5814 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
eea478d3 5815 //
51ad6848 5816 if (dens00<dens10 && dens01<dens11) continue;
5817 if (dens00>dens10 && dens01>dens11) continue;
5818 if (TMath::Max(dens00,dens10)<0.1) continue;
5819 if (TMath::Max(dens01,dens11)<0.3) continue;
5820 //
5821 if (TMath::Min(dens00,dens10)>0.6) continue;
5822 if (TMath::Min(dens01,dens11)>0.6) continue;
5823
5824 //
5825 AliTPCseed * ktrack0, *ktrack1;
5826 if (dens00>dens10){
5827 ktrack0 = track0;
5828 ktrack1 = track1;
5829 }
5830 else{
5831 ktrack0 = track1;
5832 ktrack1 = track0;
5833 }
5834 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
5835 AliExternalTrackParam paramm(*ktrack0);
5836 AliExternalTrackParam paramd(*ktrack1);
316c6cd9 5837 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
51ad6848 5838 //
5839 //
5840 kink->SetMother(paramm);
5841 kink->SetDaughter(paramd);
5842 kink->Update();
5843
2942f542 5844 Float_t x[3] = { static_cast<Float_t>(kink->GetPosition()[0]),static_cast<Float_t>(kink->GetPosition()[1]),static_cast<Float_t>(kink->GetPosition()[2])};
51ad6848 5845 Int_t index[4];
47af7ca4 5846 fkParam->Transform0to1(x,index);
5847 fkParam->Transform1to2(x,index);
51ad6848 5848 row0 = GetRowNumber(x[0]);
5849
eea478d3 5850 if (kink->GetR()<100) continue;
5851 if (kink->GetR()>240) continue;
5852 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
5853 if (kink->GetDistance()>cdist3) continue;
5854 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
51ad6848 5855 if (dird<0) continue;
5856
eea478d3 5857 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
51ad6848 5858 if (dirm<0) continue;
eea478d3 5859 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
51ad6848 5860 if (mpt<0.2) continue;
5861
eea478d3 5862 if (mpt<1){
5863 //for high momenta momentum not defined well in first iteration
6c94f330 5864 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
eea478d3 5865 if (qt>0.35) continue;
5866 }
51ad6848 5867
eea478d3 5868 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
5869 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
51ad6848 5870 if (dens00>dens10){
eea478d3 5871 kink->SetTPCDensity(dens00,0,0);
5872 kink->SetTPCDensity(dens01,0,1);
5873 kink->SetTPCDensity(dens10,1,0);
5874 kink->SetTPCDensity(dens11,1,1);
5875 kink->SetIndex(i,0);
5876 kink->SetIndex(j,1);
51ad6848 5877 }
5878 else{
eea478d3 5879 kink->SetTPCDensity(dens10,0,0);
5880 kink->SetTPCDensity(dens11,0,1);
5881 kink->SetTPCDensity(dens00,1,0);
5882 kink->SetTPCDensity(dens01,1,1);
5883 kink->SetIndex(j,0);
5884 kink->SetIndex(i,1);
51ad6848 5885 }
51ad6848 5886
eea478d3 5887 if (mpt<1||kink->GetAngle(2)>0.1){
5888 // angle and densities not defined yet
5889 if (kink->GetTPCDensityFactor()<0.8) continue;
5890 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
6c94f330 5891 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
eea478d3 5892 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5893 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5894
6c94f330 5895 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5896 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
eea478d3 5897 criticalangle= 3*TMath::Sqrt(criticalangle);
5898 if (criticalangle>0.02) criticalangle=0.02;
5899 if (kink->GetAngle(2)<criticalangle) continue;
5900 }
51ad6848 5901 //
eea478d3 5902 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
51ad6848 5903 Float_t shapesum =0;
5904 Float_t sum = 0;
5905 for ( Int_t row = row0-drow; row<row0+drow;row++){
5906 if (row<0) continue;
5907 if (row>155) continue;
b9671574 5908 if (ktrack0->GetClusterPointer(row)){
51ad6848 5909 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5910 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5911 sum++;
5912 }
b9671574 5913 if (ktrack1->GetClusterPointer(row)){
51ad6848 5914 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5915 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5916 sum++;
5917 }
5918 }
5919 if (sum<4){
eea478d3 5920 kink->SetShapeFactor(-1.);
51ad6848 5921 }
5922 else{
eea478d3 5923 kink->SetShapeFactor(shapesum/sum);
5924 }
51ad6848 5925 // esd->AddKink(kink);
16299eac 5926 //
5927 // kink->SetMother(paramm);
5928 //kink->SetDaughter(paramd);
5929
5930 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
5931 chi2P2*=chi2P2;
5932 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
5933 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
5934 chi2P3*=chi2P3;
5935 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
5936 //
65e67c9c 5937 if ((AliTPCReconstructor::StreamLevel()&kStreamFindKinks)>0) { // flag: stream track infroamtion in the FindKinks method
16299eac 5938 (*fDebugStreamer)<<"kinkLpt"<<
5939 "chi2P2="<<chi2P2<<
5940 "chi2P3="<<chi2P3<<
5941 "p0.="<<&paramm<<
5942 "p1.="<<&paramd<<
5943 "k.="<<kink<<
5944 "\n";
5945 }
5946 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
5947 continue;
5948 }
5949 //
ddfbc51a 5950 kinks->AddLast(kink);
5951 kink = new AliKink;
51ad6848 5952 ncandidates++;
5953 }
5954 }
ddfbc51a 5955 //
eea478d3 5956 // sort the kinks according quality - and refit them towards vertex
5957 //
ddfbc51a 5958 Int_t nkinks = kinks->GetEntriesFast();
5959 Float_t *quality = new Float_t[nkinks];
5960 Int_t *indexes = new Int_t[nkinks];
5961 AliTPCseed *mothers = new AliTPCseed[nkinks];
5962 AliTPCseed *daughters = new AliTPCseed[nkinks];
eea478d3 5963 //
5964 //
51ad6848 5965 for (Int_t i=0;i<nkinks;i++){
5966 quality[i] =100000;
ddfbc51a 5967 AliKink *kinkl = (AliKink*)kinks->At(i);
eea478d3 5968 //
5969 // refit kinks towards vertex
5970 //
77f88633 5971 Int_t index0 = kinkl->GetIndex(0);
5972 Int_t index1 = kinkl->GetIndex(1);
eea478d3 5973 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5974 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5975 //
b9671574 5976 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
eea478d3 5977 //
5978 // Refit Kink under if too small angle
5979 //
77f88633 5980 if (kinkl->GetAngle(2)<0.05){
5981 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5982 Int_t row0 = kinkl->GetTPCRow0();
5983 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
eea478d3 5984 //
5985 //
5986 Int_t last = row0-drow;
5987 if (last<40) last=40;
b9671574 5988 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
eea478d3 5989 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
5990 //
5991 //
5992 Int_t first = row0+drow;
5993 if (first>130) first=130;
b9671574 5994 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
eea478d3 5995 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
5996 //
ddfbc51a 5997 if (seed0 && seed1){
77f88633 5998 kinkl->SetStatus(1,8);
5999 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
6000 row0 = GetRowNumber(kinkl->GetR());
b9671574 6001 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
ddfbc51a 6002 mothers[i] = *seed0;
6003 daughters[i] = *seed1;
eea478d3 6004 }
ddfbc51a 6005 else{
6006 delete kinks->RemoveAt(i);
6007 if (seed0) MarkSeedFree( seed0 );
6008 if (seed1) MarkSeedFree( seed1 );
eea478d3 6009 continue;
6010 }
77f88633 6011 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
ddfbc51a 6012 delete kinks->RemoveAt(i);
6013 if (seed0) MarkSeedFree( seed0 );
6014 if (seed1) MarkSeedFree( seed1 );
eea478d3 6015 continue;
6016 }
ddfbc51a 6017 //
6018 MarkSeedFree( seed0 );
6019 MarkSeedFree( seed1 );
eea478d3 6020 }
6021 //
77f88633 6022 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
51ad6848 6023 }
6024 TMath::Sort(nkinks,quality,indexes,kFALSE);
eea478d3 6025 //
6026 //remove double find kinks
6027 //
6028 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
ddfbc51a 6029 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
eea478d3 6030 if (!kink0) continue;
6031 //
6a6ba9a2 6032 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
ddfbc51a 6033 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6034 if (!kink0) continue;
6035 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
eea478d3 6036 if (!kink1) continue;
6037 // if not close kink continue
6038 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
6039 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
6040 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
6041 //
ddfbc51a 6042 AliTPCseed &mother0 = mothers[indexes[ikink0]];
6043 AliTPCseed &daughter0 = daughters[indexes[ikink0]];
6044 AliTPCseed &mother1 = mothers[indexes[ikink1]];
6045 AliTPCseed &daughter1 = daughters[indexes[ikink1]];
eea478d3 6046 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
6047 //
6048 Int_t same = 0;
6049 Int_t both = 0;
6050 Int_t samem = 0;
6051 Int_t bothm = 0;
6052 Int_t samed = 0;
6053 Int_t bothd = 0;
6054 //
6055 for (Int_t i=0;i<row0;i++){
ddfbc51a 6056 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
eea478d3 6057 both++;
6058 bothm++;
ddfbc51a 6059 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
eea478d3 6060 same++;
6061 samem++;
6062 }
6063 }
6064 }
6065
6066 for (Int_t i=row0;i<158;i++){
f06a1ff6 6067 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
ddfbc51a 6068 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
eea478d3 6069 both++;
6070 bothd++;
ddfbc51a 6071 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
eea478d3 6072 same++;
6073 samed++;
6074 }
6075 }
6076 }
6077 Float_t ratio = Float_t(same+1)/Float_t(both+1);
6078 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
6079 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
6080 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
ddfbc51a 6081 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
6082 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
eea478d3 6083 if (sum1>sum0){
6084 shared[kink0->GetIndex(0)]= kTRUE;
6085 shared[kink0->GetIndex(1)]= kTRUE;
ddfbc51a 6086 delete kinks->RemoveAt(indexes[ikink0]);
b3659bad 6087 break;
eea478d3 6088 }
6089 else{
6090 shared[kink1->GetIndex(0)]= kTRUE;
6091 shared[kink1->GetIndex(1)]= kTRUE;
ddfbc51a 6092 delete kinks->RemoveAt(indexes[ikink1]);
eea478d3 6093 }
6094 }
6095 }
6096 }
6097
6098
51ad6848 6099 for (Int_t i=0;i<nkinks;i++){
ddfbc51a 6100 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
77f88633 6101 if (!kinkl) continue;
6102 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6103 Int_t index0 = kinkl->GetIndex(0);
6104 Int_t index1 = kinkl->GetIndex(1);
6105 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
6106 kinkl->SetMultiple(usage[index0],0);
6107 kinkl->SetMultiple(usage[index1],1);
6108 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
6109 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
6110 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
6111 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
51ad6848 6112
51ad6848 6113 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6114 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
eea478d3 6115 if (!ktrack0 || !ktrack1) continue;
77f88633 6116 Int_t index = esd->AddKink(kinkl);
eea478d3 6117 //
6118 //
b9671574 6119 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
ddfbc51a 6120 if (mothers[indexes[i]].GetNumberOfClusters()>20 && daughters[indexes[i]].GetNumberOfClusters()>20 && (mothers[indexes[i]].GetNumberOfClusters()+daughters[indexes[i]].GetNumberOfClusters())>100){
6121 *ktrack0 = mothers[indexes[i]];
6122 *ktrack1 = daughters[indexes[i]];
eea478d3 6123 }
6124 }
6125 //
b9671574 6126 ktrack0->SetKinkIndex(usage[index0],-(index+1));
6127 ktrack1->SetKinkIndex(usage[index1], (index+1));
51ad6848 6128 usage[index0]++;
6129 usage[index1]++;
6130 }
eea478d3 6131 //
6132 // Remove tracks corresponding to shared kink's
6133 //
6134 for (Int_t i=0;i<nentries;i++){
6135 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6136 if (!track0) continue;
b9671574 6137 if (track0->GetKinkIndex(0)!=0) continue;
ddfbc51a 6138 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
eea478d3 6139 }
ddfbc51a 6140
eea478d3 6141 //
6142 //
6143 RemoveUsed2(array,0.5,0.4,30);
6144 UnsignClusters();
81e97e0d 6145 for (Int_t i=0;i<nentries;i++){
6146 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6147 if (!track0) continue;
6148 track0->CookdEdx(0.02,0.6);
6149 track0->CookPID();
6150 }
eea478d3 6151 //
6152 for (Int_t i=0;i<nentries;i++){
6153 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6154 if (!track0) continue;
8467b758 6155 if (track0->Pt()<1.4) continue;
eea478d3 6156 //remove double high momenta tracks - overlapped with kink candidates
77f88633 6157 Int_t ishared=0;
eea478d3 6158 Int_t all =0;
b9671574 6159 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
6160 if (track0->GetClusterPointer(icl)!=0){
eea478d3 6161 all++;
77f88633 6162 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
eea478d3 6163 }
6164 }
77f88633 6165 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
ddfbc51a 6166 MarkSeedFree( array->RemoveAt(i) );
f99dc368 6167 continue;
eea478d3 6168 }
6169 //
b9671574 6170 if (track0->GetKinkIndex(0)!=0) continue;
eea478d3 6171 if (track0->GetNumberOfClusters()<80) continue;
4a12af72 6172
ddfbc51a 6173 AliTPCseed *pmother = new AliTPCseed();
6174 AliTPCseed *pdaughter = new AliTPCseed();
6175 AliKink *pkink = new AliKink;
6176
4a12af72 6177 AliTPCseed & mother = *pmother;
6178 AliTPCseed & daughter = *pdaughter;
77f88633 6179 AliKink & kinkl = *pkink;
6180 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
b9671574 6181 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
ddfbc51a 6182 delete pmother;
6183 delete pdaughter;
6184 delete pkink;
4a12af72 6185 continue; //too short tracks
6186 }
8467b758 6187 if (mother.Pt()<1.4) {
ddfbc51a 6188 delete pmother;
6189 delete pdaughter;
6190 delete pkink;
4a12af72 6191 continue;
6192 }
77f88633 6193 Int_t row0= kinkl.GetTPCRow0();
6194 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
ddfbc51a 6195 delete pmother;
6196 delete pdaughter;
6197 delete pkink;
eea478d3 6198 continue;
6199 }
6200 //
77f88633 6201 Int_t index = esd->AddKink(&kinkl);
b9671574 6202 mother.SetKinkIndex(0,-(index+1));
6203 daughter.SetKinkIndex(0,index+1);
6204 if (mother.GetNumberOfClusters()>50) {
ddfbc51a 6205 MarkSeedFree( array->RemoveAt(i) );
6206 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6207 mtc->SetPoolID(fLastSeedID);
f06a1ff6 6208 array->AddAt(mtc,i);
eea478d3 6209 }
6210 else{
ddfbc51a 6211 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6212 mtc->SetPoolID(fLastSeedID);
f06a1ff6 6213 array->AddLast(mtc);
eea478d3 6214 }
ddfbc51a 6215 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
6216 dtc->SetPoolID(fLastSeedID);
f06a1ff6 6217 array->AddLast(dtc);
eea478d3 6218 for (Int_t icl=0;icl<row0;icl++) {
b9671574 6219 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
eea478d3 6220 }
6221 //
6222 for (Int_t icl=row0;icl<158;icl++) {
b9671574 6223 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
eea478d3 6224 }
6225 //
6226 }
ddfbc51a 6227 delete pmother;
6228 delete pdaughter;
6229 delete pkink;
eea478d3 6230 }
ddfbc51a 6231
6232 delete [] daughters;
6233 delete [] mothers;
eea478d3 6234 //
eea478d3 6235 //
ddfbc51a 6236 delete [] dca;
6237 delete []circular;
6238 delete []shared;
6239 delete []quality;
6240 delete []indexes;
6241 //
6242 delete kink;
6243 delete[]fim;
6244 delete[] zm;
6245 delete[] z0;
6246 delete [] usage;
6247 delete[] alpha;
6248 delete[] nclusters;
6249 delete[] sign;
bfa00fba 6250 delete[] helixes;
ddfbc51a 6251 kinks->Delete();
6252 delete kinks;
6253
7b9ce4fd 6254 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
51ad6848 6255 timer.Print();
6256}
6257
81e97e0d 6258
ddfbc51a 6259/*
829455ad 6260void AliTPCtracker::FindKinks(TObjArray * array, AliESDEvent *esd)
eea478d3 6261{
6262 //
ddfbc51a 6263 // find kinks
eea478d3 6264 //
6265 //
6c94f330 6266
ddfbc51a 6267 TObjArray *kinks= new TObjArray(10000);
6268 // TObjArray *v0s= new TObjArray(10000);
6269 Int_t nentries = array->GetEntriesFast();
6270 AliHelix *helixes = new AliHelix[nentries];
6271 Int_t *sign = new Int_t[nentries];
6272 Int_t *nclusters = new Int_t[nentries];
6273 Float_t *alpha = new Float_t[nentries];
6274 AliKink *kink = new AliKink();
6275 Int_t * usage = new Int_t[nentries];
6276 Float_t *zm = new Float_t[nentries];
6277 Float_t *z0 = new Float_t[nentries];
6278 Float_t *fim = new Float_t[nentries];
6279 Float_t *shared = new Float_t[nentries];
6280 Bool_t *circular = new Bool_t[nentries];
6281 Float_t *dca = new Float_t[nentries];
6282 //const AliESDVertex * primvertex = esd->GetVertex();
eea478d3 6283 //
ddfbc51a 6284 // nentries = array->GetEntriesFast();
eea478d3 6285 //
ddfbc51a 6286
e546b023 6287 //
e546b023 6288 //
ddfbc51a 6289 for (Int_t i=0;i<nentries;i++){
6290 sign[i]=0;
6291 usage[i]=0;
6292 AliTPCseed* track = (AliTPCseed*)array->At(i);
6293 if (!track) continue;
6294 track->SetCircular(0);
6295 shared[i] = kFALSE;
6296 track->UpdatePoints();
6297 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
6298 }
6299 nclusters[i]=track->GetNumberOfClusters();
6300 alpha[i] = track->GetAlpha();
6301 new (&helixes[i]) AliHelix(*track);
6302 Double_t xyz[3];
6303 helixes[i].Evaluate(0,xyz);
6304 sign[i] = (track->GetC()>0) ? -1:1;
6305 Double_t x,y,z;
6306 x=160;
6307 if (track->GetProlongation(x,y,z)){
6308 zm[i] = z;
6309 fim[i] = alpha[i]+TMath::ATan2(y,x);
eea478d3 6310 }
ddfbc51a 6311 else{
6312 zm[i] = track->GetZ();
6313 fim[i] = alpha[i];
6314 }
6315 z0[i]=1000;
6316 circular[i]= kFALSE;
6317 if (track->GetProlongation(0,y,z)) z0[i] = z;
6318 dca[i] = track->GetD(0,0);
eea478d3 6319 }
6320 //
eea478d3 6321 //
ddfbc51a 6322 TStopwatch timer;
6323 timer.Start();
6324 Int_t ncandidates =0;
6325 Int_t nall =0;
6326 Int_t ntracks=0;
6327 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
6328
eea478d3 6329 //
ddfbc51a 6330 // Find circling track
e546b023 6331 //
ddfbc51a 6332 for (Int_t i0=0;i0<nentries;i0++){
6333 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
6334 if (!track0) continue;
6335 if (track0->GetNumberOfClusters()<40) continue;
6336 if (TMath::Abs(1./track0->GetC())>200) continue;
6337 for (Int_t i1=i0+1;i1<nentries;i1++){
6338 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
6339 if (!track1) continue;
6340 if (track1->GetNumberOfClusters()<40) continue;
6341 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
6342 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
6343 if (TMath::Abs(1./track1->GetC())>200) continue;
6344 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
6345 if (track1->GetTgl()*track0->GetTgl()>0) continue;
6346 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
6347 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
6348 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
6349 //
6350 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
6351 if (mindcar<5) continue;
6352 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
6353 if (mindcaz<5) continue;
6354 if (mindcar+mindcaz<20) continue;
6355 //
6356 //
6357 Float_t xc0 = helixes[i0].GetHelix(6);
6358 Float_t yc0 = helixes[i0].GetHelix(7);
6359 Float_t r0 = helixes[i0].GetHelix(8);
6360 Float_t xc1 = helixes[i1].GetHelix(6);
6361 Float_t yc1 = helixes[i1].GetHelix(7);
6362 Float_t r1 = helixes[i1].GetHelix(8);
6363
6364 Float_t rmean = (r0+r1)*0.5;
6365 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
6366 //if (delta>30) continue;
6367 if (delta>rmean*0.25) continue;
6368 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
6369 //
6370 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
6371 if (npoints==0) continue;
6372 helixes[i0].GetClosestPhases(helixes[i1], phase);
6373 //
6374 Double_t xyz0[3];
6375 Double_t xyz1[3];
6376 Double_t hangles[3];
6377 helixes[i0].Evaluate(phase[0][0],xyz0);
6378 helixes[i1].Evaluate(phase[0][1],xyz1);
e546b023 6379
ddfbc51a 6380 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
6381 Double_t deltah[2],deltabest;
6382 if (hangles[2]<2.8) continue;
6383 if (npoints>0){
6384 Int_t ibest=0;
6385 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
6386 if (npoints==2){
6387 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
6388 if (deltah[1]<deltah[0]) ibest=1;
6389 }
6390 deltabest = TMath::Sqrt(deltah[ibest]);
6391 helixes[i0].Evaluate(phase[ibest][0],xyz0);
6392 helixes[i1].Evaluate(phase[ibest][1],xyz1);
6393 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
6394 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
6395 //
6396 if (deltabest>6) continue;
6397 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
6398 Bool_t lsign =kFALSE;
6399 if (hangles[2]>3.06) lsign =kTRUE;
6400 //
6401 if (lsign){
6402 circular[i0] = kTRUE;
6403 circular[i1] = kTRUE;
6404 if (track0->OneOverPt()<track1->OneOverPt()){
6405 track0->SetCircular(track0->GetCircular()+1);
6406 track1->SetCircular(track1->GetCircular()+2);
6407 }
6408 else{
6409 track1->SetCircular(track1->GetCircular()+1);
6410 track0->SetCircular(track0->GetCircular()+2);
6411 }
6412 }
65e67c9c 6413 if (lsign&&((AliTPCReconstructor::StreamLevel()&kStreamFindKinks)>0)){// flag: stream track infroamtion in the FindKinks method
ddfbc51a 6414 //debug stream
6415 Int_t lab0=track0->GetLabel();
6416 Int_t lab1=track1->GetLabel();
6417 TTreeSRedirector &cstream = *fDebugStreamer;
6418 cstream<<"Curling"<<
6419 "lab0="<<lab0<<
6420 "lab1="<<lab1<<
6421 "Tr0.="<<track0<<
6422 "Tr1.="<<track1<<
6423 "dca0="<<dca[i0]<<
6424 "dca1="<<dca[i1]<<
6425 "mindcar="<<mindcar<<
6426 "mindcaz="<<mindcaz<<
6427 "delta="<<delta<<
6428 "rmean="<<rmean<<
6429 "npoints="<<npoints<<
6430 "hangles0="<<hangles[0]<<
6431 "hangles2="<<hangles[2]<<
6432 "xyz0="<<xyz0[2]<<
6433 "xyzz1="<<xyz1[2]<<
6434 "z0="<<z0[i0]<<
6435 "z1="<<z0[i1]<<
6436 "radius="<<radiusbest<<
6437 "deltabest="<<deltabest<<
6438 "phase0="<<phase[ibest][0]<<
6439 "phase1="<<phase[ibest][1]<<
6440 "\n";
6441 }
6442 }
6443 }
6444 }
51ad6848 6445 //
ddfbc51a 6446 // Finf kinks loop
6447 //
f06a1ff6 6448 //
ddfbc51a 6449 for (Int_t i =0;i<nentries;i++){
6450 if (sign[i]==0) continue;
6451 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6452 if (track0==0) {
6453 AliInfo("seed==0");
6454 continue;
6455 }
6456 ntracks++;
6457 //
6458 Double_t cradius0 = 40*40;
6459 Double_t cradius1 = 270*270;
6460 Double_t cdist1=8.;
6461 Double_t cdist2=8.;
6462 Double_t cdist3=0.55;
6463 for (Int_t j =i+1;j<nentries;j++){
6464 nall++;
6465 if (sign[j]*sign[i]<1) continue;
6466 if ( (nclusters[i]+nclusters[j])>200) continue;
6467 if ( (nclusters[i]+nclusters[j])<80) continue;
6468 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
6469 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
6470 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
6471 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
6472 if (npoints<1) continue;
6473 // cuts on radius
6474 if (npoints==1){
6475 if (radius[0]<cradius0||radius[0]>cradius1) continue;
6476 }
6477 else{
6478 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
6479 }
6480 //
6481 Double_t delta1=10000,delta2=10000;
6482 // cuts on the intersection radius
6483 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
6484 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
6485 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
6486 if (npoints==2){
6487 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
6488 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
6489 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
6490 }
6491 //
6492 Double_t distance1 = TMath::Min(delta1,delta2);
6493 if (distance1>cdist1) continue; // cut on DCA linear approximation
6494 //
6495 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
6496 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
6497 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
6498 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
6499 //
6500 if (npoints==2){
6501 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
6502 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
6503 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
6504 }
6505 distance1 = TMath::Min(delta1,delta2);
6506 Float_t rkink =0;
6507 if (delta1<delta2){
6508 rkink = TMath::Sqrt(radius[0]);
6509 }
6510 else{
6511 rkink = TMath::Sqrt(radius[1]);
6512 }
6513 if (distance1>cdist2) continue;
6514 //
6515 //
6516 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
6517 //
6518 //
6519 Int_t row0 = GetRowNumber(rkink);
6520 if (row0<10) continue;
6521 if (row0>150) continue;
6522 //
6523 //
6524 Float_t dens00=-1,dens01=-1;
6525 Float_t dens10=-1,dens11=-1;
6526 //
6527 Int_t found,foundable,ishared;
6528 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
6529 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
6530 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
6531 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
6532 //
6533 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
6534 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
6535 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
6536 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
6537 //
6538 if (dens00<dens10 && dens01<dens11) continue;
6539 if (dens00>dens10 && dens01>dens11) continue;
6540 if (TMath::Max(dens00,dens10)<0.1) continue;
6541 if (TMath::Max(dens01,dens11)<0.3) continue;
6542 //
6543 if (TMath::Min(dens00,dens10)>0.6) continue;
6544 if (TMath::Min(dens01,dens11)>0.6) continue;
6545
6546 //
6547 AliTPCseed * ktrack0, *ktrack1;
6548 if (dens00>dens10){
6549 ktrack0 = track0;
6550 ktrack1 = track1;
6551 }
6552 else{
6553 ktrack0 = track1;
6554 ktrack1 = track0;
6555 }
6556 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
6557 AliExternalTrackParam paramm(*ktrack0);
6558 AliExternalTrackParam paramd(*ktrack1);
6559 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
6560 //
6561 //
6562 kink->SetMother(paramm);
6563 kink->SetDaughter(paramd);
6564 kink->Update();
6565
2942f542 6566 Float_t x[3] = { static_cast<Float_t>(kink->GetPosition()[0]),static_cast<Float_t>(kink->GetPosition()[1]),static_cast<Float_t>(kink->GetPosition()[2])};
ddfbc51a 6567 Int_t index[4];
6568 fkParam->Transform0to1(x,index);
6569 fkParam->Transform1to2(x,index);
6570 row0 = GetRowNumber(x[0]);
6571
6572 if (kink->GetR()<100) continue;
6573 if (kink->GetR()>240) continue;
6574 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
6575 if (kink->GetDistance()>cdist3) continue;
6576 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
6577 if (dird<0) continue;
6578
6579 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
6580 if (dirm<0) continue;
6581 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
6582 if (mpt<0.2) continue;
6583
6584 if (mpt<1){
6585 //for high momenta momentum not defined well in first iteration
6586 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
6587 if (qt>0.35) continue;
6588 }
6589
6590 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
6591 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
6592 if (dens00>dens10){
6593 kink->SetTPCDensity(dens00,0,0);
6594 kink->SetTPCDensity(dens01,0,1);
6595 kink->SetTPCDensity(dens10,1,0);
6596 kink->SetTPCDensity(dens11,1,1);
6597 kink->SetIndex(i,0);
6598 kink->SetIndex(j,1);
6599 }
6600 else{
6601 kink->SetTPCDensity(dens10,0,0);
6602 kink->SetTPCDensity(dens11,0,1);
6603 kink->SetTPCDensity(dens00,1,0);
6604 kink->SetTPCDensity(dens01,1,1);
6605 kink->SetIndex(j,0);
6606 kink->SetIndex(i,1);
6607 }
6608
6609 if (mpt<1||kink->GetAngle(2)>0.1){
6610 // angle and densities not defined yet
6611 if (kink->GetTPCDensityFactor()<0.8) continue;
6612 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
6613 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
6614 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
6615 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
6616
6617 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
6618 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
6619 criticalangle= 3*TMath::Sqrt(criticalangle);
6620 if (criticalangle>0.02) criticalangle=0.02;
6621 if (kink->GetAngle(2)<criticalangle) continue;
6622 }
6623 //
6624 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
6625 Float_t shapesum =0;
6626 Float_t sum = 0;
6627 for ( Int_t row = row0-drow; row<row0+drow;row++){
6628 if (row<0) continue;
6629 if (row>155) continue;
6630 if (ktrack0->GetClusterPointer(row)){
6631 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
6632 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
6633 sum++;
6634 }
6635 if (ktrack1->GetClusterPointer(row)){
6636 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
6637 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
6638 sum++;
6639 }
6640 }
6641 if (sum<4){
6642 kink->SetShapeFactor(-1.);
6643 }
6644 else{
6645 kink->SetShapeFactor(shapesum/sum);
6646 }
6647 // esd->AddKink(kink);
6648 //
6649 // kink->SetMother(paramm);
6650 //kink->SetDaughter(paramd);
6651
6652 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
6653 chi2P2*=chi2P2;
6654 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
6655 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
6656 chi2P3*=chi2P3;
6657 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
6658 //
65e67c9c 6659 if (AliTPCReconstructor::StreamLevel()&kStreamFindKinks) {// flag: stream track infroamtion in the FindKinks method
ddfbc51a 6660 (*fDebugStreamer)<<"kinkLpt"<<
6661 "chi2P2="<<chi2P2<<
6662 "chi2P3="<<chi2P3<<
6663 "p0.="<<&paramm<<
6664 "p1.="<<&paramd<<
6665 "k.="<<kink<<
6666 "\n";
6667 }
6668 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
6669 continue;
6670 }
6671 //
6672 kinks->AddLast(kink);
6673 kink = new AliKink;
6674 ncandidates++;
6675 }
6676 }
6677 //
6678 // sort the kinks according quality - and refit them towards vertex
6679 //
6680 Int_t nkinks = kinks->GetEntriesFast();
6681 Float_t *quality = new Float_t[nkinks];
6682 Int_t *indexes = new Int_t[nkinks];
6683 AliTPCseed **mothers = new AliTPCseed*[nkinks]; memset(mothers, 0, nkinks*sizeof(AliTPCseed*));
6684 AliTPCseed **daughters = new AliTPCseed*[nkinks]; memset(daughters, 0, nkinks*sizeof(AliTPCseed*));
6685 //
6686 //
6687 for (Int_t i=0;i<nkinks;i++){
6688 quality[i] =100000;
6689 AliKink *kinkl = (AliKink*)kinks->At(i);
6690 //
6691 // refit kinks towards vertex
6692 //
6693 Int_t index0 = kinkl->GetIndex(0);
6694 Int_t index1 = kinkl->GetIndex(1);
6695 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6696 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6697 //
6698 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
6699 //
6700 // Refit Kink under if too small angle
6701 //
6702 if (kinkl->GetAngle(2)<0.05){
6703 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6704 Int_t row0 = kinkl->GetTPCRow0();
6705 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
6706 //
6707 //
6708 Int_t last = row0-drow;
6709 if (last<40) last=40;
6710 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
6711 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
6712 //
6713 //
6714 Int_t first = row0+drow;
6715 if (first>130) first=130;
6716 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
6717 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
6718 //
6719 if (seed0 && seed1){
6720 kinkl->SetStatus(1,8);
6721 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
6722 row0 = GetRowNumber(kinkl->GetR());
6723 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
6724 mothers[i] = new ( NextFreeSeed() ) AliTPCseed(*seed0);
6725 mothers[i]->SetPoolID(fLastSeedID);
6726 daughters[i] = new (NextFreeSeed() ) AliTPCseed(*seed1);
6727 daughters[i]->SetPoolID(fLastSeedID);
6728 }
6729 else{
6730 delete kinks->RemoveAt(i);
6731 if (seed0) MarkSeedFree( seed0 );
6732 if (seed1) MarkSeedFree( seed1 );
6733 continue;
6734 }
6735 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
6736 delete kinks->RemoveAt(i);
6737 if (seed0) MarkSeedFree( seed0 );
6738 if (seed1) MarkSeedFree( seed1 );
6739 continue;
6740 }
6741 //
6742 MarkSeedFree( seed0 );
6743 MarkSeedFree( seed1 );
6744 }
6745 //
6746 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
6747 }
6748 TMath::Sort(nkinks,quality,indexes,kFALSE);
6749 //
6750 //remove double find kinks
6751 //
6752 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
6753 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6754 if (!kink0) continue;
6755 //
6756 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
6757 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6758 if (!kink0) continue;
6759 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
6760 if (!kink1) continue;
6761 // if not close kink continue
6762 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
6763 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
6764 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
6765 //
6766 AliTPCseed &mother0 = *mothers[indexes[ikink0]];
6767 AliTPCseed &daughter0 = *daughters[indexes[ikink0]];
6768 AliTPCseed &mother1 = *mothers[indexes[ikink1]];
6769 AliTPCseed &daughter1 = *daughters[indexes[ikink1]];
6770 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
6771 //
6772 Int_t same = 0;
6773 Int_t both = 0;
6774 Int_t samem = 0;
6775 Int_t bothm = 0;
6776 Int_t samed = 0;
6777 Int_t bothd = 0;
6778 //
6779 for (Int_t i=0;i<row0;i++){
6780 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
6781 both++;
6782 bothm++;
6783 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6784 same++;
6785 samem++;
6786 }
6787 }
6788 }
6789
6790 for (Int_t i=row0;i<158;i++){
6791 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
6792 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
6793 both++;
6794 bothd++;
6795 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6796 same++;
6797 samed++;
6798 }
6799 }
6800 }
6801 Float_t ratio = Float_t(same+1)/Float_t(both+1);
6802 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
6803 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
6804 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
6805 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
6806 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
6807 if (sum1>sum0){
6808 shared[kink0->GetIndex(0)]= kTRUE;
6809 shared[kink0->GetIndex(1)]= kTRUE;
6810 delete kinks->RemoveAt(indexes[ikink0]);
6811 break;
6812 }
6813 else{
6814 shared[kink1->GetIndex(0)]= kTRUE;
6815 shared[kink1->GetIndex(1)]= kTRUE;
6816 delete kinks->RemoveAt(indexes[ikink1]);
6817 }
6818 }
6819 }
6820 }
6821
6822
6823 for (Int_t i=0;i<nkinks;i++){
6824 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
6825 if (!kinkl) continue;
6826 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6827 Int_t index0 = kinkl->GetIndex(0);
6828 Int_t index1 = kinkl->GetIndex(1);
6829 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
6830 kinkl->SetMultiple(usage[index0],0);
6831 kinkl->SetMultiple(usage[index1],1);
6832 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
6833 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
6834 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
6835 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
6836
6837 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6838 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6839 if (!ktrack0 || !ktrack1) continue;
6840 Int_t index = esd->AddKink(kinkl);
6841 //
6842 //
6843 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
6844 if (mothers[indexes[i]]->GetNumberOfClusters()>20 && daughters[indexes[i]]->GetNumberOfClusters()>20 &&
6845 (mothers[indexes[i]]->GetNumberOfClusters()+daughters[indexes[i]]->GetNumberOfClusters())>100){
6846 *ktrack0 = *mothers[indexes[i]];
6847 *ktrack1 = *daughters[indexes[i]];
6848 }
6849 }
6850 //
6851 ktrack0->SetKinkIndex(usage[index0],-(index+1));
6852 ktrack1->SetKinkIndex(usage[index1], (index+1));
6853 usage[index0]++;
6854 usage[index1]++;
6855 }
6856 //
6857 // Remove tracks corresponding to shared kink's
6858 //
6859 for (Int_t i=0;i<nentries;i++){
6860 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6861 if (!track0) continue;
6862 if (track0->GetKinkIndex(0)!=0) continue;
6863 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
6864 }
6865
6866 //
6867 //
6868 RemoveUsed2(array,0.5,0.4,30);
6869 UnsignClusters();
6870 for (Int_t i=0;i<nentries;i++){
6871 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6872 if (!track0) continue;
6873 track0->CookdEdx(0.02,0.6);
6874 track0->CookPID();
6875 }
6876 //
6877 for (Int_t i=0;i<nentries;i++){
6878 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6879 if (!track0) continue;
6880 if (track0->Pt()<1.4) continue;
6881 //remove double high momenta tracks - overlapped with kink candidates
6882 Int_t ishared=0;
6883 Int_t all =0;
6884 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
6885 if (track0->GetClusterPointer(icl)!=0){
6886 all++;
6887 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
6888 }
6889 }
6890 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
6891 MarkSeedFree( array->RemoveAt(i) );
6892 continue;
6893 }
6894 //
6895 if (track0->GetKinkIndex(0)!=0) continue;
6896 if (track0->GetNumberOfClusters()<80) continue;
6897
6898 AliTPCseed *pmother = new( NextFreeSeed() ) AliTPCseed();
6899 pmother->SetPoolID(fLastSeedID);
6900 AliTPCseed *pdaughter = new( NextFreeSeed() ) AliTPCseed();
6901 pdaughter->SetPoolID(fLastSeedID);
6902 AliKink *pkink = new AliKink;
6903
6904 AliTPCseed & mother = *pmother;
6905 AliTPCseed & daughter = *pdaughter;
6906 AliKink & kinkl = *pkink;
6907 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
6908 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
6909 MarkSeedFree( pmother );
6910 MarkSeedFree( pdaughter );
6911 delete pkink;
6912 continue; //too short tracks
6913 }
6914 if (mother.Pt()<1.4) {
6915 MarkSeedFree( pmother );
6916 MarkSeedFree( pdaughter );
6917 delete pkink;
6918 continue;
6919 }
6920 Int_t row0= kinkl.GetTPCRow0();
6921 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
6922 MarkSeedFree( pmother );
6923 MarkSeedFree( pdaughter );
6924 delete pkink;
6925 continue;
6926 }
6927 //
6928 Int_t index = esd->AddKink(&kinkl);
6929 mother.SetKinkIndex(0,-(index+1));
6930 daughter.SetKinkIndex(0,index+1);
6931 if (mother.GetNumberOfClusters()>50) {
6932 MarkSeedFree( array->RemoveAt(i) );
6933 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6934 mtc->SetPoolID(fLastSeedID);
6935 array->AddAt(mtc,i);
6936 }
6937 else{
6938 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6939 mtc->SetPoolID(fLastSeedID);
6940 array->AddLast(mtc);
6941 }
6942 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
6943 dtc->SetPoolID(fLastSeedID);
6944 array->AddLast(dtc);
6945 for (Int_t icl=0;icl<row0;icl++) {
6946 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
6947 }
6948 //
6949 for (Int_t icl=row0;icl<158;icl++) {
6950 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
6951 }
6952 //
6953 }
6954 MarkSeedFree( pmother );
6955 MarkSeedFree( pdaughter );
6956 delete pkink;
6957 }
6958
6959 delete [] daughters;
6960 delete [] mothers;
6961 //
6962 //
6963 delete [] dca;
6964 delete []circular;
6965 delete []shared;
6966 delete []quality;
6967 delete []indexes;
6968 //
6969 delete kink;
6970 delete[]fim;
6971 delete[] zm;
6972 delete[] z0;
6973 delete [] usage;
6974 delete[] alpha;
6975 delete[] nclusters;
6976 delete[] sign;
6977 delete[] helixes;
6978 kinks->Delete();
6979 delete kinks;
6980
6981 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
6982 timer.Print();
6983}
6984*/
6985
829455ad 6986Int_t AliTPCtracker::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
ddfbc51a 6987{
6988 //
6989 // refit kink towards to the vertex
6990 //
6991 //
6992 AliKink &kink=(AliKink &)knk;
6993
6994 Int_t row0 = GetRowNumber(kink.GetR());
6995 FollowProlongation(mother,0);
6996 mother.Reset(kFALSE);
6997 //
6998 FollowProlongation(daughter,row0);
6999 daughter.Reset(kFALSE);
7000 FollowBackProlongation(daughter,158);
7001 daughter.Reset(kFALSE);
7002 Int_t first = TMath::Max(row0-20,30);
7003 Int_t last = TMath::Min(row0+20,140);
7004 //
7005 const Int_t kNdiv =5;
7006 AliTPCseed param0[kNdiv]; // parameters along the track
7007 AliTPCseed param1[kNdiv]; // parameters along the track
7008 AliKink kinks[kNdiv]; // corresponding kink parameters
7009 //
7010 Int_t rows[kNdiv];
7011 for (Int_t irow=0; irow<kNdiv;irow++){
7012 rows[irow] = first +((last-first)*irow)/(kNdiv-1);
7013 }
7014 // store parameters along the track
7015 //
7016 for (Int_t irow=0;irow<kNdiv;irow++){
7017 FollowBackProlongation(mother, rows[irow]);
7018 FollowProlongation(daughter,rows[kNdiv-1-irow]);
7019 param0[irow] = mother;
7020 param1[kNdiv-1-irow] = daughter;
7021 }
7022 //
7023 // define kinks
7024 for (Int_t irow=0; irow<kNdiv-1;irow++){
7025 if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
7026 kinks[irow].SetMother(param0[irow]);
7027 kinks[irow].SetDaughter(param1[irow]);
7028 kinks[irow].Update();
7029 }
7030 //
7031 // choose kink with best "quality"
7032 Int_t index =-1;
7033 Double_t mindist = 10000;
7034 for (Int_t irow=0;irow<kNdiv;irow++){
7035 if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
7036 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
7037 if (TMath::Abs(kinks[irow].GetR())<100.) continue;
7038 //
7039 Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
7040 normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
7041 if (normdist < mindist){
7042 mindist = normdist;
7043 index = irow;
7044 }
7045 }
7046 //
7047 if (index==-1) return 0;
7048 //
7049 //
7050 param0[index].Reset(kTRUE);
7051 FollowProlongation(param0[index],0);
7052 //
7053 mother = param0[index];
7054 daughter = param1[index]; // daughter in vertex
7055 //
7056 kink.SetMother(mother);
7057 kink.SetDaughter(daughter);
7058 kink.Update();
7059 kink.SetTPCRow0(GetRowNumber(kink.GetR()));
7060 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
7061 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
7062 kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
7063 kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
7064 mother.SetLabel(kink.GetLabel(0));
7065 daughter.SetLabel(kink.GetLabel(1));
7066
7067 return 1;
7068}
7069
7070
829455ad 7071void AliTPCtracker::UpdateKinkQualityM(AliTPCseed * seed){
ddfbc51a 7072 //
7073 // update Kink quality information for mother after back propagation
7074 //
7075 if (seed->GetKinkIndex(0)>=0) return;
7076 for (Int_t ikink=0;ikink<3;ikink++){
7077 Int_t index = seed->GetKinkIndex(ikink);
7078 if (index>=0) break;
51ad6848 7079 index = TMath::Abs(index)-1;
7080 AliESDkink * kink = fEvent->GetKink(index);
f941f7fa 7081 kink->SetTPCDensity(-1,0,0);
7082 kink->SetTPCDensity(1,0,1);
51ad6848 7083 //
eea478d3 7084 Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 7085 if (row0<15) row0=15;
7086 //
eea478d3 7087 Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 7088 if (row1>145) row1=145;
7089 //
7090 Int_t found,foundable,shared;
7091 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
f941f7fa 7092 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,0);
51ad6848 7093 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
f941f7fa 7094 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,1);
51ad6848 7095 }
7096
7097}
7098
829455ad 7099void AliTPCtracker::UpdateKinkQualityD(AliTPCseed * seed){
91162307 7100 //
eea478d3 7101 // update Kink quality information for daughter after refit
91162307 7102 //
eea478d3 7103 if (seed->GetKinkIndex(0)<=0) return;
7104 for (Int_t ikink=0;ikink<3;ikink++){
7105 Int_t index = seed->GetKinkIndex(ikink);
7106 if (index<=0) break;
7107 index = TMath::Abs(index)-1;
7108 AliESDkink * kink = fEvent->GetKink(index);
f941f7fa 7109 kink->SetTPCDensity(-1,1,0);
7110 kink->SetTPCDensity(-1,1,1);
91162307 7111 //
eea478d3 7112 Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
7113 if (row0<15) row0=15;
7114 //
7115 Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
7116 if (row1>145) row1=145;
7117 //
7118 Int_t found,foundable,shared;
7119 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
f941f7fa 7120 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,0);
eea478d3 7121 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
f941f7fa 7122 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,1);
91162307 7123 }
eea478d3 7124
7125}
7126
7127
829455ad 7128Int_t AliTPCtracker::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
eea478d3 7129{
91162307 7130 //
eea478d3 7131 // check kink point for given track
7132 // if return value=0 kink point not found
7133 // otherwise seed0 correspond to mother particle
7134 // seed1 correspond to daughter particle
7135 // kink parameter of kink point
6c94f330 7136 AliKink &kink=(AliKink &)knk;
91162307 7137
b9671574 7138 Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
7139 Int_t first = seed->GetFirstPoint();
7140 Int_t last = seed->GetLastPoint();
eea478d3 7141 if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
91162307 7142
eea478d3 7143
7144 AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
7145 if (!seed1) return 0;
b9671574 7146 FollowProlongation(*seed1,seed->GetLastPoint()-20);
eea478d3 7147 seed1->Reset(kTRUE);
7148 FollowProlongation(*seed1,158);
7149 seed1->Reset(kTRUE);
b9671574 7150 last = seed1->GetLastPoint();
eea478d3 7151 //
ddfbc51a 7152 AliTPCseed *seed0 = new( NextFreeSeed() ) AliTPCseed(*seed);
7153 seed0->SetPoolID(fLastSeedID);
eea478d3 7154 seed0->Reset(kFALSE);
7155 seed0->Reset();
7156 //
7157 AliTPCseed param0[20]; // parameters along the track
7158 AliTPCseed param1[20]; // parameters along the track
6c94f330 7159 AliKink kinks[20]; // corresponding kink parameters
eea478d3 7160 Int_t rows[20];
7161 for (Int_t irow=0; irow<20;irow++){
7162 rows[irow] = first +((last-first)*irow)/19;
7163 }
7164 // store parameters along the track
7165 //
7166 for (Int_t irow=0;irow<20;irow++){
7167 FollowBackProlongation(*seed0, rows[irow]);
7168 FollowProlongation(*seed1,rows[19-irow]);
316c6cd9 7169 param0[irow] = *seed0;
7170 param1[19-irow] = *seed1;
eea478d3 7171 }
7172 //
7173 // define kinks
7174 for (Int_t irow=0; irow<19;irow++){
7175 kinks[irow].SetMother(param0[irow]);
7176 kinks[irow].SetDaughter(param1[irow]);
7177 kinks[irow].Update();
7178 }
7179 //
7180 // choose kink with biggest change of angle
7181 Int_t index =-1;
7182 Double_t maxchange= 0;
7183 for (Int_t irow=1;irow<19;irow++){
7184 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
7185 if (TMath::Abs(kinks[irow].GetR())<110.) continue;
6c94f330 7186 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 7187 if ( quality > maxchange){
7188 maxchange = quality;
7189 index = irow;
7190 //
91162307 7191 }
7192 }
ddfbc51a 7193 MarkSeedFree( seed0 );
7194 MarkSeedFree( seed1 );
eea478d3 7195 if (index<0) return 0;
7196 //
7197 Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
ddfbc51a 7198 seed0 = new( NextFreeSeed() ) AliTPCseed(param0[index]);
7199 seed0->SetPoolID(fLastSeedID);
7200 seed1 = new( NextFreeSeed() ) AliTPCseed(param1[index]);
7201 seed1->SetPoolID(fLastSeedID);
eea478d3 7202 seed0->Reset(kFALSE);
7203 seed1->Reset(kFALSE);
6c94f330 7204 seed0->ResetCovariance(10.);
7205 seed1->ResetCovariance(10.);
eea478d3 7206 FollowProlongation(*seed0,0);
7207 FollowBackProlongation(*seed1,158);
316c6cd9 7208 mother = *seed0; // backup mother at position 0
eea478d3 7209 seed0->Reset(kFALSE);
7210 seed1->Reset(kFALSE);
6c94f330 7211 seed0->ResetCovariance(10.);
7212 seed1->ResetCovariance(10.);
eea478d3 7213 //
7214 first = TMath::Max(row0-20,0);
7215 last = TMath::Min(row0+20,158);
7216 //
7217 for (Int_t irow=0; irow<20;irow++){
7218 rows[irow] = first +((last-first)*irow)/19;
7219 }
7220 // store parameters along the track
7221 //
7222 for (Int_t irow=0;irow<20;irow++){
7223 FollowBackProlongation(*seed0, rows[irow]);
7224 FollowProlongation(*seed1,rows[19-irow]);
316c6cd9 7225 param0[irow] = *seed0;
7226 param1[19-irow] = *seed1;
eea478d3 7227 }
7228 //
7229 // define kinks
7230 for (Int_t irow=0; irow<19;irow++){
7231 kinks[irow].SetMother(param0[irow]);
7232 kinks[irow].SetDaughter(param1[irow]);
7233 // param0[irow].Dump();
7234 //param1[irow].Dump();
7235 kinks[irow].Update();
7236 }
7237 //
7238 // choose kink with biggest change of angle
7239 index =-1;
7240 maxchange= 0;
7241 for (Int_t irow=0;irow<20;irow++){
7242 if (TMath::Abs(kinks[irow].GetR())>250.) continue;
7243 if (TMath::Abs(kinks[irow].GetR())<90.) continue;
6c94f330 7244 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 7245 if ( quality > maxchange){
7246 maxchange = quality;
7247 index = irow;
7248 //
91162307 7249 }
7250 }
7251 //
7252 //
b9671574 7253 if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
ddfbc51a 7254 MarkSeedFree( seed0 );
7255 MarkSeedFree( seed1 );
eea478d3 7256 return 0;
1627d1c4 7257 }
16299eac 7258
eea478d3 7259 // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
1627d1c4 7260
eea478d3 7261 kink.SetMother(param0[index]);
7262 kink.SetDaughter(param1[index]);
7263 kink.Update();
16299eac 7264
7265 Double_t chi2P2 = param0[index].GetParameter()[2]-param1[index].GetParameter()[2];
7266 chi2P2*=chi2P2;
7267 chi2P2/=param0[index].GetCovariance()[5]+param1[index].GetCovariance()[5];
7268 Double_t chi2P3 = param0[index].GetParameter()[3]-param1[index].GetParameter()[3];
7269 chi2P3*=chi2P3;
7270 chi2P3/=param0[index].GetCovariance()[9]+param1[index].GetCovariance()[9];
7271 //
65e67c9c 7272 if (AliTPCReconstructor::StreamLevel()&kStreamFindKinks) { // flag: stream track infroamtion in the FindKinks method
16299eac 7273 (*fDebugStreamer)<<"kinkHpt"<<
7274 "chi2P2="<<chi2P2<<
7275 "chi2P3="<<chi2P3<<
7276 "p0.="<<&param0[index]<<
7277 "p1.="<<&param1[index]<<
7278 "k.="<<&kink<<
7279 "\n";
7280 }
7281 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
ddfbc51a 7282 MarkSeedFree( seed0 );
7283 MarkSeedFree( seed1 );
16299eac 7284 return 0;
7285 }
7286
7287
eea478d3 7288 row0 = GetRowNumber(kink.GetR());
7289 kink.SetTPCRow0(row0);
7290 kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
7291 kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
7292 kink.SetIndex(-10,0);
b9671574 7293 kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
7294 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
7295 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
eea478d3 7296 //
7297 //
7298 // new (&mother) AliTPCseed(param0[index]);
316c6cd9 7299 daughter = param1[index];
eea478d3 7300 daughter.SetLabel(kink.GetLabel(1));
7301 param0[index].Reset(kTRUE);
16299eac 7302 FollowProlongation(param0[index],0);
316c6cd9 7303 mother = param0[index];
eea478d3 7304 mother.SetLabel(kink.GetLabel(0));
16299eac 7305 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(1)){
7306 mother=*seed;
7307 }
ddfbc51a 7308 MarkSeedFree( seed0 );
7309 MarkSeedFree( seed1 );
eea478d3 7310 //
7311 return 1;
1627d1c4 7312}
7313
7314
7315
7316
829455ad 7317AliTPCseed* AliTPCtracker::ReSeed(AliTPCseed *t)
91162307 7318{
7319 //
7320 // reseed - refit - track
7321 //
7322 Int_t first = 0;
7323 // Int_t last = fSectors->GetNRows()-1;
7324 //
7325 if (fSectors == fOuterSec){
b9671574 7326 first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
91162307 7327 //last =
7328 }
7329 else
b9671574 7330 first = t->GetFirstPoint();
91162307 7331 //
7332 AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
7333 FollowBackProlongation(*t,fSectors->GetNRows()-1);
7334 t->Reset(kFALSE);
7335 FollowProlongation(*t,first);
7336 return seed;
7337}
7338
7339
7340
7341
7342
7343
7344
1c53abe2 7345//_____________________________________________________________________________
829455ad 7346Int_t AliTPCtracker::ReadSeeds(const TFile *inp) {
1c53abe2 7347 //-----------------------------------------------------------------
7348 // This function reades track seeds.
7349 //-----------------------------------------------------------------
7350 TDirectory *savedir=gDirectory;
7351
7352 TFile *in=(TFile*)inp;
7353 if (!in->IsOpen()) {
829455ad 7354 cerr<<"AliTPCtracker::ReadSeeds(): input file is not open !\n";
1c53abe2 7355 return 1;
7356 }
7357
7358 in->cd();
7359 TTree *seedTree=(TTree*)in->Get("Seeds");
7360 if (!seedTree) {
829455ad 7361 cerr<<"AliTPCtracker::ReadSeeds(): ";
1c53abe2 7362 cerr<<"can't get a tree with track seeds !\n";
7363 return 2;
7364 }
7365 AliTPCtrack *seed=new AliTPCtrack;
7366 seedTree->SetBranchAddress("tracks",&seed);
7367
7368 if (fSeeds==0) fSeeds=new TObjArray(15000);
7369
7370 Int_t n=(Int_t)seedTree->GetEntries();
7371 for (Int_t i=0; i<n; i++) {
7372 seedTree->GetEvent(i);
ddfbc51a 7373 AliTPCseed* sdc = new( NextFreeSeed() ) AliTPCseed(*seed/*,seed->GetAlpha()*/);
7374 sdc->SetPoolID(fLastSeedID);
f06a1ff6 7375 fSeeds->AddLast(sdc);
1c53abe2 7376 }
7377
f06a1ff6 7378 delete seed; // RS: this seed is not from the pool, delete it !!!
1c53abe2 7379 delete seedTree;
7380 savedir->cd();
7381 return 0;
7382}
7383
829455ad 7384Int_t AliTPCtracker::Clusters2TracksHLT (AliESDEvent *const esd, const AliESDEvent *hltEvent)
d26d9159 7385{
7386 //
544c295f 7387 // clusters to tracks
d9b8978b 7388 if (fSeeds) DeleteSeeds();
ddfbc51a 7389 else ResetSeedsPool();
e1dadcd0 7390 fEvent = esd;
72e25240 7391 fEventHLT = hltEvent;
65e67c9c 7392 if (AliTPCReconstructor::GetRecoParam()->GetUseOulierClusterFilter()) FilterOutlierClusters();
e1dadcd0 7393 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
7394 transform->SetCurrentTimeStamp( esd->GetTimeStamp());
7395 transform->SetCurrentRun(esd->GetRunNumber());
7396
65e67c9c 7397
d26d9159 7398 Clusters2Tracks();
72e25240 7399 fEventHLT = 0;
d26d9159 7400 if (!fSeeds) return 1;
7401 FillESD(fSeeds);
3e1f1ce7 7402 if ((AliTPCReconstructor::StreamLevel()&kStreamClDump)>0) DumpClusters(0,fSeeds);
d26d9159 7403 return 0;
7404 //
7405}
7406
829455ad 7407Int_t AliTPCtracker::Clusters2Tracks(AliESDEvent *const esd)
72e25240 7408{
7409 //
7410 // clusters to tracks
7411 return Clusters2TracksHLT( esd, 0);
7412}
d26d9159 7413
1c53abe2 7414//_____________________________________________________________________________
829455ad 7415Int_t AliTPCtracker::Clusters2Tracks() {
1c53abe2 7416 //-----------------------------------------------------------------
7417 // This is a track finder.
7418 //-----------------------------------------------------------------
91162307 7419 TDirectory *savedir=gDirectory;
1c53abe2 7420 TStopwatch timer;
d26d9159 7421
91162307 7422 fIteration = 0;
7423 fSeeds = Tracking();
1c53abe2 7424
6bdc18d6 7425 if (fDebug>0){
7426 Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
7427 }
91162307 7428 //activate again some tracks
7429 for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
7430 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7431 if (!pt) continue;
7432 Int_t nc=t.GetNumberOfClusters();
7433 if (nc<20) {
ddfbc51a 7434 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7435 continue;
eea478d3 7436 }
f5cbf2ef 7437 CookLabel(pt,0.1);
b9671574 7438 if (pt->GetRemoval()==10) {
91162307 7439 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
bad6eb00 7440 pt->Desactivate(10); // make track again active // MvL: should be 0 ?
91162307 7441 else{
7442 pt->Desactivate(20);
ddfbc51a 7443 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7444 }
7445 }
7446 }
51ad6848 7447 //
7448 RemoveUsed2(fSeeds,0.85,0.85,0);
a3232aae 7449 if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
6d493ea0 7450 //FindCurling(fSeeds, fEvent,0);
65e67c9c 7451 if (AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC) FindMultiMC(fSeeds, fEvent,-1); // find multi found tracks
81e97e0d 7452 RemoveUsed2(fSeeds,0.5,0.4,20);
1af5da7e 7453 FindSplitted(fSeeds, fEvent,0); // find multi found tracks
65e67c9c 7454 if (AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC) FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
6d493ea0 7455
81e97e0d 7456 // //
7457// // refit short tracks
7458// //
7459 Int_t nseed=fSeeds->GetEntriesFast();
1c53abe2 7460 //
91162307 7461 Int_t found = 0;
7462 for (Int_t i=0; i<nseed; i++) {
7463 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7464 if (!pt) continue;
7465 Int_t nc=t.GetNumberOfClusters();
7466 if (nc<15) {
ddfbc51a 7467 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7468 continue;
7469 }
7470 CookLabel(pt,0.1); //For comparison only
7471 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 7472 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
d9b8978b 7473 found++;
7474 if (fDebug>0) cerr<<found<<'\r';
b9671574 7475 pt->SetLab2(i);
91162307 7476 }
7477 else
ddfbc51a 7478 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7479 }
7480
7481
7482 //RemoveOverlap(fSeeds,0.99,7,kTRUE);
7483 SignShared(fSeeds);
7484 //RemoveUsed(fSeeds,0.9,0.9,6);
1c53abe2 7485 //
91162307 7486 nseed=fSeeds->GetEntriesFast();
7487 found = 0;
7488 for (Int_t i=0; i<nseed; i++) {
7489 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7490 if (!pt) continue;
7491 Int_t nc=t.GetNumberOfClusters();
7492 if (nc<15) {
ddfbc51a 7493 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7494 continue;
7495 }
7496 t.SetUniqueID(i);
7497 t.CookdEdx(0.02,0.6);
7498 // CheckKinkPoint(&t,0.05);
7499 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 7500 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6bdc18d6 7501 found++;
7502 if (fDebug>0){
7503 cerr<<found<<'\r';
7504 }
b9671574 7505 pt->SetLab2(i);
91162307 7506 }
7507 else
ddfbc51a 7508 MarkSeedFree( fSeeds->RemoveAt(i) );
d26d9159 7509 //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
7510 //if (seed1){
7511 // FollowProlongation(*seed1,0);
7512 // Int_t n = seed1->GetNumberOfClusters();
7513 // printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
7514 // printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
7515 //
7516 //}
7517 //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
7518
91162307 7519 }
7520
7521 SortTracks(fSeeds, 1);
1c53abe2 7522
982aff31 7523 /*
91162307 7524 fIteration = 1;
982aff31 7525 PrepareForBackProlongation(fSeeds,5.);
91162307 7526 PropagateBack(fSeeds);
7527 printf("Time for back propagation: \t");timer.Print();timer.Start();
7528
7529 fIteration = 2;
1c53abe2 7530
982aff31 7531 PrepareForProlongation(fSeeds,5.);
f124f8bf 7532 PropagateForard2(fSeeds);
d26d9159 7533
91162307 7534 printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
7535 // RemoveUsed(fSeeds,0.7,0.7,6);
7536 //RemoveOverlap(fSeeds,0.9,7,kTRUE);
d26d9159 7537
1c53abe2 7538 nseed=fSeeds->GetEntriesFast();
91162307 7539 found = 0;
7540 for (Int_t i=0; i<nseed; i++) {
1c53abe2 7541 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7542 if (!pt) continue;
7543 Int_t nc=t.GetNumberOfClusters();
91162307 7544 if (nc<15) {
ddfbc51a 7545 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7546 continue;
7547 }
1c53abe2 7548 t.CookdEdx(0.02,0.6);
91162307 7549 // CookLabel(pt,0.1); //For comparison only
7550 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
7551 if ((pt->IsActive() || (pt->fRemoval==10) )){
7552 cerr<<found++<<'\r';
7553 }
7554 else
ddfbc51a 7555 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7556 pt->fLab2 = i;
1c53abe2 7557 }
91162307 7558 */
7559
c9427e08 7560 // fNTracks = found;
6bdc18d6 7561 if (fDebug>0){
7562 Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
7563 }
91162307 7564 //
6bdc18d6 7565 // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
7566 Info("Clusters2Tracks","Number of found tracks %d",found);
91162307 7567 savedir->cd();
91162307 7568 // UnloadClusters();
d26d9159 7569 //
1c53abe2 7570 return 0;
7571}
7572
829455ad 7573void AliTPCtracker::Tracking(TObjArray * arr)
91162307 7574{
7575 //
7576 // tracking of the seeds
7577 //
7578
7579 fSectors = fOuterSec;
7580 ParallelTracking(arr,150,63);
7581 fSectors = fOuterSec;
7582 ParallelTracking(arr,63,0);
7583}
7584
829455ad 7585TObjArray * AliTPCtracker::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
91162307 7586{
7587 //
7588 //
7589 //tracking routine
f06a1ff6 7590 static TObjArray arrTracks;
7591 TObjArray * arr = &arrTracks;
91162307 7592 //
7593 fSectors = fOuterSec;
7594 TStopwatch timer;
7595 timer.Start();
7596 for (Int_t sec=0;sec<fkNOS;sec++){
7597 if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
7598 if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);
7599 if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
7600 }
7601 if (fDebug>0){
6bdc18d6 7602 Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
91162307 7603 timer.Print();
7604 timer.Start();
7605 }
7606 Tracking(arr);
7607 if (fDebug>0){
7608 timer.Print();
7609 }
7610
7611 return arr;
7612}
7613
829455ad 7614TObjArray * AliTPCtracker::Tracking()
91162307 7615{
544c295f 7616 // tracking
91162307 7617 //
a3232aae 7618 if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
91162307 7619 TStopwatch timer;
7620 timer.Start();
7621 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7622
7623 TObjArray * seeds = new TObjArray;
7624 TObjArray * arr=0;
6d1424d5 7625 Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
7626 Int_t gapPrim = AliTPCReconstructor::GetRecoParam()->GetSeedGapPrim();
7627 Int_t gapSec = AliTPCReconstructor::GetRecoParam()->GetSeedGapSec();
91162307 7628
7629 Int_t gap =20;
7630 Float_t cuts[4];
7631 cuts[0] = 0.002;
7632 cuts[1] = 1.5;
7633 cuts[2] = 3.;
7634 cuts[3] = 3.;
7635 Float_t fnumber = 3.0;
7636 Float_t fdensity = 3.0;
72e25240 7637
7638 // make HLT seeds
fa90aa2b 7639 if (AliTPCReconstructor::GetRecoParam()->GetUseHLTPreSeeding()) {
72e25240 7640 arr = MakeSeedsHLT( fEventHLT );
7641 if( arr ){
7642 SumTracks(seeds,arr);
7643 delete arr;
7644 arr=0;
7645 //cout<<"HLT tracks left after sorting: "<<seeds->GetEntriesFast()<<endl;
7646 //SignClusters(seeds,fnumber,fdensity);
7647 }
7648 }
91162307 7649
7650 //
7651 //find primaries
7652 cuts[0]=0.0066;
6d1424d5 7653 for (Int_t delta = 0; delta<18; delta+=gapPrim){
91162307 7654 //
7655 cuts[0]=0.0070;
7656 cuts[1] = 1.5;
7657 arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
7658 SumTracks(seeds,arr);
7659 SignClusters(seeds,fnumber,fdensity);
7660 //
7661 for (Int_t i=2;i<6;i+=2){
7662 // seed high pt tracks
7663 cuts[0]=0.0022;
7664 cuts[1]=0.3;
7665 arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
7666 SumTracks(seeds,arr);
7667 SignClusters(seeds,fnumber,fdensity);
7668 }
7669 }
7670 fnumber = 4;
7671 fdensity = 4.;
7672 // RemoveUsed(seeds,0.9,0.9,1);
7673 // UnsignClusters();
7674 // SignClusters(seeds,fnumber,fdensity);
7675
7676 //find primaries
7677 cuts[0]=0.0077;
6d1424d5 7678 for (Int_t delta = 20; delta<120; delta+=gapPrim){
91162307 7679 //
7680 // seed high pt tracks
7681 cuts[0]=0.0060;
7682 cuts[1]=0.3;
7683 cuts[2]=6.;
7684 arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
7685 SumTracks(seeds,arr);
7686 SignClusters(seeds,fnumber,fdensity);
7687
7688 cuts[0]=0.003;
7689 cuts[1]=0.3;
7690 cuts[2]=6.;
7691 arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
7692 SumTracks(seeds,arr);
7693 SignClusters(seeds,fnumber,fdensity);
7694 }
7695
7696 cuts[0] = 0.01;
7697 cuts[1] = 2.0;
7698 cuts[2] = 3.;
7699 cuts[3] = 2.0;
7700 fnumber = 2.;
7701 fdensity = 2.;
7702
7703 if (fDebug>0){
6bdc18d6 7704 Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 7705 timer.Print();
7706 timer.Start();
7707 }
7708 // RemoveUsed(seeds,0.75,0.75,1);
7709 //UnsignClusters();
7710 //SignClusters(seeds,fnumber,fdensity);
7711
7712 // find secondaries
7713
7714 cuts[0] = 0.3;
7715 cuts[1] = 1.5;
7716 cuts[2] = 3.;
7717 cuts[3] = 1.5;
7718
7719 arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
7720 SumTracks(seeds,arr);
7721 SignClusters(seeds,fnumber,fdensity);
7722 //
7723 arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
7724 SumTracks(seeds,arr);
7725 SignClusters(seeds,fnumber,fdensity);
7726 //
7727 arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
7728 SumTracks(seeds,arr);
7729 SignClusters(seeds,fnumber,fdensity);
7730 //
6d1424d5 7731 arr = Tracking(4,nup-5,nup-5-gap,cuts,-1);
7732 SumTracks(seeds,arr);
7733 SignClusters(seeds,fnumber,fdensity);
7734 //
7735 arr = Tracking(4,nup-7,nup-7-gap,cuts,-1);
7736 SumTracks(seeds,arr);
7737 SignClusters(seeds,fnumber,fdensity);
7738 //
7739 //
7740 arr = Tracking(4,nup-9,nup-9-gap,cuts,-1);
7741 SumTracks(seeds,arr);
7742 SignClusters(seeds,fnumber,fdensity);
7743 //
91162307 7744
7745
6d1424d5 7746 for (Int_t delta = 9; delta<30; delta+=gapSec){
91162307 7747 //
7748 cuts[0] = 0.3;
7749 cuts[1] = 1.5;
7750 cuts[2] = 3.;
7751 cuts[3] = 1.5;
7752 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7753 SumTracks(seeds,arr);
7754 SignClusters(seeds,fnumber,fdensity);
7755 //
7756 arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
7757 SumTracks(seeds,arr);
7758 SignClusters(seeds,fnumber,fdensity);
7759 //
7760 }
7761 fnumber = 1;
7762 fdensity = 1;
7763 //
7764 // change cuts
7765 fnumber = 2.;
7766 fdensity = 2.;
7767 cuts[0]=0.0080;
7768
7d27c1df 7769
91162307 7770 // find secondaries
6d1424d5 7771 for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=gapSec){
91162307 7772 //
7773 cuts[0] = 0.3;
2bd61959 7774 cuts[1] = 3.5;
91162307 7775 cuts[2] = 3.;
2bd61959 7776 cuts[3] = 3.5;
91162307 7777 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7778 SumTracks(seeds,arr);
7779 SignClusters(seeds,fnumber,fdensity);
7780 //
7781 arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
7782 SumTracks(seeds,arr);
7783 SignClusters(seeds,fnumber,fdensity);
7784 }
7785
7786 if (fDebug>0){
6bdc18d6 7787 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 7788 timer.Print();
7789 timer.Start();
7790 }
7791
7792 return seeds;
7793 //
7794
7795}
7796
7797
829455ad 7798TObjArray * AliTPCtracker::TrackingSpecial()
a3232aae 7799{
7800 //
7801 // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
7802 // no primary vertex seeding tried
7803 //
7804 TStopwatch timer;
7805 timer.Start();
7806 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7807
7808 TObjArray * seeds = new TObjArray;
7809 TObjArray * arr=0;
7810
7811 Int_t gap = 15;
7812 Float_t cuts[4];
7813 Float_t fnumber = 3.0;
7814 Float_t fdensity = 3.0;
7815
7816 // find secondaries
7817 cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC(); // max curvature
7818 cuts[1] = 3.5; // max tan(phi) angle for seeding
7819 cuts[2] = 3.; // not used (cut on z primary vertex)
7820 cuts[3] = 3.5; // max tan(theta) angle for seeding
7821
7822 for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
7823 //
7824 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7825 SumTracks(seeds,arr);
7826 SignClusters(seeds,fnumber,fdensity);
7827 }
7828
7829 if (fDebug>0){
7830 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
7831 timer.Print();
7832 timer.Start();
7833 }
7834
7835 return seeds;
7836 //
7837
7838}
7839
7840
829455ad 7841void AliTPCtracker::SumTracks(TObjArray *arr1,TObjArray *&arr2)
91162307 7842{
7843 //
7844 //sum tracks to common container
7845 //remove suspicious tracks
f06a1ff6 7846 // RS: Attention: supplied tracks come in the static array, don't delete them
91162307 7847 Int_t nseed = arr2->GetEntriesFast();
7848 for (Int_t i=0;i<nseed;i++){
7849 AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);
7850 if (pt){
a3232aae 7851 //
7852 // remove tracks with too big curvature
7853 //
7854 if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
ddfbc51a 7855 MarkSeedFree( arr2->RemoveAt(i) );
a3232aae 7856 continue;
7857 }
ca142b1f 7858 // REMOVE VERY SHORT TRACKS
7859 if (pt->GetNumberOfClusters()<20){
ddfbc51a 7860 MarkSeedFree( arr2->RemoveAt(i) );
ca142b1f 7861 continue;
7862 }// patch 28 fev06
91162307 7863 // NORMAL ACTIVE TRACK
7864 if (pt->IsActive()){
7865 arr1->AddLast(arr2->RemoveAt(i));
7866 continue;
7867 }
7868 //remove not usable tracks
b9671574 7869 if (pt->GetRemoval()!=10){
ddfbc51a 7870 MarkSeedFree( arr2->RemoveAt(i) );
91162307 7871 continue;
7872 }
ca142b1f 7873
91162307 7874 // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
7875 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
7876 arr1->AddLast(arr2->RemoveAt(i));
7877 else{
ddfbc51a 7878 MarkSeedFree( arr2->RemoveAt(i) );
91162307 7879 }
7880 }
7881 }
f06a1ff6 7882 // delete arr2; arr2 = 0; // RS: this is static array, don't delete it
91162307 7883}
7884
7885
1c53abe2 7886
829455ad 7887void AliTPCtracker::ParallelTracking(TObjArray *const arr, Int_t rfirst, Int_t rlast)
1c53abe2 7888{
7889 //
7890 // try to track in parralel
7891
91162307 7892 Int_t nseed=arr->GetEntriesFast();
1c53abe2 7893 //prepare seeds for tracking
7894 for (Int_t i=0; i<nseed; i++) {
91162307 7895 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 7896 if (!pt) continue;
7897 if (!t.IsActive()) continue;
7898 // follow prolongation to the first layer
47af7ca4 7899 if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fkParam->GetNRowLow()>rfirst+1) )
c9427e08 7900 FollowProlongation(t, rfirst+1);
1c53abe2 7901 }
7902
7903
7904 //
982aff31 7905 for (Int_t nr=rfirst; nr>=rlast; nr--){
7906 if (nr<fInnerSec->GetNRows())
7907 fSectors = fInnerSec;
7908 else
7909 fSectors = fOuterSec;
1c53abe2 7910 // make indexes with the cluster tracks for given
1c53abe2 7911
7912 // find nearest cluster
7913 for (Int_t i=0; i<nseed; i++) {
91162307 7914 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 7915 if (!pt) continue;
51ad6848 7916 if (nr==80) pt->UpdateReference();
1c53abe2 7917 if (!pt->IsActive()) continue;
47af7ca4 7918 // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
b9671574 7919 if (pt->GetRelativeSector()>17) {
1627d1c4 7920 continue;
7921 }
91162307 7922 UpdateClusters(t,nr);
1c53abe2 7923 }
7924 // prolonagate to the nearest cluster - if founded
7925 for (Int_t i=0; i<nseed; i++) {
91162307 7926 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
1c53abe2 7927 if (!pt) continue;
1627d1c4 7928 if (!pt->IsActive()) continue;
47af7ca4 7929 // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
b9671574 7930 if (pt->GetRelativeSector()>17) {
1627d1c4 7931 continue;
7932 }
91162307 7933 FollowToNextCluster(*pt,nr);
1c53abe2 7934 }
91162307 7935 }
7936}
7937
829455ad 7938void AliTPCtracker::PrepareForBackProlongation(const TObjArray *const arr,Float_t fac) const
91162307 7939{
7940 //
7941 //
7942 // if we use TPC track itself we have to "update" covariance
7943 //
7944 Int_t nseed= arr->GetEntriesFast();
7945 for (Int_t i=0;i<nseed;i++){
7946 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7947 if (pt) {
7948 pt->Modify(fac);
7949 //
7950 //rotate to current local system at first accepted point
b9671574 7951 Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
91162307 7952 Int_t sec = (index&0xff000000)>>24;
7953 sec = sec%18;
7954 Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
7955 if (angle1>TMath::Pi())
7956 angle1-=2.*TMath::Pi();
7957 Float_t angle2 = pt->GetAlpha();
7958
7959 if (TMath::Abs(angle1-angle2)>0.001){
17abbffb 7960 if (!pt->Rotate(angle1-angle2)) return;
91162307 7961 //angle2 = pt->GetAlpha();
7962 //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
7963 //if (pt->GetAlpha()<0)
7964 // pt->fRelativeSector+=18;
7965 //sec = pt->fRelativeSector;
7966 }
7967
7968 }
7969
7970 }
7971
7972
7973}
829455ad 7974void AliTPCtracker::PrepareForProlongation(TObjArray *const arr, Float_t fac) const
91162307 7975{
7976 //
7977 //
7978 // if we use TPC track itself we have to "update" covariance
7979 //
7980 Int_t nseed= arr->GetEntriesFast();
7981 for (Int_t i=0;i<nseed;i++){
7982 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7983 if (pt) {
7984 pt->Modify(fac);
b9671574 7985 pt->SetFirstPoint(pt->GetLastPoint());
91162307 7986 }
7987
7988 }
7989
7990
7991}
7992
829455ad 7993Int_t AliTPCtracker::PropagateBack(const TObjArray *const arr)
91162307 7994{
7995 //
7996 // make back propagation
7997 //
7998 Int_t nseed= arr->GetEntriesFast();
7999 for (Int_t i=0;i<nseed;i++){
8000 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
51ad6848 8001 if (pt&& pt->GetKinkIndex(0)<=0) {
d9b8978b 8002 //AliTPCseed *pt2 = new AliTPCseed(*pt);
91162307 8003 fSectors = fInnerSec;
d26d9159 8004 //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
8005 //fSectors = fOuterSec;
f124f8bf 8006 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
4d158c36 8007 //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
d9b8978b 8008 // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
4d158c36 8009 // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
d9b8978b 8010 //}
51ad6848 8011 }
8012 if (pt&& pt->GetKinkIndex(0)>0) {
8013 AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
b9671574 8014 pt->SetFirstPoint(kink->GetTPCRow0());
51ad6848 8015 fSectors = fInnerSec;
f124f8bf 8016 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
51ad6848 8017 }
6d493ea0 8018 CookLabel(pt,0.3);
91162307 8019 }
8020 return 0;
8021}
8022
8023
829455ad 8024Int_t AliTPCtracker::PropagateForward2(const TObjArray *const arr)
91162307 8025{
8026 //
8027 // make forward propagation
8028 //
8029 Int_t nseed= arr->GetEntriesFast();
4d158c36 8030 //
91162307 8031 for (Int_t i=0;i<nseed;i++){
8032 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
8033 if (pt) {
f124f8bf 8034 FollowProlongation(*pt,0,1,1);
6d493ea0 8035 CookLabel(pt,0.3);
4d158c36 8036 }
6d493ea0 8037
91162307 8038 }
f124f8bf 8039 return 0;
91162307 8040}
8041
8042
829455ad 8043Int_t AliTPCtracker::PropagateForward()
91162307 8044{
b67e07dc 8045 //
8046 // propagate track forward
4d158c36 8047 //UnsignClusters();
d26d9159 8048 Int_t nseed = fSeeds->GetEntriesFast();
8049 for (Int_t i=0;i<nseed;i++){
8050 AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
8051 if (pt){
8052 AliTPCseed &t = *pt;
8053 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
8054 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
8055 if (alpha < 0. ) alpha += 2.*TMath::Pi();
b9671574 8056 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
d26d9159 8057 }
8058 }
8059
91162307 8060 fSectors = fOuterSec;
d26d9159 8061 ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
91162307 8062 fSectors = fInnerSec;
d26d9159 8063 ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
91162307 8064 return 1;
8065}
8066
8067
8068
8069
8070
8071
829455ad 8072Int_t AliTPCtracker::PropagateBack(AliTPCseed *const pt, Int_t row0, Int_t row1)
91162307 8073{
8074 //
8075 // make back propagation, in between row0 and row1
8076 //
1c53abe2 8077
91162307 8078 if (pt) {
8079 fSectors = fInnerSec;
8080 Int_t r1;
8081 //
8082 if (row1<fSectors->GetNRows())
8083 r1 = row1;
8084 else
8085 r1 = fSectors->GetNRows()-1;
8086
8087 if (row0<fSectors->GetNRows()&& r1>0 )
8088 FollowBackProlongation(*pt,r1);
8089 if (row1<=fSectors->GetNRows())
8090 return 0;
8091 //
8092 r1 = row1 - fSectors->GetNRows();
8093 if (r1<=0) return 0;
8094 if (r1>=fOuterSec->GetNRows()) return 0;
8095 fSectors = fOuterSec;
8096 return FollowBackProlongation(*pt,r1);
8097 }
8098 return 0;
8099}
8100
8101
8102
8103
829455ad 8104void AliTPCtracker::GetShape(AliTPCseed * seed, Int_t row)
91162307 8105{
544c295f 8106 // gets cluster shape
fd065ea2 8107 //
8108 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
47af7ca4 8109 Float_t zdrift = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())));
8110 Int_t type = (seed->GetSector() < fkParam->GetNSector()/2) ? 0: (row>126) ? 1:2;
3f82c4f2 8111 Double_t angulary = seed->GetSnp();
feed67f9 8112
8113 if (TMath::Abs(angulary)>AliTPCReconstructor::GetMaxSnpTracker()) {
8114 angulary = TMath::Sign(AliTPCReconstructor::GetMaxSnpTracker(),angulary);
8115 }
8116
bfd20868 8117 angulary = angulary*angulary/((1.-angulary)*(1.+angulary));
fd065ea2 8118 Double_t angularz = seed->GetTgl()*seed->GetTgl()*(1.+angulary);
8119
e0e13b88 8120 Double_t sigmay = clparam->GetRMS0(0,type,zdrift,TMath::Sqrt(TMath::Abs(angulary)));
8121 Double_t sigmaz = clparam->GetRMS0(1,type,zdrift,TMath::Sqrt(TMath::Abs(angularz)));
fd065ea2 8122 seed->SetCurrentSigmaY2(sigmay*sigmay);
8123 seed->SetCurrentSigmaZ2(sigmaz*sigmaz);
47af7ca4 8124 // Float_t sd2 = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fkParam->GetDiffL()*fkParam->GetDiffL();
8125// // Float_t padlength = fkParam->GetPadPitchLength(seed->fSector);
fd065ea2 8126// Float_t padlength = GetPadPitchLength(row);
8127// //
47af7ca4 8128// Float_t sresy = (seed->GetSector() < fkParam->GetNSector()/2) ? 0.2 :0.3;
fd065ea2 8129// seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
8130// //
47af7ca4 8131// Float_t sresz = fkParam->GetZSigma();
fd065ea2 8132// seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
91162307 8133 /*
8134 Float_t wy = GetSigmaY(seed);
8135 Float_t wz = GetSigmaZ(seed);
8136 wy*=wy;
8137 wz*=wz;
8138 if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
8139 printf("problem\n");
8140 }
8141 */
1c53abe2 8142}
8143
91162307 8144
1c53abe2 8145
1c53abe2 8146//__________________________________________________________________________
829455ad 8147void AliTPCtracker::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
1c53abe2 8148 //--------------------------------------------------------------------
8149 //This function "cooks" a track label. If label<0, this track is fake.
8150 //--------------------------------------------------------------------
316c6cd9 8151 AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
8152 if(!t){
8153 printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
8154 return;
8155 }
8156
1c53abe2 8157 Int_t noc=t->GetNumberOfClusters();
91162307 8158 if (noc<10){
d26d9159 8159 //printf("\nnot founded prolongation\n\n\n");
8160 //t->Dump();
91162307 8161 return ;
8162 }
8163 Int_t lb[160];
8164 Int_t mx[160];
8165 AliTPCclusterMI *clusters[160];
8166 //
8167 for (Int_t i=0;i<160;i++) {
8168 clusters[i]=0;
8169 lb[i]=mx[i]=0;
8170 }
1c53abe2 8171
8172 Int_t i;
91162307 8173 Int_t current=0;
8174 for (i=0; i<160 && current<noc; i++) {
8175
8176 Int_t index=t->GetClusterIndex2(i);
8177 if (index<=0) continue;
8178 if (index&0x8000) continue;
8179 //
8180 //clusters[current]=GetClusterMI(index);
b9671574 8181 if (t->GetClusterPointer(i)){
8182 clusters[current]=t->GetClusterPointer(i);
91162307 8183 current++;
8184 }
1c53abe2 8185 }
91162307 8186 noc = current;
1c53abe2 8187
8188 Int_t lab=123456789;
8189 for (i=0; i<noc; i++) {
8190 AliTPCclusterMI *c=clusters[i];
91162307 8191 if (!c) continue;
1c53abe2 8192 lab=TMath::Abs(c->GetLabel(0));
8193 Int_t j;
8194 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
8195 lb[j]=lab;
8196 (mx[j])++;
8197 }
8198
8199 Int_t max=0;
8200 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
8201
8202 for (i=0; i<noc; i++) {
9918f10a 8203 AliTPCclusterMI *c=clusters[i];
91162307 8204 if (!c) continue;
1c53abe2 8205 if (TMath::Abs(c->GetLabel(1)) == lab ||
8206 TMath::Abs(c->GetLabel(2)) == lab ) max++;
8207 }
52033b55 8208 if (noc<=0) { lab=-1; return;}
8209 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
1c53abe2 8210
8211 else {
8212 Int_t tail=Int_t(0.10*noc);
8213 max=0;
91162307 8214 Int_t ind=0;
ec26e231 8215 for (i=1; i<160&&ind<tail; i++) {
91162307 8216 // AliTPCclusterMI *c=clusters[noc-i];
8217 AliTPCclusterMI *c=clusters[i];
8218 if (!c) continue;
1c53abe2 8219 if (lab == TMath::Abs(c->GetLabel(0)) ||
8220 lab == TMath::Abs(c->GetLabel(1)) ||
8221 lab == TMath::Abs(c->GetLabel(2))) max++;
91162307 8222 ind++;
1c53abe2 8223 }
8224 if (max < Int_t(0.5*tail)) lab=-lab;
8225 }
8226
8227 t->SetLabel(lab);
8228
91162307 8229 // delete[] lb;
8230 //delete[] mx;
8231 //delete[] clusters;
1c53abe2 8232}
8233
47966a6d 8234
51ad6848 8235//__________________________________________________________________________
829455ad 8236Int_t AliTPCtracker::CookLabel(AliTPCseed *const t, Float_t wrong,Int_t first, Int_t last) const {
51ad6848 8237 //--------------------------------------------------------------------
8238 //This function "cooks" a track label. If label<0, this track is fake.
8239 //--------------------------------------------------------------------
8240 Int_t noc=t->GetNumberOfClusters();
8241 if (noc<10){
8242 //printf("\nnot founded prolongation\n\n\n");
8243 //t->Dump();
8244 return -1;
8245 }
8246 Int_t lb[160];
8247 Int_t mx[160];
8248 AliTPCclusterMI *clusters[160];
8249 //
8250 for (Int_t i=0;i<160;i++) {
8251 clusters[i]=0;
8252 lb[i]=mx[i]=0;
8253 }
8254
8255 Int_t i;
8256 Int_t current=0;
8257 for (i=0; i<160 && current<noc; i++) {
8258 if (i<first) continue;
8259 if (i>last) continue;
8260 Int_t index=t->GetClusterIndex2(i);
8261 if (index<=0) continue;
8262 if (index&0x8000) continue;
8263 //
8264 //clusters[current]=GetClusterMI(index);
b9671574 8265 if (t->GetClusterPointer(i)){
8266 clusters[current]=t->GetClusterPointer(i);
51ad6848 8267 current++;
8268 }
8269 }
8270 noc = current;
17abbffb 8271 //if (noc<5) return -1;
51ad6848 8272 Int_t lab=123456789;
8273 for (i=0; i<noc; i++) {
8274 AliTPCclusterMI *c=clusters[i];
8275 if (!c) continue;
8276 lab=TMath::Abs(c->GetLabel(0));
8277 Int_t j;
8278 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
8279 lb[j]=lab;
8280 (mx[j])++;
8281 }
8282
8283 Int_t max=0;
8284 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
8285
8286 for (i=0; i<noc; i++) {
8287 AliTPCclusterMI *c=clusters[i];
8288 if (!c) continue;
8289 if (TMath::Abs(c->GetLabel(1)) == lab ||
8290 TMath::Abs(c->GetLabel(2)) == lab ) max++;
8291 }
52033b55 8292 if (noc<=0) { lab=-1; return -1;}
8293 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
51ad6848 8294
8295 else {
8296 Int_t tail=Int_t(0.10*noc);
8297 max=0;
8298 Int_t ind=0;
ec26e231 8299 for (i=1; i<160&&ind<tail; i++) {
51ad6848 8300 // AliTPCclusterMI *c=clusters[noc-i];
8301 AliTPCclusterMI *c=clusters[i];
8302 if (!c) continue;
8303 if (lab == TMath::Abs(c->GetLabel(0)) ||
8304 lab == TMath::Abs(c->GetLabel(1)) ||
8305 lab == TMath::Abs(c->GetLabel(2))) max++;
8306 ind++;
8307 }
8308 if (max < Int_t(0.5*tail)) lab=-lab;
8309 }
8310
8311 // t->SetLabel(lab);
8312 return lab;
8313 // delete[] lb;
8314 //delete[] mx;
8315 //delete[] clusters;
8316}
8317
8318
829455ad 8319Int_t AliTPCtracker::GetRowNumber(Double_t x[3]) const
eea478d3 8320{
8321 //return pad row number for given x vector
8322 Float_t phi = TMath::ATan2(x[1],x[0]);
8323 if(phi<0) phi=2.*TMath::Pi()+phi;
8324 // Get the local angle in the sector philoc
8325 const Float_t kRaddeg = 180/3.14159265358979312;
8326 Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
8327 Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
8328 return GetRowNumber(localx);
8329}
8330
91162307 8331
91162307 8332
829455ad 8333void AliTPCtracker::MakeESDBitmaps(AliTPCseed *t, AliESDtrack *esd)
19b00333 8334{
8335 //-----------------------------------------------------------------------
8336 // Fill the cluster and sharing bitmaps of the track
8337 //-----------------------------------------------------------------------
8338
8339 Int_t firstpoint = 0;
8340 Int_t lastpoint = 159;
8341 AliTPCTrackerPoint *point;
52c51057 8342 AliTPCclusterMI *cluster;
19b00333 8343
bad6eb00 8344 Int_t nclsf = 0;
8345 TBits clusterMap(159);
8346 TBits sharedMap(159);
8347 TBits fitMap(159);
19b00333 8348 for (int iter=firstpoint; iter<lastpoint; iter++) {
52c51057 8349 // Change to cluster pointers to see if we have a cluster at given padrow
bad6eb00 8350
52c51057 8351 cluster = t->GetClusterPointer(iter);
8352 if (cluster) {
bad6eb00 8353 clusterMap.SetBitNumber(iter, kTRUE);
52c51057 8354 point = t->GetTrackPoint(iter);
19b00333 8355 if (point->IsShared())
bad6eb00 8356 sharedMap.SetBitNumber(iter,kTRUE);
19b00333 8357 }
bad6eb00 8358 if (t->GetClusterIndex(iter) >= 0 && (t->GetClusterIndex(iter) & 0x8000) == 0) {
8359 fitMap.SetBitNumber(iter, kTRUE);
8360 nclsf++;
19b00333 8361 }
8362 }
bad6eb00 8363 esd->SetTPCClusterMap(clusterMap);
8364 esd->SetTPCSharedMap(sharedMap);
8365 esd->SetTPCFitMap(fitMap);
8366 if (nclsf != t->GetNumberOfClusters())
27540e35 8367 AliDebug(3,Form("Inconsistency between ncls %d and indices %d (found %d)",t->GetNumberOfClusters(),nclsf,esd->GetTPCClusterMap().CountBits()));
19b00333 8368}
92f513f5 8369
829455ad 8370Bool_t AliTPCtracker::IsFindable(AliTPCseed & track){
76d56fd6 8371 //
8372 // return flag if there is findable cluster at given position
8373 //
8374 Float_t kDeltaZ=10;
8375 Float_t z = track.GetZ();
8376
8377 if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*track.GetX()+kDeltaZ) &&
47af7ca4 8378 TMath::Abs(z)<fkParam->GetZLength(0) &&
76d56fd6 8379 (TMath::Abs(track.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
8380 return kTRUE;
8381 return kFALSE;
8382}
92f513f5 8383
8384
829455ad 8385void AliTPCtracker::AddCovariance(AliTPCseed * seed){
92f513f5 8386 //
e1dadcd0 8387 // Adding systematic error estimate to the covariance matrix
b87c2bbc 8388 // !!!! the systematic error for element 4 is in 1/GeV
8389 // 03.03.2012 MI changed in respect to the previous versions
e1dadcd0 8390 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
8391 //
8392 // use only the diagonal part if not specified otherwise
8393 if (!AliTPCReconstructor::GetRecoParam()->GetUseSystematicCorrelation()) return AddCovarianceAdd(seed);
8394 //
8395 Double_t *covarS= (Double_t*)seed->GetCovariance();
8396 Double_t factor[5]={1,1,1,1,1};
e1dadcd0 8397 factor[0]= TMath::Sqrt(TMath::Abs((covarS[0] + param[0]*param[0])/covarS[0]));
8398 factor[1]= TMath::Sqrt(TMath::Abs((covarS[2] + param[1]*param[1])/covarS[2]));
8399 factor[2]= TMath::Sqrt(TMath::Abs((covarS[5] + param[2]*param[2])/covarS[5]));
8400 factor[3]= TMath::Sqrt(TMath::Abs((covarS[9] + param[3]*param[3])/covarS[9]));
b87c2bbc 8401 factor[4]= TMath::Sqrt(TMath::Abs((covarS[14] +param[4]*param[4])/covarS[14]));
9b550f87 8402 //
8403 factor[0]=factor[2];
8404 factor[4]=factor[2];
e1dadcd0 8405 // 0
8406 // 1 2
8407 // 3 4 5
8408 // 6 7 8 9
8409 // 10 11 12 13 14
8410 for (Int_t i=0; i<5; i++){
8411 for (Int_t j=i; j<5; j++){
8412 Int_t index=seed->GetIndex(i,j);
8413 covarS[index]*=factor[i]*factor[j];
8414 }
8415 }
8416}
8417
92f513f5 8418
829455ad 8419void AliTPCtracker::AddCovarianceAdd(AliTPCseed * seed){
e1dadcd0 8420 //
8421 // Adding systematic error - as additive factor without correlation
8422 //
b87c2bbc 8423 // !!!! the systematic error for element 4 is in 1/GeV
8424 // 03.03.2012 MI changed in respect to the previous versions
8425
92f513f5 8426 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
f47588e0 8427 Double_t *covarIn= (Double_t*)seed->GetCovariance();
92f513f5 8428 Double_t covar[15];
8429 for (Int_t i=0;i<15;i++) covar[i]=0;
8430 // 0
8431 // 1 2
8432 // 3 4 5
8433 // 6 7 8 9
8434 // 10 11 12 13 14
8435 covar[0] = param[0]*param[0];
8436 covar[2] = param[1]*param[1];
8437 covar[5] = param[2]*param[2];
8438 covar[9] = param[3]*param[3];
b87c2bbc 8439 covar[14]= param[4]*param[4];
f47588e0 8440 //
8441 covar[1]=TMath::Sqrt((covar[0]*covar[2]))*covarIn[1]/TMath::Sqrt((covarIn[0]*covarIn[2]));
8442 //
8443 covar[3]=TMath::Sqrt((covar[0]*covar[5]))*covarIn[3]/TMath::Sqrt((covarIn[0]*covarIn[5]));
8444 covar[4]=TMath::Sqrt((covar[2]*covar[5]))*covarIn[4]/TMath::Sqrt((covarIn[2]*covarIn[5]));
8445 //
8446 covar[6]=TMath::Sqrt((covar[0]*covar[9]))*covarIn[6]/TMath::Sqrt((covarIn[0]*covarIn[9]));
8447 covar[7]=TMath::Sqrt((covar[2]*covar[9]))*covarIn[7]/TMath::Sqrt((covarIn[2]*covarIn[9]));
8448 covar[8]=TMath::Sqrt((covar[5]*covar[9]))*covarIn[8]/TMath::Sqrt((covarIn[5]*covarIn[9]));
8449 //
8450 covar[10]=TMath::Sqrt((covar[0]*covar[14]))*covarIn[10]/TMath::Sqrt((covarIn[0]*covarIn[14]));
8451 covar[11]=TMath::Sqrt((covar[2]*covar[14]))*covarIn[11]/TMath::Sqrt((covarIn[2]*covarIn[14]));
8452 covar[12]=TMath::Sqrt((covar[5]*covar[14]))*covarIn[12]/TMath::Sqrt((covarIn[5]*covarIn[14]));
8453 covar[13]=TMath::Sqrt((covar[9]*covar[14]))*covarIn[13]/TMath::Sqrt((covarIn[9]*covarIn[14]));
8454 //
92f513f5 8455 seed->AddCovariance(covar);
8456}
f06a1ff6 8457
ec7e4ad6 8458//_____________________________________________________________________________
829455ad 8459Bool_t AliTPCtracker::IsTPCHVDipEvent(AliESDEvent const *esdEvent)
661f340b 8460{
8461 //
8462 // check events affected by TPC HV dip
8463 //
8464 if(!esdEvent) return kFALSE;
ec7e4ad6 8465
661f340b 8466 // Init TPC OCDB
8467 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
8468 if(!db) return kFALSE;
8469 db->SetRun(esdEvent->GetRunNumber());
ec7e4ad6 8470
661f340b 8471 // maximum allowed voltage before an event is identified as a dip event
8472 // and scanning period
8473 const Double_t kTPCHVdip = db->GetParameters()->GetMaxDipVoltage();
8474 const Double_t dipEventScanPeriod = db->GetParameters()->GetVoltageDipScanPeriod();
8475 const Double_t tevSec = esdEvent->GetTimeStamp();
8476
ec7e4ad6 8477 for(Int_t sector=0; sector<72; sector++)
8478 {
661f340b 8479 // don't use excluded chambers, since the state is not defined at all
8480 if (!db->GetChamberHVStatus(sector)) continue;
8481
8482 // get hv sensor of the chamber
8483 AliDCSSensor *sensor = db->GetChamberHVSensor(sector);
8484 if (!sensor) continue;
8485 TGraph *grSensor=sensor->GetGraph();
8486 if (!grSensor) continue;
8487 if (grSensor->GetN()<1) continue;
ec7e4ad6 8488
661f340b 8489 // get median
8490 const Double_t median = db->GetChamberHighVoltageMedian(sector);
8491 if(median < 1.) continue;
ec7e4ad6 8492
661f340b 8493 for (Int_t ipoint=0; ipoint<grSensor->GetN()-1; ++ipoint){
8494 Double_t nextTime=grSensor->GetX()[ipoint+1]*3600+sensor->GetStartTime();
8495 if (tevSec-dipEventScanPeriod>nextTime) continue;
8496 const Float_t deltaV=TMath::Abs(grSensor->GetY()[ipoint]-median);
8497 if (deltaV>kTPCHVdip) {
8498 AliDebug(3,Form("HV dip detected in ROC '%02d' with dV '%.2f' at time stamp '%.0f'",sector,deltaV,tevSec));
8499 return kTRUE;
8500 }
8501 if (nextTime>tevSec+dipEventScanPeriod) break;
ec7e4ad6 8502 }
661f340b 8503 }
8504
8505 return kFALSE;
8506}
ddfbc51a 8507
8508//________________________________________
829455ad 8509void AliTPCtracker::MarkSeedFree(TObject *sd)
ddfbc51a 8510{
8511 // account that this seed is "deleted"
8512 AliTPCseed* seed = dynamic_cast<AliTPCseed*>(sd);
88492b27 8513 if (!seed) {
b6565e28 8514 AliError(Form("Freeing of non-AliTPCseed %p from the pool is requested",sd));
8515 return;
8516 }
88492b27 8517 int id = seed->GetPoolID();
b6565e28 8518 if (id<0) {
8519 AliError(Form("Freeing of seed %p NOT from the pool is requested",sd));
8520 return;
8521 }
ddfbc51a 8522 // AliInfo(Form("%d %p",id, seed));
8523 fSeedsPool->RemoveAt(id);
8524 if (fFreeSeedsID.GetSize()<=fNFreeSeeds) fFreeSeedsID.Set( 2*fNFreeSeeds + 100 );
8525 fFreeSeedsID.GetArray()[fNFreeSeeds++] = id;
8526}
8527
8528//________________________________________
829455ad 8529TObject *&AliTPCtracker::NextFreeSeed()
ddfbc51a 8530{
8531 // return next free slot where the seed can be created
8532 fLastSeedID = fNFreeSeeds ? fFreeSeedsID.GetArray()[--fNFreeSeeds] : fSeedsPool->GetEntriesFast();
8533 // AliInfo(Form("%d",fLastSeedID));
8534 return (*fSeedsPool)[ fLastSeedID ];
8535 //
8536}
8537
8538//________________________________________
829455ad 8539void AliTPCtracker::ResetSeedsPool()
ddfbc51a 8540{
8541 // mark all seeds in the pool as unused
8542 AliInfo(Form("CurrentSize: %d, BookedUpTo: %d, free: %d",fSeedsPool->GetSize(),fSeedsPool->GetEntriesFast(),fNFreeSeeds));
8543 fNFreeSeeds = 0;
8544 fSeedsPool->Clear("C"); // RS: nominally the seeds may allocate memory...
8545}
72e25240 8546
829455ad 8547Int_t AliTPCtracker::PropagateToRowHLT(AliTPCseed *pt, int nrow)
72e25240 8548{
8549 AliTPCseed &t=*pt;
8550 Double_t x= GetXrow(nrow);
8551 Double_t ymax= GetMaxY(nrow);
8552 Int_t rotate = 0;
8553 Int_t nRotations=0;
8554 int ret = 1;
8555 do{
8556 rotate = 0;
8557 if (!t.PropagateTo(x) ){
8558 //cout<<"can't propagate to row "<<nrow<<", x="<<t.GetX()<<" -> "<<x<<endl;
8559 //t.Print();
8560 ret = 0;
8561 break;
8562 }
8563 t.SetRow(nrow);
8564 Double_t y = t.GetY();
8565 if( y > ymax ) {
8566 if( rotate!=-1 ) rotate=1;
8567 } else if (y <-ymax) {
8568 if( rotate!=1 ) rotate = -1;
8569 }
8570 if( rotate==0 ) break;
8571 //cout<<"rotate at row "<<nrow<<": "<<rotate<<endl;
8572 if (!t.Rotate( rotate==1 ?fSectors->GetAlpha() :-fSectors->GetAlpha())) {
8573 //cout<<"can't rotate "<<endl;
8574 ret=0;
8575 break;
8576 }
8577 nRotations+= rotate;
8578 }while(rotate!=0);
8579 if( nRotations!=0 ){
8580 int newSec= t.GetRelativeSector()+nRotations;
8581 if( newSec>=fN ) newSec-=fN;
8582 else if( newSec<0 ) newSec +=fN;
8583 //cout<<"rotate at row "<<nrow<<": "<<nRotations<<" times "<<" sec "
8584 //<< t.GetRelativeSector()<<" -> "<<newSec<<endl;
8585 t.SetRelativeSector(newSec);
8586 }
8587 return ret;
8588}
8589
829455ad 8590void AliTPCtracker::TrackFollowingHLT(TObjArray *const arr )
72e25240 8591{
8592 //
8593 // try to track in parralel
8594
8595 Int_t nRows=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8596 fSectors=fInnerSec;
8597
8598 Int_t nseed=arr->GetEntriesFast();
8599 //cout<<"Parallel tracking My.."<<endl;
8600 double shapeY2[160], shapeZ2[160];
8601 Int_t clusterIndex[160];
8602
8603 for (Int_t iSeed=0; iSeed<nseed; iSeed++) {
8604 //if( iSeed!=1 ) continue;
8605 AliTPCseed *pt=(AliTPCseed*) (arr->UncheckedAt(iSeed));
8606 if (!pt) continue;
8607 AliTPCseed &t=*pt;
8608
8609 //cout <<"Pt "<<t.GetSigned1Pt()<<endl;
8610
8611 // t.Print();
8612
8613 for( int iter=0; iter<3; iter++ ){
8614
8615 t.Reset();
8616 t.SetLastPoint(0); // first cluster in track position
8617 t.SetFirstPoint(nRows-1);
8618 t.ResetCovariance(.1);
8619 t.SetNumberOfClusters(0);
8620 for( int i=0; i<nRows; i++ ){
8621 shapeY2[i]=1.;
8622 shapeZ2[i]=1.;
8623 clusterIndex[i]=-1;
8624 t.SetClusterIndex2(i,-1);
8625 t.SetClusterIndex(i,-1);
8626 }
8627
8628 // pick up the clusters
8629
8630 Double_t roady = 20.;
8631 Double_t roadz = 20.;
8632 double roadr = 5;
8633
8634 AliTPCseed t0(t);
8635 t0.Reset();
8636 int nClusters = 0;
8637 {
8638 t0.SetRelativeSector(t.GetRelativeSector());
8639 t0.SetLastPoint(0); // first cluster in track position
8640 t0.SetFirstPoint(159);
8641 for (Int_t nr=0; nr<nRows; nr++){
8642 if( nr<fInnerSec->GetNRows() ) fSectors=fInnerSec;
8643 else fSectors=fOuterSec;
8644
8645 if( !PropagateToRowHLT(&t0, nr ) ){ break; }
8646 if (TMath::Abs(t0.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8647 //cout<<"Snp is too big: "<<t0.GetSnp()<<endl;
8648 continue;
8649 }
8650 if (!IsActive(t0.GetRelativeSector(),nr)) {
8651 continue;
8652 }
8653
8654 if( iter==0 ){
8655 GetShape(&t0,nr);
8656 shapeY2[nr]=t0.GetCurrentSigmaY2();
8657 shapeZ2[nr]=t0.GetCurrentSigmaZ2();
8658 }
8659
8660 AliTPCtrackerRow &krow=GetRow(t0.GetRelativeSector(),nr);
8661 if( !krow ) continue;
8662
8663 t.SetClusterIndex2(nr,-3); // foundable
8664 t.SetClusterIndex(nr,-3);
8665
8666 AliTPCclusterMI *cl=0;
8667 UInt_t uindex = 0;
8668 cl = krow.FindNearest2(t0.GetY(),t0.GetZ(),roady,roadz,uindex);
8669 if (!cl ) continue;
8670 double dy = cl->GetY()-t0.GetY();
8671 double dz = cl->GetZ()-t0.GetZ();
8672 double dr = sqrt(dy*dy+dz*dz);
8673 if( dr>roadr ){
8674 //cout<<"row "<<nr<<", best cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8675 continue;
8676 }
8677 //cout<<"row "<<nr<<", found cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8678
8679 t0.SetClusterPointer(nr, cl);
8680 clusterIndex[nr] = krow.GetIndex(uindex);
8681 if( t0.GetFirstPoint()>nr ) t0.SetFirstPoint(nr);
8682 t0.SetLastPoint(nr);
8683 nClusters++;
8684 }
8685 }
8686
8687 if( nClusters <3 ){
8688 //cout<<"NOT ENOUGTH CLUSTERS: "<<nClusters<<endl;
8689 break;
8690 }
8691 Int_t basePoints[3] = {t0.GetFirstPoint(),t0.GetFirstPoint(),t0.GetLastPoint()};
8692
8693 // find midpoint
8694 {
8695 Int_t midRow = (t0.GetLastPoint()-t0.GetFirstPoint())/2;
8696 int dist=200;
8697 for( int nr=t0.GetFirstPoint()+1; nr< t0.GetLastPoint(); nr++){
8698 if( !t0.GetClusterPointer(nr) ) continue;
8699 int d = TMath::Abs(nr-midRow);
8700 if( d < dist ){
8701 dist = d;
8702 basePoints[1] = nr;
8703 }
8704 }
8705 }
8706
8707 // first fit 3 base points
8708 if( 1||iter<2 ){
8709 //cout<<"Fit3: "<<endl;
8710 for( int icl=0; icl<3; icl++){
8711 int nr = basePoints[icl];
8712 int lr=nr;
8713 if( nr>=fInnerSec->GetNRows()){
8714 lr = nr - fInnerSec->GetNRows();
8715 fSectors=fOuterSec;
8716 } else fSectors=fInnerSec;
8717
8718 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8719 if(!cl){
8720 //cout<<"WRONG!!!!"<<endl;
8721 continue;
8722 }
8723 int iSec = cl->GetDetector() %fkNIS;
8724 int rotate = iSec - t.GetRelativeSector();
8725 if( rotate!=0 ){
8726 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8727 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8728 //cout<<"can't rotate "<<endl;
8729 break;
8730 }
8731 t.SetRelativeSector(iSec);
8732 }
8733 Double_t x= cl->GetX();
8734 if (!t.PropagateTo(x)){
8735 //cout<<"can't propagate to x="<<x<<endl;
8736 break;
8737 }
8738
8739 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8740 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8741 break;
8742 }
8743 //cout<<"fit3 : row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8744
8745 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8746 t.SetCurrentCluster(cl);
8747 t.SetRow(lr);
8748
8749 t.SetErrorY2(shapeY2[nr]);
8750 t.SetErrorZ2(shapeZ2[nr]);
8751 if( icl==0 ){
8752 double cov[15];
8753 for( int j=0; j<15; j++ ) cov[j]=0;
8754 cov[0]=10;
8755 cov[2]=10;
8756 cov[5]=.5;
8757 cov[9]=.5;
8758 cov[14]=1.;
8759 t.AliExternalTrackParam::AddCovariance(cov);
8760 }
8761 if( !UpdateTrack(&t,0) ){
8762 //cout<<"Can not update"<<endl;
8763 //t.Print();
8764 t.SetClusterIndex2(nr,-1);
8765 t.SetClusterIndex(nr,-1);
8766 t.SetClusterPointer(nr,0);
8767 break;
8768 }
8769 //t.SetClusterPointer(nr, cl);
8770 }
8771
8772 //t.SetLastPoint(t0.GetLastPoint());
8773 //t.SetFirstPoint(t0.GetFirstPoint());
8774
8775 //cout<<"Fit: "<<endl;
8776 for (Int_t nr=t0.GetLastPoint(); nr>=t0.GetFirstPoint(); nr-- ){
8777 int lr=nr;
8778 if( nr>=fInnerSec->GetNRows()){
8779 lr = nr - fInnerSec->GetNRows();
8780 fSectors=fOuterSec;
8781 } else fSectors=fInnerSec;
8782
8783 if(1|| iter<2 ){
8784 if( nr == basePoints[0] ) continue;
8785 if( nr == basePoints[1] ) continue;
8786 if( nr == basePoints[2] ) continue;
8787 }
8788 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8789 if(!cl) continue;
8790
8791 int iSec = cl->GetDetector() %fkNIS;
8792 int rotate = iSec - t.GetRelativeSector();
8793 if( rotate!=0 ){
8794 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8795 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8796 //cout<<"can't rotate "<<endl;
8797 break;
8798 }
8799 t.SetRelativeSector(iSec);
8800 }
8801 Double_t x= cl->GetX();
8802 if (!t.PropagateTo(x)){
8803 //cout<<"can't propagate to x="<<x<<endl;
8804 break;
8805 }
8806 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8807 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8808 break;
8809 }
8810
8811 //cout<<"fit: row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8812
8813 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8814 t.SetCurrentCluster(cl);
8815 t.SetRow(lr);
8816 t.SetErrorY2(shapeY2[nr]);
8817 t.SetErrorZ2(shapeZ2[nr]);
8818
8819 if( !UpdateTrack(&t,0) ){
8820 //cout<<"Can not update"<<endl;
8821 //t.Print();
8822 t.SetClusterIndex2(nr,-1);
8823 t.SetClusterIndex(nr,-1);
8824 break;
8825 }
8826 //t.SetClusterPointer(nr, cl);
8827 }
8828 }
8829 //cout<<"After iter "<<iter<<": N clusters="<<t.GetNumberOfClusters()<<" : "<<nClusters<<endl;
8830 }
8831
8832 //cout<<"fitted track"<<iSeed<<endl;
8833 //t.Print();
8834 //cout<<"Statistics: "<<endl;
8835 Int_t foundable,found,shared;
8836 t.GetClusterStatistic(0,nRows, found, foundable, shared, kTRUE);
8837 t.SetNFoundable(foundable);
8838 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8839
8840 }
8841}
8842
8843
829455ad 8844TObjArray * AliTPCtracker::MakeSeedsHLT(const AliESDEvent *hltEvent)
72e25240 8845{
8846 // tracking
8847 //
8848
8849 if( !hltEvent ) return 0;
8850
8851
8852 Int_t nentr=hltEvent->GetNumberOfTracks();
8853
8854 AliInfo(Form("Using %d HLT tracks for seeding",nentr));
8855
8856 TObjArray * seeds = new TObjArray(nentr);
8857
8858 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8859 Int_t index = 0;
8860
8861 Int_t nTr=hltEvent->GetNumberOfTracks();
8862
8863 for( int itr=0; itr<nTr; itr++ ){
8864 //if( itr!=97 ) continue;
8865 const AliExternalTrackParam *param = hltEvent->GetTrack(itr)->GetTPCInnerParam();
8866 if( !param ) continue;
8867 //if( TMath::Abs(esdTr->GetSigned1Pt())>1 ) continue;
8868 //if( TMath::Abs(esdTr->GetTgl())>1. ) continue;
8869 AliTPCtrack tr;
8870 tr.Set(param->GetX(),param->GetAlpha(),param->GetParameter(),param->GetCovariance());
8871 tr.SetNumberOfClusters(0);
8872 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed(tr);
8873
8874 Double_t alpha=seed->GetAlpha();// - fSectors->GetAlphaShift();
8875 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
8876 if (alpha < 0. ) alpha += 2.*TMath::Pi();
8877 //
8878 seed->SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
8879 Double_t alphaSec = fSectors->GetAlpha() * seed->GetRelativeSector() + fSectors->GetAlphaShift();
8880
8881 if (alphaSec >= TMath::Pi()) alphaSec -= 2.*TMath::Pi();
8882 if (alphaSec < -TMath::Pi()) alphaSec += 2.*TMath::Pi();
8883
8884 seed->Rotate(alphaSec - alpha);
8885
8886 seed->SetPoolID(fLastSeedID);
8887 seed->SetIsSeeding(kTRUE);
8888 seed->SetSeed1(nup-1);
8889 seed->SetSeed2(nup-2);
8890 seed->SetSeedType(0);
8891 seed->SetFirstPoint(-1);
8892 seed->SetLastPoint(-1);
8893 seeds->AddLast(seed); // note, track is seed, don't free the seed
8894 index++;
8895 //if( index>3 ) break;
8896 }
8897
8898
8899 fSectors = fOuterSec;
8900
8901 TrackFollowingHLT(seeds );
8902
8903 nTr = seeds->GetEntriesFast();
8904 for( int itr=0; itr<nTr; itr++ ){
8905 AliTPCseed * seed = (AliTPCseed*) seeds->UncheckedAt(itr);
8906 if( !seed ) continue;
8907 //FollowBackProlongation(*seed,0);
8908 // cout<<seed->GetNumberOfClusters()<<endl;
8909 Int_t foundable,found,shared;
8910 seed->GetClusterStatistic(0,nup, found, foundable, shared, kTRUE);
8911 seed->SetNFoundable(foundable);
8912 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8913 //if ((found<0.55*foundable) || shared>0.5*found ){// || (seed->GetSigmaY2()+seed->GetSigmaZ2())>0.5){
8914 //MarkSeedFree(seeds->RemoveAt(itr));
8915 //continue;
8916 //}
8917 if (seed->GetNumberOfClusters()<30 ||
8918 seed->GetNumberOfClusters() < seed->GetNFoundable()*0.6 ||
8919 seed->GetNShared()>0.4*seed->GetNumberOfClusters() ) {
8920 MarkSeedFree(seeds->RemoveAt(itr));
8921 continue;
8922 }
8923
8924 for( int ir=0; ir<nup; ir++){
8925 AliTPCclusterMI *c = seed->GetClusterPointer(ir);
8926 if( c ) c->Use(10);
8927 }
8928 }
492a4365 8929 std::cout<<"\n\nHLT tracks left: "<<seeds->GetEntries()<<" out of "<<hltEvent->GetNumberOfTracks()<<endl<<endl;
72e25240 8930 return seeds;
8931}
5576d489 8932
8933void AliTPCtracker::FillClusterOccupancyInfo()
8934{
8935 //fill the cluster occupancy info into the ESD friend
8936 AliESDfriend* esdFriend = static_cast<AliESDfriend*>(fEvent->FindListObject("AliESDfriend"));
8937 if (!esdFriend) return;
8938
8939 for (Int_t isector=0; isector<18; isector++){
8940 AliTPCtrackerSector &iroc = fInnerSec[isector];
8941 AliTPCtrackerSector &oroc = fOuterSec[isector];
8942 //all clusters
8943 esdFriend->SetNclustersTPC(isector, iroc.GetNClInSector(0));
8944 esdFriend->SetNclustersTPC(isector+18,iroc.GetNClInSector(1));
8945 esdFriend->SetNclustersTPC(isector+36,oroc.GetNClInSector(0));
8946 esdFriend->SetNclustersTPC(isector+54,oroc.GetNClInSector(1));
8947 //clusters used in tracking
8948 esdFriend->SetNclustersTPCused(isector, iroc.GetNClUsedInSector(0));
8949 esdFriend->SetNclustersTPCused(isector+18, iroc.GetNClUsedInSector(1));
8950 esdFriend->SetNclustersTPCused(isector+36, oroc.GetNClUsedInSector(0));
8951 esdFriend->SetNclustersTPCused(isector+54, oroc.GetNClUsedInSector(1));
8952 }
8953}