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