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