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