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