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