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