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