]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/Rec/AliTPCtracker.cxx
Calculate crosstalk correction in separate function. Do calculation in 2 itterations...
[u/mrichter/AliRoot.git] / TPC / Rec / AliTPCtracker.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//
dee67df8 24// The track fitting is based on Kalman filtering approach
6d493ea0 25// The track finding steps:
26// 1. Seeding - with and without vertex constraint
27// - seeding with vertex constain done at first n^2 proble
28// - seeding without vertex constraint n^3 problem
29// 2. Tracking - follow prolongation road - find cluster - update kalman track
6d493ea0 30// The seeding and tracking is repeated several times, in different seeding region.
31// This approach enables to find the track which cannot be seeded in some region of TPC
32// 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) ...
33
34// With this approach we reach almost 100 % efficiency also for high occupancy events.
35// (If the seeding efficiency in a region is about 90 % than with logical or of several
36// regions we will reach 100% (in theory - supposing independence)
37
38// Repeating several seeding - tracking procedures some of the tracks can be find
39// several times.
40
41// The procedures to remove multi find tacks are impremented:
42// RemoveUsed2 - fast procedure n problem -
43// Algorithm - Sorting tracks according quality
44// remove tracks with some shared fraction
45// Sharing in respect to all tacks
46// Signing clusters in gold region
47// FindSplitted - slower algorithm n^2
48// Sort the tracks according quality
49// Loop over pair of tracks
50// If overlap with other track bigger than threshold - remove track
51//
52// FindCurling - Finds the pair of tracks which are curling
53// - About 10% of tracks can be find with this procedure
54// The combinatorial background is too big to be used in High
55// multiplicity environment
56// - n^2 problem - Slow procedure - currently it is disabled because of
57// low efficiency
58//
59// The number of splitted tracks can be reduced disabling the sharing of the cluster.
60// tpcRecoParam-> SetClusterSharing(kFALSE);
61// IT IS HIGHLY non recomended to use it in high flux enviroonment
62// Even using this switch some tracks can be found more than once
63// (because of multiple seeding and low quality tracks which will not cross full chamber)
64//
65//
66// The tracker itself can be debugged - the information about tracks can be stored in several // phases of the reconstruction
67// To enable storage of the TPC tracks in the ESD friend track
16299eac 68// use AliTPCReconstructor::SetStreamLevel(n);
6d493ea0 69//
65e67c9c 70// The debug level - different procedure produce tree for numerical debugging of code and data (see comments foEStreamFlags in AliTPCtracker.h )
6d493ea0 71//
92f513f5 72
73//
74// Adding systematic errors to the covariance:
75//
76// The systematic errors due to the misalignment and miscalibration are added to the covariance matrix
77// of the tracks (not to the clusters as they are dependent):
78// The parameters form AliTPCRecoParam are used AliTPCRecoParam::GetSystematicError
b87c2bbc 79// The systematic errors are expressed there in RMS - position (cm), angle (rad), curvature (1/GeV)
92f513f5 80// The default values are 0.
81//
65e67c9c 82// The systematic errors are added to the covariance matrix in following places:
92f513f5 83//
829455ad 84// 1. During fisrt itteration - AliTPCtracker::FillESD
92f513f5 85// 2. Second iteration -
829455ad 86// 2.a ITS->TPC - AliTPCtracker::ReadSeeds
87// 2.b TPC->TRD - AliTPCtracker::PropagateBack
92f513f5 88// 3. Third iteration -
829455ad 89// 3.a TRD->TPC - AliTPCtracker::ReadSeeds
90// 3.b TPC->ITS - AliTPCtracker::RefitInward
92f513f5 91//
47966a6d 92
93/* $Id$ */
94
cc5e9db0 95#include "Riostream.h"
6d171107 96#include <TClonesArray.h>
97#include <TFile.h>
98#include <TObjArray.h>
99#include <TTree.h>
8cc1870a 100#include <TMatrixD.h>
6d64657a 101#include <TGraphErrors.h>
661f340b 102#include <TTimeStamp.h>
a3232aae 103#include "AliLog.h"
47966a6d 104#include "AliComplexCluster.h"
af885e0f 105#include "AliESDEvent.h"
aad72f45 106#include "AliESDtrack.h"
107#include "AliESDVertex.h"
6c94f330 108#include "AliKink.h"
109#include "AliV0.h"
91162307 110#include "AliHelix.h"
91162307 111#include "AliRunLoader.h"
6d171107 112#include "AliTPCClustersRow.h"
113#include "AliTPCParam.h"
9996a03b 114#include "AliTPCReconstructor.h"
6d171107 115#include "AliTPCpolyTrack.h"
81e97e0d 116#include "AliTPCreco.h"
9350f379 117#include "AliTPCseed.h"
118
119#include "AliTPCtrackerSector.h"
829455ad 120#include "AliTPCtracker.h"
6d171107 121#include "TStopwatch.h"
81e97e0d 122#include "AliTPCReconstructor.h"
5d837844 123#include "AliAlignObj.h"
124#include "AliTrackPointArray.h"
6d493ea0 125#include "TRandom.h"
24db6af7 126#include "AliTPCcalibDB.h"
6d64657a 127#include "AliTPCcalibDButil.h"
24db6af7 128#include "AliTPCTransform.h"
fd065ea2 129#include "AliTPCClusterParam.h"
64bf5ca0 130#include "AliTPCdEdxInfo.h"
ec7e4ad6 131#include "AliDCSSensorArray.h"
132#include "AliDCSSensor.h"
133#include "AliDAQ.h"
3aa6a136 134#include "AliCosmicTracker.h"
44ca7282 135#include "AliTPCROC.h"
e731a3f8 136#include "AliMathBase.h"
6d171107 137//
c9427e08 138
a11596ad 139using std::cerr;
140using std::endl;
829455ad 141ClassImp(AliTPCtracker)
c9427e08 142
143
002af263 144
b67e07dc 145class AliTPCFastMath {
91162307 146public:
b67e07dc 147 AliTPCFastMath();
91162307 148 static Double_t FastAsin(Double_t x);
149 private:
b67e07dc 150 static Double_t fgFastAsin[20000]; //lookup table for fast asin computation
91162307 151};
c9427e08 152
b67e07dc 153Double_t AliTPCFastMath::fgFastAsin[20000];
2274b54b 154AliTPCFastMath gAliTPCFastMath; // needed to fill the LUT
c9427e08 155
b67e07dc 156AliTPCFastMath::AliTPCFastMath(){
157 //
158 // initialized lookup table;
91162307 159 for (Int_t i=0;i<10000;i++){
160 fgFastAsin[2*i] = TMath::ASin(i/10000.);
161 fgFastAsin[2*i+1] = (TMath::ASin((i+1)/10000.)-fgFastAsin[2*i]);
162 }
c9427e08 163}
164
b67e07dc 165Double_t AliTPCFastMath::FastAsin(Double_t x){
166 //
167 // return asin using lookup table
91162307 168 if (x>0){
169 Int_t index = int(x*10000);
170 return fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1];
171 }
172 x*=-1;
173 Int_t index = int(x*10000);
174 return -(fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1]);
1c53abe2 175}
e046d791 176//__________________________________________________________________
829455ad 177AliTPCtracker::AliTPCtracker()
e046d791 178 :AliTracker(),
179 fkNIS(0),
180 fInnerSec(0),
181 fkNOS(0),
182 fOuterSec(0),
183 fN(0),
184 fSectors(0),
185 fInput(0),
186 fOutput(0),
187 fSeedTree(0),
188 fTreeDebug(0),
189 fEvent(0),
72e25240 190 fEventHLT(0),
e046d791 191 fDebug(0),
192 fNewIO(kFALSE),
193 fNtracks(0),
194 fSeeds(0),
195 fIteration(0),
47af7ca4 196 fkParam(0),
1598ba75 197 fDebugStreamer(0),
f06a1ff6 198 fUseHLTClusters(4),
8cc1870a 199 fCrossTalkSignalArray(0),
f06a1ff6 200 fSeedsPool(0),
ddfbc51a 201 fFreeSeedsID(500),
202 fNFreeSeeds(0),
203 fLastSeedID(-1)
e046d791 204{
205 //
206 // default constructor
207 //
0f923679 208 for (Int_t irow=0; irow<200; irow++){
209 fXRow[irow]=0;
210 fYMax[irow]=0;
211 fPadLength[irow]=0;
212 }
e046d791 213}
214//_____________________________________________________________________
1c53abe2 215
216
217
829455ad 218Int_t AliTPCtracker::UpdateTrack(AliTPCseed * track, Int_t accept){
b67e07dc 219 //
220 //update track information using current cluster - track->fCurrentCluster
221
1c53abe2 222
b9671574 223 AliTPCclusterMI* c =track->GetCurrentCluster();
f124f8bf 224 if (accept > 0) //sign not accepted clusters
225 track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() | 0x8000);
226 else // unsign accpeted clusters
227 track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() & 0xffff7fff);
b9671574 228 UInt_t i = track->GetCurrentClusterIndex1();
1c53abe2 229
230 Int_t sec=(i&0xff000000)>>24;
91162307 231 //Int_t row = (i&0x00ff0000)>>16;
b9671574 232 track->SetRow((i&0x00ff0000)>>16);
233 track->SetSector(sec);
1c53abe2 234 // Int_t index = i&0xFFFF;
47af7ca4 235 if (sec>=fkParam->GetNInnerSector()) track->SetRow(track->GetRow()+fkParam->GetNRowLow());
b9671574 236 track->SetClusterIndex2(track->GetRow(), i);
91162307 237 //track->fFirstPoint = row;
238 //if ( track->fLastPoint<row) track->fLastPoint =row;
239 // if (track->fRow<0 || track->fRow>160) {
240 // printf("problem\n");
241 //}
b9671574 242 if (track->GetFirstPoint()>track->GetRow())
243 track->SetFirstPoint(track->GetRow());
244 if (track->GetLastPoint()<track->GetRow())
245 track->SetLastPoint(track->GetRow());
91162307 246
247
b9671574 248 track->SetClusterPointer(track->GetRow(),c);
1c53abe2 249 //
250
3f82c4f2 251 Double_t angle2 = track->GetSnp()*track->GetSnp();
1c53abe2 252 //
253 //SET NEW Track Point
254 //
85e2b57d 255 if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
91162307 256 {
85e2b57d 257 angle2 = TMath::Sqrt(angle2/(1-angle2));
b9671574 258 AliTPCTrackerPoint &point =*(track->GetTrackPoint(track->GetRow()));
1c53abe2 259 //
b9671574 260 point.SetSigmaY(c->GetSigmaY2()/track->GetCurrentSigmaY2());
261 point.SetSigmaZ(c->GetSigmaZ2()/track->GetCurrentSigmaZ2());
262 point.SetErrY(sqrt(track->GetErrorY2()));
263 point.SetErrZ(sqrt(track->GetErrorZ2()));
1c53abe2 264 //
91162307 265 point.SetX(track->GetX());
266 point.SetY(track->GetY());
267 point.SetZ(track->GetZ());
268 point.SetAngleY(angle2);
269 point.SetAngleZ(track->GetTgl());
b9671574 270 if (point.IsShared()){
271 track->SetErrorY2(track->GetErrorY2()*4);
272 track->SetErrorZ2(track->GetErrorZ2()*4);
91162307 273 }
274 }
275
b9671574 276 Double_t chi2 = track->GetPredictedChi2(track->GetCurrentCluster());
91162307 277 //
1d91d749 278// track->SetErrorY2(track->GetErrorY2()*1.3);
279// track->SetErrorY2(track->GetErrorY2()+0.01);
280// track->SetErrorZ2(track->GetErrorZ2()*1.3);
281// track->SetErrorZ2(track->GetErrorZ2()+0.005);
91162307 282 //}
283 if (accept>0) return 0;
284 if (track->GetNumberOfClusters()%20==0){
285 // if (track->fHelixIn){
286 // TClonesArray & larr = *(track->fHelixIn);
287 // Int_t ihelix = larr.GetEntriesFast();
288 // new(larr[ihelix]) AliHelix(*track) ;
289 //}
1c53abe2 290 }
65e67c9c 291 if (AliTPCReconstructor::StreamLevel()&kStreamUpdateTrack) {
bda5ad6d 292 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
293 AliExternalTrackParam param(*track);
294 TTreeSRedirector &cstream = *fDebugStreamer;
65e67c9c 295 cstream<<"UpdateTrack"<<
bda5ad6d 296 "cl.="<<c<<
265b5e37 297 "event="<<event<<
bda5ad6d 298 "track.="<<&param<<
299 "\n";
300 }
b9671574 301 track->SetNoCluster(0);
91162307 302 return track->Update(c,chi2,i);
303}
304
305
306
829455ad 307Int_t AliTPCtracker::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster)
91162307 308{
1c53abe2 309 //
91162307 310 // decide according desired precision to accept given
311 // cluster for tracking
6fbe1e5c 312 Double_t yt=0,zt=0;
313 seed->GetProlongation(cluster->GetX(),yt,zt);
00055a22 314 Double_t sy2=ErrY2(seed,cluster);
315 Double_t sz2=ErrZ2(seed,cluster);
1c53abe2 316
91162307 317 Double_t sdistancey2 = sy2+seed->GetSigmaY2();
318 Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
6fbe1e5c 319 Double_t dy=seed->GetCurrentCluster()->GetY()-yt;
f47588e0 320 Double_t dz=seed->GetCurrentCluster()->GetZ()-zt;
6fbe1e5c 321 Double_t rdistancey2 = (seed->GetCurrentCluster()->GetY()-yt)*
322 (seed->GetCurrentCluster()->GetY()-yt)/sdistancey2;
323 Double_t rdistancez2 = (seed->GetCurrentCluster()->GetZ()-zt)*
324 (seed->GetCurrentCluster()->GetZ()-zt)/sdistancez2;
91162307 325
326 Double_t rdistance2 = rdistancey2+rdistancez2;
327 //Int_t accept =0;
1c53abe2 328
f5a565c3 329 if (AliTPCReconstructor::StreamLevel()>2 && ( (fIteration>0)|| (seed->GetNumberOfClusters()>20))) {
a9ff2f09 330 // if (AliTPCReconstructor::StreamLevel()>2 && seed->GetNumberOfClusters()>20) {
fd065ea2 331 Float_t rmsy2 = seed->GetCurrentSigmaY2();
332 Float_t rmsz2 = seed->GetCurrentSigmaZ2();
e0e13b88 333 Float_t rmsy2p30 = seed->GetCMeanSigmaY2p30();
334 Float_t rmsz2p30 = seed->GetCMeanSigmaZ2p30();
42aec1f1 335 Float_t rmsy2p30R = seed->GetCMeanSigmaY2p30R();
336 Float_t rmsz2p30R = seed->GetCMeanSigmaZ2p30R();
6fbe1e5c 337 AliExternalTrackParam param(*seed);
eea6b724 338 static TVectorD gcl(3),gtr(3);
339 Float_t gclf[3];
340 param.GetXYZ(gcl.GetMatrixArray());
341 cluster->GetGlobalXYZ(gclf);
342 gcl[0]=gclf[0]; gcl[1]=gclf[1]; gcl[2]=gclf[2];
a9ff2f09 343 Int_t nclSeed=seed->GetNumberOfClusters();
b194b32c 344
65e67c9c 345 if (AliTPCReconstructor::StreamLevel()&kStreamErrParam) { // flag:stream in debug mode cluster and track extrapolation at given row together with error nad shape estimate
b9d88e03 346 Int_t eventNr = fEvent->GetEventNumberInFile();
347
fd065ea2 348 (*fDebugStreamer)<<"ErrParam"<<
498b9441 349 "iter="<<fIteration<<
b9d88e03 350 "eventNr="<<eventNr<<
e0e13b88 351 "Cl.="<<cluster<<
a9ff2f09 352 "nclSeed="<<nclSeed<<
e0e13b88 353 "T.="<<&param<<
6fbe1e5c 354 "dy="<<dy<<
355 "dz="<<dz<<
356 "yt="<<yt<<
357 "zt="<<zt<<
eea6b724 358 "gcl.="<<&gcl<<
359 "gtr.="<<&gtr<<
e0e13b88 360 "erry2="<<sy2<<
361 "errz2="<<sz2<<
362 "rmsy2="<<rmsy2<<
363 "rmsz2="<<rmsz2<<
364 "rmsy2p30="<<rmsy2p30<<
365 "rmsz2p30="<<rmsz2p30<<
42aec1f1 366 "rmsy2p30R="<<rmsy2p30R<<
367 "rmsz2p30R="<<rmsz2p30R<<
f47588e0 368 // normalize distance -
369 "rdisty="<<rdistancey2<<
370 "rdistz="<<rdistancez2<<
371 "rdist="<<rdistance2<< //
e0e13b88 372 "\n";
b194b32c 373 }
fd065ea2 374 }
6fbe1e5c 375 //return 0; // temporary
376 if (rdistance2>32) return 3;
91162307 377
378
00055a22 379 if ((rdistancey2>9. || rdistancez2>9.) && cluster->GetType()==0)
91162307 380 return 2; //suspisiouce - will be changed
381
00055a22 382 if ((rdistancey2>6.25 || rdistancez2>6.25) && cluster->GetType()>0)
91162307 383 // strict cut on overlaped cluster
384 return 2; //suspisiouce - will be changed
385
00055a22 386 if ( (rdistancey2>1. || rdistancez2>6.25 )
91162307 387 && cluster->GetType()<0){
b9671574 388 seed->SetNFoundable(seed->GetNFoundable()-1);
91162307 389 return 2;
1c53abe2 390 }
19dcf504 391
1598ba75 392 if (fUseHLTClusters == 3 || fUseHLTClusters == 4) {
36b89541 393 if (fIteration==2){
394 if(!AliTPCReconstructor::GetRecoParam()->GetUseHLTOnePadCluster()) {
395 if (TMath::Abs(cluster->GetSigmaY2()) < kAlmost0)
396 return 2;
397 }
1598ba75 398 }
19dcf504 399 }
1598ba75 400
91162307 401 return 0;
402}
403
404
1c53abe2 405
1c53abe2 406
1af5da7e 407
1c53abe2 408//_____________________________________________________________________________
829455ad 409AliTPCtracker::AliTPCtracker(const AliTPCParam *par):
e046d791 410AliTracker(),
411 fkNIS(par->GetNInnerSector()/2),
412 fInnerSec(0),
413 fkNOS(par->GetNOuterSector()/2),
414 fOuterSec(0),
415 fN(0),
416 fSectors(0),
417 fInput(0),
418 fOutput(0),
419 fSeedTree(0),
420 fTreeDebug(0),
421 fEvent(0),
72e25240 422 fEventHLT(0),
e046d791 423 fDebug(0),
424 fNewIO(0),
425 fNtracks(0),
426 fSeeds(0),
427 fIteration(0),
47af7ca4 428 fkParam(0),
8cc1870a 429 fDebugStreamer(0),
430 fUseHLTClusters(4),
431 fCrossTalkSignalArray(0),
8cc1870a 432 fSeedsPool(0),
ddfbc51a 433 fFreeSeedsID(500),
434 fNFreeSeeds(0),
435 fLastSeedID(-1)
1c53abe2 436{
437 //---------------------------------------------------------------------
438 // The main TPC tracker constructor
439 //---------------------------------------------------------------------
9350f379 440 fInnerSec=new AliTPCtrackerSector[fkNIS];
441 fOuterSec=new AliTPCtrackerSector[fkNOS];
91162307 442
1c53abe2 443 Int_t i;
444 for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
445 for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
446
47af7ca4 447 fkParam = par;
91162307 448 Int_t nrowlow = par->GetNRowLow();
449 Int_t nrowup = par->GetNRowUp();
450
451
77f88633 452 for (i=0;i<nrowlow;i++){
91162307 453 fXRow[i] = par->GetPadRowRadiiLow(i);
454 fPadLength[i]= par->GetPadPitchLength(0,i);
455 fYMax[i] = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
456 }
457
458
77f88633 459 for (i=0;i<nrowup;i++){
91162307 460 fXRow[i+nrowlow] = par->GetPadRowRadiiUp(i);
461 fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
462 fYMax[i+nrowlow] = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
463 }
e046d791 464
b194b32c 465 if (AliTPCReconstructor::StreamLevel()>0) {
3d674021 466 fDebugStreamer = new TTreeSRedirector("TPCdebug.root","recreate");
b194b32c 467 }
f06a1ff6 468 //
ddfbc51a 469 fSeedsPool = new TClonesArray("AliTPCseed",1000);
265b5e37 470
471 // crosstalk array and matrix initialization
472 Int_t nROCs = 72;
473 Int_t nTimeBinsAll = par->GetMaxTBin();
474 Int_t nWireSegments = 11;
3c8c25a3 475 fCrossTalkSignalArray = new TObjArray(nROCs*4); //
265b5e37 476 fCrossTalkSignalArray->SetOwner(kTRUE);
3c8c25a3 477 for (Int_t isector=0; isector<4*nROCs; isector++){
39240815 478 TMatrixD * crossTalkSignal = new TMatrixD(nWireSegments,nTimeBinsAll);
265b5e37 479 for (Int_t imatrix = 0; imatrix<11; imatrix++)
480 for (Int_t jmatrix = 0; jmatrix<nTimeBinsAll; jmatrix++){
39240815 481 (*crossTalkSignal)[imatrix][jmatrix]=0.;
265b5e37 482 }
39240815 483 fCrossTalkSignalArray->AddAt(crossTalkSignal,isector);
265b5e37 484 }
485
1c53abe2 486}
2fc0c115 487//________________________________________________________________________
829455ad 488AliTPCtracker::AliTPCtracker(const AliTPCtracker &t):
58251ea0 489 AliTracker(t),
e046d791 490 fkNIS(t.fkNIS),
491 fInnerSec(0),
492 fkNOS(t.fkNOS),
493 fOuterSec(0),
494 fN(0),
495 fSectors(0),
496 fInput(0),
497 fOutput(0),
498 fSeedTree(0),
499 fTreeDebug(0),
500 fEvent(0),
72e25240 501 fEventHLT(0),
e046d791 502 fDebug(0),
503 fNewIO(kFALSE),
504 fNtracks(0),
505 fSeeds(0),
506 fIteration(0),
47af7ca4 507 fkParam(0),
8cc1870a 508 fDebugStreamer(0),
509 fUseHLTClusters(4),
510 fCrossTalkSignalArray(0),
8cc1870a 511 fSeedsPool(0),
ddfbc51a 512 fFreeSeedsID(500),
513 fNFreeSeeds(0),
514 fLastSeedID(-1)
58251ea0 515{
2fc0c115 516 //------------------------------------
517 // dummy copy constructor
518 //------------------------------------------------------------------
e046d791 519 fOutput=t.fOutput;
17abbffb 520 for (Int_t irow=0; irow<200; irow++){
521 fXRow[irow]=0;
522 fYMax[irow]=0;
523 fPadLength[irow]=0;
524 }
525
2fc0c115 526}
829455ad 527AliTPCtracker & AliTPCtracker::operator=(const AliTPCtracker& /*r*/)
47af7ca4 528{
2fc0c115 529 //------------------------------
530 // dummy
531 //--------------------------------------------------------------
532 return *this;
533}
1c53abe2 534//_____________________________________________________________________________
829455ad 535AliTPCtracker::~AliTPCtracker() {
1c53abe2 536 //------------------------------------------------------------------
537 // TPC tracker destructor
538 //------------------------------------------------------------------
539 delete[] fInnerSec;
540 delete[] fOuterSec;
541 if (fSeeds) {
f06a1ff6 542 fSeeds->Clear();
1c53abe2 543 delete fSeeds;
544 }
8cc1870a 545 if (fCrossTalkSignalArray) delete fCrossTalkSignalArray;
81e97e0d 546 if (fDebugStreamer) delete fDebugStreamer;
ddfbc51a 547 if (fSeedsPool) delete fSeedsPool;
1c53abe2 548}
549
1c53abe2 550
829455ad 551void AliTPCtracker::FillESD(const TObjArray* arr)
91162307 552{
47966a6d 553 //
554 //
555 //fill esds using updated tracks
ada522d7 556
ec26e231 557 if (!fEvent) return;
ada522d7 558
559 AliESDtrack iotrack;
ec26e231 560
91162307 561 // write tracks to the event
562 // store index of the track
d26d9159 563 Int_t nseed=arr->GetEntriesFast();
51ad6848 564 //FindKinks(arr,fEvent);
91162307 565 for (Int_t i=0; i<nseed; i++) {
d26d9159 566 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 567 if (!pt) continue;
51ad6848 568 pt->UpdatePoints();
92f513f5 569 AddCovariance(pt);
65e67c9c 570 if (AliTPCReconstructor::StreamLevel()&kStreamFillESD) {
571 (*fDebugStreamer)<<"FillESD"<< // flag: stream track information in FillESD function (after track Iteration 0)
8cecaa87 572 "Tr0.="<<pt<<
573 "\n";
574 }
47af7ca4 575 // pt->PropagateTo(fkParam->GetInnerRadiusLow());
eea478d3 576 if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
47af7ca4 577 pt->PropagateTo(fkParam->GetInnerRadiusLow());
eea478d3 578 }
51ad6848 579
580 if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
ada522d7 581 iotrack.~AliESDtrack();
582 new(&iotrack) AliESDtrack;
51ad6848 583 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 584 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 585 iotrack.SetTPCPoints(pt->GetPoints());
586 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 587 iotrack.SetV0Indexes(pt->GetV0Indexes());
588 // iotrack.SetTPCpid(pt->fTPCr);
f5cbf2ef 589 //iotrack.SetTPCindex(i);
590 MakeESDBitmaps(pt, &iotrack);
51ad6848 591 fEvent->AddTrack(&iotrack);
592 continue;
593 }
594
b9671574 595 if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
ada522d7 596 iotrack.~AliESDtrack();
597 new(&iotrack) AliESDtrack;
51ad6848 598 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 599 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 600 iotrack.SetTPCPoints(pt->GetPoints());
d26d9159 601 //iotrack.SetTPCindex(i);
51ad6848 602 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 603 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 604 MakeESDBitmaps(pt, &iotrack);
81e97e0d 605 // iotrack.SetTPCpid(pt->fTPCr);
d26d9159 606 fEvent->AddTrack(&iotrack);
a42a6bae 607 continue;
608 }
51ad6848 609 //
610 // short tracks - maybe decays
611
b9671574 612 if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
a42a6bae 613 Int_t found,foundable,shared;
614 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
b9671574 615 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
ada522d7 616 iotrack.~AliESDtrack();
617 new(&iotrack) AliESDtrack;
a42a6bae 618 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 619 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
a42a6bae 620 //iotrack.SetTPCindex(i);
51ad6848 621 iotrack.SetTPCPoints(pt->GetPoints());
622 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 623 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 624 MakeESDBitmaps(pt, &iotrack);
81e97e0d 625 //iotrack.SetTPCpid(pt->fTPCr);
a42a6bae 626 fEvent->AddTrack(&iotrack);
627 continue;
628 }
629 }
630
b9671574 631 if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
a42a6bae 632 Int_t found,foundable,shared;
633 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
634 if (found<20) continue;
b9671574 635 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
a42a6bae 636 //
ada522d7 637 iotrack.~AliESDtrack();
638 new(&iotrack) AliESDtrack;
a42a6bae 639 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 640 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 641 iotrack.SetTPCPoints(pt->GetPoints());
642 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 643 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 644 MakeESDBitmaps(pt, &iotrack);
81e97e0d 645 //iotrack.SetTPCpid(pt->fTPCr);
51ad6848 646 //iotrack.SetTPCindex(i);
647 fEvent->AddTrack(&iotrack);
648 continue;
649 }
650 // short tracks - secondaties
651 //
652 if ( (pt->GetNumberOfClusters()>30) ) {
653 Int_t found,foundable,shared;
654 pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
b9671574 655 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
ada522d7 656 iotrack.~AliESDtrack();
657 new(&iotrack) AliESDtrack;
51ad6848 658 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 659 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 660 iotrack.SetTPCPoints(pt->GetPoints());
661 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 662 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 663 MakeESDBitmaps(pt, &iotrack);
81e97e0d 664 //iotrack.SetTPCpid(pt->fTPCr);
51ad6848 665 //iotrack.SetTPCindex(i);
666 fEvent->AddTrack(&iotrack);
667 continue;
668 }
669 }
670
671 if ( (pt->GetNumberOfClusters()>15)) {
672 Int_t found,foundable,shared;
673 pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
674 if (found<15) continue;
e7eb17e4 675 if (foundable<=0) continue;
b9671574 676 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
51ad6848 677 if (float(found)/float(foundable)<0.8) continue;
678 //
ada522d7 679 iotrack.~AliESDtrack();
680 new(&iotrack) AliESDtrack;
51ad6848 681 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 682 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 683 iotrack.SetTPCPoints(pt->GetPoints());
684 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 685 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 686 MakeESDBitmaps(pt, &iotrack);
81e97e0d 687 // iotrack.SetTPCpid(pt->fTPCr);
a42a6bae 688 //iotrack.SetTPCindex(i);
689 fEvent->AddTrack(&iotrack);
690 continue;
691 }
91162307 692 }
6fbe1e5c 693 // >> account for suppressed tracks in the kink indices (RS)
694 int nESDtracks = fEvent->GetNumberOfTracks();
695 for (int it=nESDtracks;it--;) {
696 AliESDtrack* esdTr = fEvent->GetTrack(it);
697 if (!esdTr || !esdTr->GetKinkIndex(0)) continue;
698 for (int ik=0;ik<3;ik++) {
699 int knkId=0;
700 if (!(knkId=esdTr->GetKinkIndex(ik))) break; // no more kinks for this track
701 AliESDkink* kink = fEvent->GetKink(TMath::Abs(knkId)-1);
702 if (!kink) {
703 AliError(Form("ESDTrack%d refers to non-existing kink %d",it,TMath::Abs(knkId)-1));
704 continue;
705 }
706 kink->SetIndex(it, knkId<0 ? 0:1); // update track index of the kink: mother at 0, daughter at 1
707 }
708 }
ada522d7 709
ec26e231 710 // << account for suppressed tracks in the kink indices (RS)
711 AliInfo(Form("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks()));
712
d26d9159 713}
714
d26d9159 715
1c53abe2 716
1c53abe2 717
718
829455ad 719Double_t AliTPCtracker::ErrY2(AliTPCseed* seed, const AliTPCclusterMI * cl){
91162307 720 //
721 //
fd065ea2 722 // Use calibrated cluster error from OCDB
91162307 723 //
fd065ea2 724 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
91162307 725 //
47af7ca4 726 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
91162307 727 Int_t ctype = cl->GetType();
fd065ea2 728 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
729 Double_t angle = seed->GetSnp()*seed->GetSnp();
e0e13b88 730 angle = TMath::Sqrt(TMath::Abs(angle/(1.-angle)));
fd065ea2 731 Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
732 if (ctype<0) {
733 erry2+=0.5; // edge cluster
734 }
735 erry2*=erry2;
0b2c141b 736 Double_t addErr=0;
737 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
f858edae 738 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
0b2c141b 739 erry2+=addErr*addErr;
44ca7282 740 const Double_t *errCluster = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorCluster();
741 erry2+=errCluster[0]*errCluster[0];
fd065ea2 742 seed->SetErrorY2(erry2);
743 //
744 return erry2;
745
746//calculate look-up table at the beginning
747// static Bool_t ginit = kFALSE;
748// static Float_t gnoise1,gnoise2,gnoise3;
749// static Float_t ggg1[10000];
750// static Float_t ggg2[10000];
751// static Float_t ggg3[10000];
752// static Float_t glandau1[10000];
753// static Float_t glandau2[10000];
754// static Float_t glandau3[10000];
755// //
756// static Float_t gcor01[500];
757// static Float_t gcor02[500];
758// static Float_t gcorp[500];
759// //
1c53abe2 760
fd065ea2 761// //
762// if (ginit==kFALSE){
763// for (Int_t i=1;i<500;i++){
764// Float_t rsigma = float(i)/100.;
765// gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
766// gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
767// gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
768// }
769
770// //
771// for (Int_t i=3;i<10000;i++){
772// //
773// //
774// // inner sector
775// Float_t amp = float(i);
776// Float_t padlength =0.75;
777// gnoise1 = 0.0004/padlength;
778// Float_t nel = 0.268*amp;
779// Float_t nprim = 0.155*amp;
47af7ca4 780// ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
fd065ea2 781// glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
782// if (glandau1[i]>1) glandau1[i]=1;
783// glandau1[i]*=padlength*padlength/12.;
784// //
785// // outer short
786// padlength =1.;
787// gnoise2 = 0.0004/padlength;
788// nel = 0.3*amp;
789// nprim = 0.133*amp;
47af7ca4 790// ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 791// glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
792// if (glandau2[i]>1) glandau2[i]=1;
793// glandau2[i]*=padlength*padlength/12.;
794// //
795// //
796// // outer long
797// padlength =1.5;
798// gnoise3 = 0.0004/padlength;
799// nel = 0.3*amp;
800// nprim = 0.133*amp;
47af7ca4 801// ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 802// glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
803// if (glandau3[i]>1) glandau3[i]=1;
804// glandau3[i]*=padlength*padlength/12.;
805// //
806// }
807// ginit = kTRUE;
808// }
809// //
810// //
811// //
812// Int_t amp = int(TMath::Abs(cl->GetQ()));
813// if (amp>9999) {
814// seed->SetErrorY2(1.);
815// return 1.;
816// }
817// Float_t snoise2;
47af7ca4 818// Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
fd065ea2 819// Int_t ctype = cl->GetType();
820// Float_t padlength= GetPadPitchLength(seed->GetRow());
821// Double_t angle2 = seed->GetSnp()*seed->GetSnp();
822// angle2 = angle2/(1-angle2);
823// //
824// //cluster "quality"
825// Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
826// Float_t res;
827// //
828// if (fSectors==fInnerSec){
829// snoise2 = gnoise1;
830// res = ggg1[amp]*z+glandau1[amp]*angle2;
831// if (ctype==0) res *= gcor01[rsigmay];
832// if ((ctype>0)){
833// res+=0.002;
834// res*= gcorp[rsigmay];
835// }
836// }
837// else {
838// if (padlength<1.1){
839// snoise2 = gnoise2;
840// res = ggg2[amp]*z+glandau2[amp]*angle2;
841// if (ctype==0) res *= gcor02[rsigmay];
842// if ((ctype>0)){
843// res+=0.002;
844// res*= gcorp[rsigmay];
845// }
846// }
847// else{
848// snoise2 = gnoise3;
849// res = ggg3[amp]*z+glandau3[amp]*angle2;
850// if (ctype==0) res *= gcor02[rsigmay];
851// if ((ctype>0)){
852// res+=0.002;
853// res*= gcorp[rsigmay];
854// }
855// }
856// }
857
858// if (ctype<0){
859// res+=0.005;
860// res*=2.4; // overestimate error 2 times
861// }
862// res+= snoise2;
91162307 863
fd065ea2 864// if (res<2*snoise2)
865// res = 2*snoise2;
91162307 866
fd065ea2 867// seed->SetErrorY2(res);
868// return res;
1c53abe2 869
870
91162307 871}
c9427e08 872
873
874
829455ad 875Double_t AliTPCtracker::ErrZ2(AliTPCseed* seed, const AliTPCclusterMI * cl){
91162307 876 //
877 //
fd065ea2 878 // Use calibrated cluster error from OCDB
91162307 879 //
fd065ea2 880 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
91162307 881 //
47af7ca4 882 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
91162307 883 Int_t ctype = cl->GetType();
fd065ea2 884 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
91162307 885 //
3f82c4f2 886 Double_t angle2 = seed->GetSnp()*seed->GetSnp();
91162307 887 angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
e0e13b88 888 Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
fd065ea2 889 Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
890 if (ctype<0) {
891 errz2+=0.5; // edge cluster
91162307 892 }
1af5da7e 893 errz2*=errz2;
0b2c141b 894 Double_t addErr=0;
895 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
f858edae 896 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
0b2c141b 897 errz2+=addErr*addErr;
44ca7282 898 const Double_t *errCluster = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorCluster();
899 errz2+=errCluster[1]*errCluster[1];
fd065ea2 900 seed->SetErrorZ2(errz2);
901 //
902 return errz2;
91162307 903
fd065ea2 904
905
906// //seed->SetErrorY2(0.1);
907// //return 0.1;
908// //calculate look-up table at the beginning
909// static Bool_t ginit = kFALSE;
910// static Float_t gnoise1,gnoise2,gnoise3;
911// static Float_t ggg1[10000];
912// static Float_t ggg2[10000];
913// static Float_t ggg3[10000];
914// static Float_t glandau1[10000];
915// static Float_t glandau2[10000];
916// static Float_t glandau3[10000];
917// //
918// static Float_t gcor01[1000];
919// static Float_t gcor02[1000];
920// static Float_t gcorp[1000];
921// //
922
923// //
924// if (ginit==kFALSE){
925// for (Int_t i=1;i<1000;i++){
926// Float_t rsigma = float(i)/100.;
927// gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
928// gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
929// gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
930// }
931
932// //
933// for (Int_t i=3;i<10000;i++){
934// //
935// //
936// // inner sector
937// Float_t amp = float(i);
938// Float_t padlength =0.75;
939// gnoise1 = 0.0004/padlength;
940// Float_t nel = 0.268*amp;
941// Float_t nprim = 0.155*amp;
47af7ca4 942// ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
fd065ea2 943// glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
944// if (glandau1[i]>1) glandau1[i]=1;
945// glandau1[i]*=padlength*padlength/12.;
946// //
947// // outer short
948// padlength =1.;
949// gnoise2 = 0.0004/padlength;
950// nel = 0.3*amp;
951// nprim = 0.133*amp;
47af7ca4 952// ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 953// glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
954// if (glandau2[i]>1) glandau2[i]=1;
955// glandau2[i]*=padlength*padlength/12.;
956// //
957// //
958// // outer long
959// padlength =1.5;
960// gnoise3 = 0.0004/padlength;
961// nel = 0.3*amp;
962// nprim = 0.133*amp;
47af7ca4 963// ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 964// glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
965// if (glandau3[i]>1) glandau3[i]=1;
966// glandau3[i]*=padlength*padlength/12.;
967// //
968// }
969// ginit = kTRUE;
970// }
971// //
972// //
973// //
974// Int_t amp = int(TMath::Abs(cl->GetQ()));
975// if (amp>9999) {
976// seed->SetErrorY2(1.);
977// return 1.;
978// }
979// Float_t snoise2;
47af7ca4 980// Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
fd065ea2 981// Int_t ctype = cl->GetType();
982// Float_t padlength= GetPadPitchLength(seed->GetRow());
983// //
984// Double_t angle2 = seed->GetSnp()*seed->GetSnp();
985// // if (angle2<0.6) angle2 = 0.6;
986// angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
987// //
988// //cluster "quality"
989// Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
990// Float_t res;
991// //
992// if (fSectors==fInnerSec){
993// snoise2 = gnoise1;
994// res = ggg1[amp]*z+glandau1[amp]*angle2;
995// if (ctype==0) res *= gcor01[rsigmaz];
996// if ((ctype>0)){
997// res+=0.002;
998// res*= gcorp[rsigmaz];
999// }
1000// }
1001// else {
1002// if (padlength<1.1){
1003// snoise2 = gnoise2;
1004// res = ggg2[amp]*z+glandau2[amp]*angle2;
1005// if (ctype==0) res *= gcor02[rsigmaz];
1006// if ((ctype>0)){
1007// res+=0.002;
1008// res*= gcorp[rsigmaz];
1009// }
1010// }
1011// else{
1012// snoise2 = gnoise3;
1013// res = ggg3[amp]*z+glandau3[amp]*angle2;
1014// if (ctype==0) res *= gcor02[rsigmaz];
1015// if ((ctype>0)){
1016// res+=0.002;
1017// res*= gcorp[rsigmaz];
1018// }
1019// }
1020// }
1021
1022// if (ctype<0){
1023// res+=0.002;
1024// res*=1.3;
1025// }
1026// if ((ctype<0) &&amp<70){
1027// res+=0.002;
1028// res*=1.3;
1029// }
1030// res += snoise2;
1031// if (res<2*snoise2)
1032// res = 2*snoise2;
1033// if (res>3) res =3;
1034// seed->SetErrorZ2(res);
1035// return res;
91162307 1036}
1037
1038
1039
91162307 1040
1c53abe2 1041
829455ad 1042void AliTPCtracker::RotateToLocal(AliTPCseed *seed)
c9427e08 1043{
1044 //rotate to track "local coordinata
1045 Float_t x = seed->GetX();
1046 Float_t y = seed->GetY();
1047 Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
91162307 1048
c9427e08 1049 if (y > ymax) {
b9671574 1050 seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
c9427e08 1051 if (!seed->Rotate(fSectors->GetAlpha()))
1052 return;
1053 } else if (y <-ymax) {
b9671574 1054 seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
c9427e08 1055 if (!seed->Rotate(-fSectors->GetAlpha()))
1056 return;
1057 }
1c53abe2 1058
c9427e08 1059}
1c53abe2 1060
1061
1062
1c53abe2 1063//_____________________________________________________________________________
829455ad 1064Double_t AliTPCtracker::F1old(Double_t x1,Double_t y1,
1c53abe2 1065 Double_t x2,Double_t y2,
47af7ca4 1066 Double_t x3,Double_t y3) const
1c53abe2 1067{
1068 //-----------------------------------------------------------------
1069 // Initial approximation of the track curvature
1070 //-----------------------------------------------------------------
1071 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1072 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1073 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1074 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1075 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1076
1077 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
91162307 1078 if ( xr*xr+yr*yr<=0.00000000000001) return 100;
1c53abe2 1079 return -xr*yr/sqrt(xr*xr+yr*yr);
1080}
1081
1082
91162307 1083
1c53abe2 1084//_____________________________________________________________________________
829455ad 1085Double_t AliTPCtracker::F1(Double_t x1,Double_t y1,
91162307 1086 Double_t x2,Double_t y2,
47af7ca4 1087 Double_t x3,Double_t y3) const
91162307 1088{
1089 //-----------------------------------------------------------------
1090 // Initial approximation of the track curvature
1091 //-----------------------------------------------------------------
1092 x3 -=x1;
1093 x2 -=x1;
1094 y3 -=y1;
1095 y2 -=y1;
1096 //
1097 Double_t det = x3*y2-x2*y3;
6e23caff 1098 if (TMath::Abs(det)<1e-10){
91162307 1099 return 100;
1100 }
1101 //
1102 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1103 Double_t x0 = x3*0.5-y3*u;
1104 Double_t y0 = y3*0.5+x3*u;
1105 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1106 if (det<0) c2*=-1;
1107 return c2;
1108}
1109
1110
829455ad 1111Double_t AliTPCtracker::F2(Double_t x1,Double_t y1,
1c53abe2 1112 Double_t x2,Double_t y2,
47af7ca4 1113 Double_t x3,Double_t y3) const
91162307 1114{
1115 //-----------------------------------------------------------------
1116 // Initial approximation of the track curvature
1117 //-----------------------------------------------------------------
1118 x3 -=x1;
1119 x2 -=x1;
1120 y3 -=y1;
1121 y2 -=y1;
1122 //
1123 Double_t det = x3*y2-x2*y3;
6e23caff 1124 if (TMath::Abs(det)<1e-10) {
91162307 1125 return 100;
1126 }
1127 //
1128 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1129 Double_t x0 = x3*0.5-y3*u;
1130 Double_t y0 = y3*0.5+x3*u;
1131 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1132 if (det<0) c2*=-1;
1133 x0+=x1;
1134 x0*=c2;
1135 return x0;
1136}
1137
1138
1139
1140//_____________________________________________________________________________
829455ad 1141Double_t AliTPCtracker::F2old(Double_t x1,Double_t y1,
91162307 1142 Double_t x2,Double_t y2,
47af7ca4 1143 Double_t x3,Double_t y3) const
1c53abe2 1144{
1145 //-----------------------------------------------------------------
1146 // Initial approximation of the track curvature times center of curvature
1147 //-----------------------------------------------------------------
1148 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1149 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1150 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1151 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1152 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1153
1154 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1155
1156 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1157}
1158
1159//_____________________________________________________________________________
829455ad 1160Double_t AliTPCtracker::F3(Double_t x1,Double_t y1,
1c53abe2 1161 Double_t x2,Double_t y2,
47af7ca4 1162 Double_t z1,Double_t z2) const
1c53abe2 1163{
1164 //-----------------------------------------------------------------
1165 // Initial approximation of the tangent of the track dip angle
1166 //-----------------------------------------------------------------
1167 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1168}
1169
1170
829455ad 1171Double_t AliTPCtracker::F3n(Double_t x1,Double_t y1,
91162307 1172 Double_t x2,Double_t y2,
47af7ca4 1173 Double_t z1,Double_t z2, Double_t c) const
1c53abe2 1174{
91162307 1175 //-----------------------------------------------------------------
1176 // Initial approximation of the tangent of the track dip angle
1177 //-----------------------------------------------------------------
1178
1179 // Double_t angle1;
1180
1181 //angle1 = (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1c53abe2 1182 //
91162307 1183 Double_t d = TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1184 if (TMath::Abs(d*c*0.5)>1) return 0;
1185 // Double_t angle2 = TMath::ASin(d*c*0.5);
b67e07dc 1186 // Double_t angle2 = AliTPCFastMath::FastAsin(d*c*0.5);
1187 Double_t angle2 = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): AliTPCFastMath::FastAsin(d*c*0.5);
91162307 1188
1189 angle2 = (z1-z2)*c/(angle2*2.);
1190 return angle2;
1191}
1192
829455ad 1193Bool_t AliTPCtracker::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
91162307 1194{//-----------------------------------------------------------------
1195 // This function find proloncation of a track to a reference plane x=x2.
1196 //-----------------------------------------------------------------
1197
1198 Double_t dx=x2-x1;
1199
1200 if (TMath::Abs(x[4]*x1 - x[2]) >= 0.999) {
1201 return kFALSE;
1c53abe2 1202 }
f8aae377 1203
bfd20868 1204 Double_t c1=x[4]*x1 - x[2], r1=TMath::Sqrt((1.-c1)*(1.+c1));
1205 Double_t c2=x[4]*x2 - x[2], r2=TMath::Sqrt((1.-c2)*(1.+c2));
91162307 1206 y = x[0];
1207 z = x[1];
1208
1209 Double_t dy = dx*(c1+c2)/(r1+r2);
1210 Double_t dz = 0;
1211 //
1212 Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1213
1214 if (TMath::Abs(delta)>0.01){
1215 dz = x[3]*TMath::ASin(delta)/x[4];
1216 }else{
b67e07dc 1217 dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
91162307 1218 }
1219
b67e07dc 1220 //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
f8aae377 1221
91162307 1222 y+=dy;
1223 z+=dz;
1224
1225 return kTRUE;
1c53abe2 1226}
1227
829455ad 1228Int_t AliTPCtracker::LoadClusters (TTree *const tree)
d26d9159 1229{
544c295f 1230 // load clusters
d26d9159 1231 //
1232 fInput = tree;
1233 return LoadClusters();
1234}
91162307 1235
af86c1fd 1236
829455ad 1237Int_t AliTPCtracker::LoadClusters(const TObjArray *arr)
af86c1fd 1238{
1239 //
1240 // load clusters to the memory
e7de6656 1241 AliTPCClustersRow *clrow = new AliTPCClustersRow("AliTPCclusterMI");
af86c1fd 1242 Int_t lower = arr->LowerBound();
1243 Int_t entries = arr->GetEntriesFast();
77f88633 1244
af86c1fd 1245 for (Int_t i=lower; i<entries; i++) {
1246 clrow = (AliTPCClustersRow*) arr->At(i);
77f88633 1247 if(!clrow) continue;
1248 if(!clrow->GetArray()) continue;
1249
af86c1fd 1250 //
1251 Int_t sec,row;
47af7ca4 1252 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
77f88633 1253
af86c1fd 1254 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1255 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1256 }
1257 //
1258 if (clrow->GetArray()->GetEntriesFast()<=0) continue;
bd26fa83 1259 AliTPCtrackerRow * tpcrow=0;
af86c1fd 1260 Int_t left=0;
1261 if (sec<fkNIS*2){
1262 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1263 left = sec/fkNIS;
1264 }
1265 else{
1266 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1267 left = (sec-fkNIS*2)/fkNOS;
1268 }
1269 if (left ==0){
1270 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
77f88633 1271 for (Int_t j=0;j<tpcrow->GetN1();++j)
1272 tpcrow->SetCluster1(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
af86c1fd 1273 }
1274 if (left ==1){
1275 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
77f88633 1276 for (Int_t j=0;j<tpcrow->GetN2();++j)
bfa00fba 1277 tpcrow->SetCluster2(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
af86c1fd 1278 }
e7de6656 1279 clrow->GetArray()->Clear("C");
af86c1fd 1280 }
1281 //
1282 delete clrow;
1283 LoadOuterSectors();
1284 LoadInnerSectors();
1285 return 0;
1286}
1287
829455ad 1288Int_t AliTPCtracker::LoadClusters(const TClonesArray *arr)
aa7f1a5a 1289{
1290 //
1291 // load clusters to the memory from one
1292 // TClonesArray
1293 //
1294 AliTPCclusterMI *clust=0;
98ee6d31 1295 Int_t count[72][96] = { {0} , {0} };
aa7f1a5a 1296
1297 // loop over clusters
1298 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1299 clust = (AliTPCclusterMI*)arr->At(icl);
1300 if(!clust) continue;
1301 //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
1302
1303 // transform clusters
1304 Transform(clust);
1305
1306 // count clusters per pad row
1307 count[clust->GetDetector()][clust->GetRow()]++;
1308 }
1309
1310 // insert clusters to sectors
1311 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1312 clust = (AliTPCclusterMI*)arr->At(icl);
1313 if(!clust) continue;
1314
1315 Int_t sec = clust->GetDetector();
1316 Int_t row = clust->GetRow();
98ee6d31 1317
1318 // filter overlapping pad rows needed by HLT
1319 if(sec<fkNIS*2) { //IROCs
1320 if(row == 30) continue;
1321 }
1322 else { // OROCs
1323 if(row == 27 || row == 76) continue;
1324 }
1325
2a97785a 1326 // Int_t left=0;
aa7f1a5a 1327 if (sec<fkNIS*2){
2a97785a 1328 // left = sec/fkNIS;
47af7ca4 1329 fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fkParam);
aa7f1a5a 1330 }
1331 else{
2a97785a 1332 // left = (sec-fkNIS*2)/fkNOS;
47af7ca4 1333 fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fkParam);
aa7f1a5a 1334 }
1335 }
1336
98ee6d31 1337 // Load functions must be called behind LoadCluster(TClonesArray*)
1338 // needed by HLT
1339 //LoadOuterSectors();
1340 //LoadInnerSectors();
aa7f1a5a 1341
1342 return 0;
1343}
1344
af86c1fd 1345
829455ad 1346Int_t AliTPCtracker::LoadClusters()
1c53abe2 1347{
3c8c25a3 1348 //
1349 // load clusters to the memory
bfa00fba 1350 static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
91162307 1351 //
1352 // TTree * tree = fClustersArray.GetTree();
9a836cc2 1353 AliInfo("LoadClusters()\n");
91162307 1354
1355 TTree * tree = fInput;
1356 TBranch * br = tree->GetBranch("Segment");
1357 br->SetAddress(&clrow);
bad6eb00 1358
1359 // Conversion of pad, row coordinates in local tracking coords.
1360 // Could be skipped here; is already done in clusterfinder
1361
91162307 1362 Int_t j=Int_t(tree->GetEntries());
1c53abe2 1363 for (Int_t i=0; i<j; i++) {
91162307 1364 br->GetEntry(i);
1365 //
1366 Int_t sec,row;
47af7ca4 1367 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
0201b65c 1368 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
3c8c25a3 1369 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
0201b65c 1370 }
91162307 1371 //
bd26fa83 1372 AliTPCtrackerRow * tpcrow=0;
91162307 1373 Int_t left=0;
1374 if (sec<fkNIS*2){
1375 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1376 left = sec/fkNIS;
1377 }
1378 else{
1379 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1380 left = (sec-fkNIS*2)/fkNOS;
1381 }
1382 if (left ==0){
b9671574 1383 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
77f88633 1384 for (Int_t k=0;k<tpcrow->GetN1();++k)
1385 tpcrow->SetCluster1(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
91162307 1386 }
1387 if (left ==1){
b9671574 1388 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
77f88633 1389 for (Int_t k=0;k<tpcrow->GetN2();++k)
bfa00fba 1390 tpcrow->SetCluster2(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
91162307 1391 }
1c53abe2 1392 }
3c8c25a3 1393 //
1394 clrow->Clear("C");
1395 LoadOuterSectors();
1396 LoadInnerSectors();
1397
1398 cout << " =================================================================================================================================== " << endl;
1399 cout << " AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection() = " << AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection() << endl;
1400 cout << " AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection() = " << AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection() << endl;
1401 cout << " =================================================================================================================================== " << endl;
1402
1403 if (AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection()) ApplyTailCancellation();
1404 if (AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection()!=0.) CalculateXtalkCorrection();
1405 if (AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection()!=0.) ApplyXtalkCorrection();
1406 //if (AliTPCReconstructor::GetRecoParam()->GetUseOulierClusterFilter()) FilterOutlierClusters();
1407 return 0;
1408}
1409
1410
1411void AliTPCtracker::CalculateXtalkCorrection(){
1412 //
1413 //
1414 //
1415 const Int_t nROCs = 72;
1416
1417 // 0.) reset crosstalk matrix
1418 //
1419 for (Int_t isector=0; isector<nROCs*4; isector++){ //set all ellemts of crosstalk matrix to 0
1420 TMatrixD * crossTalkMatrix = (TMatrixD*)fCrossTalkSignalArray->At(isector);
1421 if (crossTalkMatrix)(*crossTalkMatrix)*=0;
1422 }
1423
1424 //
1425 // 1.) Filling part -- loop over clusters
1426 //
1427 Double_t missingChargeFactor= AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrectionMissingCharge();
1428 for (Int_t iter=0; iter<2;iter++){
1429 for (Int_t isector=0; isector<36; isector++){ // loop over sectors
1430 for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1431 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1432 Int_t nrows = sector.GetNRows();
1433 Int_t sec=0;
1434 if (isector<18) sec=isector+18*iside;
1435 if (isector>=18) sec=36+isector+18*iside;
1436 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1437 //
1438 //
1439 Int_t wireSegmentID = fkParam->GetWireSegment(sec,row);
1440 Float_t nPadsPerSegment = (Float_t)(fkParam->GetNPadsPerSegment(wireSegmentID));
1441 TMatrixD &crossTalkSignal = *((TMatrixD*)fCrossTalkSignalArray->At(sec));
1442 TMatrixD &crossTalkSignalCache = *((TMatrixD*)fCrossTalkSignalArray->At(sec+nROCs*2)); // this is the cache value of the crosstalk from previous iteration
1443 TMatrixD &crossTalkSignalBelow = *((TMatrixD*)fCrossTalkSignalArray->At(sec+nROCs));
1444 Int_t nCols=crossTalkSignal.GetNcols();
1445 //
1446 AliTPCtrackerRow& tpcrow = sector[row];
1447 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1448 if (iside>0) ncl=tpcrow.GetN2();
1449 for (Int_t i=0;i<ncl;i++) { // loop over clusters
1450 AliTPCclusterMI *clXtalk= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1451
1452 Int_t timeBinXtalk = clXtalk->GetTimeBin();
1453 Double_t rmsPadMin2=0.5*0.5+(fkParam->GetDiffT()*fkParam->GetDiffT())*(TMath::Abs((clXtalk->GetZ()-fkParam->GetZLength())))/(fkParam->GetPadPitchWidth(sec)*fkParam->GetPadPitchWidth(sec)); // minimal PRF width - 0.5 is the PRF in the pad units - we should et it from fkparam getters
1454 Double_t rmsTimeMin2=1+(fkParam->GetDiffL()*fkParam->GetDiffL())*(TMath::Abs((clXtalk->GetZ()-fkParam->GetZLength())))/(fkParam->GetZWidth()*fkParam->GetZWidth()); // minimal PRF width - 1 is the TRF in the time bin units - we should et it from fkParam getters
1455 Double_t rmsTime2 = clXtalk->GetSigmaZ2()/(fkParam->GetZWidth()*fkParam->GetZWidth());
1456 Double_t rmsPad2 = clXtalk->GetSigmaY2()/(fkParam->GetPadPitchWidth(sec)*fkParam->GetPadPitchWidth(sec));
1457 if (rmsPadMin2>rmsPad2){
1458 rmsPad2=rmsPadMin2;
1459 }
1460 if (rmsTimeMin2>rmsTime2){
1461 rmsTime2=rmsTimeMin2;
1462 }
1463
1464 Double_t norm= 2.*TMath::Exp(-1.0/(2.*rmsTime2))+2.*TMath::Exp(-4.0/(2.*rmsTime2))+1.;
1465 Double_t qTotXtalk = 0.;
1466 Double_t qTotXtalkMissing = 0.;
1467 for (Int_t itb=timeBinXtalk-2, idelta=-2; itb<=timeBinXtalk+2; itb++,idelta++) {
1468 if (itb<0 || itb>=nCols) continue;
1469 Double_t missingCharge=0;
1470 Double_t trf= TMath::Exp(-idelta*idelta/(2.*rmsTime2));
1471 if (missingChargeFactor>0) {
1472 for (Int_t dpad=-2; dpad<=2; dpad++){
1473 Double_t qPad = clXtalk->GetMax()*TMath::Exp(-dpad*dpad/(2.*rmsPad2))*trf;
1474 if (TMath::Nint(qPad-crossTalkSignalCache[wireSegmentID][itb])<=fkParam->GetZeroSup()){
1475 missingCharge+=qPad+crossTalkSignalCache[wireSegmentID][itb];
1476 }else{
1477 missingCharge+=crossTalkSignalCache[wireSegmentID][itb];
1478 }
1479 }
1480 }
1481 qTotXtalk = clXtalk->GetQ()*trf/norm+missingCharge*missingChargeFactor;
1482 qTotXtalkMissing = missingCharge;
1483 crossTalkSignal[wireSegmentID][itb]+= qTotXtalk/nPadsPerSegment;
1484 crossTalkSignalBelow[wireSegmentID][itb]+= qTotXtalkMissing/nPadsPerSegment;
1485 } // end of time bin loop
1486 } // end of cluster loop
1487 } // end of rows loop
1488 } // end of side loop
1489 } // end of sector loop
1490 //
1491 // copy crosstalk matrix to cached used for next itteration
434cdbe1 1492 //
3c8c25a3 1493 for (Int_t isector=0; isector<nROCs*4; isector++){ //set all ellemts of crosstalk matrix to 0
1494 TMatrixD * crossTalkMatrix = (TMatrixD*)fCrossTalkSignalArray->At(isector);
1495 TMatrixD * crossTalkMatrixCache = (TMatrixD*)fCrossTalkSignalArray->At(isector+nROCs*2);
1496 if (crossTalkMatrix){
1497 (*crossTalkMatrixCache)*=0;
1498 (*crossTalkMatrixCache)+=(*crossTalkMatrix);
1499 }
1500 }
1501 } // end of 2 iterations
1502
1503 //
1504 // 2.) dump the crosstalk matrices to tree for further investigation
1505 // a.) to estimate fluctuation of pedestal in indiviula wire segments
1506 // b.) to check correlation between regions
1507 // c.) to check relative conribution of signal below threshold to crosstalk
1508
1509 if (AliTPCReconstructor::StreamLevel()&kStreamCrosstalkMatrix) {
434cdbe1 1510 for (Int_t isector=0; isector<nROCs; isector++){ //set all ellemts of crosstalk matrix to 0
1511 TMatrixD * crossTalkMatrix = (TMatrixD*)fCrossTalkSignalArray->At(isector);
1512 TMatrixD * crossTalkMatrixBelow = (TMatrixD*)fCrossTalkSignalArray->At(isector+nROCs);
1513 TVectorD vecAll(crossTalkMatrix->GetNrows());
1514 TVectorD vecBelow(crossTalkMatrix->GetNrows());
1515 //
1516 for (Int_t itime=0; itime<crossTalkMatrix->GetNcols(); itime++){
1517 for (Int_t iwire=0; iwire<crossTalkMatrix->GetNrows(); iwire++){
1518 vecAll[iwire]=(*crossTalkMatrix)(iwire,itime);
1519 vecBelow[iwire]=(*crossTalkMatrixBelow)(iwire,itime);
1520 }
1521 (*fDebugStreamer)<<"crosstalkMatrix"<<
1522 "sector="<<isector<<
1523 "itime="<<itime<<
1524 "vecAll.="<<&vecAll<< // crosstalk charge + charge below threshold
1525 "vecBelow.="<<&vecBelow<< // crosstalk contribution from signal below threshold
1526 "\n";
1527 }
1528 }
1529 }
1530
1531
6f8ff889 1532
1c53abe2 1533}
1534
3c8c25a3 1535
1536
1537
eea44233 1538void AliTPCtracker::FilterOutlierClusters(){
1539 //
1540 // filter outlier clusters
1541 //
1542 /*
1543 1.)..... booking part
1544 nSectors=72;
1545 nTimeBins=fParam->Get....
1546 TH2F hisTime("","", sector,0,sector, nTimeBins,0,nTimeBins);
1547 TH2F hisPadRow("","", sector,0,sector, nPadRows,0,nPadRows);
1548 2.) .... filling part
1549 .... cluster loop { hisTime.Fill(cluster->GetDetector(),cluster->GetTimeBin()); }
1550
1551 3.) ...filtering part
1552 sector loop { calculate median,mean80 and rms80 of the nclusters per time bin; calculate median,mean80 and rms80 of the nclusters per par row; .... export values to the debug streamers - to decide which threshold to be used... }
1553
1554 sector loop
1555 { disable clusters in time bins > mean+ n rms80+ offsetTime disable clusters in padRow > mean+ n rms80+ offsetPadRow // how to dislable clusters? - new bit to introduce }
1556 //
1557 4. Disabling clusters
1558
1559 */
1560
1561 //
1562 // 1.) booking part
e731a3f8 1563 //
3e1f1ce7 1564 // AliTPCcalibDB *db=AliTPCcalibDB::Instance();
e731a3f8 1565 Int_t nSectors=AliTPCROC::Instance()->GetNSectors();
3e1f1ce7 1566 Int_t nTimeBins= 1100; // *Bug here - we should get NTimeBins from ALTRO - Parameters not relyable
1567 Int_t nPadRows=(AliTPCROC::Instance()->GetNRows(0) + AliTPCROC::Instance()->GetNRows(36));
e731a3f8 1568 // parameters for filtering
1569 const Double_t nSigmaCut=9.; // should be in recoParam ?
1570 const Double_t offsetTime=100; // should be in RecoParam ? -
1571 const Double_t offsetPadRow=300; // should be in RecoParam ?
1572 const Double_t offsetTimeAccept=8; // should be in RecoParam ? - obtained as mean +1 rms in high IR pp
eea44233 1573 TH2F hisTime("hisSectorTime","hisSectorTime", nSectors,0,nSectors, nTimeBins,0,nTimeBins);
1574 TH2F hisPadRow("hisSectorRow","hisSectorRow", nSectors,0,nSectors, nPadRows,0,nPadRows);
1575 //
1576 // 2.) Filling part -- loop over clusters
1577 //
44ca7282 1578 for (Int_t isector=0; isector<36; isector++){ // loop over sectors
1579 for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1580 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1581 Int_t nrows = sector.GetNRows();
1582 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1583 AliTPCtrackerRow& tpcrow = sector[row];
1584 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1585 if (iside>0) ncl=tpcrow.GetN2();
1586 for (Int_t i=0;i<ncl;i++) { // loop over clusters
1587 AliTPCclusterMI *cluster= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1588 hisTime.Fill(cluster->GetDetector(),cluster->GetTimeBin());
1589 hisPadRow.Fill(cluster->GetDetector(),cluster->GetRow());
1590 }
1591 }
1592 }
1593 }
44ca7282 1594
eea44233 1595 //
1596 // 3. Filtering part
1597 //
1598 TVectorD vecTime(nTimeBins);
44ca7282 1599 TVectorD vecPadRow(nPadRows);
c5dce091 1600 TVectorD vecMedianSectorTime(nSectors);
44ca7282 1601 TVectorD vecRMSSectorTime(nSectors);
c5dce091 1602 TVectorD vecMedianSectorTimeOut6(nSectors);
1603 TVectorD vecMedianSectorTimeOut9(nSectors);//
3e1f1ce7 1604 TVectorD vecMedianSectorTimeOut(nSectors);//
c5dce091 1605 TVectorD vecMedianSectorPadRow(nSectors);
44ca7282 1606 TVectorD vecRMSSectorPadRow(nSectors);
c5dce091 1607 TVectorD vecMedianSectorPadRowOut6(nSectors);
1608 TVectorD vecMedianSectorPadRowOut9(nSectors);
3e1f1ce7 1609 TVectorD vecMedianSectorPadRowOut(nSectors);
e731a3f8 1610 TVectorD vecSectorOut6(nSectors);
1611 TVectorD vecSectorOut9(nSectors);
3e1f1ce7 1612 TMatrixD matSectorCluster(nSectors,2);
e731a3f8 1613 //
1614 // 3.a) median, rms calculations for hisTime
1615 //
eea44233 1616 for (Int_t isec=0; isec<nSectors; isec++){
c5dce091 1617 vecMedianSectorTimeOut6[isec]=0;
1618 vecMedianSectorTimeOut9[isec]=0;
eea44233 1619 for (Int_t itime=0; itime<nTimeBins; itime++){
1620 vecTime[itime]=hisTime.GetBinContent(isec+1, itime+1);
1621 }
3e1f1ce7 1622 Double_t median= TMath::Mean(nTimeBins,vecTime.GetMatrixArray());
c5dce091 1623 Double_t rms= TMath::RMS(nTimeBins,vecTime.GetMatrixArray());
1624 vecMedianSectorTime[isec]=median;
44ca7282 1625 vecRMSSectorTime[isec]=rms;
3e1f1ce7 1626 if ((AliTPCReconstructor::StreamLevel()&kStreamFilterClusterInfo)>0) AliInfo(TString::Format("Sector TimeStat: %d\t%8.0f\t%8.0f",isec,median,rms).Data());
eea44233 1627 //
1628 // declare outliers
1629 for (Int_t itime=0; itime<nTimeBins; itime++){
1630 Double_t entries= hisTime.GetBinContent(isec+1, itime+1);
44ca7282 1631 if (entries>median+6.*rms+offsetTime) {
c5dce091 1632 vecMedianSectorTimeOut6[isec]+=1;
1633 }
44ca7282 1634 if (entries>median+9.*rms+offsetTime) {
c5dce091 1635 vecMedianSectorTimeOut9[isec]+=1;
eea44233 1636 }
1637 }
c5dce091 1638 }
e731a3f8 1639 //
1640 // 3.b) median, rms calculations for hisPadRow
1641 //
44ca7282 1642 for (Int_t isec=0; isec<nSectors; isec++){
1643 vecMedianSectorPadRowOut6[isec]=0;
1644 vecMedianSectorPadRowOut9[isec]=0;
1645 for (Int_t ipadrow=0; ipadrow<nPadRows; ipadrow++){
1646 vecPadRow[ipadrow]=hisPadRow.GetBinContent(isec+1, ipadrow+1);
1647 }
3e1f1ce7 1648 Int_t nPadRowsSector= AliTPCROC::Instance()->GetNRows(isec);
1649 Double_t median= TMath::Mean(nPadRowsSector,vecPadRow.GetMatrixArray());
1650 Double_t rms= TMath::RMS(nPadRowsSector,vecPadRow.GetMatrixArray());
44ca7282 1651 vecMedianSectorPadRow[isec]=median;
1652 vecRMSSectorPadRow[isec]=rms;
3e1f1ce7 1653 if ((AliTPCReconstructor::StreamLevel()&kStreamFilterClusterInfo)>0) AliInfo(TString::Format("Sector PadRowStat: %d\t%8.0f\t%8.0f",isec,median,rms).Data());
44ca7282 1654 //
1655 // declare outliers
1656 for (Int_t ipadrow=0; ipadrow<nPadRows; ipadrow++){
1657 Double_t entries= hisPadRow.GetBinContent(isec+1, ipadrow+1);
1658 if (entries>median+6.*rms+offsetPadRow) {
1659 vecMedianSectorPadRowOut6[isec]+=1;
1660 }
1661 if (entries>median+9.*rms+offsetPadRow) {
1662 vecMedianSectorPadRowOut9[isec]+=1;
1663 }
1664 }
1665 }
1666 //
e731a3f8 1667 // 3.c) filter outlier sectors
1668 //
1669 Double_t medianSectorTime = TMath::Median(nSectors, vecTime.GetMatrixArray());
1670 Double_t mean69SectorTime, rms69SectorTime=0;
1671 AliMathBase::EvaluateUni(nSectors, vecTime.GetMatrixArray(), mean69SectorTime,rms69SectorTime,69);
1672 for (Int_t isec=0; isec<nSectors; isec++){
1673 vecSectorOut6[isec]=0;
1674 vecSectorOut9[isec]=0;
3e1f1ce7 1675 matSectorCluster(isec,0)=0;
1676 matSectorCluster(isec,1)=0;
65e67c9c 1677 if (TMath::Abs(vecMedianSectorTime[isec])>(mean69SectorTime+6.*(rms69SectorTime+ offsetTimeAccept))) {
1678 vecSectorOut6[isec]=1;
1679 }
1680 if (TMath::Abs(vecMedianSectorTime[isec])>(mean69SectorTime+9.*(rms69SectorTime+ offsetTimeAccept))){
1681 vecSectorOut9[isec]=1;
1682 }
e731a3f8 1683 }
1684 // light version of export variable
1685 Int_t filteredSector= vecSectorOut9.Sum(); // light version of export variable
1686 Int_t filteredSectorTime= vecMedianSectorTimeOut9.Sum();
1687 Int_t filteredSectorPadRow= vecMedianSectorPadRowOut9.Sum();
b9d88e03 1688 if (fEvent) if (fEvent->GetHeader()){
1689 fEvent->GetHeader()->SetTPCNoiseFilterCounter(0,TMath::Min(filteredSector,255));
1690 fEvent->GetHeader()->SetTPCNoiseFilterCounter(1,TMath::Min(filteredSectorTime,255));
1691 fEvent->GetHeader()->SetTPCNoiseFilterCounter(2,TMath::Min(filteredSectorPadRow,255));
eea44233 1692 }
65e67c9c 1693
44ca7282 1694 //
1695 // 4. Disabling clusters in outlier layers
1696 //
65e67c9c 1697 Int_t counterAll=0;
1698 Int_t counterOut=0;
44ca7282 1699 for (Int_t isector=0; isector<36; isector++){ // loop over sectors
1700 for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1701 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1702 Int_t nrows = sector.GetNRows();
1703 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1704 AliTPCtrackerRow& tpcrow = sector[row];
1705 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1706 if (iside>0) ncl=tpcrow.GetN2();
1707 for (Int_t i=0;i<ncl;i++) { // loop over clusters
1708 AliTPCclusterMI *cluster= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1709 Double_t medianTime=vecMedianSectorTime[cluster->GetDetector()];
1710 Double_t medianPadRow=vecMedianSectorPadRow[cluster->GetDetector()];
1711 Double_t rmsTime=vecRMSSectorTime[cluster->GetDetector()];
1712 Double_t rmsPadRow=vecRMSSectorPadRow[cluster->GetDetector()];
1713 Int_t entriesPadRow=hisPadRow.GetBinContent(cluster->GetDetector()+1, cluster->GetRow()+1);
1714 Int_t entriesTime=hisTime.GetBinContent(cluster->GetDetector()+1, cluster->GetTimeBin()+1);
1715 Bool_t isOut=kFALSE;
65e67c9c 1716 if (vecSectorOut9[cluster->GetDetector()]>0.5) {
1717 isOut=kTRUE;
1718 }
e731a3f8 1719
3e1f1ce7 1720 if (entriesTime>medianTime+nSigmaCut*rmsTime+offsetTime) {
1721 isOut=kTRUE;
1722 vecMedianSectorTimeOut[cluster->GetDetector()]++;
1723 }
1724 if (entriesPadRow>medianPadRow+nSigmaCut*rmsPadRow+offsetPadRow) {
1725 isOut=kTRUE;
1726 vecMedianSectorPadRowOut[cluster->GetDetector()]++;
1727 }
65e67c9c 1728 counterAll++;
3e1f1ce7 1729 matSectorCluster(cluster->GetDetector(),0)+=1;
44ca7282 1730 if (isOut){
1731 cluster->Disable();
65e67c9c 1732 counterOut++;
3e1f1ce7 1733 matSectorCluster(cluster->GetDetector(),1)+=1;
44ca7282 1734 }
1735 }
1736 }
1737 }
1738 }
3e1f1ce7 1739 for (Int_t isec=0; isec<nSectors; isec++){
1740 if ((AliTPCReconstructor::StreamLevel()&kStreamFilterClusterInfo)>0) AliInfo(TString::Format("Sector Stat: %d\t%8.0f\t%8.0f",isec,matSectorCluster(isec,1),matSectorCluster(isec,0)).Data());
1741 }
65e67c9c 1742 //
1743 // dump info to streamer - for later tuning of cuts
1744 //
1745 if ((AliTPCReconstructor::StreamLevel()&kStreamFilterClusterInfo)>0) { // stream TPC data ouliers filtering infomation
3e1f1ce7 1746 AliLog::Flush();
1747 AliInfo(TString::Format("Cluster counter: (%d/%d) (Filtered/All)",counterOut,counterAll).Data());
1748 for (Int_t iSec=0; iSec<nSectors; iSec++){
1749 if (vecSectorOut9[iSec]>0 || matSectorCluster(iSec,1)>0) {
1750 AliInfo(TString::Format("Filtered sector\t%d",iSec).Data());
1751 Double_t vecMedTime =TMath::Median(72,vecMedianSectorTime.GetMatrixArray());
1752 Double_t vecMedPadRow =TMath::Median(72,vecMedianSectorPadRow.GetMatrixArray());
1753 Double_t vecMedCluster=(counterAll-counterOut)/72;
1754 AliInfo(TString::Format("VecMedianSectorTime\t(%4.4f/%4.4f/%4.4f)", vecMedianSectorTimeOut[iSec],vecMedianSectorTime[iSec],vecMedTime).Data());
1755 AliInfo(TString::Format("VecMedianSectorPadRow\t(%4.4f/%4.4f/%4.4f)", vecMedianSectorPadRowOut[iSec],vecMedianSectorPadRow[iSec],vecMedPadRow).Data());
1756 AliInfo(TString::Format("MatSectorCluster\t(%4.4f/%4.4f/%4.4f)\n", matSectorCluster(iSec,1), matSectorCluster(iSec,0), vecMedCluster).Data());
1757 AliLog::Flush();
1758 }
1759 }
1760 AliLog::Flush();
1761 Int_t eventNr = fEvent->GetEventNumberInFile();
65e67c9c 1762 (*fDebugStreamer)<<"filterClusterInfo"<<
1763 // minimal set variables for the ESDevent
3e1f1ce7 1764 "eventNr="<<eventNr<<
65e67c9c 1765 "counterAll="<<counterAll<<
1766 "counterOut="<<counterOut<<
3c8c25a3 1767 "matSectotCluster.="<<&matSectorCluster<< //
65e67c9c 1768 //
1769 "filteredSector="<<filteredSector<< // counter filtered sectors
1770 "filteredSectorTime="<<filteredSectorTime<< // counter filtered time bins
1771 "filteredSectorPadRow="<<filteredSectorPadRow<< // counter filtered pad-rows
1772 // per sector outlier information
1773 "medianSectorTime="<<medianSectorTime<< // median number of clusters per sector/timebin
1774 "mean69SectorTime="<<mean69SectorTime<< // LTM statistic mean of clusters per sector/timebin
1775 "rms69SectorTime="<<rms69SectorTime<< // LTM statistic RMS of clusters per sector/timebin
1776 "vecSectorOut6.="<<&vecSectorOut6<< // flag array sector - 6 sigma +accept margin outlier
1777 "vecSectorOut9.="<<&vecSectorOut9<< // flag array sector - 9 sigma + accept margin outlier
1778 // per sector/timebin outlier detection
1779 "vecMedianSectorTime.="<<&vecMedianSectorTime<<
1780 "vecRMSSectorTime.="<<&vecRMSSectorTime<<
1781 "vecMedianSectorTimeOut6.="<<&vecMedianSectorTimeOut6<<
1782 "vecMedianSectorTimeOut9.="<<&vecMedianSectorTimeOut9<<
3e1f1ce7 1783 "vecMedianSectorTimeOut0.="<<&vecMedianSectorTimeOut<<
65e67c9c 1784 // per sector/pad-row outlier detection
1785 "vecMedianSectorPadRow.="<<&vecMedianSectorPadRow<<
1786 "vecRMSSectorPadRow.="<<&vecRMSSectorPadRow<<
1787 "vecMedianSectorPadRowOut6.="<<&vecMedianSectorPadRowOut6<<
1788 "vecMedianSectorPadRowOut9.="<<&vecMedianSectorPadRowOut9<<
3e1f1ce7 1789 "vecMedianSectorPadRowOut9.="<<&vecMedianSectorPadRowOut<<
65e67c9c 1790 "\n";
1791 ((*fDebugStreamer)<<"filterClusterInfo").GetTree()->Write();
1792 fDebugStreamer->GetFile()->Flush();
1793 }
eea44233 1794}
1795
829455ad 1796void AliTPCtracker::UnloadClusters()
91162307 1797{
1798 //
1799 // unload clusters from the memory
1800 //
1801 Int_t nrows = fOuterSec->GetNRows();
1802 for (Int_t sec = 0;sec<fkNOS;sec++)
1803 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1804 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
982aff31 1805 // if (tpcrow){
1806 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1807 // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1808 //}
1809 tpcrow->ResetClusters();
1c53abe2 1810 }
91162307 1811 //
1812 nrows = fInnerSec->GetNRows();
1813 for (Int_t sec = 0;sec<fkNIS;sec++)
1814 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1815 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
982aff31 1816 //if (tpcrow){
1817 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1818 //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1819 //}
1820 tpcrow->ResetClusters();
91162307 1821 }
1822
1823 return ;
1c53abe2 1824}
1825
829455ad 1826void AliTPCtracker::FillClusterArray(TObjArray* array) const{
002af263 1827 //
1828 // Filling cluster to the array - For visualization purposes
1829 //
1830 Int_t nrows=0;
1831 nrows = fOuterSec->GetNRows();
1832 for (Int_t sec = 0;sec<fkNOS;sec++)
1833 for (Int_t row = 0;row<nrows;row++){
1834 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1835 if (!tpcrow) continue;
1836 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1837 array->AddLast((TObject*)((*tpcrow)[icl]));
1838 }
1839 }
1840 nrows = fInnerSec->GetNRows();
1841 for (Int_t sec = 0;sec<fkNIS;sec++)
1842 for (Int_t row = 0;row<nrows;row++){
1843 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1844 if (!tpcrow) continue;
1845 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1846 array->AddLast((TObject*)(*tpcrow)[icl]);
1847 }
1848 }
1849}
1850
1851
829455ad 1852void AliTPCtracker::Transform(AliTPCclusterMI * cluster){
893468d9 1853 //
544c295f 1854 // transformation
893468d9 1855 //
3f3549a3 1856 AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1857 AliTPCTransform *transform = calibDB->GetTransform() ;
24db6af7 1858 if (!transform) {
1859 AliFatal("Tranformations not in calibDB");
ec26e231 1860 return;
24db6af7 1861 }
239f39b1 1862 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
2942f542 1863 Double_t x[3]={static_cast<Double_t>(cluster->GetRow()),static_cast<Double_t>(cluster->GetPad()),static_cast<Double_t>(cluster->GetTimeBin())};
24db6af7 1864 Int_t i[1]={cluster->GetDetector()};
022ee144 1865 transform->Transform(x,i,0,1);
afbaa016 1866 // if (cluster->GetDetector()%36>17){
1867 // x[1]*=-1;
1868 //}
022ee144 1869
24db6af7 1870 //
1871 // in debug mode check the transformation
1872 //
65e67c9c 1873 if ((AliTPCReconstructor::StreamLevel()&kStreamTransform)>0) {
af86c1fd 1874 Float_t gx[3];
1875 cluster->GetGlobalXYZ(gx);
002af263 1876 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
24db6af7 1877 TTreeSRedirector &cstream = *fDebugStreamer;
65e67c9c 1878 cstream<<"Transform"<< // needed for debugging of the cluster transformation, resp. used for later visualization
002af263 1879 "event="<<event<<
24db6af7 1880 "x0="<<x[0]<<
1881 "x1="<<x[1]<<
1882 "x2="<<x[2]<<
af86c1fd 1883 "gx0="<<gx[0]<<
1884 "gx1="<<gx[1]<<
1885 "gx2="<<gx[2]<<
24db6af7 1886 "Cl.="<<cluster<<
1887 "\n";
1888 }
1889 cluster->SetX(x[0]);
1890 cluster->SetY(x[1]);
1891 cluster->SetZ(x[2]);
19b00333 1892 // The old stuff:
0201b65c 1893 //
1894 //
1895 //
47af7ca4 1896 //if (!fkParam->IsGeoRead()) fkParam->ReadGeoMatrices();
3f3549a3 1897 if (AliTPCReconstructor::GetRecoParam()->GetUseSectorAlignment() && (!calibDB->HasAlignmentOCDB())){
1898 TGeoHMatrix *mat = fkParam->GetClusterMatrix(cluster->GetDetector());
1899 //TGeoHMatrix mat;
1900 Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1901 Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1902 if (mat) mat->LocalToMaster(pos,posC);
1903 else{
1904 // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
1905 }
1906 cluster->SetX(posC[0]);
1907 cluster->SetY(posC[1]);
1908 cluster->SetZ(posC[2]);
a7760332 1909 }
0201b65c 1910}
1c53abe2 1911
265b5e37 1912void AliTPCtracker::ApplyXtalkCorrection(){
1913 //
1914 // ApplyXtalk correction
1915 // Loop over all clusters
1916 // add to each cluster signal corresponding to common Xtalk mode for given time bin at given wire segment
265b5e37 1917 // cluster loop
1918 for (Int_t isector=0; isector<36; isector++){ //loop tracking sectors
1919 for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1920 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1921 Int_t nrows = sector.GetNRows();
1922 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1923 AliTPCtrackerRow& tpcrow = sector[row]; // row object
1924 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1925 if (iside>0) ncl=tpcrow.GetN2();
1926 Int_t xSector=0; // sector number in the TPC convention 0-72
1927 if (isector<18){ //if IROC
1928 xSector=isector+(iside>0)*18;
1929 }else{
1930 xSector=isector+18; // isector -18 +36
1931 if (iside>0) xSector+=18;
1932 }
1933 TMatrixD &crossTalkMatrix= *((TMatrixD*)fCrossTalkSignalArray->At(xSector));
1934 Int_t wireSegmentID = fkParam->GetWireSegment(xSector,row);
1935 for (Int_t i=0;i<ncl;i++) {
1936 AliTPCclusterMI *cluster= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1937 Int_t iTimeBin=TMath::Nint(cluster->GetTimeBin());
1938 Double_t xTalk= crossTalkMatrix[wireSegmentID][iTimeBin];
1939 cluster->SetMax(cluster->GetMax()+xTalk);
6f8ff889 1940 const Double_t kDummy=4;
265b5e37 1941 Double_t sumxTalk=xTalk*kDummy; // should be calculated via time response function
1942 cluster->SetQ(cluster->GetQ()+sumxTalk);
6f8ff889 1943
1944
65e67c9c 1945 if ((AliTPCReconstructor::StreamLevel()&kStreamXtalk)>0) { // flag: stream crosstalk correctio as applied to cluster
6f8ff889 1946 TTreeSRedirector &cstream = *fDebugStreamer;
1947 if (gRandom->Rndm() > 0.){
1948 cstream<<"Xtalk"<<
1949 "isector=" << isector << // sector [0,36]
1950 "iside=" << iside << // side A or C
1951 "row=" << row << // padrow
1952 "i=" << i << // index of the cluster
1953 "xSector=" << xSector << // sector [0,72]
1954 "wireSegmentID=" << wireSegmentID << // anode wire segment id [0,10]
1955 "iTimeBin=" << iTimeBin << // timebin of the corrected cluster
1956 "xTalk=" << xTalk << // Xtalk contribution added to Qmax
1957 "sumxTalk=" << sumxTalk << // Xtalk contribution added to Qtot (roughly 3*Xtalk)
1958 "cluster.=" << cluster << // corrected cluster object
1959 "\n";
1960 }
1961 }// dump the results to the debug streamer if in debug mode
1962
1963
1964
1965
1966
265b5e37 1967 }
1968 }
1969 }
1970 }
1971}
1972
9a836cc2 1973void AliTPCtracker::ApplyTailCancellation(){
7bc5f28b 1974 //
9a836cc2 1975 // Correct the cluster charge for the ion tail effect
7bc5f28b 1976 // The TimeResponse function accessed via AliTPCcalibDB (TPC/Calib/IonTail)
1977 //
7bc5f28b 1978
9a836cc2 1979 // Retrieve
1980 TObjArray *ionTailArr = (TObjArray*)AliTPCcalibDB::Instance()->GetIonTailArray();
1981 if (!ionTailArr) {AliFatal("TPC - Missing IonTail OCDB object");}
1982 TObject *rocFactorIROC = ionTailArr->FindObject("factorIROC");
1983 TObject *rocFactorOROC = ionTailArr->FindObject("factorOROC");
1984 Float_t factorIROC = (atof(rocFactorIROC->GetTitle()));
1985 Float_t factorOROC = (atof(rocFactorOROC->GetTitle()));
1986
1987 // find the number of clusters for the whole TPC (nclALL)
1988 Int_t nclALL=0;
1989 for (Int_t isector=0; isector<36; isector++){
1990 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1991 nclALL += sector.GetNClInSector(0);
1992 nclALL += sector.GetNClInSector(1);
1993 }
1994
1995 // start looping over all clusters
1996 for (Int_t iside=0; iside<2; iside++){ // loop over sides
7bc5f28b 1997 //
1998 //
9a836cc2 1999 for (Int_t secType=0; secType<2; secType++){ //loop over inner or outer sector
2000 // cache experimantal tuning factor for the different chamber type
2001 const Float_t ampfactor = (secType==0)?factorIROC:factorOROC;
2002 std::cout << " ampfactor = " << ampfactor << std::endl;
7bc5f28b 2003 //
9a836cc2 2004 for (Int_t sec = 0;sec<fkNOS;sec++){ //loop overs sectors
2005 //
2006 //
2007 // Cache time response functions and their positons to COG of the cluster
2008 TGraphErrors ** graphRes = new TGraphErrors *[20];
2009 Float_t * indexAmpGraphs = new Float_t[20];
2010 for (Int_t icache=0; icache<20; icache++)
2011 {
2012 graphRes[icache] = NULL;
2013 indexAmpGraphs[icache] = 0;
2014 }
2015 ///////////////////////////// --> position fo sie loop
d4559772 2016 if (!AliTPCcalibDB::Instance()->GetTailcancelationGraphs(sec+36*secType+18*iside,graphRes,indexAmpGraphs))
2017 {
2018 continue;
2019 }
9a836cc2 2020
2021 AliTPCtrackerSector &sector= (secType==0)?fInnerSec[sec]:fOuterSec[sec];
2022 Int_t nrows = sector.GetNRows(); // number of rows
2023 Int_t nclSector = sector.GetNClInSector(iside); // ncl per sector to be used for debugging
2024
2025 for (Int_t row = 0;row<nrows;row++){ // loop over rows
2026
2027 AliTPCtrackerRow& tpcrow = sector[row]; // row object
2028 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
2029 if (iside>0) ncl=tpcrow.GetN2();
2030
2031 // Order clusters in time for the proper correction of ion tail
2032 Float_t qTotArray[ncl]; // arrays to be filled with modified Qtot and Qmax values in order to avoid float->int conversion
2033 Float_t qMaxArray[ncl];
2034 Int_t sortedClusterIndex[ncl];
2035 Float_t sortedClusterTimeBin[ncl];
2036 TObjArray *rowClusterArray = new TObjArray(ncl); // cache clusters for each row
2037 for (Int_t i=0;i<ncl;i++)
2038 {
2039 qTotArray[i]=0;
2040 qMaxArray[i]=0;
2041 sortedClusterIndex[i]=i;
2042 AliTPCclusterMI *rowcl= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
2043 if (rowcl) {
2044 rowClusterArray->AddAt(rowcl,i);
2045 } else {
2046 rowClusterArray->RemoveAt(i);
2047 }
2048 // Fill the timebin info to the array in order to sort wrt tb
2049 if (!rowcl) {
2050 sortedClusterTimeBin[i]=0.0;
2051 } else {
2052 sortedClusterTimeBin[i] = rowcl->GetTimeBin();
2053 }
2054
2055 }
2056 TMath::Sort(ncl,sortedClusterTimeBin,sortedClusterIndex,kFALSE); // sort clusters in time
2057
2058 // Main cluster correction loops over clusters
2059 for (Int_t icl0=0; icl0<ncl;icl0++){ // first loop over clusters
2060
2061 AliTPCclusterMI *cl0= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl0]));
2062
2063 if (!cl0) continue;
2064 Int_t nclPad=0;
265b5e37 2065 for (Int_t icl1=0; icl1<ncl;icl1++){ // second loop over clusters
9a836cc2 2066 AliTPCclusterMI *cl1= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl1]));
2067 if (!cl1) continue;
2068 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())>4) continue; // no contribution if far away in pad direction
2069 if (cl0->GetTimeBin()<= cl1->GetTimeBin()) continue; // no contibution to the tail if later
2070 if (TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin())>600) continue; // out of the range of response function
2071
2072 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())<4) nclPad++; // count ncl for every pad for debugging
2073
2074 // Get the correction values for Qmax and Qtot and find total correction for a given cluster
2075 Double_t ionTailMax=0.;
2076 Double_t ionTailTotal=0.;
2077 GetTailValue(ampfactor,ionTailMax,ionTailTotal,graphRes,indexAmpGraphs,cl0,cl1);
2078 ionTailMax=TMath::Abs(ionTailMax);
2079 ionTailTotal=TMath::Abs(ionTailTotal);
2080 qTotArray[icl0]+=ionTailTotal;
2081 qMaxArray[icl0]+=ionTailMax;
2082
2083 // Dump some info for debugging while clusters are being corrected
65e67c9c 2084 if ((AliTPCReconstructor::StreamLevel()&kStreamIonTail)>0) { // flag: stream ion tail correction as applied to cluster
9a836cc2 2085 TTreeSRedirector &cstream = *fDebugStreamer;
2086 if (gRandom->Rndm() > 0.999){
2087 cstream<<"IonTail"<<
2088 "cl0.=" <<cl0 << // cluster 0 (to be corrected)
2089 "cl1.=" <<cl1 << // cluster 1 (previous cluster)
2090 "ionTailTotal=" <<ionTailTotal << // ion Tail from cluster 1 contribution to cluster0
2091 "ionTailMax=" <<ionTailMax << // ion Tail from cluster 1 contribution to cluster0
2092 "\n";
2093 }
2094 }// dump the results to the debug streamer if in debug mode
2095
2096 }//end of second loop over clusters
2097
2098 // Set corrected values of the corrected cluster
2099 cl0->SetQ(TMath::Nint(Float_t(cl0->GetQ())+Float_t(qTotArray[icl0])));
2100 cl0->SetMax(TMath::Nint(Float_t(cl0->GetMax())+qMaxArray[icl0]));
2101
2102 // Dump some info for debugging after clusters are corrected
65e67c9c 2103 if ((AliTPCReconstructor::StreamLevel()&kStreamIonTail)>0) {
9a836cc2 2104 TTreeSRedirector &cstream = *fDebugStreamer;
2105 if (gRandom->Rndm() > 0.999){
2106 cstream<<"IonTailCorrected"<<
2107 "cl0.=" << cl0 << // cluster 0 with huge Qmax
2108 "ionTailTotalPerCluster=" << qTotArray[icl0] <<
2109 "ionTailMaxPerCluster=" << qMaxArray[icl0] <<
2110 "nclALL=" << nclALL <<
2111 "nclSector=" << nclSector <<
2112 "nclRow=" << ncl <<
2113 "nclPad=" << nclPad <<
2114 "row=" << row <<
2115 "sector=" << sec <<
2116 "icl0=" << icl0 <<
2117 "\n";
2118 }
2119 }// dump the results to the debug streamer if in debug mode
2120
2121 }//end of first loop over cluster
2122 delete rowClusterArray;
2123 }//end of loop over rows
2124 for (int i=0; i<20; i++) delete graphRes[i];
2125 delete [] graphRes;
2126 delete [] indexAmpGraphs;
2127
2128 }//end of loop over sectors
2129 }//end of loop over IROC/OROC
2130 }// end of side loop
7bc5f28b 2131}
9a836cc2 2132//_____________________________________________________________________________
5a516e0a 2133void AliTPCtracker::GetTailValue(Float_t ampfactor,Double_t &ionTailMax, Double_t &ionTailTotal,TGraphErrors **graphRes,Float_t *indexAmpGraphs,AliTPCclusterMI *cl0,AliTPCclusterMI *cl1){
9a836cc2 2134
2135 //
2136 // Function in order to calculate the amount of the correction to be added for a given cluster, return values are ionTailTaoltal and ionTailMax
265b5e37 2137 // Parameters:
2138 // cl0 - cluster to be modified
2139 // cl1 - source cluster ion tail of this cluster will be added to the cl0 (accroding time and pad response function)
9a836cc2 2140 //
9a836cc2 2141 const Double_t kMinPRF = 0.5; // minimal PRF width
2142 ionTailTotal = 0.; // correction value to be added to Qtot of cl0
2143 ionTailMax = 0.; // correction value to be added to Qmax of cl0
2144
2145 Float_t qTot0 = cl0->GetQ(); // cl0 Qtot info
2146 Float_t qTot1 = cl1->GetQ(); // cl1 Qtot info
2147 Int_t sectorPad = cl1->GetDetector(); // sector number
2148 Int_t padcl0 = TMath::Nint(cl0->GetPad()); // pad0
2149 Int_t padcl1 = TMath::Nint(cl1->GetPad()); // pad1
2150 Float_t padWidth = (sectorPad < 36)?0.4:0.6; // pad width in cm
2151 const Int_t deltaTimebin = TMath::Nint(TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin()))+12; //distance between pads of cl1 and cl0 increased by 12 bins
2152 Double_t rmsPad1 = (cl1->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl1->GetSigmaY2())/padWidth);
2153 Double_t rmsPad0 = (cl0->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl0->GetSigmaY2())/padWidth);
265b5e37 2154
2155
a3986da2 2156
9a836cc2 2157 Double_t sumAmp1=0.;
2158 for (Int_t idelta =-2; idelta<=2;idelta++){
2159 sumAmp1+=TMath::Exp(-idelta*idelta/(2*rmsPad1));
2160 }
7bc5f28b 2161
9a836cc2 2162 Double_t sumAmp0=0.;
2163 for (Int_t idelta =-2; idelta<=2;idelta++){
2164 sumAmp0+=TMath::Exp(-idelta*idelta/(2*rmsPad0));
2165 }
7bc5f28b 2166
9a836cc2 2167 // Apply the correction --> cl1 corrects cl0 (loop over cl1's pads and find which pads of cl0 are going to be corrected)
2168 Int_t padScan=2; // +-2 pad-timebin window will be scanned
2169 for (Int_t ipad1=padcl1-padScan; ipad1<=padcl1+padScan; ipad1++) {
2170 //
2171 //
2172 Float_t deltaPad1 = TMath::Abs(cl1->GetPad()-(Float_t)ipad1);
2173 Double_t amp1 = (TMath::Exp(-(deltaPad1*deltaPad1)/(2*rmsPad1)))/sumAmp1; // normalized pad response function
2174 Float_t qTotPad1 = amp1*qTot1; // used as a factor to multipliy the response function
2175
2176 // find closest value of cl1 to COG (among the time response functions' amplitude array --> to select proper t.r.f.)
2177 Int_t ampIndex = 0;
2178 Float_t diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[0]);
2179 for (Int_t j=0;j<20;j++) {
2180 if (diffAmp > TMath::Abs(deltaPad1-indexAmpGraphs[j]) && indexAmpGraphs[j]!=0)
2181 {
2182 diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[j]);
2183 ampIndex = j;
2184 }
2185 }
2186 if (!graphRes[ampIndex]) continue;
b4742ddd 2187 if (deltaTimebin+2 >= graphRes[ampIndex]->GetN()) continue;
9a836cc2 2188 if (graphRes[ampIndex]->GetY()[deltaTimebin+2]>=0) continue;
2189
2190 for (Int_t ipad0=padcl0-padScan; ipad0<=padcl0+padScan; ipad0++) {
2191 //
2192 //
2193 if (ipad1!=ipad0) continue; // check if ipad1 channel sees ipad0 channel, if not no correction to be applied.
2194
2195 Float_t deltaPad0 = TMath::Abs(cl0->GetPad()-(Float_t)ipad0);
2196 Double_t amp0 = (TMath::Exp(-(deltaPad0*deltaPad0)/(2*rmsPad0)))/sumAmp0; // normalized pad resp function
2197 Float_t qMaxPad0 = amp0*qTot0;
2198
2199 // Add 5 timebin range contribution around the max peak (-+2 tb window)
2200 for (Int_t itb=deltaTimebin-2; itb<=deltaTimebin+2; itb++) {
2201
2202 if (itb<0) continue;
2203 if (itb>=graphRes[ampIndex]->GetN()) continue;
2204
2205 // calculate contribution to qTot
2206 Float_t tailCorr = TMath::Abs((qTotPad1*ampfactor)*(graphRes[ampIndex])->GetY()[itb]);
2207 if (ipad1!=padcl0) {
2208 ionTailTotal += TMath::Min(qMaxPad0,tailCorr); // for side pad
2209 } else {
2210 ionTailTotal += tailCorr; // for center pad
2211 }
2212 // calculate contribution to qMax
2213 if (itb == deltaTimebin && ipad1 == padcl0) ionTailMax += tailCorr;
2214
2215 } // end of tb correction loop which is applied over 5 tb range
2216
2217 } // end of cl0 loop
2218 } // end of cl1 loop
2219
2220}
7bc5f28b 2221
1c53abe2 2222//_____________________________________________________________________________
829455ad 2223Int_t AliTPCtracker::LoadOuterSectors() {
1c53abe2 2224 //-----------------------------------------------------------------
91162307 2225 // This function fills outer TPC sectors with clusters.
1c53abe2 2226 //-----------------------------------------------------------------
91162307 2227 Int_t nrows = fOuterSec->GetNRows();
2228 UInt_t index=0;
2229 for (Int_t sec = 0;sec<fkNOS;sec++)
2230 for (Int_t row = 0;row<nrows;row++){
bd26fa83 2231 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
91162307 2232 Int_t sec2 = sec+2*fkNIS;
2233 //left
b9671574 2234 Int_t ncl = tpcrow->GetN1();
91162307 2235 while (ncl--) {
b9671574 2236 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
91162307 2237 index=(((sec2<<8)+row)<<16)+ncl;
2238 tpcrow->InsertCluster(c,index);
2239 }
2240 //right
b9671574 2241 ncl = tpcrow->GetN2();
91162307 2242 while (ncl--) {
b9671574 2243 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
91162307 2244 index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
2245 tpcrow->InsertCluster(c,index);
2246 }
2247 //
2248 // write indexes for fast acces
2249 //
2250 for (Int_t i=0;i<510;i++)
b9671574 2251 tpcrow->SetFastCluster(i,-1);
91162307 2252 for (Int_t i=0;i<tpcrow->GetN();i++){
2253 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
b9671574 2254 tpcrow->SetFastCluster(zi,i); // write index
91162307 2255 }
2256 Int_t last = 0;
2257 for (Int_t i=0;i<510;i++){
b9671574 2258 if (tpcrow->GetFastCluster(i)<0)
2259 tpcrow->SetFastCluster(i,last);
91162307 2260 else
b9671574 2261 last = tpcrow->GetFastCluster(i);
91162307 2262 }
2263 }
2264 fN=fkNOS;
2265 fSectors=fOuterSec;
2266 return 0;
2267}
2268
2269
2270//_____________________________________________________________________________
829455ad 2271Int_t AliTPCtracker::LoadInnerSectors() {
91162307 2272 //-----------------------------------------------------------------
2273 // This function fills inner TPC sectors with clusters.
2274 //-----------------------------------------------------------------
2275 Int_t nrows = fInnerSec->GetNRows();
2276 UInt_t index=0;
2277 for (Int_t sec = 0;sec<fkNIS;sec++)
2278 for (Int_t row = 0;row<nrows;row++){
bd26fa83 2279 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
91162307 2280 //
2281 //left
b9671574 2282 Int_t ncl = tpcrow->GetN1();
91162307 2283 while (ncl--) {
b9671574 2284 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
91162307 2285 index=(((sec<<8)+row)<<16)+ncl;
2286 tpcrow->InsertCluster(c,index);
2287 }
2288 //right
b9671574 2289 ncl = tpcrow->GetN2();
91162307 2290 while (ncl--) {
b9671574 2291 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
91162307 2292 index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
2293 tpcrow->InsertCluster(c,index);
2294 }
2295 //
2296 // write indexes for fast acces
2297 //
2298 for (Int_t i=0;i<510;i++)
b9671574 2299 tpcrow->SetFastCluster(i,-1);
91162307 2300 for (Int_t i=0;i<tpcrow->GetN();i++){
2301 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
b9671574 2302 tpcrow->SetFastCluster(zi,i); // write index
91162307 2303 }
2304 Int_t last = 0;
2305 for (Int_t i=0;i<510;i++){
b9671574 2306 if (tpcrow->GetFastCluster(i)<0)
2307 tpcrow->SetFastCluster(i,last);
91162307 2308 else
b9671574 2309 last = tpcrow->GetFastCluster(i);
91162307 2310 }
1c53abe2 2311
91162307 2312 }
2313
1c53abe2 2314 fN=fkNIS;
2315 fSectors=fInnerSec;
91162307 2316 return 0;
2317}
2318
2319
2320
2321//_________________________________________________________________________
829455ad 2322AliTPCclusterMI *AliTPCtracker::GetClusterMI(Int_t index) const {
91162307 2323 //--------------------------------------------------------------------
2324 // Return pointer to a given cluster
2325 //--------------------------------------------------------------------
e7eb17e4 2326 if (index<0) return 0; // no cluster
91162307 2327 Int_t sec=(index&0xff000000)>>24;
2328 Int_t row=(index&0x00ff0000)>>16;
d26d9159 2329 Int_t ncl=(index&0x00007fff)>>00;
91162307 2330
bd26fa83 2331 const AliTPCtrackerRow * tpcrow=0;
bfa00fba 2332 TClonesArray * clrow =0;
3da363a1 2333
ad23441a 2334 if (sec<0 || sec>=fkNIS*4) {
2335 AliWarning(Form("Wrong sector %d",sec));
2336 return 0x0;
2337 }
2338
91162307 2339 if (sec<fkNIS*2){
462fb6e0 2340 AliTPCtrackerSector& tracksec = fInnerSec[sec%fkNIS];
2341 if (tracksec.GetNRows()<=row) return 0;
2342 tpcrow = &(tracksec[row]);
3da363a1 2343 if (tpcrow==0) return 0;
2344
2345 if (sec<fkNIS) {
b9671574 2346 if (tpcrow->GetN1()<=ncl) return 0;
2347 clrow = tpcrow->GetClusters1();
3da363a1 2348 }
2349 else {
b9671574 2350 if (tpcrow->GetN2()<=ncl) return 0;
2351 clrow = tpcrow->GetClusters2();
3da363a1 2352 }
91162307 2353 }
3da363a1 2354 else {
462fb6e0 2355 AliTPCtrackerSector& tracksec = fOuterSec[(sec-fkNIS*2)%fkNOS];
2356 if (tracksec.GetNRows()<=row) return 0;
2357 tpcrow = &(tracksec[row]);
3da363a1 2358 if (tpcrow==0) return 0;
2359
2360 if (sec-2*fkNIS<fkNOS) {
b9671574 2361 if (tpcrow->GetN1()<=ncl) return 0;
2362 clrow = tpcrow->GetClusters1();
3da363a1 2363 }
2364 else {
b9671574 2365 if (tpcrow->GetN2()<=ncl) return 0;
2366 clrow = tpcrow->GetClusters2();
3da363a1 2367 }
91162307 2368 }
3da363a1 2369
bfa00fba 2370 return (AliTPCclusterMI*)clrow->At(ncl);
91162307 2371
1c53abe2 2372}
2373
91162307 2374
2375
829455ad 2376Int_t AliTPCtracker::FollowToNext(AliTPCseed& t, Int_t nr) {
1c53abe2 2377 //-----------------------------------------------------------------
2378 // This function tries to find a track prolongation to next pad row
2379 //-----------------------------------------------------------------
1c53abe2 2380 //
91162307 2381 Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
76d56fd6 2382 //
2383 //
4d158c36 2384 AliTPCclusterMI *cl=0;
2385 Int_t tpcindex= t.GetClusterIndex2(nr);
2386 //
2387 // update current shape info every 5 pad-row
2388 // if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
2389 GetShape(&t,nr);
2390 //}
2391 //
2392 if (fIteration>0 && tpcindex>=-1){ //if we have already clusters
2393 //
2394 if (tpcindex==-1) return 0; //track in dead zone
f124f8bf 2395 if (tpcindex >= 0){ //
b9671574 2396 cl = t.GetClusterPointer(nr);
97d77e7a 2397 //if (cl==0) cl = GetClusterMI(tpcindex);
2398 if (!cl) cl = GetClusterMI(tpcindex);
b9671574 2399 t.SetCurrentClusterIndex1(tpcindex);
4d158c36 2400 }
2401 if (cl){
2402 Int_t relativesector = ((tpcindex&0xff000000)>>24)%18; // if previously accepted cluster in different sector
2403 Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
2404 //
2405 if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
2406 if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
2407
2408 if (TMath::Abs(angle-t.GetAlpha())>0.001){
2409 Double_t rotation = angle-t.GetAlpha();
b9671574 2410 t.SetRelativeSector(relativesector);
1791d824 2411 if (!t.Rotate(rotation)) {
2412 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
2413 return 0;
2414 }
2415 }
2416 if (!t.PropagateTo(x)) {
2417 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
2418 return 0;
4d158c36 2419 }
4d158c36 2420 //
b9671574 2421 t.SetCurrentCluster(cl);
2422 t.SetRow(nr);
00055a22 2423 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
4d158c36 2424 if ((tpcindex&0x8000)==0) accept =0;
2425 if (accept<3) {
2426 //if founded cluster is acceptible
2427 if (cl->IsUsed(11)) { // id cluster is shared inrease uncertainty
b9671574 2428 t.SetErrorY2(t.GetErrorY2()+0.03);
2429 t.SetErrorZ2(t.GetErrorZ2()+0.03);
2430 t.SetErrorY2(t.GetErrorY2()*3);
2431 t.SetErrorZ2(t.GetErrorZ2()*3);
4d158c36 2432 }
b9671574 2433 t.SetNFoundable(t.GetNFoundable()+1);
4d158c36 2434 UpdateTrack(&t,accept);
2435 return 1;
f124f8bf 2436 }
2437 else { // Remove old cluster from track
2438 t.SetClusterIndex(nr, -3);
2439 t.SetClusterPointer(nr, 0);
2440 }
4d158c36 2441 }
1627d1c4 2442 }
3f82c4f2 2443 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0; // cut on angle
76d56fd6 2444 if (fIteration>1 && IsFindable(t)){
3f82c4f2 2445 // not look for new cluster during refitting
b9671574 2446 t.SetNFoundable(t.GetNFoundable()+1);
3f82c4f2 2447 return 0;
2448 }
91162307 2449 //
4d158c36 2450 UInt_t index=0;
ca142b1f 2451 // if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
f124f8bf 2452 if (!t.PropagateTo(x)) {
2453 if (fIteration==0) t.SetRemoval(10);
2454 return 0;
2455 }
2456 Double_t y = t.GetY();
91162307 2457 if (TMath::Abs(y)>ymax){
2458 if (y > ymax) {
b9671574 2459 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
91162307 2460 if (!t.Rotate(fSectors->GetAlpha()))
2461 return 0;
2462 } else if (y <-ymax) {
b9671574 2463 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
91162307 2464 if (!t.Rotate(-fSectors->GetAlpha()))
2465 return 0;
2466 }
f124f8bf 2467 if (!t.PropagateTo(x)) {
2468 if (fIteration==0) t.SetRemoval(10);
2469 return 0;
2470 }
2471 y = t.GetY();
91162307 2472 }
2473 //
4d158c36 2474 Double_t z=t.GetZ();
2475 //
a3232aae 2476
b9671574 2477 if (!IsActive(t.GetRelativeSector(),nr)) {
2478 t.SetInDead(kTRUE);
a3232aae 2479 t.SetClusterIndex2(nr,-1);
2480 return 0;
2481 }
2482 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
b9671574 2483 Bool_t isActive = IsActive(t.GetRelativeSector(),nr);
2484 Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
a3232aae 2485
2486 if (!isActive || !isActive2) return 0;
2487
bd26fa83 2488 const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
91162307 2489 if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
2490 Double_t roady =1.;
2491 Double_t roadz = 1.;
2492 //
b9671574 2493 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
2494 t.SetInDead(kTRUE);
91162307 2495 t.SetClusterIndex2(nr,-1);
1c53abe2 2496 return 0;
2497 }
2498 else
2499 {
76d56fd6 2500 if (IsFindable(t))
47af7ca4 2501 // if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fkParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
b9671574 2502 t.SetNFoundable(t.GetNFoundable()+1);
1627d1c4 2503 else
2504 return 0;
1c53abe2 2505 }
2506 //calculate
91162307 2507 if (krow) {
2508 // cl = krow.FindNearest2(y+10.,z,roady,roadz,index);
2509 cl = krow.FindNearest2(y,z,roady,roadz,index);
b9671574 2510 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
91162307 2511 }
91162307 2512 if (cl) {
b9671574 2513 t.SetCurrentCluster(cl);
2514 t.SetRow(nr);
4d158c36 2515 if (fIteration==2&&cl->IsUsed(10)) return 0;
00055a22 2516 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
4d158c36 2517 if (fIteration==2&&cl->IsUsed(11)) {
b9671574 2518 t.SetErrorY2(t.GetErrorY2()+0.03);
2519 t.SetErrorZ2(t.GetErrorZ2()+0.03);
2520 t.SetErrorY2(t.GetErrorY2()*3);
2521 t.SetErrorZ2(t.GetErrorZ2()*3);
4d158c36 2522 }
d26d9159 2523 /*
91162307 2524 if (t.fCurrentCluster->IsUsed(10)){
2525 //
2526 //
c9427e08 2527
91162307 2528 t.fNShared++;
2529 if (t.fNShared>0.7*t.GetNumberOfClusters()) {
2530 t.fRemoval =10;
2531 return 0;
2532 }
2533 }
d26d9159 2534 */
91162307 2535 if (accept<3) UpdateTrack(&t,accept);
c9427e08 2536
91162307 2537 } else {
b9671574 2538 if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
91162307 2539
2540 }
2541 return 1;
2542}
c9427e08 2543
1c53abe2 2544
91162307 2545
5d837844 2546//_________________________________________________________________________
829455ad 2547Bool_t AliTPCtracker::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
5d837844 2548{
2549 // Get track space point by index
2550 // return false in case the cluster doesn't exist
2551 AliTPCclusterMI *cl = GetClusterMI(index);
2552 if (!cl) return kFALSE;
2553 Int_t sector = (index&0xff000000)>>24;
0201b65c 2554 // Int_t row = (index&0x00ff0000)>>16;
5d837844 2555 Float_t xyz[3];
47af7ca4 2556 // xyz[0] = fkParam->GetPadRowRadii(sector,row);
0201b65c 2557 xyz[0] = cl->GetX();
5d837844 2558 xyz[1] = cl->GetY();
2559 xyz[2] = cl->GetZ();
2560 Float_t sin,cos;
47af7ca4 2561 fkParam->AdjustCosSin(sector,cos,sin);
5d837844 2562 Float_t x = cos*xyz[0]-sin*xyz[1];
2563 Float_t y = cos*xyz[1]+sin*xyz[0];
2564 Float_t cov[6];
2565 Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
47af7ca4 2566 if (sector < fkParam->GetNInnerSector()) sigmaY2 *= 2.07;
5d837844 2567 Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
47af7ca4 2568 if (sector < fkParam->GetNInnerSector()) sigmaZ2 *= 1.77;
5d837844 2569 cov[0] = sin*sin*sigmaY2;
2570 cov[1] = -sin*cos*sigmaY2;
2571 cov[2] = 0.;
2572 cov[3] = cos*cos*sigmaY2;
2573 cov[4] = 0.;
2574 cov[5] = sigmaZ2;
2575 p.SetXYZ(x,y,xyz[2],cov);
ae079791 2576 AliGeomManager::ELayerID iLayer;
5d837844 2577 Int_t idet;
47af7ca4 2578 if (sector < fkParam->GetNInnerSector()) {
ae079791 2579 iLayer = AliGeomManager::kTPC1;
5d837844 2580 idet = sector;
2581 }
2582 else {
ae079791 2583 iLayer = AliGeomManager::kTPC2;
47af7ca4 2584 idet = sector - fkParam->GetNInnerSector();
5d837844 2585 }
ae079791 2586 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
5d837844 2587 p.SetVolumeID(volid);
2588 return kTRUE;
2589}
2590
2591
2592
829455ad 2593Int_t AliTPCtracker::UpdateClusters(AliTPCseed& t, Int_t nr) {
1c53abe2 2594 //-----------------------------------------------------------------
2595 // This function tries to find a track prolongation to next pad row
2596 //-----------------------------------------------------------------
b9671574 2597 t.SetCurrentCluster(0);
f124f8bf 2598 t.SetCurrentClusterIndex1(-3);
1c53abe2 2599
2600 Double_t xt=t.GetX();
91162307 2601 Int_t row = GetRowNumber(xt)-1;
2602 Double_t ymax= GetMaxY(nr);
2603
1c53abe2 2604 if (row < nr) return 1; // don't prolongate if not information until now -
ca142b1f 2605// if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
2606// t.fRemoval =10;
2607// return 0; // not prolongate strongly inclined tracks
2608// }
2609// if (TMath::Abs(t.GetSnp())>0.95) {
2610// t.fRemoval =10;
2611// return 0; // not prolongate strongly inclined tracks
2612// }// patch 28 fev 06
91162307 2613
2614 Double_t x= GetXrow(nr);
2615 Double_t y,z;
2616 //t.PropagateTo(x+0.02);
2617 //t.PropagateTo(x+0.01);
1627d1c4 2618 if (!t.PropagateTo(x)){
1627d1c4 2619 return 0;
2620 }
1c53abe2 2621 //
91162307 2622 y=t.GetY();
2623 z=t.GetZ();
1c53abe2 2624
91162307 2625 if (TMath::Abs(y)>ymax){
2626 if (y > ymax) {
b9671574 2627 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
91162307 2628 if (!t.Rotate(fSectors->GetAlpha()))
2629 return 0;
2630 } else if (y <-ymax) {
b9671574 2631 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
91162307 2632 if (!t.Rotate(-fSectors->GetAlpha()))
2633 return 0;
2634 }
982aff31 2635 // if (!t.PropagateTo(x)){
2636 // return 0;
2637 //}
2638 return 1;
2639 //y = t.GetY();
1c53abe2 2640 }
91162307 2641 //
3f82c4f2 2642 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
a3232aae 2643
b9671574 2644 if (!IsActive(t.GetRelativeSector(),nr)) {
2645 t.SetInDead(kTRUE);
a3232aae 2646 t.SetClusterIndex2(nr,-1);
2647 return 0;
2648 }
2649 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
2650
bd26fa83 2651 AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1c53abe2 2652
b9671574 2653 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
2654 t.SetInDead(kTRUE);
91162307 2655 t.SetClusterIndex2(nr,-1);
1c53abe2 2656 return 0;
2657 }
2658 else
2659 {
76d56fd6 2660
2661 // if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
2662 if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
1627d1c4 2663 else
2664 return 0;
1c53abe2 2665 }
1c53abe2 2666
91162307 2667 // update current
42aec1f1 2668 if ( (nr%2==0) || t.GetNumberOfClusters()<2){
91162307 2669 // t.fCurrentSigmaY = GetSigmaY(&t);
2670 //t.fCurrentSigmaZ = GetSigmaZ(&t);
2671 GetShape(&t,nr);
2672 }
1c53abe2 2673
91162307 2674 AliTPCclusterMI *cl=0;
d184f295 2675 Int_t index=0;
91162307 2676 //
2677 Double_t roady = 1.;
2678 Double_t roadz = 1.;
2679 //
d26d9159 2680
2681 if (!cl){
2682 index = t.GetClusterIndex2(nr);
bad6eb00 2683 if ( (index >= 0) && (index&0x8000)==0){
b9671574 2684 cl = t.GetClusterPointer(nr);
bad6eb00 2685 if ( (cl==0) && (index >= 0)) cl = GetClusterMI(index);
b9671574 2686 t.SetCurrentClusterIndex1(index);
d26d9159 2687 if (cl) {
b9671574 2688 t.SetCurrentCluster(cl);
d26d9159 2689 return 1;
2690 }
2691 }
2692 }
2693
3d172d79 2694 // if (index<0) return 0;
2695 UInt_t uindex = TMath::Abs(index);
d184f295 2696
91162307 2697 if (krow) {
d184f295 2698 //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
2699 cl = krow.FindNearest2(y,z,roady,roadz,uindex);
91162307 2700 }
d26d9159 2701
b9671574 2702 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));
2703 t.SetCurrentCluster(cl);
d26d9159 2704
91162307 2705 return 1;
2706}
1c53abe2 2707
1c53abe2 2708
829455ad 2709Int_t AliTPCtracker::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
91162307 2710 //-----------------------------------------------------------------
2711 // This function tries to find a track prolongation to next pad row
2712 //-----------------------------------------------------------------
1c53abe2 2713
91162307 2714 //update error according neighborhoud
1c53abe2 2715
b9671574 2716 if (t.GetCurrentCluster()) {
2717 t.SetRow(nr);
00055a22 2718 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
91162307 2719
b9671574 2720 if (t.GetCurrentCluster()->IsUsed(10)){
91162307 2721 //
2722 //
2723 // t.fErrorZ2*=2;
2724 // t.fErrorY2*=2;
b9671574 2725 t.SetNShared(t.GetNShared()+1);
2726 if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
2727 t.SetRemoval(10);
91162307 2728 return 0;
2729 }
b364ca79 2730 }
d26d9159 2731 if (fIteration>0) accept = 0;
b364ca79 2732 if (accept<3) UpdateTrack(&t,accept);
2733
1c53abe2 2734 } else {
91162307 2735 if (fIteration==0){
f124f8bf 2736 if ( t.GetNumberOfClusters()>18 && ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)) t.SetRemoval(10);
2737 if ( t.GetNumberOfClusters()>18 && t.GetChi2()/t.GetNumberOfClusters()>6 ) t.SetRemoval(10);
91162307 2738
b9671574 2739 if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
1c53abe2 2740 }
2741 }
2742 return 1;
2743}
2744
2745
2746
91162307 2747//_____________________________________________________________________________
829455ad 2748Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step, Bool_t fromSeeds) {
1c53abe2 2749 //-----------------------------------------------------------------
91162307 2750 // This function tries to find a track prolongation.
1c53abe2 2751 //-----------------------------------------------------------------
2752 Double_t xt=t.GetX();
2753 //
f124f8bf 2754 Double_t alpha=t.GetAlpha();
1c53abe2 2755 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2756 if (alpha < 0. ) alpha += 2.*TMath::Pi();
91162307 2757 //
a3f36f42 2758 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1c53abe2 2759
f124f8bf 2760 Int_t first = GetRowNumber(xt);
2761 if (!fromSeeds)
2762 first -= step;
a3f36f42 2763 if (first < 0)
2764 first = 0;
51ad6848 2765 for (Int_t nr= first; nr>=rf; nr-=step) {
2766 // update kink info
2767 if (t.GetKinkIndexes()[0]>0){
2768 for (Int_t i=0;i<3;i++){
2769 Int_t index = t.GetKinkIndexes()[i];
2770 if (index==0) break;
2771 if (index<0) continue;
2772 //
6c94f330 2773 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
51ad6848 2774 if (!kink){
2775 printf("PROBLEM\n");
2776 }
2777 else{
eea478d3 2778 Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
51ad6848 2779 if (kinkrow==nr){
2780 AliExternalTrackParam paramd(t);
2781 kink->SetDaughter(paramd);
eea478d3 2782 kink->SetStatus(2,5);
51ad6848 2783 kink->Update();
51ad6848 2784 }
2785 }
2786 }
2787 }
2788
2789 if (nr==80) t.UpdateReference();
982aff31 2790 if (nr<fInnerSec->GetNRows())
2791 fSectors = fInnerSec;
2792 else
2793 fSectors = fOuterSec;
91162307 2794 if (FollowToNext(t,nr)==0)
4d158c36 2795 if (!t.IsActive())
2796 return 0;
91162307 2797
2798 }
2799 return 1;
2800}
2801
1c53abe2 2802
1c53abe2 2803
91162307 2804
2805
2806
829455ad 2807Int_t AliTPCtracker::FollowBackProlongation(AliTPCseed& t, Int_t rf, Bool_t fromSeeds) {
1c53abe2 2808 //-----------------------------------------------------------------
2809 // This function tries to find a track prolongation.
2810 //-----------------------------------------------------------------
1c53abe2 2811 //
eea478d3 2812 Double_t xt=t.GetX();
f124f8bf 2813 Double_t alpha=t.GetAlpha();
1c53abe2 2814 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2815 if (alpha < 0. ) alpha += 2.*TMath::Pi();
bad6eb00 2816 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1c53abe2 2817
b9671574 2818 Int_t first = t.GetFirstPoint();
f124f8bf 2819 Int_t ri = GetRowNumber(xt);
2820 if (!fromSeeds)
2821 ri += 1;
2822
2823 if (first<ri) first = ri;
91162307 2824 //
2825 if (first<0) first=0;
4d158c36 2826 for (Int_t nr=first; nr<=rf; nr++) {
ca142b1f 2827 // if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
51ad6848 2828 if (t.GetKinkIndexes()[0]<0){
2829 for (Int_t i=0;i<3;i++){
2830 Int_t index = t.GetKinkIndexes()[i];
2831 if (index==0) break;
2832 if (index>0) continue;
2833 index = TMath::Abs(index);
6c94f330 2834 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
51ad6848 2835 if (!kink){
2836 printf("PROBLEM\n");
2837 }
2838 else{
eea478d3 2839 Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
51ad6848 2840 if (kinkrow==nr){
2841 AliExternalTrackParam paramm(t);
2842 kink->SetMother(paramm);
eea478d3 2843 kink->SetStatus(2,1);
51ad6848 2844 kink->Update();
51ad6848 2845 }
2846 }
eea478d3 2847 }
51ad6848 2848 }
eea478d3 2849 //
d26d9159 2850 if (nr<fInnerSec->GetNRows())
2851 fSectors = fInnerSec;
2852 else
2853 fSectors = fOuterSec;
c274e255 2854
d26d9159 2855 FollowToNext(t,nr);
1c53abe2 2856 }
2857 return 1;
2858}
2859
2860
2861
2862
2863
829455ad 2864Float_t AliTPCtracker::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
1c53abe2 2865{
544c295f 2866 // overlapping factor
1c53abe2 2867 //
2868 sum1=0;
2869 sum2=0;
2870 Int_t sum=0;
1c53abe2 2871 //
2872 Float_t dz2 =(s1->GetZ() - s2->GetZ());
c9427e08 2873 dz2*=dz2;
91162307 2874
c9427e08 2875 Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
1c53abe2 2876 dy2*=dy2;
2877 Float_t distance = TMath::Sqrt(dz2+dy2);
c9427e08 2878 if (distance>4.) return 0; // if there are far away - not overlap - to reduce combinatorics
1c53abe2 2879
91162307 2880 // Int_t offset =0;
b9671574 2881 Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
2882 Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
c9427e08 2883 if (lastpoint>160)
2884 lastpoint =160;
2885 if (firstpoint<0)
2886 firstpoint = 0;
91162307 2887 if (firstpoint>lastpoint) {
2888 firstpoint =lastpoint;
2889 // lastpoint =160;
c9427e08 2890 }
2891
2892
91162307 2893 for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
2894 if (s1->GetClusterIndex2(i)>0) sum1++;
2895 if (s2->GetClusterIndex2(i)>0) sum2++;
2896 if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
1c53abe2 2897 sum++;
2898 }
2899 }
91162307 2900 if (sum<5) return 0;
2901
1627d1c4 2902 Float_t summin = TMath::Min(sum1+1,sum2+1);
2903 Float_t ratio = (sum+1)/Float_t(summin);
1c53abe2 2904 return ratio;
2905}
2906
829455ad 2907void AliTPCtracker::SignShared(AliTPCseed * s1, AliTPCseed * s2)
1c53abe2 2908{
544c295f 2909 // shared clusters
1c53abe2 2910 //
a0f4d6a6 2911 Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
2912 if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
2913 Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
2914 Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
91162307 2915
1c53abe2 2916 //
91162307 2917 Int_t sumshared=0;
2918 //
a0f4d6a6 2919 //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
2920 //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
2921 Int_t firstpoint = 0;
2922 Int_t lastpoint = 160;
91162307 2923 //
a0f4d6a6 2924 // if (firstpoint>=lastpoint-5) return;;
1af5da7e 2925
91162307 2926 for (Int_t i=firstpoint;i<lastpoint;i++){
2927 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2928 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2929 sumshared++;
2930 }
2931 }
a0f4d6a6 2932 if (sumshared>cutN0){
91162307 2933 // sign clusters
2934 //
2935 for (Int_t i=firstpoint;i<lastpoint;i++){
2936 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2937 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2938 AliTPCTrackerPoint *p1 = s1->GetTrackPoint(i);
2939 AliTPCTrackerPoint *p2 = s2->GetTrackPoint(i);;
2940 if (s1->IsActive()&&s2->IsActive()){
b9671574 2941 p1->SetShared(kTRUE);
2942 p2->SetShared(kTRUE);
91162307 2943 }
2944 }
2945 }
2946 }
2947 //
a0f4d6a6 2948 if (sumshared>cutN0){
91162307 2949 for (Int_t i=0;i<4;i++){
b9671574 2950 if (s1->GetOverlapLabel(3*i)==0){
2951 s1->SetOverlapLabel(3*i, s2->GetLabel());
2952 s1->SetOverlapLabel(3*i+1,sumshared);
2953 s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
91162307 2954 break;
2955 }
2956 }
2957 for (Int_t i=0;i<4;i++){
b9671574 2958 if (s2->GetOverlapLabel(3*i)==0){
2959 s2->SetOverlapLabel(3*i, s1->GetLabel());
2960 s2->SetOverlapLabel(3*i+1,sumshared);
2961 s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
91162307 2962 break;
2963 }
2964 }
2965 }
91162307 2966}
1c53abe2 2967
829455ad 2968void AliTPCtracker::SignShared(TObjArray * arr)
91162307 2969{
1c53abe2 2970 //
91162307 2971 //sort trackss according sectors
2972 //
c9427e08 2973 for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2974 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 2975 if (!pt) continue;
2976 //if (pt) RotateToLocal(pt);
b9671574 2977 pt->SetSort(0);
c9427e08 2978 }
91162307 2979 arr->UnSort();
6d493ea0 2980 arr->Sort(); // sorting according relative sectors
1c53abe2 2981 arr->Expand(arr->GetEntries());
91162307 2982 //
2983 //
1c53abe2 2984 Int_t nseed=arr->GetEntriesFast();
1c53abe2 2985 for (Int_t i=0; i<nseed; i++) {
2986 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 2987 if (!pt) continue;
ec26e231 2988 for (Int_t j=0;j<12;j++){
b9671574 2989 pt->SetOverlapLabel(j,0);
1c53abe2 2990 }
91162307 2991 }
2992 for (Int_t i=0; i<nseed; i++) {
2993 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2994 if (!pt) continue;
b9671574 2995 if (pt->GetRemoval()>10) continue;
1c53abe2 2996 for (Int_t j=i+1; j<nseed; j++){
2997 AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
1af5da7e 2998 if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
91162307 2999 // if (pt2){
b9671574 3000 if (pt2->GetRemoval()<=10) {
6d493ea0 3001 //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
91162307 3002 SignShared(pt,pt2);
c9427e08 3003 }
91162307 3004 }
3005 }
3006}
3007
91162307 3008
829455ad 3009void AliTPCtracker::SortTracks(TObjArray * arr, Int_t mode) const
91162307 3010{
3011 //
3012 //sort tracks in array according mode criteria
3013 Int_t nseed = arr->GetEntriesFast();
3014 for (Int_t i=0; i<nseed; i++) {
3015 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3016 if (!pt) {
3017 continue;
3018 }
b9671574 3019 pt->SetSort(mode);
91162307 3020 }
3021 arr->UnSort();
3022 arr->Sort();
1c53abe2 3023}
c9427e08 3024
51ad6848 3025
829455ad 3026void AliTPCtracker::RemoveUsed2(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t minimal)
51ad6848 3027{
51ad6848 3028 //
6d493ea0 3029 // Loop over all tracks and remove overlaped tracks (with lower quality)
3030 // Algorithm:
3031 // 1. Unsign clusters
3032 // 2. Sort tracks according quality
3033 // Quality is defined by the number of cluster between first and last points
3034 //
3035 // 3. Loop over tracks - decreasing quality order
3036 // a.) remove - If the fraction of shared cluster less than factor (1- n or 2)
3037 // b.) remove - If the minimal number of clusters less than minimal and not ITS
3038 // c.) if track accepted - sign clusters
51ad6848 3039 //
829455ad 3040 //Called in - AliTPCtracker::Clusters2Tracks()
3041 // - AliTPCtracker::PropagateBack()
3042 // - AliTPCtracker::RefitInward()
6d493ea0 3043 //
be34cb88 3044 // Arguments:
3045 // factor1 - factor for constrained
3046 // factor2 - for non constrained tracks
3047 // if (Float_t(shared+1)/Float_t(found+1)>factor) - DELETE
3048 //
51ad6848 3049 UnsignClusters();
3050 //
3051 Int_t nseed = arr->GetEntriesFast();
3052 Float_t * quality = new Float_t[nseed];
3053 Int_t * indexes = new Int_t[nseed];
3054 Int_t good =0;
3055 //
3056 //
3057 for (Int_t i=0; i<nseed; i++) {
3058 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3059 if (!pt){
3060 quality[i]=-1;
3061 continue;
3062 }
3063 pt->UpdatePoints(); //select first last max dens points
3064 Float_t * points = pt->GetPoints();
3065 if (points[3]<0.8) quality[i] =-1;
51ad6848 3066 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
6d493ea0 3067 //prefer high momenta tracks if overlaps
3068 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
51ad6848 3069 }
3070 TMath::Sort(nseed,quality,indexes);
3071 //
3072 //
3073 for (Int_t itrack=0; itrack<nseed; itrack++) {
3074 Int_t trackindex = indexes[itrack];
6d493ea0 3075 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);
3076 if (!pt) continue;
3077 //
51ad6848 3078 if (quality[trackindex]<0){
ddfbc51a 3079 MarkSeedFree( arr->RemoveAt(trackindex) );
f06a1ff6 3080 continue;
51ad6848 3081 }
3082 //
6d493ea0 3083 //
51ad6848 3084 Int_t first = Int_t(pt->GetPoints()[0]);
3085 Int_t last = Int_t(pt->GetPoints()[2]);
b9671574 3086 Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
51ad6848 3087 //
3088 Int_t found,foundable,shared;
6d493ea0 3089 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
3090 // pt->GetClusterStatistic(0,160, found, foundable,shared,kFALSE);
b406fdb0 3091 Bool_t itsgold =kFALSE;
b9671574 3092 if (pt->GetESD()){
ef7253ac 3093 Int_t dummy[12];
b9671574 3094 if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
51ad6848 3095 }
b406fdb0 3096 if (!itsgold){
3097 //
3098 if (Float_t(shared+1)/Float_t(found+1)>factor){
3099 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
65e67c9c 3100 if( (AliTPCReconstructor::StreamLevel()&kStreamRemoveUsed)>0){ // flag:stream information about TPC tracks which were descarded (double track removal)
be34cb88 3101 TTreeSRedirector &cstream = *fDebugStreamer;
3102 cstream<<"RemoveUsed"<<
3103 "iter="<<fIteration<<
3104 "pt.="<<pt<<
3105 "\n";
3106 }
ddfbc51a 3107 MarkSeedFree( arr->RemoveAt(trackindex) );
b406fdb0 3108 continue;
3109 }
3110 if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){ //remove short tracks
3111 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
65e67c9c 3112 if( (AliTPCReconstructor::StreamLevel()&kStreamRemoveShort)>0){ // flag:stream information about TPC tracks which were discarded (short track removal)
be34cb88 3113 TTreeSRedirector &cstream = *fDebugStreamer;
3114 cstream<<"RemoveShort"<<
3115 "iter="<<fIteration<<
3116 "pt.="<<pt<<
3117 "\n";
3118 }
ddfbc51a 3119 MarkSeedFree( arr->RemoveAt(trackindex) );
b406fdb0 3120 continue;
3121 }
51ad6848 3122 }
3123
3124 good++;
6d493ea0 3125 //if (sharedfactor>0.4) continue;
b406fdb0 3126 if (pt->GetKinkIndexes()[0]>0) continue;
6d493ea0 3127 //Remove tracks with undefined properties - seems
3128 if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ?
3129 //
51ad6848 3130 for (Int_t i=first; i<last; i++) {
3131 Int_t index=pt->GetClusterIndex2(i);
3132 // if (index<0 || index&0x8000 ) continue;
3133 if (index<0 || index&0x8000 ) continue;
b9671574 3134 AliTPCclusterMI *c= pt->GetClusterPointer(i);
51ad6848 3135 if (!c) continue;
3136 c->Use(10);
3137 }
3138 }
3139 fNtracks = good;
3140 if (fDebug>0){
3141 Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
3142 }
3143 delete []quality;
3144 delete []indexes;
3145}
3146
829455ad 3147void AliTPCtracker::DumpClusters(Int_t iter, TObjArray *trackArray)
f47588e0 3148{
3149 //
3150 // Dump clusters after reco
3151 // signed and unsigned cluster can be visualized
3152 // 1. Unsign all cluster
3153 // 2. Sign all used clusters
3154 // 3. Dump clusters
3155 UnsignClusters();
3156 Int_t nseed = trackArray->GetEntries();
3157 for (Int_t i=0; i<nseed; i++){
3158 AliTPCseed *pt=(AliTPCseed*)trackArray->UncheckedAt(i);
3159 if (!pt) {
3160 continue;
3161 }
3162 Bool_t isKink=pt->GetKinkIndex(0)!=0;
3163 for (Int_t j=0; j<160; ++j) {
3164 Int_t index=pt->GetClusterIndex2(j);
3165 if (index<0) continue;
3166 AliTPCclusterMI *c= pt->GetClusterPointer(j);
3167 if (!c) continue;
3168 if (isKink) c->Use(100); // kink
3169 c->Use(10); // by default usage 10
3170 }
3171 }
3172 //
b9d88e03 3173 Int_t eventNr = fEvent->GetEventNumberInFile();
f47588e0 3174
3175 for (Int_t sec=0;sec<fkNIS;sec++){
3176 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
bfa00fba 3177 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
f47588e0 3178 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++){
bfa00fba 3179 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
3180 Float_t gx[3]; cl->GetGlobalXYZ(gx);
f47588e0 3181 (*fDebugStreamer)<<"clDump"<<
b9d88e03 3182 "eventNr="<<eventNr<<
f47588e0 3183 "iter="<<iter<<
bfa00fba 3184 "cl.="<<cl<<
f47588e0 3185 "gx0="<<gx[0]<<
3186 "gx1="<<gx[1]<<
3187 "gx2="<<gx[2]<<
3188 "\n";
3189 }
bfa00fba 3190 cla = fInnerSec[sec][row].GetClusters2();
f47588e0 3191 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++){
bfa00fba 3192 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
3193 Float_t gx[3]; cl->GetGlobalXYZ(gx);
f47588e0 3194 (*fDebugStreamer)<<"clDump"<<
b9d88e03 3195 "eventNr="<<eventNr<<
f47588e0 3196 "iter="<<iter<<
bfa00fba 3197 "cl.="<<cl<<
f47588e0 3198 "gx0="<<gx[0]<<
3199 "gx1="<<gx[1]<<
3200 "gx2="<<gx[2]<<
3201 "\n";
3202 }
3203 }
3204 }
3205
3206 for (Int_t sec=0;sec<fkNOS;sec++){
3207 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
bfa00fba 3208 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
f47588e0 3209 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++){
bfa00fba 3210 Float_t gx[3];
3211 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
3212 cl->GetGlobalXYZ(gx);
f47588e0 3213 (*fDebugStreamer)<<"clDump"<<
b9d88e03 3214 "eventNr="<<eventNr<<
f47588e0 3215 "iter="<<iter<<
bfa00fba 3216 "cl.="<<cl<<
f47588e0 3217 "gx0="<<gx[0]<<
3218 "gx1="<<gx[1]<<
3219 "gx2="<<gx[2]<<
3220 "\n";
3221 }
bfa00fba 3222 cla = fOuterSec[sec][row].GetClusters2();
f47588e0 3223 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++){
bfa00fba 3224 Float_t gx[3];
3225 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
3226 cl->GetGlobalXYZ(gx);
f47588e0 3227 (*fDebugStreamer)<<"clDump"<<
b9d88e03 3228 "eventNr="<<eventNr<<
f47588e0 3229 "iter="<<iter<<
bfa00fba 3230 "cl.="<<cl<<
f47588e0 3231 "gx0="<<gx[0]<<
3232 "gx1="<<gx[1]<<
3233 "gx2="<<gx[2]<<
3234 "\n";
3235 }
3236 }
3237 }
3238
3239}
829455ad 3240void AliTPCtracker::UnsignClusters()
1c53abe2 3241{
91162307 3242 //
3243 // loop over all clusters and unsign them
3244 //
3245
3246 for (Int_t sec=0;sec<fkNIS;sec++){
3247 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
bfa00fba 3248 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
b9671574 3249 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
91162307 3250 // if (cl[icl].IsUsed(10))
bfa00fba 3251 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
3252 cla = fInnerSec[sec][row].GetClusters2();
b9671574 3253 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
91162307 3254 //if (cl[icl].IsUsed(10))
bfa00fba 3255 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
91162307 3256 }
3257 }
3258
3259 for (Int_t sec=0;sec<fkNOS;sec++){
3260 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
bfa00fba 3261 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
b9671574 3262 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
91162307 3263 //if (cl[icl].IsUsed(10))
bfa00fba 3264 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
3265 cla = fOuterSec[sec][row].GetClusters2();
b9671574 3266 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
91162307 3267 //if (cl[icl].IsUsed(10))
bfa00fba 3268 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
91162307 3269 }
3270 }
3271
1c53abe2 3272}
3273
91162307 3274
3275
829455ad 3276void AliTPCtracker::SignClusters(const TObjArray * arr, Float_t fnumber, Float_t fdensity)
1c53abe2 3277{
3278 //
91162307 3279 //sign clusters to be "used"
3280 //
3281 // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
3282 // loop over "primaries"
3283
3284 Float_t sumdens=0;
3285 Float_t sumdens2=0;
3286 Float_t sumn =0;
3287 Float_t sumn2 =0;
3288 Float_t sumchi =0;
3289 Float_t sumchi2 =0;
3290
3291 Float_t sum =0;
3292
1c53abe2 3293 TStopwatch timer;
91162307 3294 timer.Start();
1c53abe2 3295
91162307 3296 Int_t nseed = arr->GetEntriesFast();
3297 for (Int_t i=0; i<nseed; i++) {
3298 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3299 if (!pt) {
3300 continue;
3301 }
3302 if (!(pt->IsActive())) continue;
b9671574 3303 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
91162307 3304 if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
3305 sumdens += dens;
3306 sumdens2+= dens*dens;
3307 sumn += pt->GetNumberOfClusters();
3308 sumn2 += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
3309 Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
3310 if (chi2>5) chi2=5;
3311 sumchi +=chi2;
3312 sumchi2 +=chi2*chi2;
3313 sum++;
3314 }
1627d1c4 3315 }
91162307 3316
3317 Float_t mdensity = 0.9;
3318 Float_t meann = 130;
3319 Float_t meanchi = 1;
3320 Float_t sdensity = 0.1;
3321 Float_t smeann = 10;
3322 Float_t smeanchi =0.4;
1627d1c4 3323
91162307 3324
3325 if (sum>20){
3326 mdensity = sumdens/sum;
3327 meann = sumn/sum;
3328 meanchi = sumchi/sum;
3329 //
3330 sdensity = sumdens2/sum-mdensity*mdensity;
c1ea348f 3331 if (sdensity >= 0)
3332 sdensity = TMath::Sqrt(sdensity);
3333 else
3334 sdensity = 0.1;
91162307 3335 //
3336 smeann = sumn2/sum-meann*meann;
c1ea348f 3337 if (smeann >= 0)
3338 smeann = TMath::Sqrt(smeann);
3339 else
3340 smeann = 10;
91162307 3341 //
3342 smeanchi = sumchi2/sum - meanchi*meanchi;
c1ea348f 3343 if (smeanchi >= 0)
3344 smeanchi = TMath::Sqrt(smeanchi);
3345 else
3346 smeanchi = 0.4;
91162307 3347 }
3348
3349
3350 //REMOVE SHORT DELTAS or tracks going out of sensitive volume of TPC
3351 //
3352 for (Int_t i=0; i<nseed; i++) {
3353 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3354 if (!pt) {
3355 continue;
1c53abe2 3356 }
b9671574 3357 if (pt->GetBSigned()) continue;
3358 if (pt->GetBConstrain()) continue;
91162307 3359 //if (!(pt->IsActive())) continue;
3360 /*
3361 Int_t found,foundable,shared;
3362 pt->GetClusterStatistic(0,160,found, foundable,shared);
3363 if (shared/float(found)>0.3) {
3364 if (shared/float(found)>0.9 ){
ddfbc51a 3365 //MarkSeedFree( arr->RemoveAt(i) );
91162307 3366 }
3367 continue;
c9427e08 3368 }
91162307 3369 */
3370 Bool_t isok =kFALSE;
b9671574 3371 if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
91162307 3372 isok = kTRUE;
b9671574 3373 if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
91162307 3374 isok =kTRUE;
3375 if (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
3376 isok =kTRUE;
3377 if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
3378 isok =kTRUE;
3379
3380 if (isok)
77f88633 3381 for (Int_t j=0; j<160; ++j) {
3382 Int_t index=pt->GetClusterIndex2(j);
91162307 3383 if (index<0) continue;
77f88633 3384 AliTPCclusterMI *c= pt->GetClusterPointer(j);
91162307 3385 if (!c) continue;
3386 //if (!(c->IsUsed(10))) c->Use();
3387 c->Use(10);
3388 }
3389 }
3390
c9427e08 3391
1c53abe2 3392 //
91162307 3393 Double_t maxchi = meanchi+2.*smeanchi;
3394
3395 for (Int_t i=0; i<nseed; i++) {
3396 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3397 if (!pt) {
1c53abe2 3398 continue;
91162307 3399 }
3400 //if (!(pt->IsActive())) continue;
b9671574 3401 if (pt->GetBSigned()) continue;
91162307 3402 Double_t chi = pt->GetChi2()/pt->GetNumberOfClusters();
3403 if (chi>maxchi) continue;
3404
3405 Float_t bfactor=1;
b9671574 3406 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
91162307 3407
3408 //sign only tracks with enoug big density at the beginning
3409
3410 if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue;
3411
3412
3e5d0aa2 3413 Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
91162307 3414 Double_t minn = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
3415
3416 // if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
b9671574 3417 if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
91162307 3418 minn=0;
3419
3420 if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
3421 //Int_t noc=pt->GetNumberOfClusters();
b9671574 3422 pt->SetBSigned(kTRUE);
77f88633 3423 for (Int_t j=0; j<160; ++j) {
91162307 3424
77f88633 3425 Int_t index=pt->GetClusterIndex2(j);
91162307 3426 if (index<0) continue;
77f88633 3427 AliTPCclusterMI *c= pt->GetClusterPointer(j);
91162307 3428 if (!c) continue;
3429 // if (!(c->IsUsed(10))) c->Use();
3430 c->Use(10);
3431 }
1c53abe2 3432 }
91162307 3433 }
3434 // gLastCheck = nseed;
3435 // arr->Compress();
3436 if (fDebug>0){
3437 timer.Print();
3438 }
1c53abe2 3439}
3440
3441
1c53abe2 3442
829455ad 3443Int_t AliTPCtracker::RefitInward(AliESDEvent *event)
d26d9159 3444{
3445 //
3446 // back propagation of ESD tracks
3447 //
3448 //return 0;
ec26e231 3449 if (!event) return 0;
6d493ea0 3450 const Int_t kMaxFriendTracks=2000;
d26d9159 3451 fEvent = event;
72e25240 3452 fEventHLT = 0;
6d64657a 3453 // extract correction object for multiplicity dependence of dEdx
3454 TObjArray * gainCalibArray = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(event->GetRunNumber());
23728788 3455
3456 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
3457 if (!transform) {
3458 AliFatal("Tranformations not in RefitInward");
3459 return 0;
3460 }
3461 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
6d64657a 3462 const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
012c4694 3463 Int_t nContribut = event->GetNumberOfTracks();
6d64657a 3464 TGraphErrors * graphMultDependenceDeDx = 0x0;
23728788 3465 if (recoParam && recoParam->GetUseMultiplicityCorrectionDedx() && gainCalibArray) {
6d64657a 3466 if (recoParam->GetUseTotCharge()) {
3467 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
3468 } else {
3469 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
3470 }
3471 }
3472 //
d26d9159 3473 ReadSeeds(event,2);
3474 fIteration=2;
982aff31 3475 //PrepareForProlongation(fSeeds,1);
3476 PropagateForward2(fSeeds);
6d493ea0 3477 RemoveUsed2(fSeeds,0.4,0.4,20);
1af5da7e 3478
bda5ad6d 3479 Int_t entriesSeed=fSeeds->GetEntries();
3480 TObjArray arraySeed(entriesSeed);
3481 for (Int_t i=0;i<entriesSeed;i++) {
a0f4d6a6 3482 arraySeed.AddAt(fSeeds->At(i),i);
3483 }
3484 SignShared(&arraySeed);
6d493ea0 3485 // FindCurling(fSeeds, event,2); // find multi found tracks
1af5da7e 3486 FindSplitted(fSeeds, event,2); // find multi found tracks
65e67c9c 3487 if ((AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC)>0) FindMultiMC(fSeeds, fEvent,2); // flag: stream MC infomation about the multiple find track (ONLY for MC data)
af32720d 3488
4d158c36 3489 Int_t ntracks=0;
d26d9159 3490 Int_t nseed = fSeeds->GetEntriesFast();
3491 for (Int_t i=0;i<nseed;i++){
3492 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
4d158c36 3493 if (!seed) continue;
eea478d3 3494 if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
be34cb88 3495 AliESDtrack *esd=event->GetTrack(i);
3496
3497 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
3498 AliExternalTrackParam paramIn;
3499 AliExternalTrackParam paramOut;
3500 Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
65e67c9c 3501 if ((AliTPCReconstructor::StreamLevel() & kStreamRecoverIn)>0) { // flag: stream track information for track failing in RefitInward function and recovered back
3502 (*fDebugStreamer)<<"RecoverIn"<<
0e90d29a 3503 "seed.="<<seed<<
3504 "esd.="<<esd<<
3505 "pin.="<<&paramIn<<
3506 "pout.="<<&paramOut<<
3507 "ncl="<<ncl<<
3508 "\n";
3509 }
be34cb88 3510 if (ncl>15) {
3511 seed->Set(paramIn.GetX(),paramIn.GetAlpha(),paramIn.GetParameter(),paramIn.GetCovariance());
3512 seed->SetNumberOfClusters(ncl);
3513 }
3514 }
eea478d3 3515
47af7ca4 3516 seed->PropagateTo(fkParam->GetInnerRadiusLow());
51ad6848 3517 seed->UpdatePoints();
92f513f5 3518 AddCovariance(seed);
bad6eb00 3519 MakeESDBitmaps(seed, esd);
d26d9159 3520 seed->CookdEdx(0.02,0.6);
3521 CookLabel(seed,0.1); //For comparison only
af32720d 3522 //
65e67c9c 3523 if (((AliTPCReconstructor::StreamLevel()&kStreamRefitInward)>0) && seed!=0) {
af32720d 3524 TTreeSRedirector &cstream = *fDebugStreamer;
65e67c9c 3525 cstream<<"RefitInward"<< // flag: stream track information in RefitInward function (after tracking Iteration 2)
af32720d 3526 "Esd.="<<esd<<
3527 "Track.="<<seed<<
3528 "\n";
3529 }
c274e255 3530
51ad6848 3531 if (seed->GetNumberOfClusters()>15){
4d158c36 3532 esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
51ad6848 3533 esd->SetTPCPoints(seed->GetPoints());
b9671574 3534 esd->SetTPCPointsF(seed->GetNFoundable());
83afd539 3535 Int_t ndedx = seed->GetNCDEDX(0);
3536 Float_t sdedx = seed->GetSDEDX(0);
b406fdb0 3537 Float_t dedx = seed->GetdEdx();
6d64657a 3538 // apply mutliplicity dependent dEdx correction if available
3539 if (graphMultDependenceDeDx) {
6d64657a 3540 Double_t corrGain = AliTPCcalibDButil::EvalGraphConst(graphMultDependenceDeDx, nContribut);
012c4694 3541 dedx += (1 - corrGain)*50.; // MIP is normalized to 50
6d64657a 3542 }
b406fdb0 3543 esd->SetTPCsignal(dedx, sdedx, ndedx);
fdedfdec 3544 //
64bf5ca0 3545 // fill new dEdx information
3546 //
3547 Double32_t signal[4];
dee67df8 3548 Double32_t signalMax[4];
64bf5ca0 3549 Char_t ncl[3];
3550 Char_t nrows[3];
3551 //
3552 for(Int_t iarr=0;iarr<3;iarr++) {
fb57da8a 3553 signal[iarr] = seed->GetDEDXregion(iarr+1);
dee67df8 3554 signalMax[iarr] = seed->GetDEDXregion(iarr+5);
fb57da8a 3555 ncl[iarr] = seed->GetNCDEDX(iarr+1);
3556 nrows[iarr] = seed->GetNCDEDXInclThres(iarr+1);
64bf5ca0 3557 }
3558 signal[3] = seed->GetDEDXregion(4);
dee67df8 3559 signalMax[3] = seed->GetDEDXregion(8);
3560
64bf5ca0 3561 //
ddfbc51a 3562 AliTPCdEdxInfo * infoTpcPid = new AliTPCdEdxInfo();
64bf5ca0 3563 infoTpcPid->SetTPCSignalRegionInfo(signal, ncl, nrows);
dee67df8 3564 infoTpcPid->SetTPCSignalsQmax(signalMax);
64bf5ca0 3565 esd->SetTPCdEdxInfo(infoTpcPid);
3566 //
fdedfdec 3567 // add seed to the esd track in Calib level
3568 //
6d493ea0 3569 Bool_t storeFriend = gRandom->Rndm()<(kMaxFriendTracks)/Float_t(nseed);
ddfbc51a 3570 if (AliTPCReconstructor::StreamLevel()>0 &&storeFriend){
3571 // RS: this is the only place where the seed is created not in the pool,
3572 // since it should belong to ESDevent
3573 AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE);
fdedfdec 3574 esd->AddCalibObject(seedCopy);
3575 }
4d158c36 3576 ntracks++;
d26d9159 3577 }
3578 else{
3579 //printf("problem\n");
3580 }
3581 }
51ad6848 3582 //FindKinks(fSeeds,event);
65e67c9c 3583 if ((AliTPCReconstructor::StreamLevel()&kStreamClDump)>0) DumpClusters(2,fSeeds); // dump clusters at the end of process (signed with useage flags)
4d158c36 3584 Info("RefitInward","Number of refitted tracks %d",ntracks);
3aa6a136 3585
3586 AliCosmicTracker::FindCosmic(event, kTRUE);
3587
5576d489 3588 FillClusterOccupancyInfo();
3589
d26d9159 3590 return 0;
3591}
3592
1c53abe2 3593
829455ad 3594Int_t AliTPCtracker::PropagateBack(AliESDEvent *event)
91162307 3595{
3596 //
3597 // back propagation of ESD tracks
3598 //
ec26e231 3599 if (!event) return 0;
91162307 3600 fEvent = event;
72e25240 3601 fEventHLT = 0;
d26d9159 3602 fIteration = 1;
5d837844 3603 ReadSeeds(event,1);
b406fdb0 3604 PropagateBack(fSeeds);
3605 RemoveUsed2(fSeeds,0.4,0.4,20);
6d493ea0 3606 //FindCurling(fSeeds, fEvent,1);
1af5da7e 3607 FindSplitted(fSeeds, event,1); // find multi found tracks
65e67c9c 3608 if ((AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC)>0) FindMultiMC(fSeeds, fEvent,1); // find multi found tracks
1af5da7e 3609
b406fdb0 3610 //
91162307 3611 Int_t nseed = fSeeds->GetEntriesFast();
4d158c36 3612 Int_t ntracks=0;
91162307 3613 for (Int_t i=0;i<nseed;i++){
3614 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
d9e62e7e 3615 if (!seed) continue;
51ad6848 3616 if (seed->GetKinkIndex(0)<0) UpdateKinkQualityM(seed); // update quality informations for kinks
3617 seed->UpdatePoints();
92f513f5 3618 AddCovariance(seed);
91162307 3619 AliESDtrack *esd=event->GetTrack(i);
e1dadcd0 3620 if (!esd) continue; //never happen
be34cb88 3621 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
3622 AliExternalTrackParam paramIn;
3623 AliExternalTrackParam paramOut;
3624 Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
65e67c9c 3625 if ((AliTPCReconstructor::StreamLevel()&kStreamRecoverBack)>0) { // flag: stream track information for track faling PropagateBack function and recovered back (RefitTrack)
ca449e98 3626 (*fDebugStreamer)<<"RecoverBack"<<
3627 "seed.="<<seed<<
3628 "esd.="<<esd<<
3629 "pin.="<<&paramIn<<
3630 "pout.="<<&paramOut<<
3631 "ncl="<<ncl<<
3632 "\n";
3633 }
be34cb88 3634 if (ncl>15) {
3635 seed->Set(paramOut.GetX(),paramOut.GetAlpha(),paramOut.GetParameter(),paramOut.GetCovariance());
3636 seed->SetNumberOfClusters(ncl);
3637 }
3638 }
d26d9159 3639 seed->CookdEdx(0.02,0.6);
91162307 3640 CookLabel(seed,0.1); //For comparison only
51ad6848 3641 if (seed->GetNumberOfClusters()>15){
4d158c36 3642 esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
51ad6848 3643 esd->SetTPCPoints(seed->GetPoints());
b9671574 3644 esd->SetTPCPointsF(seed->GetNFoundable());
83afd539 3645 Int_t ndedx = seed->GetNCDEDX(0);
3646 Float_t sdedx = seed->GetSDEDX(0);
167c41ab 3647 Float_t dedx = seed->GetdEdx();
3648 esd->SetTPCsignal(dedx, sdedx, ndedx);
4d158c36 3649 ntracks++;
31fd97b2 3650 Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
3651 // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
65e67c9c 3652 if (((AliTPCReconstructor::StreamLevel()&kStreamCPropagateBack)>0) && esd) {
3653 (*fDebugStreamer)<<"PropagateBack"<< // flag: stream track information in PropagateBack function (after tracking Iteration 1)
6d493ea0 3654 "Tr0.="<<seed<<
8cecaa87 3655 "esd.="<<esd<<
6d493ea0 3656 "EventNrInFile="<<eventnumber<<
8cecaa87 3657 "\n";
6d493ea0 3658 }
4d158c36 3659 }
91162307 3660 }
65e67c9c 3661 if (AliTPCReconstructor::StreamLevel()&kStreamClDump) DumpClusters(1,fSeeds); // flag:stream clusters at the end of process (signed with usage flag)
51ad6848 3662 //FindKinks(fSeeds,event);
4d158c36 3663 Info("PropagateBack","Number of back propagated tracks %d",ntracks);
91162307 3664 fEvent =0;
72e25240 3665 fEventHLT = 0;
3666
91162307 3667 return 0;
3668}
3669
3670
829455ad 3671Int_t AliTPCtracker::PostProcess(AliESDEvent *event)
ec7e4ad6 3672{
3673 //
3674 // Post process events
3675 //
3676 if (!event) return 0;
3677
3678 //
3679 // Set TPC event status
3680 //
3681
3682 // event affected by HV dip
3683 // reset TPC status
3684 if(IsTPCHVDipEvent(event)) {
3685 event->ResetDetectorStatus(AliDAQ::kTPC);
3686 }
3687
3688 //printf("Status %d \n", event->IsDetectorOn(AliDAQ::kTPC));
3689
3690 return 0;
3691}
3692
3693
829455ad 3694 void AliTPCtracker::DeleteSeeds()
91162307 3695{
b67e07dc 3696 //
f06a1ff6 3697 fSeeds->Clear();
ddfbc51a 3698 ResetSeedsPool();
91162307 3699 delete fSeeds;
3700 fSeeds =0;
3701}
3702
829455ad 3703void AliTPCtracker::ReadSeeds(const AliESDEvent *const event, Int_t direction)
91162307 3704{
3705 //
3706 //read seeds from the event
3707
3708 Int_t nentr=event->GetNumberOfTracks();
6bdc18d6 3709 if (fDebug>0){
3710 Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
3711 }
91162307 3712 if (fSeeds)
3713 DeleteSeeds();
3714 if (!fSeeds){
4d158c36 3715 fSeeds = new TObjArray(nentr);
91162307 3716 }
4d158c36 3717 UnsignClusters();
3718 // Int_t ntrk=0;
91162307 3719 for (Int_t i=0; i<nentr; i++) {
3720 AliESDtrack *esd=event->GetTrack(i);
51ad6848 3721 ULong_t status=esd->GetStatus();
3722 if (!(status&AliESDtrack::kTPCin)) continue;
1af5da7e 3723 AliTPCtrack t(*esd);
5d837844 3724 t.SetNumberOfClusters(0);
eea478d3 3725 // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
ddfbc51a 3726 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(t/*,t.GetAlpha()*/);
3727 seed->SetPoolID(fLastSeedID);
a0f4d6a6 3728 seed->SetUniqueID(esd->GetID());
92f513f5 3729 AddCovariance(seed); //add systematic ucertainty
eea478d3 3730 for (Int_t ikink=0;ikink<3;ikink++) {
3731 Int_t index = esd->GetKinkIndex(ikink);
3732 seed->GetKinkIndexes()[ikink] = index;
3733 if (index==0) continue;
3734 index = TMath::Abs(index);
3735 AliESDkink * kink = fEvent->GetKink(index-1);
3736 if (kink&&esd->GetKinkIndex(ikink)<0){
3737 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
3738 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,0);
3739 }
3740 if (kink&&esd->GetKinkIndex(ikink)>0){
3741 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
3742 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,4);
3743 }
3744
3745 }
6c94f330 3746 if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.);
2c4acef0 3747 //RS if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
6c94f330 3748 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
be34cb88 3749 //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
3750 // fSeeds->AddAt(0,i);
ddfbc51a 3751 // MarkSeedFree( seed );
be34cb88 3752 // continue;
3753 //}
a3986da2 3754
91162307 3755 //
3756 //
3757 // rotate to the local coordinate system
eea478d3 3758 //
3759 fSectors=fInnerSec; fN=fkNIS;
f124f8bf 3760 Double_t alpha=seed->GetAlpha();
91162307 3761 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
3762 if (alpha < 0. ) alpha += 2.*TMath::Pi();
a3f36f42 3763 Int_t ns=Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
91162307 3764 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
f124f8bf 3765 alpha-=seed->GetAlpha();
4d158c36 3766 if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
3767 if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
f124f8bf 3768 if (TMath::Abs(alpha) > 0.001) { // This should not happen normally
3769 AliWarning(Form("Rotating track over %f",alpha));
3770 if (!seed->Rotate(alpha)) {
ddfbc51a 3771 MarkSeedFree( seed );
f124f8bf 3772 continue;
3773 }
d9b8978b 3774 }
b9671574 3775 seed->SetESD(esd);
4d158c36 3776 // sign clusters
b406fdb0 3777 if (esd->GetKinkIndex(0)<=0){
3778 for (Int_t irow=0;irow<160;irow++){
3779 Int_t index = seed->GetClusterIndex2(irow);
bad6eb00 3780 if (index >= 0){
b406fdb0 3781 //
3782 AliTPCclusterMI * cl = GetClusterMI(index);
b9671574 3783 seed->SetClusterPointer(irow,cl);
b406fdb0 3784 if (cl){
3785 if ((index & 0x8000)==0){
3786 cl->Use(10); // accepted cluster
3787 }else{
3788 cl->Use(6); // close cluster not accepted
3789 }
4d158c36 3790 }else{
b406fdb0 3791 Info("ReadSeeds","Not found cluster");
3792 }
4d158c36 3793 }
3794 }
3795 }
3796 fSeeds->AddAt(seed,i);
91162307 3797 }
3798}
3799
3800
3801
3802//_____________________________________________________________________________
829455ad 3803void AliTPCtracker::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
91162307 3804 Float_t deltay, Int_t ddsec) {
3805 //-----------------------------------------------------------------
3806 // This function creates track seeds.
3807 // SEEDING WITH VERTEX CONSTRAIN
3808 //-----------------------------------------------------------------
3809 // cuts[0] - fP4 cut
3810 // cuts[1] - tan(phi) cut
3811 // cuts[2] - zvertex cut
3812 // cuts[3] - fP3 cut
3813 Int_t nin0 = 0;
3814 Int_t nin1 = 0;
3815 Int_t nin2 = 0;
3816 Int_t nin = 0;
3817 Int_t nout1 = 0;
3818 Int_t nout2 = 0;
3819
3820 Double_t x[5], c[15];
3821 // Int_t di = i1-i2;
3822 //
ddfbc51a 3823 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed();
3824 seed->SetPoolID(fLastSeedID);
91162307 3825 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
3826 Double_t cs=cos(alpha), sn=sin(alpha);
d757548f 3827 //
3828 // Double_t x1 =fOuterSec->GetX(i1);
3829 //Double_t xx2=fOuterSec->GetX(i2);
3830
91162307 3831 Double_t x1 =GetXrow(i1);
3832 Double_t xx2=GetXrow(i2);
3833
3834 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
3835
3836 Int_t imiddle = (i2+i1)/2; //middle pad row index
3837 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
bd26fa83 3838 const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
91162307 3839 //
3840 Int_t ns =sec;
3841
bd26fa83 3842 const AliTPCtrackerRow& kr1=GetRow(ns,i1);
b9671574 3843 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
3844 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
91162307 3845
3846 //
3847 // change cut on curvature if it can't reach this layer
3848 // maximal curvature set to reach it
3849 Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
3850 if (dvertexmax*0.5*cuts[0]>0.85){
3851 cuts[0] = 0.85/(dvertexmax*0.5+1.);
3852 }
3853 Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
3854
3855 // Int_t ddsec = 1;
3856 if (deltay>0) ddsec = 0;
3857 // loop over clusters
3858 for (Int_t is=0; is < kr1; is++) {
3859 //
3860 if (kr1[is]->IsUsed(10)) continue;
3e1f1ce7 3861 if (kr1[is]->IsDisabled()) {
3862 continue;
3863 }
65e67c9c 3864
91162307 3865 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3866 //if (TMath::Abs(y1)>ymax) continue;
3867
3868 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3869
3870 // find possible directions
3871 Float_t anglez = (z1-z3)/(x1-x3);
3872 Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
3873 //
3874 //
3875 //find rotation angles relative to line given by vertex and point 1
3876 Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
3877 Double_t dvertex = TMath::Sqrt(dvertex2);
3878 Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
3879 Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
3880
3881 //
3882 // loop over 2 sectors
3883 Int_t dsec1=-ddsec;
3884 Int_t dsec2= ddsec;
3885 if (y1<0) dsec2= 0;
3886 if (y1>0) dsec1= 0;
3887
3888 Double_t dddz1=0; // direction of delta inclination in z axis
3889 Double_t dddz2=0;
3890 if ( (z1-z3)>0)
3891 dddz1 =1;
3892 else
3893 dddz2 =1;
3894 //
3895 for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
3896 Int_t sec2 = sec + dsec;
3897 //
bd26fa83 3898 // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
3899 //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
3900 AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
3901 AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
91162307 3902 Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
3903 Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
3904
3905 // rotation angles to p1-p3
3906 Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
3907 Double_t x2, y2, z2;
3908 //
3909 // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
3910
3911 //
3912 Double_t dxx0 = (xx2-x3)*cs13r;
3913 Double_t dyy0 = (xx2-x3)*sn13r;
3914 for (Int_t js=index1; js < index2; js++) {
3915 const AliTPCclusterMI *kcl = kr2[js];
65e67c9c 3916 if (kcl->IsUsed(10)) continue;
3e1f1ce7 3917 if (kcl->IsDisabled()) {
3918 continue;
3919 }
91162307 3920 //
3921 //calcutate parameters
3922 //
3923 Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
3924 // stright track
3925 if (TMath::Abs(yy0)<0.000001) continue;
3926 Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
3927 Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
3928 Double_t r02 = (0.25+y0*y0)*dvertex2;
3929 //curvature (radius) cut
3930 if (r02<r2min) continue;
3931
3932 nin0++;
3933 //
3934 Double_t c0 = 1/TMath::Sqrt(r02);
3935 if (yy0>0) c0*=-1.;
3936
3937
3938 //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
3939 //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
b67e07dc 3940 Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
3941 Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
91162307 3942 //
3943 //
3944 Double_t z0 = kcl->GetZ();
3945 Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
3946 if (TMath::Abs(zzzz2-z0)>0.5) continue;
3947 nin1++;
3948 //
3949 Double_t dip = (z1-z0)*c0/dfi1;
3950 Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
3951 //
3952 y2 = kcl->GetY();
3953 if (dsec==0){
3954 x2 = xx2;
3955 z2 = kcl->GetZ();
3956 }
3957 else
3958 {
3959 // rotation
3960 z2 = kcl->GetZ();
3961 x2= xx2*cs-y2*sn*dsec;
3962 y2=+xx2*sn*dsec+y2*cs;
3963 }
3964
3965 x[0] = y1;
3966 x[1] = z1;
3967 x[2] = x0;
3968 x[3] = dip;
3969 x[4] = c0;
3970 //
3971 //
3972 // do we have cluster at the middle ?
3973 Double_t ym,zm;
3974 GetProlongation(x1,xm,x,ym,zm);
3975 UInt_t dummy;
3976 AliTPCclusterMI * cm=0;
3977 if (TMath::Abs(ym)-ymaxm<0){
3978 cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3979 if ((!cm) || (cm->IsUsed(10))) {
3980 continue;
3981 }
3982 }
3983 else{
3984 // rotate y1 to system 0
3985 // get state vector in rotated system
3986 Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
3987 Double_t xr2 = x0*cs+yr1*sn*dsec;
3988 Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3989 //
3990 GetProlongation(xx2,xm,xr,ym,zm);
3991 if (TMath::Abs(ym)-ymaxm<0){
3992 cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3993 if ((!cm) || (cm->IsUsed(10))) {
3994 continue;
3995 }
3996 }
3997 }
3998
3999
2a97785a 4000 // Double_t dym = 0;
4001 // Double_t dzm = 0;
4002 // if (cm){
4003 // dym = ym - cm->GetY();
4004 // dzm = zm - cm->GetZ();
4005 // }
91162307 4006 nin2++;
4007
4008
4009 //
4010 //
4011 Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
4012 Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
4013 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
4014 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
4015 //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
4016
b67e07dc 4017 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
4018 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
4019 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
4020 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
4021 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
4022 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
91162307 4023
b67e07dc 4024 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
4025 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
4026 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
4027 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
91162307 4028
1c53abe2 4029 c[0]=sy1;
4030 c[1]=0.; c[2]=sz1;
4031 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4032 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4033 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4034 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4035 c[13]=f30*sy1*f40+f32*sy2*f42;
4036 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
91162307 4037
d757548f 4038 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
91162307 4039
1c53abe2 4040 UInt_t index=kr1.GetIndex(is);
ddfbc51a 4041 if (seed) {MarkSeedFree(seed); seed = 0;}
4042 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, ns*alpha+shift, x, c, index);
4043 seed->SetPoolID(fLastSeedID);
d757548f 4044 track->SetIsSeeding(kTRUE);
4045 track->SetSeed1(i1);
4046 track->SetSeed2(i2);
4047 track->SetSeedType(3);
c9427e08 4048
91162307 4049
4050 //if (dsec==0) {
d757548f 4051 FollowProlongation(*track, (i1+i2)/2,1);
91162307 4052 Int_t foundable,found,shared;
d757548f 4053 track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
4054 if ((found<0.55*foundable) || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
ddfbc51a 4055 MarkSeedFree(seed); seed = 0;
91162307 4056 continue;
4057 }
4058 //}
4059
4060 nin++;
d757548f 4061 FollowProlongation(*track, i2,1);
91162307 4062
4063
4064 //Int_t rc = 1;
d757548f 4065 track->SetBConstrain(1);
91162307 4066 // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
d757548f 4067 track->SetLastPoint(i1); // first cluster in track position
4068 track->SetFirstPoint(track->GetLastPoint());
91162307 4069
d757548f 4070 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
4071 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
4072 track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
ddfbc51a 4073 MarkSeedFree(seed); seed = 0;
c9427e08 4074 continue;
4075 }
91162307 4076 nout1++;
4077 // Z VERTEX CONDITION
c274e255 4078 Double_t zv, bz=GetBz();
d757548f 4079 if ( !track->GetZAt(0.,bz,zv) ) continue;
91162307 4080 if (TMath::Abs(zv-z3)>cuts[2]) {
d757548f 4081 FollowProlongation(*track, TMath::Max(i2-20,0));
4082 if ( !track->GetZAt(0.,bz,zv) ) continue;
91162307 4083 if (TMath::Abs(zv-z3)>cuts[2]){
d757548f 4084 FollowProlongation(*track, TMath::Max(i2-40,0));
4085 if ( !track->GetZAt(0.,bz,zv) ) continue;
4086 if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
91162307 4087 // make seed without constrain
d757548f 4088 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
91162307 4089 FollowProlongation(*track2, i2,1);
b9671574 4090 track2->SetBConstrain(kFALSE);
4091 track2->SetSeedType(1);
d757548f 4092 arr->AddLast(track2);
ddfbc51a 4093 MarkSeedFree( seed ); seed = 0;
91162307 4094 continue;
4095 }
4096 else{
ddfbc51a 4097 MarkSeedFree( seed ); seed = 0;
91162307 4098 continue;
d757548f 4099
91162307 4100 }
4101 }
c9427e08 4102 }
316c6cd9 4103
d757548f 4104 track->SetSeedType(0);
f06a1ff6 4105 arr->AddLast(track); // note, track is seed, don't free the seed
ddfbc51a 4106 seed = new( NextFreeSeed() ) AliTPCseed;
4107 seed->SetPoolID(fLastSeedID);
91162307 4108 nout2++;
4109 // don't consider other combinations
d757548f 4110 if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
91162307 4111 break;
1c53abe2 4112 }
4113 }
4114 }
6bdc18d6 4115 if (fDebug>3){
4116 Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
91162307 4117 }
ddfbc51a 4118 if (seed) MarkSeedFree( seed );
1c53abe2 4119}
4120
1627d1c4 4121
829455ad 4122void AliTPCtracker::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
91162307 4123 Float_t deltay) {
4124
4125
4126
1627d1c4 4127 //-----------------------------------------------------------------
91162307 4128 // This function creates track seeds.
1627d1c4 4129 //-----------------------------------------------------------------
91162307 4130 // cuts[0] - fP4 cut
4131 // cuts[1] - tan(phi) cut
4132 // cuts[2] - zvertex cut
4133 // cuts[3] - fP3 cut
4134
4135
4136 Int_t nin0 = 0;
4137 Int_t nin1 = 0;
4138 Int_t nin2 = 0;
4139 Int_t nin = 0;
4140 Int_t nout1 = 0;
4141 Int_t nout2 = 0;
4142 Int_t nout3 =0;
4143 Double_t x[5], c[15];
4144 //
4145 // make temporary seed
ddfbc51a 4146 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
4147 seed->SetPoolID(fLastSeedID);
1627d1c4 4148 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
4149 // Double_t cs=cos(alpha), sn=sin(alpha);
91162307 4150 //
4151 //
1627d1c4 4152
91162307 4153 // first 3 padrows
4154 Double_t x1 = GetXrow(i1-1);
bd26fa83 4155 const AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
b9671574 4156 Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
91162307 4157 //
4158 Double_t x1p = GetXrow(i1);
bd26fa83 4159 const AliTPCtrackerRow& kr1p=GetRow(sec,i1);
91162307 4160 //
4161 Double_t x1m = GetXrow(i1-2);
bd26fa83 4162 const AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
1627d1c4 4163
91162307 4164 //
4165 //last 3 padrow for seeding
bd26fa83 4166 AliTPCtrackerRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
91162307 4167 Double_t x3 = GetXrow(i1-7);
4168 // Double_t y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;
4169 //
bd26fa83 4170 AliTPCtrackerRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
91162307 4171 Double_t x3p = GetXrow(i1-6);
4172 //
bd26fa83 4173 AliTPCtrackerRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
91162307 4174 Double_t x3m = GetXrow(i1-8);
1627d1c4 4175
91162307 4176 //
4177 //
4178 // middle padrow
4179 Int_t im = i1-4; //middle pad row index
4180 Double_t xm = GetXrow(im); // radius of middle pad-row
bd26fa83 4181 const AliTPCtrackerRow& krm=GetRow(sec,im); //middle pad -row
91162307 4182 // Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;
4183 //
4184 //
4185 Double_t deltax = x1-x3;
4186 Double_t dymax = deltax*cuts[1];
4187 Double_t dzmax = deltax*cuts[3];
4188 //
4189 // loop over clusters
4190 for (Int_t is=0; is < kr1; is++) {
1627d1c4 4191 //
65e67c9c 4192 if (kr1[is]->IsUsed(10)) continue;
3e1f1ce7 4193 if (kr1[is]->IsDisabled()) {
4194 continue;
4195 }
65e67c9c 4196
91162307 4197 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
1627d1c4 4198 //
91162307 4199 if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
4200 //
4201 Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
4202 Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
4203 //
4204 Double_t y3, z3;
1627d1c4 4205 //
1627d1c4 4206 //
91162307 4207 UInt_t index;
4208 for (Int_t js=index1; js < index2; js++) {
4209 const AliTPCclusterMI *kcl = kr3[js];
3e1f1ce7 4210 if (kcl->IsDisabled()) {
4211 continue;
4212 }
65e67c9c 4213
91162307 4214 if (kcl->IsUsed(10)) continue;
4215 y3 = kcl->GetY();
4216 // apply angular cuts
4217 if (TMath::Abs(y1-y3)>dymax) continue;
97d77e7a 4218 //x3 = x3;
91162307 4219 z3 = kcl->GetZ();
4220 if (TMath::Abs(z1-z3)>dzmax) continue;
4221 //
4222 Double_t angley = (y1-y3)/(x1-x3);
4223 Double_t anglez = (z1-z3)/(x1-x3);
4224 //
4225 Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
4226 Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
4227 //
4228 Double_t yyym = angley*(xm-x1)+y1;
4229 Double_t zzzm = anglez*(xm-x1)+z1;
4230
4231 const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
4232 if (!kcm) continue;
4233 if (kcm->IsUsed(10)) continue;
3e1f1ce7 4234 if (kcm->IsDisabled()) {
4235 continue;
4236 }
65e67c9c 4237
91162307 4238 erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
4239 errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
4240 //
4241 //
4242 //
4243 Int_t used =0;
4244 Int_t found =0;
4245 //
4246 // look around first
4247 const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
4248 anglez*(x1m-x1)+z1,
4249 erry,errz,index);
4250 //
4251 if (kc1m){
4252 found++;
4253 if (kc1m->IsUsed(10)) used++;
1627d1c4 4254 }
91162307 4255 const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
4256 anglez*(x1p-x1)+z1,
4257 erry,errz,index);
1627d1c4 4258 //
91162307 4259 if (kc1p){
4260 found++;
4261 if (kc1p->IsUsed(10)) used++;
1627d1c4 4262 }
91162307 4263 if (used>1) continue;
4264 if (found<1) continue;
1627d1c4 4265
91162307 4266 //
4267 // look around last
4268 const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
4269 anglez*(x3m-x3)+z3,
4270 erry,errz,index);
4271 //
4272 if (kc3m){
4273 found++;
4274 if (kc3m->IsUsed(10)) used++;
4275 }
4276 else
4277 continue;
4278 const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
4279 anglez*(x3p-x3)+z3,
4280 erry,errz,index);
4281 //
4282 if (kc3p){
4283 found++;
4284 if (kc3p->IsUsed(10)) used++;
4285 }
4286 else
4287 continue;
4288 if (used>1) continue;
4289 if (found<3) continue;
4290 //
4291 Double_t x2,y2,z2;
4292 x2 = xm;
4293 y2 = kcm->GetY();
4294 z2 = kcm->GetZ();
4295 //
4296
1627d1c4 4297 x[0]=y1;
4298 x[1]=z1;
b67e07dc 4299 x[4]=F1(x1,y1,x2,y2,x3,y3);
91162307 4300 //if (TMath::Abs(x[4]) >= cuts[0]) continue;
4301 nin0++;
4302 //
b67e07dc 4303 x[2]=F2(x1,y1,x2,y2,x3,y3);
91162307 4304 nin1++;
4305 //
b67e07dc 4306 x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
91162307 4307 //if (TMath::Abs(x[3]) > cuts[3]) continue;
4308 nin2++;
4309 //
4310 //
4311 Double_t sy1=0.1, sz1=0.1;
4312 Double_t sy2=0.1, sz2=0.1;
4313 Double_t sy3=0.1, sy=0.1, sz=0.1;
1627d1c4 4314
b67e07dc 4315 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
4316 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
4317 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
4318 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
4319 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
4320 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
91162307 4321
b67e07dc 4322 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
4323 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
4324 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
4325 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
1627d1c4 4326
4327 c[0]=sy1;
91162307 4328 c[1]=0.; c[2]=sz1;
1627d1c4 4329 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4330 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4331 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4332 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4333 c[13]=f30*sy1*f40+f32*sy2*f42;
4334 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4335
91162307 4336 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
4337
77f88633 4338 index=kr1.GetIndex(is);
ddfbc51a 4339 if (seed) {MarkSeedFree( seed ); seed = 0;}
4340 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, sec*alpha+shift, x, c, index);
4341 seed->SetPoolID(fLastSeedID);
91162307 4342
b9671574 4343 track->SetIsSeeding(kTRUE);
91162307 4344
4345 nin++;
4346 FollowProlongation(*track, i1-7,1);
b9671574 4347 if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
4348 track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
ddfbc51a 4349 MarkSeedFree( seed ); seed = 0;
91162307 4350 continue;
4351 }
4352 nout1++;
4353 nout2++;
4354 //Int_t rc = 1;
4355 FollowProlongation(*track, i2,1);
b9671574 4356 track->SetBConstrain(0);
4357 track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
4358 track->SetFirstPoint(track->GetLastPoint());
91162307 4359
4360 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 4361 track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
4362 track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
ddfbc51a 4363 MarkSeedFree( seed ); seed = 0;
91162307 4364 continue;
4365 }
4366
4367 {
4368 FollowProlongation(*track, TMath::Max(i2-10,0),1);
4369 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
4370 FollowProlongation(*track2, i2,1);
b9671574 4371 track2->SetBConstrain(kFALSE);
4372 track2->SetSeedType(4);
f06a1ff6 4373 arr->AddLast(track2);
ddfbc51a 4374 MarkSeedFree( seed ); seed = 0;
91162307 4375 }
4376
4377
4378 //arr->AddLast(track);
4379 //seed = new AliTPCseed;
4380 nout3++;
4381 }
4382 }
4383
6bdc18d6 4384 if (fDebug>3){
7d85e147 4385 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 4386 }
ddfbc51a 4387 if (seed) MarkSeedFree(seed);
91162307 4388}
4389
4390
4391//_____________________________________________________________________________
829455ad 4392void AliTPCtracker::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
176aff27 4393 Float_t deltay, Bool_t /*bconstrain*/) {
91162307 4394 //-----------------------------------------------------------------
4395 // This function creates track seeds - without vertex constraint
4396 //-----------------------------------------------------------------
4397 // cuts[0] - fP4 cut - not applied
4398 // cuts[1] - tan(phi) cut
4399 // cuts[2] - zvertex cut - not applied
4400 // cuts[3] - fP3 cut
4401 Int_t nin0=0;
4402 Int_t nin1=0;
4403 Int_t nin2=0;
4404 Int_t nin3=0;
4405 // Int_t nin4=0;
4406 //Int_t nin5=0;
4407
4408
4409
4410 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
4411 // Double_t cs=cos(alpha), sn=sin(alpha);
4412 Int_t row0 = (i1+i2)/2;
4413 Int_t drow = (i1-i2)/2;
bd26fa83 4414 const AliTPCtrackerRow& kr0=fSectors[sec][row0];
4415 AliTPCtrackerRow * kr=0;
91162307 4416
4417 AliTPCpolyTrack polytrack;
4418 Int_t nclusters=fSectors[sec][row0];
ddfbc51a 4419 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
4420 seed->SetPoolID(fLastSeedID);
91162307 4421
4422 Int_t sumused=0;
4423 Int_t cused=0;
4424 Int_t cnused=0;
4425 for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
4426 Int_t nfound =0;
4427 Int_t nfoundable =0;
4428 for (Int_t iter =1; iter<2; iter++){ //iterations
bd26fa83 4429 const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
4430 const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];
91162307 4431 const AliTPCclusterMI * cl= kr0[is];
3e1f1ce7 4432 if (cl->IsDisabled()) {
4433 continue;
4434 }
65e67c9c 4435
91162307 4436 if (cl->IsUsed(10)) {
4437 cused++;
4438 }
4439 else{
4440 cnused++;
4441 }
4442 Double_t x = kr0.GetX();
4443 // Initialization of the polytrack
4444 nfound =0;
4445 nfoundable =0;
4446 polytrack.Reset();
4447 //
4448 Double_t y0= cl->GetY();
4449 Double_t z0= cl->GetZ();
4450 Float_t erry = 0;
4451 Float_t errz = 0;
4452
b9671574 4453 Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
91162307 4454 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
4455
4456 erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
4457 errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
4458 polytrack.AddPoint(x,y0,z0,erry, errz);
4459
4460 sumused=0;
4461 if (cl->IsUsed(10)) sumused++;
4462
4463
4464 Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
4465 Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
4466 //
4467 x = krm.GetX();
4468 AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
4469 if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
4470 erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
4471 errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
4472 if (cl1->IsUsed(10)) sumused++;
4473 polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
4474 }
4475 //
4476 x = krp.GetX();
4477 AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
4478 if (cl2) {
4479 erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
4480 errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
4481 if (cl2->IsUsed(10)) sumused++;
4482 polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
4483 }
4484 //
4485 if (sumused>0) continue;
4486 nin0++;
4487 polytrack.UpdateParameters();
4488 // follow polytrack
4489 roadz = 1.2;
4490 roady = 1.2;
4491 //
4492 Double_t yn,zn;
4493 nfoundable = polytrack.GetN();
4494 nfound = nfoundable;
4495 //
4496 for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
4497 Float_t maxdist = 0.8*(1.+3./(ddrow));
4498 for (Int_t delta = -1;delta<=1;delta+=2){
4499 Int_t row = row0+ddrow*delta;
4500 kr = &(fSectors[sec][row]);
4501 Double_t xn = kr->GetX();
77f88633 4502 Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
91162307 4503 polytrack.GetFitPoint(xn,yn,zn);
77f88633 4504 if (TMath::Abs(yn)>ymax1) continue;
91162307 4505 nfoundable++;
4506 AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
4507 if (cln) {
4508 Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
4509 if (dist<maxdist){
4510 /*
4511 erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
4512 errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
4513 if (cln->IsUsed(10)) {
4514 // printf("used\n");
4515 sumused++;
4516 erry*=2;
4517 errz*=2;
4518 }
4519 */
4520 erry=0.1;
4521 errz=0.1;
4522 polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
4523 nfound++;
4524 }
4525 }
4526 }
4527 if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
4528 polytrack.UpdateParameters();
4529 }
4530 }
4531 if ( (sumused>3) || (sumused>0.5*nfound)) {
4532 //printf("sumused %d\n",sumused);
4533 continue;
4534 }
4535 nin1++;
4536 Double_t dy,dz;
4537 polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
4538 AliTPCpolyTrack track2;
4539
4540 polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
4541 if (track2.GetN()<0.5*nfoundable) continue;
4542 nin2++;
4543
4544 if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
4545 //
4546 // test seed with and without constrain
4547 for (Int_t constrain=0; constrain<=0;constrain++){
4548 // add polytrack candidate
4549
4550 Double_t x[5], c[15];
4551 Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
4552 track2.GetBoundaries(x3,x1);
4553 x2 = (x1+x3)/2.;
4554 track2.GetFitPoint(x1,y1,z1);
4555 track2.GetFitPoint(x2,y2,z2);
4556 track2.GetFitPoint(x3,y3,z3);
4557 //
4558 //is track pointing to the vertex ?
4559 Double_t x0,y0,z0;
4560 x0=0;
4561 polytrack.GetFitPoint(x0,y0,z0);
4562
4563 if (constrain) {
4564 x2 = x3;
4565 y2 = y3;
4566 z2 = z3;
4567
4568 x3 = 0;
4569 y3 = 0;
4570 z3 = 0;
4571 }
4572 x[0]=y1;
4573 x[1]=z1;
b67e07dc 4574 x[4]=F1(x1,y1,x2,y2,x3,y3);
91162307 4575
4576 // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
b67e07dc 4577 x[2]=F2(x1,y1,x2,y2,x3,y3);
91162307 4578
4579 //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
b67e07dc 4580 //x[3]=F3(x1,y1,x2,y2,z1,z2);
4581 x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
91162307 4582 //if (TMath::Abs(x[3]) > cuts[3]) continue;
4583
4584
4585 Double_t sy =0.1, sz =0.1;
4586 Double_t sy1=0.02, sz1=0.02;
4587 Double_t sy2=0.02, sz2=0.02;
4588 Double_t sy3=0.02;
4589
4590 if (constrain){
4591 sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
4592 }
4593
b67e07dc 4594 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
4595 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
4596 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
4597 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
4598 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
4599 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
4600
4601 Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
4602 Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
4603 Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
4604 Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
91162307 4605
4606
4607 c[0]=sy1;
4608 c[1]=0.; c[2]=sz1;
4609 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4610 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4611 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4612 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4613 c[13]=f30*sy1*f40+f32*sy2*f42;
4614 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4615
4616 //Int_t row1 = fSectors->GetRowNumber(x1);
4617 Int_t row1 = GetRowNumber(x1);
4618
4619 UInt_t index=0;
4620 //kr0.GetIndex(is);
ddfbc51a 4621 if (seed) {MarkSeedFree( seed ); seed = 0;}
4622 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1,sec*alpha+shift,x,c,index);
4623 seed->SetPoolID(fLastSeedID);
b9671574 4624 track->SetIsSeeding(kTRUE);
91162307 4625 Int_t rc=FollowProlongation(*track, i2);
b9671574 4626 if (constrain) track->SetBConstrain(1);
91162307 4627 else
b9671574 4628 track->SetBConstrain(0);
4629 track->SetLastPoint(row1+fInnerSec->GetNRows()); // first cluster in track position
4630 track->SetFirstPoint(track->GetLastPoint());
91162307 4631
4632 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 4633 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
4634 track->GetNShared()>0.4*track->GetNumberOfClusters()) {
ddfbc51a 4635 MarkSeedFree( seed ); seed = 0;
91162307 4636 }
4637 else {
f06a1ff6 4638 arr->AddLast(track); // track IS seed, don't free seed
ddfbc51a 4639 seed = new( NextFreeSeed() ) AliTPCseed;
4640 seed->SetPoolID(fLastSeedID);
91162307 4641 }
4642 nin3++;
4643 }
4644 } // if accepted seed
4645 }
6bdc18d6 4646 if (fDebug>3){
4647 Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
91162307 4648 }
ddfbc51a 4649 if (seed) MarkSeedFree( seed );
91162307 4650}
4651
4652
829455ad 4653AliTPCseed *AliTPCtracker::MakeSeed(AliTPCseed *const track, Float_t r0, Float_t r1, Float_t r2)
91162307 4654{
4655 //
4656 //
d26d9159 4657 //reseed using track points
91162307 4658 Int_t p0 = int(r0*track->GetNumberOfClusters()); // point 0
4659 Int_t p1 = int(r1*track->GetNumberOfClusters());
4660 Int_t p2 = int(r2*track->GetNumberOfClusters()); // last point
176aff27 4661 Int_t pp2=0;
91162307 4662 Double_t x0[3],x1[3],x2[3];
89e09524 4663 for (Int_t i=0;i<3;i++){
4664 x0[i]=-1;
4665 x1[i]=-1;
4666 x2[i]=-1;
4667 }
91162307 4668
4669 // find track position at given ratio of the length
89e09524 4670 Int_t sec0=0, sec1=0, sec2=0;
91162307 4671 Int_t index=-1;
4672 Int_t clindex;
4673 for (Int_t i=0;i<160;i++){
b9671574 4674 if (track->GetClusterPointer(i)){
91162307 4675 index++;
4676 AliTPCTrackerPoint *trpoint =track->GetTrackPoint(i);
4677 if ( (index<p0) || x0[0]<0 ){
4678 if (trpoint->GetX()>1){
4679 clindex = track->GetClusterIndex2(i);
bad6eb00 4680 if (clindex >= 0){
91162307 4681 x0[0] = trpoint->GetX();
4682 x0[1] = trpoint->GetY();
4683 x0[2] = trpoint->GetZ();
4684 sec0 = ((clindex&0xff000000)>>24)%18;
4685 }
4686 }
4687 }
4688
4689 if ( (index<p1) &&(trpoint->GetX()>1)){
4690 clindex = track->GetClusterIndex2(i);
bad6eb00 4691 if (clindex >= 0){
91162307 4692 x1[0] = trpoint->GetX();
4693 x1[1] = trpoint->GetY();
4694 x1[2] = trpoint->GetZ();
4695 sec1 = ((clindex&0xff000000)>>24)%18;
4696 }
4697 }
4698 if ( (index<p2) &&(trpoint->GetX()>1)){
4699 clindex = track->GetClusterIndex2(i);
bad6eb00 4700 if (clindex >= 0){
91162307 4701 x2[0] = trpoint->GetX();
4702 x2[1] = trpoint->GetY();
4703 x2[2] = trpoint->GetZ();
4704 sec2 = ((clindex&0xff000000)>>24)%18;
4705 pp2 = i;
4706 }
4707 }
4708 }
4709 }
4710
4711 Double_t alpha, cs,sn, xx2,yy2;
4712 //
4713 alpha = (sec1-sec2)*fSectors->GetAlpha();
4714 cs = TMath::Cos(alpha);
4715 sn = TMath::Sin(alpha);
4716 xx2= x1[0]*cs-x1[1]*sn;
4717 yy2= x1[0]*sn+x1[1]*cs;
4718 x1[0] = xx2;
4719 x1[1] = yy2;
4720 //
4721 alpha = (sec0-sec2)*fSectors->GetAlpha();
4722 cs = TMath::Cos(alpha);
4723 sn = TMath::Sin(alpha);
4724 xx2= x0[0]*cs-x0[1]*sn;
4725 yy2= x0[0]*sn+x0[1]*cs;
4726 x0[0] = xx2;
4727 x0[1] = yy2;
4728 //
4729 //
4730 //
4731 Double_t x[5],c[15];
4732 //
4733 x[0]=x2[1];
4734 x[1]=x2[2];
b67e07dc 4735 x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
91162307 4736 // if (x[4]>1) return 0;
b67e07dc 4737 x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
4738 x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
91162307 4739 //if (TMath::Abs(x[3]) > 2.2) return 0;
4740 //if (TMath::Abs(x[2]) > 1.99) return 0;
4741 //
4742 Double_t sy =0.1, sz =0.1;
4743 //
4744 Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
4745 Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
4746 Double_t sy3=0.01+track->GetSigmaY2();
4747 //
b67e07dc 4748 Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
4749 Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
4750 Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
4751 Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
4752 Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
4753 Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
4754 //
4755 Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
4756 Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
4757 Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
4758 Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
91162307 4759
4760
4761 c[0]=sy1;
4762 c[1]=0.; c[2]=sz1;
4763 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4764 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4765 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4766 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4767 c[13]=f30*sy1*f40+f32*sy2*f42;
4768 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4769
4770 // Int_t row1 = fSectors->GetRowNumber(x2[0]);
ddfbc51a 4771 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4772 seed->SetPoolID(fLastSeedID);
91162307 4773 // Double_t y0,z0,y1,z1, y2,z2;
4774 //seed->GetProlongation(x0[0],y0,z0);
4775 // seed->GetProlongation(x1[0],y1,z1);
4776 //seed->GetProlongation(x2[0],y2,z2);
4777 // seed =0;
b9671574 4778 seed->SetLastPoint(pp2);
4779 seed->SetFirstPoint(pp2);
91162307 4780
4781
4782 return seed;
4783}
4784
d26d9159 4785
829455ad 4786AliTPCseed *AliTPCtracker::ReSeed(const AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
d26d9159 4787{
4788 //
4789 //
4790 //reseed using founded clusters
4791 //
4792 // Find the number of clusters
4793 Int_t nclusters = 0;
4794 for (Int_t irow=0;irow<160;irow++){
4795 if (track->GetClusterIndex(irow)>0) nclusters++;
4796 }
4797 //
4798 Int_t ipos[3];
4799 ipos[0] = TMath::Max(int(r0*nclusters),0); // point 0 cluster
4800 ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1); //
4801 ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1); // last point
4802 //
4803 //
ec26e231 4804 Double_t xyz[3][3]={{0}};
4805 Int_t row[3]={0},sec[3]={0,0,0};
d26d9159 4806 //
4807 // find track row position at given ratio of the length
4808 Int_t index=-1;
4809 for (Int_t irow=0;irow<160;irow++){
4810 if (track->GetClusterIndex2(irow)<0) continue;
4811 index++;
4812 for (Int_t ipoint=0;ipoint<3;ipoint++){
4813 if (index<=ipos[ipoint]) row[ipoint] = irow;
4814 }
4815 }
4816 //
4817 //Get cluster and sector position
4818 for (Int_t ipoint=0;ipoint<3;ipoint++){
4819 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4820 AliTPCclusterMI * cl = GetClusterMI(clindex);
4821 if (cl==0) {
6bdc18d6 4822 //Error("Bug\n");
47966a6d 4823 // AliTPCclusterMI * cl = GetClusterMI(clindex);
d26d9159 4824 return 0;
4825 }
4826 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4827 xyz[ipoint][0] = GetXrow(row[ipoint]);
4828 xyz[ipoint][1] = cl->GetY();
4829 xyz[ipoint][2] = cl->GetZ();
4830 }
4831 //
4832 //
4833 // Calculate seed state vector and covariance matrix
4834
4835 Double_t alpha, cs,sn, xx2,yy2;
4836 //
4837 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4838 cs = TMath::Cos(alpha);
4839 sn = TMath::Sin(alpha);
4840 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4841 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4842 xyz[1][0] = xx2;
4843 xyz[1][1] = yy2;
4844 //
4845 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4846 cs = TMath::Cos(alpha);
4847 sn = TMath::Sin(alpha);
4848 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4849 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4850 xyz[0][0] = xx2;
4851 xyz[0][1] = yy2;
4852 //
4853 //
4854 //
4855 Double_t x[5],c[15];
4856 //
4857 x[0]=xyz[2][1];
4858 x[1]=xyz[2][2];
4859 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4860 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4861 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4862 //
4863 Double_t sy =0.1, sz =0.1;
4864 //
4865 Double_t sy1=0.2, sz1=0.2;
4866 Double_t sy2=0.2, sz2=0.2;
4867 Double_t sy3=0.2;
4868 //
4869 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;
4870 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;
4871 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;
4872 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;
4873 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;
4874 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;
4875 //
4876 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;
4877 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;
4878 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;
4879 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;
4880
4881
4882 c[0]=sy1;
4883 c[1]=0.; c[2]=sz1;
4884 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4885 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4886 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4887 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4888 c[13]=f30*sy1*f40+f32*sy2*f42;
4889 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4890
4891 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
ddfbc51a 4892 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4893 seed->SetPoolID(fLastSeedID);
b9671574 4894 seed->SetLastPoint(row[2]);
4895 seed->SetFirstPoint(row[2]);
d26d9159 4896 return seed;
4897}
4898
eea478d3 4899
829455ad 4900AliTPCseed *AliTPCtracker::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
eea478d3 4901{
4902 //
4903 //
4904 //reseed using founded clusters
4905 //
4906 Double_t xyz[3][3];
4a12af72 4907 Int_t row[3]={0,0,0};
4908 Int_t sec[3]={0,0,0};
eea478d3 4909 //
4910 // forward direction
4911 if (forward){
4912 for (Int_t irow=r0;irow<160;irow++){
4913 if (track->GetClusterIndex(irow)>0){
4914 row[0] = irow;
4915 break;
4916 }
4917 }
4918 for (Int_t irow=160;irow>r0;irow--){
4919 if (track->GetClusterIndex(irow)>0){
4920 row[2] = irow;
4921 break;
4922 }
4923 }
4924 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4925 if (track->GetClusterIndex(irow)>0){
4926 row[1] = irow;
4927 break;
4928 }
4929 }
4930 //
4931 }
4932 if (!forward){
4933 for (Int_t irow=0;irow<r0;irow++){
4934 if (track->GetClusterIndex(irow)>0){
4935 row[0] = irow;
4936 break;
4937 }
4938 }
4939 for (Int_t irow=r0;irow>0;irow--){
4940 if (track->GetClusterIndex(irow)>0){
4941 row[2] = irow;
4942 break;
4943 }
4944 }
4945 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4946 if (track->GetClusterIndex(irow)>0){
4947 row[1] = irow;
4948 break;
4949 }
4950 }
4951 }
4952 //
4953 if ((row[2]-row[0])<20) return 0;
4954 if (row[1]==0) return 0;
4955 //
4956 //
4957 //Get cluster and sector position
4958 for (Int_t ipoint=0;ipoint<3;ipoint++){
4959 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4960 AliTPCclusterMI * cl = GetClusterMI(clindex);
4961 if (cl==0) {
4962 //Error("Bug\n");
4963 // AliTPCclusterMI * cl = GetClusterMI(clindex);
4964 return 0;
4965 }
4966 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4967 xyz[ipoint][0] = GetXrow(row[ipoint]);
4968 AliTPCTrackerPoint * point = track->GetTrackPoint(row[ipoint]);
4969 if (point&&ipoint<2){
4970 //
4971 xyz[ipoint][1] = point->GetY();
4972 xyz[ipoint][2] = point->GetZ();
4973 }
4974 else{
4975 xyz[ipoint][1] = cl->GetY();
4976 xyz[ipoint][2] = cl->GetZ();
4977 }
4978 }
4979 //
4980 //
4981 //
4982 //
4983 // Calculate seed state vector and covariance matrix
4984
4985 Double_t alpha, cs,sn, xx2,yy2;
4986 //
4987 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4988 cs = TMath::Cos(alpha);
4989 sn = TMath::Sin(alpha);
4990 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4991 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4992 xyz[1][0] = xx2;
4993 xyz[1][1] = yy2;
4994 //
4995 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4996 cs = TMath::Cos(alpha);
4997 sn = TMath::Sin(alpha);
4998 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4999 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
5000 xyz[0][0] = xx2;
5001 xyz[0][1] = yy2;
5002 //
5003 //
5004 //
5005 Double_t x[5],c[15];
5006 //
5007 x[0]=xyz[2][1];
5008 x[1]=xyz[2][2];
5009 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
5010 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
5011 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
5012 //
5013 Double_t sy =0.1, sz =0.1;
5014 //
5015 Double_t sy1=0.2, sz1=0.2;
5016 Double_t sy2=0.2, sz2=0.2;
5017 Double_t sy3=0.2;
5018 //
5019 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;
5020 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;
5021 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;
5022 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;
5023 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;
5024 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;
5025 //
5026 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;
5027 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;
5028 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;
5029 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;
5030
5031
5032 c[0]=sy1;
5033 c[1]=0.; c[2]=sz1;
5034 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
5035 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
5036 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
5037 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
5038 c[13]=f30*sy1*f40+f32*sy2*f42;
5039 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
5040
5041 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
ddfbc51a 5042 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
5043 seed->SetPoolID(fLastSeedID);
b9671574 5044 seed->SetLastPoint(row[2]);
5045 seed->SetFirstPoint(row[2]);
eea478d3 5046 for (Int_t i=row[0];i<row[2];i++){
b9671574 5047 seed->SetClusterIndex(i, track->GetClusterIndex(i));
eea478d3 5048 }
5049
5050 return seed;
5051}
5052
6d493ea0 5053
5054
829455ad 5055void AliTPCtracker::FindMultiMC(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
6d493ea0 5056{
5057 //
5058 // find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
5059 // USES MC LABELS
65e67c9c 5060 // Use AliTPCReconstructor::StreamLevel()& kStreamFindMultiMC if you want to tune parameters - cuts
6d493ea0 5061 //
5062 // Two reasons to have multiple find tracks
5063 // 1. Curling tracks can be find more than once
5064 // 2. Splitted tracks
5065 // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
5066 // b.) Edge effect on the sector boundaries
5067 //
5068 //
5069 // Algorithm done in 2 phases - because of CPU consumption
5070 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
5071 //
5072 // Algorihm for curling tracks sign:
5073 // 1 phase -makes a very rough fast cuts to minimize combinatorics
5074 // a.) opposite sign
5075 // b.) one of the tracks - not pointing to the primary vertex -
5076 // c.) delta tan(theta)
5077 // d.) delta phi
5078 // 2 phase - calculates DCA between tracks - time consument
5079
5080 //
5081 // fast cuts
5082 //
5083 // General cuts - for splitted tracks and for curling tracks
5084 //
5085 const Float_t kMaxdPhi = 0.2; // maximal distance in phi
5086 //
5087 // Curling tracks cuts
5088 //
5089 //
5090 //
5091 //
5092 Int_t nentries = array->GetEntriesFast();
5093 AliHelix *helixes = new AliHelix[nentries];
5094 Float_t *xm = new Float_t[nentries];
5095 Float_t *dz0 = new Float_t[nentries];
5096 Float_t *dz1 = new Float_t[nentries];
5097 //
5098 //
5099 TStopwatch timer;
5100 timer.Start();
5101 //
5102 // Find track COG in x direction - point with best defined parameters
5103 //
5104 for (Int_t i=0;i<nentries;i++){
5105 AliTPCseed* track = (AliTPCseed*)array->At(i);
5106 if (!track) continue;
5107 track->SetCircular(0);
5108 new (&helixes[i]) AliHelix(*track);
5109 Int_t ncl=0;
5110 xm[i]=0;
5111 Float_t dz[2];
5112 track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
5113 dz0[i]=dz[0];
5114 dz1[i]=dz[1];
5115 for (Int_t icl=0; icl<160; icl++){
5116 AliTPCclusterMI * cl = track->GetClusterPointer(icl);
5117 if (cl) {
5118 xm[i]+=cl->GetX();
5119 ncl++;
5120 }
5121 }
5122 if (ncl>0) xm[i]/=Float_t(ncl);
5123 }
6d493ea0 5124 //
5125 for (Int_t i0=0;i0<nentries;i0++){
5126 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5127 if (!track0) continue;
5128 Float_t xc0 = helixes[i0].GetHelix(6);
5129 Float_t yc0 = helixes[i0].GetHelix(7);
5130 Float_t r0 = helixes[i0].GetHelix(8);
5131 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
5132 Float_t fi0 = TMath::ATan2(yc0,xc0);
5133
5134 for (Int_t i1=i0+1;i1<nentries;i1++){
5135 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5136 if (!track1) continue;
5137 Int_t lab0=track0->GetLabel();
5138 Int_t lab1=track1->GetLabel();
5139 if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
5140 //
5141 Float_t xc1 = helixes[i1].GetHelix(6);
5142 Float_t yc1 = helixes[i1].GetHelix(7);
5143 Float_t r1 = helixes[i1].GetHelix(8);
5144 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
5145 Float_t fi1 = TMath::ATan2(yc1,xc1);
5146 //
5147 Float_t dfi = fi0-fi1;
5148 //
5149 //
5150 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
5151 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
5152 if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
5153 //
5154 // if short tracks with undefined sign
5155 fi1 = -TMath::ATan2(yc1,-xc1);
5156 dfi = fi0-fi1;
5157 }
5158 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
5159
5160 //
5161 // debug stream to tune "fast cuts"
5162 //
5163 Double_t dist[3]; // distance at X
5164 Double_t mdist[3]={0,0,0}; // mean distance X+-40cm
5165 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
5166 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
5167 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
5168 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
5169 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
5170 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
5171 for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
5172
5173 Float_t sum =0;
5174 Float_t sums=0;
5175 for (Int_t icl=0; icl<160; icl++){
5176 AliTPCclusterMI * cl0 = track0->GetClusterPointer(icl);
5177 AliTPCclusterMI * cl1 = track1->GetClusterPointer(icl);
5178 if (cl0&&cl1) {
5179 sum++;
5180 if (cl0==cl1) sums++;
5181 }
5182 }
5183 //
65e67c9c 5184 if ((AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC)>0) { // flag: stream MC infomation about the multiple find track (ONLY for MC data)
b194b32c 5185 TTreeSRedirector &cstream = *fDebugStreamer;
6d493ea0 5186 cstream<<"Multi"<<
5187 "iter="<<iter<<
5188 "lab0="<<lab0<<
5189 "lab1="<<lab1<<
5190 "Tr0.="<<track0<< // seed0
5191 "Tr1.="<<track1<< // seed1
5192 "h0.="<<&helixes[i0]<<
5193 "h1.="<<&helixes[i1]<<
5194 //
5195 "sum="<<sum<< //the sum of rows with cl in both
5196 "sums="<<sums<< //the sum of shared clusters
5197 "xm0="<<xm[i0]<< // the center of track
5198 "xm1="<<xm[i1]<< // the x center of track
5199 // General cut variables
5200 "dfi="<<dfi<< // distance in fi angle
5201 "dtheta="<<dtheta<< // distance int theta angle
5202 //
5203 "dz00="<<dz0[i0]<<
5204 "dz01="<<dz0[i1]<<
5205 "dz10="<<dz1[i1]<<
5206 "dz11="<<dz1[i1]<<
5207 "dist0="<<dist[0]<< //distance x
5208 "dist1="<<dist[1]<< //distance y
5209 "dist2="<<dist[2]<< //distance z
5210 "mdist0="<<mdist[0]<< //distance x
5211 "mdist1="<<mdist[1]<< //distance y
5212 "mdist2="<<mdist[2]<< //distance z
5213 //
5214 "r0="<<r0<<
5215 "rc0="<<rc0<<
5216 "fi0="<<fi0<<
5217 "fi1="<<fi1<<
5218 "r1="<<r1<<
5219 "rc1="<<rc1<<
5220 "\n";
b194b32c 5221 }
6d493ea0 5222 }
5223 }
5224 delete [] helixes;
5225 delete [] xm;
ec26e231 5226 delete [] dz0;
5227 delete [] dz1;
65e67c9c 5228 if (AliTPCReconstructor::StreamLevel()>0) {
6d493ea0 5229 AliInfo("Time for curling tracks removal DEBUGGING MC");
5230 timer.Print();
5231 }
5232}
5233
5234
1af5da7e 5235
829455ad 5236void AliTPCtracker::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t /*iter*/){
6d493ea0 5237 //
6fbe1e5c 5238 // Find Splitted tracks and remove the one with worst quality
5239 // Corresponding debug streamer to tune selections - "Splitted2"
5240 // Algorithm:
65e67c9c 5241 // 0. Sort tracks according quality
6fbe1e5c 5242 // 1. Propagate the tracks to the reference radius
5243 // 2. Double_t loop to select close tracks (only to speed up process)
5244 // 3. Calculate cluster overlap ratio - and remove the track if bigger than a threshold
5245 // 4. Delete temporary parameters
5246 //
5247 const Double_t xref=GetXrow(63); // reference radius -IROC/OROC boundary
5248 // rough cuts
5249 const Double_t kCutP1=10; // delta Z cut 10 cm
5250 const Double_t kCutP2=0.15; // delta snp(fi) cut 0.15
5251 const Double_t kCutP3=0.15; // delta tgl(theta) cut 0.15
5252 const Double_t kCutAlpha=0.15; // delta alpha cut
5253 Int_t firstpoint = 0;
5254 Int_t lastpoint = 160;
6d493ea0 5255 //
5256 Int_t nentries = array->GetEntriesFast();
6fbe1e5c 5257 AliExternalTrackParam *params = new AliExternalTrackParam[nentries];
6d493ea0 5258 //
5259 //
5260 TStopwatch timer;
5261 timer.Start();
5262 //
6fbe1e5c 5263 //0. Sort tracks according quality
5264 //1. Propagate the ext. param to reference radius
6d493ea0 5265 Int_t nseed = array->GetEntriesFast();
6e23caff 5266 if (nseed<=0) return;
6d493ea0 5267 Float_t * quality = new Float_t[nseed];
5268 Int_t * indexes = new Int_t[nseed];
5269 for (Int_t i=0; i<nseed; i++) {
5270 AliTPCseed *pt=(AliTPCseed*)array->UncheckedAt(i);
5271 if (!pt){
5272 quality[i]=-1;
5273 continue;
5274 }
5275 pt->UpdatePoints(); //select first last max dens points
5276 Float_t * points = pt->GetPoints();
5277 if (points[3]<0.8) quality[i] =-1;
5278 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
1af5da7e 5279 //prefer high momenta tracks if overlaps
5280 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
6fbe1e5c 5281 params[i]=(*pt);
5282 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),5.,kTRUE);
5283 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),1.,kTRUE);
6d493ea0 5284 }
5285 TMath::Sort(nseed,quality,indexes);
6d493ea0 5286 //
6fbe1e5c 5287 // 3. Loop over pair of tracks
5288 //
5289 for (Int_t i0=0; i0<nseed; i0++) {
5290 Int_t index0=indexes[i0];
5291 if (!(array->UncheckedAt(index0))) continue;
5292 AliTPCseed *s1 = (AliTPCseed*)array->UncheckedAt(index0);
5293 if (!s1->IsActive()) continue;
5294 AliExternalTrackParam &par0=params[index0];
5295 for (Int_t i1=i0+1; i1<nseed; i1++) {
5296 Int_t index1=indexes[i1];
5297 if (!(array->UncheckedAt(index1))) continue;
5298 AliTPCseed *s2 = (AliTPCseed*)array->UncheckedAt(index1);
5299 if (!s2->IsActive()) continue;
5300 if (s2->GetKinkIndexes()[0]!=0)
5301 if (s2->GetKinkIndexes()[0] == -s1->GetKinkIndexes()[0]) continue;
5302 AliExternalTrackParam &par1=params[index1];
5303 if (TMath::Abs(par0.GetParameter()[3]-par1.GetParameter()[3])>kCutP3) continue;
5304 if (TMath::Abs(par0.GetParameter()[1]-par1.GetParameter()[1])>kCutP1) continue;
5305 if (TMath::Abs(par0.GetParameter()[2]-par1.GetParameter()[2])>kCutP2) continue;
5306 Double_t dAlpha= TMath::Abs(par0.GetAlpha()-par1.GetAlpha());
5307 if (dAlpha>TMath::Pi()) dAlpha-=TMath::Pi();
5308 if (TMath::Abs(dAlpha)>kCutAlpha) continue;
6d493ea0 5309 //
6fbe1e5c 5310 Int_t sumShared=0;
5311 Int_t nall0=0;
5312 Int_t nall1=0;
5313 Int_t firstShared=lastpoint, lastShared=firstpoint;
5314 Int_t firstRow=lastpoint, lastRow=firstpoint;
6d493ea0 5315 //
6fbe1e5c 5316 for (Int_t i=firstpoint;i<lastpoint;i++){
5317 if (s1->GetClusterIndex2(i)>0) nall0++;
5318 if (s2->GetClusterIndex2(i)>0) nall1++;
5319 if (s1->GetClusterIndex2(i)>0 && s2->GetClusterIndex2(i)>0) {
5320 if (i<firstRow) firstRow=i;
5321 if (i>lastRow) lastRow=i;
5322 }
5323 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
5324 if (i<firstShared) firstShared=i;
5325 if (i>lastShared) lastShared=i;
5326 sumShared++;
5327 }
5328 }
5329 Double_t ratio0 = Float_t(sumShared)/Float_t(TMath::Min(nall0+1,nall1+1));
5330 Double_t ratio1 = Float_t(sumShared)/Float_t(TMath::Max(nall0+1,nall1+1));
5331
65e67c9c 5332 if ((AliTPCReconstructor::StreamLevel()&kStreamSplitted2)>0){ // flag:stream information about discarded TPC tracks pair algorithm
6fbe1e5c 5333 TTreeSRedirector &cstream = *fDebugStreamer;
5334 Int_t n0=s1->GetNumberOfClusters();
5335 Int_t n1=s2->GetNumberOfClusters();
5336 Int_t n0F=s1->GetNFoundable();
5337 Int_t n1F=s2->GetNFoundable();
5338 Int_t lab0=s1->GetLabel();
5339 Int_t lab1=s2->GetLabel();
5340
65e67c9c 5341 cstream<<"Splitted2"<< // flag:stream information about discarded TPC tracks pair algorithm
6fbe1e5c 5342 "iter="<<fIteration<<
5343 "lab0="<<lab0<< // MC label if exist
5344 "lab1="<<lab1<< // MC label if exist
5345 "index0="<<index0<<
5346 "index1="<<index1<<
5347 "ratio0="<<ratio0<< // shared ratio
5348 "ratio1="<<ratio1<< // shared ratio
5349 "p0.="<<&par0<< // track parameters
5350 "p1.="<<&par1<<
5351 "s0.="<<s1<< // full seed
5352 "s1.="<<s2<<
5353 "n0="<<n0<< // number of clusters track 0
5354 "n1="<<n1<< // number of clusters track 1
5355 "nall0="<<nall0<< // number of clusters track 0
5356 "nall1="<<nall1<< // number of clusters track 1
5357 "n0F="<<n0F<< // number of findable
5358 "n1F="<<n1F<< // number of findable
5359 "shared="<<sumShared<< // number of shared clusters
5360 "firstS="<<firstShared<< // first and the last shared row
5361 "lastS="<<lastShared<<
5362 "firstRow="<<firstRow<< // first and the last row with cluster
5363 "lastRow="<<lastRow<< //
5364 "\n";
6d493ea0 5365 }
6d493ea0 5366 //
6fbe1e5c 5367 // remove track with lower quality
6d493ea0 5368 //
6fbe1e5c 5369 if (ratio0>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(0) ||
5370 ratio1>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(1)){
5371 //
5372 //
5373 //
ddfbc51a 5374 MarkSeedFree( array->RemoveAt(index1) );
44adbd4b 5375 }
6d493ea0 5376 }
6fbe1e5c 5377 }
5378 //
5379 // 4. Delete temporary array
5380 //
5381 delete [] params;
6e23caff 5382 delete [] quality;
5383 delete [] indexes;
5384
6d493ea0 5385}
5386
5387
5388
829455ad 5389void AliTPCtracker::FindCurling(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
6d493ea0 5390{
5391 //
5392 // find Curling tracks
65e67c9c 5393 // Use AliTPCReconstructor::StreamLevel()&kStreamFindCurling if you want to tune parameters - cuts
6d493ea0 5394 //
5395 //
5396 // Algorithm done in 2 phases - because of CPU consumption
5397 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
5398 // see detal in MC part what can be used to cut
5399 //
5400 //
5401 //
5402 const Float_t kMaxC = 400; // maximal curvature to of the track
5403 const Float_t kMaxdTheta = 0.15; // maximal distance in theta
5404 const Float_t kMaxdPhi = 0.15; // maximal distance in phi
5405 const Float_t kPtRatio = 0.3; // ratio between pt
5406 const Float_t kMinDCAR = 2.; // distance to the primary vertex in r - see cpipe cut
5407
5408 //
5409 // Curling tracks cuts
5410 //
5411 //
5412 const Float_t kMaxDeltaRMax = 40; // distance in outer radius
5413 const Float_t kMaxDeltaRMin = 5.; // distance in lower radius - see cpipe cut
5414 const Float_t kMinAngle = 2.9; // angle between tracks
5415 const Float_t kMaxDist = 5; // biggest distance
5416 //
5417 // The cuts can be tuned using the "MC information stored in Multi tree ==> see FindMultiMC
5418 /*
5419 Fast cuts:
5420 TCut csign("csign","Tr0.fP[4]*Tr1.fP[4]<0"); //opposite sign
5421 TCut cmax("cmax","abs(Tr0.GetC())>1/400");
5422 TCut cda("cda","sqrt(dtheta^2+dfi^2)<0.15");
5423 TCut ccratio("ccratio","abs((Tr0.fP[4]+Tr1.fP[4])/(abs(Tr0.fP[4])+abs(Tr1.fP[4])))<0.3");
5424 TCut cpipe("cpipe", "min(abs(r0-rc0),abs(r1-rc1))>5");
5425 //
5426 TCut cdrmax("cdrmax","abs(abs(rc0+r0)-abs(rc1+r1))<40")
5427 TCut cdrmin("cdrmin","abs(abs(rc0+r0)-abs(rc1+r1))<10")
5428 //
5429 Multi->Draw("dfi","iter==0"+csign+cmax+cda+ccratio); ~94% of curling tracks fulfill
5430 Multi->Draw("min(abs(r0-rc0),abs(r1-rc1))","iter==0&&abs(lab1)==abs(lab0)"+csign+cmax+cda+ccratio+cpipe+cdrmin+cdrmax); //80%
5431 //
5432 Curling2->Draw("dfi","iter==0&&abs(lab0)==abs(lab1)"+csign+cmax+cdtheta+cdfi+ccratio)
5433
5434 */
5435 //
5436 //
5437 //
5438 Int_t nentries = array->GetEntriesFast();
5439 AliHelix *helixes = new AliHelix[nentries];
5440 for (Int_t i=0;i<nentries;i++){
5441 AliTPCseed* track = (AliTPCseed*)array->At(i);
5442 if (!track) continue;
5443 track->SetCircular(0);
5444 new (&helixes[i]) AliHelix(*track);
5445 }
5446 //
5447 //
5448 TStopwatch timer;
5449 timer.Start();
ec26e231 5450 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
5451
6d493ea0 5452 //
5453 // Find tracks
5454 //
6d493ea0 5455 //
5456 for (Int_t i0=0;i0<nentries;i0++){
5457 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5458 if (!track0) continue;
5459 if (TMath::Abs(track0->GetC())<1/kMaxC) continue;
5460 Float_t xc0 = helixes[i0].GetHelix(6);
5461 Float_t yc0 = helixes[i0].GetHelix(7);
5462 Float_t r0 = helixes[i0].GetHelix(8);
5463 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
5464 Float_t fi0 = TMath::ATan2(yc0,xc0);
5465
5466 for (Int_t i1=i0+1;i1<nentries;i1++){
5467 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5468 if (!track1) continue;
5469 if (TMath::Abs(track1->GetC())<1/kMaxC) continue;
5470 Float_t xc1 = helixes[i1].GetHelix(6);
5471 Float_t yc1 = helixes[i1].GetHelix(7);
5472 Float_t r1 = helixes[i1].GetHelix(8);
5473 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
5474 Float_t fi1 = TMath::ATan2(yc1,xc1);
5475 //
5476 Float_t dfi = fi0-fi1;
5477 //
5478 //
5479 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
5480 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
5481 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
5482 //
5483 //
5484 // FIRST fast cuts
5485 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue; // not constrained
5486 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue; // not the same sign
5487 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>kMaxdTheta) continue; //distance in the Theta
5488 if ( TMath::Abs(dfi)>kMaxdPhi) continue; //distance in phi
5489 if ( TMath::Sqrt(dfi*dfi+dtheta*dtheta)>kMaxdPhi) continue; //common angular offset
5490 //
5491 Float_t pt0 = track0->GetSignedPt();
5492 Float_t pt1 = track1->GetSignedPt();
5493 if ((TMath::Abs(pt0+pt1)/(TMath::Abs(pt0)+TMath::Abs(pt1)))>kPtRatio) continue;
5494 if ((iter==1) && TMath::Abs(TMath::Abs(rc0+r0)-TMath::Abs(rc1+r1))>kMaxDeltaRMax) continue;
5495 if ((iter!=1) &&TMath::Abs(TMath::Abs(rc0-r0)-TMath::Abs(rc1-r1))>kMaxDeltaRMin) continue;
5496 if (TMath::Min(TMath::Abs(rc0-r0),TMath::Abs(rc1-r1))<kMinDCAR) continue;
5497 //
5498 //
5499 // Now find closest approach
5500 //
5501 //
5502 //
5503 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5504 if (npoints==0) continue;
5505 helixes[i0].GetClosestPhases(helixes[i1], phase);
5506 //
5507 Double_t xyz0[3];
5508 Double_t xyz1[3];
5509 Double_t hangles[3];
5510 helixes[i0].Evaluate(phase[0][0],xyz0);
5511 helixes[i1].Evaluate(phase[0][1],xyz1);
5512
5513 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5514 Double_t deltah[2],deltabest;
5515 if (TMath::Abs(hangles[2])<kMinAngle) continue;
5516
5517 if (npoints>0){
5518 Int_t ibest=0;
5519 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
5520 if (npoints==2){
5521 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
5522 if (deltah[1]<deltah[0]) ibest=1;
5523 }
5524 deltabest = TMath::Sqrt(deltah[ibest]);
5525 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5526 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5527 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5528 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5529 //
5530 if (deltabest>kMaxDist) continue;
5531 // if (mindcar+mindcaz<40 && (TMath::Abs(hangles[2])<kMinAngle ||deltabest>3)) continue;
5532 Bool_t sign =kFALSE;
5533 if (hangles[2]>kMinAngle) sign =kTRUE;
5534 //
5535 if (sign){
5536 // circular[i0] = kTRUE;
5537 // circular[i1] = kTRUE;
5538 if (track0->OneOverPt()<track1->OneOverPt()){
5539 track0->SetCircular(track0->GetCircular()+1);
5540 track1->SetCircular(track1->GetCircular()+2);
5541 }
5542 else{
5543 track1->SetCircular(track1->GetCircular()+1);
5544 track0->SetCircular(track0->GetCircular()+2);
5545 }
5546 }
65e67c9c 5547 if ((AliTPCReconstructor::StreamLevel()&kStreamFindCurling)>0){ // flag: stream track infroamtion if the FindCurling tracks method
6d493ea0 5548 //
5549 //debug stream to tune "fine" cuts
5550 Int_t lab0=track0->GetLabel();
5551 Int_t lab1=track1->GetLabel();
b194b32c 5552 TTreeSRedirector &cstream = *fDebugStreamer;
6d493ea0 5553 cstream<<"Curling2"<<
5554 "iter="<<iter<<
5555 "lab0="<<lab0<<
5556 "lab1="<<lab1<<
5557 "Tr0.="<<track0<<
5558 "Tr1.="<<track1<<
5559 //
5560 "r0="<<r0<<
5561 "rc0="<<rc0<<
5562 "fi0="<<fi0<<
5563 "r1="<<r1<<
5564 "rc1="<<rc1<<
5565 "fi1="<<fi1<<
5566 "dfi="<<dfi<<
5567 "dtheta="<<dtheta<<
5568 //
5569 "npoints="<<npoints<<
5570 "hangles0="<<hangles[0]<<
5571 "hangles1="<<hangles[1]<<
5572 "hangles2="<<hangles[2]<<
5573 "xyz0="<<xyz0[2]<<
5574 "xyzz1="<<xyz1[2]<<
5575 "radius="<<radiusbest<<
5576 "deltabest="<<deltabest<<
5577 "phase0="<<phase[ibest][0]<<
5578 "phase1="<<phase[ibest][1]<<
5579 "\n";
5580
5581 }
5582 }
5583 }
5584 }
5585 delete [] helixes;
5586 if (AliTPCReconstructor::StreamLevel()>1) {
5587 AliInfo("Time for curling tracks removal");
5588 timer.Print();
5589 }
5590}
5591
5592
829455ad 5593void AliTPCtracker::FindKinks(TObjArray * array, AliESDEvent *esd)
51ad6848 5594{
5595 //
5596 // find kinks
5597 //
5598 //
f06a1ff6 5599 // RS something is wrong in this routine: not all seeds are assigned to daughters and mothers array, but they all are queried
5600 // to check later
ddfbc51a 5601
5602 TObjArray *kinks= new TObjArray(10000);
81e97e0d 5603 // TObjArray *v0s= new TObjArray(10000);
51ad6848 5604 Int_t nentries = array->GetEntriesFast();
ddfbc51a 5605 AliHelix *helixes = new AliHelix[nentries];
5606 Int_t *sign = new Int_t[nentries];
5607 Int_t *nclusters = new Int_t[nentries];
5608 Float_t *alpha = new Float_t[nentries];
5609 AliKink *kink = new AliKink();
5610 Int_t * usage = new Int_t[nentries];
5611 Float_t *zm = new Float_t[nentries];
5612 Float_t *z0 = new Float_t[nentries];
5613 Float_t *fim = new Float_t[nentries];
5614 Float_t *shared = new Float_t[nentries];
5615 Bool_t *circular = new Bool_t[nentries];
5616 Float_t *dca = new Float_t[nentries];
81e97e0d 5617 //const AliESDVertex * primvertex = esd->GetVertex();
eea478d3 5618 //
5619 // nentries = array->GetEntriesFast();
ddfbc51a 5620 //
5621
51ad6848 5622 //
5623 //
5624 for (Int_t i=0;i<nentries;i++){
5625 sign[i]=0;
5626 usage[i]=0;
5627 AliTPCseed* track = (AliTPCseed*)array->At(i);
5628 if (!track) continue;
b9671574 5629 track->SetCircular(0);
eea478d3 5630 shared[i] = kFALSE;
51ad6848 5631 track->UpdatePoints();
5632 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
51ad6848 5633 }
eea478d3 5634 nclusters[i]=track->GetNumberOfClusters();
5635 alpha[i] = track->GetAlpha();
5636 new (&helixes[i]) AliHelix(*track);
5637 Double_t xyz[3];
5638 helixes[i].Evaluate(0,xyz);
5639 sign[i] = (track->GetC()>0) ? -1:1;
5640 Double_t x,y,z;
5641 x=160;
5642 if (track->GetProlongation(x,y,z)){
5643 zm[i] = z;
5644 fim[i] = alpha[i]+TMath::ATan2(y,x);
5645 }
5646 else{
5647 zm[i] = track->GetZ();
5648 fim[i] = alpha[i];
5649 }
5650 z0[i]=1000;
5651 circular[i]= kFALSE;
81e97e0d 5652 if (track->GetProlongation(0,y,z)) z0[i] = z;
5653 dca[i] = track->GetD(0,0);
51ad6848 5654 }
5655 //
5656 //
5657 TStopwatch timer;
5658 timer.Start();
5659 Int_t ncandidates =0;
5660 Int_t nall =0;
5661 Int_t ntracks=0;
ec26e231 5662 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
eea478d3 5663
5664 //
5665 // Find circling track
eea478d3 5666 //
5667 for (Int_t i0=0;i0<nentries;i0++){
5668 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5669 if (!track0) continue;
b9671574 5670 if (track0->GetNumberOfClusters()<40) continue;
6c94f330 5671 if (TMath::Abs(1./track0->GetC())>200) continue;
eea478d3 5672 for (Int_t i1=i0+1;i1<nentries;i1++){
5673 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5674 if (!track1) continue;
b9671574 5675 if (track1->GetNumberOfClusters()<40) continue;
6c94f330 5676 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
b9671574 5677 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
6c94f330 5678 if (TMath::Abs(1./track1->GetC())>200) continue;
8467b758 5679 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
6c94f330 5680 if (track1->GetTgl()*track0->GetTgl()>0) continue;
1b36647b 5681 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
8467b758 5682 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
5683 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
eea478d3 5684 //
81e97e0d 5685 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
5686 if (mindcar<5) continue;
5687 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
5688 if (mindcaz<5) continue;
5689 if (mindcar+mindcaz<20) continue;
5690 //
5691 //
eea478d3 5692 Float_t xc0 = helixes[i0].GetHelix(6);
5693 Float_t yc0 = helixes[i0].GetHelix(7);
5694 Float_t r0 = helixes[i0].GetHelix(8);
5695 Float_t xc1 = helixes[i1].GetHelix(6);
5696 Float_t yc1 = helixes[i1].GetHelix(7);
5697 Float_t r1 = helixes[i1].GetHelix(8);
5698
5699 Float_t rmean = (r0+r1)*0.5;
5700 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
81e97e0d 5701 //if (delta>30) continue;
eea478d3 5702 if (delta>rmean*0.25) continue;
5703 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
5704 //
5705 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5706 if (npoints==0) continue;
5707 helixes[i0].GetClosestPhases(helixes[i1], phase);
5708 //
5709 Double_t xyz0[3];
5710 Double_t xyz1[3];
5711 Double_t hangles[3];
5712 helixes[i0].Evaluate(phase[0][0],xyz0);
5713 helixes[i1].Evaluate(phase[0][1],xyz1);
5714
5715 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5716 Double_t deltah[2],deltabest;
5717 if (hangles[2]<2.8) continue;
eea478d3 5718 if (npoints>0){
5719 Int_t ibest=0;
81e97e0d 5720 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
eea478d3 5721 if (npoints==2){
81e97e0d 5722 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
eea478d3 5723 if (deltah[1]<deltah[0]) ibest=1;
5724 }
5725 deltabest = TMath::Sqrt(deltah[ibest]);
5726 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5727 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5728 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
81e97e0d 5729 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
eea478d3 5730 //
81e97e0d 5731 if (deltabest>6) continue;
5732 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
77f88633 5733 Bool_t lsign =kFALSE;
5734 if (hangles[2]>3.06) lsign =kTRUE;
81e97e0d 5735 //
77f88633 5736 if (lsign){
eea478d3 5737 circular[i0] = kTRUE;
81e97e0d 5738 circular[i1] = kTRUE;
8467b758 5739 if (track0->OneOverPt()<track1->OneOverPt()){
b9671574 5740 track0->SetCircular(track0->GetCircular()+1);
5741 track1->SetCircular(track1->GetCircular()+2);
81e97e0d 5742 }
5743 else{
b9671574 5744 track1->SetCircular(track1->GetCircular()+1);
5745 track0->SetCircular(track0->GetCircular()+2);
81e97e0d 5746 }
5747 }
65e67c9c 5748 if (lsign&&((AliTPCReconstructor::StreamLevel()&kStreamFindCurling)>0)){
34acb742 5749 //debug stream
b9671574 5750 Int_t lab0=track0->GetLabel();
5751 Int_t lab1=track1->GetLabel();
b194b32c 5752 TTreeSRedirector &cstream = *fDebugStreamer;
81e97e0d 5753 cstream<<"Curling"<<
b9671574 5754 "lab0="<<lab0<<
5755 "lab1="<<lab1<<
81e97e0d 5756 "Tr0.="<<track0<<
5757 "Tr1.="<<track1<<
5758 "dca0="<<dca[i0]<<
5759 "dca1="<<dca[i1]<<
5760 "mindcar="<<mindcar<<
5761 "mindcaz="<<mindcaz<<
5762 "delta="<<delta<<
5763 "rmean="<<rmean<<
5764 "npoints="<<npoints<<
5765 "hangles0="<<hangles[0]<<
5766 "hangles2="<<hangles[2]<<
5767 "xyz0="<<xyz0[2]<<
5768 "xyzz1="<<xyz1[2]<<
5769 "z0="<<z0[i0]<<
5770 "z1="<<z0[i1]<<
5771 "radius="<<radiusbest<<
5772 "deltabest="<<deltabest<<
5773 "phase0="<<phase[ibest][0]<<
5774 "phase1="<<phase[ibest][1]<<
5775 "\n";
eea478d3 5776 }
5777 }
5778 }
5779 }
5780 //
ddfbc51a 5781 // Finf kinks loop
81e97e0d 5782 //
51ad6848 5783 //
5784 for (Int_t i =0;i<nentries;i++){
5785 if (sign[i]==0) continue;
5786 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
c1ea348f 5787 if (track0==0) {
5788 AliInfo("seed==0");
5789 continue;
5790 }
51ad6848 5791 ntracks++;
5792 //
5793 Double_t cradius0 = 40*40;
5794 Double_t cradius1 = 270*270;
5795 Double_t cdist1=8.;
5796 Double_t cdist2=8.;
5797 Double_t cdist3=0.55;
5798 for (Int_t j =i+1;j<nentries;j++){
5799 nall++;
5800 if (sign[j]*sign[i]<1) continue;
5801 if ( (nclusters[i]+nclusters[j])>200) continue;
5802 if ( (nclusters[i]+nclusters[j])<80) continue;
5803 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
5804 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
5805 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
5806 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5807 if (npoints<1) continue;
5808 // cuts on radius
5809 if (npoints==1){
5810 if (radius[0]<cradius0||radius[0]>cradius1) continue;
5811 }
5812 else{
5813 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
5814 }
5815 //
5816 Double_t delta1=10000,delta2=10000;
5817 // cuts on the intersection radius
5818 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5819 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5820 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5821 if (npoints==2){
5822 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5823 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5824 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5825 }
5826 //
5827 Double_t distance1 = TMath::Min(delta1,delta2);
5828 if (distance1>cdist1) continue; // cut on DCA linear approximation
5829 //
5830 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5831 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5832 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5833 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5834 //
5835 if (npoints==2){
5836 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5837 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5838 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5839 }
5840 distance1 = TMath::Min(delta1,delta2);
5841 Float_t rkink =0;
5842 if (delta1<delta2){
5843 rkink = TMath::Sqrt(radius[0]);
5844 }
5845 else{
5846 rkink = TMath::Sqrt(radius[1]);
5847 }
5848 if (distance1>cdist2) continue;
5849 //
5850 //
5851 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5852 //
5853 //
5854 Int_t row0 = GetRowNumber(rkink);
5855 if (row0<10) continue;
5856 if (row0>150) continue;
5857 //
5858 //
5859 Float_t dens00=-1,dens01=-1;
5860 Float_t dens10=-1,dens11=-1;
5861 //
77f88633 5862 Int_t found,foundable,ishared;
5863 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
51ad6848 5864 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
77f88633 5865 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
51ad6848 5866 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
5867 //
77f88633 5868 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
51ad6848 5869 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
77f88633 5870 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
51ad6848 5871 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
eea478d3 5872 //
51ad6848 5873 if (dens00<dens10 && dens01<dens11) continue;
5874 if (dens00>dens10 && dens01>dens11) continue;
5875 if (TMath::Max(dens00,dens10)<0.1) continue;
5876 if (TMath::Max(dens01,dens11)<0.3) continue;
5877 //
5878 if (TMath::Min(dens00,dens10)>0.6) continue;
5879 if (TMath::Min(dens01,dens11)>0.6) continue;
5880
5881 //
5882 AliTPCseed * ktrack0, *ktrack1;
5883 if (dens00>dens10){
5884 ktrack0 = track0;
5885 ktrack1 = track1;
5886 }
5887 else{
5888 ktrack0 = track1;
5889 ktrack1 = track0;
5890 }
5891 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
5892 AliExternalTrackParam paramm(*ktrack0);
5893 AliExternalTrackParam paramd(*ktrack1);
316c6cd9 5894 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
51ad6848 5895 //
5896 //
5897 kink->SetMother(paramm);
5898 kink->SetDaughter(paramd);
5899 kink->Update();
5900
2942f542 5901 Float_t x[3] = { static_cast<Float_t>(kink->GetPosition()[0]),static_cast<Float_t>(kink->GetPosition()[1]),static_cast<Float_t>(kink->GetPosition()[2])};
51ad6848 5902 Int_t index[4];
47af7ca4 5903 fkParam->Transform0to1(x,index);
5904 fkParam->Transform1to2(x,index);
51ad6848 5905 row0 = GetRowNumber(x[0]);
5906
eea478d3 5907 if (kink->GetR()<100) continue;
5908 if (kink->GetR()>240) continue;
5909 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
5910 if (kink->GetDistance()>cdist3) continue;
5911 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
51ad6848 5912 if (dird<0) continue;
5913
eea478d3 5914 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
51ad6848 5915 if (dirm<0) continue;
eea478d3 5916 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
51ad6848 5917 if (mpt<0.2) continue;
5918
eea478d3 5919 if (mpt<1){
5920 //for high momenta momentum not defined well in first iteration
6c94f330 5921 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
eea478d3 5922 if (qt>0.35) continue;
5923 }
51ad6848 5924
eea478d3 5925 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
5926 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
51ad6848 5927 if (dens00>dens10){
eea478d3 5928 kink->SetTPCDensity(dens00,0,0);
5929 kink->SetTPCDensity(dens01,0,1);
5930 kink->SetTPCDensity(dens10,1,0);
5931 kink->SetTPCDensity(dens11,1,1);
5932 kink->SetIndex(i,0);
5933 kink->SetIndex(j,1);
51ad6848 5934 }
5935 else{
eea478d3 5936 kink->SetTPCDensity(dens10,0,0);
5937 kink->SetTPCDensity(dens11,0,1);
5938 kink->SetTPCDensity(dens00,1,0);
5939 kink->SetTPCDensity(dens01,1,1);
5940 kink->SetIndex(j,0);
5941 kink->SetIndex(i,1);
51ad6848 5942 }
51ad6848 5943
eea478d3 5944 if (mpt<1||kink->GetAngle(2)>0.1){
5945 // angle and densities not defined yet
5946 if (kink->GetTPCDensityFactor()<0.8) continue;
5947 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
6c94f330 5948 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
eea478d3 5949 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5950 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5951
6c94f330 5952 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5953 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
eea478d3 5954 criticalangle= 3*TMath::Sqrt(criticalangle);
5955 if (criticalangle>0.02) criticalangle=0.02;
5956 if (kink->GetAngle(2)<criticalangle) continue;
5957 }
51ad6848 5958 //
eea478d3 5959 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
51ad6848 5960 Float_t shapesum =0;
5961 Float_t sum = 0;
5962 for ( Int_t row = row0-drow; row<row0+drow;row++){
5963 if (row<0) continue;
5964 if (row>155) continue;
b9671574 5965 if (ktrack0->GetClusterPointer(row)){
51ad6848 5966 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5967 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5968 sum++;
5969 }
b9671574 5970 if (ktrack1->GetClusterPointer(row)){
51ad6848 5971 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5972 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5973 sum++;
5974 }
5975 }
5976 if (sum<4){
eea478d3 5977 kink->SetShapeFactor(-1.);
51ad6848 5978 }
5979 else{
eea478d3 5980 kink->SetShapeFactor(shapesum/sum);
5981 }
51ad6848 5982 // esd->AddKink(kink);
16299eac 5983 //
5984 // kink->SetMother(paramm);
5985 //kink->SetDaughter(paramd);
5986
5987 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
5988 chi2P2*=chi2P2;
5989 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
5990 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
5991 chi2P3*=chi2P3;
5992 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
5993 //
65e67c9c 5994 if ((AliTPCReconstructor::StreamLevel()&kStreamFindKinks)>0) { // flag: stream track infroamtion in the FindKinks method
16299eac 5995 (*fDebugStreamer)<<"kinkLpt"<<
5996 "chi2P2="<<chi2P2<<
5997 "chi2P3="<<chi2P3<<
5998 "p0.="<<&paramm<<
5999 "p1.="<<&paramd<<
6000 "k.="<<kink<<
6001 "\n";
6002 }
6003 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
6004 continue;
6005 }
6006 //
ddfbc51a 6007 kinks->AddLast(kink);
6008 kink = new AliKink;
51ad6848 6009 ncandidates++;
6010 }
6011 }
ddfbc51a 6012 //
eea478d3 6013 // sort the kinks according quality - and refit them towards vertex
6014 //
ddfbc51a 6015 Int_t nkinks = kinks->GetEntriesFast();
6016 Float_t *quality = new Float_t[nkinks];
6017 Int_t *indexes = new Int_t[nkinks];
6018 AliTPCseed *mothers = new AliTPCseed[nkinks];
6019 AliTPCseed *daughters = new AliTPCseed[nkinks];
eea478d3 6020 //
6021 //
51ad6848 6022 for (Int_t i=0;i<nkinks;i++){
6023 quality[i] =100000;
ddfbc51a 6024 AliKink *kinkl = (AliKink*)kinks->At(i);
eea478d3 6025 //
6026 // refit kinks towards vertex
6027 //
77f88633 6028 Int_t index0 = kinkl->GetIndex(0);
6029 Int_t index1 = kinkl->GetIndex(1);
eea478d3 6030 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6031 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6032 //
b9671574 6033 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
eea478d3 6034 //
6035 // Refit Kink under if too small angle
6036 //
77f88633 6037 if (kinkl->GetAngle(2)<0.05){
6038 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6039 Int_t row0 = kinkl->GetTPCRow0();
6040 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
eea478d3 6041 //
6042 //
6043 Int_t last = row0-drow;
6044 if (last<40) last=40;
b9671574 6045 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
eea478d3 6046 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
6047 //
6048 //
6049 Int_t first = row0+drow;
6050 if (first>130) first=130;
b9671574 6051 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
eea478d3 6052 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
6053 //
ddfbc51a 6054 if (seed0 && seed1){
77f88633 6055 kinkl->SetStatus(1,8);
6056 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
6057 row0 = GetRowNumber(kinkl->GetR());
b9671574 6058 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
ddfbc51a 6059 mothers[i] = *seed0;
6060 daughters[i] = *seed1;
eea478d3 6061 }
ddfbc51a 6062 else{
6063 delete kinks->RemoveAt(i);
6064 if (seed0) MarkSeedFree( seed0 );
6065 if (seed1) MarkSeedFree( seed1 );
eea478d3 6066 continue;
6067 }
77f88633 6068 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
ddfbc51a 6069 delete kinks->RemoveAt(i);
6070 if (seed0) MarkSeedFree( seed0 );
6071 if (seed1) MarkSeedFree( seed1 );
eea478d3 6072 continue;
6073 }
ddfbc51a 6074 //
6075 MarkSeedFree( seed0 );
6076 MarkSeedFree( seed1 );
eea478d3 6077 }
6078 //
77f88633 6079 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
51ad6848 6080 }
6081 TMath::Sort(nkinks,quality,indexes,kFALSE);
eea478d3 6082 //
6083 //remove double find kinks
6084 //
6085 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
ddfbc51a 6086 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
eea478d3 6087 if (!kink0) continue;
6088 //
6a6ba9a2 6089 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
ddfbc51a 6090 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6091 if (!kink0) continue;
6092 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
eea478d3 6093 if (!kink1) continue;
6094 // if not close kink continue
6095 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
6096 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
6097 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
6098 //
ddfbc51a 6099 AliTPCseed &mother0 = mothers[indexes[ikink0]];
6100 AliTPCseed &daughter0 = daughters[indexes[ikink0]];
6101 AliTPCseed &mother1 = mothers[indexes[ikink1]];
6102 AliTPCseed &daughter1 = daughters[indexes[ikink1]];
eea478d3 6103 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
6104 //
6105 Int_t same = 0;
6106 Int_t both = 0;
6107 Int_t samem = 0;
6108 Int_t bothm = 0;
6109 Int_t samed = 0;
6110 Int_t bothd = 0;
6111 //
6112 for (Int_t i=0;i<row0;i++){
ddfbc51a 6113 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
eea478d3 6114 both++;
6115 bothm++;
ddfbc51a 6116 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
eea478d3 6117 same++;
6118 samem++;
6119 }
6120 }
6121 }
6122
6123 for (Int_t i=row0;i<158;i++){
f06a1ff6 6124 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
ddfbc51a 6125 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
eea478d3 6126 both++;
6127 bothd++;
ddfbc51a 6128 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
eea478d3 6129 same++;
6130 samed++;
6131 }
6132 }
6133 }
6134 Float_t ratio = Float_t(same+1)/Float_t(both+1);
6135 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
6136 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
6137 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
ddfbc51a 6138 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
6139 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
eea478d3 6140 if (sum1>sum0){
6141 shared[kink0->GetIndex(0)]= kTRUE;
6142 shared[kink0->GetIndex(1)]= kTRUE;
ddfbc51a 6143 delete kinks->RemoveAt(indexes[ikink0]);
b3659bad 6144 break;
eea478d3 6145 }
6146 else{
6147 shared[kink1->GetIndex(0)]= kTRUE;
6148 shared[kink1->GetIndex(1)]= kTRUE;
ddfbc51a 6149 delete kinks->RemoveAt(indexes[ikink1]);
eea478d3 6150 }
6151 }
6152 }
6153 }
6154
6155
51ad6848 6156 for (Int_t i=0;i<nkinks;i++){
ddfbc51a 6157 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
77f88633 6158 if (!kinkl) continue;
6159 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6160 Int_t index0 = kinkl->GetIndex(0);
6161 Int_t index1 = kinkl->GetIndex(1);
6162 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
6163 kinkl->SetMultiple(usage[index0],0);
6164 kinkl->SetMultiple(usage[index1],1);
6165 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
6166 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
6167 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
6168 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
51ad6848 6169
51ad6848 6170 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6171 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
eea478d3 6172 if (!ktrack0 || !ktrack1) continue;
77f88633 6173 Int_t index = esd->AddKink(kinkl);
eea478d3 6174 //
6175 //
b9671574 6176 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
ddfbc51a 6177 if (mothers[indexes[i]].GetNumberOfClusters()>20 && daughters[indexes[i]].GetNumberOfClusters()>20 && (mothers[indexes[i]].GetNumberOfClusters()+daughters[indexes[i]].GetNumberOfClusters())>100){
6178 *ktrack0 = mothers[indexes[i]];
6179 *ktrack1 = daughters[indexes[i]];
eea478d3 6180 }
6181 }
6182 //
b9671574 6183 ktrack0->SetKinkIndex(usage[index0],-(index+1));
6184 ktrack1->SetKinkIndex(usage[index1], (index+1));
51ad6848 6185 usage[index0]++;
6186 usage[index1]++;
6187 }
eea478d3 6188 //
6189 // Remove tracks corresponding to shared kink's
6190 //
6191 for (Int_t i=0;i<nentries;i++){
6192 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6193 if (!track0) continue;
b9671574 6194 if (track0->GetKinkIndex(0)!=0) continue;
ddfbc51a 6195 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
eea478d3 6196 }
ddfbc51a 6197
eea478d3 6198 //
6199 //
6200 RemoveUsed2(array,0.5,0.4,30);
6201 UnsignClusters();
81e97e0d 6202 for (Int_t i=0;i<nentries;i++){
6203 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6204 if (!track0) continue;
6205 track0->CookdEdx(0.02,0.6);
6206 track0->CookPID();
6207 }
eea478d3 6208 //
6209 for (Int_t i=0;i<nentries;i++){
6210 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6211 if (!track0) continue;
8467b758 6212 if (track0->Pt()<1.4) continue;
eea478d3 6213 //remove double high momenta tracks - overlapped with kink candidates
77f88633 6214 Int_t ishared=0;
eea478d3 6215 Int_t all =0;
b9671574 6216 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
6217 if (track0->GetClusterPointer(icl)!=0){
eea478d3 6218 all++;
77f88633 6219 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
eea478d3 6220 }
6221 }
77f88633 6222 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
ddfbc51a 6223 MarkSeedFree( array->RemoveAt(i) );
f99dc368 6224 continue;
eea478d3 6225 }
6226 //
b9671574 6227 if (track0->GetKinkIndex(0)!=0) continue;
eea478d3 6228 if (track0->GetNumberOfClusters()<80) continue;
4a12af72 6229
ddfbc51a 6230 AliTPCseed *pmother = new AliTPCseed();
6231 AliTPCseed *pdaughter = new AliTPCseed();
6232 AliKink *pkink = new AliKink;
6233
4a12af72 6234 AliTPCseed & mother = *pmother;
6235 AliTPCseed & daughter = *pdaughter;
77f88633 6236 AliKink & kinkl = *pkink;
6237 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
b9671574 6238 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
ddfbc51a 6239 delete pmother;
6240 delete pdaughter;
6241 delete pkink;
4a12af72 6242 continue; //too short tracks
6243 }
8467b758 6244 if (mother.Pt()<1.4) {
ddfbc51a 6245 delete pmother;
6246 delete pdaughter;
6247 delete pkink;
4a12af72 6248 continue;
6249 }
77f88633 6250 Int_t row0= kinkl.GetTPCRow0();
6251 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
ddfbc51a 6252 delete pmother;
6253 delete pdaughter;
6254 delete pkink;
eea478d3 6255 continue;
6256 }
6257 //
77f88633 6258 Int_t index = esd->AddKink(&kinkl);
b9671574 6259 mother.SetKinkIndex(0,-(index+1));
6260 daughter.SetKinkIndex(0,index+1);
6261 if (mother.GetNumberOfClusters()>50) {
ddfbc51a 6262 MarkSeedFree( array->RemoveAt(i) );
6263 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6264 mtc->SetPoolID(fLastSeedID);
f06a1ff6 6265 array->AddAt(mtc,i);
eea478d3 6266 }
6267 else{
ddfbc51a 6268 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6269 mtc->SetPoolID(fLastSeedID);
f06a1ff6 6270 array->AddLast(mtc);
eea478d3 6271 }
ddfbc51a 6272 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
6273 dtc->SetPoolID(fLastSeedID);
f06a1ff6 6274 array->AddLast(dtc);
eea478d3 6275 for (Int_t icl=0;icl<row0;icl++) {
b9671574 6276 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
eea478d3 6277 }
6278 //
6279 for (Int_t icl=row0;icl<158;icl++) {
b9671574 6280 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
eea478d3 6281 }
6282 //
6283 }
ddfbc51a 6284 delete pmother;
6285 delete pdaughter;
6286 delete pkink;
eea478d3 6287 }
ddfbc51a 6288
6289 delete [] daughters;
6290 delete [] mothers;
eea478d3 6291 //
eea478d3 6292 //
ddfbc51a 6293 delete [] dca;
6294 delete []circular;
6295 delete []shared;
6296 delete []quality;
6297 delete []indexes;
6298 //
6299 delete kink;
6300 delete[]fim;
6301 delete[] zm;
6302 delete[] z0;
6303 delete [] usage;
6304 delete[] alpha;
6305 delete[] nclusters;
6306 delete[] sign;
bfa00fba 6307 delete[] helixes;
ddfbc51a 6308 kinks->Delete();
6309 delete kinks;
6310
7b9ce4fd 6311 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
51ad6848 6312 timer.Print();
6313}
6314
81e97e0d 6315
ddfbc51a 6316/*
829455ad 6317void AliTPCtracker::FindKinks(TObjArray * array, AliESDEvent *esd)
eea478d3 6318{
6319 //
ddfbc51a 6320 // find kinks
eea478d3 6321 //
6322 //
6c94f330 6323
ddfbc51a 6324 TObjArray *kinks= new TObjArray(10000);
6325 // TObjArray *v0s= new TObjArray(10000);
6326 Int_t nentries = array->GetEntriesFast();
6327 AliHelix *helixes = new AliHelix[nentries];
6328 Int_t *sign = new Int_t[nentries];
6329 Int_t *nclusters = new Int_t[nentries];
6330 Float_t *alpha = new Float_t[nentries];
6331 AliKink *kink = new AliKink();
6332 Int_t * usage = new Int_t[nentries];
6333 Float_t *zm = new Float_t[nentries];
6334 Float_t *z0 = new Float_t[nentries];
6335 Float_t *fim = new Float_t[nentries];
6336 Float_t *shared = new Float_t[nentries];
6337 Bool_t *circular = new Bool_t[nentries];
6338 Float_t *dca = new Float_t[nentries];
6339 //const AliESDVertex * primvertex = esd->GetVertex();
eea478d3 6340 //
ddfbc51a 6341 // nentries = array->GetEntriesFast();
eea478d3 6342 //
ddfbc51a 6343
e546b023 6344 //
e546b023 6345 //
ddfbc51a 6346 for (Int_t i=0;i<nentries;i++){
6347 sign[i]=0;
6348 usage[i]=0;
6349 AliTPCseed* track = (AliTPCseed*)array->At(i);
6350 if (!track) continue;
6351 track->SetCircular(0);
6352 shared[i] = kFALSE;
6353 track->UpdatePoints();
6354 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
6355 }
6356 nclusters[i]=track->GetNumberOfClusters();
6357 alpha[i] = track->GetAlpha();
6358 new (&helixes[i]) AliHelix(*track);
6359 Double_t xyz[3];
6360 helixes[i].Evaluate(0,xyz);
6361 sign[i] = (track->GetC()>0) ? -1:1;
6362 Double_t x,y,z;
6363 x=160;
6364 if (track->GetProlongation(x,y,z)){
6365 zm[i] = z;
6366 fim[i] = alpha[i]+TMath::ATan2(y,x);
eea478d3 6367 }
ddfbc51a 6368 else{
6369 zm[i] = track->GetZ();
6370 fim[i] = alpha[i];
6371 }
6372 z0[i]=1000;
6373 circular[i]= kFALSE;
6374 if (track->GetProlongation(0,y,z)) z0[i] = z;
6375 dca[i] = track->GetD(0,0);
eea478d3 6376 }
6377 //
eea478d3 6378 //
ddfbc51a 6379 TStopwatch timer;
6380 timer.Start();
6381 Int_t ncandidates =0;
6382 Int_t nall =0;
6383 Int_t ntracks=0;
6384 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
6385
eea478d3 6386 //
ddfbc51a 6387 // Find circling track
e546b023 6388 //
ddfbc51a 6389 for (Int_t i0=0;i0<nentries;i0++){
6390 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
6391 if (!track0) continue;
6392 if (track0->GetNumberOfClusters()<40) continue;
6393 if (TMath::Abs(1./track0->GetC())>200) continue;
6394 for (Int_t i1=i0+1;i1<nentries;i1++){
6395 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
6396 if (!track1) continue;
6397 if (track1->GetNumberOfClusters()<40) continue;
6398 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
6399 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
6400 if (TMath::Abs(1./track1->GetC())>200) continue;
6401 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
6402 if (track1->GetTgl()*track0->GetTgl()>0) continue;
6403 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
6404 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
6405 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
6406 //
6407 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
6408 if (mindcar<5) continue;
6409 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
6410 if (mindcaz<5) continue;
6411 if (mindcar+mindcaz<20) continue;
6412 //
6413 //
6414 Float_t xc0 = helixes[i0].GetHelix(6);
6415 Float_t yc0 = helixes[i0].GetHelix(7);
6416 Float_t r0 = helixes[i0].GetHelix(8);
6417 Float_t xc1 = helixes[i1].GetHelix(6);
6418 Float_t yc1 = helixes[i1].GetHelix(7);
6419 Float_t r1 = helixes[i1].GetHelix(8);
6420
6421 Float_t rmean = (r0+r1)*0.5;
6422 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
6423 //if (delta>30) continue;
6424 if (delta>rmean*0.25) continue;
6425 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
6426 //
6427 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
6428 if (npoints==0) continue;
6429 helixes[i0].GetClosestPhases(helixes[i1], phase);
6430 //
6431 Double_t xyz0[3];
6432 Double_t xyz1[3];
6433 Double_t hangles[3];
6434 helixes[i0].Evaluate(phase[0][0],xyz0);
6435 helixes[i1].Evaluate(phase[0][1],xyz1);
e546b023 6436
ddfbc51a 6437 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
6438 Double_t deltah[2],deltabest;
6439 if (hangles[2]<2.8) continue;
6440 if (npoints>0){
6441 Int_t ibest=0;
6442 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
6443 if (npoints==2){
6444 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
6445 if (deltah[1]<deltah[0]) ibest=1;
6446 }
6447 deltabest = TMath::Sqrt(deltah[ibest]);
6448 helixes[i0].Evaluate(phase[ibest][0],xyz0);
6449 helixes[i1].Evaluate(phase[ibest][1],xyz1);
6450 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
6451 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
6452 //
6453 if (deltabest>6) continue;
6454 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
6455 Bool_t lsign =kFALSE;
6456 if (hangles[2]>3.06) lsign =kTRUE;
6457 //
6458 if (lsign){
6459 circular[i0] = kTRUE;
6460 circular[i1] = kTRUE;
6461 if (track0->OneOverPt()<track1->OneOverPt()){
6462 track0->SetCircular(track0->GetCircular()+1);
6463 track1->SetCircular(track1->GetCircular()+2);
6464 }
6465 else{
6466 track1->SetCircular(track1->GetCircular()+1);
6467 track0->SetCircular(track0->GetCircular()+2);
6468 }
6469 }
65e67c9c 6470 if (lsign&&((AliTPCReconstructor::StreamLevel()&kStreamFindKinks)>0)){// flag: stream track infroamtion in the FindKinks method
ddfbc51a 6471 //debug stream
6472 Int_t lab0=track0->GetLabel();
6473 Int_t lab1=track1->GetLabel();
6474 TTreeSRedirector &cstream = *fDebugStreamer;
6475 cstream<<"Curling"<<
6476 "lab0="<<lab0<<
6477 "lab1="<<lab1<<
6478 "Tr0.="<<track0<<
6479 "Tr1.="<<track1<<
6480 "dca0="<<dca[i0]<<
6481 "dca1="<<dca[i1]<<
6482 "mindcar="<<mindcar<<
6483 "mindcaz="<<mindcaz<<
6484 "delta="<<delta<<
6485 "rmean="<<rmean<<
6486 "npoints="<<npoints<<
6487 "hangles0="<<hangles[0]<<
6488 "hangles2="<<hangles[2]<<
6489 "xyz0="<<xyz0[2]<<
6490 "xyzz1="<<xyz1[2]<<
6491 "z0="<<z0[i0]<<
6492 "z1="<<z0[i1]<<
6493 "radius="<<radiusbest<<
6494 "deltabest="<<deltabest<<
6495 "phase0="<<phase[ibest][0]<<
6496 "phase1="<<phase[ibest][1]<<
6497 "\n";
6498 }
6499 }
6500 }
6501 }
51ad6848 6502 //
ddfbc51a 6503 // Finf kinks loop
6504 //
f06a1ff6 6505 //
ddfbc51a 6506 for (Int_t i =0;i<nentries;i++){
6507 if (sign[i]==0) continue;
6508 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6509 if (track0==0) {
6510 AliInfo("seed==0");
6511 continue;
6512 }
6513 ntracks++;
6514 //
6515 Double_t cradius0 = 40*40;
6516 Double_t cradius1 = 270*270;
6517 Double_t cdist1=8.;
6518 Double_t cdist2=8.;
6519 Double_t cdist3=0.55;
6520 for (Int_t j =i+1;j<nentries;j++){
6521 nall++;
6522 if (sign[j]*sign[i]<1) continue;
6523 if ( (nclusters[i]+nclusters[j])>200) continue;
6524 if ( (nclusters[i]+nclusters[j])<80) continue;
6525 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
6526 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
6527 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
6528 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
6529 if (npoints<1) continue;
6530 // cuts on radius
6531 if (npoints==1){
6532 if (radius[0]<cradius0||radius[0]>cradius1) continue;
6533 }
6534 else{
6535 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
6536 }
6537 //
6538 Double_t delta1=10000,delta2=10000;
6539 // cuts on the intersection radius
6540 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
6541 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
6542 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
6543 if (npoints==2){
6544 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
6545 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
6546 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
6547 }
6548 //
6549 Double_t distance1 = TMath::Min(delta1,delta2);
6550 if (distance1>cdist1) continue; // cut on DCA linear approximation
6551 //
6552 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
6553 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
6554 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
6555 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
6556 //
6557 if (npoints==2){
6558 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
6559 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
6560 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
6561 }
6562 distance1 = TMath::Min(delta1,delta2);
6563 Float_t rkink =0;
6564 if (delta1<delta2){
6565 rkink = TMath::Sqrt(radius[0]);
6566 }
6567 else{
6568 rkink = TMath::Sqrt(radius[1]);
6569 }
6570 if (distance1>cdist2) continue;
6571 //
6572 //
6573 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
6574 //
6575 //
6576 Int_t row0 = GetRowNumber(rkink);
6577 if (row0<10) continue;
6578 if (row0>150) continue;
6579 //
6580 //
6581 Float_t dens00=-1,dens01=-1;
6582 Float_t dens10=-1,dens11=-1;
6583 //
6584 Int_t found,foundable,ishared;
6585 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
6586 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
6587 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
6588 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
6589 //
6590 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
6591 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
6592 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
6593 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
6594 //
6595 if (dens00<dens10 && dens01<dens11) continue;
6596 if (dens00>dens10 && dens01>dens11) continue;
6597 if (TMath::Max(dens00,dens10)<0.1) continue;
6598 if (TMath::Max(dens01,dens11)<0.3) continue;
6599 //
6600 if (TMath::Min(dens00,dens10)>0.6) continue;
6601 if (TMath::Min(dens01,dens11)>0.6) continue;
6602
6603 //
6604 AliTPCseed * ktrack0, *ktrack1;
6605 if (dens00>dens10){
6606 ktrack0 = track0;
6607 ktrack1 = track1;
6608 }
6609 else{
6610 ktrack0 = track1;
6611 ktrack1 = track0;
6612 }
6613 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
6614 AliExternalTrackParam paramm(*ktrack0);
6615 AliExternalTrackParam paramd(*ktrack1);
6616 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
6617 //
6618 //
6619 kink->SetMother(paramm);
6620 kink->SetDaughter(paramd);
6621 kink->Update();
6622
2942f542 6623 Float_t x[3] = { static_cast<Float_t>(kink->GetPosition()[0]),static_cast<Float_t>(kink->GetPosition()[1]),static_cast<Float_t>(kink->GetPosition()[2])};
ddfbc51a 6624 Int_t index[4];
6625 fkParam->Transform0to1(x,index);
6626 fkParam->Transform1to2(x,index);
6627 row0 = GetRowNumber(x[0]);
6628
6629 if (kink->GetR()<100) continue;
6630 if (kink->GetR()>240) continue;
6631 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
6632 if (kink->GetDistance()>cdist3) continue;
6633 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
6634 if (dird<0) continue;
6635
6636 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
6637 if (dirm<0) continue;
6638 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
6639 if (mpt<0.2) continue;
6640
6641 if (mpt<1){
6642 //for high momenta momentum not defined well in first iteration
6643 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
6644 if (qt>0.35) continue;
6645 }
6646
6647 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
6648 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
6649 if (dens00>dens10){
6650 kink->SetTPCDensity(dens00,0,0);
6651 kink->SetTPCDensity(dens01,0,1);
6652 kink->SetTPCDensity(dens10,1,0);
6653 kink->SetTPCDensity(dens11,1,1);
6654 kink->SetIndex(i,0);
6655 kink->SetIndex(j,1);
6656 }
6657 else{
6658 kink->SetTPCDensity(dens10,0,0);
6659 kink->SetTPCDensity(dens11,0,1);
6660 kink->SetTPCDensity(dens00,1,0);
6661 kink->SetTPCDensity(dens01,1,1);
6662 kink->SetIndex(j,0);
6663 kink->SetIndex(i,1);
6664 }
6665
6666 if (mpt<1||kink->GetAngle(2)>0.1){
6667 // angle and densities not defined yet
6668 if (kink->GetTPCDensityFactor()<0.8) continue;
6669 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
6670 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
6671 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
6672 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
6673
6674 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
6675 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
6676 criticalangle= 3*TMath::Sqrt(criticalangle);
6677 if (criticalangle>0.02) criticalangle=0.02;
6678 if (kink->GetAngle(2)<criticalangle) continue;
6679 }
6680 //
6681 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
6682 Float_t shapesum =0;
6683 Float_t sum = 0;
6684 for ( Int_t row = row0-drow; row<row0+drow;row++){
6685 if (row<0) continue;
6686 if (row>155) continue;
6687 if (ktrack0->GetClusterPointer(row)){
6688 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
6689 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
6690 sum++;
6691 }
6692 if (ktrack1->GetClusterPointer(row)){
6693 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
6694 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
6695 sum++;
6696 }
6697 }
6698 if (sum<4){
6699 kink->SetShapeFactor(-1.);
6700 }
6701 else{
6702 kink->SetShapeFactor(shapesum/sum);
6703 }
6704 // esd->AddKink(kink);
6705 //
6706 // kink->SetMother(paramm);
6707 //kink->SetDaughter(paramd);
6708
6709 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
6710 chi2P2*=chi2P2;
6711 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
6712 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
6713 chi2P3*=chi2P3;
6714 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
6715 //
65e67c9c 6716 if (AliTPCReconstructor::StreamLevel()&kStreamFindKinks) {// flag: stream track infroamtion in the FindKinks method
ddfbc51a 6717 (*fDebugStreamer)<<"kinkLpt"<<
6718 "chi2P2="<<chi2P2<<
6719 "chi2P3="<<chi2P3<<
6720 "p0.="<<&paramm<<
6721 "p1.="<<&paramd<<
6722 "k.="<<kink<<
6723 "\n";
6724 }
6725 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
6726 continue;
6727 }
6728 //
6729 kinks->AddLast(kink);
6730 kink = new AliKink;
6731 ncandidates++;
6732 }
6733 }
6734 //
6735 // sort the kinks according quality - and refit them towards vertex
6736 //
6737 Int_t nkinks = kinks->GetEntriesFast();
6738 Float_t *quality = new Float_t[nkinks];
6739 Int_t *indexes = new Int_t[nkinks];
6740 AliTPCseed **mothers = new AliTPCseed*[nkinks]; memset(mothers, 0, nkinks*sizeof(AliTPCseed*));
6741 AliTPCseed **daughters = new AliTPCseed*[nkinks]; memset(daughters, 0, nkinks*sizeof(AliTPCseed*));
6742 //
6743 //
6744 for (Int_t i=0;i<nkinks;i++){
6745 quality[i] =100000;
6746 AliKink *kinkl = (AliKink*)kinks->At(i);
6747 //
6748 // refit kinks towards vertex
6749 //
6750 Int_t index0 = kinkl->GetIndex(0);
6751 Int_t index1 = kinkl->GetIndex(1);
6752 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6753 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6754 //
6755 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
6756 //
6757 // Refit Kink under if too small angle
6758 //
6759 if (kinkl->GetAngle(2)<0.05){
6760 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6761 Int_t row0 = kinkl->GetTPCRow0();
6762 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
6763 //
6764 //
6765 Int_t last = row0-drow;
6766 if (last<40) last=40;
6767 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
6768 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
6769 //
6770 //
6771 Int_t first = row0+drow;
6772 if (first>130) first=130;
6773 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
6774 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
6775 //
6776 if (seed0 && seed1){
6777 kinkl->SetStatus(1,8);
6778 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
6779 row0 = GetRowNumber(kinkl->GetR());
6780 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
6781 mothers[i] = new ( NextFreeSeed() ) AliTPCseed(*seed0);
6782 mothers[i]->SetPoolID(fLastSeedID);
6783 daughters[i] = new (NextFreeSeed() ) AliTPCseed(*seed1);
6784 daughters[i]->SetPoolID(fLastSeedID);
6785 }
6786 else{
6787 delete kinks->RemoveAt(i);
6788 if (seed0) MarkSeedFree( seed0 );
6789 if (seed1) MarkSeedFree( seed1 );
6790 continue;
6791 }
6792 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
6793 delete kinks->RemoveAt(i);
6794 if (seed0) MarkSeedFree( seed0 );
6795 if (seed1) MarkSeedFree( seed1 );
6796 continue;
6797 }
6798 //
6799 MarkSeedFree( seed0 );
6800 MarkSeedFree( seed1 );
6801 }
6802 //
6803 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
6804 }
6805 TMath::Sort(nkinks,quality,indexes,kFALSE);
6806 //
6807 //remove double find kinks
6808 //
6809 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
6810 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6811 if (!kink0) continue;
6812 //
6813 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
6814 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6815 if (!kink0) continue;
6816 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
6817 if (!kink1) continue;
6818 // if not close kink continue
6819 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
6820 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
6821 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
6822 //
6823 AliTPCseed &mother0 = *mothers[indexes[ikink0]];
6824 AliTPCseed &daughter0 = *daughters[indexes[ikink0]];
6825 AliTPCseed &mother1 = *mothers[indexes[ikink1]];
6826 AliTPCseed &daughter1 = *daughters[indexes[ikink1]];
6827 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
6828 //
6829 Int_t same = 0;
6830 Int_t both = 0;
6831 Int_t samem = 0;
6832 Int_t bothm = 0;
6833 Int_t samed = 0;
6834 Int_t bothd = 0;
6835 //
6836 for (Int_t i=0;i<row0;i++){
6837 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
6838 both++;
6839 bothm++;
6840 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6841 same++;
6842 samem++;
6843 }
6844 }
6845 }
6846
6847 for (Int_t i=row0;i<158;i++){
6848 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
6849 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
6850 both++;
6851 bothd++;
6852 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6853 same++;
6854 samed++;
6855 }
6856 }
6857 }
6858 Float_t ratio = Float_t(same+1)/Float_t(both+1);
6859 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
6860 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
6861 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
6862 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
6863 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
6864 if (sum1>sum0){
6865 shared[kink0->GetIndex(0)]= kTRUE;
6866 shared[kink0->GetIndex(1)]= kTRUE;
6867 delete kinks->RemoveAt(indexes[ikink0]);
6868 break;
6869 }
6870 else{
6871 shared[kink1->GetIndex(0)]= kTRUE;
6872 shared[kink1->GetIndex(1)]= kTRUE;
6873 delete kinks->RemoveAt(indexes[ikink1]);
6874 }
6875 }
6876 }
6877 }
6878
6879
6880 for (Int_t i=0;i<nkinks;i++){
6881 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
6882 if (!kinkl) continue;
6883 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6884 Int_t index0 = kinkl->GetIndex(0);
6885 Int_t index1 = kinkl->GetIndex(1);
6886 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
6887 kinkl->SetMultiple(usage[index0],0);
6888 kinkl->SetMultiple(usage[index1],1);
6889 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
6890 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
6891 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
6892 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
6893
6894 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6895 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6896 if (!ktrack0 || !ktrack1) continue;
6897 Int_t index = esd->AddKink(kinkl);
6898 //
6899 //
6900 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
6901 if (mothers[indexes[i]]->GetNumberOfClusters()>20 && daughters[indexes[i]]->GetNumberOfClusters()>20 &&
6902 (mothers[indexes[i]]->GetNumberOfClusters()+daughters[indexes[i]]->GetNumberOfClusters())>100){
6903 *ktrack0 = *mothers[indexes[i]];
6904 *ktrack1 = *daughters[indexes[i]];
6905 }
6906 }
6907 //
6908 ktrack0->SetKinkIndex(usage[index0],-(index+1));
6909 ktrack1->SetKinkIndex(usage[index1], (index+1));
6910 usage[index0]++;
6911 usage[index1]++;
6912 }
6913 //
6914 // Remove tracks corresponding to shared kink's
6915 //
6916 for (Int_t i=0;i<nentries;i++){
6917 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6918 if (!track0) continue;
6919 if (track0->GetKinkIndex(0)!=0) continue;
6920 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
6921 }
6922
6923 //
6924 //
6925 RemoveUsed2(array,0.5,0.4,30);
6926 UnsignClusters();
6927 for (Int_t i=0;i<nentries;i++){
6928 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6929 if (!track0) continue;
6930 track0->CookdEdx(0.02,0.6);
6931 track0->CookPID();
6932 }
6933 //
6934 for (Int_t i=0;i<nentries;i++){
6935 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6936 if (!track0) continue;
6937 if (track0->Pt()<1.4) continue;
6938 //remove double high momenta tracks - overlapped with kink candidates
6939 Int_t ishared=0;
6940 Int_t all =0;
6941 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
6942 if (track0->GetClusterPointer(icl)!=0){
6943 all++;
6944 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
6945 }
6946 }
6947 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
6948 MarkSeedFree( array->RemoveAt(i) );
6949 continue;
6950 }
6951 //
6952 if (track0->GetKinkIndex(0)!=0) continue;
6953 if (track0->GetNumberOfClusters()<80) continue;
6954
6955 AliTPCseed *pmother = new( NextFreeSeed() ) AliTPCseed();
6956 pmother->SetPoolID(fLastSeedID);
6957 AliTPCseed *pdaughter = new( NextFreeSeed() ) AliTPCseed();
6958 pdaughter->SetPoolID(fLastSeedID);
6959 AliKink *pkink = new AliKink;
6960
6961 AliTPCseed & mother = *pmother;
6962 AliTPCseed & daughter = *pdaughter;
6963 AliKink & kinkl = *pkink;
6964 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
6965 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
6966 MarkSeedFree( pmother );
6967 MarkSeedFree( pdaughter );
6968 delete pkink;
6969 continue; //too short tracks
6970 }
6971 if (mother.Pt()<1.4) {
6972 MarkSeedFree( pmother );
6973 MarkSeedFree( pdaughter );
6974 delete pkink;
6975 continue;
6976 }
6977 Int_t row0= kinkl.GetTPCRow0();
6978 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
6979 MarkSeedFree( pmother );
6980 MarkSeedFree( pdaughter );
6981 delete pkink;
6982 continue;
6983 }
6984 //
6985 Int_t index = esd->AddKink(&kinkl);
6986 mother.SetKinkIndex(0,-(index+1));
6987 daughter.SetKinkIndex(0,index+1);
6988 if (mother.GetNumberOfClusters()>50) {
6989 MarkSeedFree( array->RemoveAt(i) );
6990 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6991 mtc->SetPoolID(fLastSeedID);
6992 array->AddAt(mtc,i);
6993 }
6994 else{
6995 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6996 mtc->SetPoolID(fLastSeedID);
6997 array->AddLast(mtc);
6998 }
6999 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
7000 dtc->SetPoolID(fLastSeedID);
7001 array->AddLast(dtc);
7002 for (Int_t icl=0;icl<row0;icl++) {
7003 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
7004 }
7005 //
7006 for (Int_t icl=row0;icl<158;icl++) {
7007 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
7008 }
7009 //
7010 }
7011 MarkSeedFree( pmother );
7012 MarkSeedFree( pdaughter );
7013 delete pkink;
7014 }
7015
7016 delete [] daughters;
7017 delete [] mothers;
7018 //
7019 //
7020 delete [] dca;
7021 delete []circular;
7022 delete []shared;
7023 delete []quality;
7024 delete []indexes;
7025 //
7026 delete kink;
7027 delete[]fim;
7028 delete[] zm;
7029 delete[] z0;
7030 delete [] usage;
7031 delete[] alpha;
7032 delete[] nclusters;
7033 delete[] sign;
7034 delete[] helixes;
7035 kinks->Delete();
7036 delete kinks;
7037
7038 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
7039 timer.Print();
7040}
7041*/
7042
829455ad 7043Int_t AliTPCtracker::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
ddfbc51a 7044{
7045 //
7046 // refit kink towards to the vertex
7047 //
7048 //
7049 AliKink &kink=(AliKink &)knk;
7050
7051 Int_t row0 = GetRowNumber(kink.GetR());
7052 FollowProlongation(mother,0);
7053 mother.Reset(kFALSE);
7054 //
7055 FollowProlongation(daughter,row0);
7056 daughter.Reset(kFALSE);
7057 FollowBackProlongation(daughter,158);
7058 daughter.Reset(kFALSE);
7059 Int_t first = TMath::Max(row0-20,30);
7060 Int_t last = TMath::Min(row0+20,140);
7061 //
7062 const Int_t kNdiv =5;
7063 AliTPCseed param0[kNdiv]; // parameters along the track
7064 AliTPCseed param1[kNdiv]; // parameters along the track
7065 AliKink kinks[kNdiv]; // corresponding kink parameters
7066 //
7067 Int_t rows[kNdiv];
7068 for (Int_t irow=0; irow<kNdiv;irow++){
7069 rows[irow] = first +((last-first)*irow)/(kNdiv-1);
7070 }
7071 // store parameters along the track
7072 //
7073 for (Int_t irow=0;irow<kNdiv;irow++){
7074 FollowBackProlongation(mother, rows[irow]);
7075 FollowProlongation(daughter,rows[kNdiv-1-irow]);
7076 param0[irow] = mother;
7077 param1[kNdiv-1-irow] = daughter;
7078 }
7079 //
7080 // define kinks
7081 for (Int_t irow=0; irow<kNdiv-1;irow++){
7082 if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
7083 kinks[irow].SetMother(param0[irow]);
7084 kinks[irow].SetDaughter(param1[irow]);
7085 kinks[irow].Update();
7086 }
7087 //
7088 // choose kink with best "quality"
7089 Int_t index =-1;
7090 Double_t mindist = 10000;
7091 for (Int_t irow=0;irow<kNdiv;irow++){
7092 if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
7093 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
7094 if (TMath::Abs(kinks[irow].GetR())<100.) continue;
7095 //
7096 Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
7097 normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
7098 if (normdist < mindist){
7099 mindist = normdist;
7100 index = irow;
7101 }
7102 }
7103 //
7104 if (index==-1) return 0;
7105 //
7106 //
7107 param0[index].Reset(kTRUE);
7108 FollowProlongation(param0[index],0);
7109 //
7110 mother = param0[index];
7111 daughter = param1[index]; // daughter in vertex
7112 //
7113 kink.SetMother(mother);
7114 kink.SetDaughter(daughter);
7115 kink.Update();
7116 kink.SetTPCRow0(GetRowNumber(kink.GetR()));
7117 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
7118 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
7119 kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
7120 kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
7121 mother.SetLabel(kink.GetLabel(0));
7122 daughter.SetLabel(kink.GetLabel(1));
7123
7124 return 1;
7125}
7126
7127
829455ad 7128void AliTPCtracker::UpdateKinkQualityM(AliTPCseed * seed){
ddfbc51a 7129 //
7130 // update Kink quality information for mother after back propagation
7131 //
7132 if (seed->GetKinkIndex(0)>=0) return;
7133 for (Int_t ikink=0;ikink<3;ikink++){
7134 Int_t index = seed->GetKinkIndex(ikink);
7135 if (index>=0) break;
51ad6848 7136 index = TMath::Abs(index)-1;
7137 AliESDkink * kink = fEvent->GetKink(index);
f941f7fa 7138 kink->SetTPCDensity(-1,0,0);
7139 kink->SetTPCDensity(1,0,1);
51ad6848 7140 //
eea478d3 7141 Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 7142 if (row0<15) row0=15;
7143 //
eea478d3 7144 Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 7145 if (row1>145) row1=145;
7146 //
7147 Int_t found,foundable,shared;
7148 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
f941f7fa 7149 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,0);
51ad6848 7150 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
f941f7fa 7151 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,1);
51ad6848 7152 }
7153
7154}
7155
829455ad 7156void AliTPCtracker::UpdateKinkQualityD(AliTPCseed * seed){
91162307 7157 //
eea478d3 7158 // update Kink quality information for daughter after refit
91162307 7159 //
eea478d3 7160 if (seed->GetKinkIndex(0)<=0) return;
7161 for (Int_t ikink=0;ikink<3;ikink++){
7162 Int_t index = seed->GetKinkIndex(ikink);
7163 if (index<=0) break;
7164 index = TMath::Abs(index)-1;
7165 AliESDkink * kink = fEvent->GetKink(index);
f941f7fa 7166 kink->SetTPCDensity(-1,1,0);
7167 kink->SetTPCDensity(-1,1,1);
91162307 7168 //
eea478d3 7169 Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
7170 if (row0<15) row0=15;
7171 //
7172 Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
7173 if (row1>145) row1=145;
7174 //
7175 Int_t found,foundable,shared;
7176 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
f941f7fa 7177 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,0);
eea478d3 7178 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
f941f7fa 7179 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,1);
91162307 7180 }
eea478d3 7181
7182}
7183
7184
829455ad 7185Int_t AliTPCtracker::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
eea478d3 7186{
91162307 7187 //
eea478d3 7188 // check kink point for given track
7189 // if return value=0 kink point not found
7190 // otherwise seed0 correspond to mother particle
7191 // seed1 correspond to daughter particle
7192 // kink parameter of kink point
6c94f330 7193 AliKink &kink=(AliKink &)knk;
91162307 7194
b9671574 7195 Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
7196 Int_t first = seed->GetFirstPoint();
7197 Int_t last = seed->GetLastPoint();
eea478d3 7198 if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
91162307 7199
eea478d3 7200
7201 AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
7202 if (!seed1) return 0;
b9671574 7203 FollowProlongation(*seed1,seed->GetLastPoint()-20);
eea478d3 7204 seed1->Reset(kTRUE);
7205 FollowProlongation(*seed1,158);
7206 seed1->Reset(kTRUE);
b9671574 7207 last = seed1->GetLastPoint();
eea478d3 7208 //
ddfbc51a 7209 AliTPCseed *seed0 = new( NextFreeSeed() ) AliTPCseed(*seed);
7210 seed0->SetPoolID(fLastSeedID);
eea478d3 7211 seed0->Reset(kFALSE);
7212 seed0->Reset();
7213 //
7214 AliTPCseed param0[20]; // parameters along the track
7215 AliTPCseed param1[20]; // parameters along the track
6c94f330 7216 AliKink kinks[20]; // corresponding kink parameters
eea478d3 7217 Int_t rows[20];
7218 for (Int_t irow=0; irow<20;irow++){
7219 rows[irow] = first +((last-first)*irow)/19;
7220 }
7221 // store parameters along the track
7222 //
7223 for (Int_t irow=0;irow<20;irow++){
7224 FollowBackProlongation(*seed0, rows[irow]);
7225 FollowProlongation(*seed1,rows[19-irow]);
316c6cd9 7226 param0[irow] = *seed0;
7227 param1[19-irow] = *seed1;
eea478d3 7228 }
7229 //
7230 // define kinks
7231 for (Int_t irow=0; irow<19;irow++){
7232 kinks[irow].SetMother(param0[irow]);
7233 kinks[irow].SetDaughter(param1[irow]);
7234 kinks[irow].Update();
7235 }
7236 //
7237 // choose kink with biggest change of angle
7238 Int_t index =-1;
7239 Double_t maxchange= 0;
7240 for (Int_t irow=1;irow<19;irow++){
7241 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
7242 if (TMath::Abs(kinks[irow].GetR())<110.) continue;
6c94f330 7243 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 7244 if ( quality > maxchange){
7245 maxchange = quality;
7246 index = irow;
7247 //
91162307 7248 }
7249 }
ddfbc51a 7250 MarkSeedFree( seed0 );
7251 MarkSeedFree( seed1 );
eea478d3 7252 if (index<0) return 0;
7253 //
7254 Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
ddfbc51a 7255 seed0 = new( NextFreeSeed() ) AliTPCseed(param0[index]);
7256 seed0->SetPoolID(fLastSeedID);
7257 seed1 = new( NextFreeSeed() ) AliTPCseed(param1[index]);
7258 seed1->SetPoolID(fLastSeedID);
eea478d3 7259 seed0->Reset(kFALSE);
7260 seed1->Reset(kFALSE);
6c94f330 7261 seed0->ResetCovariance(10.);
7262 seed1->ResetCovariance(10.);
eea478d3 7263 FollowProlongation(*seed0,0);
7264 FollowBackProlongation(*seed1,158);
316c6cd9 7265 mother = *seed0; // backup mother at position 0
eea478d3 7266 seed0->Reset(kFALSE);
7267 seed1->Reset(kFALSE);
6c94f330 7268 seed0->ResetCovariance(10.);
7269 seed1->ResetCovariance(10.);
eea478d3 7270 //
7271 first = TMath::Max(row0-20,0);
7272 last = TMath::Min(row0+20,158);
7273 //
7274 for (Int_t irow=0; irow<20;irow++){
7275 rows[irow] = first +((last-first)*irow)/19;
7276 }
7277 // store parameters along the track
7278 //
7279 for (Int_t irow=0;irow<20;irow++){
7280 FollowBackProlongation(*seed0, rows[irow]);
7281 FollowProlongation(*seed1,rows[19-irow]);
316c6cd9 7282 param0[irow] = *seed0;
7283 param1[19-irow] = *seed1;
eea478d3 7284 }
7285 //
7286 // define kinks
7287 for (Int_t irow=0; irow<19;irow++){
7288 kinks[irow].SetMother(param0[irow]);
7289 kinks[irow].SetDaughter(param1[irow]);
7290 // param0[irow].Dump();
7291 //param1[irow].Dump();
7292 kinks[irow].Update();
7293 }
7294 //
7295 // choose kink with biggest change of angle
7296 index =-1;
7297 maxchange= 0;
7298 for (Int_t irow=0;irow<20;irow++){
7299 if (TMath::Abs(kinks[irow].GetR())>250.) continue;
7300 if (TMath::Abs(kinks[irow].GetR())<90.) continue;
6c94f330 7301 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 7302 if ( quality > maxchange){
7303 maxchange = quality;
7304 index = irow;
7305 //
91162307 7306 }
7307 }
7308 //
7309 //
b9671574 7310 if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
ddfbc51a 7311 MarkSeedFree( seed0 );
7312 MarkSeedFree( seed1 );
eea478d3 7313 return 0;
1627d1c4 7314 }
16299eac 7315
eea478d3 7316 // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
1627d1c4 7317
eea478d3 7318 kink.SetMother(param0[index]);
7319 kink.SetDaughter(param1[index]);
7320 kink.Update();
16299eac 7321
7322 Double_t chi2P2 = param0[index].GetParameter()[2]-param1[index].GetParameter()[2];
7323 chi2P2*=chi2P2;
7324 chi2P2/=param0[index].GetCovariance()[5]+param1[index].GetCovariance()[5];
7325 Double_t chi2P3 = param0[index].GetParameter()[3]-param1[index].GetParameter()[3];
7326 chi2P3*=chi2P3;
7327 chi2P3/=param0[index].GetCovariance()[9]+param1[index].GetCovariance()[9];
7328 //
65e67c9c 7329 if (AliTPCReconstructor::StreamLevel()&kStreamFindKinks) { // flag: stream track infroamtion in the FindKinks method
16299eac 7330 (*fDebugStreamer)<<"kinkHpt"<<
7331 "chi2P2="<<chi2P2<<
7332 "chi2P3="<<chi2P3<<
7333 "p0.="<<&param0[index]<<
7334 "p1.="<<&param1[index]<<
7335 "k.="<<&kink<<
7336 "\n";
7337 }
7338 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
ddfbc51a 7339 MarkSeedFree( seed0 );
7340 MarkSeedFree( seed1 );
16299eac 7341 return 0;
7342 }
7343
7344
eea478d3 7345 row0 = GetRowNumber(kink.GetR());
7346 kink.SetTPCRow0(row0);
7347 kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
7348 kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
7349 kink.SetIndex(-10,0);
b9671574 7350 kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
7351 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
7352 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
eea478d3 7353 //
7354 //
7355 // new (&mother) AliTPCseed(param0[index]);
316c6cd9 7356 daughter = param1[index];
eea478d3 7357 daughter.SetLabel(kink.GetLabel(1));
7358 param0[index].Reset(kTRUE);
16299eac 7359 FollowProlongation(param0[index],0);
316c6cd9 7360 mother = param0[index];
eea478d3 7361 mother.SetLabel(kink.GetLabel(0));
16299eac 7362 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(1)){
7363 mother=*seed;
7364 }
ddfbc51a 7365 MarkSeedFree( seed0 );
7366 MarkSeedFree( seed1 );
eea478d3 7367 //
7368 return 1;
1627d1c4 7369}
7370
7371
7372
7373
829455ad 7374AliTPCseed* AliTPCtracker::ReSeed(AliTPCseed *t)
91162307 7375{
7376 //
7377 // reseed - refit - track
7378 //
7379 Int_t first = 0;
7380 // Int_t last = fSectors->GetNRows()-1;
7381 //
7382 if (fSectors == fOuterSec){
b9671574 7383 first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
91162307 7384 //last =
7385 }
7386 else
b9671574 7387 first = t->GetFirstPoint();
91162307 7388 //
7389 AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
7390 FollowBackProlongation(*t,fSectors->GetNRows()-1);
7391 t->Reset(kFALSE);
7392 FollowProlongation(*t,first);
7393 return seed;
7394}
7395
7396
7397
7398
7399
7400
7401
1c53abe2 7402//_____________________________________________________________________________
829455ad 7403Int_t AliTPCtracker::ReadSeeds(const TFile *inp) {
1c53abe2 7404 //-----------------------------------------------------------------
7405 // This function reades track seeds.
7406 //-----------------------------------------------------------------
7407 TDirectory *savedir=gDirectory;
7408
7409 TFile *in=(TFile*)inp;
7410 if (!in->IsOpen()) {
829455ad 7411 cerr<<"AliTPCtracker::ReadSeeds(): input file is not open !\n";
1c53abe2 7412 return 1;
7413 }
7414
7415 in->cd();
7416 TTree *seedTree=(TTree*)in->Get("Seeds");
7417 if (!seedTree) {
829455ad 7418 cerr<<"AliTPCtracker::ReadSeeds(): ";
1c53abe2 7419 cerr<<"can't get a tree with track seeds !\n";
7420 return 2;
7421 }
7422 AliTPCtrack *seed=new AliTPCtrack;
7423 seedTree->SetBranchAddress("tracks",&seed);
7424
7425 if (fSeeds==0) fSeeds=new TObjArray(15000);
7426
7427 Int_t n=(Int_t)seedTree->GetEntries();
7428 for (Int_t i=0; i<n; i++) {
7429 seedTree->GetEvent(i);
ddfbc51a 7430 AliTPCseed* sdc = new( NextFreeSeed() ) AliTPCseed(*seed/*,seed->GetAlpha()*/);
7431 sdc->SetPoolID(fLastSeedID);
f06a1ff6 7432 fSeeds->AddLast(sdc);
1c53abe2 7433 }
7434
f06a1ff6 7435 delete seed; // RS: this seed is not from the pool, delete it !!!
1c53abe2 7436 delete seedTree;
7437 savedir->cd();
7438 return 0;
7439}
7440
829455ad 7441Int_t AliTPCtracker::Clusters2TracksHLT (AliESDEvent *const esd, const AliESDEvent *hltEvent)
d26d9159 7442{
7443 //
544c295f 7444 // clusters to tracks
d9b8978b 7445 if (fSeeds) DeleteSeeds();
ddfbc51a 7446 else ResetSeedsPool();
e1dadcd0 7447 fEvent = esd;
72e25240 7448 fEventHLT = hltEvent;
65e67c9c 7449 if (AliTPCReconstructor::GetRecoParam()->GetUseOulierClusterFilter()) FilterOutlierClusters();
e1dadcd0 7450 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
7451 transform->SetCurrentTimeStamp( esd->GetTimeStamp());
7452 transform->SetCurrentRun(esd->GetRunNumber());
7453
65e67c9c 7454
d26d9159 7455 Clusters2Tracks();
72e25240 7456 fEventHLT = 0;
d26d9159 7457 if (!fSeeds) return 1;
7458 FillESD(fSeeds);
3e1f1ce7 7459 if ((AliTPCReconstructor::StreamLevel()&kStreamClDump)>0) DumpClusters(0,fSeeds);
d26d9159 7460 return 0;
7461 //
7462}
7463
829455ad 7464Int_t AliTPCtracker::Clusters2Tracks(AliESDEvent *const esd)
72e25240 7465{
7466 //
7467 // clusters to tracks
7468 return Clusters2TracksHLT( esd, 0);
7469}
d26d9159 7470
1c53abe2 7471//_____________________________________________________________________________
829455ad 7472Int_t AliTPCtracker::Clusters2Tracks() {
1c53abe2 7473 //-----------------------------------------------------------------
7474 // This is a track finder.
7475 //-----------------------------------------------------------------
91162307 7476 TDirectory *savedir=gDirectory;
1c53abe2 7477 TStopwatch timer;
d26d9159 7478
91162307 7479 fIteration = 0;
7480 fSeeds = Tracking();
1c53abe2 7481
6bdc18d6 7482 if (fDebug>0){
7483 Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
7484 }
91162307 7485 //activate again some tracks
7486 for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
7487 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7488 if (!pt) continue;
7489 Int_t nc=t.GetNumberOfClusters();
7490 if (nc<20) {
ddfbc51a 7491 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7492 continue;
eea478d3 7493 }
f5cbf2ef 7494 CookLabel(pt,0.1);
b9671574 7495 if (pt->GetRemoval()==10) {
91162307 7496 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
bad6eb00 7497 pt->Desactivate(10); // make track again active // MvL: should be 0 ?
91162307 7498 else{
7499 pt->Desactivate(20);
ddfbc51a 7500 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7501 }
7502 }
7503 }
51ad6848 7504 //
7505 RemoveUsed2(fSeeds,0.85,0.85,0);
a3232aae 7506 if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
6d493ea0 7507 //FindCurling(fSeeds, fEvent,0);
65e67c9c 7508 if (AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC) FindMultiMC(fSeeds, fEvent,-1); // find multi found tracks
81e97e0d 7509 RemoveUsed2(fSeeds,0.5,0.4,20);
1af5da7e 7510 FindSplitted(fSeeds, fEvent,0); // find multi found tracks
65e67c9c 7511 if (AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC) FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
6d493ea0 7512
81e97e0d 7513 // //
7514// // refit short tracks
7515// //
7516 Int_t nseed=fSeeds->GetEntriesFast();
1c53abe2 7517 //
91162307 7518 Int_t found = 0;
7519 for (Int_t i=0; i<nseed; i++) {
7520 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7521 if (!pt) continue;
7522 Int_t nc=t.GetNumberOfClusters();
7523 if (nc<15) {
ddfbc51a 7524 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7525 continue;
7526 }
7527 CookLabel(pt,0.1); //For comparison only
7528 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 7529 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
d9b8978b 7530 found++;
7531 if (fDebug>0) cerr<<found<<'\r';
b9671574 7532 pt->SetLab2(i);
91162307 7533 }
7534 else
ddfbc51a 7535 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7536 }
7537
7538
7539 //RemoveOverlap(fSeeds,0.99,7,kTRUE);
7540 SignShared(fSeeds);
7541 //RemoveUsed(fSeeds,0.9,0.9,6);
1c53abe2 7542 //
91162307 7543 nseed=fSeeds->GetEntriesFast();
7544 found = 0;
7545 for (Int_t i=0; i<nseed; i++) {
7546 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7547 if (!pt) continue;
7548 Int_t nc=t.GetNumberOfClusters();
7549 if (nc<15) {
ddfbc51a 7550 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7551 continue;
7552 }
7553 t.SetUniqueID(i);
7554 t.CookdEdx(0.02,0.6);
7555 // CheckKinkPoint(&t,0.05);
7556 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 7557 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6bdc18d6 7558 found++;
7559 if (fDebug>0){
7560 cerr<<found<<'\r';
7561 }
b9671574 7562 pt->SetLab2(i);
91162307 7563 }
7564 else
ddfbc51a 7565 MarkSeedFree( fSeeds->RemoveAt(i) );
d26d9159 7566 //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
7567 //if (seed1){
7568 // FollowProlongation(*seed1,0);
7569 // Int_t n = seed1->GetNumberOfClusters();
7570 // printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
7571 // printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
7572 //
7573 //}
7574 //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
7575
91162307 7576 }
7577
7578 SortTracks(fSeeds, 1);
1c53abe2 7579
982aff31 7580 /*
91162307 7581 fIteration = 1;
982aff31 7582 PrepareForBackProlongation(fSeeds,5.);
91162307 7583 PropagateBack(fSeeds);
7584 printf("Time for back propagation: \t");timer.Print();timer.Start();
7585
7586 fIteration = 2;
1c53abe2 7587
982aff31 7588 PrepareForProlongation(fSeeds,5.);
f124f8bf 7589 PropagateForard2(fSeeds);
d26d9159 7590
91162307 7591 printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
7592 // RemoveUsed(fSeeds,0.7,0.7,6);
7593 //RemoveOverlap(fSeeds,0.9,7,kTRUE);
d26d9159 7594
1c53abe2 7595 nseed=fSeeds->GetEntriesFast();
91162307 7596 found = 0;
7597 for (Int_t i=0; i<nseed; i++) {
1c53abe2 7598 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7599 if (!pt) continue;
7600 Int_t nc=t.GetNumberOfClusters();
91162307 7601 if (nc<15) {
ddfbc51a 7602 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7603 continue;
7604 }
1c53abe2 7605 t.CookdEdx(0.02,0.6);
91162307 7606 // CookLabel(pt,0.1); //For comparison only
7607 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
7608 if ((pt->IsActive() || (pt->fRemoval==10) )){
7609 cerr<<found++<<'\r';
7610 }
7611 else
ddfbc51a 7612 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7613 pt->fLab2 = i;
1c53abe2 7614 }
91162307 7615 */
7616
c9427e08 7617 // fNTracks = found;
6bdc18d6 7618 if (fDebug>0){
7619 Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
7620 }
91162307 7621 //
6bdc18d6 7622 // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
7623 Info("Clusters2Tracks","Number of found tracks %d",found);
91162307 7624 savedir->cd();
91162307 7625 // UnloadClusters();
d26d9159 7626 //
1c53abe2 7627 return 0;
7628}
7629
829455ad 7630void AliTPCtracker::Tracking(TObjArray * arr)
91162307 7631{
7632 //
7633 // tracking of the seeds
7634 //
7635
7636 fSectors = fOuterSec;
7637 ParallelTracking(arr,150,63);
7638 fSectors = fOuterSec;
7639 ParallelTracking(arr,63,0);
7640}
7641
829455ad 7642TObjArray * AliTPCtracker::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
91162307 7643{
7644 //
7645 //
7646 //tracking routine
f06a1ff6 7647 static TObjArray arrTracks;
7648 TObjArray * arr = &arrTracks;
91162307 7649 //
7650 fSectors = fOuterSec;
7651 TStopwatch timer;
7652 timer.Start();
7653 for (Int_t sec=0;sec<fkNOS;sec++){
7654 if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
7655 if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);
7656 if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
7657 }
7658 if (fDebug>0){
6bdc18d6 7659 Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
91162307 7660 timer.Print();
7661 timer.Start();
7662 }
7663 Tracking(arr);
7664 if (fDebug>0){
7665 timer.Print();
7666 }
7667
7668 return arr;
7669}
7670
829455ad 7671TObjArray * AliTPCtracker::Tracking()
91162307 7672{
544c295f 7673 // tracking
91162307 7674 //
a3232aae 7675 if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
91162307 7676 TStopwatch timer;
7677 timer.Start();
7678 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7679
7680 TObjArray * seeds = new TObjArray;
7681 TObjArray * arr=0;
6d1424d5 7682 Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
7683 Int_t gapPrim = AliTPCReconstructor::GetRecoParam()->GetSeedGapPrim();
7684 Int_t gapSec = AliTPCReconstructor::GetRecoParam()->GetSeedGapSec();
91162307 7685
7686 Int_t gap =20;
7687 Float_t cuts[4];
7688 cuts[0] = 0.002;
7689 cuts[1] = 1.5;
7690 cuts[2] = 3.;
7691 cuts[3] = 3.;
7692 Float_t fnumber = 3.0;
7693 Float_t fdensity = 3.0;
72e25240 7694
7695 // make HLT seeds
fa90aa2b 7696 if (AliTPCReconstructor::GetRecoParam()->GetUseHLTPreSeeding()) {
72e25240 7697 arr = MakeSeedsHLT( fEventHLT );
7698 if( arr ){
7699 SumTracks(seeds,arr);
7700 delete arr;
7701 arr=0;
7702 //cout<<"HLT tracks left after sorting: "<<seeds->GetEntriesFast()<<endl;
7703 //SignClusters(seeds,fnumber,fdensity);
7704 }
7705 }
91162307 7706
7707 //
7708 //find primaries
7709 cuts[0]=0.0066;
6d1424d5 7710 for (Int_t delta = 0; delta<18; delta+=gapPrim){
91162307 7711 //
7712 cuts[0]=0.0070;
7713 cuts[1] = 1.5;
7714 arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
7715 SumTracks(seeds,arr);
7716 SignClusters(seeds,fnumber,fdensity);
7717 //
7718 for (Int_t i=2;i<6;i+=2){
7719 // seed high pt tracks
7720 cuts[0]=0.0022;
7721 cuts[1]=0.3;
7722 arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
7723 SumTracks(seeds,arr);
7724 SignClusters(seeds,fnumber,fdensity);
7725 }
7726 }
7727 fnumber = 4;
7728 fdensity = 4.;
7729 // RemoveUsed(seeds,0.9,0.9,1);
7730 // UnsignClusters();
7731 // SignClusters(seeds,fnumber,fdensity);
7732
7733 //find primaries
7734 cuts[0]=0.0077;
6d1424d5 7735 for (Int_t delta = 20; delta<120; delta+=gapPrim){
91162307 7736 //
7737 // seed high pt tracks
7738 cuts[0]=0.0060;
7739 cuts[1]=0.3;
7740 cuts[2]=6.;
7741 arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
7742 SumTracks(seeds,arr);
7743 SignClusters(seeds,fnumber,fdensity);
7744
7745 cuts[0]=0.003;
7746 cuts[1]=0.3;
7747 cuts[2]=6.;
7748 arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
7749 SumTracks(seeds,arr);
7750 SignClusters(seeds,fnumber,fdensity);
7751 }
7752
7753 cuts[0] = 0.01;
7754 cuts[1] = 2.0;
7755 cuts[2] = 3.;
7756 cuts[3] = 2.0;
7757 fnumber = 2.;
7758 fdensity = 2.;
7759
7760 if (fDebug>0){
6bdc18d6 7761 Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 7762 timer.Print();
7763 timer.Start();
7764 }
7765 // RemoveUsed(seeds,0.75,0.75,1);
7766 //UnsignClusters();
7767 //SignClusters(seeds,fnumber,fdensity);
7768
7769 // find secondaries
7770
7771 cuts[0] = 0.3;
7772 cuts[1] = 1.5;
7773 cuts[2] = 3.;
7774 cuts[3] = 1.5;
7775
7776 arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
7777 SumTracks(seeds,arr);
7778 SignClusters(seeds,fnumber,fdensity);
7779 //
7780 arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
7781 SumTracks(seeds,arr);
7782 SignClusters(seeds,fnumber,fdensity);
7783 //
7784 arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
7785 SumTracks(seeds,arr);
7786 SignClusters(seeds,fnumber,fdensity);
7787 //
6d1424d5 7788 arr = Tracking(4,nup-5,nup-5-gap,cuts,-1);
7789 SumTracks(seeds,arr);
7790 SignClusters(seeds,fnumber,fdensity);
7791 //
7792 arr = Tracking(4,nup-7,nup-7-gap,cuts,-1);
7793 SumTracks(seeds,arr);
7794 SignClusters(seeds,fnumber,fdensity);
7795 //
7796 //
7797 arr = Tracking(4,nup-9,nup-9-gap,cuts,-1);
7798 SumTracks(seeds,arr);
7799 SignClusters(seeds,fnumber,fdensity);
7800 //
91162307 7801
7802
6d1424d5 7803 for (Int_t delta = 9; delta<30; delta+=gapSec){
91162307 7804 //
7805 cuts[0] = 0.3;
7806 cuts[1] = 1.5;
7807 cuts[2] = 3.;
7808 cuts[3] = 1.5;
7809 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7810 SumTracks(seeds,arr);
7811 SignClusters(seeds,fnumber,fdensity);
7812 //
7813 arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
7814 SumTracks(seeds,arr);
7815 SignClusters(seeds,fnumber,fdensity);
7816 //
7817 }
7818 fnumber = 1;
7819 fdensity = 1;
7820 //
7821 // change cuts
7822 fnumber = 2.;
7823 fdensity = 2.;
7824 cuts[0]=0.0080;
7825
7d27c1df 7826
91162307 7827 // find secondaries
6d1424d5 7828 for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=gapSec){
91162307 7829 //
7830 cuts[0] = 0.3;
2bd61959 7831 cuts[1] = 3.5;
91162307 7832 cuts[2] = 3.;
2bd61959 7833 cuts[3] = 3.5;
91162307 7834 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7835 SumTracks(seeds,arr);
7836 SignClusters(seeds,fnumber,fdensity);
7837 //
7838 arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
7839 SumTracks(seeds,arr);
7840 SignClusters(seeds,fnumber,fdensity);
7841 }
7842
7843 if (fDebug>0){
6bdc18d6 7844 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 7845 timer.Print();
7846 timer.Start();
7847 }
7848
7849 return seeds;
7850 //
7851
7852}
7853
7854
829455ad 7855TObjArray * AliTPCtracker::TrackingSpecial()
a3232aae 7856{
7857 //
7858 // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
7859 // no primary vertex seeding tried
7860 //
7861 TStopwatch timer;
7862 timer.Start();
7863 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7864
7865 TObjArray * seeds = new TObjArray;
7866 TObjArray * arr=0;
7867
7868 Int_t gap = 15;
7869 Float_t cuts[4];
7870 Float_t fnumber = 3.0;
7871 Float_t fdensity = 3.0;
7872
7873 // find secondaries
7874 cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC(); // max curvature
7875 cuts[1] = 3.5; // max tan(phi) angle for seeding
7876 cuts[2] = 3.; // not used (cut on z primary vertex)
7877 cuts[3] = 3.5; // max tan(theta) angle for seeding
7878
7879 for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
7880 //
7881 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7882 SumTracks(seeds,arr);
7883 SignClusters(seeds,fnumber,fdensity);
7884 }
7885
7886 if (fDebug>0){
7887 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
7888 timer.Print();
7889 timer.Start();
7890 }
7891
7892 return seeds;
7893 //
7894
7895}
7896
7897
829455ad 7898void AliTPCtracker::SumTracks(TObjArray *arr1,TObjArray *&arr2)
91162307 7899{
7900 //
7901 //sum tracks to common container
7902 //remove suspicious tracks
f06a1ff6 7903 // RS: Attention: supplied tracks come in the static array, don't delete them
91162307 7904 Int_t nseed = arr2->GetEntriesFast();
7905 for (Int_t i=0;i<nseed;i++){
7906 AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);
7907 if (pt){
a3232aae 7908 //
7909 // remove tracks with too big curvature
7910 //
7911 if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
ddfbc51a 7912 MarkSeedFree( arr2->RemoveAt(i) );
a3232aae 7913 continue;
7914 }
ca142b1f 7915 // REMOVE VERY SHORT TRACKS
7916 if (pt->GetNumberOfClusters()<20){
ddfbc51a 7917 MarkSeedFree( arr2->RemoveAt(i) );
ca142b1f 7918 continue;
7919 }// patch 28 fev06
91162307 7920 // NORMAL ACTIVE TRACK
7921 if (pt->IsActive()){
7922 arr1->AddLast(arr2->RemoveAt(i));
7923 continue;
7924 }
7925 //remove not usable tracks
b9671574 7926 if (pt->GetRemoval()!=10){
ddfbc51a 7927 MarkSeedFree( arr2->RemoveAt(i) );
91162307 7928 continue;
7929 }
ca142b1f 7930
91162307 7931 // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
7932 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
7933 arr1->AddLast(arr2->RemoveAt(i));
7934 else{
ddfbc51a 7935 MarkSeedFree( arr2->RemoveAt(i) );
91162307 7936 }
7937 }
7938 }
f06a1ff6 7939 // delete arr2; arr2 = 0; // RS: this is static array, don't delete it
91162307 7940}
7941
7942
1c53abe2 7943
829455ad 7944void AliTPCtracker::ParallelTracking(TObjArray *const arr, Int_t rfirst, Int_t rlast)
1c53abe2 7945{
7946 //
7947 // try to track in parralel
7948
91162307 7949 Int_t nseed=arr->GetEntriesFast();
1c53abe2 7950 //prepare seeds for tracking
7951 for (Int_t i=0; i<nseed; i++) {
91162307 7952 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 7953 if (!pt) continue;
7954 if (!t.IsActive()) continue;
7955 // follow prolongation to the first layer
47af7ca4 7956 if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fkParam->GetNRowLow()>rfirst+1) )
c9427e08 7957 FollowProlongation(t, rfirst+1);
1c53abe2 7958 }
7959
7960
7961 //
982aff31 7962 for (Int_t nr=rfirst; nr>=rlast; nr--){
7963 if (nr<fInnerSec->GetNRows())
7964 fSectors = fInnerSec;
7965 else
7966 fSectors = fOuterSec;
1c53abe2 7967 // make indexes with the cluster tracks for given
1c53abe2 7968
7969 // find nearest cluster
7970 for (Int_t i=0; i<nseed; i++) {
91162307 7971 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 7972 if (!pt) continue;
51ad6848 7973 if (nr==80) pt->UpdateReference();
1c53abe2 7974 if (!pt->IsActive()) continue;
47af7ca4 7975 // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
b9671574 7976 if (pt->GetRelativeSector()>17) {
1627d1c4 7977 continue;
7978 }
91162307 7979 UpdateClusters(t,nr);
1c53abe2 7980 }
7981 // prolonagate to the nearest cluster - if founded
7982 for (Int_t i=0; i<nseed; i++) {
91162307 7983 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
1c53abe2 7984 if (!pt) continue;
1627d1c4 7985 if (!pt->IsActive()) continue;
47af7ca4 7986 // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
b9671574 7987 if (pt->GetRelativeSector()>17) {
1627d1c4 7988 continue;
7989 }
91162307 7990 FollowToNextCluster(*pt,nr);
1c53abe2 7991 }
91162307 7992 }
7993}
7994
829455ad 7995void AliTPCtracker::PrepareForBackProlongation(const TObjArray *const arr,Float_t fac) const
91162307 7996{
7997 //
7998 //
7999 // if we use TPC track itself we have to "update" covariance
8000 //
8001 Int_t nseed= arr->GetEntriesFast();
8002 for (Int_t i=0;i<nseed;i++){
8003 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
8004 if (pt) {
8005 pt->Modify(fac);
8006 //
8007 //rotate to current local system at first accepted point
b9671574 8008 Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
91162307 8009 Int_t sec = (index&0xff000000)>>24;
8010 sec = sec%18;
8011 Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
8012 if (angle1>TMath::Pi())
8013 angle1-=2.*TMath::Pi();
8014 Float_t angle2 = pt->GetAlpha();
8015
8016 if (TMath::Abs(angle1-angle2)>0.001){
17abbffb 8017 if (!pt->Rotate(angle1-angle2)) return;
91162307 8018 //angle2 = pt->GetAlpha();
8019 //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
8020 //if (pt->GetAlpha()<0)
8021 // pt->fRelativeSector+=18;
8022 //sec = pt->fRelativeSector;
8023 }
8024
8025 }
8026
8027 }
8028
8029
8030}
829455ad 8031void AliTPCtracker::PrepareForProlongation(TObjArray *const arr, Float_t fac) const
91162307 8032{
8033 //
8034 //
8035 // if we use TPC track itself we have to "update" covariance
8036 //
8037 Int_t nseed= arr->GetEntriesFast();
8038 for (Int_t i=0;i<nseed;i++){
8039 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
8040 if (pt) {
8041 pt->Modify(fac);
b9671574 8042 pt->SetFirstPoint(pt->GetLastPoint());
91162307 8043 }
8044
8045 }
8046
8047
8048}
8049
829455ad 8050Int_t AliTPCtracker::PropagateBack(const TObjArray *const arr)
91162307 8051{
8052 //
8053 // make back propagation
8054 //
8055 Int_t nseed= arr->GetEntriesFast();
8056 for (Int_t i=0;i<nseed;i++){
8057 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
51ad6848 8058 if (pt&& pt->GetKinkIndex(0)<=0) {
d9b8978b 8059 //AliTPCseed *pt2 = new AliTPCseed(*pt);
91162307 8060 fSectors = fInnerSec;
d26d9159 8061 //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
8062 //fSectors = fOuterSec;
f124f8bf 8063 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
4d158c36 8064 //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
d9b8978b 8065 // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
4d158c36 8066 // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
d9b8978b 8067 //}
51ad6848 8068 }
8069 if (pt&& pt->GetKinkIndex(0)>0) {
8070 AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
b9671574 8071 pt->SetFirstPoint(kink->GetTPCRow0());
51ad6848 8072 fSectors = fInnerSec;
f124f8bf 8073 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
51ad6848 8074 }
6d493ea0 8075 CookLabel(pt,0.3);
91162307 8076 }
8077 return 0;
8078}
8079
8080
829455ad 8081Int_t AliTPCtracker::PropagateForward2(const TObjArray *const arr)
91162307 8082{
8083 //
8084 // make forward propagation
8085 //
8086 Int_t nseed= arr->GetEntriesFast();
4d158c36 8087 //
91162307 8088 for (Int_t i=0;i<nseed;i++){
8089 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
8090 if (pt) {
f124f8bf 8091 FollowProlongation(*pt,0,1,1);
6d493ea0 8092 CookLabel(pt,0.3);
4d158c36 8093 }
6d493ea0 8094
91162307 8095 }
f124f8bf 8096 return 0;
91162307 8097}
8098
8099
829455ad 8100Int_t AliTPCtracker::PropagateForward()
91162307 8101{
b67e07dc 8102 //
8103 // propagate track forward
4d158c36 8104 //UnsignClusters();
d26d9159 8105 Int_t nseed = fSeeds->GetEntriesFast();
8106 for (Int_t i=0;i<nseed;i++){
8107 AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
8108 if (pt){
8109 AliTPCseed &t = *pt;
8110 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
8111 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
8112 if (alpha < 0. ) alpha += 2.*TMath::Pi();
b9671574 8113 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
d26d9159 8114 }
8115 }
8116
91162307 8117 fSectors = fOuterSec;
d26d9159 8118 ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
91162307 8119 fSectors = fInnerSec;
d26d9159 8120 ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
91162307 8121 return 1;
8122}
8123
8124
8125
8126
8127
8128
829455ad 8129Int_t AliTPCtracker::PropagateBack(AliTPCseed *const pt, Int_t row0, Int_t row1)
91162307 8130{
8131 //
8132 // make back propagation, in between row0 and row1
8133 //
1c53abe2 8134
91162307 8135 if (pt) {
8136 fSectors = fInnerSec;
8137 Int_t r1;
8138 //
8139 if (row1<fSectors->GetNRows())
8140 r1 = row1;
8141 else
8142 r1 = fSectors->GetNRows()-1;
8143
8144 if (row0<fSectors->GetNRows()&& r1>0 )
8145 FollowBackProlongation(*pt,r1);
8146 if (row1<=fSectors->GetNRows())
8147 return 0;
8148 //
8149 r1 = row1 - fSectors->GetNRows();
8150 if (r1<=0) return 0;
8151 if (r1>=fOuterSec->GetNRows()) return 0;
8152 fSectors = fOuterSec;
8153 return FollowBackProlongation(*pt,r1);
8154 }
8155 return 0;
8156}
8157
8158
8159
8160
829455ad 8161void AliTPCtracker::GetShape(AliTPCseed * seed, Int_t row)
91162307 8162{
544c295f 8163 // gets cluster shape
fd065ea2 8164 //
8165 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
47af7ca4 8166 Float_t zdrift = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())));
8167 Int_t type = (seed->GetSector() < fkParam->GetNSector()/2) ? 0: (row>126) ? 1:2;
3f82c4f2 8168 Double_t angulary = seed->GetSnp();
feed67f9 8169
8170 if (TMath::Abs(angulary)>AliTPCReconstructor::GetMaxSnpTracker()) {
8171 angulary = TMath::Sign(AliTPCReconstructor::GetMaxSnpTracker(),angulary);
8172 }
8173
bfd20868 8174 angulary = angulary*angulary/((1.-angulary)*(1.+angulary));
fd065ea2 8175 Double_t angularz = seed->GetTgl()*seed->GetTgl()*(1.+angulary);
8176
e0e13b88 8177 Double_t sigmay = clparam->GetRMS0(0,type,zdrift,TMath::Sqrt(TMath::Abs(angulary)));
8178 Double_t sigmaz = clparam->GetRMS0(1,type,zdrift,TMath::Sqrt(TMath::Abs(angularz)));
fd065ea2 8179 seed->SetCurrentSigmaY2(sigmay*sigmay);
8180 seed->SetCurrentSigmaZ2(sigmaz*sigmaz);
47af7ca4 8181 // Float_t sd2 = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fkParam->GetDiffL()*fkParam->GetDiffL();
8182// // Float_t padlength = fkParam->GetPadPitchLength(seed->fSector);
fd065ea2 8183// Float_t padlength = GetPadPitchLength(row);
8184// //
47af7ca4 8185// Float_t sresy = (seed->GetSector() < fkParam->GetNSector()/2) ? 0.2 :0.3;
fd065ea2 8186// seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
8187// //
47af7ca4 8188// Float_t sresz = fkParam->GetZSigma();
fd065ea2 8189// seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
91162307 8190 /*
8191 Float_t wy = GetSigmaY(seed);
8192 Float_t wz = GetSigmaZ(seed);
8193 wy*=wy;
8194 wz*=wz;
8195 if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
8196 printf("problem\n");
8197 }
8198 */
1c53abe2 8199}
8200
91162307 8201
1c53abe2 8202
1c53abe2 8203//__________________________________________________________________________
829455ad 8204void AliTPCtracker::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
1c53abe2 8205 //--------------------------------------------------------------------
8206 //This function "cooks" a track label. If label<0, this track is fake.
8207 //--------------------------------------------------------------------
316c6cd9 8208 AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
8209 if(!t){
8210 printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
8211 return;
8212 }
8213
1c53abe2 8214 Int_t noc=t->GetNumberOfClusters();
91162307 8215 if (noc<10){
d26d9159 8216 //printf("\nnot founded prolongation\n\n\n");
8217 //t->Dump();
91162307 8218 return ;
8219 }
8220 Int_t lb[160];
8221 Int_t mx[160];
8222 AliTPCclusterMI *clusters[160];
8223 //
8224 for (Int_t i=0;i<160;i++) {
8225 clusters[i]=0;
8226 lb[i]=mx[i]=0;
8227 }
1c53abe2 8228
8229 Int_t i;
91162307 8230 Int_t current=0;
8231 for (i=0; i<160 && current<noc; i++) {
8232
8233 Int_t index=t->GetClusterIndex2(i);
8234 if (index<=0) continue;
8235 if (index&0x8000) continue;
8236 //
8237 //clusters[current]=GetClusterMI(index);
b9671574 8238 if (t->GetClusterPointer(i)){
8239 clusters[current]=t->GetClusterPointer(i);
91162307 8240 current++;
8241 }
1c53abe2 8242 }
91162307 8243 noc = current;
1c53abe2 8244
8245 Int_t lab=123456789;
8246 for (i=0; i<noc; i++) {
8247 AliTPCclusterMI *c=clusters[i];
91162307 8248 if (!c) continue;
1c53abe2 8249 lab=TMath::Abs(c->GetLabel(0));
8250 Int_t j;
8251 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
8252 lb[j]=lab;
8253 (mx[j])++;
8254 }
8255
8256 Int_t max=0;
8257 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
8258
8259 for (i=0; i<noc; i++) {
9918f10a 8260 AliTPCclusterMI *c=clusters[i];
91162307 8261 if (!c) continue;
1c53abe2 8262 if (TMath::Abs(c->GetLabel(1)) == lab ||
8263 TMath::Abs(c->GetLabel(2)) == lab ) max++;
8264 }
52033b55 8265 if (noc<=0) { lab=-1; return;}
8266 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
1c53abe2 8267
8268 else {
8269 Int_t tail=Int_t(0.10*noc);
8270 max=0;
91162307 8271 Int_t ind=0;
ec26e231 8272 for (i=1; i<160&&ind<tail; i++) {
91162307 8273 // AliTPCclusterMI *c=clusters[noc-i];
8274 AliTPCclusterMI *c=clusters[i];
8275 if (!c) continue;
1c53abe2 8276 if (lab == TMath::Abs(c->GetLabel(0)) ||
8277 lab == TMath::Abs(c->GetLabel(1)) ||
8278 lab == TMath::Abs(c->GetLabel(2))) max++;
91162307 8279 ind++;
1c53abe2 8280 }
8281 if (max < Int_t(0.5*tail)) lab=-lab;
8282 }
8283
8284 t->SetLabel(lab);
8285
91162307 8286 // delete[] lb;
8287 //delete[] mx;
8288 //delete[] clusters;
1c53abe2 8289}
8290
47966a6d 8291
51ad6848 8292//__________________________________________________________________________
829455ad 8293Int_t AliTPCtracker::CookLabel(AliTPCseed *const t, Float_t wrong,Int_t first, Int_t last) const {
51ad6848 8294 //--------------------------------------------------------------------
8295 //This function "cooks" a track label. If label<0, this track is fake.
8296 //--------------------------------------------------------------------
8297 Int_t noc=t->GetNumberOfClusters();
8298 if (noc<10){
8299 //printf("\nnot founded prolongation\n\n\n");
8300 //t->Dump();
8301 return -1;
8302 }
8303 Int_t lb[160];
8304 Int_t mx[160];
8305 AliTPCclusterMI *clusters[160];
8306 //
8307 for (Int_t i=0;i<160;i++) {
8308 clusters[i]=0;
8309 lb[i]=mx[i]=0;
8310 }
8311
8312 Int_t i;
8313 Int_t current=0;
8314 for (i=0; i<160 && current<noc; i++) {
8315 if (i<first) continue;
8316 if (i>last) continue;
8317 Int_t index=t->GetClusterIndex2(i);
8318 if (index<=0) continue;
8319 if (index&0x8000) continue;
8320 //
8321 //clusters[current]=GetClusterMI(index);
b9671574 8322 if (t->GetClusterPointer(i)){
8323 clusters[current]=t->GetClusterPointer(i);
51ad6848 8324 current++;
8325 }
8326 }
8327 noc = current;
17abbffb 8328 //if (noc<5) return -1;
51ad6848 8329 Int_t lab=123456789;
8330 for (i=0; i<noc; i++) {
8331 AliTPCclusterMI *c=clusters[i];
8332 if (!c) continue;
8333 lab=TMath::Abs(c->GetLabel(0));
8334 Int_t j;
8335 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
8336 lb[j]=lab;
8337 (mx[j])++;
8338 }
8339
8340 Int_t max=0;
8341 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
8342
8343 for (i=0; i<noc; i++) {
8344 AliTPCclusterMI *c=clusters[i];
8345 if (!c) continue;
8346 if (TMath::Abs(c->GetLabel(1)) == lab ||
8347 TMath::Abs(c->GetLabel(2)) == lab ) max++;
8348 }
52033b55 8349 if (noc<=0) { lab=-1; return -1;}
8350 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
51ad6848 8351
8352 else {
8353 Int_t tail=Int_t(0.10*noc);
8354 max=0;
8355 Int_t ind=0;
ec26e231 8356 for (i=1; i<160&&ind<tail; i++) {
51ad6848 8357 // AliTPCclusterMI *c=clusters[noc-i];
8358 AliTPCclusterMI *c=clusters[i];
8359 if (!c) continue;
8360 if (lab == TMath::Abs(c->GetLabel(0)) ||
8361 lab == TMath::Abs(c->GetLabel(1)) ||
8362 lab == TMath::Abs(c->GetLabel(2))) max++;
8363 ind++;
8364 }
8365 if (max < Int_t(0.5*tail)) lab=-lab;
8366 }
8367
8368 // t->SetLabel(lab);
8369 return lab;
8370 // delete[] lb;
8371 //delete[] mx;
8372 //delete[] clusters;
8373}
8374
8375
829455ad 8376Int_t AliTPCtracker::GetRowNumber(Double_t x[3]) const
eea478d3 8377{
8378 //return pad row number for given x vector
8379 Float_t phi = TMath::ATan2(x[1],x[0]);
8380 if(phi<0) phi=2.*TMath::Pi()+phi;
8381 // Get the local angle in the sector philoc
8382 const Float_t kRaddeg = 180/3.14159265358979312;
8383 Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
8384 Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
8385 return GetRowNumber(localx);
8386}
8387
91162307 8388
91162307 8389
829455ad 8390void AliTPCtracker::MakeESDBitmaps(AliTPCseed *t, AliESDtrack *esd)
19b00333 8391{
8392 //-----------------------------------------------------------------------
8393 // Fill the cluster and sharing bitmaps of the track
8394 //-----------------------------------------------------------------------
8395
8396 Int_t firstpoint = 0;
8397 Int_t lastpoint = 159;
8398 AliTPCTrackerPoint *point;
52c51057 8399 AliTPCclusterMI *cluster;
19b00333 8400
bad6eb00 8401 Int_t nclsf = 0;
8402 TBits clusterMap(159);
8403 TBits sharedMap(159);
8404 TBits fitMap(159);
19b00333 8405 for (int iter=firstpoint; iter<lastpoint; iter++) {
52c51057 8406 // Change to cluster pointers to see if we have a cluster at given padrow
bad6eb00 8407
52c51057 8408 cluster = t->GetClusterPointer(iter);
8409 if (cluster) {
bad6eb00 8410 clusterMap.SetBitNumber(iter, kTRUE);
52c51057 8411 point = t->GetTrackPoint(iter);
19b00333 8412 if (point->IsShared())
bad6eb00 8413 sharedMap.SetBitNumber(iter,kTRUE);
19b00333 8414 }
bad6eb00 8415 if (t->GetClusterIndex(iter) >= 0 && (t->GetClusterIndex(iter) & 0x8000) == 0) {
8416 fitMap.SetBitNumber(iter, kTRUE);
8417 nclsf++;
19b00333 8418 }
8419 }
bad6eb00 8420 esd->SetTPCClusterMap(clusterMap);
8421 esd->SetTPCSharedMap(sharedMap);
8422 esd->SetTPCFitMap(fitMap);
8423 if (nclsf != t->GetNumberOfClusters())
27540e35 8424 AliDebug(3,Form("Inconsistency between ncls %d and indices %d (found %d)",t->GetNumberOfClusters(),nclsf,esd->GetTPCClusterMap().CountBits()));
19b00333 8425}
92f513f5 8426
829455ad 8427Bool_t AliTPCtracker::IsFindable(AliTPCseed & track){
76d56fd6 8428 //
8429 // return flag if there is findable cluster at given position
8430 //
8431 Float_t kDeltaZ=10;
8432 Float_t z = track.GetZ();
8433
8434 if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*track.GetX()+kDeltaZ) &&
47af7ca4 8435 TMath::Abs(z)<fkParam->GetZLength(0) &&
76d56fd6 8436 (TMath::Abs(track.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
8437 return kTRUE;
8438 return kFALSE;
8439}
92f513f5 8440
8441
829455ad 8442void AliTPCtracker::AddCovariance(AliTPCseed * seed){
92f513f5 8443 //
e1dadcd0 8444 // Adding systematic error estimate to the covariance matrix
b87c2bbc 8445 // !!!! the systematic error for element 4 is in 1/GeV
8446 // 03.03.2012 MI changed in respect to the previous versions
e1dadcd0 8447 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
8448 //
8449 // use only the diagonal part if not specified otherwise
8450 if (!AliTPCReconstructor::GetRecoParam()->GetUseSystematicCorrelation()) return AddCovarianceAdd(seed);
8451 //
8452 Double_t *covarS= (Double_t*)seed->GetCovariance();
8453 Double_t factor[5]={1,1,1,1,1};
e1dadcd0 8454 factor[0]= TMath::Sqrt(TMath::Abs((covarS[0] + param[0]*param[0])/covarS[0]));
8455 factor[1]= TMath::Sqrt(TMath::Abs((covarS[2] + param[1]*param[1])/covarS[2]));
8456 factor[2]= TMath::Sqrt(TMath::Abs((covarS[5] + param[2]*param[2])/covarS[5]));
8457 factor[3]= TMath::Sqrt(TMath::Abs((covarS[9] + param[3]*param[3])/covarS[9]));
b87c2bbc 8458 factor[4]= TMath::Sqrt(TMath::Abs((covarS[14] +param[4]*param[4])/covarS[14]));
9b550f87 8459 //
8460 factor[0]=factor[2];
8461 factor[4]=factor[2];
e1dadcd0 8462 // 0
8463 // 1 2
8464 // 3 4 5
8465 // 6 7 8 9
8466 // 10 11 12 13 14
8467 for (Int_t i=0; i<5; i++){
8468 for (Int_t j=i; j<5; j++){
8469 Int_t index=seed->GetIndex(i,j);
8470 covarS[index]*=factor[i]*factor[j];
8471 }
8472 }
8473}
8474
92f513f5 8475
829455ad 8476void AliTPCtracker::AddCovarianceAdd(AliTPCseed * seed){
e1dadcd0 8477 //
8478 // Adding systematic error - as additive factor without correlation
8479 //
b87c2bbc 8480 // !!!! the systematic error for element 4 is in 1/GeV
8481 // 03.03.2012 MI changed in respect to the previous versions
8482
92f513f5 8483 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
f47588e0 8484 Double_t *covarIn= (Double_t*)seed->GetCovariance();
92f513f5 8485 Double_t covar[15];
8486 for (Int_t i=0;i<15;i++) covar[i]=0;
8487 // 0
8488 // 1 2
8489 // 3 4 5
8490 // 6 7 8 9
8491 // 10 11 12 13 14
8492 covar[0] = param[0]*param[0];
8493 covar[2] = param[1]*param[1];
8494 covar[5] = param[2]*param[2];
8495 covar[9] = param[3]*param[3];
b87c2bbc 8496 covar[14]= param[4]*param[4];
f47588e0 8497 //
8498 covar[1]=TMath::Sqrt((covar[0]*covar[2]))*covarIn[1]/TMath::Sqrt((covarIn[0]*covarIn[2]));
8499 //
8500 covar[3]=TMath::Sqrt((covar[0]*covar[5]))*covarIn[3]/TMath::Sqrt((covarIn[0]*covarIn[5]));
8501 covar[4]=TMath::Sqrt((covar[2]*covar[5]))*covarIn[4]/TMath::Sqrt((covarIn[2]*covarIn[5]));
8502 //
8503 covar[6]=TMath::Sqrt((covar[0]*covar[9]))*covarIn[6]/TMath::Sqrt((covarIn[0]*covarIn[9]));
8504 covar[7]=TMath::Sqrt((covar[2]*covar[9]))*covarIn[7]/TMath::Sqrt((covarIn[2]*covarIn[9]));
8505 covar[8]=TMath::Sqrt((covar[5]*covar[9]))*covarIn[8]/TMath::Sqrt((covarIn[5]*covarIn[9]));
8506 //
8507 covar[10]=TMath::Sqrt((covar[0]*covar[14]))*covarIn[10]/TMath::Sqrt((covarIn[0]*covarIn[14]));
8508 covar[11]=TMath::Sqrt((covar[2]*covar[14]))*covarIn[11]/TMath::Sqrt((covarIn[2]*covarIn[14]));
8509 covar[12]=TMath::Sqrt((covar[5]*covar[14]))*covarIn[12]/TMath::Sqrt((covarIn[5]*covarIn[14]));
8510 covar[13]=TMath::Sqrt((covar[9]*covar[14]))*covarIn[13]/TMath::Sqrt((covarIn[9]*covarIn[14]));
8511 //
92f513f5 8512 seed->AddCovariance(covar);
8513}
f06a1ff6 8514
ec7e4ad6 8515//_____________________________________________________________________________
829455ad 8516Bool_t AliTPCtracker::IsTPCHVDipEvent(AliESDEvent const *esdEvent)
661f340b 8517{
8518 //
8519 // check events affected by TPC HV dip
8520 //
8521 if(!esdEvent) return kFALSE;
ec7e4ad6 8522
661f340b 8523 // Init TPC OCDB
8524 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
8525 if(!db) return kFALSE;
8526 db->SetRun(esdEvent->GetRunNumber());
ec7e4ad6 8527
661f340b 8528 // maximum allowed voltage before an event is identified as a dip event
8529 // and scanning period
8530 const Double_t kTPCHVdip = db->GetParameters()->GetMaxDipVoltage();
8531 const Double_t dipEventScanPeriod = db->GetParameters()->GetVoltageDipScanPeriod();
8532 const Double_t tevSec = esdEvent->GetTimeStamp();
8533
ec7e4ad6 8534 for(Int_t sector=0; sector<72; sector++)
8535 {
661f340b 8536 // don't use excluded chambers, since the state is not defined at all
8537 if (!db->GetChamberHVStatus(sector)) continue;
8538
8539 // get hv sensor of the chamber
8540 AliDCSSensor *sensor = db->GetChamberHVSensor(sector);
8541 if (!sensor) continue;
8542 TGraph *grSensor=sensor->GetGraph();
8543 if (!grSensor) continue;
8544 if (grSensor->GetN()<1) continue;
ec7e4ad6 8545
661f340b 8546 // get median
8547 const Double_t median = db->GetChamberHighVoltageMedian(sector);
8548 if(median < 1.) continue;
ec7e4ad6 8549
661f340b 8550 for (Int_t ipoint=0; ipoint<grSensor->GetN()-1; ++ipoint){
8551 Double_t nextTime=grSensor->GetX()[ipoint+1]*3600+sensor->GetStartTime();
8552 if (tevSec-dipEventScanPeriod>nextTime) continue;
8553 const Float_t deltaV=TMath::Abs(grSensor->GetY()[ipoint]-median);
8554 if (deltaV>kTPCHVdip) {
8555 AliDebug(3,Form("HV dip detected in ROC '%02d' with dV '%.2f' at time stamp '%.0f'",sector,deltaV,tevSec));
8556 return kTRUE;
8557 }
8558 if (nextTime>tevSec+dipEventScanPeriod) break;
ec7e4ad6 8559 }
661f340b 8560 }
8561
8562 return kFALSE;
8563}
ddfbc51a 8564
8565//________________________________________
829455ad 8566void AliTPCtracker::MarkSeedFree(TObject *sd)
ddfbc51a 8567{
8568 // account that this seed is "deleted"
8569 AliTPCseed* seed = dynamic_cast<AliTPCseed*>(sd);
88492b27 8570 if (!seed) {
b6565e28 8571 AliError(Form("Freeing of non-AliTPCseed %p from the pool is requested",sd));
8572 return;
8573 }
88492b27 8574 int id = seed->GetPoolID();
b6565e28 8575 if (id<0) {
8576 AliError(Form("Freeing of seed %p NOT from the pool is requested",sd));
8577 return;
8578 }
ddfbc51a 8579 // AliInfo(Form("%d %p",id, seed));
8580 fSeedsPool->RemoveAt(id);
8581 if (fFreeSeedsID.GetSize()<=fNFreeSeeds) fFreeSeedsID.Set( 2*fNFreeSeeds + 100 );
8582 fFreeSeedsID.GetArray()[fNFreeSeeds++] = id;
8583}
8584
8585//________________________________________
829455ad 8586TObject *&AliTPCtracker::NextFreeSeed()
ddfbc51a 8587{
8588 // return next free slot where the seed can be created
8589 fLastSeedID = fNFreeSeeds ? fFreeSeedsID.GetArray()[--fNFreeSeeds] : fSeedsPool->GetEntriesFast();
8590 // AliInfo(Form("%d",fLastSeedID));
8591 return (*fSeedsPool)[ fLastSeedID ];
8592 //
8593}
8594
8595//________________________________________
829455ad 8596void AliTPCtracker::ResetSeedsPool()
ddfbc51a 8597{
8598 // mark all seeds in the pool as unused
8599 AliInfo(Form("CurrentSize: %d, BookedUpTo: %d, free: %d",fSeedsPool->GetSize(),fSeedsPool->GetEntriesFast(),fNFreeSeeds));
8600 fNFreeSeeds = 0;
8601 fSeedsPool->Clear("C"); // RS: nominally the seeds may allocate memory...
8602}
72e25240 8603
829455ad 8604Int_t AliTPCtracker::PropagateToRowHLT(AliTPCseed *pt, int nrow)
72e25240 8605{
8606 AliTPCseed &t=*pt;
8607 Double_t x= GetXrow(nrow);
8608 Double_t ymax= GetMaxY(nrow);
8609 Int_t rotate = 0;
8610 Int_t nRotations=0;
8611 int ret = 1;
8612 do{
8613 rotate = 0;
8614 if (!t.PropagateTo(x) ){
8615 //cout<<"can't propagate to row "<<nrow<<", x="<<t.GetX()<<" -> "<<x<<endl;
8616 //t.Print();
8617 ret = 0;
8618 break;
8619 }
8620 t.SetRow(nrow);
8621 Double_t y = t.GetY();
8622 if( y > ymax ) {
8623 if( rotate!=-1 ) rotate=1;
8624 } else if (y <-ymax) {
8625 if( rotate!=1 ) rotate = -1;
8626 }
8627 if( rotate==0 ) break;
8628 //cout<<"rotate at row "<<nrow<<": "<<rotate<<endl;
8629 if (!t.Rotate( rotate==1 ?fSectors->GetAlpha() :-fSectors->GetAlpha())) {
8630 //cout<<"can't rotate "<<endl;
8631 ret=0;
8632 break;
8633 }
8634 nRotations+= rotate;
8635 }while(rotate!=0);
8636 if( nRotations!=0 ){
8637 int newSec= t.GetRelativeSector()+nRotations;
8638 if( newSec>=fN ) newSec-=fN;
8639 else if( newSec<0 ) newSec +=fN;
8640 //cout<<"rotate at row "<<nrow<<": "<<nRotations<<" times "<<" sec "
8641 //<< t.GetRelativeSector()<<" -> "<<newSec<<endl;
8642 t.SetRelativeSector(newSec);
8643 }
8644 return ret;
8645}
8646
829455ad 8647void AliTPCtracker::TrackFollowingHLT(TObjArray *const arr )
72e25240 8648{
8649 //
8650 // try to track in parralel
8651
8652 Int_t nRows=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8653 fSectors=fInnerSec;
8654
8655 Int_t nseed=arr->GetEntriesFast();
8656 //cout<<"Parallel tracking My.."<<endl;
8657 double shapeY2[160], shapeZ2[160];
8658 Int_t clusterIndex[160];
8659
8660 for (Int_t iSeed=0; iSeed<nseed; iSeed++) {
8661 //if( iSeed!=1 ) continue;
8662 AliTPCseed *pt=(AliTPCseed*) (arr->UncheckedAt(iSeed));
8663 if (!pt) continue;
8664 AliTPCseed &t=*pt;
8665
8666 //cout <<"Pt "<<t.GetSigned1Pt()<<endl;
8667
8668 // t.Print();
8669
8670 for( int iter=0; iter<3; iter++ ){
8671
8672 t.Reset();
8673 t.SetLastPoint(0); // first cluster in track position
8674 t.SetFirstPoint(nRows-1);
8675 t.ResetCovariance(.1);
8676 t.SetNumberOfClusters(0);
8677 for( int i=0; i<nRows; i++ ){
8678 shapeY2[i]=1.;
8679 shapeZ2[i]=1.;
8680 clusterIndex[i]=-1;
8681 t.SetClusterIndex2(i,-1);
8682 t.SetClusterIndex(i,-1);
8683 }
8684
8685 // pick up the clusters
8686
8687 Double_t roady = 20.;
8688 Double_t roadz = 20.;
8689 double roadr = 5;
8690
8691 AliTPCseed t0(t);
8692 t0.Reset();
8693 int nClusters = 0;
8694 {
8695 t0.SetRelativeSector(t.GetRelativeSector());
8696 t0.SetLastPoint(0); // first cluster in track position
8697 t0.SetFirstPoint(159);
8698 for (Int_t nr=0; nr<nRows; nr++){
8699 if( nr<fInnerSec->GetNRows() ) fSectors=fInnerSec;
8700 else fSectors=fOuterSec;
8701
8702 if( !PropagateToRowHLT(&t0, nr ) ){ break; }
8703 if (TMath::Abs(t0.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8704 //cout<<"Snp is too big: "<<t0.GetSnp()<<endl;
8705 continue;
8706 }
8707 if (!IsActive(t0.GetRelativeSector(),nr)) {
8708 continue;
8709 }
8710
8711 if( iter==0 ){
8712 GetShape(&t0,nr);
8713 shapeY2[nr]=t0.GetCurrentSigmaY2();
8714 shapeZ2[nr]=t0.GetCurrentSigmaZ2();
8715 }
8716
8717 AliTPCtrackerRow &krow=GetRow(t0.GetRelativeSector(),nr);
8718 if( !krow ) continue;
8719
8720 t.SetClusterIndex2(nr,-3); // foundable
8721 t.SetClusterIndex(nr,-3);
8722
8723 AliTPCclusterMI *cl=0;
8724 UInt_t uindex = 0;
8725 cl = krow.FindNearest2(t0.GetY(),t0.GetZ(),roady,roadz,uindex);
8726 if (!cl ) continue;
8727 double dy = cl->GetY()-t0.GetY();
8728 double dz = cl->GetZ()-t0.GetZ();
8729 double dr = sqrt(dy*dy+dz*dz);
8730 if( dr>roadr ){
8731 //cout<<"row "<<nr<<", best cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8732 continue;
8733 }
8734 //cout<<"row "<<nr<<", found cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8735
8736 t0.SetClusterPointer(nr, cl);
8737 clusterIndex[nr] = krow.GetIndex(uindex);
8738 if( t0.GetFirstPoint()>nr ) t0.SetFirstPoint(nr);
8739 t0.SetLastPoint(nr);
8740 nClusters++;
8741 }
8742 }
8743
8744 if( nClusters <3 ){
8745 //cout<<"NOT ENOUGTH CLUSTERS: "<<nClusters<<endl;
8746 break;
8747 }
8748 Int_t basePoints[3] = {t0.GetFirstPoint(),t0.GetFirstPoint(),t0.GetLastPoint()};
8749
8750 // find midpoint
8751 {
8752 Int_t midRow = (t0.GetLastPoint()-t0.GetFirstPoint())/2;
8753 int dist=200;
8754 for( int nr=t0.GetFirstPoint()+1; nr< t0.GetLastPoint(); nr++){
8755 if( !t0.GetClusterPointer(nr) ) continue;
8756 int d = TMath::Abs(nr-midRow);
8757 if( d < dist ){
8758 dist = d;
8759 basePoints[1] = nr;
8760 }
8761 }
8762 }
8763
8764 // first fit 3 base points
8765 if( 1||iter<2 ){
8766 //cout<<"Fit3: "<<endl;
8767 for( int icl=0; icl<3; icl++){
8768 int nr = basePoints[icl];
8769 int lr=nr;
8770 if( nr>=fInnerSec->GetNRows()){
8771 lr = nr - fInnerSec->GetNRows();
8772 fSectors=fOuterSec;
8773 } else fSectors=fInnerSec;
8774
8775 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8776 if(!cl){
8777 //cout<<"WRONG!!!!"<<endl;
8778 continue;
8779 }
8780 int iSec = cl->GetDetector() %fkNIS;
8781 int rotate = iSec - t.GetRelativeSector();
8782 if( rotate!=0 ){
8783 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8784 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8785 //cout<<"can't rotate "<<endl;
8786 break;
8787 }
8788 t.SetRelativeSector(iSec);
8789 }
8790 Double_t x= cl->GetX();
8791 if (!t.PropagateTo(x)){
8792 //cout<<"can't propagate to x="<<x<<endl;
8793 break;
8794 }
8795
8796 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8797 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8798 break;
8799 }
8800 //cout<<"fit3 : row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8801
8802 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8803 t.SetCurrentCluster(cl);
8804 t.SetRow(lr);
8805
8806 t.SetErrorY2(shapeY2[nr]);
8807 t.SetErrorZ2(shapeZ2[nr]);
8808 if( icl==0 ){
8809 double cov[15];
8810 for( int j=0; j<15; j++ ) cov[j]=0;
8811 cov[0]=10;
8812 cov[2]=10;
8813 cov[5]=.5;
8814 cov[9]=.5;
8815 cov[14]=1.;
8816 t.AliExternalTrackParam::AddCovariance(cov);
8817 }
8818 if( !UpdateTrack(&t,0) ){
8819 //cout<<"Can not update"<<endl;
8820 //t.Print();
8821 t.SetClusterIndex2(nr,-1);
8822 t.SetClusterIndex(nr,-1);
8823 t.SetClusterPointer(nr,0);
8824 break;
8825 }
8826 //t.SetClusterPointer(nr, cl);
8827 }
8828
8829 //t.SetLastPoint(t0.GetLastPoint());
8830 //t.SetFirstPoint(t0.GetFirstPoint());
8831
8832 //cout<<"Fit: "<<endl;
8833 for (Int_t nr=t0.GetLastPoint(); nr>=t0.GetFirstPoint(); nr-- ){
8834 int lr=nr;
8835 if( nr>=fInnerSec->GetNRows()){
8836 lr = nr - fInnerSec->GetNRows();
8837 fSectors=fOuterSec;
8838 } else fSectors=fInnerSec;
8839
8840 if(1|| iter<2 ){
8841 if( nr == basePoints[0] ) continue;
8842 if( nr == basePoints[1] ) continue;
8843 if( nr == basePoints[2] ) continue;
8844 }
8845 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8846 if(!cl) continue;
8847
8848 int iSec = cl->GetDetector() %fkNIS;
8849 int rotate = iSec - t.GetRelativeSector();
8850 if( rotate!=0 ){
8851 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8852 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8853 //cout<<"can't rotate "<<endl;
8854 break;
8855 }
8856 t.SetRelativeSector(iSec);
8857 }
8858 Double_t x= cl->GetX();
8859 if (!t.PropagateTo(x)){
8860 //cout<<"can't propagate to x="<<x<<endl;
8861 break;
8862 }
8863 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8864 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8865 break;
8866 }
8867
8868 //cout<<"fit: row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8869
8870 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8871 t.SetCurrentCluster(cl);
8872 t.SetRow(lr);
8873 t.SetErrorY2(shapeY2[nr]);
8874 t.SetErrorZ2(shapeZ2[nr]);
8875
8876 if( !UpdateTrack(&t,0) ){
8877 //cout<<"Can not update"<<endl;
8878 //t.Print();
8879 t.SetClusterIndex2(nr,-1);
8880 t.SetClusterIndex(nr,-1);
8881 break;
8882 }
8883 //t.SetClusterPointer(nr, cl);
8884 }
8885 }
8886 //cout<<"After iter "<<iter<<": N clusters="<<t.GetNumberOfClusters()<<" : "<<nClusters<<endl;
8887 }
8888
8889 //cout<<"fitted track"<<iSeed<<endl;
8890 //t.Print();
8891 //cout<<"Statistics: "<<endl;
8892 Int_t foundable,found,shared;
8893 t.GetClusterStatistic(0,nRows, found, foundable, shared, kTRUE);
8894 t.SetNFoundable(foundable);
8895 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8896
8897 }
8898}
8899
8900
829455ad 8901TObjArray * AliTPCtracker::MakeSeedsHLT(const AliESDEvent *hltEvent)
72e25240 8902{
8903 // tracking
8904 //
8905
8906 if( !hltEvent ) return 0;
8907
8908
8909 Int_t nentr=hltEvent->GetNumberOfTracks();
8910
8911 AliInfo(Form("Using %d HLT tracks for seeding",nentr));
8912
8913 TObjArray * seeds = new TObjArray(nentr);
8914
8915 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8916 Int_t index = 0;
8917
8918 Int_t nTr=hltEvent->GetNumberOfTracks();
8919
8920 for( int itr=0; itr<nTr; itr++ ){
8921 //if( itr!=97 ) continue;
8922 const AliExternalTrackParam *param = hltEvent->GetTrack(itr)->GetTPCInnerParam();
8923 if( !param ) continue;
8924 //if( TMath::Abs(esdTr->GetSigned1Pt())>1 ) continue;
8925 //if( TMath::Abs(esdTr->GetTgl())>1. ) continue;
8926 AliTPCtrack tr;
8927 tr.Set(param->GetX(),param->GetAlpha(),param->GetParameter(),param->GetCovariance());
8928 tr.SetNumberOfClusters(0);
8929 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed(tr);
8930
8931 Double_t alpha=seed->GetAlpha();// - fSectors->GetAlphaShift();
8932 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
8933 if (alpha < 0. ) alpha += 2.*TMath::Pi();
8934 //
8935 seed->SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
8936 Double_t alphaSec = fSectors->GetAlpha() * seed->GetRelativeSector() + fSectors->GetAlphaShift();
8937
8938 if (alphaSec >= TMath::Pi()) alphaSec -= 2.*TMath::Pi();
8939 if (alphaSec < -TMath::Pi()) alphaSec += 2.*TMath::Pi();
8940
8941 seed->Rotate(alphaSec - alpha);
8942
8943 seed->SetPoolID(fLastSeedID);
8944 seed->SetIsSeeding(kTRUE);
8945 seed->SetSeed1(nup-1);
8946 seed->SetSeed2(nup-2);
8947 seed->SetSeedType(0);
8948 seed->SetFirstPoint(-1);
8949 seed->SetLastPoint(-1);
8950 seeds->AddLast(seed); // note, track is seed, don't free the seed
8951 index++;
8952 //if( index>3 ) break;
8953 }
8954
8955
8956 fSectors = fOuterSec;
8957
8958 TrackFollowingHLT(seeds );
8959
8960 nTr = seeds->GetEntriesFast();
8961 for( int itr=0; itr<nTr; itr++ ){
8962 AliTPCseed * seed = (AliTPCseed*) seeds->UncheckedAt(itr);
8963 if( !seed ) continue;
8964 //FollowBackProlongation(*seed,0);
8965 // cout<<seed->GetNumberOfClusters()<<endl;
8966 Int_t foundable,found,shared;
8967 seed->GetClusterStatistic(0,nup, found, foundable, shared, kTRUE);
8968 seed->SetNFoundable(foundable);
8969 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8970 //if ((found<0.55*foundable) || shared>0.5*found ){// || (seed->GetSigmaY2()+seed->GetSigmaZ2())>0.5){
8971 //MarkSeedFree(seeds->RemoveAt(itr));
8972 //continue;
8973 //}
8974 if (seed->GetNumberOfClusters()<30 ||
8975 seed->GetNumberOfClusters() < seed->GetNFoundable()*0.6 ||
8976 seed->GetNShared()>0.4*seed->GetNumberOfClusters() ) {
8977 MarkSeedFree(seeds->RemoveAt(itr));
8978 continue;
8979 }
8980
8981 for( int ir=0; ir<nup; ir++){
8982 AliTPCclusterMI *c = seed->GetClusterPointer(ir);
8983 if( c ) c->Use(10);
8984 }
8985 }
492a4365 8986 std::cout<<"\n\nHLT tracks left: "<<seeds->GetEntries()<<" out of "<<hltEvent->GetNumberOfTracks()<<endl<<endl;
72e25240 8987 return seeds;
8988}
5576d489 8989
8990void AliTPCtracker::FillClusterOccupancyInfo()
8991{
8992 //fill the cluster occupancy info into the ESD friend
8993 AliESDfriend* esdFriend = static_cast<AliESDfriend*>(fEvent->FindListObject("AliESDfriend"));
8994 if (!esdFriend) return;
8995
8996 for (Int_t isector=0; isector<18; isector++){
8997 AliTPCtrackerSector &iroc = fInnerSec[isector];
8998 AliTPCtrackerSector &oroc = fOuterSec[isector];
8999 //all clusters
9000 esdFriend->SetNclustersTPC(isector, iroc.GetNClInSector(0));
9001 esdFriend->SetNclustersTPC(isector+18,iroc.GetNClInSector(1));
9002 esdFriend->SetNclustersTPC(isector+36,oroc.GetNClInSector(0));
9003 esdFriend->SetNclustersTPC(isector+54,oroc.GetNClInSector(1));
9004 //clusters used in tracking
9005 esdFriend->SetNclustersTPCused(isector, iroc.GetNClUsedInSector(0));
9006 esdFriend->SetNclustersTPCused(isector+18, iroc.GetNClUsedInSector(1));
9007 esdFriend->SetNclustersTPCused(isector+36, oroc.GetNClUsedInSector(0));
9008 esdFriend->SetNclustersTPCused(isector+54, oroc.GetNClUsedInSector(1));
9009 }
9010}