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