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