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