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