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