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