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