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