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