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