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