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