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