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