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