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