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