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