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