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