]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/Rec/AliTPCtracker.cxx
PWGPP-71 - Noise event outlier removal also on sector level. Propagate information...
[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
26// The track finding steps:
27// 1. Seeding - with and without vertex constraint
28// - seeding with vertex constain done at first n^2 proble
29// - seeding without vertex constraint n^3 problem
30// 2. Tracking - follow prolongation road - find cluster - update kalman track
31
32// The seeding and tracking is repeated several times, in different seeding region.
33// This approach enables to find the track which cannot be seeded in some region of TPC
34// This can happen because of low momenta (track do not reach outer radius), or track is currently in the ded region between sectors, or the track is for the moment overlapped with other track (seed quality is poor) ...
35
36// With this approach we reach almost 100 % efficiency also for high occupancy events.
37// (If the seeding efficiency in a region is about 90 % than with logical or of several
38// regions we will reach 100% (in theory - supposing independence)
39
40// Repeating several seeding - tracking procedures some of the tracks can be find
41// several times.
42
43// The procedures to remove multi find tacks are impremented:
44// RemoveUsed2 - fast procedure n problem -
45// Algorithm - Sorting tracks according quality
46// remove tracks with some shared fraction
47// Sharing in respect to all tacks
48// Signing clusters in gold region
49// FindSplitted - slower algorithm n^2
50// Sort the tracks according quality
51// Loop over pair of tracks
52// If overlap with other track bigger than threshold - remove track
53//
54// FindCurling - Finds the pair of tracks which are curling
55// - About 10% of tracks can be find with this procedure
56// The combinatorial background is too big to be used in High
57// multiplicity environment
58// - n^2 problem - Slow procedure - currently it is disabled because of
59// low efficiency
60//
61// The number of splitted tracks can be reduced disabling the sharing of the cluster.
62// tpcRecoParam-> SetClusterSharing(kFALSE);
63// IT IS HIGHLY non recomended to use it in high flux enviroonment
64// Even using this switch some tracks can be found more than once
65// (because of multiple seeding and low quality tracks which will not cross full chamber)
66//
67//
68// The tracker itself can be debugged - the information about tracks can be stored in several // phases of the reconstruction
69// To enable storage of the TPC tracks in the ESD friend track
16299eac 70// use AliTPCReconstructor::SetStreamLevel(n);
6d493ea0 71//
72// The debug level - different procedure produce tree for numerical debugging
73// To enable them set AliTPCReconstructor::SetStreamLevel(n); where nis bigger 1
74//
92f513f5 75
76//
77// Adding systematic errors to the covariance:
78//
79// The systematic errors due to the misalignment and miscalibration are added to the covariance matrix
80// of the tracks (not to the clusters as they are dependent):
81// The parameters form AliTPCRecoParam are used AliTPCRecoParam::GetSystematicError
b87c2bbc 82// The systematic errors are expressed there in RMS - position (cm), angle (rad), curvature (1/GeV)
92f513f5 83// The default values are 0.
84//
85// The sytematic errors are added to the covariance matrix in following places:
86//
829455ad 87// 1. During fisrt itteration - AliTPCtracker::FillESD
92f513f5 88// 2. Second iteration -
829455ad 89// 2.a ITS->TPC - AliTPCtracker::ReadSeeds
90// 2.b TPC->TRD - AliTPCtracker::PropagateBack
92f513f5 91// 3. Third iteration -
829455ad 92// 3.a TRD->TPC - AliTPCtracker::ReadSeeds
93// 3.b TPC->ITS - AliTPCtracker::RefitInward
92f513f5 94//
fd065ea2 95// There are several places in the code which can be numerically debuged
96// This code is keeped in order to enable code development and to check the calibration implementtion
97//
16299eac 98// 1. ErrParam stream - dump information about
fd065ea2 99// 1.a) cluster
100// 2.a) cluster error estimate
101// 3.a) cluster shape estimate
102//
103//
16299eac 104// Debug streamer levels:
105//
1c53abe2 106//-------------------------------------------------------
47966a6d 107
108
109/* $Id$ */
110
cc5e9db0 111#include "Riostream.h"
6d171107 112#include <TClonesArray.h>
113#include <TFile.h>
114#include <TObjArray.h>
115#include <TTree.h>
8cc1870a 116#include <TMatrixD.h>
6d64657a 117#include <TGraphErrors.h>
661f340b 118#include <TTimeStamp.h>
a3232aae 119#include "AliLog.h"
47966a6d 120#include "AliComplexCluster.h"
af885e0f 121#include "AliESDEvent.h"
aad72f45 122#include "AliESDtrack.h"
123#include "AliESDVertex.h"
6c94f330 124#include "AliKink.h"
125#include "AliV0.h"
91162307 126#include "AliHelix.h"
91162307 127#include "AliRunLoader.h"
6d171107 128#include "AliTPCClustersRow.h"
129#include "AliTPCParam.h"
9996a03b 130#include "AliTPCReconstructor.h"
6d171107 131#include "AliTPCpolyTrack.h"
81e97e0d 132#include "AliTPCreco.h"
9350f379 133#include "AliTPCseed.h"
134
135#include "AliTPCtrackerSector.h"
829455ad 136#include "AliTPCtracker.h"
6d171107 137#include "TStopwatch.h"
81e97e0d 138#include "AliTPCReconstructor.h"
5d837844 139#include "AliAlignObj.h"
140#include "AliTrackPointArray.h"
6d493ea0 141#include "TRandom.h"
24db6af7 142#include "AliTPCcalibDB.h"
6d64657a 143#include "AliTPCcalibDButil.h"
24db6af7 144#include "AliTPCTransform.h"
fd065ea2 145#include "AliTPCClusterParam.h"
64bf5ca0 146#include "AliTPCdEdxInfo.h"
ec7e4ad6 147#include "AliDCSSensorArray.h"
148#include "AliDCSSensor.h"
149#include "AliDAQ.h"
3aa6a136 150#include "AliCosmicTracker.h"
44ca7282 151#include "AliTPCROC.h"
e731a3f8 152#include "AliMathBase.h"
6d171107 153//
c9427e08 154
a11596ad 155using std::cerr;
156using std::endl;
829455ad 157ClassImp(AliTPCtracker)
c9427e08 158
159
002af263 160
b67e07dc 161class AliTPCFastMath {
91162307 162public:
b67e07dc 163 AliTPCFastMath();
91162307 164 static Double_t FastAsin(Double_t x);
165 private:
b67e07dc 166 static Double_t fgFastAsin[20000]; //lookup table for fast asin computation
91162307 167};
c9427e08 168
b67e07dc 169Double_t AliTPCFastMath::fgFastAsin[20000];
2274b54b 170AliTPCFastMath gAliTPCFastMath; // needed to fill the LUT
c9427e08 171
b67e07dc 172AliTPCFastMath::AliTPCFastMath(){
173 //
174 // initialized lookup table;
91162307 175 for (Int_t i=0;i<10000;i++){
176 fgFastAsin[2*i] = TMath::ASin(i/10000.);
177 fgFastAsin[2*i+1] = (TMath::ASin((i+1)/10000.)-fgFastAsin[2*i]);
178 }
c9427e08 179}
180
b67e07dc 181Double_t AliTPCFastMath::FastAsin(Double_t x){
182 //
183 // return asin using lookup table
91162307 184 if (x>0){
185 Int_t index = int(x*10000);
186 return fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1];
187 }
188 x*=-1;
189 Int_t index = int(x*10000);
190 return -(fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1]);
1c53abe2 191}
e046d791 192//__________________________________________________________________
829455ad 193AliTPCtracker::AliTPCtracker()
e046d791 194 :AliTracker(),
195 fkNIS(0),
196 fInnerSec(0),
197 fkNOS(0),
198 fOuterSec(0),
199 fN(0),
200 fSectors(0),
201 fInput(0),
202 fOutput(0),
203 fSeedTree(0),
204 fTreeDebug(0),
205 fEvent(0),
72e25240 206 fEventHLT(0),
e046d791 207 fDebug(0),
208 fNewIO(kFALSE),
209 fNtracks(0),
210 fSeeds(0),
211 fIteration(0),
47af7ca4 212 fkParam(0),
1598ba75 213 fDebugStreamer(0),
f06a1ff6 214 fUseHLTClusters(4),
8cc1870a 215 fCrossTalkSignalArray(0),
f06a1ff6 216 fSeedsPool(0),
ddfbc51a 217 fFreeSeedsID(500),
218 fNFreeSeeds(0),
219 fLastSeedID(-1)
e046d791 220{
221 //
222 // default constructor
223 //
0f923679 224 for (Int_t irow=0; irow<200; irow++){
225 fXRow[irow]=0;
226 fYMax[irow]=0;
227 fPadLength[irow]=0;
228 }
e046d791 229}
230//_____________________________________________________________________
1c53abe2 231
232
233
829455ad 234Int_t AliTPCtracker::UpdateTrack(AliTPCseed * track, Int_t accept){
b67e07dc 235 //
236 //update track information using current cluster - track->fCurrentCluster
237
1c53abe2 238
b9671574 239 AliTPCclusterMI* c =track->GetCurrentCluster();
f124f8bf 240 if (accept > 0) //sign not accepted clusters
241 track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() | 0x8000);
242 else // unsign accpeted clusters
243 track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() & 0xffff7fff);
b9671574 244 UInt_t i = track->GetCurrentClusterIndex1();
1c53abe2 245
246 Int_t sec=(i&0xff000000)>>24;
91162307 247 //Int_t row = (i&0x00ff0000)>>16;
b9671574 248 track->SetRow((i&0x00ff0000)>>16);
249 track->SetSector(sec);
1c53abe2 250 // Int_t index = i&0xFFFF;
47af7ca4 251 if (sec>=fkParam->GetNInnerSector()) track->SetRow(track->GetRow()+fkParam->GetNRowLow());
b9671574 252 track->SetClusterIndex2(track->GetRow(), i);
91162307 253 //track->fFirstPoint = row;
254 //if ( track->fLastPoint<row) track->fLastPoint =row;
255 // if (track->fRow<0 || track->fRow>160) {
256 // printf("problem\n");
257 //}
b9671574 258 if (track->GetFirstPoint()>track->GetRow())
259 track->SetFirstPoint(track->GetRow());
260 if (track->GetLastPoint()<track->GetRow())
261 track->SetLastPoint(track->GetRow());
91162307 262
263
b9671574 264 track->SetClusterPointer(track->GetRow(),c);
1c53abe2 265 //
266
3f82c4f2 267 Double_t angle2 = track->GetSnp()*track->GetSnp();
1c53abe2 268 //
269 //SET NEW Track Point
270 //
85e2b57d 271 if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
91162307 272 {
85e2b57d 273 angle2 = TMath::Sqrt(angle2/(1-angle2));
b9671574 274 AliTPCTrackerPoint &point =*(track->GetTrackPoint(track->GetRow()));
1c53abe2 275 //
b9671574 276 point.SetSigmaY(c->GetSigmaY2()/track->GetCurrentSigmaY2());
277 point.SetSigmaZ(c->GetSigmaZ2()/track->GetCurrentSigmaZ2());
278 point.SetErrY(sqrt(track->GetErrorY2()));
279 point.SetErrZ(sqrt(track->GetErrorZ2()));
1c53abe2 280 //
91162307 281 point.SetX(track->GetX());
282 point.SetY(track->GetY());
283 point.SetZ(track->GetZ());
284 point.SetAngleY(angle2);
285 point.SetAngleZ(track->GetTgl());
b9671574 286 if (point.IsShared()){
287 track->SetErrorY2(track->GetErrorY2()*4);
288 track->SetErrorZ2(track->GetErrorZ2()*4);
91162307 289 }
290 }
291
b9671574 292 Double_t chi2 = track->GetPredictedChi2(track->GetCurrentCluster());
91162307 293 //
1d91d749 294// track->SetErrorY2(track->GetErrorY2()*1.3);
295// track->SetErrorY2(track->GetErrorY2()+0.01);
296// track->SetErrorZ2(track->GetErrorZ2()*1.3);
297// track->SetErrorZ2(track->GetErrorZ2()+0.005);
91162307 298 //}
299 if (accept>0) return 0;
300 if (track->GetNumberOfClusters()%20==0){
301 // if (track->fHelixIn){
302 // TClonesArray & larr = *(track->fHelixIn);
303 // Int_t ihelix = larr.GetEntriesFast();
304 // new(larr[ihelix]) AliHelix(*track) ;
305 //}
1c53abe2 306 }
518f85b7 307 if (AliTPCReconstructor::StreamLevel()>5) {
bda5ad6d 308 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
309 AliExternalTrackParam param(*track);
310 TTreeSRedirector &cstream = *fDebugStreamer;
311 cstream<<"Update"<<
312 "cl.="<<c<<
265b5e37 313 "event="<<event<<
bda5ad6d 314 "track.="<<&param<<
315 "\n";
316 }
b9671574 317 track->SetNoCluster(0);
91162307 318 return track->Update(c,chi2,i);
319}
320
321
322
829455ad 323Int_t AliTPCtracker::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster)
91162307 324{
1c53abe2 325 //
91162307 326 // decide according desired precision to accept given
327 // cluster for tracking
6fbe1e5c 328 Double_t yt=0,zt=0;
329 seed->GetProlongation(cluster->GetX(),yt,zt);
00055a22 330 Double_t sy2=ErrY2(seed,cluster);
331 Double_t sz2=ErrZ2(seed,cluster);
1c53abe2 332
91162307 333 Double_t sdistancey2 = sy2+seed->GetSigmaY2();
334 Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
6fbe1e5c 335 Double_t dy=seed->GetCurrentCluster()->GetY()-yt;
f47588e0 336 Double_t dz=seed->GetCurrentCluster()->GetZ()-zt;
6fbe1e5c 337 Double_t rdistancey2 = (seed->GetCurrentCluster()->GetY()-yt)*
338 (seed->GetCurrentCluster()->GetY()-yt)/sdistancey2;
339 Double_t rdistancez2 = (seed->GetCurrentCluster()->GetZ()-zt)*
340 (seed->GetCurrentCluster()->GetZ()-zt)/sdistancez2;
91162307 341
342 Double_t rdistance2 = rdistancey2+rdistancez2;
343 //Int_t accept =0;
1c53abe2 344
f5a565c3 345 if (AliTPCReconstructor::StreamLevel()>2 && ( (fIteration>0)|| (seed->GetNumberOfClusters()>20))) {
a9ff2f09 346 // if (AliTPCReconstructor::StreamLevel()>2 && seed->GetNumberOfClusters()>20) {
fd065ea2 347 Float_t rmsy2 = seed->GetCurrentSigmaY2();
348 Float_t rmsz2 = seed->GetCurrentSigmaZ2();
e0e13b88 349 Float_t rmsy2p30 = seed->GetCMeanSigmaY2p30();
350 Float_t rmsz2p30 = seed->GetCMeanSigmaZ2p30();
42aec1f1 351 Float_t rmsy2p30R = seed->GetCMeanSigmaY2p30R();
352 Float_t rmsz2p30R = seed->GetCMeanSigmaZ2p30R();
6fbe1e5c 353 AliExternalTrackParam param(*seed);
eea6b724 354 static TVectorD gcl(3),gtr(3);
355 Float_t gclf[3];
356 param.GetXYZ(gcl.GetMatrixArray());
357 cluster->GetGlobalXYZ(gclf);
358 gcl[0]=gclf[0]; gcl[1]=gclf[1]; gcl[2]=gclf[2];
a9ff2f09 359 Int_t nclSeed=seed->GetNumberOfClusters();
b194b32c 360
16299eac 361 if (AliTPCReconstructor::StreamLevel()>2) {
fd065ea2 362 (*fDebugStreamer)<<"ErrParam"<<
498b9441 363 "iter="<<fIteration<<
e0e13b88 364 "Cl.="<<cluster<<
a9ff2f09 365 "nclSeed="<<nclSeed<<
e0e13b88 366 "T.="<<&param<<
6fbe1e5c 367 "dy="<<dy<<
368 "dz="<<dz<<
369 "yt="<<yt<<
370 "zt="<<zt<<
eea6b724 371 "gcl.="<<&gcl<<
372 "gtr.="<<&gtr<<
e0e13b88 373 "erry2="<<sy2<<
374 "errz2="<<sz2<<
375 "rmsy2="<<rmsy2<<
376 "rmsz2="<<rmsz2<<
377 "rmsy2p30="<<rmsy2p30<<
378 "rmsz2p30="<<rmsz2p30<<
42aec1f1 379 "rmsy2p30R="<<rmsy2p30R<<
380 "rmsz2p30R="<<rmsz2p30R<<
f47588e0 381 // normalize distance -
382 "rdisty="<<rdistancey2<<
383 "rdistz="<<rdistancez2<<
384 "rdist="<<rdistance2<< //
e0e13b88 385 "\n";
b194b32c 386 }
fd065ea2 387 }
6fbe1e5c 388 //return 0; // temporary
389 if (rdistance2>32) return 3;
91162307 390
391
00055a22 392 if ((rdistancey2>9. || rdistancez2>9.) && cluster->GetType()==0)
91162307 393 return 2; //suspisiouce - will be changed
394
00055a22 395 if ((rdistancey2>6.25 || rdistancez2>6.25) && cluster->GetType()>0)
91162307 396 // strict cut on overlaped cluster
397 return 2; //suspisiouce - will be changed
398
00055a22 399 if ( (rdistancey2>1. || rdistancez2>6.25 )
91162307 400 && cluster->GetType()<0){
b9671574 401 seed->SetNFoundable(seed->GetNFoundable()-1);
91162307 402 return 2;
1c53abe2 403 }
19dcf504 404
1598ba75 405 if (fUseHLTClusters == 3 || fUseHLTClusters == 4) {
36b89541 406 if (fIteration==2){
407 if(!AliTPCReconstructor::GetRecoParam()->GetUseHLTOnePadCluster()) {
408 if (TMath::Abs(cluster->GetSigmaY2()) < kAlmost0)
409 return 2;
410 }
1598ba75 411 }
19dcf504 412 }
1598ba75 413
91162307 414 return 0;
415}
416
417
1c53abe2 418
1c53abe2 419
1af5da7e 420
1c53abe2 421//_____________________________________________________________________________
829455ad 422AliTPCtracker::AliTPCtracker(const AliTPCParam *par):
e046d791 423AliTracker(),
424 fkNIS(par->GetNInnerSector()/2),
425 fInnerSec(0),
426 fkNOS(par->GetNOuterSector()/2),
427 fOuterSec(0),
428 fN(0),
429 fSectors(0),
430 fInput(0),
431 fOutput(0),
432 fSeedTree(0),
433 fTreeDebug(0),
434 fEvent(0),
72e25240 435 fEventHLT(0),
e046d791 436 fDebug(0),
437 fNewIO(0),
438 fNtracks(0),
439 fSeeds(0),
440 fIteration(0),
47af7ca4 441 fkParam(0),
8cc1870a 442 fDebugStreamer(0),
443 fUseHLTClusters(4),
444 fCrossTalkSignalArray(0),
8cc1870a 445 fSeedsPool(0),
ddfbc51a 446 fFreeSeedsID(500),
447 fNFreeSeeds(0),
448 fLastSeedID(-1)
1c53abe2 449{
450 //---------------------------------------------------------------------
451 // The main TPC tracker constructor
452 //---------------------------------------------------------------------
9350f379 453 fInnerSec=new AliTPCtrackerSector[fkNIS];
454 fOuterSec=new AliTPCtrackerSector[fkNOS];
91162307 455
1c53abe2 456 Int_t i;
457 for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
458 for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
459
47af7ca4 460 fkParam = par;
91162307 461 Int_t nrowlow = par->GetNRowLow();
462 Int_t nrowup = par->GetNRowUp();
463
464
77f88633 465 for (i=0;i<nrowlow;i++){
91162307 466 fXRow[i] = par->GetPadRowRadiiLow(i);
467 fPadLength[i]= par->GetPadPitchLength(0,i);
468 fYMax[i] = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
469 }
470
471
77f88633 472 for (i=0;i<nrowup;i++){
91162307 473 fXRow[i+nrowlow] = par->GetPadRowRadiiUp(i);
474 fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
475 fYMax[i+nrowlow] = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
476 }
e046d791 477
b194b32c 478 if (AliTPCReconstructor::StreamLevel()>0) {
3d674021 479 fDebugStreamer = new TTreeSRedirector("TPCdebug.root","recreate");
b194b32c 480 }
f06a1ff6 481 //
ddfbc51a 482 fSeedsPool = new TClonesArray("AliTPCseed",1000);
265b5e37 483
484 // crosstalk array and matrix initialization
485 Int_t nROCs = 72;
486 Int_t nTimeBinsAll = par->GetMaxTBin();
487 Int_t nWireSegments = 11;
434cdbe1 488 fCrossTalkSignalArray = new TObjArray(nROCs*2); //
265b5e37 489 fCrossTalkSignalArray->SetOwner(kTRUE);
434cdbe1 490 for (Int_t isector=0; isector<2*nROCs; isector++){
39240815 491 TMatrixD * crossTalkSignal = new TMatrixD(nWireSegments,nTimeBinsAll);
265b5e37 492 for (Int_t imatrix = 0; imatrix<11; imatrix++)
493 for (Int_t jmatrix = 0; jmatrix<nTimeBinsAll; jmatrix++){
39240815 494 (*crossTalkSignal)[imatrix][jmatrix]=0.;
265b5e37 495 }
39240815 496 fCrossTalkSignalArray->AddAt(crossTalkSignal,isector);
265b5e37 497 }
498
1c53abe2 499}
2fc0c115 500//________________________________________________________________________
829455ad 501AliTPCtracker::AliTPCtracker(const AliTPCtracker &t):
58251ea0 502 AliTracker(t),
e046d791 503 fkNIS(t.fkNIS),
504 fInnerSec(0),
505 fkNOS(t.fkNOS),
506 fOuterSec(0),
507 fN(0),
508 fSectors(0),
509 fInput(0),
510 fOutput(0),
511 fSeedTree(0),
512 fTreeDebug(0),
513 fEvent(0),
72e25240 514 fEventHLT(0),
e046d791 515 fDebug(0),
516 fNewIO(kFALSE),
517 fNtracks(0),
518 fSeeds(0),
519 fIteration(0),
47af7ca4 520 fkParam(0),
8cc1870a 521 fDebugStreamer(0),
522 fUseHLTClusters(4),
523 fCrossTalkSignalArray(0),
8cc1870a 524 fSeedsPool(0),
ddfbc51a 525 fFreeSeedsID(500),
526 fNFreeSeeds(0),
527 fLastSeedID(-1)
58251ea0 528{
2fc0c115 529 //------------------------------------
530 // dummy copy constructor
531 //------------------------------------------------------------------
e046d791 532 fOutput=t.fOutput;
17abbffb 533 for (Int_t irow=0; irow<200; irow++){
534 fXRow[irow]=0;
535 fYMax[irow]=0;
536 fPadLength[irow]=0;
537 }
538
2fc0c115 539}
829455ad 540AliTPCtracker & AliTPCtracker::operator=(const AliTPCtracker& /*r*/)
47af7ca4 541{
2fc0c115 542 //------------------------------
543 // dummy
544 //--------------------------------------------------------------
545 return *this;
546}
1c53abe2 547//_____________________________________________________________________________
829455ad 548AliTPCtracker::~AliTPCtracker() {
1c53abe2 549 //------------------------------------------------------------------
550 // TPC tracker destructor
551 //------------------------------------------------------------------
552 delete[] fInnerSec;
553 delete[] fOuterSec;
554 if (fSeeds) {
f06a1ff6 555 fSeeds->Clear();
1c53abe2 556 delete fSeeds;
557 }
8cc1870a 558 if (fCrossTalkSignalArray) delete fCrossTalkSignalArray;
81e97e0d 559 if (fDebugStreamer) delete fDebugStreamer;
ddfbc51a 560 if (fSeedsPool) delete fSeedsPool;
1c53abe2 561}
562
1c53abe2 563
829455ad 564void AliTPCtracker::FillESD(const TObjArray* arr)
91162307 565{
47966a6d 566 //
567 //
568 //fill esds using updated tracks
ada522d7 569
ec26e231 570 if (!fEvent) return;
ada522d7 571
572 AliESDtrack iotrack;
ec26e231 573
91162307 574 // write tracks to the event
575 // store index of the track
d26d9159 576 Int_t nseed=arr->GetEntriesFast();
51ad6848 577 //FindKinks(arr,fEvent);
91162307 578 for (Int_t i=0; i<nseed; i++) {
d26d9159 579 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 580 if (!pt) continue;
51ad6848 581 pt->UpdatePoints();
92f513f5 582 AddCovariance(pt);
8cecaa87 583 if (AliTPCReconstructor::StreamLevel()>1) {
584 (*fDebugStreamer)<<"Track0"<<
585 "Tr0.="<<pt<<
586 "\n";
587 }
47af7ca4 588 // pt->PropagateTo(fkParam->GetInnerRadiusLow());
eea478d3 589 if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
47af7ca4 590 pt->PropagateTo(fkParam->GetInnerRadiusLow());
eea478d3 591 }
51ad6848 592
593 if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
ada522d7 594 iotrack.~AliESDtrack();
595 new(&iotrack) AliESDtrack;
51ad6848 596 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 597 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 598 iotrack.SetTPCPoints(pt->GetPoints());
599 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 600 iotrack.SetV0Indexes(pt->GetV0Indexes());
601 // iotrack.SetTPCpid(pt->fTPCr);
f5cbf2ef 602 //iotrack.SetTPCindex(i);
603 MakeESDBitmaps(pt, &iotrack);
51ad6848 604 fEvent->AddTrack(&iotrack);
605 continue;
606 }
607
b9671574 608 if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
ada522d7 609 iotrack.~AliESDtrack();
610 new(&iotrack) AliESDtrack;
51ad6848 611 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 612 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 613 iotrack.SetTPCPoints(pt->GetPoints());
d26d9159 614 //iotrack.SetTPCindex(i);
51ad6848 615 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 616 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 617 MakeESDBitmaps(pt, &iotrack);
81e97e0d 618 // iotrack.SetTPCpid(pt->fTPCr);
d26d9159 619 fEvent->AddTrack(&iotrack);
a42a6bae 620 continue;
621 }
51ad6848 622 //
623 // short tracks - maybe decays
624
b9671574 625 if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
a42a6bae 626 Int_t found,foundable,shared;
627 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
b9671574 628 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
ada522d7 629 iotrack.~AliESDtrack();
630 new(&iotrack) AliESDtrack;
a42a6bae 631 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 632 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
a42a6bae 633 //iotrack.SetTPCindex(i);
51ad6848 634 iotrack.SetTPCPoints(pt->GetPoints());
635 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 636 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 637 MakeESDBitmaps(pt, &iotrack);
81e97e0d 638 //iotrack.SetTPCpid(pt->fTPCr);
a42a6bae 639 fEvent->AddTrack(&iotrack);
640 continue;
641 }
642 }
643
b9671574 644 if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
a42a6bae 645 Int_t found,foundable,shared;
646 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
647 if (found<20) continue;
b9671574 648 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
a42a6bae 649 //
ada522d7 650 iotrack.~AliESDtrack();
651 new(&iotrack) AliESDtrack;
a42a6bae 652 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 653 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 654 iotrack.SetTPCPoints(pt->GetPoints());
655 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 656 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 657 MakeESDBitmaps(pt, &iotrack);
81e97e0d 658 //iotrack.SetTPCpid(pt->fTPCr);
51ad6848 659 //iotrack.SetTPCindex(i);
660 fEvent->AddTrack(&iotrack);
661 continue;
662 }
663 // short tracks - secondaties
664 //
665 if ( (pt->GetNumberOfClusters()>30) ) {
666 Int_t found,foundable,shared;
667 pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
b9671574 668 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
ada522d7 669 iotrack.~AliESDtrack();
670 new(&iotrack) AliESDtrack;
51ad6848 671 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 672 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 673 iotrack.SetTPCPoints(pt->GetPoints());
674 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 675 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 676 MakeESDBitmaps(pt, &iotrack);
81e97e0d 677 //iotrack.SetTPCpid(pt->fTPCr);
51ad6848 678 //iotrack.SetTPCindex(i);
679 fEvent->AddTrack(&iotrack);
680 continue;
681 }
682 }
683
684 if ( (pt->GetNumberOfClusters()>15)) {
685 Int_t found,foundable,shared;
686 pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
687 if (found<15) continue;
e7eb17e4 688 if (foundable<=0) continue;
b9671574 689 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
51ad6848 690 if (float(found)/float(foundable)<0.8) continue;
691 //
ada522d7 692 iotrack.~AliESDtrack();
693 new(&iotrack) AliESDtrack;
51ad6848 694 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
a2e215dd 695 iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
51ad6848 696 iotrack.SetTPCPoints(pt->GetPoints());
697 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
81e97e0d 698 iotrack.SetV0Indexes(pt->GetV0Indexes());
f5cbf2ef 699 MakeESDBitmaps(pt, &iotrack);
81e97e0d 700 // iotrack.SetTPCpid(pt->fTPCr);
a42a6bae 701 //iotrack.SetTPCindex(i);
702 fEvent->AddTrack(&iotrack);
703 continue;
704 }
91162307 705 }
6fbe1e5c 706 // >> account for suppressed tracks in the kink indices (RS)
707 int nESDtracks = fEvent->GetNumberOfTracks();
708 for (int it=nESDtracks;it--;) {
709 AliESDtrack* esdTr = fEvent->GetTrack(it);
710 if (!esdTr || !esdTr->GetKinkIndex(0)) continue;
711 for (int ik=0;ik<3;ik++) {
712 int knkId=0;
713 if (!(knkId=esdTr->GetKinkIndex(ik))) break; // no more kinks for this track
714 AliESDkink* kink = fEvent->GetKink(TMath::Abs(knkId)-1);
715 if (!kink) {
716 AliError(Form("ESDTrack%d refers to non-existing kink %d",it,TMath::Abs(knkId)-1));
717 continue;
718 }
719 kink->SetIndex(it, knkId<0 ? 0:1); // update track index of the kink: mother at 0, daughter at 1
720 }
721 }
ada522d7 722
ec26e231 723 // << account for suppressed tracks in the kink indices (RS)
724 AliInfo(Form("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks()));
725
d26d9159 726}
727
d26d9159 728
1c53abe2 729
1c53abe2 730
731
829455ad 732Double_t AliTPCtracker::ErrY2(AliTPCseed* seed, const AliTPCclusterMI * cl){
91162307 733 //
734 //
fd065ea2 735 // Use calibrated cluster error from OCDB
91162307 736 //
fd065ea2 737 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
91162307 738 //
47af7ca4 739 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
91162307 740 Int_t ctype = cl->GetType();
fd065ea2 741 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
742 Double_t angle = seed->GetSnp()*seed->GetSnp();
e0e13b88 743 angle = TMath::Sqrt(TMath::Abs(angle/(1.-angle)));
fd065ea2 744 Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
745 if (ctype<0) {
746 erry2+=0.5; // edge cluster
747 }
748 erry2*=erry2;
0b2c141b 749 Double_t addErr=0;
750 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
f858edae 751 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
0b2c141b 752 erry2+=addErr*addErr;
44ca7282 753 const Double_t *errCluster = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorCluster();
754 erry2+=errCluster[0]*errCluster[0];
fd065ea2 755 seed->SetErrorY2(erry2);
756 //
757 return erry2;
758
759//calculate look-up table at the beginning
760// static Bool_t ginit = kFALSE;
761// static Float_t gnoise1,gnoise2,gnoise3;
762// static Float_t ggg1[10000];
763// static Float_t ggg2[10000];
764// static Float_t ggg3[10000];
765// static Float_t glandau1[10000];
766// static Float_t glandau2[10000];
767// static Float_t glandau3[10000];
768// //
769// static Float_t gcor01[500];
770// static Float_t gcor02[500];
771// static Float_t gcorp[500];
772// //
1c53abe2 773
fd065ea2 774// //
775// if (ginit==kFALSE){
776// for (Int_t i=1;i<500;i++){
777// Float_t rsigma = float(i)/100.;
778// gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
779// gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
780// gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
781// }
782
783// //
784// for (Int_t i=3;i<10000;i++){
785// //
786// //
787// // inner sector
788// Float_t amp = float(i);
789// Float_t padlength =0.75;
790// gnoise1 = 0.0004/padlength;
791// Float_t nel = 0.268*amp;
792// Float_t nprim = 0.155*amp;
47af7ca4 793// ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
fd065ea2 794// glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
795// if (glandau1[i]>1) glandau1[i]=1;
796// glandau1[i]*=padlength*padlength/12.;
797// //
798// // outer short
799// padlength =1.;
800// gnoise2 = 0.0004/padlength;
801// nel = 0.3*amp;
802// nprim = 0.133*amp;
47af7ca4 803// ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 804// glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
805// if (glandau2[i]>1) glandau2[i]=1;
806// glandau2[i]*=padlength*padlength/12.;
807// //
808// //
809// // outer long
810// padlength =1.5;
811// gnoise3 = 0.0004/padlength;
812// nel = 0.3*amp;
813// nprim = 0.133*amp;
47af7ca4 814// ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 815// glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
816// if (glandau3[i]>1) glandau3[i]=1;
817// glandau3[i]*=padlength*padlength/12.;
818// //
819// }
820// ginit = kTRUE;
821// }
822// //
823// //
824// //
825// Int_t amp = int(TMath::Abs(cl->GetQ()));
826// if (amp>9999) {
827// seed->SetErrorY2(1.);
828// return 1.;
829// }
830// Float_t snoise2;
47af7ca4 831// Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
fd065ea2 832// Int_t ctype = cl->GetType();
833// Float_t padlength= GetPadPitchLength(seed->GetRow());
834// Double_t angle2 = seed->GetSnp()*seed->GetSnp();
835// angle2 = angle2/(1-angle2);
836// //
837// //cluster "quality"
838// Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
839// Float_t res;
840// //
841// if (fSectors==fInnerSec){
842// snoise2 = gnoise1;
843// res = ggg1[amp]*z+glandau1[amp]*angle2;
844// if (ctype==0) res *= gcor01[rsigmay];
845// if ((ctype>0)){
846// res+=0.002;
847// res*= gcorp[rsigmay];
848// }
849// }
850// else {
851// if (padlength<1.1){
852// snoise2 = gnoise2;
853// res = ggg2[amp]*z+glandau2[amp]*angle2;
854// if (ctype==0) res *= gcor02[rsigmay];
855// if ((ctype>0)){
856// res+=0.002;
857// res*= gcorp[rsigmay];
858// }
859// }
860// else{
861// snoise2 = gnoise3;
862// res = ggg3[amp]*z+glandau3[amp]*angle2;
863// if (ctype==0) res *= gcor02[rsigmay];
864// if ((ctype>0)){
865// res+=0.002;
866// res*= gcorp[rsigmay];
867// }
868// }
869// }
870
871// if (ctype<0){
872// res+=0.005;
873// res*=2.4; // overestimate error 2 times
874// }
875// res+= snoise2;
91162307 876
fd065ea2 877// if (res<2*snoise2)
878// res = 2*snoise2;
91162307 879
fd065ea2 880// seed->SetErrorY2(res);
881// return res;
1c53abe2 882
883
91162307 884}
c9427e08 885
886
887
829455ad 888Double_t AliTPCtracker::ErrZ2(AliTPCseed* seed, const AliTPCclusterMI * cl){
91162307 889 //
890 //
fd065ea2 891 // Use calibrated cluster error from OCDB
91162307 892 //
fd065ea2 893 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
91162307 894 //
47af7ca4 895 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
91162307 896 Int_t ctype = cl->GetType();
fd065ea2 897 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
91162307 898 //
3f82c4f2 899 Double_t angle2 = seed->GetSnp()*seed->GetSnp();
91162307 900 angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
e0e13b88 901 Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
fd065ea2 902 Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
903 if (ctype<0) {
904 errz2+=0.5; // edge cluster
91162307 905 }
1af5da7e 906 errz2*=errz2;
0b2c141b 907 Double_t addErr=0;
908 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
f858edae 909 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
0b2c141b 910 errz2+=addErr*addErr;
44ca7282 911 const Double_t *errCluster = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorCluster();
912 errz2+=errCluster[1]*errCluster[1];
fd065ea2 913 seed->SetErrorZ2(errz2);
914 //
915 return errz2;
91162307 916
fd065ea2 917
918
919// //seed->SetErrorY2(0.1);
920// //return 0.1;
921// //calculate look-up table at the beginning
922// static Bool_t ginit = kFALSE;
923// static Float_t gnoise1,gnoise2,gnoise3;
924// static Float_t ggg1[10000];
925// static Float_t ggg2[10000];
926// static Float_t ggg3[10000];
927// static Float_t glandau1[10000];
928// static Float_t glandau2[10000];
929// static Float_t glandau3[10000];
930// //
931// static Float_t gcor01[1000];
932// static Float_t gcor02[1000];
933// static Float_t gcorp[1000];
934// //
935
936// //
937// if (ginit==kFALSE){
938// for (Int_t i=1;i<1000;i++){
939// Float_t rsigma = float(i)/100.;
940// gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
941// gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
942// gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
943// }
944
945// //
946// for (Int_t i=3;i<10000;i++){
947// //
948// //
949// // inner sector
950// Float_t amp = float(i);
951// Float_t padlength =0.75;
952// gnoise1 = 0.0004/padlength;
953// Float_t nel = 0.268*amp;
954// Float_t nprim = 0.155*amp;
47af7ca4 955// ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
fd065ea2 956// glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
957// if (glandau1[i]>1) glandau1[i]=1;
958// glandau1[i]*=padlength*padlength/12.;
959// //
960// // outer short
961// padlength =1.;
962// gnoise2 = 0.0004/padlength;
963// nel = 0.3*amp;
964// nprim = 0.133*amp;
47af7ca4 965// ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 966// glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
967// if (glandau2[i]>1) glandau2[i]=1;
968// glandau2[i]*=padlength*padlength/12.;
969// //
970// //
971// // outer long
972// padlength =1.5;
973// gnoise3 = 0.0004/padlength;
974// nel = 0.3*amp;
975// nprim = 0.133*amp;
47af7ca4 976// ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
fd065ea2 977// glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
978// if (glandau3[i]>1) glandau3[i]=1;
979// glandau3[i]*=padlength*padlength/12.;
980// //
981// }
982// ginit = kTRUE;
983// }
984// //
985// //
986// //
987// Int_t amp = int(TMath::Abs(cl->GetQ()));
988// if (amp>9999) {
989// seed->SetErrorY2(1.);
990// return 1.;
991// }
992// Float_t snoise2;
47af7ca4 993// Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
fd065ea2 994// Int_t ctype = cl->GetType();
995// Float_t padlength= GetPadPitchLength(seed->GetRow());
996// //
997// Double_t angle2 = seed->GetSnp()*seed->GetSnp();
998// // if (angle2<0.6) angle2 = 0.6;
999// angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
1000// //
1001// //cluster "quality"
1002// Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
1003// Float_t res;
1004// //
1005// if (fSectors==fInnerSec){
1006// snoise2 = gnoise1;
1007// res = ggg1[amp]*z+glandau1[amp]*angle2;
1008// if (ctype==0) res *= gcor01[rsigmaz];
1009// if ((ctype>0)){
1010// res+=0.002;
1011// res*= gcorp[rsigmaz];
1012// }
1013// }
1014// else {
1015// if (padlength<1.1){
1016// snoise2 = gnoise2;
1017// res = ggg2[amp]*z+glandau2[amp]*angle2;
1018// if (ctype==0) res *= gcor02[rsigmaz];
1019// if ((ctype>0)){
1020// res+=0.002;
1021// res*= gcorp[rsigmaz];
1022// }
1023// }
1024// else{
1025// snoise2 = gnoise3;
1026// res = ggg3[amp]*z+glandau3[amp]*angle2;
1027// if (ctype==0) res *= gcor02[rsigmaz];
1028// if ((ctype>0)){
1029// res+=0.002;
1030// res*= gcorp[rsigmaz];
1031// }
1032// }
1033// }
1034
1035// if (ctype<0){
1036// res+=0.002;
1037// res*=1.3;
1038// }
1039// if ((ctype<0) &&amp<70){
1040// res+=0.002;
1041// res*=1.3;
1042// }
1043// res += snoise2;
1044// if (res<2*snoise2)
1045// res = 2*snoise2;
1046// if (res>3) res =3;
1047// seed->SetErrorZ2(res);
1048// return res;
91162307 1049}
1050
1051
1052
91162307 1053
1c53abe2 1054
829455ad 1055void AliTPCtracker::RotateToLocal(AliTPCseed *seed)
c9427e08 1056{
1057 //rotate to track "local coordinata
1058 Float_t x = seed->GetX();
1059 Float_t y = seed->GetY();
1060 Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
91162307 1061
c9427e08 1062 if (y > ymax) {
b9671574 1063 seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
c9427e08 1064 if (!seed->Rotate(fSectors->GetAlpha()))
1065 return;
1066 } else if (y <-ymax) {
b9671574 1067 seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
c9427e08 1068 if (!seed->Rotate(-fSectors->GetAlpha()))
1069 return;
1070 }
1c53abe2 1071
c9427e08 1072}
1c53abe2 1073
1074
1075
1c53abe2 1076//_____________________________________________________________________________
829455ad 1077Double_t AliTPCtracker::F1old(Double_t x1,Double_t y1,
1c53abe2 1078 Double_t x2,Double_t y2,
47af7ca4 1079 Double_t x3,Double_t y3) const
1c53abe2 1080{
1081 //-----------------------------------------------------------------
1082 // Initial approximation of the track curvature
1083 //-----------------------------------------------------------------
1084 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1085 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1086 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1087 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1088 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1089
1090 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
91162307 1091 if ( xr*xr+yr*yr<=0.00000000000001) return 100;
1c53abe2 1092 return -xr*yr/sqrt(xr*xr+yr*yr);
1093}
1094
1095
91162307 1096
1c53abe2 1097//_____________________________________________________________________________
829455ad 1098Double_t AliTPCtracker::F1(Double_t x1,Double_t y1,
91162307 1099 Double_t x2,Double_t y2,
47af7ca4 1100 Double_t x3,Double_t y3) const
91162307 1101{
1102 //-----------------------------------------------------------------
1103 // Initial approximation of the track curvature
1104 //-----------------------------------------------------------------
1105 x3 -=x1;
1106 x2 -=x1;
1107 y3 -=y1;
1108 y2 -=y1;
1109 //
1110 Double_t det = x3*y2-x2*y3;
6e23caff 1111 if (TMath::Abs(det)<1e-10){
91162307 1112 return 100;
1113 }
1114 //
1115 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1116 Double_t x0 = x3*0.5-y3*u;
1117 Double_t y0 = y3*0.5+x3*u;
1118 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1119 if (det<0) c2*=-1;
1120 return c2;
1121}
1122
1123
829455ad 1124Double_t AliTPCtracker::F2(Double_t x1,Double_t y1,
1c53abe2 1125 Double_t x2,Double_t y2,
47af7ca4 1126 Double_t x3,Double_t y3) const
91162307 1127{
1128 //-----------------------------------------------------------------
1129 // Initial approximation of the track curvature
1130 //-----------------------------------------------------------------
1131 x3 -=x1;
1132 x2 -=x1;
1133 y3 -=y1;
1134 y2 -=y1;
1135 //
1136 Double_t det = x3*y2-x2*y3;
6e23caff 1137 if (TMath::Abs(det)<1e-10) {
91162307 1138 return 100;
1139 }
1140 //
1141 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1142 Double_t x0 = x3*0.5-y3*u;
1143 Double_t y0 = y3*0.5+x3*u;
1144 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1145 if (det<0) c2*=-1;
1146 x0+=x1;
1147 x0*=c2;
1148 return x0;
1149}
1150
1151
1152
1153//_____________________________________________________________________________
829455ad 1154Double_t AliTPCtracker::F2old(Double_t x1,Double_t y1,
91162307 1155 Double_t x2,Double_t y2,
47af7ca4 1156 Double_t x3,Double_t y3) const
1c53abe2 1157{
1158 //-----------------------------------------------------------------
1159 // Initial approximation of the track curvature times center of curvature
1160 //-----------------------------------------------------------------
1161 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1162 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1163 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1164 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1165 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1166
1167 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1168
1169 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1170}
1171
1172//_____________________________________________________________________________
829455ad 1173Double_t AliTPCtracker::F3(Double_t x1,Double_t y1,
1c53abe2 1174 Double_t x2,Double_t y2,
47af7ca4 1175 Double_t z1,Double_t z2) const
1c53abe2 1176{
1177 //-----------------------------------------------------------------
1178 // Initial approximation of the tangent of the track dip angle
1179 //-----------------------------------------------------------------
1180 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1181}
1182
1183
829455ad 1184Double_t AliTPCtracker::F3n(Double_t x1,Double_t y1,
91162307 1185 Double_t x2,Double_t y2,
47af7ca4 1186 Double_t z1,Double_t z2, Double_t c) const
1c53abe2 1187{
91162307 1188 //-----------------------------------------------------------------
1189 // Initial approximation of the tangent of the track dip angle
1190 //-----------------------------------------------------------------
1191
1192 // Double_t angle1;
1193
1194 //angle1 = (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1c53abe2 1195 //
91162307 1196 Double_t d = TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1197 if (TMath::Abs(d*c*0.5)>1) return 0;
1198 // Double_t angle2 = TMath::ASin(d*c*0.5);
b67e07dc 1199 // Double_t angle2 = AliTPCFastMath::FastAsin(d*c*0.5);
1200 Double_t angle2 = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): AliTPCFastMath::FastAsin(d*c*0.5);
91162307 1201
1202 angle2 = (z1-z2)*c/(angle2*2.);
1203 return angle2;
1204}
1205
829455ad 1206Bool_t AliTPCtracker::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
91162307 1207{//-----------------------------------------------------------------
1208 // This function find proloncation of a track to a reference plane x=x2.
1209 //-----------------------------------------------------------------
1210
1211 Double_t dx=x2-x1;
1212
1213 if (TMath::Abs(x[4]*x1 - x[2]) >= 0.999) {
1214 return kFALSE;
1c53abe2 1215 }
f8aae377 1216
bfd20868 1217 Double_t c1=x[4]*x1 - x[2], r1=TMath::Sqrt((1.-c1)*(1.+c1));
1218 Double_t c2=x[4]*x2 - x[2], r2=TMath::Sqrt((1.-c2)*(1.+c2));
91162307 1219 y = x[0];
1220 z = x[1];
1221
1222 Double_t dy = dx*(c1+c2)/(r1+r2);
1223 Double_t dz = 0;
1224 //
1225 Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1226
1227 if (TMath::Abs(delta)>0.01){
1228 dz = x[3]*TMath::ASin(delta)/x[4];
1229 }else{
b67e07dc 1230 dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
91162307 1231 }
1232
b67e07dc 1233 //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
f8aae377 1234
91162307 1235 y+=dy;
1236 z+=dz;
1237
1238 return kTRUE;
1c53abe2 1239}
1240
829455ad 1241Int_t AliTPCtracker::LoadClusters (TTree *const tree)
d26d9159 1242{
544c295f 1243 // load clusters
d26d9159 1244 //
1245 fInput = tree;
1246 return LoadClusters();
1247}
91162307 1248
af86c1fd 1249
829455ad 1250Int_t AliTPCtracker::LoadClusters(const TObjArray *arr)
af86c1fd 1251{
1252 //
1253 // load clusters to the memory
e7de6656 1254 AliTPCClustersRow *clrow = new AliTPCClustersRow("AliTPCclusterMI");
af86c1fd 1255 Int_t lower = arr->LowerBound();
1256 Int_t entries = arr->GetEntriesFast();
77f88633 1257
af86c1fd 1258 for (Int_t i=lower; i<entries; i++) {
1259 clrow = (AliTPCClustersRow*) arr->At(i);
77f88633 1260 if(!clrow) continue;
1261 if(!clrow->GetArray()) continue;
1262
af86c1fd 1263 //
1264 Int_t sec,row;
47af7ca4 1265 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
77f88633 1266
af86c1fd 1267 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1268 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1269 }
1270 //
1271 if (clrow->GetArray()->GetEntriesFast()<=0) continue;
bd26fa83 1272 AliTPCtrackerRow * tpcrow=0;
af86c1fd 1273 Int_t left=0;
1274 if (sec<fkNIS*2){
1275 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1276 left = sec/fkNIS;
1277 }
1278 else{
1279 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1280 left = (sec-fkNIS*2)/fkNOS;
1281 }
1282 if (left ==0){
1283 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
77f88633 1284 for (Int_t j=0;j<tpcrow->GetN1();++j)
1285 tpcrow->SetCluster1(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
af86c1fd 1286 }
1287 if (left ==1){
1288 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
77f88633 1289 for (Int_t j=0;j<tpcrow->GetN2();++j)
bfa00fba 1290 tpcrow->SetCluster2(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
af86c1fd 1291 }
e7de6656 1292 clrow->GetArray()->Clear("C");
af86c1fd 1293 }
1294 //
1295 delete clrow;
1296 LoadOuterSectors();
1297 LoadInnerSectors();
1298 return 0;
1299}
1300
829455ad 1301Int_t AliTPCtracker::LoadClusters(const TClonesArray *arr)
aa7f1a5a 1302{
1303 //
1304 // load clusters to the memory from one
1305 // TClonesArray
1306 //
1307 AliTPCclusterMI *clust=0;
98ee6d31 1308 Int_t count[72][96] = { {0} , {0} };
aa7f1a5a 1309
1310 // loop over clusters
1311 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1312 clust = (AliTPCclusterMI*)arr->At(icl);
1313 if(!clust) continue;
1314 //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
1315
1316 // transform clusters
1317 Transform(clust);
1318
1319 // count clusters per pad row
1320 count[clust->GetDetector()][clust->GetRow()]++;
1321 }
1322
1323 // insert clusters to sectors
1324 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1325 clust = (AliTPCclusterMI*)arr->At(icl);
1326 if(!clust) continue;
1327
1328 Int_t sec = clust->GetDetector();
1329 Int_t row = clust->GetRow();
98ee6d31 1330
1331 // filter overlapping pad rows needed by HLT
1332 if(sec<fkNIS*2) { //IROCs
1333 if(row == 30) continue;
1334 }
1335 else { // OROCs
1336 if(row == 27 || row == 76) continue;
1337 }
1338
2a97785a 1339 // Int_t left=0;
aa7f1a5a 1340 if (sec<fkNIS*2){
2a97785a 1341 // left = sec/fkNIS;
47af7ca4 1342 fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fkParam);
aa7f1a5a 1343 }
1344 else{
2a97785a 1345 // left = (sec-fkNIS*2)/fkNOS;
47af7ca4 1346 fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fkParam);
aa7f1a5a 1347 }
1348 }
1349
98ee6d31 1350 // Load functions must be called behind LoadCluster(TClonesArray*)
1351 // needed by HLT
1352 //LoadOuterSectors();
1353 //LoadInnerSectors();
aa7f1a5a 1354
1355 return 0;
1356}
1357
af86c1fd 1358
829455ad 1359Int_t AliTPCtracker::LoadClusters()
1c53abe2 1360{
1361 //
434cdbe1 1362 // load clusters to the memory
1363 Int_t nROCs = 72;
bfa00fba 1364 static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
91162307 1365 //
1366 // TTree * tree = fClustersArray.GetTree();
9a836cc2 1367 AliInfo("LoadClusters()\n");
39240815 1368 // reset crosstalk matrix
1369 //
434cdbe1 1370 for (Int_t isector=0; isector<nROCs*2; isector++){ //set all ellemts of crosstalk matrix to 0
39240815 1371 TMatrixD * crossTalkMatrix = (TMatrixD*)fCrossTalkSignalArray->At(isector);
1372 if (crossTalkMatrix)(*crossTalkMatrix)*=0;
1373 }
91162307 1374
1375 TTree * tree = fInput;
1376 TBranch * br = tree->GetBranch("Segment");
1377 br->SetAddress(&clrow);
bad6eb00 1378
1379 // Conversion of pad, row coordinates in local tracking coords.
1380 // Could be skipped here; is already done in clusterfinder
1381
6f8ff889 1382
91162307 1383 Int_t j=Int_t(tree->GetEntries());
1c53abe2 1384 for (Int_t i=0; i<j; i++) {
91162307 1385 br->GetEntry(i);
1386 //
1387 Int_t sec,row;
47af7ca4 1388 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
8cc1870a 1389
1390 // wire segmentID and nPadsPerSegment to be used for Xtalk calculation
1391 Int_t wireSegmentID = fkParam->GetWireSegment(sec,row);
1392 Float_t nPadsPerSegment = (Float_t)(fkParam->GetNPadsPerSegment(wireSegmentID));
1393 TMatrixD &crossTalkSignal = *((TMatrixD*)fCrossTalkSignalArray->At(sec));
434cdbe1 1394 TMatrixD &crossTalkSignalBelow = *((TMatrixD*)fCrossTalkSignalArray->At(sec+nROCs));
265b5e37 1395 Int_t nCols=crossTalkSignal.GetNcols();
3449a97c 1396 Double_t missingChargeFactor= AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrectionMissingCharge();
0201b65c 1397 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
8cc1870a 1398 AliTPCclusterMI *clXtalk= static_cast<AliTPCclusterMI*>(clrow->GetArray()->At(icl));
8cc1870a 1399 Transform((AliTPCclusterMI*)(clXtalk));
434cdbe1 1400 Int_t timeBinXtalk = clXtalk->GetTimeBin();
1401 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
1402 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
6f8ff889 1403 Double_t rmsTime2 = clXtalk->GetSigmaZ2()/(fkParam->GetZWidth()*fkParam->GetZWidth());
3449a97c 1404 Double_t rmsPad2 = clXtalk->GetSigmaY2()/(fkParam->GetPadPitchWidth(sec)*fkParam->GetPadPitchWidth(sec));
434cdbe1 1405 if (rmsPadMin2>rmsPad2){
1406 rmsPad2=rmsPadMin2;
1407 }
1408 if (rmsTimeMin2>rmsTime2){
1409 rmsTime2=rmsTimeMin2;
1410 }
3449a97c 1411
6f8ff889 1412 Double_t norm= 2.*TMath::Exp(-1.0/(2.*rmsTime2))+2.*TMath::Exp(-4.0/(2.*rmsTime2))+1.;
434cdbe1 1413 Double_t qTotXtalk = 0.;
1414 Double_t qTotXtalkMissing = 0.;
6f8ff889 1415 for (Int_t itb=timeBinXtalk-2, idelta=-2; itb<=timeBinXtalk+2; itb++,idelta++) {
265b5e37 1416 if (itb<0 || itb>=nCols) continue;
3449a97c 1417 Double_t missingCharge=0;
1418 Double_t trf= TMath::Exp(-idelta*idelta/(2.*rmsTime2));
434cdbe1 1419 if (missingChargeFactor>0) {
1420 for (Int_t dpad=-2; dpad<=2; dpad++){
1421 Double_t qPad = clXtalk->GetMax()*TMath::Exp(-dpad*dpad/(2.*rmsPad2))*trf;
1422 qPad-=2.*crossTalkSignal[wireSegmentID][itb]; // missing part due crosttalk - feedback part - factor 2 used
1423 if (TMath::Nint(qPad)<=fkParam->GetZeroSup()){
1424 missingCharge+=qPad+2.*crossTalkSignal[wireSegmentID][itb];
1425 }else{
1426 missingCharge+=2.*crossTalkSignal[wireSegmentID][itb];
1427 }
3449a97c 1428 }
1429 }
434cdbe1 1430 qTotXtalk = clXtalk->GetQ()*trf/norm+missingCharge*missingChargeFactor;
1431 qTotXtalkMissing = missingCharge;
1432 crossTalkSignal[wireSegmentID][itb]+= qTotXtalk/nPadsPerSegment;
1433 crossTalkSignalBelow[wireSegmentID][itb]+= qTotXtalkMissing/nPadsPerSegment;
1434 }
0201b65c 1435 }
434cdbe1 1436
91162307 1437 //
bd26fa83 1438 AliTPCtrackerRow * tpcrow=0;
91162307 1439 Int_t left=0;
1440 if (sec<fkNIS*2){
1441 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1442 left = sec/fkNIS;
1443 }
1444 else{
1445 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1446 left = (sec-fkNIS*2)/fkNOS;
1447 }
1448 if (left ==0){
b9671574 1449 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
77f88633 1450 for (Int_t k=0;k<tpcrow->GetN1();++k)
1451 tpcrow->SetCluster1(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
91162307 1452 }
1453 if (left ==1){
b9671574 1454 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
77f88633 1455 for (Int_t k=0;k<tpcrow->GetN2();++k)
bfa00fba 1456 tpcrow->SetCluster2(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
91162307 1457 }
1c53abe2 1458 }
434cdbe1 1459 if (AliTPCReconstructor::StreamLevel()==1) {
1460 //
1461 // dump the crosstalk matrices to tree for further investigation
1462 // a.) to estimate fluctuation of pedestal in indiviula wire segments
1463 // b.) to check correlation between regions
1464 // c.) to check relative conribution of signal below threshold to crosstalk
1465 for (Int_t isector=0; isector<nROCs; isector++){ //set all ellemts of crosstalk matrix to 0
1466 TMatrixD * crossTalkMatrix = (TMatrixD*)fCrossTalkSignalArray->At(isector);
1467 TMatrixD * crossTalkMatrixBelow = (TMatrixD*)fCrossTalkSignalArray->At(isector+nROCs);
1468 TVectorD vecAll(crossTalkMatrix->GetNrows());
1469 TVectorD vecBelow(crossTalkMatrix->GetNrows());
1470 //
1471 for (Int_t itime=0; itime<crossTalkMatrix->GetNcols(); itime++){
1472 for (Int_t iwire=0; iwire<crossTalkMatrix->GetNrows(); iwire++){
1473 vecAll[iwire]=(*crossTalkMatrix)(iwire,itime);
1474 vecBelow[iwire]=(*crossTalkMatrixBelow)(iwire,itime);
1475 }
1476 (*fDebugStreamer)<<"crosstalkMatrix"<<
1477 "sector="<<isector<<
1478 "itime="<<itime<<
1479 "vecAll.="<<&vecAll<< // crosstalk charge + charge below threshold
1480 "vecBelow.="<<&vecBelow<< // crosstalk contribution from signal below threshold
1481 "\n";
1482 }
1483 }
1484 }
1485
1486
91162307 1487 //
bfa00fba 1488 clrow->Clear("C");
91162307 1489 LoadOuterSectors();
1490 LoadInnerSectors();
6f8ff889 1491
1492 cout << " =================================================================================================================================== " << endl;
1493 cout << " AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection() = " << AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection() << endl;
1494 cout << " AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection() = " << AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection() << endl;
1495 cout << " =================================================================================================================================== " << endl;
1496
832977ba 1497 if (AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection()) ApplyTailCancellation();
265b5e37 1498 if (AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection()!=0.) ApplyXtalkCorrection();
44ca7282 1499 if (AliTPCReconstructor::GetRecoParam()->GetUseOulierClusterFilter()) FilterOutlierClusters();
91162307 1500 return 0;
1c53abe2 1501}
1502
eea44233 1503void AliTPCtracker::FilterOutlierClusters(){
1504 //
1505 // filter outlier clusters
1506 //
1507 /*
1508 1.)..... booking part
1509 nSectors=72;
1510 nTimeBins=fParam->Get....
1511 TH2F hisTime("","", sector,0,sector, nTimeBins,0,nTimeBins);
1512 TH2F hisPadRow("","", sector,0,sector, nPadRows,0,nPadRows);
1513 2.) .... filling part
1514 .... cluster loop { hisTime.Fill(cluster->GetDetector(),cluster->GetTimeBin()); }
1515
1516 3.) ...filtering part
1517 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... }
1518
1519 sector loop
1520 { 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 }
1521 //
1522 4. Disabling clusters
1523
1524 */
1525
1526 //
1527 // 1.) booking part
e731a3f8 1528 //
1529 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
1530 Int_t nSectors=AliTPCROC::Instance()->GetNSectors();
1531 Int_t nTimeBins= db->GetParameters()->GetMaxTBin();
44ca7282 1532 Int_t nPadRows=AliTPCROC::Instance()->GetNRows(0) + AliTPCROC::Instance()->GetNRows(36);
e731a3f8 1533 // parameters for filtering
1534 const Double_t nSigmaCut=9.; // should be in recoParam ?
1535 const Double_t offsetTime=100; // should be in RecoParam ? -
1536 const Double_t offsetPadRow=300; // should be in RecoParam ?
1537 const Double_t offsetTimeAccept=8; // should be in RecoParam ? - obtained as mean +1 rms in high IR pp
eea44233 1538 TH2F hisTime("hisSectorTime","hisSectorTime", nSectors,0,nSectors, nTimeBins,0,nTimeBins);
1539 TH2F hisPadRow("hisSectorRow","hisSectorRow", nSectors,0,nSectors, nPadRows,0,nPadRows);
1540 //
1541 // 2.) Filling part -- loop over clusters
1542 //
44ca7282 1543 for (Int_t isector=0; isector<36; isector++){ // loop over sectors
1544 for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1545 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1546 Int_t nrows = sector.GetNRows();
1547 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1548 AliTPCtrackerRow& tpcrow = sector[row];
1549 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1550 if (iside>0) ncl=tpcrow.GetN2();
1551 for (Int_t i=0;i<ncl;i++) { // loop over clusters
1552 AliTPCclusterMI *cluster= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1553 hisTime.Fill(cluster->GetDetector(),cluster->GetTimeBin());
1554 hisPadRow.Fill(cluster->GetDetector(),cluster->GetRow());
1555 }
1556 }
1557 }
1558 }
44ca7282 1559
eea44233 1560 //
1561 // 3. Filtering part
1562 //
1563 TVectorD vecTime(nTimeBins);
44ca7282 1564 TVectorD vecPadRow(nPadRows);
c5dce091 1565 TVectorD vecMedianSectorTime(nSectors);
44ca7282 1566 TVectorD vecRMSSectorTime(nSectors);
c5dce091 1567 TVectorD vecMedianSectorTimeOut6(nSectors);
1568 TVectorD vecMedianSectorTimeOut9(nSectors);//
1569 TVectorD vecMedianSectorPadRow(nSectors);
44ca7282 1570 TVectorD vecRMSSectorPadRow(nSectors);
c5dce091 1571 TVectorD vecMedianSectorPadRowOut6(nSectors);
1572 TVectorD vecMedianSectorPadRowOut9(nSectors);
e731a3f8 1573 TVectorD vecSectorOut6(nSectors);
1574 TVectorD vecSectorOut9(nSectors);
1575 //
1576 // 3.a) median, rms calculations for hisTime
1577 //
eea44233 1578 for (Int_t isec=0; isec<nSectors; isec++){
c5dce091 1579 vecMedianSectorTimeOut6[isec]=0;
1580 vecMedianSectorTimeOut9[isec]=0;
eea44233 1581 for (Int_t itime=0; itime<nTimeBins; itime++){
1582 vecTime[itime]=hisTime.GetBinContent(isec+1, itime+1);
1583 }
1584 Double_t median= TMath::Median(nTimeBins,vecTime.GetMatrixArray());
c5dce091 1585 Double_t rms= TMath::RMS(nTimeBins,vecTime.GetMatrixArray());
1586 vecMedianSectorTime[isec]=median;
44ca7282 1587 vecRMSSectorTime[isec]=rms;
eea44233 1588 printf("%d\t%f\t%f\n",isec,median,rms);
1589 //
1590 // declare outliers
1591 for (Int_t itime=0; itime<nTimeBins; itime++){
1592 Double_t entries= hisTime.GetBinContent(isec+1, itime+1);
44ca7282 1593 if (entries>median+6.*rms+offsetTime) {
c5dce091 1594 vecMedianSectorTimeOut6[isec]+=1;
1595 }
44ca7282 1596 if (entries>median+9.*rms+offsetTime) {
c5dce091 1597 vecMedianSectorTimeOut9[isec]+=1;
eea44233 1598 }
1599 }
c5dce091 1600 }
e731a3f8 1601 //
1602 // 3.b) median, rms calculations for hisPadRow
1603 //
44ca7282 1604 for (Int_t isec=0; isec<nSectors; isec++){
1605 vecMedianSectorPadRowOut6[isec]=0;
1606 vecMedianSectorPadRowOut9[isec]=0;
1607 for (Int_t ipadrow=0; ipadrow<nPadRows; ipadrow++){
1608 vecPadRow[ipadrow]=hisPadRow.GetBinContent(isec+1, ipadrow+1);
1609 }
1610 Double_t median= TMath::Median(nPadRows,vecPadRow.GetMatrixArray());
1611 Double_t rms= TMath::RMS(nPadRows,vecPadRow.GetMatrixArray());
1612 vecMedianSectorPadRow[isec]=median;
1613 vecRMSSectorPadRow[isec]=rms;
1614 printf("%d\t%f\t%f\n",isec,median,rms);
1615 //
1616 // declare outliers
1617 for (Int_t ipadrow=0; ipadrow<nPadRows; ipadrow++){
1618 Double_t entries= hisPadRow.GetBinContent(isec+1, ipadrow+1);
1619 if (entries>median+6.*rms+offsetPadRow) {
1620 vecMedianSectorPadRowOut6[isec]+=1;
1621 }
1622 if (entries>median+9.*rms+offsetPadRow) {
1623 vecMedianSectorPadRowOut9[isec]+=1;
1624 }
1625 }
1626 }
1627 //
e731a3f8 1628 // 3.c) filter outlier sectors
1629 //
1630 Double_t medianSectorTime = TMath::Median(nSectors, vecTime.GetMatrixArray());
1631 Double_t mean69SectorTime, rms69SectorTime=0;
1632 AliMathBase::EvaluateUni(nSectors, vecTime.GetMatrixArray(), mean69SectorTime,rms69SectorTime,69);
1633 for (Int_t isec=0; isec<nSectors; isec++){
1634 vecSectorOut6[isec]=0;
1635 vecSectorOut9[isec]=0;
1636 if (TMath::Abs(vecTime[isec])>(mean69SectorTime+6.*(rms69SectorTime+ offsetTimeAccept))) vecSectorOut6[isec]=1;
1637 if (TMath::Abs(vecTime[isec])>(mean69SectorTime+9.*(rms69SectorTime+ offsetTimeAccept))) vecSectorOut9[isec]=1;
1638 }
1639 // light version of export variable
1640 Int_t filteredSector= vecSectorOut9.Sum(); // light version of export variable
1641 Int_t filteredSectorTime= vecMedianSectorTimeOut9.Sum();
1642 Int_t filteredSectorPadRow= vecMedianSectorPadRowOut9.Sum();
1643 fEvent->SetTPCNoiseFilterCounter(0,TMath::Min(filteredSector,255));
1644 fEvent->SetTPCNoiseFilterCounter(1,TMath::Min(filteredSectorTime,255));
1645 fEvent->SetTPCNoiseFilterCounter(2,TMath::Min(filteredSectorPadRow,255));
1646 //
44ca7282 1647 // dump info to streamer - for later tuning of cuts
1648 //
1649 if ((AliTPCReconstructor::StreamLevel()%4)>0) { //bit 4 used
c5dce091 1650 (*fDebugStreamer)<<"filterClusterInfo"<<
e731a3f8 1651 // minimal set variables for the ESDevent
1652 "filteredSector="<<filteredSector<< // counter filtered sectors
1653 "filteredSectorTime="<<filteredSectorTime<< // counter filtered time bins
1654 "filteredSectorPadRow="<<filteredSectorPadRow<< // counter filtered pad-rows
1655 // per sector outlier information
1656 "medianSectorTime="<<medianSectorTime<< // median number of clusters per sector/timebin
1657 "mean69SectorTime="<<mean69SectorTime<< // LTM statistic mean of clusters per sector/timebin
1658 "rms69SectorTime="<<rms69SectorTime<< // LTM statistic RMS of clusters per sector/timebin
1659 "vecSectorOut6.="<<&vecSectorOut6<< // flag array sector - 6 sigma +accept margin outlier
1660 "vecSectorOut9.="<<&vecSectorOut9<< // flag array sector - 9 sigma + accept margin outlier
1661 // per sector/timebin outlier detection
c5dce091 1662 "vecMedianSectorTime.="<<&vecMedianSectorTime<<
44ca7282 1663 "vecRMSSectorTime.="<<&vecRMSSectorTime<<
c5dce091 1664 "vecMedianSectorTimeOut6.="<<&vecMedianSectorTimeOut6<<
1665 "vecMedianSectorTimeOut9.="<<&vecMedianSectorTimeOut9<<
e731a3f8 1666 // per sector/pad-row outlier detection
c5dce091 1667 "vecMedianSectorPadRow.="<<&vecMedianSectorPadRow<<
44ca7282 1668 "vecRMSSectorPadRow.="<<&vecRMSSectorPadRow<<
c5dce091 1669 "vecMedianSectorPadRowOut6.="<<&vecMedianSectorPadRowOut6<<
1670 "vecMedianSectorPadRowOut9.="<<&vecMedianSectorPadRowOut9<<
1671 "\n";
eea44233 1672 }
44ca7282 1673 //
1674 // 4. Disabling clusters in outlier layers
1675 //
1676 for (Int_t isector=0; isector<36; isector++){ // loop over sectors
1677 for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1678 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1679 Int_t nrows = sector.GetNRows();
1680 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1681 AliTPCtrackerRow& tpcrow = sector[row];
1682 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1683 if (iside>0) ncl=tpcrow.GetN2();
1684 for (Int_t i=0;i<ncl;i++) { // loop over clusters
1685 AliTPCclusterMI *cluster= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1686 Double_t medianTime=vecMedianSectorTime[cluster->GetDetector()];
1687 Double_t medianPadRow=vecMedianSectorPadRow[cluster->GetDetector()];
1688 Double_t rmsTime=vecRMSSectorTime[cluster->GetDetector()];
1689 Double_t rmsPadRow=vecRMSSectorPadRow[cluster->GetDetector()];
1690 Int_t entriesPadRow=hisPadRow.GetBinContent(cluster->GetDetector()+1, cluster->GetRow()+1);
1691 Int_t entriesTime=hisTime.GetBinContent(cluster->GetDetector()+1, cluster->GetTimeBin()+1);
1692 Bool_t isOut=kFALSE;
e731a3f8 1693 if (vecSectorOut9[isector]>0.5) isOut=kTRUE;
1694
44ca7282 1695 if (entriesTime>medianTime+nSigmaCut*rmsTime+offsetTime) isOut=kTRUE;
1696 if (entriesPadRow>medianPadRow+nSigmaCut*rmsPadRow+offsetPadRow) isOut=kTRUE;
1697 if (isOut){
1698 cluster->Disable();
1699 }
1700 }
1701 }
1702 }
1703 }
eea44233 1704}
1705
829455ad 1706void AliTPCtracker::UnloadClusters()
91162307 1707{
1708 //
1709 // unload clusters from the memory
1710 //
1711 Int_t nrows = fOuterSec->GetNRows();
1712 for (Int_t sec = 0;sec<fkNOS;sec++)
1713 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1714 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
982aff31 1715 // if (tpcrow){
1716 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1717 // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1718 //}
1719 tpcrow->ResetClusters();
1c53abe2 1720 }
91162307 1721 //
1722 nrows = fInnerSec->GetNRows();
1723 for (Int_t sec = 0;sec<fkNIS;sec++)
1724 for (Int_t row = 0;row<nrows;row++){
bd26fa83 1725 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
982aff31 1726 //if (tpcrow){
1727 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1728 //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1729 //}
1730 tpcrow->ResetClusters();
91162307 1731 }
1732
1733 return ;
1c53abe2 1734}
1735
829455ad 1736void AliTPCtracker::FillClusterArray(TObjArray* array) const{
002af263 1737 //
1738 // Filling cluster to the array - For visualization purposes
1739 //
1740 Int_t nrows=0;
1741 nrows = fOuterSec->GetNRows();
1742 for (Int_t sec = 0;sec<fkNOS;sec++)
1743 for (Int_t row = 0;row<nrows;row++){
1744 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1745 if (!tpcrow) continue;
1746 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1747 array->AddLast((TObject*)((*tpcrow)[icl]));
1748 }
1749 }
1750 nrows = fInnerSec->GetNRows();
1751 for (Int_t sec = 0;sec<fkNIS;sec++)
1752 for (Int_t row = 0;row<nrows;row++){
1753 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1754 if (!tpcrow) continue;
1755 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1756 array->AddLast((TObject*)(*tpcrow)[icl]);
1757 }
1758 }
1759}
1760
1761
829455ad 1762void AliTPCtracker::Transform(AliTPCclusterMI * cluster){
893468d9 1763 //
544c295f 1764 // transformation
893468d9 1765 //
3f3549a3 1766 AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1767 AliTPCTransform *transform = calibDB->GetTransform() ;
24db6af7 1768 if (!transform) {
1769 AliFatal("Tranformations not in calibDB");
ec26e231 1770 return;
24db6af7 1771 }
239f39b1 1772 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
2942f542 1773 Double_t x[3]={static_cast<Double_t>(cluster->GetRow()),static_cast<Double_t>(cluster->GetPad()),static_cast<Double_t>(cluster->GetTimeBin())};
24db6af7 1774 Int_t i[1]={cluster->GetDetector()};
022ee144 1775 transform->Transform(x,i,0,1);
afbaa016 1776 // if (cluster->GetDetector()%36>17){
1777 // x[1]*=-1;
1778 //}
022ee144 1779
24db6af7 1780 //
1781 // in debug mode check the transformation
1782 //
16299eac 1783 if (AliTPCReconstructor::StreamLevel()>2) {
af86c1fd 1784 Float_t gx[3];
1785 cluster->GetGlobalXYZ(gx);
002af263 1786 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
24db6af7 1787 TTreeSRedirector &cstream = *fDebugStreamer;
1788 cstream<<"Transform"<<
002af263 1789 "event="<<event<<
24db6af7 1790 "x0="<<x[0]<<
1791 "x1="<<x[1]<<
1792 "x2="<<x[2]<<
af86c1fd 1793 "gx0="<<gx[0]<<
1794 "gx1="<<gx[1]<<
1795 "gx2="<<gx[2]<<
24db6af7 1796 "Cl.="<<cluster<<
1797 "\n";
1798 }
1799 cluster->SetX(x[0]);
1800 cluster->SetY(x[1]);
1801 cluster->SetZ(x[2]);
19b00333 1802 // The old stuff:
0201b65c 1803 //
1804 //
1805 //
47af7ca4 1806 //if (!fkParam->IsGeoRead()) fkParam->ReadGeoMatrices();
3f3549a3 1807 if (AliTPCReconstructor::GetRecoParam()->GetUseSectorAlignment() && (!calibDB->HasAlignmentOCDB())){
1808 TGeoHMatrix *mat = fkParam->GetClusterMatrix(cluster->GetDetector());
1809 //TGeoHMatrix mat;
1810 Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1811 Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1812 if (mat) mat->LocalToMaster(pos,posC);
1813 else{
1814 // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
1815 }
1816 cluster->SetX(posC[0]);
1817 cluster->SetY(posC[1]);
1818 cluster->SetZ(posC[2]);
a7760332 1819 }
0201b65c 1820}
1c53abe2 1821
265b5e37 1822void AliTPCtracker::ApplyXtalkCorrection(){
1823 //
1824 // ApplyXtalk correction
1825 // Loop over all clusters
1826 // add to each cluster signal corresponding to common Xtalk mode for given time bin at given wire segment
265b5e37 1827 // cluster loop
1828 for (Int_t isector=0; isector<36; isector++){ //loop tracking sectors
1829 for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1830 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1831 Int_t nrows = sector.GetNRows();
1832 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1833 AliTPCtrackerRow& tpcrow = sector[row]; // row object
1834 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1835 if (iside>0) ncl=tpcrow.GetN2();
1836 Int_t xSector=0; // sector number in the TPC convention 0-72
1837 if (isector<18){ //if IROC
1838 xSector=isector+(iside>0)*18;
1839 }else{
1840 xSector=isector+18; // isector -18 +36
1841 if (iside>0) xSector+=18;
1842 }
1843 TMatrixD &crossTalkMatrix= *((TMatrixD*)fCrossTalkSignalArray->At(xSector));
1844 Int_t wireSegmentID = fkParam->GetWireSegment(xSector,row);
1845 for (Int_t i=0;i<ncl;i++) {
1846 AliTPCclusterMI *cluster= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1847 Int_t iTimeBin=TMath::Nint(cluster->GetTimeBin());
1848 Double_t xTalk= crossTalkMatrix[wireSegmentID][iTimeBin];
1849 cluster->SetMax(cluster->GetMax()+xTalk);
6f8ff889 1850 const Double_t kDummy=4;
265b5e37 1851 Double_t sumxTalk=xTalk*kDummy; // should be calculated via time response function
1852 cluster->SetQ(cluster->GetQ()+sumxTalk);
6f8ff889 1853
1854
1855 if (AliTPCReconstructor::StreamLevel()==1) {
1856 TTreeSRedirector &cstream = *fDebugStreamer;
1857 if (gRandom->Rndm() > 0.){
1858 cstream<<"Xtalk"<<
1859 "isector=" << isector << // sector [0,36]
1860 "iside=" << iside << // side A or C
1861 "row=" << row << // padrow
1862 "i=" << i << // index of the cluster
1863 "xSector=" << xSector << // sector [0,72]
1864 "wireSegmentID=" << wireSegmentID << // anode wire segment id [0,10]
1865 "iTimeBin=" << iTimeBin << // timebin of the corrected cluster
1866 "xTalk=" << xTalk << // Xtalk contribution added to Qmax
1867 "sumxTalk=" << sumxTalk << // Xtalk contribution added to Qtot (roughly 3*Xtalk)
1868 "cluster.=" << cluster << // corrected cluster object
1869 "\n";
1870 }
1871 }// dump the results to the debug streamer if in debug mode
1872
1873
1874
1875
1876
265b5e37 1877 }
1878 }
1879 }
1880 }
1881}
1882
9a836cc2 1883void AliTPCtracker::ApplyTailCancellation(){
7bc5f28b 1884 //
9a836cc2 1885 // Correct the cluster charge for the ion tail effect
7bc5f28b 1886 // The TimeResponse function accessed via AliTPCcalibDB (TPC/Calib/IonTail)
1887 //
7bc5f28b 1888
9a836cc2 1889 // Retrieve
1890 TObjArray *ionTailArr = (TObjArray*)AliTPCcalibDB::Instance()->GetIonTailArray();
1891 if (!ionTailArr) {AliFatal("TPC - Missing IonTail OCDB object");}
1892 TObject *rocFactorIROC = ionTailArr->FindObject("factorIROC");
1893 TObject *rocFactorOROC = ionTailArr->FindObject("factorOROC");
1894 Float_t factorIROC = (atof(rocFactorIROC->GetTitle()));
1895 Float_t factorOROC = (atof(rocFactorOROC->GetTitle()));
1896
1897 // find the number of clusters for the whole TPC (nclALL)
1898 Int_t nclALL=0;
1899 for (Int_t isector=0; isector<36; isector++){
1900 AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1901 nclALL += sector.GetNClInSector(0);
1902 nclALL += sector.GetNClInSector(1);
1903 }
1904
1905 // start looping over all clusters
1906 for (Int_t iside=0; iside<2; iside++){ // loop over sides
7bc5f28b 1907 //
1908 //
9a836cc2 1909 for (Int_t secType=0; secType<2; secType++){ //loop over inner or outer sector
1910 // cache experimantal tuning factor for the different chamber type
1911 const Float_t ampfactor = (secType==0)?factorIROC:factorOROC;
1912 std::cout << " ampfactor = " << ampfactor << std::endl;
7bc5f28b 1913 //
9a836cc2 1914 for (Int_t sec = 0;sec<fkNOS;sec++){ //loop overs sectors
1915 //
1916 //
1917 // Cache time response functions and their positons to COG of the cluster
1918 TGraphErrors ** graphRes = new TGraphErrors *[20];
1919 Float_t * indexAmpGraphs = new Float_t[20];
1920 for (Int_t icache=0; icache<20; icache++)
1921 {
1922 graphRes[icache] = NULL;
1923 indexAmpGraphs[icache] = 0;
1924 }
1925 ///////////////////////////// --> position fo sie loop
d4559772 1926 if (!AliTPCcalibDB::Instance()->GetTailcancelationGraphs(sec+36*secType+18*iside,graphRes,indexAmpGraphs))
1927 {
1928 continue;
1929 }
9a836cc2 1930
1931 AliTPCtrackerSector &sector= (secType==0)?fInnerSec[sec]:fOuterSec[sec];
1932 Int_t nrows = sector.GetNRows(); // number of rows
1933 Int_t nclSector = sector.GetNClInSector(iside); // ncl per sector to be used for debugging
1934
1935 for (Int_t row = 0;row<nrows;row++){ // loop over rows
1936
1937 AliTPCtrackerRow& tpcrow = sector[row]; // row object
1938 Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1939 if (iside>0) ncl=tpcrow.GetN2();
1940
1941 // Order clusters in time for the proper correction of ion tail
1942 Float_t qTotArray[ncl]; // arrays to be filled with modified Qtot and Qmax values in order to avoid float->int conversion
1943 Float_t qMaxArray[ncl];
1944 Int_t sortedClusterIndex[ncl];
1945 Float_t sortedClusterTimeBin[ncl];
1946 TObjArray *rowClusterArray = new TObjArray(ncl); // cache clusters for each row
1947 for (Int_t i=0;i<ncl;i++)
1948 {
1949 qTotArray[i]=0;
1950 qMaxArray[i]=0;
1951 sortedClusterIndex[i]=i;
1952 AliTPCclusterMI *rowcl= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1953 if (rowcl) {
1954 rowClusterArray->AddAt(rowcl,i);
1955 } else {
1956 rowClusterArray->RemoveAt(i);
1957 }
1958 // Fill the timebin info to the array in order to sort wrt tb
1959 if (!rowcl) {
1960 sortedClusterTimeBin[i]=0.0;
1961 } else {
1962 sortedClusterTimeBin[i] = rowcl->GetTimeBin();
1963 }
1964
1965 }
1966 TMath::Sort(ncl,sortedClusterTimeBin,sortedClusterIndex,kFALSE); // sort clusters in time
1967
1968 // Main cluster correction loops over clusters
1969 for (Int_t icl0=0; icl0<ncl;icl0++){ // first loop over clusters
1970
1971 AliTPCclusterMI *cl0= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl0]));
1972
1973 if (!cl0) continue;
1974 Int_t nclPad=0;
265b5e37 1975 for (Int_t icl1=0; icl1<ncl;icl1++){ // second loop over clusters
9a836cc2 1976 AliTPCclusterMI *cl1= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl1]));
1977 if (!cl1) continue;
1978 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())>4) continue; // no contribution if far away in pad direction
1979 if (cl0->GetTimeBin()<= cl1->GetTimeBin()) continue; // no contibution to the tail if later
1980 if (TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin())>600) continue; // out of the range of response function
1981
1982 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())<4) nclPad++; // count ncl for every pad for debugging
1983
1984 // Get the correction values for Qmax and Qtot and find total correction for a given cluster
1985 Double_t ionTailMax=0.;
1986 Double_t ionTailTotal=0.;
1987 GetTailValue(ampfactor,ionTailMax,ionTailTotal,graphRes,indexAmpGraphs,cl0,cl1);
1988 ionTailMax=TMath::Abs(ionTailMax);
1989 ionTailTotal=TMath::Abs(ionTailTotal);
1990 qTotArray[icl0]+=ionTailTotal;
1991 qMaxArray[icl0]+=ionTailMax;
1992
1993 // Dump some info for debugging while clusters are being corrected
518f85b7 1994 if (AliTPCReconstructor::StreamLevel()>2) {
9a836cc2 1995 TTreeSRedirector &cstream = *fDebugStreamer;
1996 if (gRandom->Rndm() > 0.999){
1997 cstream<<"IonTail"<<
1998 "cl0.=" <<cl0 << // cluster 0 (to be corrected)
1999 "cl1.=" <<cl1 << // cluster 1 (previous cluster)
2000 "ionTailTotal=" <<ionTailTotal << // ion Tail from cluster 1 contribution to cluster0
2001 "ionTailMax=" <<ionTailMax << // ion Tail from cluster 1 contribution to cluster0
2002 "\n";
2003 }
2004 }// dump the results to the debug streamer if in debug mode
2005
2006 }//end of second loop over clusters
2007
2008 // Set corrected values of the corrected cluster
2009 cl0->SetQ(TMath::Nint(Float_t(cl0->GetQ())+Float_t(qTotArray[icl0])));
2010 cl0->SetMax(TMath::Nint(Float_t(cl0->GetMax())+qMaxArray[icl0]));
2011
2012 // Dump some info for debugging after clusters are corrected
518f85b7 2013 if (AliTPCReconstructor::StreamLevel()>2) {
9a836cc2 2014 TTreeSRedirector &cstream = *fDebugStreamer;
2015 if (gRandom->Rndm() > 0.999){
2016 cstream<<"IonTailCorrected"<<
2017 "cl0.=" << cl0 << // cluster 0 with huge Qmax
2018 "ionTailTotalPerCluster=" << qTotArray[icl0] <<
2019 "ionTailMaxPerCluster=" << qMaxArray[icl0] <<
2020 "nclALL=" << nclALL <<
2021 "nclSector=" << nclSector <<
2022 "nclRow=" << ncl <<
2023 "nclPad=" << nclPad <<
2024 "row=" << row <<
2025 "sector=" << sec <<
2026 "icl0=" << icl0 <<
2027 "\n";
2028 }
2029 }// dump the results to the debug streamer if in debug mode
2030
2031 }//end of first loop over cluster
2032 delete rowClusterArray;
2033 }//end of loop over rows
2034 for (int i=0; i<20; i++) delete graphRes[i];
2035 delete [] graphRes;
2036 delete [] indexAmpGraphs;
2037
2038 }//end of loop over sectors
2039 }//end of loop over IROC/OROC
2040 }// end of side loop
7bc5f28b 2041}
9a836cc2 2042//_____________________________________________________________________________
5a516e0a 2043void AliTPCtracker::GetTailValue(Float_t ampfactor,Double_t &ionTailMax, Double_t &ionTailTotal,TGraphErrors **graphRes,Float_t *indexAmpGraphs,AliTPCclusterMI *cl0,AliTPCclusterMI *cl1){
9a836cc2 2044
2045 //
2046 // Function in order to calculate the amount of the correction to be added for a given cluster, return values are ionTailTaoltal and ionTailMax
265b5e37 2047 // Parameters:
2048 // cl0 - cluster to be modified
2049 // cl1 - source cluster ion tail of this cluster will be added to the cl0 (accroding time and pad response function)
9a836cc2 2050 //
9a836cc2 2051 const Double_t kMinPRF = 0.5; // minimal PRF width
2052 ionTailTotal = 0.; // correction value to be added to Qtot of cl0
2053 ionTailMax = 0.; // correction value to be added to Qmax of cl0
2054
2055 Float_t qTot0 = cl0->GetQ(); // cl0 Qtot info
2056 Float_t qTot1 = cl1->GetQ(); // cl1 Qtot info
2057 Int_t sectorPad = cl1->GetDetector(); // sector number
2058 Int_t padcl0 = TMath::Nint(cl0->GetPad()); // pad0
2059 Int_t padcl1 = TMath::Nint(cl1->GetPad()); // pad1
2060 Float_t padWidth = (sectorPad < 36)?0.4:0.6; // pad width in cm
2061 const Int_t deltaTimebin = TMath::Nint(TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin()))+12; //distance between pads of cl1 and cl0 increased by 12 bins
2062 Double_t rmsPad1 = (cl1->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl1->GetSigmaY2())/padWidth);
2063 Double_t rmsPad0 = (cl0->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl0->GetSigmaY2())/padWidth);
265b5e37 2064
2065
a3986da2 2066
9a836cc2 2067 Double_t sumAmp1=0.;
2068 for (Int_t idelta =-2; idelta<=2;idelta++){
2069 sumAmp1+=TMath::Exp(-idelta*idelta/(2*rmsPad1));
2070 }
7bc5f28b 2071
9a836cc2 2072 Double_t sumAmp0=0.;
2073 for (Int_t idelta =-2; idelta<=2;idelta++){
2074 sumAmp0+=TMath::Exp(-idelta*idelta/(2*rmsPad0));
2075 }
7bc5f28b 2076
9a836cc2 2077 // Apply the correction --> cl1 corrects cl0 (loop over cl1's pads and find which pads of cl0 are going to be corrected)
2078 Int_t padScan=2; // +-2 pad-timebin window will be scanned
2079 for (Int_t ipad1=padcl1-padScan; ipad1<=padcl1+padScan; ipad1++) {
2080 //
2081 //
2082 Float_t deltaPad1 = TMath::Abs(cl1->GetPad()-(Float_t)ipad1);
2083 Double_t amp1 = (TMath::Exp(-(deltaPad1*deltaPad1)/(2*rmsPad1)))/sumAmp1; // normalized pad response function
2084 Float_t qTotPad1 = amp1*qTot1; // used as a factor to multipliy the response function
2085
2086 // find closest value of cl1 to COG (among the time response functions' amplitude array --> to select proper t.r.f.)
2087 Int_t ampIndex = 0;
2088 Float_t diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[0]);
2089 for (Int_t j=0;j<20;j++) {
2090 if (diffAmp > TMath::Abs(deltaPad1-indexAmpGraphs[j]) && indexAmpGraphs[j]!=0)
2091 {
2092 diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[j]);
2093 ampIndex = j;
2094 }
2095 }
2096 if (!graphRes[ampIndex]) continue;
b4742ddd 2097 if (deltaTimebin+2 >= graphRes[ampIndex]->GetN()) continue;
9a836cc2 2098 if (graphRes[ampIndex]->GetY()[deltaTimebin+2]>=0) continue;
2099
2100 for (Int_t ipad0=padcl0-padScan; ipad0<=padcl0+padScan; ipad0++) {
2101 //
2102 //
2103 if (ipad1!=ipad0) continue; // check if ipad1 channel sees ipad0 channel, if not no correction to be applied.
2104
2105 Float_t deltaPad0 = TMath::Abs(cl0->GetPad()-(Float_t)ipad0);
2106 Double_t amp0 = (TMath::Exp(-(deltaPad0*deltaPad0)/(2*rmsPad0)))/sumAmp0; // normalized pad resp function
2107 Float_t qMaxPad0 = amp0*qTot0;
2108
2109 // Add 5 timebin range contribution around the max peak (-+2 tb window)
2110 for (Int_t itb=deltaTimebin-2; itb<=deltaTimebin+2; itb++) {
2111
2112 if (itb<0) continue;
2113 if (itb>=graphRes[ampIndex]->GetN()) continue;
2114
2115 // calculate contribution to qTot
2116 Float_t tailCorr = TMath::Abs((qTotPad1*ampfactor)*(graphRes[ampIndex])->GetY()[itb]);
2117 if (ipad1!=padcl0) {
2118 ionTailTotal += TMath::Min(qMaxPad0,tailCorr); // for side pad
2119 } else {
2120 ionTailTotal += tailCorr; // for center pad
2121 }
2122 // calculate contribution to qMax
2123 if (itb == deltaTimebin && ipad1 == padcl0) ionTailMax += tailCorr;
2124
2125 } // end of tb correction loop which is applied over 5 tb range
2126
2127 } // end of cl0 loop
2128 } // end of cl1 loop
2129
2130}
7bc5f28b 2131
1c53abe2 2132//_____________________________________________________________________________
829455ad 2133Int_t AliTPCtracker::LoadOuterSectors() {
1c53abe2 2134 //-----------------------------------------------------------------
91162307 2135 // This function fills outer TPC sectors with clusters.
1c53abe2 2136 //-----------------------------------------------------------------
91162307 2137 Int_t nrows = fOuterSec->GetNRows();
2138 UInt_t index=0;
2139 for (Int_t sec = 0;sec<fkNOS;sec++)
2140 for (Int_t row = 0;row<nrows;row++){
bd26fa83 2141 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
91162307 2142 Int_t sec2 = sec+2*fkNIS;
2143 //left
b9671574 2144 Int_t ncl = tpcrow->GetN1();
91162307 2145 while (ncl--) {
b9671574 2146 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
91162307 2147 index=(((sec2<<8)+row)<<16)+ncl;
2148 tpcrow->InsertCluster(c,index);
2149 }
2150 //right
b9671574 2151 ncl = tpcrow->GetN2();
91162307 2152 while (ncl--) {
b9671574 2153 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
91162307 2154 index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
2155 tpcrow->InsertCluster(c,index);
2156 }
2157 //
2158 // write indexes for fast acces
2159 //
2160 for (Int_t i=0;i<510;i++)
b9671574 2161 tpcrow->SetFastCluster(i,-1);
91162307 2162 for (Int_t i=0;i<tpcrow->GetN();i++){
2163 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
b9671574 2164 tpcrow->SetFastCluster(zi,i); // write index
91162307 2165 }
2166 Int_t last = 0;
2167 for (Int_t i=0;i<510;i++){
b9671574 2168 if (tpcrow->GetFastCluster(i)<0)
2169 tpcrow->SetFastCluster(i,last);
91162307 2170 else
b9671574 2171 last = tpcrow->GetFastCluster(i);
91162307 2172 }
2173 }
2174 fN=fkNOS;
2175 fSectors=fOuterSec;
2176 return 0;
2177}
2178
2179
2180//_____________________________________________________________________________
829455ad 2181Int_t AliTPCtracker::LoadInnerSectors() {
91162307 2182 //-----------------------------------------------------------------
2183 // This function fills inner TPC sectors with clusters.
2184 //-----------------------------------------------------------------
2185 Int_t nrows = fInnerSec->GetNRows();
2186 UInt_t index=0;
2187 for (Int_t sec = 0;sec<fkNIS;sec++)
2188 for (Int_t row = 0;row<nrows;row++){
bd26fa83 2189 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
91162307 2190 //
2191 //left
b9671574 2192 Int_t ncl = tpcrow->GetN1();
91162307 2193 while (ncl--) {
b9671574 2194 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
91162307 2195 index=(((sec<<8)+row)<<16)+ncl;
2196 tpcrow->InsertCluster(c,index);
2197 }
2198 //right
b9671574 2199 ncl = tpcrow->GetN2();
91162307 2200 while (ncl--) {
b9671574 2201 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
91162307 2202 index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
2203 tpcrow->InsertCluster(c,index);
2204 }
2205 //
2206 // write indexes for fast acces
2207 //
2208 for (Int_t i=0;i<510;i++)
b9671574 2209 tpcrow->SetFastCluster(i,-1);
91162307 2210 for (Int_t i=0;i<tpcrow->GetN();i++){
2211 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
b9671574 2212 tpcrow->SetFastCluster(zi,i); // write index
91162307 2213 }
2214 Int_t last = 0;
2215 for (Int_t i=0;i<510;i++){
b9671574 2216 if (tpcrow->GetFastCluster(i)<0)
2217 tpcrow->SetFastCluster(i,last);
91162307 2218 else
b9671574 2219 last = tpcrow->GetFastCluster(i);
91162307 2220 }
1c53abe2 2221
91162307 2222 }
2223
1c53abe2 2224 fN=fkNIS;
2225 fSectors=fInnerSec;
91162307 2226 return 0;
2227}
2228
2229
2230
2231//_________________________________________________________________________
829455ad 2232AliTPCclusterMI *AliTPCtracker::GetClusterMI(Int_t index) const {
91162307 2233 //--------------------------------------------------------------------
2234 // Return pointer to a given cluster
2235 //--------------------------------------------------------------------
e7eb17e4 2236 if (index<0) return 0; // no cluster
91162307 2237 Int_t sec=(index&0xff000000)>>24;
2238 Int_t row=(index&0x00ff0000)>>16;
d26d9159 2239 Int_t ncl=(index&0x00007fff)>>00;
91162307 2240
bd26fa83 2241 const AliTPCtrackerRow * tpcrow=0;
bfa00fba 2242 TClonesArray * clrow =0;
3da363a1 2243
ad23441a 2244 if (sec<0 || sec>=fkNIS*4) {
2245 AliWarning(Form("Wrong sector %d",sec));
2246 return 0x0;
2247 }
2248
91162307 2249 if (sec<fkNIS*2){
462fb6e0 2250 AliTPCtrackerSector& tracksec = fInnerSec[sec%fkNIS];
2251 if (tracksec.GetNRows()<=row) return 0;
2252 tpcrow = &(tracksec[row]);
3da363a1 2253 if (tpcrow==0) return 0;
2254
2255 if (sec<fkNIS) {
b9671574 2256 if (tpcrow->GetN1()<=ncl) return 0;
2257 clrow = tpcrow->GetClusters1();
3da363a1 2258 }
2259 else {
b9671574 2260 if (tpcrow->GetN2()<=ncl) return 0;
2261 clrow = tpcrow->GetClusters2();
3da363a1 2262 }
91162307 2263 }
3da363a1 2264 else {
462fb6e0 2265 AliTPCtrackerSector& tracksec = fOuterSec[(sec-fkNIS*2)%fkNOS];
2266 if (tracksec.GetNRows()<=row) return 0;
2267 tpcrow = &(tracksec[row]);
3da363a1 2268 if (tpcrow==0) return 0;
2269
2270 if (sec-2*fkNIS<fkNOS) {
b9671574 2271 if (tpcrow->GetN1()<=ncl) return 0;
2272 clrow = tpcrow->GetClusters1();
3da363a1 2273 }
2274 else {
b9671574 2275 if (tpcrow->GetN2()<=ncl) return 0;
2276 clrow = tpcrow->GetClusters2();
3da363a1 2277 }
91162307 2278 }
3da363a1 2279
bfa00fba 2280 return (AliTPCclusterMI*)clrow->At(ncl);
91162307 2281
1c53abe2 2282}
2283
91162307 2284
2285
829455ad 2286Int_t AliTPCtracker::FollowToNext(AliTPCseed& t, Int_t nr) {
1c53abe2 2287 //-----------------------------------------------------------------
2288 // This function tries to find a track prolongation to next pad row
2289 //-----------------------------------------------------------------
1c53abe2 2290 //
91162307 2291 Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
76d56fd6 2292 //
2293 //
4d158c36 2294 AliTPCclusterMI *cl=0;
2295 Int_t tpcindex= t.GetClusterIndex2(nr);
2296 //
2297 // update current shape info every 5 pad-row
2298 // if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
2299 GetShape(&t,nr);
2300 //}
2301 //
2302 if (fIteration>0 && tpcindex>=-1){ //if we have already clusters
2303 //
2304 if (tpcindex==-1) return 0; //track in dead zone
f124f8bf 2305 if (tpcindex >= 0){ //
b9671574 2306 cl = t.GetClusterPointer(nr);
97d77e7a 2307 //if (cl==0) cl = GetClusterMI(tpcindex);
2308 if (!cl) cl = GetClusterMI(tpcindex);
b9671574 2309 t.SetCurrentClusterIndex1(tpcindex);
4d158c36 2310 }
2311 if (cl){
2312 Int_t relativesector = ((tpcindex&0xff000000)>>24)%18; // if previously accepted cluster in different sector
2313 Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
2314 //
2315 if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
2316 if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
2317
2318 if (TMath::Abs(angle-t.GetAlpha())>0.001){
2319 Double_t rotation = angle-t.GetAlpha();
b9671574 2320 t.SetRelativeSector(relativesector);
1791d824 2321 if (!t.Rotate(rotation)) {
2322 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
2323 return 0;
2324 }
2325 }
2326 if (!t.PropagateTo(x)) {
2327 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
2328 return 0;
4d158c36 2329 }
4d158c36 2330 //
b9671574 2331 t.SetCurrentCluster(cl);
2332 t.SetRow(nr);
00055a22 2333 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
4d158c36 2334 if ((tpcindex&0x8000)==0) accept =0;
2335 if (accept<3) {
2336 //if founded cluster is acceptible
2337 if (cl->IsUsed(11)) { // id cluster is shared inrease uncertainty
b9671574 2338 t.SetErrorY2(t.GetErrorY2()+0.03);
2339 t.SetErrorZ2(t.GetErrorZ2()+0.03);
2340 t.SetErrorY2(t.GetErrorY2()*3);
2341 t.SetErrorZ2(t.GetErrorZ2()*3);
4d158c36 2342 }
b9671574 2343 t.SetNFoundable(t.GetNFoundable()+1);
4d158c36 2344 UpdateTrack(&t,accept);
2345 return 1;
f124f8bf 2346 }
2347 else { // Remove old cluster from track
2348 t.SetClusterIndex(nr, -3);
2349 t.SetClusterPointer(nr, 0);
2350 }
4d158c36 2351 }
1627d1c4 2352 }
3f82c4f2 2353 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0; // cut on angle
76d56fd6 2354 if (fIteration>1 && IsFindable(t)){
3f82c4f2 2355 // not look for new cluster during refitting
b9671574 2356 t.SetNFoundable(t.GetNFoundable()+1);
3f82c4f2 2357 return 0;
2358 }
91162307 2359 //
4d158c36 2360 UInt_t index=0;
ca142b1f 2361 // if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
f124f8bf 2362 if (!t.PropagateTo(x)) {
2363 if (fIteration==0) t.SetRemoval(10);
2364 return 0;
2365 }
2366 Double_t y = t.GetY();
91162307 2367 if (TMath::Abs(y)>ymax){
2368 if (y > ymax) {
b9671574 2369 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
91162307 2370 if (!t.Rotate(fSectors->GetAlpha()))
2371 return 0;
2372 } else if (y <-ymax) {
b9671574 2373 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
91162307 2374 if (!t.Rotate(-fSectors->GetAlpha()))
2375 return 0;
2376 }
f124f8bf 2377 if (!t.PropagateTo(x)) {
2378 if (fIteration==0) t.SetRemoval(10);
2379 return 0;
2380 }
2381 y = t.GetY();
91162307 2382 }
2383 //
4d158c36 2384 Double_t z=t.GetZ();
2385 //
a3232aae 2386
b9671574 2387 if (!IsActive(t.GetRelativeSector(),nr)) {
2388 t.SetInDead(kTRUE);
a3232aae 2389 t.SetClusterIndex2(nr,-1);
2390 return 0;
2391 }
2392 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
b9671574 2393 Bool_t isActive = IsActive(t.GetRelativeSector(),nr);
2394 Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
a3232aae 2395
2396 if (!isActive || !isActive2) return 0;
2397
bd26fa83 2398 const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
91162307 2399 if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
2400 Double_t roady =1.;
2401 Double_t roadz = 1.;
2402 //
b9671574 2403 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
2404 t.SetInDead(kTRUE);
91162307 2405 t.SetClusterIndex2(nr,-1);
1c53abe2 2406 return 0;
2407 }
2408 else
2409 {
76d56fd6 2410 if (IsFindable(t))
47af7ca4 2411 // if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fkParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
b9671574 2412 t.SetNFoundable(t.GetNFoundable()+1);
1627d1c4 2413 else
2414 return 0;
1c53abe2 2415 }
2416 //calculate
91162307 2417 if (krow) {
2418 // cl = krow.FindNearest2(y+10.,z,roady,roadz,index);
2419 cl = krow.FindNearest2(y,z,roady,roadz,index);
b9671574 2420 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
91162307 2421 }
91162307 2422 if (cl) {
b9671574 2423 t.SetCurrentCluster(cl);
2424 t.SetRow(nr);
4d158c36 2425 if (fIteration==2&&cl->IsUsed(10)) return 0;
00055a22 2426 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
4d158c36 2427 if (fIteration==2&&cl->IsUsed(11)) {
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 }
d26d9159 2433 /*
91162307 2434 if (t.fCurrentCluster->IsUsed(10)){
2435 //
2436 //
c9427e08 2437
91162307 2438 t.fNShared++;
2439 if (t.fNShared>0.7*t.GetNumberOfClusters()) {
2440 t.fRemoval =10;
2441 return 0;
2442 }
2443 }
d26d9159 2444 */
91162307 2445 if (accept<3) UpdateTrack(&t,accept);
c9427e08 2446
91162307 2447 } else {
b9671574 2448 if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
91162307 2449
2450 }
2451 return 1;
2452}
c9427e08 2453
1c53abe2 2454
91162307 2455
5d837844 2456//_________________________________________________________________________
829455ad 2457Bool_t AliTPCtracker::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
5d837844 2458{
2459 // Get track space point by index
2460 // return false in case the cluster doesn't exist
2461 AliTPCclusterMI *cl = GetClusterMI(index);
2462 if (!cl) return kFALSE;
2463 Int_t sector = (index&0xff000000)>>24;
0201b65c 2464 // Int_t row = (index&0x00ff0000)>>16;
5d837844 2465 Float_t xyz[3];
47af7ca4 2466 // xyz[0] = fkParam->GetPadRowRadii(sector,row);
0201b65c 2467 xyz[0] = cl->GetX();
5d837844 2468 xyz[1] = cl->GetY();
2469 xyz[2] = cl->GetZ();
2470 Float_t sin,cos;
47af7ca4 2471 fkParam->AdjustCosSin(sector,cos,sin);
5d837844 2472 Float_t x = cos*xyz[0]-sin*xyz[1];
2473 Float_t y = cos*xyz[1]+sin*xyz[0];
2474 Float_t cov[6];
2475 Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
47af7ca4 2476 if (sector < fkParam->GetNInnerSector()) sigmaY2 *= 2.07;
5d837844 2477 Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
47af7ca4 2478 if (sector < fkParam->GetNInnerSector()) sigmaZ2 *= 1.77;
5d837844 2479 cov[0] = sin*sin*sigmaY2;
2480 cov[1] = -sin*cos*sigmaY2;
2481 cov[2] = 0.;
2482 cov[3] = cos*cos*sigmaY2;
2483 cov[4] = 0.;
2484 cov[5] = sigmaZ2;
2485 p.SetXYZ(x,y,xyz[2],cov);
ae079791 2486 AliGeomManager::ELayerID iLayer;
5d837844 2487 Int_t idet;
47af7ca4 2488 if (sector < fkParam->GetNInnerSector()) {
ae079791 2489 iLayer = AliGeomManager::kTPC1;
5d837844 2490 idet = sector;
2491 }
2492 else {
ae079791 2493 iLayer = AliGeomManager::kTPC2;
47af7ca4 2494 idet = sector - fkParam->GetNInnerSector();
5d837844 2495 }
ae079791 2496 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
5d837844 2497 p.SetVolumeID(volid);
2498 return kTRUE;
2499}
2500
2501
2502
829455ad 2503Int_t AliTPCtracker::UpdateClusters(AliTPCseed& t, Int_t nr) {
1c53abe2 2504 //-----------------------------------------------------------------
2505 // This function tries to find a track prolongation to next pad row
2506 //-----------------------------------------------------------------
b9671574 2507 t.SetCurrentCluster(0);
f124f8bf 2508 t.SetCurrentClusterIndex1(-3);
1c53abe2 2509
2510 Double_t xt=t.GetX();
91162307 2511 Int_t row = GetRowNumber(xt)-1;
2512 Double_t ymax= GetMaxY(nr);
2513
1c53abe2 2514 if (row < nr) return 1; // don't prolongate if not information until now -
ca142b1f 2515// if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
2516// t.fRemoval =10;
2517// return 0; // not prolongate strongly inclined tracks
2518// }
2519// if (TMath::Abs(t.GetSnp())>0.95) {
2520// t.fRemoval =10;
2521// return 0; // not prolongate strongly inclined tracks
2522// }// patch 28 fev 06
91162307 2523
2524 Double_t x= GetXrow(nr);
2525 Double_t y,z;
2526 //t.PropagateTo(x+0.02);
2527 //t.PropagateTo(x+0.01);
1627d1c4 2528 if (!t.PropagateTo(x)){
1627d1c4 2529 return 0;
2530 }
1c53abe2 2531 //
91162307 2532 y=t.GetY();
2533 z=t.GetZ();
1c53abe2 2534
91162307 2535 if (TMath::Abs(y)>ymax){
2536 if (y > ymax) {
b9671574 2537 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
91162307 2538 if (!t.Rotate(fSectors->GetAlpha()))
2539 return 0;
2540 } else if (y <-ymax) {
b9671574 2541 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
91162307 2542 if (!t.Rotate(-fSectors->GetAlpha()))
2543 return 0;
2544 }
982aff31 2545 // if (!t.PropagateTo(x)){
2546 // return 0;
2547 //}
2548 return 1;
2549 //y = t.GetY();
1c53abe2 2550 }
91162307 2551 //
3f82c4f2 2552 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
a3232aae 2553
b9671574 2554 if (!IsActive(t.GetRelativeSector(),nr)) {
2555 t.SetInDead(kTRUE);
a3232aae 2556 t.SetClusterIndex2(nr,-1);
2557 return 0;
2558 }
2559 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
2560
bd26fa83 2561 AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1c53abe2 2562
b9671574 2563 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
2564 t.SetInDead(kTRUE);
91162307 2565 t.SetClusterIndex2(nr,-1);
1c53abe2 2566 return 0;
2567 }
2568 else
2569 {
76d56fd6 2570
2571 // if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
2572 if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
1627d1c4 2573 else
2574 return 0;
1c53abe2 2575 }
1c53abe2 2576
91162307 2577 // update current
42aec1f1 2578 if ( (nr%2==0) || t.GetNumberOfClusters()<2){
91162307 2579 // t.fCurrentSigmaY = GetSigmaY(&t);
2580 //t.fCurrentSigmaZ = GetSigmaZ(&t);
2581 GetShape(&t,nr);
2582 }
1c53abe2 2583
91162307 2584 AliTPCclusterMI *cl=0;
d184f295 2585 Int_t index=0;
91162307 2586 //
2587 Double_t roady = 1.;
2588 Double_t roadz = 1.;
2589 //
d26d9159 2590
2591 if (!cl){
2592 index = t.GetClusterIndex2(nr);
bad6eb00 2593 if ( (index >= 0) && (index&0x8000)==0){
b9671574 2594 cl = t.GetClusterPointer(nr);
bad6eb00 2595 if ( (cl==0) && (index >= 0)) cl = GetClusterMI(index);
b9671574 2596 t.SetCurrentClusterIndex1(index);
d26d9159 2597 if (cl) {
b9671574 2598 t.SetCurrentCluster(cl);
d26d9159 2599 return 1;
2600 }
2601 }
2602 }
2603
3d172d79 2604 // if (index<0) return 0;
2605 UInt_t uindex = TMath::Abs(index);
d184f295 2606
91162307 2607 if (krow) {
d184f295 2608 //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
2609 cl = krow.FindNearest2(y,z,roady,roadz,uindex);
91162307 2610 }
d26d9159 2611
b9671574 2612 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));
2613 t.SetCurrentCluster(cl);
d26d9159 2614
91162307 2615 return 1;
2616}
1c53abe2 2617
1c53abe2 2618
829455ad 2619Int_t AliTPCtracker::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
91162307 2620 //-----------------------------------------------------------------
2621 // This function tries to find a track prolongation to next pad row
2622 //-----------------------------------------------------------------
1c53abe2 2623
91162307 2624 //update error according neighborhoud
1c53abe2 2625
b9671574 2626 if (t.GetCurrentCluster()) {
2627 t.SetRow(nr);
00055a22 2628 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
91162307 2629
b9671574 2630 if (t.GetCurrentCluster()->IsUsed(10)){
91162307 2631 //
2632 //
2633 // t.fErrorZ2*=2;
2634 // t.fErrorY2*=2;
b9671574 2635 t.SetNShared(t.GetNShared()+1);
2636 if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
2637 t.SetRemoval(10);
91162307 2638 return 0;
2639 }
b364ca79 2640 }
d26d9159 2641 if (fIteration>0) accept = 0;
b364ca79 2642 if (accept<3) UpdateTrack(&t,accept);
2643
1c53abe2 2644 } else {
91162307 2645 if (fIteration==0){
f124f8bf 2646 if ( t.GetNumberOfClusters()>18 && ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)) t.SetRemoval(10);
2647 if ( t.GetNumberOfClusters()>18 && t.GetChi2()/t.GetNumberOfClusters()>6 ) t.SetRemoval(10);
91162307 2648
b9671574 2649 if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
1c53abe2 2650 }
2651 }
2652 return 1;
2653}
2654
2655
2656
91162307 2657//_____________________________________________________________________________
829455ad 2658Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step, Bool_t fromSeeds) {
1c53abe2 2659 //-----------------------------------------------------------------
91162307 2660 // This function tries to find a track prolongation.
1c53abe2 2661 //-----------------------------------------------------------------
2662 Double_t xt=t.GetX();
2663 //
f124f8bf 2664 Double_t alpha=t.GetAlpha();
1c53abe2 2665 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2666 if (alpha < 0. ) alpha += 2.*TMath::Pi();
91162307 2667 //
a3f36f42 2668 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1c53abe2 2669
f124f8bf 2670 Int_t first = GetRowNumber(xt);
2671 if (!fromSeeds)
2672 first -= step;
a3f36f42 2673 if (first < 0)
2674 first = 0;
51ad6848 2675 for (Int_t nr= first; nr>=rf; nr-=step) {
2676 // update kink info
2677 if (t.GetKinkIndexes()[0]>0){
2678 for (Int_t i=0;i<3;i++){
2679 Int_t index = t.GetKinkIndexes()[i];
2680 if (index==0) break;
2681 if (index<0) continue;
2682 //
6c94f330 2683 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
51ad6848 2684 if (!kink){
2685 printf("PROBLEM\n");
2686 }
2687 else{
eea478d3 2688 Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
51ad6848 2689 if (kinkrow==nr){
2690 AliExternalTrackParam paramd(t);
2691 kink->SetDaughter(paramd);
eea478d3 2692 kink->SetStatus(2,5);
51ad6848 2693 kink->Update();
51ad6848 2694 }
2695 }
2696 }
2697 }
2698
2699 if (nr==80) t.UpdateReference();
982aff31 2700 if (nr<fInnerSec->GetNRows())
2701 fSectors = fInnerSec;
2702 else
2703 fSectors = fOuterSec;
91162307 2704 if (FollowToNext(t,nr)==0)
4d158c36 2705 if (!t.IsActive())
2706 return 0;
91162307 2707
2708 }
2709 return 1;
2710}
2711
1c53abe2 2712
1c53abe2 2713
91162307 2714
2715
2716
829455ad 2717Int_t AliTPCtracker::FollowBackProlongation(AliTPCseed& t, Int_t rf, Bool_t fromSeeds) {
1c53abe2 2718 //-----------------------------------------------------------------
2719 // This function tries to find a track prolongation.
2720 //-----------------------------------------------------------------
1c53abe2 2721 //
eea478d3 2722 Double_t xt=t.GetX();
f124f8bf 2723 Double_t alpha=t.GetAlpha();
1c53abe2 2724 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2725 if (alpha < 0. ) alpha += 2.*TMath::Pi();
bad6eb00 2726 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1c53abe2 2727
b9671574 2728 Int_t first = t.GetFirstPoint();
f124f8bf 2729 Int_t ri = GetRowNumber(xt);
2730 if (!fromSeeds)
2731 ri += 1;
2732
2733 if (first<ri) first = ri;
91162307 2734 //
2735 if (first<0) first=0;
4d158c36 2736 for (Int_t nr=first; nr<=rf; nr++) {
ca142b1f 2737 // if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
51ad6848 2738 if (t.GetKinkIndexes()[0]<0){
2739 for (Int_t i=0;i<3;i++){
2740 Int_t index = t.GetKinkIndexes()[i];
2741 if (index==0) break;
2742 if (index>0) continue;
2743 index = TMath::Abs(index);
6c94f330 2744 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
51ad6848 2745 if (!kink){
2746 printf("PROBLEM\n");
2747 }
2748 else{
eea478d3 2749 Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
51ad6848 2750 if (kinkrow==nr){
2751 AliExternalTrackParam paramm(t);
2752 kink->SetMother(paramm);
eea478d3 2753 kink->SetStatus(2,1);
51ad6848 2754 kink->Update();
51ad6848 2755 }
2756 }
eea478d3 2757 }
51ad6848 2758 }
eea478d3 2759 //
d26d9159 2760 if (nr<fInnerSec->GetNRows())
2761 fSectors = fInnerSec;
2762 else
2763 fSectors = fOuterSec;
c274e255 2764
d26d9159 2765 FollowToNext(t,nr);
1c53abe2 2766 }
2767 return 1;
2768}
2769
2770
2771
2772
2773
829455ad 2774Float_t AliTPCtracker::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
1c53abe2 2775{
544c295f 2776 // overlapping factor
1c53abe2 2777 //
2778 sum1=0;
2779 sum2=0;
2780 Int_t sum=0;
1c53abe2 2781 //
2782 Float_t dz2 =(s1->GetZ() - s2->GetZ());
c9427e08 2783 dz2*=dz2;
91162307 2784
c9427e08 2785 Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
1c53abe2 2786 dy2*=dy2;
2787 Float_t distance = TMath::Sqrt(dz2+dy2);
c9427e08 2788 if (distance>4.) return 0; // if there are far away - not overlap - to reduce combinatorics
1c53abe2 2789
91162307 2790 // Int_t offset =0;
b9671574 2791 Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
2792 Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
c9427e08 2793 if (lastpoint>160)
2794 lastpoint =160;
2795 if (firstpoint<0)
2796 firstpoint = 0;
91162307 2797 if (firstpoint>lastpoint) {
2798 firstpoint =lastpoint;
2799 // lastpoint =160;
c9427e08 2800 }
2801
2802
91162307 2803 for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
2804 if (s1->GetClusterIndex2(i)>0) sum1++;
2805 if (s2->GetClusterIndex2(i)>0) sum2++;
2806 if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
1c53abe2 2807 sum++;
2808 }
2809 }
91162307 2810 if (sum<5) return 0;
2811
1627d1c4 2812 Float_t summin = TMath::Min(sum1+1,sum2+1);
2813 Float_t ratio = (sum+1)/Float_t(summin);
1c53abe2 2814 return ratio;
2815}
2816
829455ad 2817void AliTPCtracker::SignShared(AliTPCseed * s1, AliTPCseed * s2)
1c53abe2 2818{
544c295f 2819 // shared clusters
1c53abe2 2820 //
a0f4d6a6 2821 Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
2822 if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
2823 Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
2824 Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
91162307 2825
1c53abe2 2826 //
91162307 2827 Int_t sumshared=0;
2828 //
a0f4d6a6 2829 //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
2830 //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
2831 Int_t firstpoint = 0;
2832 Int_t lastpoint = 160;
91162307 2833 //
a0f4d6a6 2834 // if (firstpoint>=lastpoint-5) return;;
1af5da7e 2835
91162307 2836 for (Int_t i=firstpoint;i<lastpoint;i++){
2837 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2838 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2839 sumshared++;
2840 }
2841 }
a0f4d6a6 2842 if (sumshared>cutN0){
91162307 2843 // sign clusters
2844 //
2845 for (Int_t i=firstpoint;i<lastpoint;i++){
2846 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2847 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2848 AliTPCTrackerPoint *p1 = s1->GetTrackPoint(i);
2849 AliTPCTrackerPoint *p2 = s2->GetTrackPoint(i);;
2850 if (s1->IsActive()&&s2->IsActive()){
b9671574 2851 p1->SetShared(kTRUE);
2852 p2->SetShared(kTRUE);
91162307 2853 }
2854 }
2855 }
2856 }
2857 //
a0f4d6a6 2858 if (sumshared>cutN0){
91162307 2859 for (Int_t i=0;i<4;i++){
b9671574 2860 if (s1->GetOverlapLabel(3*i)==0){
2861 s1->SetOverlapLabel(3*i, s2->GetLabel());
2862 s1->SetOverlapLabel(3*i+1,sumshared);
2863 s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
91162307 2864 break;
2865 }
2866 }
2867 for (Int_t i=0;i<4;i++){
b9671574 2868 if (s2->GetOverlapLabel(3*i)==0){
2869 s2->SetOverlapLabel(3*i, s1->GetLabel());
2870 s2->SetOverlapLabel(3*i+1,sumshared);
2871 s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
91162307 2872 break;
2873 }
2874 }
2875 }
91162307 2876}
1c53abe2 2877
829455ad 2878void AliTPCtracker::SignShared(TObjArray * arr)
91162307 2879{
1c53abe2 2880 //
91162307 2881 //sort trackss according sectors
2882 //
c9427e08 2883 for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2884 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 2885 if (!pt) continue;
2886 //if (pt) RotateToLocal(pt);
b9671574 2887 pt->SetSort(0);
c9427e08 2888 }
91162307 2889 arr->UnSort();
6d493ea0 2890 arr->Sort(); // sorting according relative sectors
1c53abe2 2891 arr->Expand(arr->GetEntries());
91162307 2892 //
2893 //
1c53abe2 2894 Int_t nseed=arr->GetEntriesFast();
1c53abe2 2895 for (Int_t i=0; i<nseed; i++) {
2896 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
91162307 2897 if (!pt) continue;
ec26e231 2898 for (Int_t j=0;j<12;j++){
b9671574 2899 pt->SetOverlapLabel(j,0);
1c53abe2 2900 }
91162307 2901 }
2902 for (Int_t i=0; i<nseed; i++) {
2903 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2904 if (!pt) continue;
b9671574 2905 if (pt->GetRemoval()>10) continue;
1c53abe2 2906 for (Int_t j=i+1; j<nseed; j++){
2907 AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
1af5da7e 2908 if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
91162307 2909 // if (pt2){
b9671574 2910 if (pt2->GetRemoval()<=10) {
6d493ea0 2911 //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
91162307 2912 SignShared(pt,pt2);
c9427e08 2913 }
91162307 2914 }
2915 }
2916}
2917
91162307 2918
829455ad 2919void AliTPCtracker::SortTracks(TObjArray * arr, Int_t mode) const
91162307 2920{
2921 //
2922 //sort tracks in array according mode criteria
2923 Int_t nseed = arr->GetEntriesFast();
2924 for (Int_t i=0; i<nseed; i++) {
2925 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2926 if (!pt) {
2927 continue;
2928 }
b9671574 2929 pt->SetSort(mode);
91162307 2930 }
2931 arr->UnSort();
2932 arr->Sort();
1c53abe2 2933}
c9427e08 2934
51ad6848 2935
829455ad 2936void AliTPCtracker::RemoveUsed2(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t minimal)
51ad6848 2937{
51ad6848 2938 //
6d493ea0 2939 // Loop over all tracks and remove overlaped tracks (with lower quality)
2940 // Algorithm:
2941 // 1. Unsign clusters
2942 // 2. Sort tracks according quality
2943 // Quality is defined by the number of cluster between first and last points
2944 //
2945 // 3. Loop over tracks - decreasing quality order
2946 // a.) remove - If the fraction of shared cluster less than factor (1- n or 2)
2947 // b.) remove - If the minimal number of clusters less than minimal and not ITS
2948 // c.) if track accepted - sign clusters
51ad6848 2949 //
829455ad 2950 //Called in - AliTPCtracker::Clusters2Tracks()
2951 // - AliTPCtracker::PropagateBack()
2952 // - AliTPCtracker::RefitInward()
6d493ea0 2953 //
be34cb88 2954 // Arguments:
2955 // factor1 - factor for constrained
2956 // factor2 - for non constrained tracks
2957 // if (Float_t(shared+1)/Float_t(found+1)>factor) - DELETE
2958 //
51ad6848 2959 UnsignClusters();
2960 //
2961 Int_t nseed = arr->GetEntriesFast();
2962 Float_t * quality = new Float_t[nseed];
2963 Int_t * indexes = new Int_t[nseed];
2964 Int_t good =0;
2965 //
2966 //
2967 for (Int_t i=0; i<nseed; i++) {
2968 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2969 if (!pt){
2970 quality[i]=-1;
2971 continue;
2972 }
2973 pt->UpdatePoints(); //select first last max dens points
2974 Float_t * points = pt->GetPoints();
2975 if (points[3]<0.8) quality[i] =-1;
51ad6848 2976 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
6d493ea0 2977 //prefer high momenta tracks if overlaps
2978 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
51ad6848 2979 }
2980 TMath::Sort(nseed,quality,indexes);
2981 //
2982 //
2983 for (Int_t itrack=0; itrack<nseed; itrack++) {
2984 Int_t trackindex = indexes[itrack];
6d493ea0 2985 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);
2986 if (!pt) continue;
2987 //
51ad6848 2988 if (quality[trackindex]<0){
ddfbc51a 2989 MarkSeedFree( arr->RemoveAt(trackindex) );
f06a1ff6 2990 continue;
51ad6848 2991 }
2992 //
6d493ea0 2993 //
51ad6848 2994 Int_t first = Int_t(pt->GetPoints()[0]);
2995 Int_t last = Int_t(pt->GetPoints()[2]);
b9671574 2996 Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
51ad6848 2997 //
2998 Int_t found,foundable,shared;
6d493ea0 2999 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
3000 // pt->GetClusterStatistic(0,160, found, foundable,shared,kFALSE);
b406fdb0 3001 Bool_t itsgold =kFALSE;
b9671574 3002 if (pt->GetESD()){
ef7253ac 3003 Int_t dummy[12];
b9671574 3004 if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
51ad6848 3005 }
b406fdb0 3006 if (!itsgold){
3007 //
3008 if (Float_t(shared+1)/Float_t(found+1)>factor){
3009 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
16299eac 3010 if( AliTPCReconstructor::StreamLevel()>3){
be34cb88 3011 TTreeSRedirector &cstream = *fDebugStreamer;
3012 cstream<<"RemoveUsed"<<
3013 "iter="<<fIteration<<
3014 "pt.="<<pt<<
3015 "\n";
3016 }
ddfbc51a 3017 MarkSeedFree( arr->RemoveAt(trackindex) );
b406fdb0 3018 continue;
3019 }
3020 if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){ //remove short tracks
3021 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
16299eac 3022 if( AliTPCReconstructor::StreamLevel()>3){
be34cb88 3023 TTreeSRedirector &cstream = *fDebugStreamer;
3024 cstream<<"RemoveShort"<<
3025 "iter="<<fIteration<<
3026 "pt.="<<pt<<
3027 "\n";
3028 }
ddfbc51a 3029 MarkSeedFree( arr->RemoveAt(trackindex) );
b406fdb0 3030 continue;
3031 }
51ad6848 3032 }
3033
3034 good++;
6d493ea0 3035 //if (sharedfactor>0.4) continue;
b406fdb0 3036 if (pt->GetKinkIndexes()[0]>0) continue;
6d493ea0 3037 //Remove tracks with undefined properties - seems
3038 if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ?
3039 //
51ad6848 3040 for (Int_t i=first; i<last; i++) {
3041 Int_t index=pt->GetClusterIndex2(i);
3042 // if (index<0 || index&0x8000 ) continue;
3043 if (index<0 || index&0x8000 ) continue;
b9671574 3044 AliTPCclusterMI *c= pt->GetClusterPointer(i);
51ad6848 3045 if (!c) continue;
3046 c->Use(10);
3047 }
3048 }
3049 fNtracks = good;
3050 if (fDebug>0){
3051 Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
3052 }
3053 delete []quality;
3054 delete []indexes;
3055}
3056
829455ad 3057void AliTPCtracker::DumpClusters(Int_t iter, TObjArray *trackArray)
f47588e0 3058{
3059 //
3060 // Dump clusters after reco
3061 // signed and unsigned cluster can be visualized
3062 // 1. Unsign all cluster
3063 // 2. Sign all used clusters
3064 // 3. Dump clusters
3065 UnsignClusters();
3066 Int_t nseed = trackArray->GetEntries();
3067 for (Int_t i=0; i<nseed; i++){
3068 AliTPCseed *pt=(AliTPCseed*)trackArray->UncheckedAt(i);
3069 if (!pt) {
3070 continue;
3071 }
3072 Bool_t isKink=pt->GetKinkIndex(0)!=0;
3073 for (Int_t j=0; j<160; ++j) {
3074 Int_t index=pt->GetClusterIndex2(j);
3075 if (index<0) continue;
3076 AliTPCclusterMI *c= pt->GetClusterPointer(j);
3077 if (!c) continue;
3078 if (isKink) c->Use(100); // kink
3079 c->Use(10); // by default usage 10
3080 }
3081 }
3082 //
3083
3084 for (Int_t sec=0;sec<fkNIS;sec++){
3085 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
bfa00fba 3086 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
f47588e0 3087 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++){
bfa00fba 3088 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
3089 Float_t gx[3]; cl->GetGlobalXYZ(gx);
f47588e0 3090 (*fDebugStreamer)<<"clDump"<<
3091 "iter="<<iter<<
bfa00fba 3092 "cl.="<<cl<<
f47588e0 3093 "gx0="<<gx[0]<<
3094 "gx1="<<gx[1]<<
3095 "gx2="<<gx[2]<<
3096 "\n";
3097 }
bfa00fba 3098 cla = fInnerSec[sec][row].GetClusters2();
f47588e0 3099 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++){
bfa00fba 3100 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
3101 Float_t gx[3]; cl->GetGlobalXYZ(gx);
f47588e0 3102 (*fDebugStreamer)<<"clDump"<<
3103 "iter="<<iter<<
bfa00fba 3104 "cl.="<<cl<<
f47588e0 3105 "gx0="<<gx[0]<<
3106 "gx1="<<gx[1]<<
3107 "gx2="<<gx[2]<<
3108 "\n";
3109 }
3110 }
3111 }
3112
3113 for (Int_t sec=0;sec<fkNOS;sec++){
3114 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
bfa00fba 3115 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
f47588e0 3116 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++){
bfa00fba 3117 Float_t gx[3];
3118 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
3119 cl->GetGlobalXYZ(gx);
f47588e0 3120 (*fDebugStreamer)<<"clDump"<<
3121 "iter="<<iter<<
bfa00fba 3122 "cl.="<<cl<<
f47588e0 3123 "gx0="<<gx[0]<<
3124 "gx1="<<gx[1]<<
3125 "gx2="<<gx[2]<<
3126 "\n";
3127 }
bfa00fba 3128 cla = fOuterSec[sec][row].GetClusters2();
f47588e0 3129 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++){
bfa00fba 3130 Float_t gx[3];
3131 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
3132 cl->GetGlobalXYZ(gx);
f47588e0 3133 (*fDebugStreamer)<<"clDump"<<
3134 "iter="<<iter<<
bfa00fba 3135 "cl.="<<cl<<
f47588e0 3136 "gx0="<<gx[0]<<
3137 "gx1="<<gx[1]<<
3138 "gx2="<<gx[2]<<
3139 "\n";
3140 }
3141 }
3142 }
3143
3144}
829455ad 3145void AliTPCtracker::UnsignClusters()
1c53abe2 3146{
91162307 3147 //
3148 // loop over all clusters and unsign them
3149 //
3150
3151 for (Int_t sec=0;sec<fkNIS;sec++){
3152 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
bfa00fba 3153 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
b9671574 3154 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
91162307 3155 // if (cl[icl].IsUsed(10))
bfa00fba 3156 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
3157 cla = fInnerSec[sec][row].GetClusters2();
b9671574 3158 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
91162307 3159 //if (cl[icl].IsUsed(10))
bfa00fba 3160 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
91162307 3161 }
3162 }
3163
3164 for (Int_t sec=0;sec<fkNOS;sec++){
3165 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
bfa00fba 3166 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
b9671574 3167 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
91162307 3168 //if (cl[icl].IsUsed(10))
bfa00fba 3169 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
3170 cla = fOuterSec[sec][row].GetClusters2();
b9671574 3171 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
91162307 3172 //if (cl[icl].IsUsed(10))
bfa00fba 3173 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
91162307 3174 }
3175 }
3176
1c53abe2 3177}
3178
91162307 3179
3180
829455ad 3181void AliTPCtracker::SignClusters(const TObjArray * arr, Float_t fnumber, Float_t fdensity)
1c53abe2 3182{
3183 //
91162307 3184 //sign clusters to be "used"
3185 //
3186 // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
3187 // loop over "primaries"
3188
3189 Float_t sumdens=0;
3190 Float_t sumdens2=0;
3191 Float_t sumn =0;
3192 Float_t sumn2 =0;
3193 Float_t sumchi =0;
3194 Float_t sumchi2 =0;
3195
3196 Float_t sum =0;
3197
1c53abe2 3198 TStopwatch timer;
91162307 3199 timer.Start();
1c53abe2 3200
91162307 3201 Int_t nseed = arr->GetEntriesFast();
3202 for (Int_t i=0; i<nseed; i++) {
3203 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3204 if (!pt) {
3205 continue;
3206 }
3207 if (!(pt->IsActive())) continue;
b9671574 3208 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
91162307 3209 if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
3210 sumdens += dens;
3211 sumdens2+= dens*dens;
3212 sumn += pt->GetNumberOfClusters();
3213 sumn2 += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
3214 Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
3215 if (chi2>5) chi2=5;
3216 sumchi +=chi2;
3217 sumchi2 +=chi2*chi2;
3218 sum++;
3219 }
1627d1c4 3220 }
91162307 3221
3222 Float_t mdensity = 0.9;
3223 Float_t meann = 130;
3224 Float_t meanchi = 1;
3225 Float_t sdensity = 0.1;
3226 Float_t smeann = 10;
3227 Float_t smeanchi =0.4;
1627d1c4 3228
91162307 3229
3230 if (sum>20){
3231 mdensity = sumdens/sum;
3232 meann = sumn/sum;
3233 meanchi = sumchi/sum;
3234 //
3235 sdensity = sumdens2/sum-mdensity*mdensity;
c1ea348f 3236 if (sdensity >= 0)
3237 sdensity = TMath::Sqrt(sdensity);
3238 else
3239 sdensity = 0.1;
91162307 3240 //
3241 smeann = sumn2/sum-meann*meann;
c1ea348f 3242 if (smeann >= 0)
3243 smeann = TMath::Sqrt(smeann);
3244 else
3245 smeann = 10;
91162307 3246 //
3247 smeanchi = sumchi2/sum - meanchi*meanchi;
c1ea348f 3248 if (smeanchi >= 0)
3249 smeanchi = TMath::Sqrt(smeanchi);
3250 else
3251 smeanchi = 0.4;
91162307 3252 }
3253
3254
3255 //REMOVE SHORT DELTAS or tracks going out of sensitive volume of TPC
3256 //
3257 for (Int_t i=0; i<nseed; i++) {
3258 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3259 if (!pt) {
3260 continue;
1c53abe2 3261 }
b9671574 3262 if (pt->GetBSigned()) continue;
3263 if (pt->GetBConstrain()) continue;
91162307 3264 //if (!(pt->IsActive())) continue;
3265 /*
3266 Int_t found,foundable,shared;
3267 pt->GetClusterStatistic(0,160,found, foundable,shared);
3268 if (shared/float(found)>0.3) {
3269 if (shared/float(found)>0.9 ){
ddfbc51a 3270 //MarkSeedFree( arr->RemoveAt(i) );
91162307 3271 }
3272 continue;
c9427e08 3273 }
91162307 3274 */
3275 Bool_t isok =kFALSE;
b9671574 3276 if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
91162307 3277 isok = kTRUE;
b9671574 3278 if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
91162307 3279 isok =kTRUE;
3280 if (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
3281 isok =kTRUE;
3282 if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
3283 isok =kTRUE;
3284
3285 if (isok)
77f88633 3286 for (Int_t j=0; j<160; ++j) {
3287 Int_t index=pt->GetClusterIndex2(j);
91162307 3288 if (index<0) continue;
77f88633 3289 AliTPCclusterMI *c= pt->GetClusterPointer(j);
91162307 3290 if (!c) continue;
3291 //if (!(c->IsUsed(10))) c->Use();
3292 c->Use(10);
3293 }
3294 }
3295
c9427e08 3296
1c53abe2 3297 //
91162307 3298 Double_t maxchi = meanchi+2.*smeanchi;
3299
3300 for (Int_t i=0; i<nseed; i++) {
3301 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3302 if (!pt) {
1c53abe2 3303 continue;
91162307 3304 }
3305 //if (!(pt->IsActive())) continue;
b9671574 3306 if (pt->GetBSigned()) continue;
91162307 3307 Double_t chi = pt->GetChi2()/pt->GetNumberOfClusters();
3308 if (chi>maxchi) continue;
3309
3310 Float_t bfactor=1;
b9671574 3311 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
91162307 3312
3313 //sign only tracks with enoug big density at the beginning
3314
3315 if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue;
3316
3317
3e5d0aa2 3318 Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
91162307 3319 Double_t minn = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
3320
3321 // if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
b9671574 3322 if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
91162307 3323 minn=0;
3324
3325 if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
3326 //Int_t noc=pt->GetNumberOfClusters();
b9671574 3327 pt->SetBSigned(kTRUE);
77f88633 3328 for (Int_t j=0; j<160; ++j) {
91162307 3329
77f88633 3330 Int_t index=pt->GetClusterIndex2(j);
91162307 3331 if (index<0) continue;
77f88633 3332 AliTPCclusterMI *c= pt->GetClusterPointer(j);
91162307 3333 if (!c) continue;
3334 // if (!(c->IsUsed(10))) c->Use();
3335 c->Use(10);
3336 }
1c53abe2 3337 }
91162307 3338 }
3339 // gLastCheck = nseed;
3340 // arr->Compress();
3341 if (fDebug>0){
3342 timer.Print();
3343 }
1c53abe2 3344}
3345
3346
1c53abe2 3347
829455ad 3348Int_t AliTPCtracker::RefitInward(AliESDEvent *event)
d26d9159 3349{
3350 //
3351 // back propagation of ESD tracks
3352 //
3353 //return 0;
ec26e231 3354 if (!event) return 0;
6d493ea0 3355 const Int_t kMaxFriendTracks=2000;
d26d9159 3356 fEvent = event;
72e25240 3357 fEventHLT = 0;
6d64657a 3358 // extract correction object for multiplicity dependence of dEdx
3359 TObjArray * gainCalibArray = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(event->GetRunNumber());
23728788 3360
3361 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
3362 if (!transform) {
3363 AliFatal("Tranformations not in RefitInward");
3364 return 0;
3365 }
3366 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
6d64657a 3367 const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
012c4694 3368 Int_t nContribut = event->GetNumberOfTracks();
6d64657a 3369 TGraphErrors * graphMultDependenceDeDx = 0x0;
23728788 3370 if (recoParam && recoParam->GetUseMultiplicityCorrectionDedx() && gainCalibArray) {
6d64657a 3371 if (recoParam->GetUseTotCharge()) {
3372 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
3373 } else {
3374 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
3375 }
3376 }
3377 //
d26d9159 3378 ReadSeeds(event,2);
3379 fIteration=2;
982aff31 3380 //PrepareForProlongation(fSeeds,1);
3381 PropagateForward2(fSeeds);
6d493ea0 3382 RemoveUsed2(fSeeds,0.4,0.4,20);
1af5da7e 3383
bda5ad6d 3384 Int_t entriesSeed=fSeeds->GetEntries();
3385 TObjArray arraySeed(entriesSeed);
3386 for (Int_t i=0;i<entriesSeed;i++) {
a0f4d6a6 3387 arraySeed.AddAt(fSeeds->At(i),i);
3388 }
3389 SignShared(&arraySeed);
6d493ea0 3390 // FindCurling(fSeeds, event,2); // find multi found tracks
1af5da7e 3391 FindSplitted(fSeeds, event,2); // find multi found tracks
16299eac 3392 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,2); // find multi found tracks
af32720d 3393
4d158c36 3394 Int_t ntracks=0;
d26d9159 3395 Int_t nseed = fSeeds->GetEntriesFast();
3396 for (Int_t i=0;i<nseed;i++){
3397 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
4d158c36 3398 if (!seed) continue;
eea478d3 3399 if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
be34cb88 3400 AliESDtrack *esd=event->GetTrack(i);
3401
3402 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
3403 AliExternalTrackParam paramIn;
3404 AliExternalTrackParam paramOut;
3405 Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
16299eac 3406 if (AliTPCReconstructor::StreamLevel()>2) {
0e90d29a 3407 (*fDebugStreamer)<<"RecoverIn"<<
3408 "seed.="<<seed<<
3409 "esd.="<<esd<<
3410 "pin.="<<&paramIn<<
3411 "pout.="<<&paramOut<<
3412 "ncl="<<ncl<<
3413 "\n";
3414 }
be34cb88 3415 if (ncl>15) {
3416 seed->Set(paramIn.GetX(),paramIn.GetAlpha(),paramIn.GetParameter(),paramIn.GetCovariance());
3417 seed->SetNumberOfClusters(ncl);
3418 }
3419 }
eea478d3 3420
47af7ca4 3421 seed->PropagateTo(fkParam->GetInnerRadiusLow());
51ad6848 3422 seed->UpdatePoints();
92f513f5 3423 AddCovariance(seed);
bad6eb00 3424 MakeESDBitmaps(seed, esd);
d26d9159 3425 seed->CookdEdx(0.02,0.6);
3426 CookLabel(seed,0.1); //For comparison only
af32720d 3427 //
ec26e231 3428 if (AliTPCReconstructor::StreamLevel()>1 && seed!=0) {
af32720d 3429 TTreeSRedirector &cstream = *fDebugStreamer;
3430 cstream<<"Crefit"<<
3431 "Esd.="<<esd<<
3432 "Track.="<<seed<<
3433 "\n";
3434 }
c274e255 3435
51ad6848 3436 if (seed->GetNumberOfClusters()>15){
4d158c36 3437 esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
51ad6848 3438 esd->SetTPCPoints(seed->GetPoints());
b9671574 3439 esd->SetTPCPointsF(seed->GetNFoundable());
83afd539 3440 Int_t ndedx = seed->GetNCDEDX(0);
3441 Float_t sdedx = seed->GetSDEDX(0);
b406fdb0 3442 Float_t dedx = seed->GetdEdx();
6d64657a 3443 // apply mutliplicity dependent dEdx correction if available
3444 if (graphMultDependenceDeDx) {
6d64657a 3445 Double_t corrGain = AliTPCcalibDButil::EvalGraphConst(graphMultDependenceDeDx, nContribut);
012c4694 3446 dedx += (1 - corrGain)*50.; // MIP is normalized to 50
6d64657a 3447 }
b406fdb0 3448 esd->SetTPCsignal(dedx, sdedx, ndedx);
fdedfdec 3449 //
64bf5ca0 3450 // fill new dEdx information
3451 //
3452 Double32_t signal[4];
dee67df8 3453 Double32_t signalMax[4];
64bf5ca0 3454 Char_t ncl[3];
3455 Char_t nrows[3];
3456 //
3457 for(Int_t iarr=0;iarr<3;iarr++) {
fb57da8a 3458 signal[iarr] = seed->GetDEDXregion(iarr+1);
dee67df8 3459 signalMax[iarr] = seed->GetDEDXregion(iarr+5);
fb57da8a 3460 ncl[iarr] = seed->GetNCDEDX(iarr+1);
3461 nrows[iarr] = seed->GetNCDEDXInclThres(iarr+1);
64bf5ca0 3462 }
3463 signal[3] = seed->GetDEDXregion(4);
dee67df8 3464 signalMax[3] = seed->GetDEDXregion(8);
3465
64bf5ca0 3466 //
ddfbc51a 3467 AliTPCdEdxInfo * infoTpcPid = new AliTPCdEdxInfo();
64bf5ca0 3468 infoTpcPid->SetTPCSignalRegionInfo(signal, ncl, nrows);
dee67df8 3469 infoTpcPid->SetTPCSignalsQmax(signalMax);
64bf5ca0 3470 esd->SetTPCdEdxInfo(infoTpcPid);
3471 //
fdedfdec 3472 // add seed to the esd track in Calib level
3473 //
6d493ea0 3474 Bool_t storeFriend = gRandom->Rndm()<(kMaxFriendTracks)/Float_t(nseed);
ddfbc51a 3475 if (AliTPCReconstructor::StreamLevel()>0 &&storeFriend){
3476 // RS: this is the only place where the seed is created not in the pool,
3477 // since it should belong to ESDevent
3478 AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE);
fdedfdec 3479 esd->AddCalibObject(seedCopy);
3480 }
4d158c36 3481 ntracks++;
d26d9159 3482 }
3483 else{
3484 //printf("problem\n");
3485 }
3486 }
51ad6848 3487 //FindKinks(fSeeds,event);
f47588e0 3488 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(2,fSeeds);
4d158c36 3489 Info("RefitInward","Number of refitted tracks %d",ntracks);
3aa6a136 3490
3491 AliCosmicTracker::FindCosmic(event, kTRUE);
3492
5576d489 3493 FillClusterOccupancyInfo();
3494
d26d9159 3495 return 0;
3496}
3497
1c53abe2 3498
829455ad 3499Int_t AliTPCtracker::PropagateBack(AliESDEvent *event)
91162307 3500{
3501 //
3502 // back propagation of ESD tracks
3503 //
ec26e231 3504 if (!event) return 0;
91162307 3505 fEvent = event;
72e25240 3506 fEventHLT = 0;
d26d9159 3507 fIteration = 1;
5d837844 3508 ReadSeeds(event,1);
b406fdb0 3509 PropagateBack(fSeeds);
3510 RemoveUsed2(fSeeds,0.4,0.4,20);
6d493ea0 3511 //FindCurling(fSeeds, fEvent,1);
1af5da7e 3512 FindSplitted(fSeeds, event,1); // find multi found tracks
16299eac 3513 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,1); // find multi found tracks
1af5da7e 3514
b406fdb0 3515 //
91162307 3516 Int_t nseed = fSeeds->GetEntriesFast();
4d158c36 3517 Int_t ntracks=0;
91162307 3518 for (Int_t i=0;i<nseed;i++){
3519 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
d9e62e7e 3520 if (!seed) continue;
51ad6848 3521 if (seed->GetKinkIndex(0)<0) UpdateKinkQualityM(seed); // update quality informations for kinks
3522 seed->UpdatePoints();
92f513f5 3523 AddCovariance(seed);
91162307 3524 AliESDtrack *esd=event->GetTrack(i);
e1dadcd0 3525 if (!esd) continue; //never happen
be34cb88 3526 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
3527 AliExternalTrackParam paramIn;
3528 AliExternalTrackParam paramOut;
3529 Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
16299eac 3530 if (AliTPCReconstructor::StreamLevel()>2) {
ca449e98 3531 (*fDebugStreamer)<<"RecoverBack"<<
3532 "seed.="<<seed<<
3533 "esd.="<<esd<<
3534 "pin.="<<&paramIn<<
3535 "pout.="<<&paramOut<<
3536 "ncl="<<ncl<<
3537 "\n";
3538 }
be34cb88 3539 if (ncl>15) {
3540 seed->Set(paramOut.GetX(),paramOut.GetAlpha(),paramOut.GetParameter(),paramOut.GetCovariance());
3541 seed->SetNumberOfClusters(ncl);
3542 }
3543 }
d26d9159 3544 seed->CookdEdx(0.02,0.6);
91162307 3545 CookLabel(seed,0.1); //For comparison only
51ad6848 3546 if (seed->GetNumberOfClusters()>15){
4d158c36 3547 esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
51ad6848 3548 esd->SetTPCPoints(seed->GetPoints());
b9671574 3549 esd->SetTPCPointsF(seed->GetNFoundable());
83afd539 3550 Int_t ndedx = seed->GetNCDEDX(0);
3551 Float_t sdedx = seed->GetSDEDX(0);
167c41ab 3552 Float_t dedx = seed->GetdEdx();
3553 esd->SetTPCsignal(dedx, sdedx, ndedx);
4d158c36 3554 ntracks++;
31fd97b2 3555 Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
3556 // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
8cecaa87 3557 if (AliTPCReconstructor::StreamLevel()>1 && esd) {
6d493ea0 3558 (*fDebugStreamer)<<"Cback"<<
3559 "Tr0.="<<seed<<
8cecaa87 3560 "esd.="<<esd<<
6d493ea0 3561 "EventNrInFile="<<eventnumber<<
8cecaa87 3562 "\n";
6d493ea0 3563 }
4d158c36 3564 }
91162307 3565 }
f47588e0 3566 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(1,fSeeds);
51ad6848 3567 //FindKinks(fSeeds,event);
4d158c36 3568 Info("PropagateBack","Number of back propagated tracks %d",ntracks);
91162307 3569 fEvent =0;
72e25240 3570 fEventHLT = 0;
3571
91162307 3572 return 0;
3573}
3574
3575
829455ad 3576Int_t AliTPCtracker::PostProcess(AliESDEvent *event)
ec7e4ad6 3577{
3578 //
3579 // Post process events
3580 //
3581 if (!event) return 0;
3582
3583 //
3584 // Set TPC event status
3585 //
3586
3587 // event affected by HV dip
3588 // reset TPC status
3589 if(IsTPCHVDipEvent(event)) {
3590 event->ResetDetectorStatus(AliDAQ::kTPC);
3591 }
3592
3593 //printf("Status %d \n", event->IsDetectorOn(AliDAQ::kTPC));
3594
3595 return 0;
3596}
3597
3598
829455ad 3599 void AliTPCtracker::DeleteSeeds()
91162307 3600{
b67e07dc 3601 //
f06a1ff6 3602 fSeeds->Clear();
ddfbc51a 3603 ResetSeedsPool();
91162307 3604 delete fSeeds;
3605 fSeeds =0;
3606}
3607
829455ad 3608void AliTPCtracker::ReadSeeds(const AliESDEvent *const event, Int_t direction)
91162307 3609{
3610 //
3611 //read seeds from the event
3612
3613 Int_t nentr=event->GetNumberOfTracks();
6bdc18d6 3614 if (fDebug>0){
3615 Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
3616 }
91162307 3617 if (fSeeds)
3618 DeleteSeeds();
3619 if (!fSeeds){
4d158c36 3620 fSeeds = new TObjArray(nentr);
91162307 3621 }
4d158c36 3622 UnsignClusters();
3623 // Int_t ntrk=0;
91162307 3624 for (Int_t i=0; i<nentr; i++) {
3625 AliESDtrack *esd=event->GetTrack(i);
51ad6848 3626 ULong_t status=esd->GetStatus();
3627 if (!(status&AliESDtrack::kTPCin)) continue;
1af5da7e 3628 AliTPCtrack t(*esd);
5d837844 3629 t.SetNumberOfClusters(0);
eea478d3 3630 // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
ddfbc51a 3631 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(t/*,t.GetAlpha()*/);
3632 seed->SetPoolID(fLastSeedID);
a0f4d6a6 3633 seed->SetUniqueID(esd->GetID());
92f513f5 3634 AddCovariance(seed); //add systematic ucertainty
eea478d3 3635 for (Int_t ikink=0;ikink<3;ikink++) {
3636 Int_t index = esd->GetKinkIndex(ikink);
3637 seed->GetKinkIndexes()[ikink] = index;
3638 if (index==0) continue;
3639 index = TMath::Abs(index);
3640 AliESDkink * kink = fEvent->GetKink(index-1);
3641 if (kink&&esd->GetKinkIndex(ikink)<0){
3642 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
3643 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,0);
3644 }
3645 if (kink&&esd->GetKinkIndex(ikink)>0){
3646 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
3647 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,4);
3648 }
3649
3650 }
6c94f330 3651 if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.);
2c4acef0 3652 //RS if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
6c94f330 3653 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
be34cb88 3654 //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
3655 // fSeeds->AddAt(0,i);
ddfbc51a 3656 // MarkSeedFree( seed );
be34cb88 3657 // continue;
3658 //}
a3986da2 3659
91162307 3660 //
3661 //
3662 // rotate to the local coordinate system
eea478d3 3663 //
3664 fSectors=fInnerSec; fN=fkNIS;
f124f8bf 3665 Double_t alpha=seed->GetAlpha();
91162307 3666 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
3667 if (alpha < 0. ) alpha += 2.*TMath::Pi();
a3f36f42 3668 Int_t ns=Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
91162307 3669 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
f124f8bf 3670 alpha-=seed->GetAlpha();
4d158c36 3671 if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
3672 if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
f124f8bf 3673 if (TMath::Abs(alpha) > 0.001) { // This should not happen normally
3674 AliWarning(Form("Rotating track over %f",alpha));
3675 if (!seed->Rotate(alpha)) {
ddfbc51a 3676 MarkSeedFree( seed );
f124f8bf 3677 continue;
3678 }
d9b8978b 3679 }
b9671574 3680 seed->SetESD(esd);
4d158c36 3681 // sign clusters
b406fdb0 3682 if (esd->GetKinkIndex(0)<=0){
3683 for (Int_t irow=0;irow<160;irow++){
3684 Int_t index = seed->GetClusterIndex2(irow);
bad6eb00 3685 if (index >= 0){
b406fdb0 3686 //
3687 AliTPCclusterMI * cl = GetClusterMI(index);
b9671574 3688 seed->SetClusterPointer(irow,cl);
b406fdb0 3689 if (cl){
3690 if ((index & 0x8000)==0){
3691 cl->Use(10); // accepted cluster
3692 }else{
3693 cl->Use(6); // close cluster not accepted
3694 }
4d158c36 3695 }else{
b406fdb0 3696 Info("ReadSeeds","Not found cluster");
3697 }
4d158c36 3698 }
3699 }
3700 }
3701 fSeeds->AddAt(seed,i);
91162307 3702 }
3703}
3704
3705
3706
3707//_____________________________________________________________________________
829455ad 3708void AliTPCtracker::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
91162307 3709 Float_t deltay, Int_t ddsec) {
3710 //-----------------------------------------------------------------
3711 // This function creates track seeds.
3712 // SEEDING WITH VERTEX CONSTRAIN
3713 //-----------------------------------------------------------------
3714 // cuts[0] - fP4 cut
3715 // cuts[1] - tan(phi) cut
3716 // cuts[2] - zvertex cut
3717 // cuts[3] - fP3 cut
3718 Int_t nin0 = 0;
3719 Int_t nin1 = 0;
3720 Int_t nin2 = 0;
3721 Int_t nin = 0;
3722 Int_t nout1 = 0;
3723 Int_t nout2 = 0;
3724
3725 Double_t x[5], c[15];
3726 // Int_t di = i1-i2;
3727 //
ddfbc51a 3728 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed();
3729 seed->SetPoolID(fLastSeedID);
91162307 3730 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
3731 Double_t cs=cos(alpha), sn=sin(alpha);
d757548f 3732 //
3733 // Double_t x1 =fOuterSec->GetX(i1);
3734 //Double_t xx2=fOuterSec->GetX(i2);
3735
91162307 3736 Double_t x1 =GetXrow(i1);
3737 Double_t xx2=GetXrow(i2);
3738
3739 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
3740
3741 Int_t imiddle = (i2+i1)/2; //middle pad row index
3742 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
bd26fa83 3743 const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
91162307 3744 //
3745 Int_t ns =sec;
3746
bd26fa83 3747 const AliTPCtrackerRow& kr1=GetRow(ns,i1);
b9671574 3748 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
3749 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
91162307 3750
3751 //
3752 // change cut on curvature if it can't reach this layer
3753 // maximal curvature set to reach it
3754 Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
3755 if (dvertexmax*0.5*cuts[0]>0.85){
3756 cuts[0] = 0.85/(dvertexmax*0.5+1.);
3757 }
3758 Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
3759
3760 // Int_t ddsec = 1;
3761 if (deltay>0) ddsec = 0;
3762 // loop over clusters
3763 for (Int_t is=0; is < kr1; is++) {
3764 //
3765 if (kr1[is]->IsUsed(10)) continue;
3766 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3767 //if (TMath::Abs(y1)>ymax) continue;
3768
3769 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3770
3771 // find possible directions
3772 Float_t anglez = (z1-z3)/(x1-x3);
3773 Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
3774 //
3775 //
3776 //find rotation angles relative to line given by vertex and point 1
3777 Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
3778 Double_t dvertex = TMath::Sqrt(dvertex2);
3779 Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
3780 Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
3781
3782 //
3783 // loop over 2 sectors
3784 Int_t dsec1=-ddsec;
3785 Int_t dsec2= ddsec;
3786 if (y1<0) dsec2= 0;
3787 if (y1>0) dsec1= 0;
3788
3789 Double_t dddz1=0; // direction of delta inclination in z axis
3790 Double_t dddz2=0;
3791 if ( (z1-z3)>0)
3792 dddz1 =1;
3793 else
3794 dddz2 =1;
3795 //
3796 for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
3797 Int_t sec2 = sec + dsec;
3798 //
bd26fa83 3799 // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
3800 //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
3801 AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
3802 AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
91162307 3803 Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
3804 Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
3805
3806 // rotation angles to p1-p3
3807 Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
3808 Double_t x2, y2, z2;
3809 //
3810 // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
3811
3812 //
3813 Double_t dxx0 = (xx2-x3)*cs13r;
3814 Double_t dyy0 = (xx2-x3)*sn13r;
3815 for (Int_t js=index1; js < index2; js++) {
3816 const AliTPCclusterMI *kcl = kr2[js];
3817 if (kcl->IsUsed(10)) continue;
3818 //
3819 //calcutate parameters
3820 //
3821 Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
3822 // stright track
3823 if (TMath::Abs(yy0)<0.000001) continue;
3824 Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
3825 Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
3826 Double_t r02 = (0.25+y0*y0)*dvertex2;
3827 //curvature (radius) cut
3828 if (r02<r2min) continue;
3829
3830 nin0++;
3831 //
3832 Double_t c0 = 1/TMath::Sqrt(r02);
3833 if (yy0>0) c0*=-1.;
3834
3835
3836 //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
3837 //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
b67e07dc 3838 Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
3839 Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
91162307 3840 //
3841 //
3842 Double_t z0 = kcl->GetZ();
3843 Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
3844 if (TMath::Abs(zzzz2-z0)>0.5) continue;
3845 nin1++;
3846 //
3847 Double_t dip = (z1-z0)*c0/dfi1;
3848 Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
3849 //
3850 y2 = kcl->GetY();
3851 if (dsec==0){
3852 x2 = xx2;
3853 z2 = kcl->GetZ();
3854 }
3855 else
3856 {
3857 // rotation
3858 z2 = kcl->GetZ();
3859 x2= xx2*cs-y2*sn*dsec;
3860 y2=+xx2*sn*dsec+y2*cs;
3861 }
3862
3863 x[0] = y1;
3864 x[1] = z1;
3865 x[2] = x0;
3866 x[3] = dip;
3867 x[4] = c0;
3868 //
3869 //
3870 // do we have cluster at the middle ?
3871 Double_t ym,zm;
3872 GetProlongation(x1,xm,x,ym,zm);
3873 UInt_t dummy;
3874 AliTPCclusterMI * cm=0;
3875 if (TMath::Abs(ym)-ymaxm<0){
3876 cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3877 if ((!cm) || (cm->IsUsed(10))) {
3878 continue;
3879 }
3880 }
3881 else{
3882 // rotate y1 to system 0
3883 // get state vector in rotated system
3884 Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
3885 Double_t xr2 = x0*cs+yr1*sn*dsec;
3886 Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3887 //
3888 GetProlongation(xx2,xm,xr,ym,zm);
3889 if (TMath::Abs(ym)-ymaxm<0){
3890 cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3891 if ((!cm) || (cm->IsUsed(10))) {
3892 continue;
3893 }
3894 }
3895 }
3896
3897
2a97785a 3898 // Double_t dym = 0;
3899 // Double_t dzm = 0;
3900 // if (cm){
3901 // dym = ym - cm->GetY();
3902 // dzm = zm - cm->GetZ();
3903 // }
91162307 3904 nin2++;
3905
3906
3907 //
3908 //
3909 Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
3910 Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
3911 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
3912 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3913 //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
3914
b67e07dc 3915 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3916 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3917 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3918 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3919 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3920 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
91162307 3921
b67e07dc 3922 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3923 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3924 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3925 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
91162307 3926
1c53abe2 3927 c[0]=sy1;
3928 c[1]=0.; c[2]=sz1;
3929 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3930 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3931 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3932 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3933 c[13]=f30*sy1*f40+f32*sy2*f42;
3934 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
91162307 3935
d757548f 3936 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
91162307 3937
1c53abe2 3938 UInt_t index=kr1.GetIndex(is);
ddfbc51a 3939 if (seed) {MarkSeedFree(seed); seed = 0;}
3940 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, ns*alpha+shift, x, c, index);
3941 seed->SetPoolID(fLastSeedID);
d757548f 3942 track->SetIsSeeding(kTRUE);
3943 track->SetSeed1(i1);
3944 track->SetSeed2(i2);
3945 track->SetSeedType(3);
c9427e08 3946
91162307 3947
3948 //if (dsec==0) {
d757548f 3949 FollowProlongation(*track, (i1+i2)/2,1);
91162307 3950 Int_t foundable,found,shared;
d757548f 3951 track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
3952 if ((found<0.55*foundable) || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
ddfbc51a 3953 MarkSeedFree(seed); seed = 0;
91162307 3954 continue;
3955 }
3956 //}
3957
3958 nin++;
d757548f 3959 FollowProlongation(*track, i2,1);
91162307 3960
3961
3962 //Int_t rc = 1;
d757548f 3963 track->SetBConstrain(1);
91162307 3964 // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
d757548f 3965 track->SetLastPoint(i1); // first cluster in track position
3966 track->SetFirstPoint(track->GetLastPoint());
91162307 3967
d757548f 3968 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3969 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3970 track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
ddfbc51a 3971 MarkSeedFree(seed); seed = 0;
c9427e08 3972 continue;
3973 }
91162307 3974 nout1++;
3975 // Z VERTEX CONDITION
c274e255 3976 Double_t zv, bz=GetBz();
d757548f 3977 if ( !track->GetZAt(0.,bz,zv) ) continue;
91162307 3978 if (TMath::Abs(zv-z3)>cuts[2]) {
d757548f 3979 FollowProlongation(*track, TMath::Max(i2-20,0));
3980 if ( !track->GetZAt(0.,bz,zv) ) continue;
91162307 3981 if (TMath::Abs(zv-z3)>cuts[2]){
d757548f 3982 FollowProlongation(*track, TMath::Max(i2-40,0));
3983 if ( !track->GetZAt(0.,bz,zv) ) continue;
3984 if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
91162307 3985 // make seed without constrain
d757548f 3986 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
91162307 3987 FollowProlongation(*track2, i2,1);
b9671574 3988 track2->SetBConstrain(kFALSE);
3989 track2->SetSeedType(1);
d757548f 3990 arr->AddLast(track2);
ddfbc51a 3991 MarkSeedFree( seed ); seed = 0;
91162307 3992 continue;
3993 }
3994 else{
ddfbc51a 3995 MarkSeedFree( seed ); seed = 0;
91162307 3996 continue;
d757548f 3997
91162307 3998 }
3999 }
c9427e08 4000 }
316c6cd9 4001
d757548f 4002 track->SetSeedType(0);
f06a1ff6 4003 arr->AddLast(track); // note, track is seed, don't free the seed
ddfbc51a 4004 seed = new( NextFreeSeed() ) AliTPCseed;
4005 seed->SetPoolID(fLastSeedID);
91162307 4006 nout2++;
4007 // don't consider other combinations
d757548f 4008 if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
91162307 4009 break;
1c53abe2 4010 }
4011 }
4012 }
6bdc18d6 4013 if (fDebug>3){
4014 Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
91162307 4015 }
ddfbc51a 4016 if (seed) MarkSeedFree( seed );
1c53abe2 4017}
4018
1627d1c4 4019
829455ad 4020void AliTPCtracker::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
91162307 4021 Float_t deltay) {
4022
4023
4024
1627d1c4 4025 //-----------------------------------------------------------------
91162307 4026 // This function creates track seeds.
1627d1c4 4027 //-----------------------------------------------------------------
91162307 4028 // cuts[0] - fP4 cut
4029 // cuts[1] - tan(phi) cut
4030 // cuts[2] - zvertex cut
4031 // cuts[3] - fP3 cut
4032
4033
4034 Int_t nin0 = 0;
4035 Int_t nin1 = 0;
4036 Int_t nin2 = 0;
4037 Int_t nin = 0;
4038 Int_t nout1 = 0;
4039 Int_t nout2 = 0;
4040 Int_t nout3 =0;
4041 Double_t x[5], c[15];
4042 //
4043 // make temporary seed
ddfbc51a 4044 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
4045 seed->SetPoolID(fLastSeedID);
1627d1c4 4046 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
4047 // Double_t cs=cos(alpha), sn=sin(alpha);
91162307 4048 //
4049 //
1627d1c4 4050
91162307 4051 // first 3 padrows
4052 Double_t x1 = GetXrow(i1-1);
bd26fa83 4053 const AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
b9671574 4054 Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
91162307 4055 //
4056 Double_t x1p = GetXrow(i1);
bd26fa83 4057 const AliTPCtrackerRow& kr1p=GetRow(sec,i1);
91162307 4058 //
4059 Double_t x1m = GetXrow(i1-2);
bd26fa83 4060 const AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
1627d1c4 4061
91162307 4062 //
4063 //last 3 padrow for seeding
bd26fa83 4064 AliTPCtrackerRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
91162307 4065 Double_t x3 = GetXrow(i1-7);
4066 // Double_t y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;
4067 //
bd26fa83 4068 AliTPCtrackerRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
91162307 4069 Double_t x3p = GetXrow(i1-6);
4070 //
bd26fa83 4071 AliTPCtrackerRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
91162307 4072 Double_t x3m = GetXrow(i1-8);
1627d1c4 4073
91162307 4074 //
4075 //
4076 // middle padrow
4077 Int_t im = i1-4; //middle pad row index
4078 Double_t xm = GetXrow(im); // radius of middle pad-row
bd26fa83 4079 const AliTPCtrackerRow& krm=GetRow(sec,im); //middle pad -row
91162307 4080 // Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;
4081 //
4082 //
4083 Double_t deltax = x1-x3;
4084 Double_t dymax = deltax*cuts[1];
4085 Double_t dzmax = deltax*cuts[3];
4086 //
4087 // loop over clusters
4088 for (Int_t is=0; is < kr1; is++) {
1627d1c4 4089 //
91162307 4090 if (kr1[is]->IsUsed(10)) continue;
4091 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
1627d1c4 4092 //
91162307 4093 if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
4094 //
4095 Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
4096 Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
4097 //
4098 Double_t y3, z3;
1627d1c4 4099 //
1627d1c4 4100 //
91162307 4101 UInt_t index;
4102 for (Int_t js=index1; js < index2; js++) {
4103 const AliTPCclusterMI *kcl = kr3[js];
4104 if (kcl->IsUsed(10)) continue;
4105 y3 = kcl->GetY();
4106 // apply angular cuts
4107 if (TMath::Abs(y1-y3)>dymax) continue;
97d77e7a 4108 //x3 = x3;
91162307 4109 z3 = kcl->GetZ();
4110 if (TMath::Abs(z1-z3)>dzmax) continue;
4111 //
4112 Double_t angley = (y1-y3)/(x1-x3);
4113 Double_t anglez = (z1-z3)/(x1-x3);
4114 //
4115 Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
4116 Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
4117 //
4118 Double_t yyym = angley*(xm-x1)+y1;
4119 Double_t zzzm = anglez*(xm-x1)+z1;
4120
4121 const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
4122 if (!kcm) continue;
4123 if (kcm->IsUsed(10)) continue;
4124
4125 erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
4126 errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
4127 //
4128 //
4129 //
4130 Int_t used =0;
4131 Int_t found =0;
4132 //
4133 // look around first
4134 const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
4135 anglez*(x1m-x1)+z1,
4136 erry,errz,index);
4137 //
4138 if (kc1m){
4139 found++;
4140 if (kc1m->IsUsed(10)) used++;
1627d1c4 4141 }
91162307 4142 const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
4143 anglez*(x1p-x1)+z1,
4144 erry,errz,index);
1627d1c4 4145 //
91162307 4146 if (kc1p){
4147 found++;
4148 if (kc1p->IsUsed(10)) used++;
1627d1c4 4149 }
91162307 4150 if (used>1) continue;
4151 if (found<1) continue;
1627d1c4 4152
91162307 4153 //
4154 // look around last
4155 const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
4156 anglez*(x3m-x3)+z3,
4157 erry,errz,index);
4158 //
4159 if (kc3m){
4160 found++;
4161 if (kc3m->IsUsed(10)) used++;
4162 }
4163 else
4164 continue;
4165 const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
4166 anglez*(x3p-x3)+z3,
4167 erry,errz,index);
4168 //
4169 if (kc3p){
4170 found++;
4171 if (kc3p->IsUsed(10)) used++;
4172 }
4173 else
4174 continue;
4175 if (used>1) continue;
4176 if (found<3) continue;
4177 //
4178 Double_t x2,y2,z2;
4179 x2 = xm;
4180 y2 = kcm->GetY();
4181 z2 = kcm->GetZ();
4182 //
4183
1627d1c4 4184 x[0]=y1;
4185 x[1]=z1;
b67e07dc 4186 x[4]=F1(x1,y1,x2,y2,x3,y3);
91162307 4187 //if (TMath::Abs(x[4]) >= cuts[0]) continue;
4188 nin0++;
4189 //
b67e07dc 4190 x[2]=F2(x1,y1,x2,y2,x3,y3);
91162307 4191 nin1++;
4192 //
b67e07dc 4193 x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
91162307 4194 //if (TMath::Abs(x[3]) > cuts[3]) continue;
4195 nin2++;
4196 //
4197 //
4198 Double_t sy1=0.1, sz1=0.1;
4199 Double_t sy2=0.1, sz2=0.1;
4200 Double_t sy3=0.1, sy=0.1, sz=0.1;
1627d1c4 4201
b67e07dc 4202 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
4203 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
4204 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
4205 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
4206 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
4207 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
91162307 4208
b67e07dc 4209 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
4210 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
4211 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
4212 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
1627d1c4 4213
4214 c[0]=sy1;
91162307 4215 c[1]=0.; c[2]=sz1;
1627d1c4 4216 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4217 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4218 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4219 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4220 c[13]=f30*sy1*f40+f32*sy2*f42;
4221 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4222
91162307 4223 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
4224
77f88633 4225 index=kr1.GetIndex(is);
ddfbc51a 4226 if (seed) {MarkSeedFree( seed ); seed = 0;}
4227 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, sec*alpha+shift, x, c, index);
4228 seed->SetPoolID(fLastSeedID);
91162307 4229
b9671574 4230 track->SetIsSeeding(kTRUE);
91162307 4231
4232 nin++;
4233 FollowProlongation(*track, i1-7,1);
b9671574 4234 if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
4235 track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
ddfbc51a 4236 MarkSeedFree( seed ); seed = 0;
91162307 4237 continue;
4238 }
4239 nout1++;
4240 nout2++;
4241 //Int_t rc = 1;
4242 FollowProlongation(*track, i2,1);
b9671574 4243 track->SetBConstrain(0);
4244 track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
4245 track->SetFirstPoint(track->GetLastPoint());
91162307 4246
4247 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 4248 track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
4249 track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
ddfbc51a 4250 MarkSeedFree( seed ); seed = 0;
91162307 4251 continue;
4252 }
4253
4254 {
4255 FollowProlongation(*track, TMath::Max(i2-10,0),1);
4256 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
4257 FollowProlongation(*track2, i2,1);
b9671574 4258 track2->SetBConstrain(kFALSE);
4259 track2->SetSeedType(4);
f06a1ff6 4260 arr->AddLast(track2);
ddfbc51a 4261 MarkSeedFree( seed ); seed = 0;
91162307 4262 }
4263
4264
4265 //arr->AddLast(track);
4266 //seed = new AliTPCseed;
4267 nout3++;
4268 }
4269 }
4270
6bdc18d6 4271 if (fDebug>3){
7d85e147 4272 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 4273 }
ddfbc51a 4274 if (seed) MarkSeedFree(seed);
91162307 4275}
4276
4277
4278//_____________________________________________________________________________
829455ad 4279void AliTPCtracker::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
176aff27 4280 Float_t deltay, Bool_t /*bconstrain*/) {
91162307 4281 //-----------------------------------------------------------------
4282 // This function creates track seeds - without vertex constraint
4283 //-----------------------------------------------------------------
4284 // cuts[0] - fP4 cut - not applied
4285 // cuts[1] - tan(phi) cut
4286 // cuts[2] - zvertex cut - not applied
4287 // cuts[3] - fP3 cut
4288 Int_t nin0=0;
4289 Int_t nin1=0;
4290 Int_t nin2=0;
4291 Int_t nin3=0;
4292 // Int_t nin4=0;
4293 //Int_t nin5=0;
4294
4295
4296
4297 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
4298 // Double_t cs=cos(alpha), sn=sin(alpha);
4299 Int_t row0 = (i1+i2)/2;
4300 Int_t drow = (i1-i2)/2;
bd26fa83 4301 const AliTPCtrackerRow& kr0=fSectors[sec][row0];
4302 AliTPCtrackerRow * kr=0;
91162307 4303
4304 AliTPCpolyTrack polytrack;
4305 Int_t nclusters=fSectors[sec][row0];
ddfbc51a 4306 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
4307 seed->SetPoolID(fLastSeedID);
91162307 4308
4309 Int_t sumused=0;
4310 Int_t cused=0;
4311 Int_t cnused=0;
4312 for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
4313 Int_t nfound =0;
4314 Int_t nfoundable =0;
4315 for (Int_t iter =1; iter<2; iter++){ //iterations
bd26fa83 4316 const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
4317 const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];
91162307 4318 const AliTPCclusterMI * cl= kr0[is];
4319
4320 if (cl->IsUsed(10)) {
4321 cused++;
4322 }
4323 else{
4324 cnused++;
4325 }
4326 Double_t x = kr0.GetX();
4327 // Initialization of the polytrack
4328 nfound =0;
4329 nfoundable =0;
4330 polytrack.Reset();
4331 //
4332 Double_t y0= cl->GetY();
4333 Double_t z0= cl->GetZ();
4334 Float_t erry = 0;
4335 Float_t errz = 0;
4336
b9671574 4337 Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
91162307 4338 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
4339
4340 erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
4341 errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
4342 polytrack.AddPoint(x,y0,z0,erry, errz);
4343
4344 sumused=0;
4345 if (cl->IsUsed(10)) sumused++;
4346
4347
4348 Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
4349 Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
4350 //
4351 x = krm.GetX();
4352 AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
4353 if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
4354 erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
4355 errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
4356 if (cl1->IsUsed(10)) sumused++;
4357 polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
4358 }
4359 //
4360 x = krp.GetX();
4361 AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
4362 if (cl2) {
4363 erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
4364 errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
4365 if (cl2->IsUsed(10)) sumused++;
4366 polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
4367 }
4368 //
4369 if (sumused>0) continue;
4370 nin0++;
4371 polytrack.UpdateParameters();
4372 // follow polytrack
4373 roadz = 1.2;
4374 roady = 1.2;
4375 //
4376 Double_t yn,zn;
4377 nfoundable = polytrack.GetN();
4378 nfound = nfoundable;
4379 //
4380 for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
4381 Float_t maxdist = 0.8*(1.+3./(ddrow));
4382 for (Int_t delta = -1;delta<=1;delta+=2){
4383 Int_t row = row0+ddrow*delta;
4384 kr = &(fSectors[sec][row]);
4385 Double_t xn = kr->GetX();
77f88633 4386 Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
91162307 4387 polytrack.GetFitPoint(xn,yn,zn);
77f88633 4388 if (TMath::Abs(yn)>ymax1) continue;
91162307 4389 nfoundable++;
4390 AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
4391 if (cln) {
4392 Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
4393 if (dist<maxdist){
4394 /*
4395 erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
4396 errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
4397 if (cln->IsUsed(10)) {
4398 // printf("used\n");
4399 sumused++;
4400 erry*=2;
4401 errz*=2;
4402 }
4403 */
4404 erry=0.1;
4405 errz=0.1;
4406 polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
4407 nfound++;
4408 }
4409 }
4410 }
4411 if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
4412 polytrack.UpdateParameters();
4413 }
4414 }
4415 if ( (sumused>3) || (sumused>0.5*nfound)) {
4416 //printf("sumused %d\n",sumused);
4417 continue;
4418 }
4419 nin1++;
4420 Double_t dy,dz;
4421 polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
4422 AliTPCpolyTrack track2;
4423
4424 polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
4425 if (track2.GetN()<0.5*nfoundable) continue;
4426 nin2++;
4427
4428 if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
4429 //
4430 // test seed with and without constrain
4431 for (Int_t constrain=0; constrain<=0;constrain++){
4432 // add polytrack candidate
4433
4434 Double_t x[5], c[15];
4435 Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
4436 track2.GetBoundaries(x3,x1);
4437 x2 = (x1+x3)/2.;
4438 track2.GetFitPoint(x1,y1,z1);
4439 track2.GetFitPoint(x2,y2,z2);
4440 track2.GetFitPoint(x3,y3,z3);
4441 //
4442 //is track pointing to the vertex ?
4443 Double_t x0,y0,z0;
4444 x0=0;
4445 polytrack.GetFitPoint(x0,y0,z0);
4446
4447 if (constrain) {
4448 x2 = x3;
4449 y2 = y3;
4450 z2 = z3;
4451
4452 x3 = 0;
4453 y3 = 0;
4454 z3 = 0;
4455 }
4456 x[0]=y1;
4457 x[1]=z1;
b67e07dc 4458 x[4]=F1(x1,y1,x2,y2,x3,y3);
91162307 4459
4460 // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
b67e07dc 4461 x[2]=F2(x1,y1,x2,y2,x3,y3);
91162307 4462
4463 //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
b67e07dc 4464 //x[3]=F3(x1,y1,x2,y2,z1,z2);
4465 x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
91162307 4466 //if (TMath::Abs(x[3]) > cuts[3]) continue;
4467
4468
4469 Double_t sy =0.1, sz =0.1;
4470 Double_t sy1=0.02, sz1=0.02;
4471 Double_t sy2=0.02, sz2=0.02;
4472 Double_t sy3=0.02;
4473
4474 if (constrain){
4475 sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
4476 }
4477
b67e07dc 4478 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
4479 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
4480 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
4481 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
4482 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
4483 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
4484
4485 Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
4486 Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
4487 Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
4488 Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
91162307 4489
4490
4491 c[0]=sy1;
4492 c[1]=0.; c[2]=sz1;
4493 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4494 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4495 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4496 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4497 c[13]=f30*sy1*f40+f32*sy2*f42;
4498 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4499
4500 //Int_t row1 = fSectors->GetRowNumber(x1);
4501 Int_t row1 = GetRowNumber(x1);
4502
4503 UInt_t index=0;
4504 //kr0.GetIndex(is);
ddfbc51a 4505 if (seed) {MarkSeedFree( seed ); seed = 0;}
4506 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1,sec*alpha+shift,x,c,index);
4507 seed->SetPoolID(fLastSeedID);
b9671574 4508 track->SetIsSeeding(kTRUE);
91162307 4509 Int_t rc=FollowProlongation(*track, i2);
b9671574 4510 if (constrain) track->SetBConstrain(1);
91162307 4511 else
b9671574 4512 track->SetBConstrain(0);
4513 track->SetLastPoint(row1+fInnerSec->GetNRows()); // first cluster in track position
4514 track->SetFirstPoint(track->GetLastPoint());
91162307 4515
4516 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 4517 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
4518 track->GetNShared()>0.4*track->GetNumberOfClusters()) {
ddfbc51a 4519 MarkSeedFree( seed ); seed = 0;
91162307 4520 }
4521 else {
f06a1ff6 4522 arr->AddLast(track); // track IS seed, don't free seed
ddfbc51a 4523 seed = new( NextFreeSeed() ) AliTPCseed;
4524 seed->SetPoolID(fLastSeedID);
91162307 4525 }
4526 nin3++;
4527 }
4528 } // if accepted seed
4529 }
6bdc18d6 4530 if (fDebug>3){
4531 Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
91162307 4532 }
ddfbc51a 4533 if (seed) MarkSeedFree( seed );
91162307 4534}
4535
4536
829455ad 4537AliTPCseed *AliTPCtracker::MakeSeed(AliTPCseed *const track, Float_t r0, Float_t r1, Float_t r2)
91162307 4538{
4539 //
4540 //
d26d9159 4541 //reseed using track points
91162307 4542 Int_t p0 = int(r0*track->GetNumberOfClusters()); // point 0
4543 Int_t p1 = int(r1*track->GetNumberOfClusters());
4544 Int_t p2 = int(r2*track->GetNumberOfClusters()); // last point
176aff27 4545 Int_t pp2=0;
91162307 4546 Double_t x0[3],x1[3],x2[3];
89e09524 4547 for (Int_t i=0;i<3;i++){
4548 x0[i]=-1;
4549 x1[i]=-1;
4550 x2[i]=-1;
4551 }
91162307 4552
4553 // find track position at given ratio of the length
89e09524 4554 Int_t sec0=0, sec1=0, sec2=0;
91162307 4555 Int_t index=-1;
4556 Int_t clindex;
4557 for (Int_t i=0;i<160;i++){
b9671574 4558 if (track->GetClusterPointer(i)){
91162307 4559 index++;
4560 AliTPCTrackerPoint *trpoint =track->GetTrackPoint(i);
4561 if ( (index<p0) || x0[0]<0 ){
4562 if (trpoint->GetX()>1){
4563 clindex = track->GetClusterIndex2(i);
bad6eb00 4564 if (clindex >= 0){
91162307 4565 x0[0] = trpoint->GetX();
4566 x0[1] = trpoint->GetY();
4567 x0[2] = trpoint->GetZ();
4568 sec0 = ((clindex&0xff000000)>>24)%18;
4569 }
4570 }
4571 }
4572
4573 if ( (index<p1) &&(trpoint->GetX()>1)){
4574 clindex = track->GetClusterIndex2(i);
bad6eb00 4575 if (clindex >= 0){
91162307 4576 x1[0] = trpoint->GetX();
4577 x1[1] = trpoint->GetY();
4578 x1[2] = trpoint->GetZ();
4579 sec1 = ((clindex&0xff000000)>>24)%18;
4580 }
4581 }
4582 if ( (index<p2) &&(trpoint->GetX()>1)){
4583 clindex = track->GetClusterIndex2(i);
bad6eb00 4584 if (clindex >= 0){
91162307 4585 x2[0] = trpoint->GetX();
4586 x2[1] = trpoint->GetY();
4587 x2[2] = trpoint->GetZ();
4588 sec2 = ((clindex&0xff000000)>>24)%18;
4589 pp2 = i;
4590 }
4591 }
4592 }
4593 }
4594
4595 Double_t alpha, cs,sn, xx2,yy2;
4596 //
4597 alpha = (sec1-sec2)*fSectors->GetAlpha();
4598 cs = TMath::Cos(alpha);
4599 sn = TMath::Sin(alpha);
4600 xx2= x1[0]*cs-x1[1]*sn;
4601 yy2= x1[0]*sn+x1[1]*cs;
4602 x1[0] = xx2;
4603 x1[1] = yy2;
4604 //
4605 alpha = (sec0-sec2)*fSectors->GetAlpha();
4606 cs = TMath::Cos(alpha);
4607 sn = TMath::Sin(alpha);
4608 xx2= x0[0]*cs-x0[1]*sn;
4609 yy2= x0[0]*sn+x0[1]*cs;
4610 x0[0] = xx2;
4611 x0[1] = yy2;
4612 //
4613 //
4614 //
4615 Double_t x[5],c[15];
4616 //
4617 x[0]=x2[1];
4618 x[1]=x2[2];
b67e07dc 4619 x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
91162307 4620 // if (x[4]>1) return 0;
b67e07dc 4621 x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
4622 x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
91162307 4623 //if (TMath::Abs(x[3]) > 2.2) return 0;
4624 //if (TMath::Abs(x[2]) > 1.99) return 0;
4625 //
4626 Double_t sy =0.1, sz =0.1;
4627 //
4628 Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
4629 Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
4630 Double_t sy3=0.01+track->GetSigmaY2();
4631 //
b67e07dc 4632 Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
4633 Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
4634 Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
4635 Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
4636 Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
4637 Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
4638 //
4639 Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
4640 Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
4641 Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
4642 Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
91162307 4643
4644
4645 c[0]=sy1;
4646 c[1]=0.; c[2]=sz1;
4647 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4648 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4649 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4650 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4651 c[13]=f30*sy1*f40+f32*sy2*f42;
4652 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4653
4654 // Int_t row1 = fSectors->GetRowNumber(x2[0]);
ddfbc51a 4655 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4656 seed->SetPoolID(fLastSeedID);
91162307 4657 // Double_t y0,z0,y1,z1, y2,z2;
4658 //seed->GetProlongation(x0[0],y0,z0);
4659 // seed->GetProlongation(x1[0],y1,z1);
4660 //seed->GetProlongation(x2[0],y2,z2);
4661 // seed =0;
b9671574 4662 seed->SetLastPoint(pp2);
4663 seed->SetFirstPoint(pp2);
91162307 4664
4665
4666 return seed;
4667}
4668
d26d9159 4669
829455ad 4670AliTPCseed *AliTPCtracker::ReSeed(const AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
d26d9159 4671{
4672 //
4673 //
4674 //reseed using founded clusters
4675 //
4676 // Find the number of clusters
4677 Int_t nclusters = 0;
4678 for (Int_t irow=0;irow<160;irow++){
4679 if (track->GetClusterIndex(irow)>0) nclusters++;
4680 }
4681 //
4682 Int_t ipos[3];
4683 ipos[0] = TMath::Max(int(r0*nclusters),0); // point 0 cluster
4684 ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1); //
4685 ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1); // last point
4686 //
4687 //
ec26e231 4688 Double_t xyz[3][3]={{0}};
4689 Int_t row[3]={0},sec[3]={0,0,0};
d26d9159 4690 //
4691 // find track row position at given ratio of the length
4692 Int_t index=-1;
4693 for (Int_t irow=0;irow<160;irow++){
4694 if (track->GetClusterIndex2(irow)<0) continue;
4695 index++;
4696 for (Int_t ipoint=0;ipoint<3;ipoint++){
4697 if (index<=ipos[ipoint]) row[ipoint] = irow;
4698 }
4699 }
4700 //
4701 //Get cluster and sector position
4702 for (Int_t ipoint=0;ipoint<3;ipoint++){
4703 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4704 AliTPCclusterMI * cl = GetClusterMI(clindex);
4705 if (cl==0) {
6bdc18d6 4706 //Error("Bug\n");
47966a6d 4707 // AliTPCclusterMI * cl = GetClusterMI(clindex);
d26d9159 4708 return 0;
4709 }
4710 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4711 xyz[ipoint][0] = GetXrow(row[ipoint]);
4712 xyz[ipoint][1] = cl->GetY();
4713 xyz[ipoint][2] = cl->GetZ();
4714 }
4715 //
4716 //
4717 // Calculate seed state vector and covariance matrix
4718
4719 Double_t alpha, cs,sn, xx2,yy2;
4720 //
4721 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4722 cs = TMath::Cos(alpha);
4723 sn = TMath::Sin(alpha);
4724 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4725 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4726 xyz[1][0] = xx2;
4727 xyz[1][1] = yy2;
4728 //
4729 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4730 cs = TMath::Cos(alpha);
4731 sn = TMath::Sin(alpha);
4732 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4733 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4734 xyz[0][0] = xx2;
4735 xyz[0][1] = yy2;
4736 //
4737 //
4738 //
4739 Double_t x[5],c[15];
4740 //
4741 x[0]=xyz[2][1];
4742 x[1]=xyz[2][2];
4743 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4744 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4745 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4746 //
4747 Double_t sy =0.1, sz =0.1;
4748 //
4749 Double_t sy1=0.2, sz1=0.2;
4750 Double_t sy2=0.2, sz2=0.2;
4751 Double_t sy3=0.2;
4752 //
4753 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;
4754 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;
4755 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;
4756 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;
4757 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;
4758 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;
4759 //
4760 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;
4761 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;
4762 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;
4763 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;
4764
4765
4766 c[0]=sy1;
4767 c[1]=0.; c[2]=sz1;
4768 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4769 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4770 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4771 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4772 c[13]=f30*sy1*f40+f32*sy2*f42;
4773 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4774
4775 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
ddfbc51a 4776 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4777 seed->SetPoolID(fLastSeedID);
b9671574 4778 seed->SetLastPoint(row[2]);
4779 seed->SetFirstPoint(row[2]);
d26d9159 4780 return seed;
4781}
4782
eea478d3 4783
829455ad 4784AliTPCseed *AliTPCtracker::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
eea478d3 4785{
4786 //
4787 //
4788 //reseed using founded clusters
4789 //
4790 Double_t xyz[3][3];
4a12af72 4791 Int_t row[3]={0,0,0};
4792 Int_t sec[3]={0,0,0};
eea478d3 4793 //
4794 // forward direction
4795 if (forward){
4796 for (Int_t irow=r0;irow<160;irow++){
4797 if (track->GetClusterIndex(irow)>0){
4798 row[0] = irow;
4799 break;
4800 }
4801 }
4802 for (Int_t irow=160;irow>r0;irow--){
4803 if (track->GetClusterIndex(irow)>0){
4804 row[2] = irow;
4805 break;
4806 }
4807 }
4808 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4809 if (track->GetClusterIndex(irow)>0){
4810 row[1] = irow;
4811 break;
4812 }
4813 }
4814 //
4815 }
4816 if (!forward){
4817 for (Int_t irow=0;irow<r0;irow++){
4818 if (track->GetClusterIndex(irow)>0){
4819 row[0] = irow;
4820 break;
4821 }
4822 }
4823 for (Int_t irow=r0;irow>0;irow--){
4824 if (track->GetClusterIndex(irow)>0){
4825 row[2] = irow;
4826 break;
4827 }
4828 }
4829 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4830 if (track->GetClusterIndex(irow)>0){
4831 row[1] = irow;
4832 break;
4833 }
4834 }
4835 }
4836 //
4837 if ((row[2]-row[0])<20) return 0;
4838 if (row[1]==0) return 0;
4839 //
4840 //
4841 //Get cluster and sector position
4842 for (Int_t ipoint=0;ipoint<3;ipoint++){
4843 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4844 AliTPCclusterMI * cl = GetClusterMI(clindex);
4845 if (cl==0) {
4846 //Error("Bug\n");
4847 // AliTPCclusterMI * cl = GetClusterMI(clindex);
4848 return 0;
4849 }
4850 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4851 xyz[ipoint][0] = GetXrow(row[ipoint]);
4852 AliTPCTrackerPoint * point = track->GetTrackPoint(row[ipoint]);
4853 if (point&&ipoint<2){
4854 //
4855 xyz[ipoint][1] = point->GetY();
4856 xyz[ipoint][2] = point->GetZ();
4857 }
4858 else{
4859 xyz[ipoint][1] = cl->GetY();
4860 xyz[ipoint][2] = cl->GetZ();
4861 }
4862 }
4863 //
4864 //
4865 //
4866 //
4867 // Calculate seed state vector and covariance matrix
4868
4869 Double_t alpha, cs,sn, xx2,yy2;
4870 //
4871 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4872 cs = TMath::Cos(alpha);
4873 sn = TMath::Sin(alpha);
4874 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4875 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4876 xyz[1][0] = xx2;
4877 xyz[1][1] = yy2;
4878 //
4879 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4880 cs = TMath::Cos(alpha);
4881 sn = TMath::Sin(alpha);
4882 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4883 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4884 xyz[0][0] = xx2;
4885 xyz[0][1] = yy2;
4886 //
4887 //
4888 //
4889 Double_t x[5],c[15];
4890 //
4891 x[0]=xyz[2][1];
4892 x[1]=xyz[2][2];
4893 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4894 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4895 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4896 //
4897 Double_t sy =0.1, sz =0.1;
4898 //
4899 Double_t sy1=0.2, sz1=0.2;
4900 Double_t sy2=0.2, sz2=0.2;
4901 Double_t sy3=0.2;
4902 //
4903 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;
4904 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;
4905 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;
4906 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;
4907 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;
4908 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;
4909 //
4910 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;
4911 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;
4912 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;
4913 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;
4914
4915
4916 c[0]=sy1;
4917 c[1]=0.; c[2]=sz1;
4918 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4919 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4920 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4921 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4922 c[13]=f30*sy1*f40+f32*sy2*f42;
4923 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4924
4925 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
ddfbc51a 4926 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4927 seed->SetPoolID(fLastSeedID);
b9671574 4928 seed->SetLastPoint(row[2]);
4929 seed->SetFirstPoint(row[2]);
eea478d3 4930 for (Int_t i=row[0];i<row[2];i++){
b9671574 4931 seed->SetClusterIndex(i, track->GetClusterIndex(i));
eea478d3 4932 }
4933
4934 return seed;
4935}
4936
6d493ea0 4937
4938
829455ad 4939void AliTPCtracker::FindMultiMC(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
6d493ea0 4940{
4941 //
4942 // find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
4943 // USES MC LABELS
4944 // Use AliTPCReconstructor::StreamLevel()>2 if you want to tune parameters - cuts
4945 //
4946 // Two reasons to have multiple find tracks
4947 // 1. Curling tracks can be find more than once
4948 // 2. Splitted tracks
4949 // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
4950 // b.) Edge effect on the sector boundaries
4951 //
4952 //
4953 // Algorithm done in 2 phases - because of CPU consumption
4954 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4955 //
4956 // Algorihm for curling tracks sign:
4957 // 1 phase -makes a very rough fast cuts to minimize combinatorics
4958 // a.) opposite sign
4959 // b.) one of the tracks - not pointing to the primary vertex -
4960 // c.) delta tan(theta)
4961 // d.) delta phi
4962 // 2 phase - calculates DCA between tracks - time consument
4963
4964 //
4965 // fast cuts
4966 //
4967 // General cuts - for splitted tracks and for curling tracks
4968 //
4969 const Float_t kMaxdPhi = 0.2; // maximal distance in phi
4970 //
4971 // Curling tracks cuts
4972 //
4973 //
4974 //
4975 //
4976 Int_t nentries = array->GetEntriesFast();
4977 AliHelix *helixes = new AliHelix[nentries];
4978 Float_t *xm = new Float_t[nentries];
4979 Float_t *dz0 = new Float_t[nentries];
4980 Float_t *dz1 = new Float_t[nentries];
4981 //
4982 //
4983 TStopwatch timer;
4984 timer.Start();
4985 //
4986 // Find track COG in x direction - point with best defined parameters
4987 //
4988 for (Int_t i=0;i<nentries;i++){
4989 AliTPCseed* track = (AliTPCseed*)array->At(i);
4990 if (!track) continue;
4991 track->SetCircular(0);
4992 new (&helixes[i]) AliHelix(*track);
4993 Int_t ncl=0;
4994 xm[i]=0;
4995 Float_t dz[2];
4996 track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
4997 dz0[i]=dz[0];
4998 dz1[i]=dz[1];
4999 for (Int_t icl=0; icl<160; icl++){
5000 AliTPCclusterMI * cl = track->GetClusterPointer(icl);
5001 if (cl) {
5002 xm[i]+=cl->GetX();
5003 ncl++;
5004 }
5005 }
5006 if (ncl>0) xm[i]/=Float_t(ncl);
5007 }
6d493ea0 5008 //
5009 for (Int_t i0=0;i0<nentries;i0++){
5010 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5011 if (!track0) continue;
5012 Float_t xc0 = helixes[i0].GetHelix(6);
5013 Float_t yc0 = helixes[i0].GetHelix(7);
5014 Float_t r0 = helixes[i0].GetHelix(8);
5015 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
5016 Float_t fi0 = TMath::ATan2(yc0,xc0);
5017
5018 for (Int_t i1=i0+1;i1<nentries;i1++){
5019 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5020 if (!track1) continue;
5021 Int_t lab0=track0->GetLabel();
5022 Int_t lab1=track1->GetLabel();
5023 if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
5024 //
5025 Float_t xc1 = helixes[i1].GetHelix(6);
5026 Float_t yc1 = helixes[i1].GetHelix(7);
5027 Float_t r1 = helixes[i1].GetHelix(8);
5028 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
5029 Float_t fi1 = TMath::ATan2(yc1,xc1);
5030 //
5031 Float_t dfi = fi0-fi1;
5032 //
5033 //
5034 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
5035 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
5036 if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
5037 //
5038 // if short tracks with undefined sign
5039 fi1 = -TMath::ATan2(yc1,-xc1);
5040 dfi = fi0-fi1;
5041 }
5042 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
5043
5044 //
5045 // debug stream to tune "fast cuts"
5046 //
5047 Double_t dist[3]; // distance at X
5048 Double_t mdist[3]={0,0,0}; // mean distance X+-40cm
5049 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
5050 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
5051 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
5052 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
5053 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
5054 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
5055 for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
5056
5057 Float_t sum =0;
5058 Float_t sums=0;
5059 for (Int_t icl=0; icl<160; icl++){
5060 AliTPCclusterMI * cl0 = track0->GetClusterPointer(icl);
5061 AliTPCclusterMI * cl1 = track1->GetClusterPointer(icl);
5062 if (cl0&&cl1) {
5063 sum++;
5064 if (cl0==cl1) sums++;
5065 }
5066 }
5067 //
16299eac 5068 if (AliTPCReconstructor::StreamLevel()>5) {
b194b32c 5069 TTreeSRedirector &cstream = *fDebugStreamer;
6d493ea0 5070 cstream<<"Multi"<<
5071 "iter="<<iter<<
5072 "lab0="<<lab0<<
5073 "lab1="<<lab1<<
5074 "Tr0.="<<track0<< // seed0
5075 "Tr1.="<<track1<< // seed1
5076 "h0.="<<&helixes[i0]<<
5077 "h1.="<<&helixes[i1]<<
5078 //
5079 "sum="<<sum<< //the sum of rows with cl in both
5080 "sums="<<sums<< //the sum of shared clusters
5081 "xm0="<<xm[i0]<< // the center of track
5082 "xm1="<<xm[i1]<< // the x center of track
5083 // General cut variables
5084 "dfi="<<dfi<< // distance in fi angle
5085 "dtheta="<<dtheta<< // distance int theta angle
5086 //
5087 "dz00="<<dz0[i0]<<
5088 "dz01="<<dz0[i1]<<
5089 "dz10="<<dz1[i1]<<
5090 "dz11="<<dz1[i1]<<
5091 "dist0="<<dist[0]<< //distance x
5092 "dist1="<<dist[1]<< //distance y
5093 "dist2="<<dist[2]<< //distance z
5094 "mdist0="<<mdist[0]<< //distance x
5095 "mdist1="<<mdist[1]<< //distance y
5096 "mdist2="<<mdist[2]<< //distance z
5097 //
5098 "r0="<<r0<<
5099 "rc0="<<rc0<<
5100 "fi0="<<fi0<<
5101 "fi1="<<fi1<<
5102 "r1="<<r1<<
5103 "rc1="<<rc1<<
5104 "\n";
b194b32c 5105 }
6d493ea0 5106 }
5107 }
5108 delete [] helixes;
5109 delete [] xm;
ec26e231 5110 delete [] dz0;
5111 delete [] dz1;
6d493ea0 5112 if (AliTPCReconstructor::StreamLevel()>1) {
5113 AliInfo("Time for curling tracks removal DEBUGGING MC");
5114 timer.Print();
5115 }
5116}
5117
5118
1af5da7e 5119
829455ad 5120void AliTPCtracker::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t /*iter*/){
6d493ea0 5121 //
6fbe1e5c 5122 // Find Splitted tracks and remove the one with worst quality
5123 // Corresponding debug streamer to tune selections - "Splitted2"
5124 // Algorithm:
5125 // 0. Sort tracks according quility
5126 // 1. Propagate the tracks to the reference radius
5127 // 2. Double_t loop to select close tracks (only to speed up process)
5128 // 3. Calculate cluster overlap ratio - and remove the track if bigger than a threshold
5129 // 4. Delete temporary parameters
5130 //
5131 const Double_t xref=GetXrow(63); // reference radius -IROC/OROC boundary
5132 // rough cuts
5133 const Double_t kCutP1=10; // delta Z cut 10 cm
5134 const Double_t kCutP2=0.15; // delta snp(fi) cut 0.15
5135 const Double_t kCutP3=0.15; // delta tgl(theta) cut 0.15
5136 const Double_t kCutAlpha=0.15; // delta alpha cut
5137 Int_t firstpoint = 0;
5138 Int_t lastpoint = 160;
6d493ea0 5139 //
5140 Int_t nentries = array->GetEntriesFast();
6fbe1e5c 5141 AliExternalTrackParam *params = new AliExternalTrackParam[nentries];
6d493ea0 5142 //
5143 //
5144 TStopwatch timer;
5145 timer.Start();
5146 //
6fbe1e5c 5147 //0. Sort tracks according quality
5148 //1. Propagate the ext. param to reference radius
6d493ea0 5149 Int_t nseed = array->GetEntriesFast();
6e23caff 5150 if (nseed<=0) return;
6d493ea0 5151 Float_t * quality = new Float_t[nseed];
5152 Int_t * indexes = new Int_t[nseed];
5153 for (Int_t i=0; i<nseed; i++) {
5154 AliTPCseed *pt=(AliTPCseed*)array->UncheckedAt(i);
5155 if (!pt){
5156 quality[i]=-1;
5157 continue;
5158 }
5159 pt->UpdatePoints(); //select first last max dens points
5160 Float_t * points = pt->GetPoints();
5161 if (points[3]<0.8) quality[i] =-1;
5162 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
1af5da7e 5163 //prefer high momenta tracks if overlaps
5164 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
6fbe1e5c 5165 params[i]=(*pt);
5166 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),5.,kTRUE);
5167 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),1.,kTRUE);
6d493ea0 5168 }
5169 TMath::Sort(nseed,quality,indexes);
6d493ea0 5170 //
6fbe1e5c 5171 // 3. Loop over pair of tracks
5172 //
5173 for (Int_t i0=0; i0<nseed; i0++) {
5174 Int_t index0=indexes[i0];
5175 if (!(array->UncheckedAt(index0))) continue;
5176 AliTPCseed *s1 = (AliTPCseed*)array->UncheckedAt(index0);
5177 if (!s1->IsActive()) continue;
5178 AliExternalTrackParam &par0=params[index0];
5179 for (Int_t i1=i0+1; i1<nseed; i1++) {
5180 Int_t index1=indexes[i1];
5181 if (!(array->UncheckedAt(index1))) continue;
5182 AliTPCseed *s2 = (AliTPCseed*)array->UncheckedAt(index1);
5183 if (!s2->IsActive()) continue;
5184 if (s2->GetKinkIndexes()[0]!=0)
5185 if (s2->GetKinkIndexes()[0] == -s1->GetKinkIndexes()[0]) continue;
5186 AliExternalTrackParam &par1=params[index1];
5187 if (TMath::Abs(par0.GetParameter()[3]-par1.GetParameter()[3])>kCutP3) continue;
5188 if (TMath::Abs(par0.GetParameter()[1]-par1.GetParameter()[1])>kCutP1) continue;
5189 if (TMath::Abs(par0.GetParameter()[2]-par1.GetParameter()[2])>kCutP2) continue;
5190 Double_t dAlpha= TMath::Abs(par0.GetAlpha()-par1.GetAlpha());
5191 if (dAlpha>TMath::Pi()) dAlpha-=TMath::Pi();
5192 if (TMath::Abs(dAlpha)>kCutAlpha) continue;
6d493ea0 5193 //
6fbe1e5c 5194 Int_t sumShared=0;
5195 Int_t nall0=0;
5196 Int_t nall1=0;
5197 Int_t firstShared=lastpoint, lastShared=firstpoint;
5198 Int_t firstRow=lastpoint, lastRow=firstpoint;
6d493ea0 5199 //
6fbe1e5c 5200 for (Int_t i=firstpoint;i<lastpoint;i++){
5201 if (s1->GetClusterIndex2(i)>0) nall0++;
5202 if (s2->GetClusterIndex2(i)>0) nall1++;
5203 if (s1->GetClusterIndex2(i)>0 && s2->GetClusterIndex2(i)>0) {
5204 if (i<firstRow) firstRow=i;
5205 if (i>lastRow) lastRow=i;
5206 }
5207 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
5208 if (i<firstShared) firstShared=i;
5209 if (i>lastShared) lastShared=i;
5210 sumShared++;
5211 }
5212 }
5213 Double_t ratio0 = Float_t(sumShared)/Float_t(TMath::Min(nall0+1,nall1+1));
5214 Double_t ratio1 = Float_t(sumShared)/Float_t(TMath::Max(nall0+1,nall1+1));
5215
16299eac 5216 if( AliTPCReconstructor::StreamLevel()>1){
6fbe1e5c 5217 TTreeSRedirector &cstream = *fDebugStreamer;
5218 Int_t n0=s1->GetNumberOfClusters();
5219 Int_t n1=s2->GetNumberOfClusters();
5220 Int_t n0F=s1->GetNFoundable();
5221 Int_t n1F=s2->GetNFoundable();
5222 Int_t lab0=s1->GetLabel();
5223 Int_t lab1=s2->GetLabel();
5224
5225 cstream<<"Splitted2"<<
5226 "iter="<<fIteration<<
5227 "lab0="<<lab0<< // MC label if exist
5228 "lab1="<<lab1<< // MC label if exist
5229 "index0="<<index0<<
5230 "index1="<<index1<<
5231 "ratio0="<<ratio0<< // shared ratio
5232 "ratio1="<<ratio1<< // shared ratio
5233 "p0.="<<&par0<< // track parameters
5234 "p1.="<<&par1<<
5235 "s0.="<<s1<< // full seed
5236 "s1.="<<s2<<
5237 "n0="<<n0<< // number of clusters track 0
5238 "n1="<<n1<< // number of clusters track 1
5239 "nall0="<<nall0<< // number of clusters track 0
5240 "nall1="<<nall1<< // number of clusters track 1
5241 "n0F="<<n0F<< // number of findable
5242 "n1F="<<n1F<< // number of findable
5243 "shared="<<sumShared<< // number of shared clusters
5244 "firstS="<<firstShared<< // first and the last shared row
5245 "lastS="<<lastShared<<
5246 "firstRow="<<firstRow<< // first and the last row with cluster
5247 "lastRow="<<lastRow<< //
5248 "\n";
6d493ea0 5249 }
6d493ea0 5250 //
6fbe1e5c 5251 // remove track with lower quality
6d493ea0 5252 //
6fbe1e5c 5253 if (ratio0>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(0) ||
5254 ratio1>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(1)){
5255 //
5256 //
5257 //
ddfbc51a 5258 MarkSeedFree( array->RemoveAt(index1) );
44adbd4b 5259 }
6d493ea0 5260 }
6fbe1e5c 5261 }
5262 //
5263 // 4. Delete temporary array
5264 //
5265 delete [] params;
6e23caff 5266 delete [] quality;
5267 delete [] indexes;
5268
6d493ea0 5269}
5270
5271
5272
829455ad 5273void AliTPCtracker::FindCurling(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
6d493ea0 5274{
5275 //
5276 // find Curling tracks
5277 // Use AliTPCReconstructor::StreamLevel()>1 if you want to tune parameters - cuts
5278 //
5279 //
5280 // Algorithm done in 2 phases - because of CPU consumption
5281 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
5282 // see detal in MC part what can be used to cut
5283 //
5284 //
5285 //
5286 const Float_t kMaxC = 400; // maximal curvature to of the track
5287 const Float_t kMaxdTheta = 0.15; // maximal distance in theta
5288 const Float_t kMaxdPhi = 0.15; // maximal distance in phi
5289 const Float_t kPtRatio = 0.3; // ratio between pt
5290 const Float_t kMinDCAR = 2.; // distance to the primary vertex in r - see cpipe cut
5291
5292 //
5293 // Curling tracks cuts
5294 //
5295 //
5296 const Float_t kMaxDeltaRMax = 40; // distance in outer radius
5297 const Float_t kMaxDeltaRMin = 5.; // distance in lower radius - see cpipe cut
5298 const Float_t kMinAngle = 2.9; // angle between tracks
5299 const Float_t kMaxDist = 5; // biggest distance
5300 //
5301 // The cuts can be tuned using the "MC information stored in Multi tree ==> see FindMultiMC
5302 /*
5303 Fast cuts:
5304 TCut csign("csign","Tr0.fP[4]*Tr1.fP[4]<0"); //opposite sign
5305 TCut cmax("cmax","abs(Tr0.GetC())>1/400");
5306 TCut cda("cda","sqrt(dtheta^2+dfi^2)<0.15");
5307 TCut ccratio("ccratio","abs((Tr0.fP[4]+Tr1.fP[4])/(abs(Tr0.fP[4])+abs(Tr1.fP[4])))<0.3");
5308 TCut cpipe("cpipe", "min(abs(r0-rc0),abs(r1-rc1))>5");
5309 //
5310 TCut cdrmax("cdrmax","abs(abs(rc0+r0)-abs(rc1+r1))<40")
5311 TCut cdrmin("cdrmin","abs(abs(rc0+r0)-abs(rc1+r1))<10")
5312 //
5313 Multi->Draw("dfi","iter==0"+csign+cmax+cda+ccratio); ~94% of curling tracks fulfill
5314 Multi->Draw("min(abs(r0-rc0),abs(r1-rc1))","iter==0&&abs(lab1)==abs(lab0)"+csign+cmax+cda+ccratio+cpipe+cdrmin+cdrmax); //80%
5315 //
5316 Curling2->Draw("dfi","iter==0&&abs(lab0)==abs(lab1)"+csign+cmax+cdtheta+cdfi+ccratio)
5317
5318 */
5319 //
5320 //
5321 //
5322 Int_t nentries = array->GetEntriesFast();
5323 AliHelix *helixes = new AliHelix[nentries];
5324 for (Int_t i=0;i<nentries;i++){
5325 AliTPCseed* track = (AliTPCseed*)array->At(i);
5326 if (!track) continue;
5327 track->SetCircular(0);
5328 new (&helixes[i]) AliHelix(*track);
5329 }
5330 //
5331 //
5332 TStopwatch timer;
5333 timer.Start();
ec26e231 5334 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
5335
6d493ea0 5336 //
5337 // Find tracks
5338 //
6d493ea0 5339 //
5340 for (Int_t i0=0;i0<nentries;i0++){
5341 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5342 if (!track0) continue;
5343 if (TMath::Abs(track0->GetC())<1/kMaxC) continue;
5344 Float_t xc0 = helixes[i0].GetHelix(6);
5345 Float_t yc0 = helixes[i0].GetHelix(7);
5346 Float_t r0 = helixes[i0].GetHelix(8);
5347 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
5348 Float_t fi0 = TMath::ATan2(yc0,xc0);
5349
5350 for (Int_t i1=i0+1;i1<nentries;i1++){
5351 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5352 if (!track1) continue;
5353 if (TMath::Abs(track1->GetC())<1/kMaxC) continue;
5354 Float_t xc1 = helixes[i1].GetHelix(6);
5355 Float_t yc1 = helixes[i1].GetHelix(7);
5356 Float_t r1 = helixes[i1].GetHelix(8);
5357 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
5358 Float_t fi1 = TMath::ATan2(yc1,xc1);
5359 //
5360 Float_t dfi = fi0-fi1;
5361 //
5362 //
5363 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
5364 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
5365 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
5366 //
5367 //
5368 // FIRST fast cuts
5369 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue; // not constrained
5370 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue; // not the same sign
5371 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>kMaxdTheta) continue; //distance in the Theta
5372 if ( TMath::Abs(dfi)>kMaxdPhi) continue; //distance in phi
5373 if ( TMath::Sqrt(dfi*dfi+dtheta*dtheta)>kMaxdPhi) continue; //common angular offset
5374 //
5375 Float_t pt0 = track0->GetSignedPt();
5376 Float_t pt1 = track1->GetSignedPt();
5377 if ((TMath::Abs(pt0+pt1)/(TMath::Abs(pt0)+TMath::Abs(pt1)))>kPtRatio) continue;
5378 if ((iter==1) && TMath::Abs(TMath::Abs(rc0+r0)-TMath::Abs(rc1+r1))>kMaxDeltaRMax) continue;
5379 if ((iter!=1) &&TMath::Abs(TMath::Abs(rc0-r0)-TMath::Abs(rc1-r1))>kMaxDeltaRMin) continue;
5380 if (TMath::Min(TMath::Abs(rc0-r0),TMath::Abs(rc1-r1))<kMinDCAR) continue;
5381 //
5382 //
5383 // Now find closest approach
5384 //
5385 //
5386 //
5387 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5388 if (npoints==0) continue;
5389 helixes[i0].GetClosestPhases(helixes[i1], phase);
5390 //
5391 Double_t xyz0[3];
5392 Double_t xyz1[3];
5393 Double_t hangles[3];
5394 helixes[i0].Evaluate(phase[0][0],xyz0);
5395 helixes[i1].Evaluate(phase[0][1],xyz1);
5396
5397 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5398 Double_t deltah[2],deltabest;
5399 if (TMath::Abs(hangles[2])<kMinAngle) continue;
5400
5401 if (npoints>0){
5402 Int_t ibest=0;
5403 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
5404 if (npoints==2){
5405 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
5406 if (deltah[1]<deltah[0]) ibest=1;
5407 }
5408 deltabest = TMath::Sqrt(deltah[ibest]);
5409 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5410 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5411 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5412 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5413 //
5414 if (deltabest>kMaxDist) continue;
5415 // if (mindcar+mindcaz<40 && (TMath::Abs(hangles[2])<kMinAngle ||deltabest>3)) continue;
5416 Bool_t sign =kFALSE;
5417 if (hangles[2]>kMinAngle) sign =kTRUE;
5418 //
5419 if (sign){
5420 // circular[i0] = kTRUE;
5421 // circular[i1] = kTRUE;
5422 if (track0->OneOverPt()<track1->OneOverPt()){
5423 track0->SetCircular(track0->GetCircular()+1);
5424 track1->SetCircular(track1->GetCircular()+2);
5425 }
5426 else{
5427 track1->SetCircular(track1->GetCircular()+1);
5428 track0->SetCircular(track0->GetCircular()+2);
5429 }
5430 }
16299eac 5431 if (AliTPCReconstructor::StreamLevel()>2){
6d493ea0 5432 //
5433 //debug stream to tune "fine" cuts
5434 Int_t lab0=track0->GetLabel();
5435 Int_t lab1=track1->GetLabel();
b194b32c 5436 TTreeSRedirector &cstream = *fDebugStreamer;
6d493ea0 5437 cstream<<"Curling2"<<
5438 "iter="<<iter<<
5439 "lab0="<<lab0<<
5440 "lab1="<<lab1<<
5441 "Tr0.="<<track0<<
5442 "Tr1.="<<track1<<
5443 //
5444 "r0="<<r0<<
5445 "rc0="<<rc0<<
5446 "fi0="<<fi0<<
5447 "r1="<<r1<<
5448 "rc1="<<rc1<<
5449 "fi1="<<fi1<<
5450 "dfi="<<dfi<<
5451 "dtheta="<<dtheta<<
5452 //
5453 "npoints="<<npoints<<
5454 "hangles0="<<hangles[0]<<
5455 "hangles1="<<hangles[1]<<
5456 "hangles2="<<hangles[2]<<
5457 "xyz0="<<xyz0[2]<<
5458 "xyzz1="<<xyz1[2]<<
5459 "radius="<<radiusbest<<
5460 "deltabest="<<deltabest<<
5461 "phase0="<<phase[ibest][0]<<
5462 "phase1="<<phase[ibest][1]<<
5463 "\n";
5464
5465 }
5466 }
5467 }
5468 }
5469 delete [] helixes;
5470 if (AliTPCReconstructor::StreamLevel()>1) {
5471 AliInfo("Time for curling tracks removal");
5472 timer.Print();
5473 }
5474}
5475
5476
829455ad 5477void AliTPCtracker::FindKinks(TObjArray * array, AliESDEvent *esd)
51ad6848 5478{
5479 //
5480 // find kinks
5481 //
5482 //
f06a1ff6 5483 // RS something is wrong in this routine: not all seeds are assigned to daughters and mothers array, but they all are queried
5484 // to check later
ddfbc51a 5485
5486 TObjArray *kinks= new TObjArray(10000);
81e97e0d 5487 // TObjArray *v0s= new TObjArray(10000);
51ad6848 5488 Int_t nentries = array->GetEntriesFast();
ddfbc51a 5489 AliHelix *helixes = new AliHelix[nentries];
5490 Int_t *sign = new Int_t[nentries];
5491 Int_t *nclusters = new Int_t[nentries];
5492 Float_t *alpha = new Float_t[nentries];
5493 AliKink *kink = new AliKink();
5494 Int_t * usage = new Int_t[nentries];
5495 Float_t *zm = new Float_t[nentries];
5496 Float_t *z0 = new Float_t[nentries];
5497 Float_t *fim = new Float_t[nentries];
5498 Float_t *shared = new Float_t[nentries];
5499 Bool_t *circular = new Bool_t[nentries];
5500 Float_t *dca = new Float_t[nentries];
81e97e0d 5501 //const AliESDVertex * primvertex = esd->GetVertex();
eea478d3 5502 //
5503 // nentries = array->GetEntriesFast();
ddfbc51a 5504 //
5505
51ad6848 5506 //
5507 //
5508 for (Int_t i=0;i<nentries;i++){
5509 sign[i]=0;
5510 usage[i]=0;
5511 AliTPCseed* track = (AliTPCseed*)array->At(i);
5512 if (!track) continue;
b9671574 5513 track->SetCircular(0);
eea478d3 5514 shared[i] = kFALSE;
51ad6848 5515 track->UpdatePoints();
5516 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
51ad6848 5517 }
eea478d3 5518 nclusters[i]=track->GetNumberOfClusters();
5519 alpha[i] = track->GetAlpha();
5520 new (&helixes[i]) AliHelix(*track);
5521 Double_t xyz[3];
5522 helixes[i].Evaluate(0,xyz);
5523 sign[i] = (track->GetC()>0) ? -1:1;
5524 Double_t x,y,z;
5525 x=160;
5526 if (track->GetProlongation(x,y,z)){
5527 zm[i] = z;
5528 fim[i] = alpha[i]+TMath::ATan2(y,x);
5529 }
5530 else{
5531 zm[i] = track->GetZ();
5532 fim[i] = alpha[i];
5533 }
5534 z0[i]=1000;
5535 circular[i]= kFALSE;
81e97e0d 5536 if (track->GetProlongation(0,y,z)) z0[i] = z;
5537 dca[i] = track->GetD(0,0);
51ad6848 5538 }
5539 //
5540 //
5541 TStopwatch timer;
5542 timer.Start();
5543 Int_t ncandidates =0;
5544 Int_t nall =0;
5545 Int_t ntracks=0;
ec26e231 5546 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
eea478d3 5547
5548 //
5549 // Find circling track
eea478d3 5550 //
5551 for (Int_t i0=0;i0<nentries;i0++){
5552 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5553 if (!track0) continue;
b9671574 5554 if (track0->GetNumberOfClusters()<40) continue;
6c94f330 5555 if (TMath::Abs(1./track0->GetC())>200) continue;
eea478d3 5556 for (Int_t i1=i0+1;i1<nentries;i1++){
5557 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5558 if (!track1) continue;
b9671574 5559 if (track1->GetNumberOfClusters()<40) continue;
6c94f330 5560 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
b9671574 5561 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
6c94f330 5562 if (TMath::Abs(1./track1->GetC())>200) continue;
8467b758 5563 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
6c94f330 5564 if (track1->GetTgl()*track0->GetTgl()>0) continue;
1b36647b 5565 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
8467b758 5566 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
5567 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
eea478d3 5568 //
81e97e0d 5569 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
5570 if (mindcar<5) continue;
5571 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
5572 if (mindcaz<5) continue;
5573 if (mindcar+mindcaz<20) continue;
5574 //
5575 //
eea478d3 5576 Float_t xc0 = helixes[i0].GetHelix(6);
5577 Float_t yc0 = helixes[i0].GetHelix(7);
5578 Float_t r0 = helixes[i0].GetHelix(8);
5579 Float_t xc1 = helixes[i1].GetHelix(6);
5580 Float_t yc1 = helixes[i1].GetHelix(7);
5581 Float_t r1 = helixes[i1].GetHelix(8);
5582
5583 Float_t rmean = (r0+r1)*0.5;
5584 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
81e97e0d 5585 //if (delta>30) continue;
eea478d3 5586 if (delta>rmean*0.25) continue;
5587 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
5588 //
5589 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5590 if (npoints==0) continue;
5591 helixes[i0].GetClosestPhases(helixes[i1], phase);
5592 //
5593 Double_t xyz0[3];
5594 Double_t xyz1[3];
5595 Double_t hangles[3];
5596 helixes[i0].Evaluate(phase[0][0],xyz0);
5597 helixes[i1].Evaluate(phase[0][1],xyz1);
5598
5599 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5600 Double_t deltah[2],deltabest;
5601 if (hangles[2]<2.8) continue;
eea478d3 5602 if (npoints>0){
5603 Int_t ibest=0;
81e97e0d 5604 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
eea478d3 5605 if (npoints==2){
81e97e0d 5606 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
eea478d3 5607 if (deltah[1]<deltah[0]) ibest=1;
5608 }
5609 deltabest = TMath::Sqrt(deltah[ibest]);
5610 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5611 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5612 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
81e97e0d 5613 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
eea478d3 5614 //
81e97e0d 5615 if (deltabest>6) continue;
5616 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
77f88633 5617 Bool_t lsign =kFALSE;
5618 if (hangles[2]>3.06) lsign =kTRUE;
81e97e0d 5619 //
77f88633 5620 if (lsign){
eea478d3 5621 circular[i0] = kTRUE;
81e97e0d 5622 circular[i1] = kTRUE;
8467b758 5623 if (track0->OneOverPt()<track1->OneOverPt()){
b9671574 5624 track0->SetCircular(track0->GetCircular()+1);
5625 track1->SetCircular(track1->GetCircular()+2);
81e97e0d 5626 }
5627 else{
b9671574 5628 track1->SetCircular(track1->GetCircular()+1);
5629 track0->SetCircular(track0->GetCircular()+2);
81e97e0d 5630 }
5631 }
77f88633 5632 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
34acb742 5633 //debug stream
b9671574 5634 Int_t lab0=track0->GetLabel();
5635 Int_t lab1=track1->GetLabel();
b194b32c 5636 TTreeSRedirector &cstream = *fDebugStreamer;
81e97e0d 5637 cstream<<"Curling"<<
b9671574 5638 "lab0="<<lab0<<
5639 "lab1="<<lab1<<
81e97e0d 5640 "Tr0.="<<track0<<
5641 "Tr1.="<<track1<<
5642 "dca0="<<dca[i0]<<
5643 "dca1="<<dca[i1]<<
5644 "mindcar="<<mindcar<<
5645 "mindcaz="<<mindcaz<<
5646 "delta="<<delta<<
5647 "rmean="<<rmean<<
5648 "npoints="<<npoints<<
5649 "hangles0="<<hangles[0]<<
5650 "hangles2="<<hangles[2]<<
5651 "xyz0="<<xyz0[2]<<
5652 "xyzz1="<<xyz1[2]<<
5653 "z0="<<z0[i0]<<
5654 "z1="<<z0[i1]<<
5655 "radius="<<radiusbest<<
5656 "deltabest="<<deltabest<<
5657 "phase0="<<phase[ibest][0]<<
5658 "phase1="<<phase[ibest][1]<<
5659 "\n";
eea478d3 5660 }
5661 }
5662 }
5663 }
5664 //
ddfbc51a 5665 // Finf kinks loop
81e97e0d 5666 //
51ad6848 5667 //
5668 for (Int_t i =0;i<nentries;i++){
5669 if (sign[i]==0) continue;
5670 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
c1ea348f 5671 if (track0==0) {
5672 AliInfo("seed==0");
5673 continue;
5674 }
51ad6848 5675 ntracks++;
5676 //
5677 Double_t cradius0 = 40*40;
5678 Double_t cradius1 = 270*270;
5679 Double_t cdist1=8.;
5680 Double_t cdist2=8.;
5681 Double_t cdist3=0.55;
5682 for (Int_t j =i+1;j<nentries;j++){
5683 nall++;
5684 if (sign[j]*sign[i]<1) continue;
5685 if ( (nclusters[i]+nclusters[j])>200) continue;
5686 if ( (nclusters[i]+nclusters[j])<80) continue;
5687 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
5688 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
5689 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
5690 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5691 if (npoints<1) continue;
5692 // cuts on radius
5693 if (npoints==1){
5694 if (radius[0]<cradius0||radius[0]>cradius1) continue;
5695 }
5696 else{
5697 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
5698 }
5699 //
5700 Double_t delta1=10000,delta2=10000;
5701 // cuts on the intersection radius
5702 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5703 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5704 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5705 if (npoints==2){
5706 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5707 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5708 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5709 }
5710 //
5711 Double_t distance1 = TMath::Min(delta1,delta2);
5712 if (distance1>cdist1) continue; // cut on DCA linear approximation
5713 //
5714 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5715 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5716 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5717 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5718 //
5719 if (npoints==2){
5720 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5721 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5722 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5723 }
5724 distance1 = TMath::Min(delta1,delta2);
5725 Float_t rkink =0;
5726 if (delta1<delta2){
5727 rkink = TMath::Sqrt(radius[0]);
5728 }
5729 else{
5730 rkink = TMath::Sqrt(radius[1]);
5731 }
5732 if (distance1>cdist2) continue;
5733 //
5734 //
5735 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5736 //
5737 //
5738 Int_t row0 = GetRowNumber(rkink);
5739 if (row0<10) continue;
5740 if (row0>150) continue;
5741 //
5742 //
5743 Float_t dens00=-1,dens01=-1;
5744 Float_t dens10=-1,dens11=-1;
5745 //
77f88633 5746 Int_t found,foundable,ishared;
5747 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
51ad6848 5748 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
77f88633 5749 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
51ad6848 5750 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
5751 //
77f88633 5752 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
51ad6848 5753 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
77f88633 5754 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
51ad6848 5755 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
eea478d3 5756 //
51ad6848 5757 if (dens00<dens10 && dens01<dens11) continue;
5758 if (dens00>dens10 && dens01>dens11) continue;
5759 if (TMath::Max(dens00,dens10)<0.1) continue;
5760 if (TMath::Max(dens01,dens11)<0.3) continue;
5761 //
5762 if (TMath::Min(dens00,dens10)>0.6) continue;
5763 if (TMath::Min(dens01,dens11)>0.6) continue;
5764
5765 //
5766 AliTPCseed * ktrack0, *ktrack1;
5767 if (dens00>dens10){
5768 ktrack0 = track0;
5769 ktrack1 = track1;
5770 }
5771 else{
5772 ktrack0 = track1;
5773 ktrack1 = track0;
5774 }
5775 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
5776 AliExternalTrackParam paramm(*ktrack0);
5777 AliExternalTrackParam paramd(*ktrack1);
316c6cd9 5778 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
51ad6848 5779 //
5780 //
5781 kink->SetMother(paramm);
5782 kink->SetDaughter(paramd);
5783 kink->Update();
5784
2942f542 5785 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 5786 Int_t index[4];
47af7ca4 5787 fkParam->Transform0to1(x,index);
5788 fkParam->Transform1to2(x,index);
51ad6848 5789 row0 = GetRowNumber(x[0]);
5790
eea478d3 5791 if (kink->GetR()<100) continue;
5792 if (kink->GetR()>240) continue;
5793 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
5794 if (kink->GetDistance()>cdist3) continue;
5795 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
51ad6848 5796 if (dird<0) continue;
5797
eea478d3 5798 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
51ad6848 5799 if (dirm<0) continue;
eea478d3 5800 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
51ad6848 5801 if (mpt<0.2) continue;
5802
eea478d3 5803 if (mpt<1){
5804 //for high momenta momentum not defined well in first iteration
6c94f330 5805 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
eea478d3 5806 if (qt>0.35) continue;
5807 }
51ad6848 5808
eea478d3 5809 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
5810 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
51ad6848 5811 if (dens00>dens10){
eea478d3 5812 kink->SetTPCDensity(dens00,0,0);
5813 kink->SetTPCDensity(dens01,0,1);
5814 kink->SetTPCDensity(dens10,1,0);
5815 kink->SetTPCDensity(dens11,1,1);
5816 kink->SetIndex(i,0);
5817 kink->SetIndex(j,1);
51ad6848 5818 }
5819 else{
eea478d3 5820 kink->SetTPCDensity(dens10,0,0);
5821 kink->SetTPCDensity(dens11,0,1);
5822 kink->SetTPCDensity(dens00,1,0);
5823 kink->SetTPCDensity(dens01,1,1);
5824 kink->SetIndex(j,0);
5825 kink->SetIndex(i,1);
51ad6848 5826 }
51ad6848 5827
eea478d3 5828 if (mpt<1||kink->GetAngle(2)>0.1){
5829 // angle and densities not defined yet
5830 if (kink->GetTPCDensityFactor()<0.8) continue;
5831 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
6c94f330 5832 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
eea478d3 5833 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5834 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5835
6c94f330 5836 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5837 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
eea478d3 5838 criticalangle= 3*TMath::Sqrt(criticalangle);
5839 if (criticalangle>0.02) criticalangle=0.02;
5840 if (kink->GetAngle(2)<criticalangle) continue;
5841 }
51ad6848 5842 //
eea478d3 5843 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
51ad6848 5844 Float_t shapesum =0;
5845 Float_t sum = 0;
5846 for ( Int_t row = row0-drow; row<row0+drow;row++){
5847 if (row<0) continue;
5848 if (row>155) continue;
b9671574 5849 if (ktrack0->GetClusterPointer(row)){
51ad6848 5850 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5851 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5852 sum++;
5853 }
b9671574 5854 if (ktrack1->GetClusterPointer(row)){
51ad6848 5855 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5856 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5857 sum++;
5858 }
5859 }
5860 if (sum<4){
eea478d3 5861 kink->SetShapeFactor(-1.);
51ad6848 5862 }
5863 else{
eea478d3 5864 kink->SetShapeFactor(shapesum/sum);
5865 }
51ad6848 5866 // esd->AddKink(kink);
16299eac 5867 //
5868 // kink->SetMother(paramm);
5869 //kink->SetDaughter(paramd);
5870
5871 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
5872 chi2P2*=chi2P2;
5873 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
5874 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
5875 chi2P3*=chi2P3;
5876 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
5877 //
5878 if (AliTPCReconstructor::StreamLevel()>1) {
5879 (*fDebugStreamer)<<"kinkLpt"<<
5880 "chi2P2="<<chi2P2<<
5881 "chi2P3="<<chi2P3<<
5882 "p0.="<<&paramm<<
5883 "p1.="<<&paramd<<
5884 "k.="<<kink<<
5885 "\n";
5886 }
5887 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
5888 continue;
5889 }
5890 //
ddfbc51a 5891 kinks->AddLast(kink);
5892 kink = new AliKink;
51ad6848 5893 ncandidates++;
5894 }
5895 }
ddfbc51a 5896 //
eea478d3 5897 // sort the kinks according quality - and refit them towards vertex
5898 //
ddfbc51a 5899 Int_t nkinks = kinks->GetEntriesFast();
5900 Float_t *quality = new Float_t[nkinks];
5901 Int_t *indexes = new Int_t[nkinks];
5902 AliTPCseed *mothers = new AliTPCseed[nkinks];
5903 AliTPCseed *daughters = new AliTPCseed[nkinks];
eea478d3 5904 //
5905 //
51ad6848 5906 for (Int_t i=0;i<nkinks;i++){
5907 quality[i] =100000;
ddfbc51a 5908 AliKink *kinkl = (AliKink*)kinks->At(i);
eea478d3 5909 //
5910 // refit kinks towards vertex
5911 //
77f88633 5912 Int_t index0 = kinkl->GetIndex(0);
5913 Int_t index1 = kinkl->GetIndex(1);
eea478d3 5914 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5915 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5916 //
b9671574 5917 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
eea478d3 5918 //
5919 // Refit Kink under if too small angle
5920 //
77f88633 5921 if (kinkl->GetAngle(2)<0.05){
5922 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5923 Int_t row0 = kinkl->GetTPCRow0();
5924 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
eea478d3 5925 //
5926 //
5927 Int_t last = row0-drow;
5928 if (last<40) last=40;
b9671574 5929 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
eea478d3 5930 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
5931 //
5932 //
5933 Int_t first = row0+drow;
5934 if (first>130) first=130;
b9671574 5935 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
eea478d3 5936 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
5937 //
ddfbc51a 5938 if (seed0 && seed1){
77f88633 5939 kinkl->SetStatus(1,8);
5940 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
5941 row0 = GetRowNumber(kinkl->GetR());
b9671574 5942 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
ddfbc51a 5943 mothers[i] = *seed0;
5944 daughters[i] = *seed1;
eea478d3 5945 }
ddfbc51a 5946 else{
5947 delete kinks->RemoveAt(i);
5948 if (seed0) MarkSeedFree( seed0 );
5949 if (seed1) MarkSeedFree( seed1 );
eea478d3 5950 continue;
5951 }
77f88633 5952 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
ddfbc51a 5953 delete kinks->RemoveAt(i);
5954 if (seed0) MarkSeedFree( seed0 );
5955 if (seed1) MarkSeedFree( seed1 );
eea478d3 5956 continue;
5957 }
ddfbc51a 5958 //
5959 MarkSeedFree( seed0 );
5960 MarkSeedFree( seed1 );
eea478d3 5961 }
5962 //
77f88633 5963 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
51ad6848 5964 }
5965 TMath::Sort(nkinks,quality,indexes,kFALSE);
eea478d3 5966 //
5967 //remove double find kinks
5968 //
5969 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
ddfbc51a 5970 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
eea478d3 5971 if (!kink0) continue;
5972 //
6a6ba9a2 5973 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
ddfbc51a 5974 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
5975 if (!kink0) continue;
5976 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
eea478d3 5977 if (!kink1) continue;
5978 // if not close kink continue
5979 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
5980 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
5981 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
5982 //
ddfbc51a 5983 AliTPCseed &mother0 = mothers[indexes[ikink0]];
5984 AliTPCseed &daughter0 = daughters[indexes[ikink0]];
5985 AliTPCseed &mother1 = mothers[indexes[ikink1]];
5986 AliTPCseed &daughter1 = daughters[indexes[ikink1]];
eea478d3 5987 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
5988 //
5989 Int_t same = 0;
5990 Int_t both = 0;
5991 Int_t samem = 0;
5992 Int_t bothm = 0;
5993 Int_t samed = 0;
5994 Int_t bothd = 0;
5995 //
5996 for (Int_t i=0;i<row0;i++){
ddfbc51a 5997 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
eea478d3 5998 both++;
5999 bothm++;
ddfbc51a 6000 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
eea478d3 6001 same++;
6002 samem++;
6003 }
6004 }
6005 }
6006
6007 for (Int_t i=row0;i<158;i++){
f06a1ff6 6008 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
ddfbc51a 6009 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
eea478d3 6010 both++;
6011 bothd++;
ddfbc51a 6012 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
eea478d3 6013 same++;
6014 samed++;
6015 }
6016 }
6017 }
6018 Float_t ratio = Float_t(same+1)/Float_t(both+1);
6019 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
6020 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
6021 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
ddfbc51a 6022 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
6023 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
eea478d3 6024 if (sum1>sum0){
6025 shared[kink0->GetIndex(0)]= kTRUE;
6026 shared[kink0->GetIndex(1)]= kTRUE;
ddfbc51a 6027 delete kinks->RemoveAt(indexes[ikink0]);
b3659bad 6028 break;
eea478d3 6029 }
6030 else{
6031 shared[kink1->GetIndex(0)]= kTRUE;
6032 shared[kink1->GetIndex(1)]= kTRUE;
ddfbc51a 6033 delete kinks->RemoveAt(indexes[ikink1]);
eea478d3 6034 }
6035 }
6036 }
6037 }
6038
6039
51ad6848 6040 for (Int_t i=0;i<nkinks;i++){
ddfbc51a 6041 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
77f88633 6042 if (!kinkl) continue;
6043 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6044 Int_t index0 = kinkl->GetIndex(0);
6045 Int_t index1 = kinkl->GetIndex(1);
6046 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
6047 kinkl->SetMultiple(usage[index0],0);
6048 kinkl->SetMultiple(usage[index1],1);
6049 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
6050 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
6051 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
6052 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
51ad6848 6053
51ad6848 6054 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6055 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
eea478d3 6056 if (!ktrack0 || !ktrack1) continue;
77f88633 6057 Int_t index = esd->AddKink(kinkl);
eea478d3 6058 //
6059 //
b9671574 6060 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
ddfbc51a 6061 if (mothers[indexes[i]].GetNumberOfClusters()>20 && daughters[indexes[i]].GetNumberOfClusters()>20 && (mothers[indexes[i]].GetNumberOfClusters()+daughters[indexes[i]].GetNumberOfClusters())>100){
6062 *ktrack0 = mothers[indexes[i]];
6063 *ktrack1 = daughters[indexes[i]];
eea478d3 6064 }
6065 }
6066 //
b9671574 6067 ktrack0->SetKinkIndex(usage[index0],-(index+1));
6068 ktrack1->SetKinkIndex(usage[index1], (index+1));
51ad6848 6069 usage[index0]++;
6070 usage[index1]++;
6071 }
eea478d3 6072 //
6073 // Remove tracks corresponding to shared kink's
6074 //
6075 for (Int_t i=0;i<nentries;i++){
6076 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6077 if (!track0) continue;
b9671574 6078 if (track0->GetKinkIndex(0)!=0) continue;
ddfbc51a 6079 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
eea478d3 6080 }
ddfbc51a 6081
eea478d3 6082 //
6083 //
6084 RemoveUsed2(array,0.5,0.4,30);
6085 UnsignClusters();
81e97e0d 6086 for (Int_t i=0;i<nentries;i++){
6087 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6088 if (!track0) continue;
6089 track0->CookdEdx(0.02,0.6);
6090 track0->CookPID();
6091 }
eea478d3 6092 //
6093 for (Int_t i=0;i<nentries;i++){
6094 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6095 if (!track0) continue;
8467b758 6096 if (track0->Pt()<1.4) continue;
eea478d3 6097 //remove double high momenta tracks - overlapped with kink candidates
77f88633 6098 Int_t ishared=0;
eea478d3 6099 Int_t all =0;
b9671574 6100 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
6101 if (track0->GetClusterPointer(icl)!=0){
eea478d3 6102 all++;
77f88633 6103 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
eea478d3 6104 }
6105 }
77f88633 6106 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
ddfbc51a 6107 MarkSeedFree( array->RemoveAt(i) );
f99dc368 6108 continue;
eea478d3 6109 }
6110 //
b9671574 6111 if (track0->GetKinkIndex(0)!=0) continue;
eea478d3 6112 if (track0->GetNumberOfClusters()<80) continue;
4a12af72 6113
ddfbc51a 6114 AliTPCseed *pmother = new AliTPCseed();
6115 AliTPCseed *pdaughter = new AliTPCseed();
6116 AliKink *pkink = new AliKink;
6117
4a12af72 6118 AliTPCseed & mother = *pmother;
6119 AliTPCseed & daughter = *pdaughter;
77f88633 6120 AliKink & kinkl = *pkink;
6121 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
b9671574 6122 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
ddfbc51a 6123 delete pmother;
6124 delete pdaughter;
6125 delete pkink;
4a12af72 6126 continue; //too short tracks
6127 }
8467b758 6128 if (mother.Pt()<1.4) {
ddfbc51a 6129 delete pmother;
6130 delete pdaughter;
6131 delete pkink;
4a12af72 6132 continue;
6133 }
77f88633 6134 Int_t row0= kinkl.GetTPCRow0();
6135 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
ddfbc51a 6136 delete pmother;
6137 delete pdaughter;
6138 delete pkink;
eea478d3 6139 continue;
6140 }
6141 //
77f88633 6142 Int_t index = esd->AddKink(&kinkl);
b9671574 6143 mother.SetKinkIndex(0,-(index+1));
6144 daughter.SetKinkIndex(0,index+1);
6145 if (mother.GetNumberOfClusters()>50) {
ddfbc51a 6146 MarkSeedFree( array->RemoveAt(i) );
6147 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6148 mtc->SetPoolID(fLastSeedID);
f06a1ff6 6149 array->AddAt(mtc,i);
eea478d3 6150 }
6151 else{
ddfbc51a 6152 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6153 mtc->SetPoolID(fLastSeedID);
f06a1ff6 6154 array->AddLast(mtc);
eea478d3 6155 }
ddfbc51a 6156 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
6157 dtc->SetPoolID(fLastSeedID);
f06a1ff6 6158 array->AddLast(dtc);
eea478d3 6159 for (Int_t icl=0;icl<row0;icl++) {
b9671574 6160 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
eea478d3 6161 }
6162 //
6163 for (Int_t icl=row0;icl<158;icl++) {
b9671574 6164 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
eea478d3 6165 }
6166 //
6167 }
ddfbc51a 6168 delete pmother;
6169 delete pdaughter;
6170 delete pkink;
eea478d3 6171 }
ddfbc51a 6172
6173 delete [] daughters;
6174 delete [] mothers;
eea478d3 6175 //
eea478d3 6176 //
ddfbc51a 6177 delete [] dca;
6178 delete []circular;
6179 delete []shared;
6180 delete []quality;
6181 delete []indexes;
6182 //
6183 delete kink;
6184 delete[]fim;
6185 delete[] zm;
6186 delete[] z0;
6187 delete [] usage;
6188 delete[] alpha;
6189 delete[] nclusters;
6190 delete[] sign;
bfa00fba 6191 delete[] helixes;
ddfbc51a 6192 kinks->Delete();
6193 delete kinks;
6194
7b9ce4fd 6195 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
51ad6848 6196 timer.Print();
6197}
6198
81e97e0d 6199
ddfbc51a 6200/*
829455ad 6201void AliTPCtracker::FindKinks(TObjArray * array, AliESDEvent *esd)
eea478d3 6202{
6203 //
ddfbc51a 6204 // find kinks
eea478d3 6205 //
6206 //
6c94f330 6207
ddfbc51a 6208 TObjArray *kinks= new TObjArray(10000);
6209 // TObjArray *v0s= new TObjArray(10000);
6210 Int_t nentries = array->GetEntriesFast();
6211 AliHelix *helixes = new AliHelix[nentries];
6212 Int_t *sign = new Int_t[nentries];
6213 Int_t *nclusters = new Int_t[nentries];
6214 Float_t *alpha = new Float_t[nentries];
6215 AliKink *kink = new AliKink();
6216 Int_t * usage = new Int_t[nentries];
6217 Float_t *zm = new Float_t[nentries];
6218 Float_t *z0 = new Float_t[nentries];
6219 Float_t *fim = new Float_t[nentries];
6220 Float_t *shared = new Float_t[nentries];
6221 Bool_t *circular = new Bool_t[nentries];
6222 Float_t *dca = new Float_t[nentries];
6223 //const AliESDVertex * primvertex = esd->GetVertex();
eea478d3 6224 //
ddfbc51a 6225 // nentries = array->GetEntriesFast();
eea478d3 6226 //
ddfbc51a 6227
e546b023 6228 //
e546b023 6229 //
ddfbc51a 6230 for (Int_t i=0;i<nentries;i++){
6231 sign[i]=0;
6232 usage[i]=0;
6233 AliTPCseed* track = (AliTPCseed*)array->At(i);
6234 if (!track) continue;
6235 track->SetCircular(0);
6236 shared[i] = kFALSE;
6237 track->UpdatePoints();
6238 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
6239 }
6240 nclusters[i]=track->GetNumberOfClusters();
6241 alpha[i] = track->GetAlpha();
6242 new (&helixes[i]) AliHelix(*track);
6243 Double_t xyz[3];
6244 helixes[i].Evaluate(0,xyz);
6245 sign[i] = (track->GetC()>0) ? -1:1;
6246 Double_t x,y,z;
6247 x=160;
6248 if (track->GetProlongation(x,y,z)){
6249 zm[i] = z;
6250 fim[i] = alpha[i]+TMath::ATan2(y,x);
eea478d3 6251 }
ddfbc51a 6252 else{
6253 zm[i] = track->GetZ();
6254 fim[i] = alpha[i];
6255 }
6256 z0[i]=1000;
6257 circular[i]= kFALSE;
6258 if (track->GetProlongation(0,y,z)) z0[i] = z;
6259 dca[i] = track->GetD(0,0);
eea478d3 6260 }
6261 //
eea478d3 6262 //
ddfbc51a 6263 TStopwatch timer;
6264 timer.Start();
6265 Int_t ncandidates =0;
6266 Int_t nall =0;
6267 Int_t ntracks=0;
6268 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
6269
eea478d3 6270 //
ddfbc51a 6271 // Find circling track
e546b023 6272 //
ddfbc51a 6273 for (Int_t i0=0;i0<nentries;i0++){
6274 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
6275 if (!track0) continue;
6276 if (track0->GetNumberOfClusters()<40) continue;
6277 if (TMath::Abs(1./track0->GetC())>200) continue;
6278 for (Int_t i1=i0+1;i1<nentries;i1++){
6279 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
6280 if (!track1) continue;
6281 if (track1->GetNumberOfClusters()<40) continue;
6282 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
6283 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
6284 if (TMath::Abs(1./track1->GetC())>200) continue;
6285 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
6286 if (track1->GetTgl()*track0->GetTgl()>0) continue;
6287 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
6288 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
6289 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
6290 //
6291 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
6292 if (mindcar<5) continue;
6293 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
6294 if (mindcaz<5) continue;
6295 if (mindcar+mindcaz<20) continue;
6296 //
6297 //
6298 Float_t xc0 = helixes[i0].GetHelix(6);
6299 Float_t yc0 = helixes[i0].GetHelix(7);
6300 Float_t r0 = helixes[i0].GetHelix(8);
6301 Float_t xc1 = helixes[i1].GetHelix(6);
6302 Float_t yc1 = helixes[i1].GetHelix(7);
6303 Float_t r1 = helixes[i1].GetHelix(8);
6304
6305 Float_t rmean = (r0+r1)*0.5;
6306 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
6307 //if (delta>30) continue;
6308 if (delta>rmean*0.25) continue;
6309 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
6310 //
6311 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
6312 if (npoints==0) continue;
6313 helixes[i0].GetClosestPhases(helixes[i1], phase);
6314 //
6315 Double_t xyz0[3];
6316 Double_t xyz1[3];
6317 Double_t hangles[3];
6318 helixes[i0].Evaluate(phase[0][0],xyz0);
6319 helixes[i1].Evaluate(phase[0][1],xyz1);
e546b023 6320
ddfbc51a 6321 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
6322 Double_t deltah[2],deltabest;
6323 if (hangles[2]<2.8) continue;
6324 if (npoints>0){
6325 Int_t ibest=0;
6326 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
6327 if (npoints==2){
6328 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
6329 if (deltah[1]<deltah[0]) ibest=1;
6330 }
6331 deltabest = TMath::Sqrt(deltah[ibest]);
6332 helixes[i0].Evaluate(phase[ibest][0],xyz0);
6333 helixes[i1].Evaluate(phase[ibest][1],xyz1);
6334 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
6335 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
6336 //
6337 if (deltabest>6) continue;
6338 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
6339 Bool_t lsign =kFALSE;
6340 if (hangles[2]>3.06) lsign =kTRUE;
6341 //
6342 if (lsign){
6343 circular[i0] = kTRUE;
6344 circular[i1] = kTRUE;
6345 if (track0->OneOverPt()<track1->OneOverPt()){
6346 track0->SetCircular(track0->GetCircular()+1);
6347 track1->SetCircular(track1->GetCircular()+2);
6348 }
6349 else{
6350 track1->SetCircular(track1->GetCircular()+1);
6351 track0->SetCircular(track0->GetCircular()+2);
6352 }
6353 }
6354 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
6355 //debug stream
6356 Int_t lab0=track0->GetLabel();
6357 Int_t lab1=track1->GetLabel();
6358 TTreeSRedirector &cstream = *fDebugStreamer;
6359 cstream<<"Curling"<<
6360 "lab0="<<lab0<<
6361 "lab1="<<lab1<<
6362 "Tr0.="<<track0<<
6363 "Tr1.="<<track1<<
6364 "dca0="<<dca[i0]<<
6365 "dca1="<<dca[i1]<<
6366 "mindcar="<<mindcar<<
6367 "mindcaz="<<mindcaz<<
6368 "delta="<<delta<<
6369 "rmean="<<rmean<<
6370 "npoints="<<npoints<<
6371 "hangles0="<<hangles[0]<<
6372 "hangles2="<<hangles[2]<<
6373 "xyz0="<<xyz0[2]<<
6374 "xyzz1="<<xyz1[2]<<
6375 "z0="<<z0[i0]<<
6376 "z1="<<z0[i1]<<
6377 "radius="<<radiusbest<<
6378 "deltabest="<<deltabest<<
6379 "phase0="<<phase[ibest][0]<<
6380 "phase1="<<phase[ibest][1]<<
6381 "\n";
6382 }
6383 }
6384 }
6385 }
51ad6848 6386 //
ddfbc51a 6387 // Finf kinks loop
6388 //
f06a1ff6 6389 //
ddfbc51a 6390 for (Int_t i =0;i<nentries;i++){
6391 if (sign[i]==0) continue;
6392 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6393 if (track0==0) {
6394 AliInfo("seed==0");
6395 continue;
6396 }
6397 ntracks++;
6398 //
6399 Double_t cradius0 = 40*40;
6400 Double_t cradius1 = 270*270;
6401 Double_t cdist1=8.;
6402 Double_t cdist2=8.;
6403 Double_t cdist3=0.55;
6404 for (Int_t j =i+1;j<nentries;j++){
6405 nall++;
6406 if (sign[j]*sign[i]<1) continue;
6407 if ( (nclusters[i]+nclusters[j])>200) continue;
6408 if ( (nclusters[i]+nclusters[j])<80) continue;
6409 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
6410 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
6411 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
6412 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
6413 if (npoints<1) continue;
6414 // cuts on radius
6415 if (npoints==1){
6416 if (radius[0]<cradius0||radius[0]>cradius1) continue;
6417 }
6418 else{
6419 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
6420 }
6421 //
6422 Double_t delta1=10000,delta2=10000;
6423 // cuts on the intersection radius
6424 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
6425 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
6426 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
6427 if (npoints==2){
6428 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
6429 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
6430 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
6431 }
6432 //
6433 Double_t distance1 = TMath::Min(delta1,delta2);
6434 if (distance1>cdist1) continue; // cut on DCA linear approximation
6435 //
6436 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
6437 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
6438 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
6439 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
6440 //
6441 if (npoints==2){
6442 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
6443 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
6444 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
6445 }
6446 distance1 = TMath::Min(delta1,delta2);
6447 Float_t rkink =0;
6448 if (delta1<delta2){
6449 rkink = TMath::Sqrt(radius[0]);
6450 }
6451 else{
6452 rkink = TMath::Sqrt(radius[1]);
6453 }
6454 if (distance1>cdist2) continue;
6455 //
6456 //
6457 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
6458 //
6459 //
6460 Int_t row0 = GetRowNumber(rkink);
6461 if (row0<10) continue;
6462 if (row0>150) continue;
6463 //
6464 //
6465 Float_t dens00=-1,dens01=-1;
6466 Float_t dens10=-1,dens11=-1;
6467 //
6468 Int_t found,foundable,ishared;
6469 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
6470 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
6471 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
6472 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
6473 //
6474 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
6475 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
6476 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
6477 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
6478 //
6479 if (dens00<dens10 && dens01<dens11) continue;
6480 if (dens00>dens10 && dens01>dens11) continue;
6481 if (TMath::Max(dens00,dens10)<0.1) continue;
6482 if (TMath::Max(dens01,dens11)<0.3) continue;
6483 //
6484 if (TMath::Min(dens00,dens10)>0.6) continue;
6485 if (TMath::Min(dens01,dens11)>0.6) continue;
6486
6487 //
6488 AliTPCseed * ktrack0, *ktrack1;
6489 if (dens00>dens10){
6490 ktrack0 = track0;
6491 ktrack1 = track1;
6492 }
6493 else{
6494 ktrack0 = track1;
6495 ktrack1 = track0;
6496 }
6497 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
6498 AliExternalTrackParam paramm(*ktrack0);
6499 AliExternalTrackParam paramd(*ktrack1);
6500 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
6501 //
6502 //
6503 kink->SetMother(paramm);
6504 kink->SetDaughter(paramd);
6505 kink->Update();
6506
2942f542 6507 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 6508 Int_t index[4];
6509 fkParam->Transform0to1(x,index);
6510 fkParam->Transform1to2(x,index);
6511 row0 = GetRowNumber(x[0]);
6512
6513 if (kink->GetR()<100) continue;
6514 if (kink->GetR()>240) continue;
6515 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
6516 if (kink->GetDistance()>cdist3) continue;
6517 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
6518 if (dird<0) continue;
6519
6520 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
6521 if (dirm<0) continue;
6522 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
6523 if (mpt<0.2) continue;
6524
6525 if (mpt<1){
6526 //for high momenta momentum not defined well in first iteration
6527 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
6528 if (qt>0.35) continue;
6529 }
6530
6531 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
6532 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
6533 if (dens00>dens10){
6534 kink->SetTPCDensity(dens00,0,0);
6535 kink->SetTPCDensity(dens01,0,1);
6536 kink->SetTPCDensity(dens10,1,0);
6537 kink->SetTPCDensity(dens11,1,1);
6538 kink->SetIndex(i,0);
6539 kink->SetIndex(j,1);
6540 }
6541 else{
6542 kink->SetTPCDensity(dens10,0,0);
6543 kink->SetTPCDensity(dens11,0,1);
6544 kink->SetTPCDensity(dens00,1,0);
6545 kink->SetTPCDensity(dens01,1,1);
6546 kink->SetIndex(j,0);
6547 kink->SetIndex(i,1);
6548 }
6549
6550 if (mpt<1||kink->GetAngle(2)>0.1){
6551 // angle and densities not defined yet
6552 if (kink->GetTPCDensityFactor()<0.8) continue;
6553 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
6554 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
6555 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
6556 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
6557
6558 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
6559 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
6560 criticalangle= 3*TMath::Sqrt(criticalangle);
6561 if (criticalangle>0.02) criticalangle=0.02;
6562 if (kink->GetAngle(2)<criticalangle) continue;
6563 }
6564 //
6565 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
6566 Float_t shapesum =0;
6567 Float_t sum = 0;
6568 for ( Int_t row = row0-drow; row<row0+drow;row++){
6569 if (row<0) continue;
6570 if (row>155) continue;
6571 if (ktrack0->GetClusterPointer(row)){
6572 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
6573 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
6574 sum++;
6575 }
6576 if (ktrack1->GetClusterPointer(row)){
6577 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
6578 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
6579 sum++;
6580 }
6581 }
6582 if (sum<4){
6583 kink->SetShapeFactor(-1.);
6584 }
6585 else{
6586 kink->SetShapeFactor(shapesum/sum);
6587 }
6588 // esd->AddKink(kink);
6589 //
6590 // kink->SetMother(paramm);
6591 //kink->SetDaughter(paramd);
6592
6593 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
6594 chi2P2*=chi2P2;
6595 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
6596 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
6597 chi2P3*=chi2P3;
6598 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
6599 //
6600 if (AliTPCReconstructor::StreamLevel()>1) {
6601 (*fDebugStreamer)<<"kinkLpt"<<
6602 "chi2P2="<<chi2P2<<
6603 "chi2P3="<<chi2P3<<
6604 "p0.="<<&paramm<<
6605 "p1.="<<&paramd<<
6606 "k.="<<kink<<
6607 "\n";
6608 }
6609 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
6610 continue;
6611 }
6612 //
6613 kinks->AddLast(kink);
6614 kink = new AliKink;
6615 ncandidates++;
6616 }
6617 }
6618 //
6619 // sort the kinks according quality - and refit them towards vertex
6620 //
6621 Int_t nkinks = kinks->GetEntriesFast();
6622 Float_t *quality = new Float_t[nkinks];
6623 Int_t *indexes = new Int_t[nkinks];
6624 AliTPCseed **mothers = new AliTPCseed*[nkinks]; memset(mothers, 0, nkinks*sizeof(AliTPCseed*));
6625 AliTPCseed **daughters = new AliTPCseed*[nkinks]; memset(daughters, 0, nkinks*sizeof(AliTPCseed*));
6626 //
6627 //
6628 for (Int_t i=0;i<nkinks;i++){
6629 quality[i] =100000;
6630 AliKink *kinkl = (AliKink*)kinks->At(i);
6631 //
6632 // refit kinks towards vertex
6633 //
6634 Int_t index0 = kinkl->GetIndex(0);
6635 Int_t index1 = kinkl->GetIndex(1);
6636 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6637 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6638 //
6639 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
6640 //
6641 // Refit Kink under if too small angle
6642 //
6643 if (kinkl->GetAngle(2)<0.05){
6644 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6645 Int_t row0 = kinkl->GetTPCRow0();
6646 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
6647 //
6648 //
6649 Int_t last = row0-drow;
6650 if (last<40) last=40;
6651 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
6652 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
6653 //
6654 //
6655 Int_t first = row0+drow;
6656 if (first>130) first=130;
6657 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
6658 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
6659 //
6660 if (seed0 && seed1){
6661 kinkl->SetStatus(1,8);
6662 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
6663 row0 = GetRowNumber(kinkl->GetR());
6664 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
6665 mothers[i] = new ( NextFreeSeed() ) AliTPCseed(*seed0);
6666 mothers[i]->SetPoolID(fLastSeedID);
6667 daughters[i] = new (NextFreeSeed() ) AliTPCseed(*seed1);
6668 daughters[i]->SetPoolID(fLastSeedID);
6669 }
6670 else{
6671 delete kinks->RemoveAt(i);
6672 if (seed0) MarkSeedFree( seed0 );
6673 if (seed1) MarkSeedFree( seed1 );
6674 continue;
6675 }
6676 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
6677 delete kinks->RemoveAt(i);
6678 if (seed0) MarkSeedFree( seed0 );
6679 if (seed1) MarkSeedFree( seed1 );
6680 continue;
6681 }
6682 //
6683 MarkSeedFree( seed0 );
6684 MarkSeedFree( seed1 );
6685 }
6686 //
6687 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
6688 }
6689 TMath::Sort(nkinks,quality,indexes,kFALSE);
6690 //
6691 //remove double find kinks
6692 //
6693 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
6694 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6695 if (!kink0) continue;
6696 //
6697 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
6698 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6699 if (!kink0) continue;
6700 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
6701 if (!kink1) continue;
6702 // if not close kink continue
6703 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
6704 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
6705 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
6706 //
6707 AliTPCseed &mother0 = *mothers[indexes[ikink0]];
6708 AliTPCseed &daughter0 = *daughters[indexes[ikink0]];
6709 AliTPCseed &mother1 = *mothers[indexes[ikink1]];
6710 AliTPCseed &daughter1 = *daughters[indexes[ikink1]];
6711 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
6712 //
6713 Int_t same = 0;
6714 Int_t both = 0;
6715 Int_t samem = 0;
6716 Int_t bothm = 0;
6717 Int_t samed = 0;
6718 Int_t bothd = 0;
6719 //
6720 for (Int_t i=0;i<row0;i++){
6721 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
6722 both++;
6723 bothm++;
6724 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6725 same++;
6726 samem++;
6727 }
6728 }
6729 }
6730
6731 for (Int_t i=row0;i<158;i++){
6732 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
6733 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
6734 both++;
6735 bothd++;
6736 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6737 same++;
6738 samed++;
6739 }
6740 }
6741 }
6742 Float_t ratio = Float_t(same+1)/Float_t(both+1);
6743 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
6744 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
6745 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
6746 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
6747 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
6748 if (sum1>sum0){
6749 shared[kink0->GetIndex(0)]= kTRUE;
6750 shared[kink0->GetIndex(1)]= kTRUE;
6751 delete kinks->RemoveAt(indexes[ikink0]);
6752 break;
6753 }
6754 else{
6755 shared[kink1->GetIndex(0)]= kTRUE;
6756 shared[kink1->GetIndex(1)]= kTRUE;
6757 delete kinks->RemoveAt(indexes[ikink1]);
6758 }
6759 }
6760 }
6761 }
6762
6763
6764 for (Int_t i=0;i<nkinks;i++){
6765 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
6766 if (!kinkl) continue;
6767 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6768 Int_t index0 = kinkl->GetIndex(0);
6769 Int_t index1 = kinkl->GetIndex(1);
6770 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
6771 kinkl->SetMultiple(usage[index0],0);
6772 kinkl->SetMultiple(usage[index1],1);
6773 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
6774 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
6775 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
6776 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
6777
6778 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6779 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6780 if (!ktrack0 || !ktrack1) continue;
6781 Int_t index = esd->AddKink(kinkl);
6782 //
6783 //
6784 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
6785 if (mothers[indexes[i]]->GetNumberOfClusters()>20 && daughters[indexes[i]]->GetNumberOfClusters()>20 &&
6786 (mothers[indexes[i]]->GetNumberOfClusters()+daughters[indexes[i]]->GetNumberOfClusters())>100){
6787 *ktrack0 = *mothers[indexes[i]];
6788 *ktrack1 = *daughters[indexes[i]];
6789 }
6790 }
6791 //
6792 ktrack0->SetKinkIndex(usage[index0],-(index+1));
6793 ktrack1->SetKinkIndex(usage[index1], (index+1));
6794 usage[index0]++;
6795 usage[index1]++;
6796 }
6797 //
6798 // Remove tracks corresponding to shared kink's
6799 //
6800 for (Int_t i=0;i<nentries;i++){
6801 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6802 if (!track0) continue;
6803 if (track0->GetKinkIndex(0)!=0) continue;
6804 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
6805 }
6806
6807 //
6808 //
6809 RemoveUsed2(array,0.5,0.4,30);
6810 UnsignClusters();
6811 for (Int_t i=0;i<nentries;i++){
6812 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6813 if (!track0) continue;
6814 track0->CookdEdx(0.02,0.6);
6815 track0->CookPID();
6816 }
6817 //
6818 for (Int_t i=0;i<nentries;i++){
6819 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6820 if (!track0) continue;
6821 if (track0->Pt()<1.4) continue;
6822 //remove double high momenta tracks - overlapped with kink candidates
6823 Int_t ishared=0;
6824 Int_t all =0;
6825 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
6826 if (track0->GetClusterPointer(icl)!=0){
6827 all++;
6828 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
6829 }
6830 }
6831 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
6832 MarkSeedFree( array->RemoveAt(i) );
6833 continue;
6834 }
6835 //
6836 if (track0->GetKinkIndex(0)!=0) continue;
6837 if (track0->GetNumberOfClusters()<80) continue;
6838
6839 AliTPCseed *pmother = new( NextFreeSeed() ) AliTPCseed();
6840 pmother->SetPoolID(fLastSeedID);
6841 AliTPCseed *pdaughter = new( NextFreeSeed() ) AliTPCseed();
6842 pdaughter->SetPoolID(fLastSeedID);
6843 AliKink *pkink = new AliKink;
6844
6845 AliTPCseed & mother = *pmother;
6846 AliTPCseed & daughter = *pdaughter;
6847 AliKink & kinkl = *pkink;
6848 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
6849 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
6850 MarkSeedFree( pmother );
6851 MarkSeedFree( pdaughter );
6852 delete pkink;
6853 continue; //too short tracks
6854 }
6855 if (mother.Pt()<1.4) {
6856 MarkSeedFree( pmother );
6857 MarkSeedFree( pdaughter );
6858 delete pkink;
6859 continue;
6860 }
6861 Int_t row0= kinkl.GetTPCRow0();
6862 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
6863 MarkSeedFree( pmother );
6864 MarkSeedFree( pdaughter );
6865 delete pkink;
6866 continue;
6867 }
6868 //
6869 Int_t index = esd->AddKink(&kinkl);
6870 mother.SetKinkIndex(0,-(index+1));
6871 daughter.SetKinkIndex(0,index+1);
6872 if (mother.GetNumberOfClusters()>50) {
6873 MarkSeedFree( array->RemoveAt(i) );
6874 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6875 mtc->SetPoolID(fLastSeedID);
6876 array->AddAt(mtc,i);
6877 }
6878 else{
6879 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6880 mtc->SetPoolID(fLastSeedID);
6881 array->AddLast(mtc);
6882 }
6883 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
6884 dtc->SetPoolID(fLastSeedID);
6885 array->AddLast(dtc);
6886 for (Int_t icl=0;icl<row0;icl++) {
6887 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
6888 }
6889 //
6890 for (Int_t icl=row0;icl<158;icl++) {
6891 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
6892 }
6893 //
6894 }
6895 MarkSeedFree( pmother );
6896 MarkSeedFree( pdaughter );
6897 delete pkink;
6898 }
6899
6900 delete [] daughters;
6901 delete [] mothers;
6902 //
6903 //
6904 delete [] dca;
6905 delete []circular;
6906 delete []shared;
6907 delete []quality;
6908 delete []indexes;
6909 //
6910 delete kink;
6911 delete[]fim;
6912 delete[] zm;
6913 delete[] z0;
6914 delete [] usage;
6915 delete[] alpha;
6916 delete[] nclusters;
6917 delete[] sign;
6918 delete[] helixes;
6919 kinks->Delete();
6920 delete kinks;
6921
6922 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
6923 timer.Print();
6924}
6925*/
6926
829455ad 6927Int_t AliTPCtracker::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
ddfbc51a 6928{
6929 //
6930 // refit kink towards to the vertex
6931 //
6932 //
6933 AliKink &kink=(AliKink &)knk;
6934
6935 Int_t row0 = GetRowNumber(kink.GetR());
6936 FollowProlongation(mother,0);
6937 mother.Reset(kFALSE);
6938 //
6939 FollowProlongation(daughter,row0);
6940 daughter.Reset(kFALSE);
6941 FollowBackProlongation(daughter,158);
6942 daughter.Reset(kFALSE);
6943 Int_t first = TMath::Max(row0-20,30);
6944 Int_t last = TMath::Min(row0+20,140);
6945 //
6946 const Int_t kNdiv =5;
6947 AliTPCseed param0[kNdiv]; // parameters along the track
6948 AliTPCseed param1[kNdiv]; // parameters along the track
6949 AliKink kinks[kNdiv]; // corresponding kink parameters
6950 //
6951 Int_t rows[kNdiv];
6952 for (Int_t irow=0; irow<kNdiv;irow++){
6953 rows[irow] = first +((last-first)*irow)/(kNdiv-1);
6954 }
6955 // store parameters along the track
6956 //
6957 for (Int_t irow=0;irow<kNdiv;irow++){
6958 FollowBackProlongation(mother, rows[irow]);
6959 FollowProlongation(daughter,rows[kNdiv-1-irow]);
6960 param0[irow] = mother;
6961 param1[kNdiv-1-irow] = daughter;
6962 }
6963 //
6964 // define kinks
6965 for (Int_t irow=0; irow<kNdiv-1;irow++){
6966 if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
6967 kinks[irow].SetMother(param0[irow]);
6968 kinks[irow].SetDaughter(param1[irow]);
6969 kinks[irow].Update();
6970 }
6971 //
6972 // choose kink with best "quality"
6973 Int_t index =-1;
6974 Double_t mindist = 10000;
6975 for (Int_t irow=0;irow<kNdiv;irow++){
6976 if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
6977 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
6978 if (TMath::Abs(kinks[irow].GetR())<100.) continue;
6979 //
6980 Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
6981 normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
6982 if (normdist < mindist){
6983 mindist = normdist;
6984 index = irow;
6985 }
6986 }
6987 //
6988 if (index==-1) return 0;
6989 //
6990 //
6991 param0[index].Reset(kTRUE);
6992 FollowProlongation(param0[index],0);
6993 //
6994 mother = param0[index];
6995 daughter = param1[index]; // daughter in vertex
6996 //
6997 kink.SetMother(mother);
6998 kink.SetDaughter(daughter);
6999 kink.Update();
7000 kink.SetTPCRow0(GetRowNumber(kink.GetR()));
7001 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
7002 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
7003 kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
7004 kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
7005 mother.SetLabel(kink.GetLabel(0));
7006 daughter.SetLabel(kink.GetLabel(1));
7007
7008 return 1;
7009}
7010
7011
829455ad 7012void AliTPCtracker::UpdateKinkQualityM(AliTPCseed * seed){
ddfbc51a 7013 //
7014 // update Kink quality information for mother after back propagation
7015 //
7016 if (seed->GetKinkIndex(0)>=0) return;
7017 for (Int_t ikink=0;ikink<3;ikink++){
7018 Int_t index = seed->GetKinkIndex(ikink);
7019 if (index>=0) break;
51ad6848 7020 index = TMath::Abs(index)-1;
7021 AliESDkink * kink = fEvent->GetKink(index);
f941f7fa 7022 kink->SetTPCDensity(-1,0,0);
7023 kink->SetTPCDensity(1,0,1);
51ad6848 7024 //
eea478d3 7025 Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 7026 if (row0<15) row0=15;
7027 //
eea478d3 7028 Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 7029 if (row1>145) row1=145;
7030 //
7031 Int_t found,foundable,shared;
7032 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
f941f7fa 7033 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,0);
51ad6848 7034 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
f941f7fa 7035 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,1);
51ad6848 7036 }
7037
7038}
7039
829455ad 7040void AliTPCtracker::UpdateKinkQualityD(AliTPCseed * seed){
91162307 7041 //
eea478d3 7042 // update Kink quality information for daughter after refit
91162307 7043 //
eea478d3 7044 if (seed->GetKinkIndex(0)<=0) return;
7045 for (Int_t ikink=0;ikink<3;ikink++){
7046 Int_t index = seed->GetKinkIndex(ikink);
7047 if (index<=0) break;
7048 index = TMath::Abs(index)-1;
7049 AliESDkink * kink = fEvent->GetKink(index);
f941f7fa 7050 kink->SetTPCDensity(-1,1,0);
7051 kink->SetTPCDensity(-1,1,1);
91162307 7052 //
eea478d3 7053 Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
7054 if (row0<15) row0=15;
7055 //
7056 Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
7057 if (row1>145) row1=145;
7058 //
7059 Int_t found,foundable,shared;
7060 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
f941f7fa 7061 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,0);
eea478d3 7062 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
f941f7fa 7063 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,1);
91162307 7064 }
eea478d3 7065
7066}
7067
7068
829455ad 7069Int_t AliTPCtracker::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
eea478d3 7070{
91162307 7071 //
eea478d3 7072 // check kink point for given track
7073 // if return value=0 kink point not found
7074 // otherwise seed0 correspond to mother particle
7075 // seed1 correspond to daughter particle
7076 // kink parameter of kink point
6c94f330 7077 AliKink &kink=(AliKink &)knk;
91162307 7078
b9671574 7079 Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
7080 Int_t first = seed->GetFirstPoint();
7081 Int_t last = seed->GetLastPoint();
eea478d3 7082 if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
91162307 7083
eea478d3 7084
7085 AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
7086 if (!seed1) return 0;
b9671574 7087 FollowProlongation(*seed1,seed->GetLastPoint()-20);
eea478d3 7088 seed1->Reset(kTRUE);
7089 FollowProlongation(*seed1,158);
7090 seed1->Reset(kTRUE);
b9671574 7091 last = seed1->GetLastPoint();
eea478d3 7092 //
ddfbc51a 7093 AliTPCseed *seed0 = new( NextFreeSeed() ) AliTPCseed(*seed);
7094 seed0->SetPoolID(fLastSeedID);
eea478d3 7095 seed0->Reset(kFALSE);
7096 seed0->Reset();
7097 //
7098 AliTPCseed param0[20]; // parameters along the track
7099 AliTPCseed param1[20]; // parameters along the track
6c94f330 7100 AliKink kinks[20]; // corresponding kink parameters
eea478d3 7101 Int_t rows[20];
7102 for (Int_t irow=0; irow<20;irow++){
7103 rows[irow] = first +((last-first)*irow)/19;
7104 }
7105 // store parameters along the track
7106 //
7107 for (Int_t irow=0;irow<20;irow++){
7108 FollowBackProlongation(*seed0, rows[irow]);
7109 FollowProlongation(*seed1,rows[19-irow]);
316c6cd9 7110 param0[irow] = *seed0;
7111 param1[19-irow] = *seed1;
eea478d3 7112 }
7113 //
7114 // define kinks
7115 for (Int_t irow=0; irow<19;irow++){
7116 kinks[irow].SetMother(param0[irow]);
7117 kinks[irow].SetDaughter(param1[irow]);
7118 kinks[irow].Update();
7119 }
7120 //
7121 // choose kink with biggest change of angle
7122 Int_t index =-1;
7123 Double_t maxchange= 0;
7124 for (Int_t irow=1;irow<19;irow++){
7125 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
7126 if (TMath::Abs(kinks[irow].GetR())<110.) continue;
6c94f330 7127 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 7128 if ( quality > maxchange){
7129 maxchange = quality;
7130 index = irow;
7131 //
91162307 7132 }
7133 }
ddfbc51a 7134 MarkSeedFree( seed0 );
7135 MarkSeedFree( seed1 );
eea478d3 7136 if (index<0) return 0;
7137 //
7138 Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
ddfbc51a 7139 seed0 = new( NextFreeSeed() ) AliTPCseed(param0[index]);
7140 seed0->SetPoolID(fLastSeedID);
7141 seed1 = new( NextFreeSeed() ) AliTPCseed(param1[index]);
7142 seed1->SetPoolID(fLastSeedID);
eea478d3 7143 seed0->Reset(kFALSE);
7144 seed1->Reset(kFALSE);
6c94f330 7145 seed0->ResetCovariance(10.);
7146 seed1->ResetCovariance(10.);
eea478d3 7147 FollowProlongation(*seed0,0);
7148 FollowBackProlongation(*seed1,158);
316c6cd9 7149 mother = *seed0; // backup mother at position 0
eea478d3 7150 seed0->Reset(kFALSE);
7151 seed1->Reset(kFALSE);
6c94f330 7152 seed0->ResetCovariance(10.);
7153 seed1->ResetCovariance(10.);
eea478d3 7154 //
7155 first = TMath::Max(row0-20,0);
7156 last = TMath::Min(row0+20,158);
7157 //
7158 for (Int_t irow=0; irow<20;irow++){
7159 rows[irow] = first +((last-first)*irow)/19;
7160 }
7161 // store parameters along the track
7162 //
7163 for (Int_t irow=0;irow<20;irow++){
7164 FollowBackProlongation(*seed0, rows[irow]);
7165 FollowProlongation(*seed1,rows[19-irow]);
316c6cd9 7166 param0[irow] = *seed0;
7167 param1[19-irow] = *seed1;
eea478d3 7168 }
7169 //
7170 // define kinks
7171 for (Int_t irow=0; irow<19;irow++){
7172 kinks[irow].SetMother(param0[irow]);
7173 kinks[irow].SetDaughter(param1[irow]);
7174 // param0[irow].Dump();
7175 //param1[irow].Dump();
7176 kinks[irow].Update();
7177 }
7178 //
7179 // choose kink with biggest change of angle
7180 index =-1;
7181 maxchange= 0;
7182 for (Int_t irow=0;irow<20;irow++){
7183 if (TMath::Abs(kinks[irow].GetR())>250.) continue;
7184 if (TMath::Abs(kinks[irow].GetR())<90.) continue;
6c94f330 7185 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 7186 if ( quality > maxchange){
7187 maxchange = quality;
7188 index = irow;
7189 //
91162307 7190 }
7191 }
7192 //
7193 //
b9671574 7194 if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
ddfbc51a 7195 MarkSeedFree( seed0 );
7196 MarkSeedFree( seed1 );
eea478d3 7197 return 0;
1627d1c4 7198 }
16299eac 7199
eea478d3 7200 // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
1627d1c4 7201
eea478d3 7202 kink.SetMother(param0[index]);
7203 kink.SetDaughter(param1[index]);
7204 kink.Update();
16299eac 7205
7206 Double_t chi2P2 = param0[index].GetParameter()[2]-param1[index].GetParameter()[2];
7207 chi2P2*=chi2P2;
7208 chi2P2/=param0[index].GetCovariance()[5]+param1[index].GetCovariance()[5];
7209 Double_t chi2P3 = param0[index].GetParameter()[3]-param1[index].GetParameter()[3];
7210 chi2P3*=chi2P3;
7211 chi2P3/=param0[index].GetCovariance()[9]+param1[index].GetCovariance()[9];
7212 //
7213 if (AliTPCReconstructor::StreamLevel()>1) {
7214 (*fDebugStreamer)<<"kinkHpt"<<
7215 "chi2P2="<<chi2P2<<
7216 "chi2P3="<<chi2P3<<
7217 "p0.="<<&param0[index]<<
7218 "p1.="<<&param1[index]<<
7219 "k.="<<&kink<<
7220 "\n";
7221 }
7222 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
ddfbc51a 7223 MarkSeedFree( seed0 );
7224 MarkSeedFree( seed1 );
16299eac 7225 return 0;
7226 }
7227
7228
eea478d3 7229 row0 = GetRowNumber(kink.GetR());
7230 kink.SetTPCRow0(row0);
7231 kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
7232 kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
7233 kink.SetIndex(-10,0);
b9671574 7234 kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
7235 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
7236 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
eea478d3 7237 //
7238 //
7239 // new (&mother) AliTPCseed(param0[index]);
316c6cd9 7240 daughter = param1[index];
eea478d3 7241 daughter.SetLabel(kink.GetLabel(1));
7242 param0[index].Reset(kTRUE);
16299eac 7243 FollowProlongation(param0[index],0);
316c6cd9 7244 mother = param0[index];
eea478d3 7245 mother.SetLabel(kink.GetLabel(0));
16299eac 7246 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(1)){
7247 mother=*seed;
7248 }
ddfbc51a 7249 MarkSeedFree( seed0 );
7250 MarkSeedFree( seed1 );
eea478d3 7251 //
7252 return 1;
1627d1c4 7253}
7254
7255
7256
7257
829455ad 7258AliTPCseed* AliTPCtracker::ReSeed(AliTPCseed *t)
91162307 7259{
7260 //
7261 // reseed - refit - track
7262 //
7263 Int_t first = 0;
7264 // Int_t last = fSectors->GetNRows()-1;
7265 //
7266 if (fSectors == fOuterSec){
b9671574 7267 first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
91162307 7268 //last =
7269 }
7270 else
b9671574 7271 first = t->GetFirstPoint();
91162307 7272 //
7273 AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
7274 FollowBackProlongation(*t,fSectors->GetNRows()-1);
7275 t->Reset(kFALSE);
7276 FollowProlongation(*t,first);
7277 return seed;
7278}
7279
7280
7281
7282
7283
7284
7285
1c53abe2 7286//_____________________________________________________________________________
829455ad 7287Int_t AliTPCtracker::ReadSeeds(const TFile *inp) {
1c53abe2 7288 //-----------------------------------------------------------------
7289 // This function reades track seeds.
7290 //-----------------------------------------------------------------
7291 TDirectory *savedir=gDirectory;
7292
7293 TFile *in=(TFile*)inp;
7294 if (!in->IsOpen()) {
829455ad 7295 cerr<<"AliTPCtracker::ReadSeeds(): input file is not open !\n";
1c53abe2 7296 return 1;
7297 }
7298
7299 in->cd();
7300 TTree *seedTree=(TTree*)in->Get("Seeds");
7301 if (!seedTree) {
829455ad 7302 cerr<<"AliTPCtracker::ReadSeeds(): ";
1c53abe2 7303 cerr<<"can't get a tree with track seeds !\n";
7304 return 2;
7305 }
7306 AliTPCtrack *seed=new AliTPCtrack;
7307 seedTree->SetBranchAddress("tracks",&seed);
7308
7309 if (fSeeds==0) fSeeds=new TObjArray(15000);
7310
7311 Int_t n=(Int_t)seedTree->GetEntries();
7312 for (Int_t i=0; i<n; i++) {
7313 seedTree->GetEvent(i);
ddfbc51a 7314 AliTPCseed* sdc = new( NextFreeSeed() ) AliTPCseed(*seed/*,seed->GetAlpha()*/);
7315 sdc->SetPoolID(fLastSeedID);
f06a1ff6 7316 fSeeds->AddLast(sdc);
1c53abe2 7317 }
7318
f06a1ff6 7319 delete seed; // RS: this seed is not from the pool, delete it !!!
1c53abe2 7320 delete seedTree;
7321 savedir->cd();
7322 return 0;
7323}
7324
829455ad 7325Int_t AliTPCtracker::Clusters2TracksHLT (AliESDEvent *const esd, const AliESDEvent *hltEvent)
d26d9159 7326{
7327 //
544c295f 7328 // clusters to tracks
d9b8978b 7329 if (fSeeds) DeleteSeeds();
ddfbc51a 7330 else ResetSeedsPool();
e1dadcd0 7331 fEvent = esd;
72e25240 7332 fEventHLT = hltEvent;
e1dadcd0 7333
7334 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
7335 transform->SetCurrentTimeStamp( esd->GetTimeStamp());
7336 transform->SetCurrentRun(esd->GetRunNumber());
7337
d26d9159 7338 Clusters2Tracks();
72e25240 7339 fEventHLT = 0;
d26d9159 7340 if (!fSeeds) return 1;
7341 FillESD(fSeeds);
f47588e0 7342 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(0,fSeeds);
d26d9159 7343 return 0;
7344 //
7345}
7346
829455ad 7347Int_t AliTPCtracker::Clusters2Tracks(AliESDEvent *const esd)
72e25240 7348{
7349 //
7350 // clusters to tracks
7351 return Clusters2TracksHLT( esd, 0);
7352}
d26d9159 7353
1c53abe2 7354//_____________________________________________________________________________
829455ad 7355Int_t AliTPCtracker::Clusters2Tracks() {
1c53abe2 7356 //-----------------------------------------------------------------
7357 // This is a track finder.
7358 //-----------------------------------------------------------------
91162307 7359 TDirectory *savedir=gDirectory;
1c53abe2 7360 TStopwatch timer;
d26d9159 7361
91162307 7362 fIteration = 0;
7363 fSeeds = Tracking();
1c53abe2 7364
6bdc18d6 7365 if (fDebug>0){
7366 Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
7367 }
91162307 7368 //activate again some tracks
7369 for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
7370 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7371 if (!pt) continue;
7372 Int_t nc=t.GetNumberOfClusters();
7373 if (nc<20) {
ddfbc51a 7374 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7375 continue;
eea478d3 7376 }
f5cbf2ef 7377 CookLabel(pt,0.1);
b9671574 7378 if (pt->GetRemoval()==10) {
91162307 7379 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
bad6eb00 7380 pt->Desactivate(10); // make track again active // MvL: should be 0 ?
91162307 7381 else{
7382 pt->Desactivate(20);
ddfbc51a 7383 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7384 }
7385 }
7386 }
51ad6848 7387 //
7388 RemoveUsed2(fSeeds,0.85,0.85,0);
a3232aae 7389 if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
6d493ea0 7390 //FindCurling(fSeeds, fEvent,0);
16299eac 7391 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,-1); // find multi found tracks
81e97e0d 7392 RemoveUsed2(fSeeds,0.5,0.4,20);
1af5da7e 7393 FindSplitted(fSeeds, fEvent,0); // find multi found tracks
16299eac 7394 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
6d493ea0 7395
81e97e0d 7396 // //
7397// // refit short tracks
7398// //
7399 Int_t nseed=fSeeds->GetEntriesFast();
1c53abe2 7400 //
91162307 7401 Int_t found = 0;
7402 for (Int_t i=0; i<nseed; i++) {
7403 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7404 if (!pt) continue;
7405 Int_t nc=t.GetNumberOfClusters();
7406 if (nc<15) {
ddfbc51a 7407 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7408 continue;
7409 }
7410 CookLabel(pt,0.1); //For comparison only
7411 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 7412 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
d9b8978b 7413 found++;
7414 if (fDebug>0) cerr<<found<<'\r';
b9671574 7415 pt->SetLab2(i);
91162307 7416 }
7417 else
ddfbc51a 7418 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7419 }
7420
7421
7422 //RemoveOverlap(fSeeds,0.99,7,kTRUE);
7423 SignShared(fSeeds);
7424 //RemoveUsed(fSeeds,0.9,0.9,6);
1c53abe2 7425 //
91162307 7426 nseed=fSeeds->GetEntriesFast();
7427 found = 0;
7428 for (Int_t i=0; i<nseed; i++) {
7429 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7430 if (!pt) continue;
7431 Int_t nc=t.GetNumberOfClusters();
7432 if (nc<15) {
ddfbc51a 7433 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7434 continue;
7435 }
7436 t.SetUniqueID(i);
7437 t.CookdEdx(0.02,0.6);
7438 // CheckKinkPoint(&t,0.05);
7439 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 7440 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6bdc18d6 7441 found++;
7442 if (fDebug>0){
7443 cerr<<found<<'\r';
7444 }
b9671574 7445 pt->SetLab2(i);
91162307 7446 }
7447 else
ddfbc51a 7448 MarkSeedFree( fSeeds->RemoveAt(i) );
d26d9159 7449 //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
7450 //if (seed1){
7451 // FollowProlongation(*seed1,0);
7452 // Int_t n = seed1->GetNumberOfClusters();
7453 // printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
7454 // printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
7455 //
7456 //}
7457 //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
7458
91162307 7459 }
7460
7461 SortTracks(fSeeds, 1);
1c53abe2 7462
982aff31 7463 /*
91162307 7464 fIteration = 1;
982aff31 7465 PrepareForBackProlongation(fSeeds,5.);
91162307 7466 PropagateBack(fSeeds);
7467 printf("Time for back propagation: \t");timer.Print();timer.Start();
7468
7469 fIteration = 2;
1c53abe2 7470
982aff31 7471 PrepareForProlongation(fSeeds,5.);
f124f8bf 7472 PropagateForard2(fSeeds);
d26d9159 7473
91162307 7474 printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
7475 // RemoveUsed(fSeeds,0.7,0.7,6);
7476 //RemoveOverlap(fSeeds,0.9,7,kTRUE);
d26d9159 7477
1c53abe2 7478 nseed=fSeeds->GetEntriesFast();
91162307 7479 found = 0;
7480 for (Int_t i=0; i<nseed; i++) {
1c53abe2 7481 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
7482 if (!pt) continue;
7483 Int_t nc=t.GetNumberOfClusters();
91162307 7484 if (nc<15) {
ddfbc51a 7485 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7486 continue;
7487 }
1c53abe2 7488 t.CookdEdx(0.02,0.6);
91162307 7489 // CookLabel(pt,0.1); //For comparison only
7490 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
7491 if ((pt->IsActive() || (pt->fRemoval==10) )){
7492 cerr<<found++<<'\r';
7493 }
7494 else
ddfbc51a 7495 MarkSeedFree( fSeeds->RemoveAt(i) );
91162307 7496 pt->fLab2 = i;
1c53abe2 7497 }
91162307 7498 */
7499
c9427e08 7500 // fNTracks = found;
6bdc18d6 7501 if (fDebug>0){
7502 Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
7503 }
91162307 7504 //
6bdc18d6 7505 // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
7506 Info("Clusters2Tracks","Number of found tracks %d",found);
91162307 7507 savedir->cd();
91162307 7508 // UnloadClusters();
d26d9159 7509 //
1c53abe2 7510 return 0;
7511}
7512
829455ad 7513void AliTPCtracker::Tracking(TObjArray * arr)
91162307 7514{
7515 //
7516 // tracking of the seeds
7517 //
7518
7519 fSectors = fOuterSec;
7520 ParallelTracking(arr,150,63);
7521 fSectors = fOuterSec;
7522 ParallelTracking(arr,63,0);
7523}
7524
829455ad 7525TObjArray * AliTPCtracker::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
91162307 7526{
7527 //
7528 //
7529 //tracking routine
f06a1ff6 7530 static TObjArray arrTracks;
7531 TObjArray * arr = &arrTracks;
91162307 7532 //
7533 fSectors = fOuterSec;
7534 TStopwatch timer;
7535 timer.Start();
7536 for (Int_t sec=0;sec<fkNOS;sec++){
7537 if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
7538 if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);
7539 if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
7540 }
7541 if (fDebug>0){
6bdc18d6 7542 Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
91162307 7543 timer.Print();
7544 timer.Start();
7545 }
7546 Tracking(arr);
7547 if (fDebug>0){
7548 timer.Print();
7549 }
7550
7551 return arr;
7552}
7553
829455ad 7554TObjArray * AliTPCtracker::Tracking()
91162307 7555{
544c295f 7556 // tracking
91162307 7557 //
a3232aae 7558 if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
91162307 7559 TStopwatch timer;
7560 timer.Start();
7561 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7562
7563 TObjArray * seeds = new TObjArray;
7564 TObjArray * arr=0;
6d1424d5 7565 Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
7566 Int_t gapPrim = AliTPCReconstructor::GetRecoParam()->GetSeedGapPrim();
7567 Int_t gapSec = AliTPCReconstructor::GetRecoParam()->GetSeedGapSec();
91162307 7568
7569 Int_t gap =20;
7570 Float_t cuts[4];
7571 cuts[0] = 0.002;
7572 cuts[1] = 1.5;
7573 cuts[2] = 3.;
7574 cuts[3] = 3.;
7575 Float_t fnumber = 3.0;
7576 Float_t fdensity = 3.0;
72e25240 7577
7578 // make HLT seeds
fa90aa2b 7579 if (AliTPCReconstructor::GetRecoParam()->GetUseHLTPreSeeding()) {
72e25240 7580 arr = MakeSeedsHLT( fEventHLT );
7581 if( arr ){
7582 SumTracks(seeds,arr);
7583 delete arr;
7584 arr=0;
7585 //cout<<"HLT tracks left after sorting: "<<seeds->GetEntriesFast()<<endl;
7586 //SignClusters(seeds,fnumber,fdensity);
7587 }
7588 }
91162307 7589
7590 //
7591 //find primaries
7592 cuts[0]=0.0066;
6d1424d5 7593 for (Int_t delta = 0; delta<18; delta+=gapPrim){
91162307 7594 //
7595 cuts[0]=0.0070;
7596 cuts[1] = 1.5;
7597 arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
7598 SumTracks(seeds,arr);
7599 SignClusters(seeds,fnumber,fdensity);
7600 //
7601 for (Int_t i=2;i<6;i+=2){
7602 // seed high pt tracks
7603 cuts[0]=0.0022;
7604 cuts[1]=0.3;
7605 arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
7606 SumTracks(seeds,arr);
7607 SignClusters(seeds,fnumber,fdensity);
7608 }
7609 }
7610 fnumber = 4;
7611 fdensity = 4.;
7612 // RemoveUsed(seeds,0.9,0.9,1);
7613 // UnsignClusters();
7614 // SignClusters(seeds,fnumber,fdensity);
7615
7616 //find primaries
7617 cuts[0]=0.0077;
6d1424d5 7618 for (Int_t delta = 20; delta<120; delta+=gapPrim){
91162307 7619 //
7620 // seed high pt tracks
7621 cuts[0]=0.0060;
7622 cuts[1]=0.3;
7623 cuts[2]=6.;
7624 arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
7625 SumTracks(seeds,arr);
7626 SignClusters(seeds,fnumber,fdensity);
7627
7628 cuts[0]=0.003;
7629 cuts[1]=0.3;
7630 cuts[2]=6.;
7631 arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
7632 SumTracks(seeds,arr);
7633 SignClusters(seeds,fnumber,fdensity);
7634 }
7635
7636 cuts[0] = 0.01;
7637 cuts[1] = 2.0;
7638 cuts[2] = 3.;
7639 cuts[3] = 2.0;
7640 fnumber = 2.;
7641 fdensity = 2.;
7642
7643 if (fDebug>0){
6bdc18d6 7644 Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 7645 timer.Print();
7646 timer.Start();
7647 }
7648 // RemoveUsed(seeds,0.75,0.75,1);
7649 //UnsignClusters();
7650 //SignClusters(seeds,fnumber,fdensity);
7651
7652 // find secondaries
7653
7654 cuts[0] = 0.3;
7655 cuts[1] = 1.5;
7656 cuts[2] = 3.;
7657 cuts[3] = 1.5;
7658
7659 arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
7660 SumTracks(seeds,arr);
7661 SignClusters(seeds,fnumber,fdensity);
7662 //
7663 arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
7664 SumTracks(seeds,arr);
7665 SignClusters(seeds,fnumber,fdensity);
7666 //
7667 arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
7668 SumTracks(seeds,arr);
7669 SignClusters(seeds,fnumber,fdensity);
7670 //
6d1424d5 7671 arr = Tracking(4,nup-5,nup-5-gap,cuts,-1);
7672 SumTracks(seeds,arr);
7673 SignClusters(seeds,fnumber,fdensity);
7674 //
7675 arr = Tracking(4,nup-7,nup-7-gap,cuts,-1);
7676 SumTracks(seeds,arr);
7677 SignClusters(seeds,fnumber,fdensity);
7678 //
7679 //
7680 arr = Tracking(4,nup-9,nup-9-gap,cuts,-1);
7681 SumTracks(seeds,arr);
7682 SignClusters(seeds,fnumber,fdensity);
7683 //
91162307 7684
7685
6d1424d5 7686 for (Int_t delta = 9; delta<30; delta+=gapSec){
91162307 7687 //
7688 cuts[0] = 0.3;
7689 cuts[1] = 1.5;
7690 cuts[2] = 3.;
7691 cuts[3] = 1.5;
7692 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7693 SumTracks(seeds,arr);
7694 SignClusters(seeds,fnumber,fdensity);
7695 //
7696 arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
7697 SumTracks(seeds,arr);
7698 SignClusters(seeds,fnumber,fdensity);
7699 //
7700 }
7701 fnumber = 1;
7702 fdensity = 1;
7703 //
7704 // change cuts
7705 fnumber = 2.;
7706 fdensity = 2.;
7707 cuts[0]=0.0080;
7708
7d27c1df 7709
91162307 7710 // find secondaries
6d1424d5 7711 for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=gapSec){
91162307 7712 //
7713 cuts[0] = 0.3;
2bd61959 7714 cuts[1] = 3.5;
91162307 7715 cuts[2] = 3.;
2bd61959 7716 cuts[3] = 3.5;
91162307 7717 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7718 SumTracks(seeds,arr);
7719 SignClusters(seeds,fnumber,fdensity);
7720 //
7721 arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
7722 SumTracks(seeds,arr);
7723 SignClusters(seeds,fnumber,fdensity);
7724 }
7725
7726 if (fDebug>0){
6bdc18d6 7727 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 7728 timer.Print();
7729 timer.Start();
7730 }
7731
7732 return seeds;
7733 //
7734
7735}
7736
7737
829455ad 7738TObjArray * AliTPCtracker::TrackingSpecial()
a3232aae 7739{
7740 //
7741 // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
7742 // no primary vertex seeding tried
7743 //
7744 TStopwatch timer;
7745 timer.Start();
7746 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7747
7748 TObjArray * seeds = new TObjArray;
7749 TObjArray * arr=0;
7750
7751 Int_t gap = 15;
7752 Float_t cuts[4];
7753 Float_t fnumber = 3.0;
7754 Float_t fdensity = 3.0;
7755
7756 // find secondaries
7757 cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC(); // max curvature
7758 cuts[1] = 3.5; // max tan(phi) angle for seeding
7759 cuts[2] = 3.; // not used (cut on z primary vertex)
7760 cuts[3] = 3.5; // max tan(theta) angle for seeding
7761
7762 for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
7763 //
7764 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7765 SumTracks(seeds,arr);
7766 SignClusters(seeds,fnumber,fdensity);
7767 }
7768
7769 if (fDebug>0){
7770 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
7771 timer.Print();
7772 timer.Start();
7773 }
7774
7775 return seeds;
7776 //
7777
7778}
7779
7780
829455ad 7781void AliTPCtracker::SumTracks(TObjArray *arr1,TObjArray *&arr2)
91162307 7782{
7783 //
7784 //sum tracks to common container
7785 //remove suspicious tracks
f06a1ff6 7786 // RS: Attention: supplied tracks come in the static array, don't delete them
91162307 7787 Int_t nseed = arr2->GetEntriesFast();
7788 for (Int_t i=0;i<nseed;i++){
7789 AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);
7790 if (pt){
a3232aae 7791 //
7792 // remove tracks with too big curvature
7793 //
7794 if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
ddfbc51a 7795 MarkSeedFree( arr2->RemoveAt(i) );
a3232aae 7796 continue;
7797 }
ca142b1f 7798 // REMOVE VERY SHORT TRACKS
7799 if (pt->GetNumberOfClusters()<20){
ddfbc51a 7800 MarkSeedFree( arr2->RemoveAt(i) );
ca142b1f 7801 continue;
7802 }// patch 28 fev06
91162307 7803 // NORMAL ACTIVE TRACK
7804 if (pt->IsActive()){
7805 arr1->AddLast(arr2->RemoveAt(i));
7806 continue;
7807 }
7808 //remove not usable tracks
b9671574 7809 if (pt->GetRemoval()!=10){
ddfbc51a 7810 MarkSeedFree( arr2->RemoveAt(i) );
91162307 7811 continue;
7812 }
ca142b1f 7813
91162307 7814 // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
7815 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
7816 arr1->AddLast(arr2->RemoveAt(i));
7817 else{
ddfbc51a 7818 MarkSeedFree( arr2->RemoveAt(i) );
91162307 7819 }
7820 }
7821 }
f06a1ff6 7822 // delete arr2; arr2 = 0; // RS: this is static array, don't delete it
91162307 7823}
7824
7825
1c53abe2 7826
829455ad 7827void AliTPCtracker::ParallelTracking(TObjArray *const arr, Int_t rfirst, Int_t rlast)
1c53abe2 7828{
7829 //
7830 // try to track in parralel
7831
91162307 7832 Int_t nseed=arr->GetEntriesFast();
1c53abe2 7833 //prepare seeds for tracking
7834 for (Int_t i=0; i<nseed; i++) {
91162307 7835 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 7836 if (!pt) continue;
7837 if (!t.IsActive()) continue;
7838 // follow prolongation to the first layer
47af7ca4 7839 if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fkParam->GetNRowLow()>rfirst+1) )
c9427e08 7840 FollowProlongation(t, rfirst+1);
1c53abe2 7841 }
7842
7843
7844 //
982aff31 7845 for (Int_t nr=rfirst; nr>=rlast; nr--){
7846 if (nr<fInnerSec->GetNRows())
7847 fSectors = fInnerSec;
7848 else
7849 fSectors = fOuterSec;
1c53abe2 7850 // make indexes with the cluster tracks for given
1c53abe2 7851
7852 // find nearest cluster
7853 for (Int_t i=0; i<nseed; i++) {
91162307 7854 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 7855 if (!pt) continue;
51ad6848 7856 if (nr==80) pt->UpdateReference();
1c53abe2 7857 if (!pt->IsActive()) continue;
47af7ca4 7858 // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
b9671574 7859 if (pt->GetRelativeSector()>17) {
1627d1c4 7860 continue;
7861 }
91162307 7862 UpdateClusters(t,nr);
1c53abe2 7863 }
7864 // prolonagate to the nearest cluster - if founded
7865 for (Int_t i=0; i<nseed; i++) {
91162307 7866 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
1c53abe2 7867 if (!pt) continue;
1627d1c4 7868 if (!pt->IsActive()) continue;
47af7ca4 7869 // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
b9671574 7870 if (pt->GetRelativeSector()>17) {
1627d1c4 7871 continue;
7872 }
91162307 7873 FollowToNextCluster(*pt,nr);
1c53abe2 7874 }
91162307 7875 }
7876}
7877
829455ad 7878void AliTPCtracker::PrepareForBackProlongation(const TObjArray *const arr,Float_t fac) const
91162307 7879{
7880 //
7881 //
7882 // if we use TPC track itself we have to "update" covariance
7883 //
7884 Int_t nseed= arr->GetEntriesFast();
7885 for (Int_t i=0;i<nseed;i++){
7886 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7887 if (pt) {
7888 pt->Modify(fac);
7889 //
7890 //rotate to current local system at first accepted point
b9671574 7891 Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
91162307 7892 Int_t sec = (index&0xff000000)>>24;
7893 sec = sec%18;
7894 Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
7895 if (angle1>TMath::Pi())
7896 angle1-=2.*TMath::Pi();
7897 Float_t angle2 = pt->GetAlpha();
7898
7899 if (TMath::Abs(angle1-angle2)>0.001){
17abbffb 7900 if (!pt->Rotate(angle1-angle2)) return;
91162307 7901 //angle2 = pt->GetAlpha();
7902 //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
7903 //if (pt->GetAlpha()<0)
7904 // pt->fRelativeSector+=18;
7905 //sec = pt->fRelativeSector;
7906 }
7907
7908 }
7909
7910 }
7911
7912
7913}
829455ad 7914void AliTPCtracker::PrepareForProlongation(TObjArray *const arr, Float_t fac) const
91162307 7915{
7916 //
7917 //
7918 // if we use TPC track itself we have to "update" covariance
7919 //
7920 Int_t nseed= arr->GetEntriesFast();
7921 for (Int_t i=0;i<nseed;i++){
7922 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7923 if (pt) {
7924 pt->Modify(fac);
b9671574 7925 pt->SetFirstPoint(pt->GetLastPoint());
91162307 7926 }
7927
7928 }
7929
7930
7931}
7932
829455ad 7933Int_t AliTPCtracker::PropagateBack(const TObjArray *const arr)
91162307 7934{
7935 //
7936 // make back propagation
7937 //
7938 Int_t nseed= arr->GetEntriesFast();
7939 for (Int_t i=0;i<nseed;i++){
7940 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
51ad6848 7941 if (pt&& pt->GetKinkIndex(0)<=0) {
d9b8978b 7942 //AliTPCseed *pt2 = new AliTPCseed(*pt);
91162307 7943 fSectors = fInnerSec;
d26d9159 7944 //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
7945 //fSectors = fOuterSec;
f124f8bf 7946 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
4d158c36 7947 //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
d9b8978b 7948 // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
4d158c36 7949 // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
d9b8978b 7950 //}
51ad6848 7951 }
7952 if (pt&& pt->GetKinkIndex(0)>0) {
7953 AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
b9671574 7954 pt->SetFirstPoint(kink->GetTPCRow0());
51ad6848 7955 fSectors = fInnerSec;
f124f8bf 7956 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
51ad6848 7957 }
6d493ea0 7958 CookLabel(pt,0.3);
91162307 7959 }
7960 return 0;
7961}
7962
7963
829455ad 7964Int_t AliTPCtracker::PropagateForward2(const TObjArray *const arr)
91162307 7965{
7966 //
7967 // make forward propagation
7968 //
7969 Int_t nseed= arr->GetEntriesFast();
4d158c36 7970 //
91162307 7971 for (Int_t i=0;i<nseed;i++){
7972 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7973 if (pt) {
f124f8bf 7974 FollowProlongation(*pt,0,1,1);
6d493ea0 7975 CookLabel(pt,0.3);
4d158c36 7976 }
6d493ea0 7977
91162307 7978 }
f124f8bf 7979 return 0;
91162307 7980}
7981
7982
829455ad 7983Int_t AliTPCtracker::PropagateForward()
91162307 7984{
b67e07dc 7985 //
7986 // propagate track forward
4d158c36 7987 //UnsignClusters();
d26d9159 7988 Int_t nseed = fSeeds->GetEntriesFast();
7989 for (Int_t i=0;i<nseed;i++){
7990 AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
7991 if (pt){
7992 AliTPCseed &t = *pt;
7993 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
7994 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
7995 if (alpha < 0. ) alpha += 2.*TMath::Pi();
b9671574 7996 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
d26d9159 7997 }
7998 }
7999
91162307 8000 fSectors = fOuterSec;
d26d9159 8001 ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
91162307 8002 fSectors = fInnerSec;
d26d9159 8003 ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
91162307 8004 return 1;
8005}
8006
8007
8008
8009
8010
8011
829455ad 8012Int_t AliTPCtracker::PropagateBack(AliTPCseed *const pt, Int_t row0, Int_t row1)
91162307 8013{
8014 //
8015 // make back propagation, in between row0 and row1
8016 //
1c53abe2 8017
91162307 8018 if (pt) {
8019 fSectors = fInnerSec;
8020 Int_t r1;
8021 //
8022 if (row1<fSectors->GetNRows())
8023 r1 = row1;
8024 else
8025 r1 = fSectors->GetNRows()-1;
8026
8027 if (row0<fSectors->GetNRows()&& r1>0 )
8028 FollowBackProlongation(*pt,r1);
8029 if (row1<=fSectors->GetNRows())
8030 return 0;
8031 //
8032 r1 = row1 - fSectors->GetNRows();
8033 if (r1<=0) return 0;
8034 if (r1>=fOuterSec->GetNRows()) return 0;
8035 fSectors = fOuterSec;
8036 return FollowBackProlongation(*pt,r1);
8037 }
8038 return 0;
8039}
8040
8041
8042
8043
829455ad 8044void AliTPCtracker::GetShape(AliTPCseed * seed, Int_t row)
91162307 8045{
544c295f 8046 // gets cluster shape
fd065ea2 8047 //
8048 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
47af7ca4 8049 Float_t zdrift = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())));
8050 Int_t type = (seed->GetSector() < fkParam->GetNSector()/2) ? 0: (row>126) ? 1:2;
3f82c4f2 8051 Double_t angulary = seed->GetSnp();
feed67f9 8052
8053 if (TMath::Abs(angulary)>AliTPCReconstructor::GetMaxSnpTracker()) {
8054 angulary = TMath::Sign(AliTPCReconstructor::GetMaxSnpTracker(),angulary);
8055 }
8056
bfd20868 8057 angulary = angulary*angulary/((1.-angulary)*(1.+angulary));
fd065ea2 8058 Double_t angularz = seed->GetTgl()*seed->GetTgl()*(1.+angulary);
8059
e0e13b88 8060 Double_t sigmay = clparam->GetRMS0(0,type,zdrift,TMath::Sqrt(TMath::Abs(angulary)));
8061 Double_t sigmaz = clparam->GetRMS0(1,type,zdrift,TMath::Sqrt(TMath::Abs(angularz)));
fd065ea2 8062 seed->SetCurrentSigmaY2(sigmay*sigmay);
8063 seed->SetCurrentSigmaZ2(sigmaz*sigmaz);
47af7ca4 8064 // Float_t sd2 = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fkParam->GetDiffL()*fkParam->GetDiffL();
8065// // Float_t padlength = fkParam->GetPadPitchLength(seed->fSector);
fd065ea2 8066// Float_t padlength = GetPadPitchLength(row);
8067// //
47af7ca4 8068// Float_t sresy = (seed->GetSector() < fkParam->GetNSector()/2) ? 0.2 :0.3;
fd065ea2 8069// seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
8070// //
47af7ca4 8071// Float_t sresz = fkParam->GetZSigma();
fd065ea2 8072// seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
91162307 8073 /*
8074 Float_t wy = GetSigmaY(seed);
8075 Float_t wz = GetSigmaZ(seed);
8076 wy*=wy;
8077 wz*=wz;
8078 if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
8079 printf("problem\n");
8080 }
8081 */
1c53abe2 8082}
8083
91162307 8084
1c53abe2 8085
1c53abe2 8086//__________________________________________________________________________
829455ad 8087void AliTPCtracker::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
1c53abe2 8088 //--------------------------------------------------------------------
8089 //This function "cooks" a track label. If label<0, this track is fake.
8090 //--------------------------------------------------------------------
316c6cd9 8091 AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
8092 if(!t){
8093 printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
8094 return;
8095 }
8096
1c53abe2 8097 Int_t noc=t->GetNumberOfClusters();
91162307 8098 if (noc<10){
d26d9159 8099 //printf("\nnot founded prolongation\n\n\n");
8100 //t->Dump();
91162307 8101 return ;
8102 }
8103 Int_t lb[160];
8104 Int_t mx[160];
8105 AliTPCclusterMI *clusters[160];
8106 //
8107 for (Int_t i=0;i<160;i++) {
8108 clusters[i]=0;
8109 lb[i]=mx[i]=0;
8110 }
1c53abe2 8111
8112 Int_t i;
91162307 8113 Int_t current=0;
8114 for (i=0; i<160 && current<noc; i++) {
8115
8116 Int_t index=t->GetClusterIndex2(i);
8117 if (index<=0) continue;
8118 if (index&0x8000) continue;
8119 //
8120 //clusters[current]=GetClusterMI(index);
b9671574 8121 if (t->GetClusterPointer(i)){
8122 clusters[current]=t->GetClusterPointer(i);
91162307 8123 current++;
8124 }
1c53abe2 8125 }
91162307 8126 noc = current;
1c53abe2 8127
8128 Int_t lab=123456789;
8129 for (i=0; i<noc; i++) {
8130 AliTPCclusterMI *c=clusters[i];
91162307 8131 if (!c) continue;
1c53abe2 8132 lab=TMath::Abs(c->GetLabel(0));
8133 Int_t j;
8134 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
8135 lb[j]=lab;
8136 (mx[j])++;
8137 }
8138
8139 Int_t max=0;
8140 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
8141
8142 for (i=0; i<noc; i++) {
9918f10a 8143 AliTPCclusterMI *c=clusters[i];
91162307 8144 if (!c) continue;
1c53abe2 8145 if (TMath::Abs(c->GetLabel(1)) == lab ||
8146 TMath::Abs(c->GetLabel(2)) == lab ) max++;
8147 }
52033b55 8148 if (noc<=0) { lab=-1; return;}
8149 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
1c53abe2 8150
8151 else {
8152 Int_t tail=Int_t(0.10*noc);
8153 max=0;
91162307 8154 Int_t ind=0;
ec26e231 8155 for (i=1; i<160&&ind<tail; i++) {
91162307 8156 // AliTPCclusterMI *c=clusters[noc-i];
8157 AliTPCclusterMI *c=clusters[i];
8158 if (!c) continue;
1c53abe2 8159 if (lab == TMath::Abs(c->GetLabel(0)) ||
8160 lab == TMath::Abs(c->GetLabel(1)) ||
8161 lab == TMath::Abs(c->GetLabel(2))) max++;
91162307 8162 ind++;
1c53abe2 8163 }
8164 if (max < Int_t(0.5*tail)) lab=-lab;
8165 }
8166
8167 t->SetLabel(lab);
8168
91162307 8169 // delete[] lb;
8170 //delete[] mx;
8171 //delete[] clusters;
1c53abe2 8172}
8173
47966a6d 8174
51ad6848 8175//__________________________________________________________________________
829455ad 8176Int_t AliTPCtracker::CookLabel(AliTPCseed *const t, Float_t wrong,Int_t first, Int_t last) const {
51ad6848 8177 //--------------------------------------------------------------------
8178 //This function "cooks" a track label. If label<0, this track is fake.
8179 //--------------------------------------------------------------------
8180 Int_t noc=t->GetNumberOfClusters();
8181 if (noc<10){
8182 //printf("\nnot founded prolongation\n\n\n");
8183 //t->Dump();
8184 return -1;
8185 }
8186 Int_t lb[160];
8187 Int_t mx[160];
8188 AliTPCclusterMI *clusters[160];
8189 //
8190 for (Int_t i=0;i<160;i++) {
8191 clusters[i]=0;
8192 lb[i]=mx[i]=0;
8193 }
8194
8195 Int_t i;
8196 Int_t current=0;
8197 for (i=0; i<160 && current<noc; i++) {
8198 if (i<first) continue;
8199 if (i>last) continue;
8200 Int_t index=t->GetClusterIndex2(i);
8201 if (index<=0) continue;
8202 if (index&0x8000) continue;
8203 //
8204 //clusters[current]=GetClusterMI(index);
b9671574 8205 if (t->GetClusterPointer(i)){
8206 clusters[current]=t->GetClusterPointer(i);
51ad6848 8207 current++;
8208 }
8209 }
8210 noc = current;
17abbffb 8211 //if (noc<5) return -1;
51ad6848 8212 Int_t lab=123456789;
8213 for (i=0; i<noc; i++) {
8214 AliTPCclusterMI *c=clusters[i];
8215 if (!c) continue;
8216 lab=TMath::Abs(c->GetLabel(0));
8217 Int_t j;
8218 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
8219 lb[j]=lab;
8220 (mx[j])++;
8221 }
8222
8223 Int_t max=0;
8224 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
8225
8226 for (i=0; i<noc; i++) {
8227 AliTPCclusterMI *c=clusters[i];
8228 if (!c) continue;
8229 if (TMath::Abs(c->GetLabel(1)) == lab ||
8230 TMath::Abs(c->GetLabel(2)) == lab ) max++;
8231 }
52033b55 8232 if (noc<=0) { lab=-1; return -1;}
8233 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
51ad6848 8234
8235 else {
8236 Int_t tail=Int_t(0.10*noc);
8237 max=0;
8238 Int_t ind=0;
ec26e231 8239 for (i=1; i<160&&ind<tail; i++) {
51ad6848 8240 // AliTPCclusterMI *c=clusters[noc-i];
8241 AliTPCclusterMI *c=clusters[i];
8242 if (!c) continue;
8243 if (lab == TMath::Abs(c->GetLabel(0)) ||
8244 lab == TMath::Abs(c->GetLabel(1)) ||
8245 lab == TMath::Abs(c->GetLabel(2))) max++;
8246 ind++;
8247 }
8248 if (max < Int_t(0.5*tail)) lab=-lab;
8249 }
8250
8251 // t->SetLabel(lab);
8252 return lab;
8253 // delete[] lb;
8254 //delete[] mx;
8255 //delete[] clusters;
8256}
8257
8258
829455ad 8259Int_t AliTPCtracker::GetRowNumber(Double_t x[3]) const
eea478d3 8260{
8261 //return pad row number for given x vector
8262 Float_t phi = TMath::ATan2(x[1],x[0]);
8263 if(phi<0) phi=2.*TMath::Pi()+phi;
8264 // Get the local angle in the sector philoc
8265 const Float_t kRaddeg = 180/3.14159265358979312;
8266 Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
8267 Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
8268 return GetRowNumber(localx);
8269}
8270
91162307 8271
91162307 8272
829455ad 8273void AliTPCtracker::MakeESDBitmaps(AliTPCseed *t, AliESDtrack *esd)
19b00333 8274{
8275 //-----------------------------------------------------------------------
8276 // Fill the cluster and sharing bitmaps of the track
8277 //-----------------------------------------------------------------------
8278
8279 Int_t firstpoint = 0;
8280 Int_t lastpoint = 159;
8281 AliTPCTrackerPoint *point;
52c51057 8282 AliTPCclusterMI *cluster;
19b00333 8283
bad6eb00 8284 Int_t nclsf = 0;
8285 TBits clusterMap(159);
8286 TBits sharedMap(159);
8287 TBits fitMap(159);
19b00333 8288 for (int iter=firstpoint; iter<lastpoint; iter++) {
52c51057 8289 // Change to cluster pointers to see if we have a cluster at given padrow
bad6eb00 8290
52c51057 8291 cluster = t->GetClusterPointer(iter);
8292 if (cluster) {
bad6eb00 8293 clusterMap.SetBitNumber(iter, kTRUE);
52c51057 8294 point = t->GetTrackPoint(iter);
19b00333 8295 if (point->IsShared())
bad6eb00 8296 sharedMap.SetBitNumber(iter,kTRUE);
19b00333 8297 }
bad6eb00 8298 if (t->GetClusterIndex(iter) >= 0 && (t->GetClusterIndex(iter) & 0x8000) == 0) {
8299 fitMap.SetBitNumber(iter, kTRUE);
8300 nclsf++;
19b00333 8301 }
8302 }
bad6eb00 8303 esd->SetTPCClusterMap(clusterMap);
8304 esd->SetTPCSharedMap(sharedMap);
8305 esd->SetTPCFitMap(fitMap);
8306 if (nclsf != t->GetNumberOfClusters())
27540e35 8307 AliDebug(3,Form("Inconsistency between ncls %d and indices %d (found %d)",t->GetNumberOfClusters(),nclsf,esd->GetTPCClusterMap().CountBits()));
19b00333 8308}
92f513f5 8309
829455ad 8310Bool_t AliTPCtracker::IsFindable(AliTPCseed & track){
76d56fd6 8311 //
8312 // return flag if there is findable cluster at given position
8313 //
8314 Float_t kDeltaZ=10;
8315 Float_t z = track.GetZ();
8316
8317 if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*track.GetX()+kDeltaZ) &&
47af7ca4 8318 TMath::Abs(z)<fkParam->GetZLength(0) &&
76d56fd6 8319 (TMath::Abs(track.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
8320 return kTRUE;
8321 return kFALSE;
8322}
92f513f5 8323
8324
829455ad 8325void AliTPCtracker::AddCovariance(AliTPCseed * seed){
92f513f5 8326 //
e1dadcd0 8327 // Adding systematic error estimate to the covariance matrix
b87c2bbc 8328 // !!!! the systematic error for element 4 is in 1/GeV
8329 // 03.03.2012 MI changed in respect to the previous versions
e1dadcd0 8330 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
8331 //
8332 // use only the diagonal part if not specified otherwise
8333 if (!AliTPCReconstructor::GetRecoParam()->GetUseSystematicCorrelation()) return AddCovarianceAdd(seed);
8334 //
8335 Double_t *covarS= (Double_t*)seed->GetCovariance();
8336 Double_t factor[5]={1,1,1,1,1};
e1dadcd0 8337 factor[0]= TMath::Sqrt(TMath::Abs((covarS[0] + param[0]*param[0])/covarS[0]));
8338 factor[1]= TMath::Sqrt(TMath::Abs((covarS[2] + param[1]*param[1])/covarS[2]));
8339 factor[2]= TMath::Sqrt(TMath::Abs((covarS[5] + param[2]*param[2])/covarS[5]));
8340 factor[3]= TMath::Sqrt(TMath::Abs((covarS[9] + param[3]*param[3])/covarS[9]));
b87c2bbc 8341 factor[4]= TMath::Sqrt(TMath::Abs((covarS[14] +param[4]*param[4])/covarS[14]));
9b550f87 8342 //
8343 factor[0]=factor[2];
8344 factor[4]=factor[2];
e1dadcd0 8345 // 0
8346 // 1 2
8347 // 3 4 5
8348 // 6 7 8 9
8349 // 10 11 12 13 14
8350 for (Int_t i=0; i<5; i++){
8351 for (Int_t j=i; j<5; j++){
8352 Int_t index=seed->GetIndex(i,j);
8353 covarS[index]*=factor[i]*factor[j];
8354 }
8355 }
8356}
8357
92f513f5 8358
829455ad 8359void AliTPCtracker::AddCovarianceAdd(AliTPCseed * seed){
e1dadcd0 8360 //
8361 // Adding systematic error - as additive factor without correlation
8362 //
b87c2bbc 8363 // !!!! the systematic error for element 4 is in 1/GeV
8364 // 03.03.2012 MI changed in respect to the previous versions
8365
92f513f5 8366 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
f47588e0 8367 Double_t *covarIn= (Double_t*)seed->GetCovariance();
92f513f5 8368 Double_t covar[15];
8369 for (Int_t i=0;i<15;i++) covar[i]=0;
8370 // 0
8371 // 1 2
8372 // 3 4 5
8373 // 6 7 8 9
8374 // 10 11 12 13 14
8375 covar[0] = param[0]*param[0];
8376 covar[2] = param[1]*param[1];
8377 covar[5] = param[2]*param[2];
8378 covar[9] = param[3]*param[3];
b87c2bbc 8379 covar[14]= param[4]*param[4];
f47588e0 8380 //
8381 covar[1]=TMath::Sqrt((covar[0]*covar[2]))*covarIn[1]/TMath::Sqrt((covarIn[0]*covarIn[2]));
8382 //
8383 covar[3]=TMath::Sqrt((covar[0]*covar[5]))*covarIn[3]/TMath::Sqrt((covarIn[0]*covarIn[5]));
8384 covar[4]=TMath::Sqrt((covar[2]*covar[5]))*covarIn[4]/TMath::Sqrt((covarIn[2]*covarIn[5]));
8385 //
8386 covar[6]=TMath::Sqrt((covar[0]*covar[9]))*covarIn[6]/TMath::Sqrt((covarIn[0]*covarIn[9]));
8387 covar[7]=TMath::Sqrt((covar[2]*covar[9]))*covarIn[7]/TMath::Sqrt((covarIn[2]*covarIn[9]));
8388 covar[8]=TMath::Sqrt((covar[5]*covar[9]))*covarIn[8]/TMath::Sqrt((covarIn[5]*covarIn[9]));
8389 //
8390 covar[10]=TMath::Sqrt((covar[0]*covar[14]))*covarIn[10]/TMath::Sqrt((covarIn[0]*covarIn[14]));
8391 covar[11]=TMath::Sqrt((covar[2]*covar[14]))*covarIn[11]/TMath::Sqrt((covarIn[2]*covarIn[14]));
8392 covar[12]=TMath::Sqrt((covar[5]*covar[14]))*covarIn[12]/TMath::Sqrt((covarIn[5]*covarIn[14]));
8393 covar[13]=TMath::Sqrt((covar[9]*covar[14]))*covarIn[13]/TMath::Sqrt((covarIn[9]*covarIn[14]));
8394 //
92f513f5 8395 seed->AddCovariance(covar);
8396}
f06a1ff6 8397
ec7e4ad6 8398//_____________________________________________________________________________
829455ad 8399Bool_t AliTPCtracker::IsTPCHVDipEvent(AliESDEvent const *esdEvent)
661f340b 8400{
8401 //
8402 // check events affected by TPC HV dip
8403 //
8404 if(!esdEvent) return kFALSE;
ec7e4ad6 8405
661f340b 8406 // Init TPC OCDB
8407 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
8408 if(!db) return kFALSE;
8409 db->SetRun(esdEvent->GetRunNumber());
ec7e4ad6 8410
661f340b 8411 // maximum allowed voltage before an event is identified as a dip event
8412 // and scanning period
8413 const Double_t kTPCHVdip = db->GetParameters()->GetMaxDipVoltage();
8414 const Double_t dipEventScanPeriod = db->GetParameters()->GetVoltageDipScanPeriod();
8415 const Double_t tevSec = esdEvent->GetTimeStamp();
8416
ec7e4ad6 8417 for(Int_t sector=0; sector<72; sector++)
8418 {
661f340b 8419 // don't use excluded chambers, since the state is not defined at all
8420 if (!db->GetChamberHVStatus(sector)) continue;
8421
8422 // get hv sensor of the chamber
8423 AliDCSSensor *sensor = db->GetChamberHVSensor(sector);
8424 if (!sensor) continue;
8425 TGraph *grSensor=sensor->GetGraph();
8426 if (!grSensor) continue;
8427 if (grSensor->GetN()<1) continue;
ec7e4ad6 8428
661f340b 8429 // get median
8430 const Double_t median = db->GetChamberHighVoltageMedian(sector);
8431 if(median < 1.) continue;
ec7e4ad6 8432
661f340b 8433 for (Int_t ipoint=0; ipoint<grSensor->GetN()-1; ++ipoint){
8434 Double_t nextTime=grSensor->GetX()[ipoint+1]*3600+sensor->GetStartTime();
8435 if (tevSec-dipEventScanPeriod>nextTime) continue;
8436 const Float_t deltaV=TMath::Abs(grSensor->GetY()[ipoint]-median);
8437 if (deltaV>kTPCHVdip) {
8438 AliDebug(3,Form("HV dip detected in ROC '%02d' with dV '%.2f' at time stamp '%.0f'",sector,deltaV,tevSec));
8439 return kTRUE;
8440 }
8441 if (nextTime>tevSec+dipEventScanPeriod) break;
ec7e4ad6 8442 }
661f340b 8443 }
8444
8445 return kFALSE;
8446}
ddfbc51a 8447
8448//________________________________________
829455ad 8449void AliTPCtracker::MarkSeedFree(TObject *sd)
ddfbc51a 8450{
8451 // account that this seed is "deleted"
8452 AliTPCseed* seed = dynamic_cast<AliTPCseed*>(sd);
88492b27 8453 if (!seed) {
b6565e28 8454 AliError(Form("Freeing of non-AliTPCseed %p from the pool is requested",sd));
8455 return;
8456 }
88492b27 8457 int id = seed->GetPoolID();
b6565e28 8458 if (id<0) {
8459 AliError(Form("Freeing of seed %p NOT from the pool is requested",sd));
8460 return;
8461 }
ddfbc51a 8462 // AliInfo(Form("%d %p",id, seed));
8463 fSeedsPool->RemoveAt(id);
8464 if (fFreeSeedsID.GetSize()<=fNFreeSeeds) fFreeSeedsID.Set( 2*fNFreeSeeds + 100 );
8465 fFreeSeedsID.GetArray()[fNFreeSeeds++] = id;
8466}
8467
8468//________________________________________
829455ad 8469TObject *&AliTPCtracker::NextFreeSeed()
ddfbc51a 8470{
8471 // return next free slot where the seed can be created
8472 fLastSeedID = fNFreeSeeds ? fFreeSeedsID.GetArray()[--fNFreeSeeds] : fSeedsPool->GetEntriesFast();
8473 // AliInfo(Form("%d",fLastSeedID));
8474 return (*fSeedsPool)[ fLastSeedID ];
8475 //
8476}
8477
8478//________________________________________
829455ad 8479void AliTPCtracker::ResetSeedsPool()
ddfbc51a 8480{
8481 // mark all seeds in the pool as unused
8482 AliInfo(Form("CurrentSize: %d, BookedUpTo: %d, free: %d",fSeedsPool->GetSize(),fSeedsPool->GetEntriesFast(),fNFreeSeeds));
8483 fNFreeSeeds = 0;
8484 fSeedsPool->Clear("C"); // RS: nominally the seeds may allocate memory...
8485}
72e25240 8486
829455ad 8487Int_t AliTPCtracker::PropagateToRowHLT(AliTPCseed *pt, int nrow)
72e25240 8488{
8489 AliTPCseed &t=*pt;
8490 Double_t x= GetXrow(nrow);
8491 Double_t ymax= GetMaxY(nrow);
8492 Int_t rotate = 0;
8493 Int_t nRotations=0;
8494 int ret = 1;
8495 do{
8496 rotate = 0;
8497 if (!t.PropagateTo(x) ){
8498 //cout<<"can't propagate to row "<<nrow<<", x="<<t.GetX()<<" -> "<<x<<endl;
8499 //t.Print();
8500 ret = 0;
8501 break;
8502 }
8503 t.SetRow(nrow);
8504 Double_t y = t.GetY();
8505 if( y > ymax ) {
8506 if( rotate!=-1 ) rotate=1;
8507 } else if (y <-ymax) {
8508 if( rotate!=1 ) rotate = -1;
8509 }
8510 if( rotate==0 ) break;
8511 //cout<<"rotate at row "<<nrow<<": "<<rotate<<endl;
8512 if (!t.Rotate( rotate==1 ?fSectors->GetAlpha() :-fSectors->GetAlpha())) {
8513 //cout<<"can't rotate "<<endl;
8514 ret=0;
8515 break;
8516 }
8517 nRotations+= rotate;
8518 }while(rotate!=0);
8519 if( nRotations!=0 ){
8520 int newSec= t.GetRelativeSector()+nRotations;
8521 if( newSec>=fN ) newSec-=fN;
8522 else if( newSec<0 ) newSec +=fN;
8523 //cout<<"rotate at row "<<nrow<<": "<<nRotations<<" times "<<" sec "
8524 //<< t.GetRelativeSector()<<" -> "<<newSec<<endl;
8525 t.SetRelativeSector(newSec);
8526 }
8527 return ret;
8528}
8529
829455ad 8530void AliTPCtracker::TrackFollowingHLT(TObjArray *const arr )
72e25240 8531{
8532 //
8533 // try to track in parralel
8534
8535 Int_t nRows=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8536 fSectors=fInnerSec;
8537
8538 Int_t nseed=arr->GetEntriesFast();
8539 //cout<<"Parallel tracking My.."<<endl;
8540 double shapeY2[160], shapeZ2[160];
8541 Int_t clusterIndex[160];
8542
8543 for (Int_t iSeed=0; iSeed<nseed; iSeed++) {
8544 //if( iSeed!=1 ) continue;
8545 AliTPCseed *pt=(AliTPCseed*) (arr->UncheckedAt(iSeed));
8546 if (!pt) continue;
8547 AliTPCseed &t=*pt;
8548
8549 //cout <<"Pt "<<t.GetSigned1Pt()<<endl;
8550
8551 // t.Print();
8552
8553 for( int iter=0; iter<3; iter++ ){
8554
8555 t.Reset();
8556 t.SetLastPoint(0); // first cluster in track position
8557 t.SetFirstPoint(nRows-1);
8558 t.ResetCovariance(.1);
8559 t.SetNumberOfClusters(0);
8560 for( int i=0; i<nRows; i++ ){
8561 shapeY2[i]=1.;
8562 shapeZ2[i]=1.;
8563 clusterIndex[i]=-1;
8564 t.SetClusterIndex2(i,-1);
8565 t.SetClusterIndex(i,-1);
8566 }
8567
8568 // pick up the clusters
8569
8570 Double_t roady = 20.;
8571 Double_t roadz = 20.;
8572 double roadr = 5;
8573
8574 AliTPCseed t0(t);
8575 t0.Reset();
8576 int nClusters = 0;
8577 {
8578 t0.SetRelativeSector(t.GetRelativeSector());
8579 t0.SetLastPoint(0); // first cluster in track position
8580 t0.SetFirstPoint(159);
8581 for (Int_t nr=0; nr<nRows; nr++){
8582 if( nr<fInnerSec->GetNRows() ) fSectors=fInnerSec;
8583 else fSectors=fOuterSec;
8584
8585 if( !PropagateToRowHLT(&t0, nr ) ){ break; }
8586 if (TMath::Abs(t0.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8587 //cout<<"Snp is too big: "<<t0.GetSnp()<<endl;
8588 continue;
8589 }
8590 if (!IsActive(t0.GetRelativeSector(),nr)) {
8591 continue;
8592 }
8593
8594 if( iter==0 ){
8595 GetShape(&t0,nr);
8596 shapeY2[nr]=t0.GetCurrentSigmaY2();
8597 shapeZ2[nr]=t0.GetCurrentSigmaZ2();
8598 }
8599
8600 AliTPCtrackerRow &krow=GetRow(t0.GetRelativeSector(),nr);
8601 if( !krow ) continue;
8602
8603 t.SetClusterIndex2(nr,-3); // foundable
8604 t.SetClusterIndex(nr,-3);
8605
8606 AliTPCclusterMI *cl=0;
8607 UInt_t uindex = 0;
8608 cl = krow.FindNearest2(t0.GetY(),t0.GetZ(),roady,roadz,uindex);
8609 if (!cl ) continue;
8610 double dy = cl->GetY()-t0.GetY();
8611 double dz = cl->GetZ()-t0.GetZ();
8612 double dr = sqrt(dy*dy+dz*dz);
8613 if( dr>roadr ){
8614 //cout<<"row "<<nr<<", best cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8615 continue;
8616 }
8617 //cout<<"row "<<nr<<", found cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8618
8619 t0.SetClusterPointer(nr, cl);
8620 clusterIndex[nr] = krow.GetIndex(uindex);
8621 if( t0.GetFirstPoint()>nr ) t0.SetFirstPoint(nr);
8622 t0.SetLastPoint(nr);
8623 nClusters++;
8624 }
8625 }
8626
8627 if( nClusters <3 ){
8628 //cout<<"NOT ENOUGTH CLUSTERS: "<<nClusters<<endl;
8629 break;
8630 }
8631 Int_t basePoints[3] = {t0.GetFirstPoint(),t0.GetFirstPoint(),t0.GetLastPoint()};
8632
8633 // find midpoint
8634 {
8635 Int_t midRow = (t0.GetLastPoint()-t0.GetFirstPoint())/2;
8636 int dist=200;
8637 for( int nr=t0.GetFirstPoint()+1; nr< t0.GetLastPoint(); nr++){
8638 if( !t0.GetClusterPointer(nr) ) continue;
8639 int d = TMath::Abs(nr-midRow);
8640 if( d < dist ){
8641 dist = d;
8642 basePoints[1] = nr;
8643 }
8644 }
8645 }
8646
8647 // first fit 3 base points
8648 if( 1||iter<2 ){
8649 //cout<<"Fit3: "<<endl;
8650 for( int icl=0; icl<3; icl++){
8651 int nr = basePoints[icl];
8652 int lr=nr;
8653 if( nr>=fInnerSec->GetNRows()){
8654 lr = nr - fInnerSec->GetNRows();
8655 fSectors=fOuterSec;
8656 } else fSectors=fInnerSec;
8657
8658 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8659 if(!cl){
8660 //cout<<"WRONG!!!!"<<endl;
8661 continue;
8662 }
8663 int iSec = cl->GetDetector() %fkNIS;
8664 int rotate = iSec - t.GetRelativeSector();
8665 if( rotate!=0 ){
8666 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8667 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8668 //cout<<"can't rotate "<<endl;
8669 break;
8670 }
8671 t.SetRelativeSector(iSec);
8672 }
8673 Double_t x= cl->GetX();
8674 if (!t.PropagateTo(x)){
8675 //cout<<"can't propagate to x="<<x<<endl;
8676 break;
8677 }
8678
8679 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8680 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8681 break;
8682 }
8683 //cout<<"fit3 : row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8684
8685 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8686 t.SetCurrentCluster(cl);
8687 t.SetRow(lr);
8688
8689 t.SetErrorY2(shapeY2[nr]);
8690 t.SetErrorZ2(shapeZ2[nr]);
8691 if( icl==0 ){
8692 double cov[15];
8693 for( int j=0; j<15; j++ ) cov[j]=0;
8694 cov[0]=10;
8695 cov[2]=10;
8696 cov[5]=.5;
8697 cov[9]=.5;
8698 cov[14]=1.;
8699 t.AliExternalTrackParam::AddCovariance(cov);
8700 }
8701 if( !UpdateTrack(&t,0) ){
8702 //cout<<"Can not update"<<endl;
8703 //t.Print();
8704 t.SetClusterIndex2(nr,-1);
8705 t.SetClusterIndex(nr,-1);
8706 t.SetClusterPointer(nr,0);
8707 break;
8708 }
8709 //t.SetClusterPointer(nr, cl);
8710 }
8711
8712 //t.SetLastPoint(t0.GetLastPoint());
8713 //t.SetFirstPoint(t0.GetFirstPoint());
8714
8715 //cout<<"Fit: "<<endl;
8716 for (Int_t nr=t0.GetLastPoint(); nr>=t0.GetFirstPoint(); nr-- ){
8717 int lr=nr;
8718 if( nr>=fInnerSec->GetNRows()){
8719 lr = nr - fInnerSec->GetNRows();
8720 fSectors=fOuterSec;
8721 } else fSectors=fInnerSec;
8722
8723 if(1|| iter<2 ){
8724 if( nr == basePoints[0] ) continue;
8725 if( nr == basePoints[1] ) continue;
8726 if( nr == basePoints[2] ) continue;
8727 }
8728 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8729 if(!cl) continue;
8730
8731 int iSec = cl->GetDetector() %fkNIS;
8732 int rotate = iSec - t.GetRelativeSector();
8733 if( rotate!=0 ){
8734 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8735 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8736 //cout<<"can't rotate "<<endl;
8737 break;
8738 }
8739 t.SetRelativeSector(iSec);
8740 }
8741 Double_t x= cl->GetX();
8742 if (!t.PropagateTo(x)){
8743 //cout<<"can't propagate to x="<<x<<endl;
8744 break;
8745 }
8746 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8747 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8748 break;
8749 }
8750
8751 //cout<<"fit: row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8752
8753 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8754 t.SetCurrentCluster(cl);
8755 t.SetRow(lr);
8756 t.SetErrorY2(shapeY2[nr]);
8757 t.SetErrorZ2(shapeZ2[nr]);
8758
8759 if( !UpdateTrack(&t,0) ){
8760 //cout<<"Can not update"<<endl;
8761 //t.Print();
8762 t.SetClusterIndex2(nr,-1);
8763 t.SetClusterIndex(nr,-1);
8764 break;
8765 }
8766 //t.SetClusterPointer(nr, cl);
8767 }
8768 }
8769 //cout<<"After iter "<<iter<<": N clusters="<<t.GetNumberOfClusters()<<" : "<<nClusters<<endl;
8770 }
8771
8772 //cout<<"fitted track"<<iSeed<<endl;
8773 //t.Print();
8774 //cout<<"Statistics: "<<endl;
8775 Int_t foundable,found,shared;
8776 t.GetClusterStatistic(0,nRows, found, foundable, shared, kTRUE);
8777 t.SetNFoundable(foundable);
8778 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8779
8780 }
8781}
8782
8783
829455ad 8784TObjArray * AliTPCtracker::MakeSeedsHLT(const AliESDEvent *hltEvent)
72e25240 8785{
8786 // tracking
8787 //
8788
8789 if( !hltEvent ) return 0;
8790
8791
8792 Int_t nentr=hltEvent->GetNumberOfTracks();
8793
8794 AliInfo(Form("Using %d HLT tracks for seeding",nentr));
8795
8796 TObjArray * seeds = new TObjArray(nentr);
8797
8798 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8799 Int_t index = 0;
8800
8801 Int_t nTr=hltEvent->GetNumberOfTracks();
8802
8803 for( int itr=0; itr<nTr; itr++ ){
8804 //if( itr!=97 ) continue;
8805 const AliExternalTrackParam *param = hltEvent->GetTrack(itr)->GetTPCInnerParam();
8806 if( !param ) continue;
8807 //if( TMath::Abs(esdTr->GetSigned1Pt())>1 ) continue;
8808 //if( TMath::Abs(esdTr->GetTgl())>1. ) continue;
8809 AliTPCtrack tr;
8810 tr.Set(param->GetX(),param->GetAlpha(),param->GetParameter(),param->GetCovariance());
8811 tr.SetNumberOfClusters(0);
8812 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed(tr);
8813
8814 Double_t alpha=seed->GetAlpha();// - fSectors->GetAlphaShift();
8815 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
8816 if (alpha < 0. ) alpha += 2.*TMath::Pi();
8817 //
8818 seed->SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
8819 Double_t alphaSec = fSectors->GetAlpha() * seed->GetRelativeSector() + fSectors->GetAlphaShift();
8820
8821 if (alphaSec >= TMath::Pi()) alphaSec -= 2.*TMath::Pi();
8822 if (alphaSec < -TMath::Pi()) alphaSec += 2.*TMath::Pi();
8823
8824 seed->Rotate(alphaSec - alpha);
8825
8826 seed->SetPoolID(fLastSeedID);
8827 seed->SetIsSeeding(kTRUE);
8828 seed->SetSeed1(nup-1);
8829 seed->SetSeed2(nup-2);
8830 seed->SetSeedType(0);
8831 seed->SetFirstPoint(-1);
8832 seed->SetLastPoint(-1);
8833 seeds->AddLast(seed); // note, track is seed, don't free the seed
8834 index++;
8835 //if( index>3 ) break;
8836 }
8837
8838
8839 fSectors = fOuterSec;
8840
8841 TrackFollowingHLT(seeds );
8842
8843 nTr = seeds->GetEntriesFast();
8844 for( int itr=0; itr<nTr; itr++ ){
8845 AliTPCseed * seed = (AliTPCseed*) seeds->UncheckedAt(itr);
8846 if( !seed ) continue;
8847 //FollowBackProlongation(*seed,0);
8848 // cout<<seed->GetNumberOfClusters()<<endl;
8849 Int_t foundable,found,shared;
8850 seed->GetClusterStatistic(0,nup, found, foundable, shared, kTRUE);
8851 seed->SetNFoundable(foundable);
8852 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8853 //if ((found<0.55*foundable) || shared>0.5*found ){// || (seed->GetSigmaY2()+seed->GetSigmaZ2())>0.5){
8854 //MarkSeedFree(seeds->RemoveAt(itr));
8855 //continue;
8856 //}
8857 if (seed->GetNumberOfClusters()<30 ||
8858 seed->GetNumberOfClusters() < seed->GetNFoundable()*0.6 ||
8859 seed->GetNShared()>0.4*seed->GetNumberOfClusters() ) {
8860 MarkSeedFree(seeds->RemoveAt(itr));
8861 continue;
8862 }
8863
8864 for( int ir=0; ir<nup; ir++){
8865 AliTPCclusterMI *c = seed->GetClusterPointer(ir);
8866 if( c ) c->Use(10);
8867 }
8868 }
492a4365 8869 std::cout<<"\n\nHLT tracks left: "<<seeds->GetEntries()<<" out of "<<hltEvent->GetNumberOfTracks()<<endl<<endl;
72e25240 8870 return seeds;
8871}
5576d489 8872
8873void AliTPCtracker::FillClusterOccupancyInfo()
8874{
8875 //fill the cluster occupancy info into the ESD friend
8876 AliESDfriend* esdFriend = static_cast<AliESDfriend*>(fEvent->FindListObject("AliESDfriend"));
8877 if (!esdFriend) return;
8878
8879 for (Int_t isector=0; isector<18; isector++){
8880 AliTPCtrackerSector &iroc = fInnerSec[isector];
8881 AliTPCtrackerSector &oroc = fOuterSec[isector];
8882 //all clusters
8883 esdFriend->SetNclustersTPC(isector, iroc.GetNClInSector(0));
8884 esdFriend->SetNclustersTPC(isector+18,iroc.GetNClInSector(1));
8885 esdFriend->SetNclustersTPC(isector+36,oroc.GetNClInSector(0));
8886 esdFriend->SetNclustersTPC(isector+54,oroc.GetNClInSector(1));
8887 //clusters used in tracking
8888 esdFriend->SetNclustersTPCused(isector, iroc.GetNClUsedInSector(0));
8889 esdFriend->SetNclustersTPCused(isector+18, iroc.GetNClUsedInSector(1));
8890 esdFriend->SetNclustersTPCused(isector+36, oroc.GetNClUsedInSector(0));
8891 esdFriend->SetNclustersTPCused(isector+54, oroc.GetNClUsedInSector(1));
8892 }
8893}