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