]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/AliTPCtrackerMI.cxx
Returning to compiling version
[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);
eea478d3 5772 //kink->fTPCdensity2[0][0]=-1;
5773 //kink->fTPCdensity2[0][1]=-1;
5774 kink->SetTPCDensity2(-1,0,0);
5775 kink->SetTPCDensity2(1,0,1);
51ad6848 5776 //
eea478d3 5777 Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 5778 if (row0<15) row0=15;
5779 //
eea478d3 5780 Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 5781 if (row1>145) row1=145;
5782 //
5783 Int_t found,foundable,shared;
5784 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
eea478d3 5785 if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),0,0);
51ad6848 5786 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
eea478d3 5787 if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),0,1);
51ad6848 5788 }
5789
5790}
5791
eea478d3 5792void AliTPCtrackerMI::UpdateKinkQualityD(AliTPCseed * seed){
91162307 5793 //
eea478d3 5794 // update Kink quality information for daughter after refit
91162307 5795 //
eea478d3 5796 if (seed->GetKinkIndex(0)<=0) return;
5797 for (Int_t ikink=0;ikink<3;ikink++){
5798 Int_t index = seed->GetKinkIndex(ikink);
5799 if (index<=0) break;
5800 index = TMath::Abs(index)-1;
5801 AliESDkink * kink = fEvent->GetKink(index);
5802 kink->SetTPCDensity2(-1,1,0);
5803 kink->SetTPCDensity2(-1,1,1);
91162307 5804 //
eea478d3 5805 Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5806 if (row0<15) row0=15;
5807 //
5808 Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5809 if (row1>145) row1=145;
5810 //
5811 Int_t found,foundable,shared;
5812 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
5813 if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),1,0);
5814 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
5815 if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),1,1);
91162307 5816 }
eea478d3 5817
5818}
5819
5820
6c94f330 5821Int_t AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, AliESDkink &knk)
eea478d3 5822{
91162307 5823 //
eea478d3 5824 // check kink point for given track
5825 // if return value=0 kink point not found
5826 // otherwise seed0 correspond to mother particle
5827 // seed1 correspond to daughter particle
5828 // kink parameter of kink point
6c94f330 5829 AliKink &kink=(AliKink &)knk;
91162307 5830
b9671574 5831 Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
5832 Int_t first = seed->GetFirstPoint();
5833 Int_t last = seed->GetLastPoint();
eea478d3 5834 if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
91162307 5835
eea478d3 5836
5837 AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
5838 if (!seed1) return 0;
b9671574 5839 FollowProlongation(*seed1,seed->GetLastPoint()-20);
eea478d3 5840 seed1->Reset(kTRUE);
5841 FollowProlongation(*seed1,158);
5842 seed1->Reset(kTRUE);
b9671574 5843 last = seed1->GetLastPoint();
eea478d3 5844 //
5845 AliTPCseed *seed0 = new AliTPCseed(*seed);
5846 seed0->Reset(kFALSE);
5847 seed0->Reset();
5848 //
5849 AliTPCseed param0[20]; // parameters along the track
5850 AliTPCseed param1[20]; // parameters along the track
6c94f330 5851 AliKink kinks[20]; // corresponding kink parameters
eea478d3 5852 Int_t rows[20];
5853 for (Int_t irow=0; irow<20;irow++){
5854 rows[irow] = first +((last-first)*irow)/19;
5855 }
5856 // store parameters along the track
5857 //
5858 for (Int_t irow=0;irow<20;irow++){
5859 FollowBackProlongation(*seed0, rows[irow]);
5860 FollowProlongation(*seed1,rows[19-irow]);
316c6cd9 5861 param0[irow] = *seed0;
5862 param1[19-irow] = *seed1;
eea478d3 5863 }
5864 //
5865 // define kinks
5866 for (Int_t irow=0; irow<19;irow++){
5867 kinks[irow].SetMother(param0[irow]);
5868 kinks[irow].SetDaughter(param1[irow]);
5869 kinks[irow].Update();
5870 }
5871 //
5872 // choose kink with biggest change of angle
5873 Int_t index =-1;
5874 Double_t maxchange= 0;
5875 for (Int_t irow=1;irow<19;irow++){
5876 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
5877 if (TMath::Abs(kinks[irow].GetR())<110.) continue;
6c94f330 5878 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 5879 if ( quality > maxchange){
5880 maxchange = quality;
5881 index = irow;
5882 //
91162307 5883 }
5884 }
eea478d3 5885 delete seed0;
5886 delete seed1;
5887 if (index<0) return 0;
5888 //
5889 Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
5890 seed0 = new AliTPCseed(param0[index]);
5891 seed1 = new AliTPCseed(param1[index]);
5892 seed0->Reset(kFALSE);
5893 seed1->Reset(kFALSE);
6c94f330 5894 seed0->ResetCovariance(10.);
5895 seed1->ResetCovariance(10.);
eea478d3 5896 FollowProlongation(*seed0,0);
5897 FollowBackProlongation(*seed1,158);
316c6cd9 5898 mother = *seed0; // backup mother at position 0
eea478d3 5899 seed0->Reset(kFALSE);
5900 seed1->Reset(kFALSE);
6c94f330 5901 seed0->ResetCovariance(10.);
5902 seed1->ResetCovariance(10.);
eea478d3 5903 //
5904 first = TMath::Max(row0-20,0);
5905 last = TMath::Min(row0+20,158);
5906 //
5907 for (Int_t irow=0; irow<20;irow++){
5908 rows[irow] = first +((last-first)*irow)/19;
5909 }
5910 // store parameters along the track
5911 //
5912 for (Int_t irow=0;irow<20;irow++){
5913 FollowBackProlongation(*seed0, rows[irow]);
5914 FollowProlongation(*seed1,rows[19-irow]);
316c6cd9 5915 param0[irow] = *seed0;
5916 param1[19-irow] = *seed1;
eea478d3 5917 }
5918 //
5919 // define kinks
5920 for (Int_t irow=0; irow<19;irow++){
5921 kinks[irow].SetMother(param0[irow]);
5922 kinks[irow].SetDaughter(param1[irow]);
5923 // param0[irow].Dump();
5924 //param1[irow].Dump();
5925 kinks[irow].Update();
5926 }
5927 //
5928 // choose kink with biggest change of angle
5929 index =-1;
5930 maxchange= 0;
5931 for (Int_t irow=0;irow<20;irow++){
5932 if (TMath::Abs(kinks[irow].GetR())>250.) continue;
5933 if (TMath::Abs(kinks[irow].GetR())<90.) continue;
6c94f330 5934 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 5935 if ( quality > maxchange){
5936 maxchange = quality;
5937 index = irow;
5938 //
91162307 5939 }
5940 }
5941 //
5942 //
b9671574 5943 if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
eea478d3 5944 delete seed0;
5945 delete seed1;
5946 return 0;
1627d1c4 5947 }
eea478d3 5948 // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
1627d1c4 5949
eea478d3 5950 kink.SetMother(param0[index]);
5951 kink.SetDaughter(param1[index]);
5952 kink.Update();
5953 row0 = GetRowNumber(kink.GetR());
5954 kink.SetTPCRow0(row0);
5955 kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
5956 kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
5957 kink.SetIndex(-10,0);
b9671574 5958 kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
5959 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
5960 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
eea478d3 5961 //
5962 //
5963 // new (&mother) AliTPCseed(param0[index]);
316c6cd9 5964 daughter = param1[index];
eea478d3 5965 daughter.SetLabel(kink.GetLabel(1));
5966 param0[index].Reset(kTRUE);
5967 FollowProlongation(param0[index],0);
316c6cd9 5968 mother = param0[index];
eea478d3 5969 mother.SetLabel(kink.GetLabel(0));
5970 delete seed0;
5971 delete seed1;
5972 //
5973 return 1;
1627d1c4 5974}
5975
5976
5977
5978
91162307 5979AliTPCseed* AliTPCtrackerMI::ReSeed(AliTPCseed *t)
5980{
5981 //
5982 // reseed - refit - track
5983 //
5984 Int_t first = 0;
5985 // Int_t last = fSectors->GetNRows()-1;
5986 //
5987 if (fSectors == fOuterSec){
b9671574 5988 first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
91162307 5989 //last =
5990 }
5991 else
b9671574 5992 first = t->GetFirstPoint();
91162307 5993 //
5994 AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
5995 FollowBackProlongation(*t,fSectors->GetNRows()-1);
5996 t->Reset(kFALSE);
5997 FollowProlongation(*t,first);
5998 return seed;
5999}
6000
6001
6002
6003
6004
6005
6006
1c53abe2 6007//_____________________________________________________________________________
6008Int_t AliTPCtrackerMI::ReadSeeds(const TFile *inp) {
6009 //-----------------------------------------------------------------
6010 // This function reades track seeds.
6011 //-----------------------------------------------------------------
6012 TDirectory *savedir=gDirectory;
6013
6014 TFile *in=(TFile*)inp;
6015 if (!in->IsOpen()) {
6016 cerr<<"AliTPCtrackerMI::ReadSeeds(): input file is not open !\n";
6017 return 1;
6018 }
6019
6020 in->cd();
6021 TTree *seedTree=(TTree*)in->Get("Seeds");
6022 if (!seedTree) {
6023 cerr<<"AliTPCtrackerMI::ReadSeeds(): ";
6024 cerr<<"can't get a tree with track seeds !\n";
6025 return 2;
6026 }
6027 AliTPCtrack *seed=new AliTPCtrack;
6028 seedTree->SetBranchAddress("tracks",&seed);
6029
6030 if (fSeeds==0) fSeeds=new TObjArray(15000);
6031
6032 Int_t n=(Int_t)seedTree->GetEntries();
6033 for (Int_t i=0; i<n; i++) {
6034 seedTree->GetEvent(i);
bbc6cd2c 6035 fSeeds->AddLast(new AliTPCseed(*seed/*,seed->GetAlpha()*/));
1c53abe2 6036 }
6037
6038 delete seed;
6039 delete seedTree;
6040 savedir->cd();
6041 return 0;
6042}
6043
af885e0f 6044Int_t AliTPCtrackerMI::Clusters2Tracks (AliESDEvent *esd)
d26d9159 6045{
6046 //
d9b8978b 6047 if (fSeeds) DeleteSeeds();
d26d9159 6048 fEvent = esd;
6049 Clusters2Tracks();
6050 if (!fSeeds) return 1;
6051 FillESD(fSeeds);
6052 return 0;
6053 //
6054}
6055
6056
1c53abe2 6057//_____________________________________________________________________________
f8aae377 6058Int_t AliTPCtrackerMI::Clusters2Tracks() {
1c53abe2 6059 //-----------------------------------------------------------------
6060 // This is a track finder.
6061 //-----------------------------------------------------------------
91162307 6062 TDirectory *savedir=gDirectory;
1c53abe2 6063 TStopwatch timer;
d26d9159 6064
91162307 6065 fIteration = 0;
6066 fSeeds = Tracking();
1c53abe2 6067
6bdc18d6 6068 if (fDebug>0){
6069 Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
6070 }
91162307 6071 //activate again some tracks
6072 for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
6073 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6074 if (!pt) continue;
6075 Int_t nc=t.GetNumberOfClusters();
6076 if (nc<20) {
6077 delete fSeeds->RemoveAt(i);
6078 continue;
eea478d3 6079 }
6080 CookLabel(pt,0.1);
b9671574 6081 if (pt->GetRemoval()==10) {
91162307 6082 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
6083 pt->Desactivate(10); // make track again active
6084 else{
6085 pt->Desactivate(20);
6086 delete fSeeds->RemoveAt(i);
6087 }
6088 }
6089 }
51ad6848 6090 //
6091 RemoveUsed2(fSeeds,0.85,0.85,0);
a3232aae 6092 if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
6d493ea0 6093 //FindCurling(fSeeds, fEvent,0);
6094 if (AliTPCReconstructor::StreamLevel()>2) FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
81e97e0d 6095 RemoveUsed2(fSeeds,0.5,0.4,20);
6d493ea0 6096 FindSplitted(fSeeds, fEvent,0); // find multi found tracks
6097
81e97e0d 6098 // //
6099// // refit short tracks
6100// //
6101 Int_t nseed=fSeeds->GetEntriesFast();
1c53abe2 6102 //
91162307 6103 Int_t found = 0;
6104 for (Int_t i=0; i<nseed; i++) {
6105 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6106 if (!pt) continue;
6107 Int_t nc=t.GetNumberOfClusters();
6108 if (nc<15) {
6109 delete fSeeds->RemoveAt(i);
6110 continue;
6111 }
6112 CookLabel(pt,0.1); //For comparison only
6113 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 6114 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
d9b8978b 6115 found++;
6116 if (fDebug>0) cerr<<found<<'\r';
b9671574 6117 pt->SetLab2(i);
91162307 6118 }
6119 else
6120 delete fSeeds->RemoveAt(i);
91162307 6121 }
6122
6123
6124 //RemoveOverlap(fSeeds,0.99,7,kTRUE);
6125 SignShared(fSeeds);
6126 //RemoveUsed(fSeeds,0.9,0.9,6);
1c53abe2 6127 //
91162307 6128 nseed=fSeeds->GetEntriesFast();
6129 found = 0;
6130 for (Int_t i=0; i<nseed; i++) {
6131 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6132 if (!pt) continue;
6133 Int_t nc=t.GetNumberOfClusters();
6134 if (nc<15) {
6135 delete fSeeds->RemoveAt(i);
6136 continue;
6137 }
6138 t.SetUniqueID(i);
6139 t.CookdEdx(0.02,0.6);
6140 // CheckKinkPoint(&t,0.05);
6141 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 6142 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6bdc18d6 6143 found++;
6144 if (fDebug>0){
6145 cerr<<found<<'\r';
6146 }
b9671574 6147 pt->SetLab2(i);
91162307 6148 }
6149 else
6150 delete fSeeds->RemoveAt(i);
d26d9159 6151 //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
6152 //if (seed1){
6153 // FollowProlongation(*seed1,0);
6154 // Int_t n = seed1->GetNumberOfClusters();
6155 // printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
6156 // printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
6157 //
6158 //}
6159 //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
6160
91162307 6161 }
6162
6163 SortTracks(fSeeds, 1);
1c53abe2 6164
982aff31 6165 /*
91162307 6166 fIteration = 1;
982aff31 6167 PrepareForBackProlongation(fSeeds,5.);
91162307 6168 PropagateBack(fSeeds);
6169 printf("Time for back propagation: \t");timer.Print();timer.Start();
6170
6171 fIteration = 2;
1c53abe2 6172
982aff31 6173 PrepareForProlongation(fSeeds,5.);
6174 PropagateForward2(fSeeds);
d26d9159 6175
91162307 6176 printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
6177 // RemoveUsed(fSeeds,0.7,0.7,6);
6178 //RemoveOverlap(fSeeds,0.9,7,kTRUE);
d26d9159 6179
1c53abe2 6180 nseed=fSeeds->GetEntriesFast();
91162307 6181 found = 0;
6182 for (Int_t i=0; i<nseed; i++) {
1c53abe2 6183 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6184 if (!pt) continue;
6185 Int_t nc=t.GetNumberOfClusters();
91162307 6186 if (nc<15) {
6187 delete fSeeds->RemoveAt(i);
6188 continue;
6189 }
1c53abe2 6190 t.CookdEdx(0.02,0.6);
91162307 6191 // CookLabel(pt,0.1); //For comparison only
6192 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6193 if ((pt->IsActive() || (pt->fRemoval==10) )){
6194 cerr<<found++<<'\r';
6195 }
6196 else
6197 delete fSeeds->RemoveAt(i);
6198 pt->fLab2 = i;
1c53abe2 6199 }
91162307 6200 */
6201
c9427e08 6202 // fNTracks = found;
6bdc18d6 6203 if (fDebug>0){
6204 Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
6205 }
91162307 6206 //
6bdc18d6 6207 // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
6208 Info("Clusters2Tracks","Number of found tracks %d",found);
91162307 6209 savedir->cd();
91162307 6210 // UnloadClusters();
d26d9159 6211 //
1c53abe2 6212 return 0;
6213}
6214
91162307 6215void AliTPCtrackerMI::Tracking(TObjArray * arr)
6216{
6217 //
6218 // tracking of the seeds
6219 //
6220
6221 fSectors = fOuterSec;
6222 ParallelTracking(arr,150,63);
6223 fSectors = fOuterSec;
6224 ParallelTracking(arr,63,0);
6225}
6226
6227TObjArray * AliTPCtrackerMI::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
6228{
6229 //
6230 //
6231 //tracking routine
6232 TObjArray * arr = new TObjArray;
6233 //
6234 fSectors = fOuterSec;
6235 TStopwatch timer;
6236 timer.Start();
6237 for (Int_t sec=0;sec<fkNOS;sec++){
6238 if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
6239 if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);
6240 if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
6241 }
6242 if (fDebug>0){
6bdc18d6 6243 Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
91162307 6244 timer.Print();
6245 timer.Start();
6246 }
6247 Tracking(arr);
6248 if (fDebug>0){
6249 timer.Print();
6250 }
6251
6252 return arr;
6253}
6254
6255TObjArray * AliTPCtrackerMI::Tracking()
6256{
6257 //
6258 //
a3232aae 6259 if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
91162307 6260 TStopwatch timer;
6261 timer.Start();
6262 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
6263
6264 TObjArray * seeds = new TObjArray;
6265 TObjArray * arr=0;
6266
6267 Int_t gap =20;
6268 Float_t cuts[4];
6269 cuts[0] = 0.002;
6270 cuts[1] = 1.5;
6271 cuts[2] = 3.;
6272 cuts[3] = 3.;
6273 Float_t fnumber = 3.0;
6274 Float_t fdensity = 3.0;
6275
6276 //
6277 //find primaries
6278 cuts[0]=0.0066;
6279 for (Int_t delta = 0; delta<18; delta+=6){
6280 //
6281 cuts[0]=0.0070;
6282 cuts[1] = 1.5;
6283 arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
6284 SumTracks(seeds,arr);
6285 SignClusters(seeds,fnumber,fdensity);
6286 //
6287 for (Int_t i=2;i<6;i+=2){
6288 // seed high pt tracks
6289 cuts[0]=0.0022;
6290 cuts[1]=0.3;
6291 arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
6292 SumTracks(seeds,arr);
6293 SignClusters(seeds,fnumber,fdensity);
6294 }
6295 }
6296 fnumber = 4;
6297 fdensity = 4.;
6298 // RemoveUsed(seeds,0.9,0.9,1);
6299 // UnsignClusters();
6300 // SignClusters(seeds,fnumber,fdensity);
6301
6302 //find primaries
6303 cuts[0]=0.0077;
6304 for (Int_t delta = 20; delta<120; delta+=10){
6305 //
6306 // seed high pt tracks
6307 cuts[0]=0.0060;
6308 cuts[1]=0.3;
6309 cuts[2]=6.;
6310 arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
6311 SumTracks(seeds,arr);
6312 SignClusters(seeds,fnumber,fdensity);
6313
6314 cuts[0]=0.003;
6315 cuts[1]=0.3;
6316 cuts[2]=6.;
6317 arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
6318 SumTracks(seeds,arr);
6319 SignClusters(seeds,fnumber,fdensity);
6320 }
6321
6322 cuts[0] = 0.01;
6323 cuts[1] = 2.0;
6324 cuts[2] = 3.;
6325 cuts[3] = 2.0;
6326 fnumber = 2.;
6327 fdensity = 2.;
6328
6329 if (fDebug>0){
6bdc18d6 6330 Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 6331 timer.Print();
6332 timer.Start();
6333 }
6334 // RemoveUsed(seeds,0.75,0.75,1);
6335 //UnsignClusters();
6336 //SignClusters(seeds,fnumber,fdensity);
6337
6338 // find secondaries
6339
6340 cuts[0] = 0.3;
6341 cuts[1] = 1.5;
6342 cuts[2] = 3.;
6343 cuts[3] = 1.5;
6344
6345 arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
6346 SumTracks(seeds,arr);
6347 SignClusters(seeds,fnumber,fdensity);
6348 //
6349 arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
6350 SumTracks(seeds,arr);
6351 SignClusters(seeds,fnumber,fdensity);
6352 //
6353 arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
6354 SumTracks(seeds,arr);
6355 SignClusters(seeds,fnumber,fdensity);
6356 //
6357
6358
6359 for (Int_t delta = 3; delta<30; delta+=5){
6360 //
6361 cuts[0] = 0.3;
6362 cuts[1] = 1.5;
6363 cuts[2] = 3.;
6364 cuts[3] = 1.5;
6365 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
6366 SumTracks(seeds,arr);
6367 SignClusters(seeds,fnumber,fdensity);
6368 //
6369 arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
6370 SumTracks(seeds,arr);
6371 SignClusters(seeds,fnumber,fdensity);
6372 //
6373 }
6374 fnumber = 1;
6375 fdensity = 1;
6376 //
6377 // change cuts
6378 fnumber = 2.;
6379 fdensity = 2.;
6380 cuts[0]=0.0080;
6381
7d27c1df 6382 Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
6383
91162307 6384 // find secondaries
7d27c1df 6385 for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=10){
91162307 6386 //
6387 cuts[0] = 0.3;
2bd61959 6388 cuts[1] = 3.5;
91162307 6389 cuts[2] = 3.;
2bd61959 6390 cuts[3] = 3.5;
91162307 6391 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
6392 SumTracks(seeds,arr);
6393 SignClusters(seeds,fnumber,fdensity);
6394 //
6395 arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
6396 SumTracks(seeds,arr);
6397 SignClusters(seeds,fnumber,fdensity);
6398 }
6399
6400 if (fDebug>0){
6bdc18d6 6401 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 6402 timer.Print();
6403 timer.Start();
6404 }
6405
6406 return seeds;
6407 //
6408
6409}
6410
6411
a3232aae 6412TObjArray * AliTPCtrackerMI::TrackingSpecial()
6413{
6414 //
6415 // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
6416 // no primary vertex seeding tried
6417 //
6418 TStopwatch timer;
6419 timer.Start();
6420 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
6421
6422 TObjArray * seeds = new TObjArray;
6423 TObjArray * arr=0;
6424
6425 Int_t gap = 15;
6426 Float_t cuts[4];
6427 Float_t fnumber = 3.0;
6428 Float_t fdensity = 3.0;
6429
6430 // find secondaries
6431 cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC(); // max curvature
6432 cuts[1] = 3.5; // max tan(phi) angle for seeding
6433 cuts[2] = 3.; // not used (cut on z primary vertex)
6434 cuts[3] = 3.5; // max tan(theta) angle for seeding
6435
6436 for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
6437 //
6438 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
6439 SumTracks(seeds,arr);
6440 SignClusters(seeds,fnumber,fdensity);
6441 }
6442
6443 if (fDebug>0){
6444 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
6445 timer.Print();
6446 timer.Start();
6447 }
6448
6449 return seeds;
6450 //
6451
6452}
6453
6454
c1ea348f 6455void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *&arr2) const
91162307 6456{
6457 //
6458 //sum tracks to common container
6459 //remove suspicious tracks
6460 Int_t nseed = arr2->GetEntriesFast();
6461 for (Int_t i=0;i<nseed;i++){
6462 AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);
6463 if (pt){
a3232aae 6464 //
6465 // remove tracks with too big curvature
6466 //
6467 if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
6468 delete arr2->RemoveAt(i);
6469 continue;
6470 }
ca142b1f 6471 // REMOVE VERY SHORT TRACKS
6472 if (pt->GetNumberOfClusters()<20){
6473 delete arr2->RemoveAt(i);
6474 continue;
6475 }// patch 28 fev06
91162307 6476 // NORMAL ACTIVE TRACK
6477 if (pt->IsActive()){
6478 arr1->AddLast(arr2->RemoveAt(i));
6479 continue;
6480 }
6481 //remove not usable tracks
b9671574 6482 if (pt->GetRemoval()!=10){
91162307 6483 delete arr2->RemoveAt(i);
6484 continue;
6485 }
ca142b1f 6486
91162307 6487 // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
6488 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
6489 arr1->AddLast(arr2->RemoveAt(i));
6490 else{
6491 delete arr2->RemoveAt(i);
6492 }
6493 }
6494 }
c1ea348f 6495 delete arr2; arr2 = 0;
91162307 6496}
6497
6498
1c53abe2 6499
91162307 6500void AliTPCtrackerMI::ParallelTracking(TObjArray * arr, Int_t rfirst, Int_t rlast)
1c53abe2 6501{
6502 //
6503 // try to track in parralel
6504
91162307 6505 Int_t nseed=arr->GetEntriesFast();
1c53abe2 6506 //prepare seeds for tracking
6507 for (Int_t i=0; i<nseed; i++) {
91162307 6508 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 6509 if (!pt) continue;
6510 if (!t.IsActive()) continue;
6511 // follow prolongation to the first layer
b9671574 6512 if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fParam->GetNRowLow()>rfirst+1) )
c9427e08 6513 FollowProlongation(t, rfirst+1);
1c53abe2 6514 }
6515
6516
6517 //
982aff31 6518 for (Int_t nr=rfirst; nr>=rlast; nr--){
6519 if (nr<fInnerSec->GetNRows())
6520 fSectors = fInnerSec;
6521 else
6522 fSectors = fOuterSec;
1c53abe2 6523 // make indexes with the cluster tracks for given
1c53abe2 6524
6525 // find nearest cluster
6526 for (Int_t i=0; i<nseed; i++) {
91162307 6527 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 6528 if (!pt) continue;
51ad6848 6529 if (nr==80) pt->UpdateReference();
1c53abe2 6530 if (!pt->IsActive()) continue;
91162307 6531 // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
b9671574 6532 if (pt->GetRelativeSector()>17) {
1627d1c4 6533 continue;
6534 }
91162307 6535 UpdateClusters(t,nr);
1c53abe2 6536 }
6537 // prolonagate to the nearest cluster - if founded
6538 for (Int_t i=0; i<nseed; i++) {
91162307 6539 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
1c53abe2 6540 if (!pt) continue;
1627d1c4 6541 if (!pt->IsActive()) continue;
91162307 6542 // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
b9671574 6543 if (pt->GetRelativeSector()>17) {
1627d1c4 6544 continue;
6545 }
91162307 6546 FollowToNextCluster(*pt,nr);
1c53abe2 6547 }
91162307 6548 }
6549}
6550
47966a6d 6551void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray * arr,Float_t fac) const
91162307 6552{
6553 //
6554 //
6555 // if we use TPC track itself we have to "update" covariance
6556 //
6557 Int_t nseed= arr->GetEntriesFast();
6558 for (Int_t i=0;i<nseed;i++){
6559 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6560 if (pt) {
6561 pt->Modify(fac);
6562 //
6563 //rotate to current local system at first accepted point
b9671574 6564 Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
91162307 6565 Int_t sec = (index&0xff000000)>>24;
6566 sec = sec%18;
6567 Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
6568 if (angle1>TMath::Pi())
6569 angle1-=2.*TMath::Pi();
6570 Float_t angle2 = pt->GetAlpha();
6571
6572 if (TMath::Abs(angle1-angle2)>0.001){
6573 pt->Rotate(angle1-angle2);
6574 //angle2 = pt->GetAlpha();
6575 //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
6576 //if (pt->GetAlpha()<0)
6577 // pt->fRelativeSector+=18;
6578 //sec = pt->fRelativeSector;
6579 }
6580
6581 }
6582
6583 }
6584
6585
6586}
47966a6d 6587void AliTPCtrackerMI::PrepareForProlongation(TObjArray * arr, Float_t fac) const
91162307 6588{
6589 //
6590 //
6591 // if we use TPC track itself we have to "update" covariance
6592 //
6593 Int_t nseed= arr->GetEntriesFast();
6594 for (Int_t i=0;i<nseed;i++){
6595 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6596 if (pt) {
6597 pt->Modify(fac);
b9671574 6598 pt->SetFirstPoint(pt->GetLastPoint());
91162307 6599 }
6600
6601 }
6602
6603
6604}
6605
6606Int_t AliTPCtrackerMI::PropagateBack(TObjArray * arr)
6607{
6608 //
6609 // make back propagation
6610 //
6611 Int_t nseed= arr->GetEntriesFast();
6612 for (Int_t i=0;i<nseed;i++){
6613 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
51ad6848 6614 if (pt&& pt->GetKinkIndex(0)<=0) {
d9b8978b 6615 //AliTPCseed *pt2 = new AliTPCseed(*pt);
91162307 6616 fSectors = fInnerSec;
d26d9159 6617 //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
6618 //fSectors = fOuterSec;
4d158c36 6619 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
6620 //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
d9b8978b 6621 // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
4d158c36 6622 // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
d9b8978b 6623 //}
51ad6848 6624 }
6625 if (pt&& pt->GetKinkIndex(0)>0) {
6626 AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
b9671574 6627 pt->SetFirstPoint(kink->GetTPCRow0());
51ad6848 6628 fSectors = fInnerSec;
6629 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
6630 }
6d493ea0 6631 CookLabel(pt,0.3);
91162307 6632 }
6633 return 0;
6634}
6635
6636
6637Int_t AliTPCtrackerMI::PropagateForward2(TObjArray * arr)
6638{
6639 //
6640 // make forward propagation
6641 //
6642 Int_t nseed= arr->GetEntriesFast();
4d158c36 6643 //
91162307 6644 for (Int_t i=0;i<nseed;i++){
6645 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6646 if (pt) {
91162307 6647 FollowProlongation(*pt,0);
6d493ea0 6648 CookLabel(pt,0.3);
4d158c36 6649 }
6d493ea0 6650
91162307 6651 }
6652 return 0;
6653}
6654
6655
6656Int_t AliTPCtrackerMI::PropagateForward()
6657{
b67e07dc 6658 //
6659 // propagate track forward
4d158c36 6660 //UnsignClusters();
d26d9159 6661 Int_t nseed = fSeeds->GetEntriesFast();
6662 for (Int_t i=0;i<nseed;i++){
6663 AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
6664 if (pt){
6665 AliTPCseed &t = *pt;
6666 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
6667 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
6668 if (alpha < 0. ) alpha += 2.*TMath::Pi();
b9671574 6669 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
d26d9159 6670 }
6671 }
6672
91162307 6673 fSectors = fOuterSec;
d26d9159 6674 ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
91162307 6675 fSectors = fInnerSec;
d26d9159 6676 ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
91162307 6677 //WriteTracks();
6678 return 1;
6679}
6680
6681
6682
6683
6684
6685
6686Int_t AliTPCtrackerMI::PropagateBack(AliTPCseed * pt, Int_t row0, Int_t row1)
6687{
6688 //
6689 // make back propagation, in between row0 and row1
6690 //
1c53abe2 6691
91162307 6692 if (pt) {
6693 fSectors = fInnerSec;
6694 Int_t r1;
6695 //
6696 if (row1<fSectors->GetNRows())
6697 r1 = row1;
6698 else
6699 r1 = fSectors->GetNRows()-1;
6700
6701 if (row0<fSectors->GetNRows()&& r1>0 )
6702 FollowBackProlongation(*pt,r1);
6703 if (row1<=fSectors->GetNRows())
6704 return 0;
6705 //
6706 r1 = row1 - fSectors->GetNRows();
6707 if (r1<=0) return 0;
6708 if (r1>=fOuterSec->GetNRows()) return 0;
6709 fSectors = fOuterSec;
6710 return FollowBackProlongation(*pt,r1);
6711 }
6712 return 0;
6713}
6714
6715
6716
6717
6718void AliTPCtrackerMI::GetShape(AliTPCseed * seed, Int_t row)
6719{
6720 //
6721 //
a1ec4d07 6722 Float_t sd2 = TMath::Abs((fParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
91162307 6723 // Float_t padlength = fParam->GetPadPitchLength(seed->fSector);
6724 Float_t padlength = GetPadPitchLength(row);
6725 //
b9671574 6726 Float_t sresy = (seed->GetSector() < fParam->GetNSector()/2) ? 0.2 :0.3;
3f82c4f2 6727 Double_t angulary = seed->GetSnp();
91162307 6728 angulary = angulary*angulary/(1-angulary*angulary);
b9671574 6729 seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
91162307 6730 //
6731 Float_t sresz = fParam->GetZSigma();
6732 Float_t angularz = seed->GetTgl();
b9671574 6733 seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
91162307 6734 /*
6735 Float_t wy = GetSigmaY(seed);
6736 Float_t wz = GetSigmaZ(seed);
6737 wy*=wy;
6738 wz*=wz;
6739 if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
6740 printf("problem\n");
6741 }
6742 */
1c53abe2 6743}
6744
91162307 6745
1c53abe2 6746Float_t AliTPCtrackerMI::GetSigmaY(AliTPCseed * seed)
6747{
6748 //
6749 //
a1ec4d07 6750 Float_t sd2 = TMath::Abs((fParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
b9671574 6751 Float_t padlength = fParam->GetPadPitchLength(seed->GetSector());
6752 Float_t sres = (seed->GetSector() < fParam->GetNSector()/2) ? 0.2 :0.3;
1c53abe2 6753 Float_t angular = seed->GetSnp();
6754 angular = angular*angular/(1-angular*angular);
6755 // angular*=angular;
6756 //angular = TMath::Sqrt(angular/(1-angular));
6757 Float_t res = TMath::Sqrt(sd2+padlength*padlength*angular/12.+sres*sres);
6758 return res;
6759}
6760Float_t AliTPCtrackerMI::GetSigmaZ(AliTPCseed * seed)
6761{
6762 //
6763 //
a1ec4d07 6764 Float_t sd2 = TMath::Abs((fParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
b9671574 6765 Float_t padlength = fParam->GetPadPitchLength(seed->GetSector());
1c53abe2 6766 Float_t sres = fParam->GetZSigma();
6767 Float_t angular = seed->GetTgl();
6768 Float_t res = TMath::Sqrt(sd2+padlength*padlength*angular*angular/12.+sres*sres);
6769 return res;
6770}
6771
6772
1c53abe2 6773//__________________________________________________________________________
af32720d 6774void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
1c53abe2 6775 //--------------------------------------------------------------------
6776 //This function "cooks" a track label. If label<0, this track is fake.
6777 //--------------------------------------------------------------------
316c6cd9 6778 AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
6779 if(!t){
6780 printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
6781 return;
6782 }
6783
1c53abe2 6784 Int_t noc=t->GetNumberOfClusters();
91162307 6785 if (noc<10){
d26d9159 6786 //printf("\nnot founded prolongation\n\n\n");
6787 //t->Dump();
91162307 6788 return ;
6789 }
6790 Int_t lb[160];
6791 Int_t mx[160];
6792 AliTPCclusterMI *clusters[160];
6793 //
6794 for (Int_t i=0;i<160;i++) {
6795 clusters[i]=0;
6796 lb[i]=mx[i]=0;
6797 }
1c53abe2 6798
6799 Int_t i;
91162307 6800 Int_t current=0;
6801 for (i=0; i<160 && current<noc; i++) {
6802
6803 Int_t index=t->GetClusterIndex2(i);
6804 if (index<=0) continue;
6805 if (index&0x8000) continue;
6806 //
6807 //clusters[current]=GetClusterMI(index);
b9671574 6808 if (t->GetClusterPointer(i)){
6809 clusters[current]=t->GetClusterPointer(i);
91162307 6810 current++;
6811 }
1c53abe2 6812 }
91162307 6813 noc = current;
1c53abe2 6814
6815 Int_t lab=123456789;
6816 for (i=0; i<noc; i++) {
6817 AliTPCclusterMI *c=clusters[i];
91162307 6818 if (!c) continue;
1c53abe2 6819 lab=TMath::Abs(c->GetLabel(0));
6820 Int_t j;
6821 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
6822 lb[j]=lab;
6823 (mx[j])++;
6824 }
6825
6826 Int_t max=0;
6827 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
6828
6829 for (i=0; i<noc; i++) {
9918f10a 6830 AliTPCclusterMI *c=clusters[i];
91162307 6831 if (!c) continue;
1c53abe2 6832 if (TMath::Abs(c->GetLabel(1)) == lab ||
6833 TMath::Abs(c->GetLabel(2)) == lab ) max++;
6834 }
6835
6836 if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
6837
6838 else {
6839 Int_t tail=Int_t(0.10*noc);
6840 max=0;
91162307 6841 Int_t ind=0;
6842 for (i=1; i<=160&&ind<tail; i++) {
6843 // AliTPCclusterMI *c=clusters[noc-i];
6844 AliTPCclusterMI *c=clusters[i];
6845 if (!c) continue;
1c53abe2 6846 if (lab == TMath::Abs(c->GetLabel(0)) ||
6847 lab == TMath::Abs(c->GetLabel(1)) ||
6848 lab == TMath::Abs(c->GetLabel(2))) max++;
91162307 6849 ind++;
1c53abe2 6850 }
6851 if (max < Int_t(0.5*tail)) lab=-lab;
6852 }
6853
6854 t->SetLabel(lab);
6855
91162307 6856 // delete[] lb;
6857 //delete[] mx;
6858 //delete[] clusters;
1c53abe2 6859}
6860
47966a6d 6861
51ad6848 6862//__________________________________________________________________________
6863Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong,Int_t first, Int_t last) const {
6864 //--------------------------------------------------------------------
6865 //This function "cooks" a track label. If label<0, this track is fake.
6866 //--------------------------------------------------------------------
6867 Int_t noc=t->GetNumberOfClusters();
6868 if (noc<10){
6869 //printf("\nnot founded prolongation\n\n\n");
6870 //t->Dump();
6871 return -1;
6872 }
6873 Int_t lb[160];
6874 Int_t mx[160];
6875 AliTPCclusterMI *clusters[160];
6876 //
6877 for (Int_t i=0;i<160;i++) {
6878 clusters[i]=0;
6879 lb[i]=mx[i]=0;
6880 }
6881
6882 Int_t i;
6883 Int_t current=0;
6884 for (i=0; i<160 && current<noc; i++) {
6885 if (i<first) continue;
6886 if (i>last) continue;
6887 Int_t index=t->GetClusterIndex2(i);
6888 if (index<=0) continue;
6889 if (index&0x8000) continue;
6890 //
6891 //clusters[current]=GetClusterMI(index);
b9671574 6892 if (t->GetClusterPointer(i)){
6893 clusters[current]=t->GetClusterPointer(i);
51ad6848 6894 current++;
6895 }
6896 }
6897 noc = current;
6898 if (noc<5) return -1;
6899 Int_t lab=123456789;
6900 for (i=0; i<noc; i++) {
6901 AliTPCclusterMI *c=clusters[i];
6902 if (!c) continue;
6903 lab=TMath::Abs(c->GetLabel(0));
6904 Int_t j;
6905 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
6906 lb[j]=lab;
6907 (mx[j])++;
6908 }
6909
6910 Int_t max=0;
6911 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
6912
6913 for (i=0; i<noc; i++) {
6914 AliTPCclusterMI *c=clusters[i];
6915 if (!c) continue;
6916 if (TMath::Abs(c->GetLabel(1)) == lab ||
6917 TMath::Abs(c->GetLabel(2)) == lab ) max++;
6918 }
6919
6920 if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
6921
6922 else {
6923 Int_t tail=Int_t(0.10*noc);
6924 max=0;
6925 Int_t ind=0;
6926 for (i=1; i<=160&&ind<tail; i++) {
6927 // AliTPCclusterMI *c=clusters[noc-i];
6928 AliTPCclusterMI *c=clusters[i];
6929 if (!c) continue;
6930 if (lab == TMath::Abs(c->GetLabel(0)) ||
6931 lab == TMath::Abs(c->GetLabel(1)) ||
6932 lab == TMath::Abs(c->GetLabel(2))) max++;
6933 ind++;
6934 }
6935 if (max < Int_t(0.5*tail)) lab=-lab;
6936 }
6937
6938 // t->SetLabel(lab);
6939 return lab;
6940 // delete[] lb;
6941 //delete[] mx;
6942 //delete[] clusters;
6943}
6944
6945
47966a6d 6946Int_t AliTPCtrackerMI::AliTPCSector::GetRowNumber(Double_t x) const
6947{
6948 //return pad row number for this x
6949 Double_t r;
6950 if (fN < 64){
6951 r=fRow[fN-1].GetX();
6952 if (x > r) return fN;
6953 r=fRow[0].GetX();
6954 if (x < r) return -1;
6955 return Int_t((x-r)/fPadPitchLength + 0.5);}
6956 else{
6957 r=fRow[fN-1].GetX();
6958 if (x > r) return fN;
6959 r=fRow[0].GetX();
6960 if (x < r) return -1;
6961 Double_t r1=fRow[64].GetX();
6962 if(x<r1){
6963 return Int_t((x-r)/f1PadPitchLength + 0.5);}
6964 else{
6965 return (Int_t((x-r1)/f2PadPitchLength + 0.5)+64);}
6966 }
6967}
6968
eea478d3 6969Int_t AliTPCtrackerMI::GetRowNumber(Double_t x[3]) const
6970{
6971 //return pad row number for given x vector
6972 Float_t phi = TMath::ATan2(x[1],x[0]);
6973 if(phi<0) phi=2.*TMath::Pi()+phi;
6974 // Get the local angle in the sector philoc
6975 const Float_t kRaddeg = 180/3.14159265358979312;
6976 Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
6977 Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
6978 return GetRowNumber(localx);
6979}
6980
1c53abe2 6981//_________________________________________________________________________
6982void AliTPCtrackerMI::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) {
6983 //-----------------------------------------------------------------------
6984 // Setup inner sector
6985 //-----------------------------------------------------------------------
6986 if (f==0) {
6987 fAlpha=par->GetInnerAngle();
6988 fAlphaShift=par->GetInnerAngleShift();
6989 fPadPitchWidth=par->GetInnerPadPitchWidth();
6990 fPadPitchLength=par->GetInnerPadPitchLength();
6991 fN=par->GetNRowLow();
316c6cd9 6992 if(fRow)delete [] fRow;fRow = 0;
1c53abe2 6993 fRow=new AliTPCRow[fN];
6994 for (Int_t i=0; i<fN; i++) {
6995 fRow[i].SetX(par->GetPadRowRadiiLow(i));
b9671574 6996 fRow[i].SetDeadZone(1.5); //1.5 cm of dead zone
1c53abe2 6997 }
6998 } else {
6999 fAlpha=par->GetOuterAngle();
7000 fAlphaShift=par->GetOuterAngleShift();
7001 fPadPitchWidth = par->GetOuterPadPitchWidth();
7002 fPadPitchLength = par->GetOuter1PadPitchLength();
7003 f1PadPitchLength = par->GetOuter1PadPitchLength();
7004 f2PadPitchLength = par->GetOuter2PadPitchLength();
1c53abe2 7005 fN=par->GetNRowUp();
316c6cd9 7006 if(fRow)delete [] fRow;fRow = 0;
1c53abe2 7007 fRow=new AliTPCRow[fN];
7008 for (Int_t i=0; i<fN; i++) {
7009 fRow[i].SetX(par->GetPadRowRadiiUp(i));
b9671574 7010 fRow[i].SetDeadZone(1.5); // 1.5 cm of dead zone
1c53abe2 7011 }
7012 }
7013}
7014
e046d791 7015AliTPCtrackerMI::AliTPCRow::AliTPCRow():
7016 fDeadZone(0.),
7017 fClusters1(0),
7018 fN1(0),
7019 fClusters2(0),
7020 fN2(0),
7021 fN(0),
7022 fX(0.)
7023{
b67e07dc 7024 //
7025 // default constructor
e046d791 7026 //
b67e07dc 7027}
1c53abe2 7028
7029AliTPCtrackerMI::AliTPCRow::~AliTPCRow(){
7030 //
c1ea348f 7031 for (Int_t i = 0; i < fN1; i++)
7032 fClusters1[i].~AliTPCclusterMI();
7033 delete [] fClusters1;
7034 for (Int_t i = 0; i < fN2; i++)
7035 fClusters2[i].~AliTPCclusterMI();
7036 delete [] fClusters2;
1c53abe2 7037}
7038
7039
7040
1c53abe2 7041//_________________________________________________________________________
7042void
7043AliTPCtrackerMI::AliTPCRow::InsertCluster(const AliTPCclusterMI* c, UInt_t index) {
7044 //-----------------------------------------------------------------------
7045 // Insert a cluster into this pad row in accordence with its y-coordinate
7046 //-----------------------------------------------------------------------
7047 if (fN==kMaxClusterPerRow) {
7048 cerr<<"AliTPCRow::InsertCluster(): Too many clusters !\n"; return;
7049 }
7050 if (fN==0) {fIndex[0]=index; fClusters[fN++]=c; return;}
7051 Int_t i=Find(c->GetZ());
7052 memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliTPCclusterMI*));
7053 memmove(fIndex +i+1 ,fIndex +i,(fN-i)*sizeof(UInt_t));
7054 fIndex[i]=index; fClusters[i]=c; fN++;
7055}
7056
982aff31 7057void AliTPCtrackerMI::AliTPCRow::ResetClusters() {
7058 //
7059 // reset clusters
c1ea348f 7060 // MvL: Need to call destructors for AliTPCclusterMI, to delete fInfo
7061 for (Int_t i = 0; i < fN1; i++)
7062 fClusters1[i].~AliTPCclusterMI();
7063 delete [] fClusters1; fClusters1=0;
7064 for (Int_t i = 0; i < fN2; i++)
7065 fClusters2[i].~AliTPCclusterMI();
7066 delete [] fClusters2; fClusters2=0;
7067
982aff31 7068 fN = 0;
7069 fN1 = 0;
7070 fN2 = 0;
7071 //delete[] fClusterArray;
c1ea348f 7072
982aff31 7073 //fClusterArray=0;
982aff31 7074}
7075
91162307 7076
1c53abe2 7077//___________________________________________________________________
7078Int_t AliTPCtrackerMI::AliTPCRow::Find(Double_t z) const {
7079 //-----------------------------------------------------------------------
7080 // Return the index of the nearest cluster
7081 //-----------------------------------------------------------------------
7082 if (fN==0) return 0;
7083 if (z <= fClusters[0]->GetZ()) return 0;
7084 if (z > fClusters[fN-1]->GetZ()) return fN;
7085 Int_t b=0, e=fN-1, m=(b+e)/2;
7086 for (; b<e; m=(b+e)/2) {
7087 if (z > fClusters[m]->GetZ()) b=m+1;
7088 else e=m;
7089 }
7090 return m;
7091}
7092
7093
7094
1627d1c4 7095//___________________________________________________________________
7096AliTPCclusterMI * AliTPCtrackerMI::AliTPCRow::FindNearest(Double_t y, Double_t z, Double_t roady, Double_t roadz) const {
7097 //-----------------------------------------------------------------------
7098 // Return the index of the nearest cluster in z y
7099 //-----------------------------------------------------------------------
7100 Float_t maxdistance = roady*roady + roadz*roadz;
7101
7102 AliTPCclusterMI *cl =0;
7103 for (Int_t i=Find(z-roadz); i<fN; i++) {
7104 AliTPCclusterMI *c=(AliTPCclusterMI*)(fClusters[i]);
7105 if (c->GetZ() > z+roadz) break;
7106 if ( (c->GetY()-y) > roady ) continue;
7107 Float_t distance = (c->GetZ()-z)*(c->GetZ()-z)+(c->GetY()-y)*(c->GetY()-y);
7108 if (maxdistance>distance) {
7109 maxdistance = distance;
7110 cl=c;
7111 }
7112 }
7113 return cl;
7114}
7115
91162307 7116AliTPCclusterMI * AliTPCtrackerMI::AliTPCRow::FindNearest2(Double_t y, Double_t z, Double_t roady, Double_t roadz,UInt_t & index) const
7117{
7118 //-----------------------------------------------------------------------
7119 // Return the index of the nearest cluster in z y
7120 //-----------------------------------------------------------------------
7121 Float_t maxdistance = roady*roady + roadz*roadz;
91162307 7122 AliTPCclusterMI *cl =0;
3381b665 7123
7124 //PH Check boundaries. 510 is the size of fFastCluster
7125 Int_t iz1 = Int_t(z-roadz+254.5);
7126 if (iz1<0 || iz1>=510) return cl;
b9671574 7127 iz1 = TMath::Max(GetFastCluster(iz1)-1,0);
3381b665 7128 Int_t iz2 = Int_t(z+roadz+255.5);
7129 if (iz2<0 || iz2>=510) return cl;
b9671574 7130 iz2 = TMath::Min(GetFastCluster(iz2)+1,fN);
6d493ea0 7131 Bool_t skipUsed = !(AliTPCReconstructor::GetRecoParam()->GetClusterSharing());
91162307 7132 //FindNearest3(y,z,roady,roadz,index);
7133 // for (Int_t i=Find(z-roadz); i<fN; i++) {
7134 for (Int_t i=iz1; i<iz2; i++) {
7135 AliTPCclusterMI *c=(AliTPCclusterMI*)(fClusters[i]);
7136 if (c->GetZ() > z+roadz) break;
7137 if ( c->GetY()-y > roady ) continue;
7138 if ( y-c->GetY() > roady ) continue;
6d493ea0 7139 if (skipUsed && c->IsUsed(11)) continue;
91162307 7140 Float_t distance = (c->GetZ()-z)*(c->GetZ()-z)+(c->GetY()-y)*(c->GetY()-y);
7141 if (maxdistance>distance) {
7142 maxdistance = distance;
7143 cl=c;
7144 index =i;
7145 //roady = TMath::Sqrt(maxdistance);
7146 }
7147 }
7148 return cl;
7149}
7150
7151
7152
91162307 7153
91162307 7154
19b00333 7155void AliTPCtrackerMI::MakeBitmaps(AliTPCseed *t)
7156{
7157 //-----------------------------------------------------------------------
7158 // Fill the cluster and sharing bitmaps of the track
7159 //-----------------------------------------------------------------------
7160
7161 Int_t firstpoint = 0;
7162 Int_t lastpoint = 159;
7163 AliTPCTrackerPoint *point;
7164
7165 for (int iter=firstpoint; iter<lastpoint; iter++) {
7166 point = t->GetTrackPoint(iter);
7167 if (point) {
7168 t->SetClusterMapBit(iter, kTRUE);
7169 if (point->IsShared())
7170 t->SetSharedMapBit(iter,kTRUE);
7171 else
7172 t->SetSharedMapBit(iter, kFALSE);
7173 }
7174 else {
7175 t->SetClusterMapBit(iter, kFALSE);
7176 t->SetSharedMapBit(iter, kFALSE);
7177 }
7178 }
7179}