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