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