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