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