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