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