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