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