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