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