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