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