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