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