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