]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/AliTPCtrackerMI.cxx
Removing files committed by mistake
[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++){
75fb37cc 1180 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
0201b65c 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
75fb37cc 1244void AliTPCtrackerMI::Transform(AliTPCclusterMI * cluster){
0201b65c 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 }
75fb37cc 1257 //cluster->SetX(posC[0]);
1258 //cluster->SetY(posC[1]);
1259 //cluster->SetZ(posC[2]);
0201b65c 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++;
31fd97b2 2716 Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
2717 // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
ca142b1f 2718 (*fDebugStreamer)<<"Cback"<<
2719 "Tr0.="<<seed<<
31fd97b2 2720 "EventNrInFile="<<eventnumber<<
ca142b1f 2721 "\n"; // patch 28 fev 06
4d158c36 2722 }
91162307 2723 }
51ad6848 2724 //FindKinks(fSeeds,event);
4d158c36 2725 Info("PropagateBack","Number of back propagated tracks %d",ntracks);
91162307 2726 fEvent =0;
d26d9159 2727 //WriteTracks();
6c94f330 2728
91162307 2729 return 0;
2730}
2731
2732
2733void AliTPCtrackerMI::DeleteSeeds()
2734{
b67e07dc 2735 //
2736 //delete Seeds
6c94f330 2737
91162307 2738 Int_t nseed = fSeeds->GetEntriesFast();
2739 for (Int_t i=0;i<nseed;i++){
2740 AliTPCseed * seed = (AliTPCseed*)fSeeds->At(i);
2741 if (seed) delete fSeeds->RemoveAt(i);
2742 }
2743 delete fSeeds;
6c94f330 2744
91162307 2745 fSeeds =0;
2746}
2747
d26d9159 2748void AliTPCtrackerMI::ReadSeeds(AliESD *event, Int_t direction)
91162307 2749{
2750 //
2751 //read seeds from the event
2752
2753 Int_t nentr=event->GetNumberOfTracks();
6bdc18d6 2754 if (fDebug>0){
2755 Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
2756 }
91162307 2757 if (fSeeds)
2758 DeleteSeeds();
2759 if (!fSeeds){
4d158c36 2760 fSeeds = new TObjArray(nentr);
91162307 2761 }
4d158c36 2762 UnsignClusters();
2763 // Int_t ntrk=0;
91162307 2764 for (Int_t i=0; i<nentr; i++) {
2765 AliESDtrack *esd=event->GetTrack(i);
51ad6848 2766 ULong_t status=esd->GetStatus();
2767 if (!(status&AliESDtrack::kTPCin)) continue;
b67e07dc 2768 AliTPCtrack t(*esd);
5d837844 2769 t.SetNumberOfClusters(0);
eea478d3 2770 // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
2771 AliTPCseed *seed = new AliTPCseed(t/*,t.GetAlpha()*/);
2772 for (Int_t ikink=0;ikink<3;ikink++) {
2773 Int_t index = esd->GetKinkIndex(ikink);
2774 seed->GetKinkIndexes()[ikink] = index;
2775 if (index==0) continue;
2776 index = TMath::Abs(index);
2777 AliESDkink * kink = fEvent->GetKink(index-1);
2778 if (kink&&esd->GetKinkIndex(ikink)<0){
2779 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
2780 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,0);
2781 }
2782 if (kink&&esd->GetKinkIndex(ikink)>0){
2783 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
2784 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,4);
2785 }
2786
2787 }
6c94f330 2788 if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.);
2789 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
4d158c36 2790 if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
2791 fSeeds->AddAt(0,i);
2792 delete seed;
2793 continue;
2794 }
2795 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) > 0 ) {
c0b978f0 2796 Double_t par0[5],par1[5],alpha,x;
2797 esd->GetInnerExternalParameters(alpha,x,par0);
4d158c36 2798 esd->GetExternalParameters(x,par1);
2799 Double_t delta1 = TMath::Abs(par0[4]-par1[4])/(0.000000001+TMath::Abs(par0[4]+par1[4]));
2800 Double_t delta2 = TMath::Abs(par0[3]-par1[3]);
51ad6848 2801 Double_t trdchi2=0;
2802 if (esd->GetTRDncls()>0) trdchi2 = esd->GetTRDchi2()/esd->GetTRDncls();
4d158c36 2803 //reset covariance if suspicious
51ad6848 2804 if ( (delta1>0.1) || (delta2>0.006) ||trdchi2>7.)
6c94f330 2805 seed->ResetCovariance(10.);
4d158c36 2806 }
982aff31 2807
91162307 2808 //
2809 //
2810 // rotate to the local coordinate system
eea478d3 2811 //
2812 fSectors=fInnerSec; fN=fkNIS;
91162307 2813 Double_t alpha=seed->GetAlpha() - fSectors->GetAlphaShift();
2814 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2815 if (alpha < 0. ) alpha += 2.*TMath::Pi();
2816 Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN;
2817 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
4d158c36 2818 if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
2819 if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
91162307 2820 alpha-=seed->GetAlpha();
d9b8978b 2821 if (!seed->Rotate(alpha)) {
2822 delete seed;
2823 continue;
2824 }
b9671574 2825 seed->SetESD(esd);
4d158c36 2826 // sign clusters
b406fdb0 2827 if (esd->GetKinkIndex(0)<=0){
2828 for (Int_t irow=0;irow<160;irow++){
2829 Int_t index = seed->GetClusterIndex2(irow);
2830 if (index>0){
2831 //
2832 AliTPCclusterMI * cl = GetClusterMI(index);
b9671574 2833 seed->SetClusterPointer(irow,cl);
b406fdb0 2834 if (cl){
2835 if ((index & 0x8000)==0){
2836 cl->Use(10); // accepted cluster
2837 }else{
2838 cl->Use(6); // close cluster not accepted
2839 }
4d158c36 2840 }else{
b406fdb0 2841 Info("ReadSeeds","Not found cluster");
2842 }
4d158c36 2843 }
2844 }
2845 }
2846 fSeeds->AddAt(seed,i);
91162307 2847 }
2848}
2849
2850
2851
2852//_____________________________________________________________________________
2853void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
2854 Float_t deltay, Int_t ddsec) {
2855 //-----------------------------------------------------------------
2856 // This function creates track seeds.
2857 // SEEDING WITH VERTEX CONSTRAIN
2858 //-----------------------------------------------------------------
2859 // cuts[0] - fP4 cut
2860 // cuts[1] - tan(phi) cut
2861 // cuts[2] - zvertex cut
2862 // cuts[3] - fP3 cut
2863 Int_t nin0 = 0;
2864 Int_t nin1 = 0;
2865 Int_t nin2 = 0;
2866 Int_t nin = 0;
2867 Int_t nout1 = 0;
2868 Int_t nout2 = 0;
2869
2870 Double_t x[5], c[15];
2871 // Int_t di = i1-i2;
2872 //
2873 AliTPCseed * seed = new AliTPCseed;
2874 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
2875 Double_t cs=cos(alpha), sn=sin(alpha);
2876 //
2877 // Double_t x1 =fOuterSec->GetX(i1);
2878 //Double_t xx2=fOuterSec->GetX(i2);
2879
2880 Double_t x1 =GetXrow(i1);
2881 Double_t xx2=GetXrow(i2);
2882
2883 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
2884
2885 Int_t imiddle = (i2+i1)/2; //middle pad row index
2886 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
2887 const AliTPCRow& krm=GetRow(sec,imiddle); //middle pad -row
2888 //
2889 Int_t ns =sec;
2890
2891 const AliTPCRow& kr1=GetRow(ns,i1);
b9671574 2892 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
2893 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
91162307 2894
2895 //
2896 // change cut on curvature if it can't reach this layer
2897 // maximal curvature set to reach it
2898 Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
2899 if (dvertexmax*0.5*cuts[0]>0.85){
2900 cuts[0] = 0.85/(dvertexmax*0.5+1.);
2901 }
2902 Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
2903
2904 // Int_t ddsec = 1;
2905 if (deltay>0) ddsec = 0;
2906 // loop over clusters
2907 for (Int_t is=0; is < kr1; is++) {
2908 //
2909 if (kr1[is]->IsUsed(10)) continue;
2910 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
2911 //if (TMath::Abs(y1)>ymax) continue;
2912
2913 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
2914
2915 // find possible directions
2916 Float_t anglez = (z1-z3)/(x1-x3);
2917 Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
2918 //
2919 //
2920 //find rotation angles relative to line given by vertex and point 1
2921 Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
2922 Double_t dvertex = TMath::Sqrt(dvertex2);
2923 Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
2924 Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
2925
2926 //
2927 // loop over 2 sectors
2928 Int_t dsec1=-ddsec;
2929 Int_t dsec2= ddsec;
2930 if (y1<0) dsec2= 0;
2931 if (y1>0) dsec1= 0;
2932
2933 Double_t dddz1=0; // direction of delta inclination in z axis
2934 Double_t dddz2=0;
2935 if ( (z1-z3)>0)
2936 dddz1 =1;
2937 else
2938 dddz2 =1;
2939 //
2940 for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
2941 Int_t sec2 = sec + dsec;
2942 //
2943 // AliTPCRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
2944 //AliTPCRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
2945 AliTPCRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
2946 AliTPCRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
2947 Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
2948 Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
2949
2950 // rotation angles to p1-p3
2951 Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
2952 Double_t x2, y2, z2;
2953 //
2954 // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
2955
2956 //
2957 Double_t dxx0 = (xx2-x3)*cs13r;
2958 Double_t dyy0 = (xx2-x3)*sn13r;
2959 for (Int_t js=index1; js < index2; js++) {
2960 const AliTPCclusterMI *kcl = kr2[js];
2961 if (kcl->IsUsed(10)) continue;
2962 //
2963 //calcutate parameters
2964 //
2965 Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
2966 // stright track
2967 if (TMath::Abs(yy0)<0.000001) continue;
2968 Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
2969 Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
2970 Double_t r02 = (0.25+y0*y0)*dvertex2;
2971 //curvature (radius) cut
2972 if (r02<r2min) continue;
2973
2974 nin0++;
2975 //
2976 Double_t c0 = 1/TMath::Sqrt(r02);
2977 if (yy0>0) c0*=-1.;
2978
2979
2980 //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
2981 //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
b67e07dc 2982 Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
2983 Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
91162307 2984 //
2985 //
2986 Double_t z0 = kcl->GetZ();
2987 Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
2988 if (TMath::Abs(zzzz2-z0)>0.5) continue;
2989 nin1++;
2990 //
2991 Double_t dip = (z1-z0)*c0/dfi1;
2992 Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
2993 //
2994 y2 = kcl->GetY();
2995 if (dsec==0){
2996 x2 = xx2;
2997 z2 = kcl->GetZ();
2998 }
2999 else
3000 {
3001 // rotation
3002 z2 = kcl->GetZ();
3003 x2= xx2*cs-y2*sn*dsec;
3004 y2=+xx2*sn*dsec+y2*cs;
3005 }
3006
3007 x[0] = y1;
3008 x[1] = z1;
3009 x[2] = x0;
3010 x[3] = dip;
3011 x[4] = c0;
3012 //
3013 //
3014 // do we have cluster at the middle ?
3015 Double_t ym,zm;
3016 GetProlongation(x1,xm,x,ym,zm);
3017 UInt_t dummy;
3018 AliTPCclusterMI * cm=0;
3019 if (TMath::Abs(ym)-ymaxm<0){
3020 cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3021 if ((!cm) || (cm->IsUsed(10))) {
3022 continue;
3023 }
3024 }
3025 else{
3026 // rotate y1 to system 0
3027 // get state vector in rotated system
3028 Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
3029 Double_t xr2 = x0*cs+yr1*sn*dsec;
3030 Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3031 //
3032 GetProlongation(xx2,xm,xr,ym,zm);
3033 if (TMath::Abs(ym)-ymaxm<0){
3034 cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3035 if ((!cm) || (cm->IsUsed(10))) {
3036 continue;
3037 }
3038 }
3039 }
3040
3041
3042 Double_t dym = 0;
3043 Double_t dzm = 0;
3044 if (cm){
3045 dym = ym - cm->GetY();
3046 dzm = zm - cm->GetZ();
3047 }
3048 nin2++;
3049
3050
3051 //
3052 //
3053 Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
3054 Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
3055 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
3056 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3057 //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
3058
b67e07dc 3059 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3060 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3061 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3062 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3063 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3064 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
91162307 3065
b67e07dc 3066 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3067 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3068 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3069 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
91162307 3070
1c53abe2 3071 c[0]=sy1;
3072 c[1]=0.; c[2]=sz1;
3073 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3074 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3075 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3076 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3077 c[13]=f30*sy1*f40+f32*sy2*f42;
3078 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
91162307 3079
3080 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3081
1c53abe2 3082 UInt_t index=kr1.GetIndex(is);
6c94f330 3083 AliTPCseed *track=new(seed) AliTPCseed(x1, ns*alpha+shift, x, c, index);
91162307 3084
b9671574 3085 track->SetIsSeeding(kTRUE);
3086 track->SetSeed1(i1);
3087 track->SetSeed2(i2);
3088 track->SetSeedType(3);
c9427e08 3089
91162307 3090
3091 //if (dsec==0) {
3092 FollowProlongation(*track, (i1+i2)/2,1);
3093 Int_t foundable,found,shared;
3094 track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
3095 if ((found<0.55*foundable) || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
3096 seed->Reset();
3097 seed->~AliTPCseed();
3098 continue;
3099 }
3100 //}
3101
3102 nin++;
3103 FollowProlongation(*track, i2,1);
3104
3105
3106 //Int_t rc = 1;
b9671574 3107 track->SetBConstrain(1);
91162307 3108 // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
b9671574 3109 track->SetLastPoint(i1); // first cluster in track position
3110 track->SetFirstPoint(track->GetLastPoint());
91162307 3111
3112 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 3113 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3114 track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
91162307 3115 seed->Reset();
3116 seed->~AliTPCseed();
c9427e08 3117 continue;
3118 }
91162307 3119 nout1++;
3120 // Z VERTEX CONDITION
c274e255 3121 Double_t zv, bz=GetBz();
3122 if ( !track->GetZAt(0.,bz,zv) ) continue;
91162307 3123 if (TMath::Abs(zv-z3)>cuts[2]) {
3124 FollowProlongation(*track, TMath::Max(i2-20,0));
c274e255 3125 if ( !track->GetZAt(0.,bz,zv) ) continue;
91162307 3126 if (TMath::Abs(zv-z3)>cuts[2]){
3127 FollowProlongation(*track, TMath::Max(i2-40,0));
c274e255 3128 if ( !track->GetZAt(0.,bz,zv) ) continue;
b9671574 3129 if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
91162307 3130 // make seed without constrain
3131 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
3132 FollowProlongation(*track2, i2,1);
b9671574 3133 track2->SetBConstrain(kFALSE);
3134 track2->SetSeedType(1);
91162307 3135 arr->AddLast(track2);
3136 seed->Reset();
3137 seed->~AliTPCseed();
3138 continue;
3139 }
3140 else{
3141 seed->Reset();
3142 seed->~AliTPCseed();
3143 continue;
3144
3145 }
3146 }
c9427e08 3147 }
1c53abe2 3148
b9671574 3149 track->SetSeedType(0);
91162307 3150 arr->AddLast(track);
3151 seed = new AliTPCseed;
3152 nout2++;
3153 // don't consider other combinations
b9671574 3154 if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
91162307 3155 break;
1c53abe2 3156 }
3157 }
3158 }
6bdc18d6 3159 if (fDebug>3){
3160 Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
91162307 3161 }
3162 delete seed;
1c53abe2 3163}
3164
1627d1c4 3165
91162307 3166void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
3167 Float_t deltay) {
3168
3169
3170
1627d1c4 3171 //-----------------------------------------------------------------
91162307 3172 // This function creates track seeds.
1627d1c4 3173 //-----------------------------------------------------------------
91162307 3174 // cuts[0] - fP4 cut
3175 // cuts[1] - tan(phi) cut
3176 // cuts[2] - zvertex cut
3177 // cuts[3] - fP3 cut
3178
3179
3180 Int_t nin0 = 0;
3181 Int_t nin1 = 0;
3182 Int_t nin2 = 0;
3183 Int_t nin = 0;
3184 Int_t nout1 = 0;
3185 Int_t nout2 = 0;
3186 Int_t nout3 =0;
3187 Double_t x[5], c[15];
3188 //
3189 // make temporary seed
3190 AliTPCseed * seed = new AliTPCseed;
1627d1c4 3191 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3192 // Double_t cs=cos(alpha), sn=sin(alpha);
91162307 3193 //
3194 //
1627d1c4 3195
91162307 3196 // first 3 padrows
3197 Double_t x1 = GetXrow(i1-1);
3198 const AliTPCRow& kr1=GetRow(sec,i1-1);
b9671574 3199 Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
91162307 3200 //
3201 Double_t x1p = GetXrow(i1);
3202 const AliTPCRow& kr1p=GetRow(sec,i1);
3203 //
3204 Double_t x1m = GetXrow(i1-2);
3205 const AliTPCRow& kr1m=GetRow(sec,i1-2);
1627d1c4 3206
91162307 3207 //
3208 //last 3 padrow for seeding
3209 AliTPCRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
3210 Double_t x3 = GetXrow(i1-7);
3211 // Double_t y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;
3212 //
3213 AliTPCRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
3214 Double_t x3p = GetXrow(i1-6);
3215 //
3216 AliTPCRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
3217 Double_t x3m = GetXrow(i1-8);
1627d1c4 3218
91162307 3219 //
3220 //
3221 // middle padrow
3222 Int_t im = i1-4; //middle pad row index
3223 Double_t xm = GetXrow(im); // radius of middle pad-row
3224 const AliTPCRow& krm=GetRow(sec,im); //middle pad -row
3225 // Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;
3226 //
3227 //
3228 Double_t deltax = x1-x3;
3229 Double_t dymax = deltax*cuts[1];
3230 Double_t dzmax = deltax*cuts[3];
3231 //
3232 // loop over clusters
3233 for (Int_t is=0; is < kr1; is++) {
1627d1c4 3234 //
91162307 3235 if (kr1[is]->IsUsed(10)) continue;
3236 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
1627d1c4 3237 //
91162307 3238 if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3239 //
3240 Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
3241 Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
3242 //
3243 Double_t y3, z3;
1627d1c4 3244 //
1627d1c4 3245 //
91162307 3246 UInt_t index;
3247 for (Int_t js=index1; js < index2; js++) {
3248 const AliTPCclusterMI *kcl = kr3[js];
3249 if (kcl->IsUsed(10)) continue;
3250 y3 = kcl->GetY();
3251 // apply angular cuts
3252 if (TMath::Abs(y1-y3)>dymax) continue;
3253 x3 = x3;
3254 z3 = kcl->GetZ();
3255 if (TMath::Abs(z1-z3)>dzmax) continue;
3256 //
3257 Double_t angley = (y1-y3)/(x1-x3);
3258 Double_t anglez = (z1-z3)/(x1-x3);
3259 //
3260 Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
3261 Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
3262 //
3263 Double_t yyym = angley*(xm-x1)+y1;
3264 Double_t zzzm = anglez*(xm-x1)+z1;
3265
3266 const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
3267 if (!kcm) continue;
3268 if (kcm->IsUsed(10)) continue;
3269
3270 erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
3271 errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
3272 //
3273 //
3274 //
3275 Int_t used =0;
3276 Int_t found =0;
3277 //
3278 // look around first
3279 const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
3280 anglez*(x1m-x1)+z1,
3281 erry,errz,index);
3282 //
3283 if (kc1m){
3284 found++;
3285 if (kc1m->IsUsed(10)) used++;
1627d1c4 3286 }
91162307 3287 const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
3288 anglez*(x1p-x1)+z1,
3289 erry,errz,index);
1627d1c4 3290 //
91162307 3291 if (kc1p){
3292 found++;
3293 if (kc1p->IsUsed(10)) used++;
1627d1c4 3294 }
91162307 3295 if (used>1) continue;
3296 if (found<1) continue;
1627d1c4 3297
91162307 3298 //
3299 // look around last
3300 const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
3301 anglez*(x3m-x3)+z3,
3302 erry,errz,index);
3303 //
3304 if (kc3m){
3305 found++;
3306 if (kc3m->IsUsed(10)) used++;
3307 }
3308 else
3309 continue;
3310 const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
3311 anglez*(x3p-x3)+z3,
3312 erry,errz,index);
3313 //
3314 if (kc3p){
3315 found++;
3316 if (kc3p->IsUsed(10)) used++;
3317 }
3318 else
3319 continue;
3320 if (used>1) continue;
3321 if (found<3) continue;
3322 //
3323 Double_t x2,y2,z2;
3324 x2 = xm;
3325 y2 = kcm->GetY();
3326 z2 = kcm->GetZ();
3327 //
3328
1627d1c4 3329 x[0]=y1;
3330 x[1]=z1;
b67e07dc 3331 x[4]=F1(x1,y1,x2,y2,x3,y3);
91162307 3332 //if (TMath::Abs(x[4]) >= cuts[0]) continue;
3333 nin0++;
3334 //
b67e07dc 3335 x[2]=F2(x1,y1,x2,y2,x3,y3);
91162307 3336 nin1++;
3337 //
b67e07dc 3338 x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
91162307 3339 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3340 nin2++;
3341 //
3342 //
3343 Double_t sy1=0.1, sz1=0.1;
3344 Double_t sy2=0.1, sz2=0.1;
3345 Double_t sy3=0.1, sy=0.1, sz=0.1;
1627d1c4 3346
b67e07dc 3347 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3348 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3349 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3350 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3351 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3352 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
91162307 3353
b67e07dc 3354 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3355 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3356 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3357 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
1627d1c4 3358
3359 c[0]=sy1;
91162307 3360 c[1]=0.; c[2]=sz1;
1627d1c4 3361 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3362 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3363 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3364 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3365 c[13]=f30*sy1*f40+f32*sy2*f42;
3366 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3367
91162307 3368 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3369
3370 UInt_t index=kr1.GetIndex(is);
6c94f330 3371 AliTPCseed *track=new(seed) AliTPCseed(x1, sec*alpha+shift, x, c, index);
91162307 3372
b9671574 3373 track->SetIsSeeding(kTRUE);
91162307 3374
3375 nin++;
3376 FollowProlongation(*track, i1-7,1);
b9671574 3377 if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
3378 track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
91162307 3379 seed->Reset();
3380 seed->~AliTPCseed();
3381 continue;
3382 }
3383 nout1++;
3384 nout2++;
3385 //Int_t rc = 1;
3386 FollowProlongation(*track, i2,1);
b9671574 3387 track->SetBConstrain(0);
3388 track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
3389 track->SetFirstPoint(track->GetLastPoint());
91162307 3390
3391 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 3392 track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
3393 track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
91162307 3394 seed->Reset();
3395 seed->~AliTPCseed();
3396 continue;
3397 }
3398
3399 {
3400 FollowProlongation(*track, TMath::Max(i2-10,0),1);
3401 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
3402 FollowProlongation(*track2, i2,1);
b9671574 3403 track2->SetBConstrain(kFALSE);
3404 track2->SetSeedType(4);
91162307 3405 arr->AddLast(track2);
3406 seed->Reset();
3407 seed->~AliTPCseed();
3408 }
3409
3410
3411 //arr->AddLast(track);
3412 //seed = new AliTPCseed;
3413 nout3++;
3414 }
3415 }
3416
6bdc18d6 3417 if (fDebug>3){
3418 Info("MakeSeeds5","\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
91162307 3419 }
3420 delete seed;
3421}
3422
3423
3424//_____________________________________________________________________________
176aff27 3425void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
3426 Float_t deltay, Bool_t /*bconstrain*/) {
91162307 3427 //-----------------------------------------------------------------
3428 // This function creates track seeds - without vertex constraint
3429 //-----------------------------------------------------------------
3430 // cuts[0] - fP4 cut - not applied
3431 // cuts[1] - tan(phi) cut
3432 // cuts[2] - zvertex cut - not applied
3433 // cuts[3] - fP3 cut
3434 Int_t nin0=0;
3435 Int_t nin1=0;
3436 Int_t nin2=0;
3437 Int_t nin3=0;
3438 // Int_t nin4=0;
3439 //Int_t nin5=0;
3440
3441
3442
3443 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3444 // Double_t cs=cos(alpha), sn=sin(alpha);
3445 Int_t row0 = (i1+i2)/2;
3446 Int_t drow = (i1-i2)/2;
3447 const AliTPCRow& kr0=fSectors[sec][row0];
3448 AliTPCRow * kr=0;
3449
3450 AliTPCpolyTrack polytrack;
3451 Int_t nclusters=fSectors[sec][row0];
3452 AliTPCseed * seed = new AliTPCseed;
3453
3454 Int_t sumused=0;
3455 Int_t cused=0;
3456 Int_t cnused=0;
3457 for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
3458 Int_t nfound =0;
3459 Int_t nfoundable =0;
3460 for (Int_t iter =1; iter<2; iter++){ //iterations
3461 const AliTPCRow& krm=fSectors[sec][row0-iter];
3462 const AliTPCRow& krp=fSectors[sec][row0+iter];
3463 const AliTPCclusterMI * cl= kr0[is];
3464
3465 if (cl->IsUsed(10)) {
3466 cused++;
3467 }
3468 else{
3469 cnused++;
3470 }
3471 Double_t x = kr0.GetX();
3472 // Initialization of the polytrack
3473 nfound =0;
3474 nfoundable =0;
3475 polytrack.Reset();
3476 //
3477 Double_t y0= cl->GetY();
3478 Double_t z0= cl->GetZ();
3479 Float_t erry = 0;
3480 Float_t errz = 0;
3481
b9671574 3482 Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
91162307 3483 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
3484
3485 erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
3486 errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
3487 polytrack.AddPoint(x,y0,z0,erry, errz);
3488
3489 sumused=0;
3490 if (cl->IsUsed(10)) sumused++;
3491
3492
3493 Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
3494 Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
3495 //
3496 x = krm.GetX();
3497 AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
3498 if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
3499 erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
3500 errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
3501 if (cl1->IsUsed(10)) sumused++;
3502 polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
3503 }
3504 //
3505 x = krp.GetX();
3506 AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
3507 if (cl2) {
3508 erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
3509 errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
3510 if (cl2->IsUsed(10)) sumused++;
3511 polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
3512 }
3513 //
3514 if (sumused>0) continue;
3515 nin0++;
3516 polytrack.UpdateParameters();
3517 // follow polytrack
3518 roadz = 1.2;
3519 roady = 1.2;
3520 //
3521 Double_t yn,zn;
3522 nfoundable = polytrack.GetN();
3523 nfound = nfoundable;
3524 //
3525 for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
3526 Float_t maxdist = 0.8*(1.+3./(ddrow));
3527 for (Int_t delta = -1;delta<=1;delta+=2){
3528 Int_t row = row0+ddrow*delta;
3529 kr = &(fSectors[sec][row]);
3530 Double_t xn = kr->GetX();
b9671574 3531 Double_t ymax = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
91162307 3532 polytrack.GetFitPoint(xn,yn,zn);
3533 if (TMath::Abs(yn)>ymax) continue;
3534 nfoundable++;
3535 AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
3536 if (cln) {
3537 Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
3538 if (dist<maxdist){
3539 /*
3540 erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3541 errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3542 if (cln->IsUsed(10)) {
3543 // printf("used\n");
3544 sumused++;
3545 erry*=2;
3546 errz*=2;
3547 }
3548 */
3549 erry=0.1;
3550 errz=0.1;
3551 polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
3552 nfound++;
3553 }
3554 }
3555 }
3556 if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
3557 polytrack.UpdateParameters();
3558 }
3559 }
3560 if ( (sumused>3) || (sumused>0.5*nfound)) {
3561 //printf("sumused %d\n",sumused);
3562 continue;
3563 }
3564 nin1++;
3565 Double_t dy,dz;
3566 polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
3567 AliTPCpolyTrack track2;
3568
3569 polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
3570 if (track2.GetN()<0.5*nfoundable) continue;
3571 nin2++;
3572
3573 if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
3574 //
3575 // test seed with and without constrain
3576 for (Int_t constrain=0; constrain<=0;constrain++){
3577 // add polytrack candidate
3578
3579 Double_t x[5], c[15];
3580 Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
3581 track2.GetBoundaries(x3,x1);
3582 x2 = (x1+x3)/2.;
3583 track2.GetFitPoint(x1,y1,z1);
3584 track2.GetFitPoint(x2,y2,z2);
3585 track2.GetFitPoint(x3,y3,z3);
3586 //
3587 //is track pointing to the vertex ?
3588 Double_t x0,y0,z0;
3589 x0=0;
3590 polytrack.GetFitPoint(x0,y0,z0);
3591
3592 if (constrain) {
3593 x2 = x3;
3594 y2 = y3;
3595 z2 = z3;
3596
3597 x3 = 0;
3598 y3 = 0;
3599 z3 = 0;
3600 }
3601 x[0]=y1;
3602 x[1]=z1;
b67e07dc 3603 x[4]=F1(x1,y1,x2,y2,x3,y3);
91162307 3604
3605 // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
b67e07dc 3606 x[2]=F2(x1,y1,x2,y2,x3,y3);
91162307 3607
3608 //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
b67e07dc 3609 //x[3]=F3(x1,y1,x2,y2,z1,z2);
3610 x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
91162307 3611 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3612
3613
3614 Double_t sy =0.1, sz =0.1;
3615 Double_t sy1=0.02, sz1=0.02;
3616 Double_t sy2=0.02, sz2=0.02;
3617 Double_t sy3=0.02;
3618
3619 if (constrain){
3620 sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3621 }
3622
b67e07dc 3623 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3624 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3625 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3626 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3627 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3628 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3629
3630 Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
3631 Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
3632 Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
3633 Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
91162307 3634
3635
3636 c[0]=sy1;
3637 c[1]=0.; c[2]=sz1;
3638 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3639 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3640 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3641 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3642 c[13]=f30*sy1*f40+f32*sy2*f42;
3643 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3644
3645 //Int_t row1 = fSectors->GetRowNumber(x1);
3646 Int_t row1 = GetRowNumber(x1);
3647
3648 UInt_t index=0;
3649 //kr0.GetIndex(is);
6c94f330 3650 AliTPCseed *track=new (seed) AliTPCseed(x1,sec*alpha+shift,x,c,index);
b9671574 3651 track->SetIsSeeding(kTRUE);
91162307 3652 Int_t rc=FollowProlongation(*track, i2);
b9671574 3653 if (constrain) track->SetBConstrain(1);
91162307 3654 else
b9671574 3655 track->SetBConstrain(0);
3656 track->SetLastPoint(row1+fInnerSec->GetNRows()); // first cluster in track position
3657 track->SetFirstPoint(track->GetLastPoint());
91162307 3658
3659 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
b9671574 3660 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3661 track->GetNShared()>0.4*track->GetNumberOfClusters()) {
91162307 3662 //delete track;
3663 seed->Reset();
3664 seed->~AliTPCseed();
3665 }
3666 else {
3667 arr->AddLast(track);
3668 seed = new AliTPCseed;
3669 }
3670 nin3++;
3671 }
3672 } // if accepted seed
3673 }
6bdc18d6 3674 if (fDebug>3){
3675 Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
91162307 3676 }
3677 delete seed;
3678}
3679
3680
3681AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
3682{
3683 //
3684 //
d26d9159 3685 //reseed using track points
91162307 3686 Int_t p0 = int(r0*track->GetNumberOfClusters()); // point 0
3687 Int_t p1 = int(r1*track->GetNumberOfClusters());
3688 Int_t p2 = int(r2*track->GetNumberOfClusters()); // last point
176aff27 3689 Int_t pp2=0;
91162307 3690 Double_t x0[3],x1[3],x2[3];
89e09524 3691 for (Int_t i=0;i<3;i++){
3692 x0[i]=-1;
3693 x1[i]=-1;
3694 x2[i]=-1;
3695 }
91162307 3696
3697 // find track position at given ratio of the length
89e09524 3698 Int_t sec0=0, sec1=0, sec2=0;
91162307 3699 Int_t index=-1;
3700 Int_t clindex;
3701 for (Int_t i=0;i<160;i++){
b9671574 3702 if (track->GetClusterPointer(i)){
91162307 3703 index++;
3704 AliTPCTrackerPoint *trpoint =track->GetTrackPoint(i);
3705 if ( (index<p0) || x0[0]<0 ){
3706 if (trpoint->GetX()>1){
3707 clindex = track->GetClusterIndex2(i);
3708 if (clindex>0){
3709 x0[0] = trpoint->GetX();
3710 x0[1] = trpoint->GetY();
3711 x0[2] = trpoint->GetZ();
3712 sec0 = ((clindex&0xff000000)>>24)%18;
3713 }
3714 }
3715 }
3716
3717 if ( (index<p1) &&(trpoint->GetX()>1)){
3718 clindex = track->GetClusterIndex2(i);
3719 if (clindex>0){
3720 x1[0] = trpoint->GetX();
3721 x1[1] = trpoint->GetY();
3722 x1[2] = trpoint->GetZ();
3723 sec1 = ((clindex&0xff000000)>>24)%18;
3724 }
3725 }
3726 if ( (index<p2) &&(trpoint->GetX()>1)){
3727 clindex = track->GetClusterIndex2(i);
3728 if (clindex>0){
3729 x2[0] = trpoint->GetX();
3730 x2[1] = trpoint->GetY();
3731 x2[2] = trpoint->GetZ();
3732 sec2 = ((clindex&0xff000000)>>24)%18;
3733 pp2 = i;
3734 }
3735 }
3736 }
3737 }
3738
3739 Double_t alpha, cs,sn, xx2,yy2;
3740 //
3741 alpha = (sec1-sec2)*fSectors->GetAlpha();
3742 cs = TMath::Cos(alpha);
3743 sn = TMath::Sin(alpha);
3744 xx2= x1[0]*cs-x1[1]*sn;
3745 yy2= x1[0]*sn+x1[1]*cs;
3746 x1[0] = xx2;
3747 x1[1] = yy2;
3748 //
3749 alpha = (sec0-sec2)*fSectors->GetAlpha();
3750 cs = TMath::Cos(alpha);
3751 sn = TMath::Sin(alpha);
3752 xx2= x0[0]*cs-x0[1]*sn;
3753 yy2= x0[0]*sn+x0[1]*cs;
3754 x0[0] = xx2;
3755 x0[1] = yy2;
3756 //
3757 //
3758 //
3759 Double_t x[5],c[15];
3760 //
3761 x[0]=x2[1];
3762 x[1]=x2[2];
b67e07dc 3763 x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
91162307 3764 // if (x[4]>1) return 0;
b67e07dc 3765 x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
3766 x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
91162307 3767 //if (TMath::Abs(x[3]) > 2.2) return 0;
3768 //if (TMath::Abs(x[2]) > 1.99) return 0;
3769 //
3770 Double_t sy =0.1, sz =0.1;
3771 //
3772 Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
3773 Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
3774 Double_t sy3=0.01+track->GetSigmaY2();
3775 //
b67e07dc 3776 Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
3777 Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
3778 Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
3779 Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
3780 Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
3781 Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
3782 //
3783 Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
3784 Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
3785 Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
3786 Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
91162307 3787
3788
3789 c[0]=sy1;
3790 c[1]=0.; c[2]=sz1;
3791 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3792 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3793 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3794 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3795 c[13]=f30*sy1*f40+f32*sy2*f42;
3796 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3797
3798 // Int_t row1 = fSectors->GetRowNumber(x2[0]);
6c94f330 3799 AliTPCseed *seed=new AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
91162307 3800 // Double_t y0,z0,y1,z1, y2,z2;
3801 //seed->GetProlongation(x0[0],y0,z0);
3802 // seed->GetProlongation(x1[0],y1,z1);
3803 //seed->GetProlongation(x2[0],y2,z2);
3804 // seed =0;
b9671574 3805 seed->SetLastPoint(pp2);
3806 seed->SetFirstPoint(pp2);
91162307 3807
3808
3809 return seed;
3810}
3811
d26d9159 3812
3813AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
3814{
3815 //
3816 //
3817 //reseed using founded clusters
3818 //
3819 // Find the number of clusters
3820 Int_t nclusters = 0;
3821 for (Int_t irow=0;irow<160;irow++){
3822 if (track->GetClusterIndex(irow)>0) nclusters++;
3823 }
3824 //
3825 Int_t ipos[3];
3826 ipos[0] = TMath::Max(int(r0*nclusters),0); // point 0 cluster
3827 ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1); //
3828 ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1); // last point
3829 //
3830 //
3831 Double_t xyz[3][3];
3832 Int_t row[3],sec[3]={0,0,0};
3833 //
3834 // find track row position at given ratio of the length
3835 Int_t index=-1;
3836 for (Int_t irow=0;irow<160;irow++){
3837 if (track->GetClusterIndex2(irow)<0) continue;
3838 index++;
3839 for (Int_t ipoint=0;ipoint<3;ipoint++){
3840 if (index<=ipos[ipoint]) row[ipoint] = irow;
3841 }
3842 }
3843 //
3844 //Get cluster and sector position
3845 for (Int_t ipoint=0;ipoint<3;ipoint++){
3846 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
3847 AliTPCclusterMI * cl = GetClusterMI(clindex);
3848 if (cl==0) {
6bdc18d6 3849 //Error("Bug\n");
47966a6d 3850 // AliTPCclusterMI * cl = GetClusterMI(clindex);
d26d9159 3851 return 0;
3852 }
3853 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
3854 xyz[ipoint][0] = GetXrow(row[ipoint]);
3855 xyz[ipoint][1] = cl->GetY();
3856 xyz[ipoint][2] = cl->GetZ();
3857 }
3858 //
3859 //
3860 // Calculate seed state vector and covariance matrix
3861
3862 Double_t alpha, cs,sn, xx2,yy2;
3863 //
3864 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
3865 cs = TMath::Cos(alpha);
3866 sn = TMath::Sin(alpha);
3867 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
3868 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
3869 xyz[1][0] = xx2;
3870 xyz[1][1] = yy2;
3871 //
3872 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
3873 cs = TMath::Cos(alpha);
3874 sn = TMath::Sin(alpha);
3875 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
3876 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
3877 xyz[0][0] = xx2;
3878 xyz[0][1] = yy2;
3879 //
3880 //
3881 //
3882 Double_t x[5],c[15];
3883 //
3884 x[0]=xyz[2][1];
3885 x[1]=xyz[2][2];
3886 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
3887 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
3888 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
3889 //
3890 Double_t sy =0.1, sz =0.1;
3891 //
3892 Double_t sy1=0.2, sz1=0.2;
3893 Double_t sy2=0.2, sz2=0.2;
3894 Double_t sy3=0.2;
3895 //
3896 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;
3897 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;
3898 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;
3899 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;
3900 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;
3901 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;
3902 //
3903 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;
3904 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;
3905 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;
3906 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;
3907
3908
3909 c[0]=sy1;
3910 c[1]=0.; c[2]=sz1;
3911 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3912 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3913 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3914 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3915 c[13]=f30*sy1*f40+f32*sy2*f42;
3916 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3917
3918 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
6c94f330 3919 AliTPCseed *seed=new AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
b9671574 3920 seed->SetLastPoint(row[2]);
3921 seed->SetFirstPoint(row[2]);
d26d9159 3922 return seed;
3923}
3924
eea478d3 3925
3926AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
3927{
3928 //
3929 //
3930 //reseed using founded clusters
3931 //
3932 Double_t xyz[3][3];
4a12af72 3933 Int_t row[3]={0,0,0};
3934 Int_t sec[3]={0,0,0};
eea478d3 3935 //
3936 // forward direction
3937 if (forward){
3938 for (Int_t irow=r0;irow<160;irow++){
3939 if (track->GetClusterIndex(irow)>0){
3940 row[0] = irow;
3941 break;
3942 }
3943 }
3944 for (Int_t irow=160;irow>r0;irow--){
3945 if (track->GetClusterIndex(irow)>0){
3946 row[2] = irow;
3947 break;
3948 }
3949 }
3950 for (Int_t irow=row[2]-15;irow>row[0];irow--){
3951 if (track->GetClusterIndex(irow)>0){
3952 row[1] = irow;
3953 break;
3954 }
3955 }
3956 //
3957 }
3958 if (!forward){
3959 for (Int_t irow=0;irow<r0;irow++){
3960 if (track->GetClusterIndex(irow)>0){
3961 row[0] = irow;
3962 break;
3963 }
3964 }
3965 for (Int_t irow=r0;irow>0;irow--){
3966 if (track->GetClusterIndex(irow)>0){
3967 row[2] = irow;
3968 break;
3969 }
3970 }
3971 for (Int_t irow=row[2]-15;irow>row[0];irow--){
3972 if (track->GetClusterIndex(irow)>0){
3973 row[1] = irow;
3974 break;
3975 }
3976 }
3977 }
3978 //
3979 if ((row[2]-row[0])<20) return 0;
3980 if (row[1]==0) return 0;
3981 //
3982 //
3983 //Get cluster and sector position
3984 for (Int_t ipoint=0;ipoint<3;ipoint++){
3985 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
3986 AliTPCclusterMI * cl = GetClusterMI(clindex);
3987 if (cl==0) {
3988 //Error("Bug\n");
3989 // AliTPCclusterMI * cl = GetClusterMI(clindex);
3990 return 0;
3991 }
3992 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
3993 xyz[ipoint][0] = GetXrow(row[ipoint]);
3994 AliTPCTrackerPoint * point = track->GetTrackPoint(row[ipoint]);
3995 if (point&&ipoint<2){
3996 //
3997 xyz[ipoint][1] = point->GetY();
3998 xyz[ipoint][2] = point->GetZ();
3999 }
4000 else{
4001 xyz[ipoint][1] = cl->GetY();
4002 xyz[ipoint][2] = cl->GetZ();
4003 }
4004 }
4005 //
4006 //
4007 //
4008 //
4009 // Calculate seed state vector and covariance matrix
4010
4011 Double_t alpha, cs,sn, xx2,yy2;
4012 //
4013 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4014 cs = TMath::Cos(alpha);
4015 sn = TMath::Sin(alpha);
4016 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4017 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4018 xyz[1][0] = xx2;
4019 xyz[1][1] = yy2;
4020 //
4021 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4022 cs = TMath::Cos(alpha);
4023 sn = TMath::Sin(alpha);
4024 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4025 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4026 xyz[0][0] = xx2;
4027 xyz[0][1] = yy2;
4028 //
4029 //
4030 //
4031 Double_t x[5],c[15];
4032 //
4033 x[0]=xyz[2][1];
4034 x[1]=xyz[2][2];
4035 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4036 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4037 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4038 //
4039 Double_t sy =0.1, sz =0.1;
4040 //
4041 Double_t sy1=0.2, sz1=0.2;
4042 Double_t sy2=0.2, sz2=0.2;
4043 Double_t sy3=0.2;
4044 //
4045 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;
4046 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;
4047 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;
4048 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;
4049 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;
4050 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;
4051 //
4052 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;
4053 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;
4054 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;
4055 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;
4056
4057
4058 c[0]=sy1;
4059 c[1]=0.; c[2]=sz1;
4060 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4061 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4062 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4063 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4064 c[13]=f30*sy1*f40+f32*sy2*f42;
4065 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4066
4067 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
6c94f330 4068 AliTPCseed *seed=new AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
b9671574 4069 seed->SetLastPoint(row[2]);
4070 seed->SetFirstPoint(row[2]);
eea478d3 4071 for (Int_t i=row[0];i<row[2];i++){
b9671574 4072 seed->SetClusterIndex(i, track->GetClusterIndex(i));
eea478d3 4073 }
4074
4075 return seed;
4076}
4077
51ad6848 4078void AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
4079{
4080 //
4081 // find kinks
4082 //
4083 //
eea478d3 4084
51ad6848 4085 TObjArray *kinks= new TObjArray(10000);
81e97e0d 4086 // TObjArray *v0s= new TObjArray(10000);
51ad6848 4087 Int_t nentries = array->GetEntriesFast();
4088 AliHelix *helixes = new AliHelix[nentries];
4089 Int_t *sign = new Int_t[nentries];
4090 Int_t *nclusters = new Int_t[nentries];
4091 Float_t *alpha = new Float_t[nentries];
6c94f330 4092 AliKink *kink = new AliKink();
51ad6848 4093 Int_t * usage = new Int_t[nentries];
eea478d3 4094 Float_t *zm = new Float_t[nentries];
4095 Float_t *z0 = new Float_t[nentries];
4096 Float_t *fim = new Float_t[nentries];
4097 Float_t *shared = new Float_t[nentries];
4098 Bool_t *circular = new Bool_t[nentries];
81e97e0d 4099 Float_t *dca = new Float_t[nentries];
4100 //const AliESDVertex * primvertex = esd->GetVertex();
eea478d3 4101 //
4102 // nentries = array->GetEntriesFast();
4103 //
4104
51ad6848 4105 //
4106 //
4107 for (Int_t i=0;i<nentries;i++){
4108 sign[i]=0;
4109 usage[i]=0;
4110 AliTPCseed* track = (AliTPCseed*)array->At(i);
4111 if (!track) continue;
b9671574 4112 track->SetCircular(0);
eea478d3 4113 shared[i] = kFALSE;
51ad6848 4114 track->UpdatePoints();
4115 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
51ad6848 4116 }
eea478d3 4117 nclusters[i]=track->GetNumberOfClusters();
4118 alpha[i] = track->GetAlpha();
4119 new (&helixes[i]) AliHelix(*track);
4120 Double_t xyz[3];
4121 helixes[i].Evaluate(0,xyz);
4122 sign[i] = (track->GetC()>0) ? -1:1;
4123 Double_t x,y,z;
4124 x=160;
4125 if (track->GetProlongation(x,y,z)){
4126 zm[i] = z;
4127 fim[i] = alpha[i]+TMath::ATan2(y,x);
4128 }
4129 else{
4130 zm[i] = track->GetZ();
4131 fim[i] = alpha[i];
4132 }
4133 z0[i]=1000;
4134 circular[i]= kFALSE;
81e97e0d 4135 if (track->GetProlongation(0,y,z)) z0[i] = z;
4136 dca[i] = track->GetD(0,0);
51ad6848 4137 }
4138 //
4139 //
4140 TStopwatch timer;
4141 timer.Start();
4142 Int_t ncandidates =0;
4143 Int_t nall =0;
4144 Int_t ntracks=0;
4145 Double_t phase[2][2],radius[2];
eea478d3 4146
4147 //
4148 // Find circling track
81e97e0d 4149 TTreeSRedirector &cstream = *fDebugStreamer;
eea478d3 4150 //
4151 for (Int_t i0=0;i0<nentries;i0++){
4152 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4153 if (!track0) continue;
b9671574 4154 if (track0->GetNumberOfClusters()<40) continue;
6c94f330 4155 if (TMath::Abs(1./track0->GetC())>200) continue;
eea478d3 4156 for (Int_t i1=i0+1;i1<nentries;i1++){
4157 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4158 if (!track1) continue;
b9671574 4159 if (track1->GetNumberOfClusters()<40) continue;
6c94f330 4160 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
b9671574 4161 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
6c94f330 4162 if (TMath::Abs(1./track1->GetC())>200) continue;
4163 if (track1->Get1Pt()*track0->Get1Pt()>0) continue;
4164 if (track1->GetTgl()*track0->GetTgl()>0) continue;
1b36647b 4165 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
b9671574 4166 if (track0->GetBConstrain()&&TMath::Abs(track1->Get1Pt())<TMath::Abs(track0->Get1Pt())) continue; //returning - lower momenta
4167 if (track1->GetBConstrain()&&TMath::Abs(track0->Get1Pt())<TMath::Abs(track1->Get1Pt())) continue; //returning - lower momenta
eea478d3 4168 //
81e97e0d 4169 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
4170 if (mindcar<5) continue;
4171 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
4172 if (mindcaz<5) continue;
4173 if (mindcar+mindcaz<20) continue;
4174 //
4175 //
eea478d3 4176 Float_t xc0 = helixes[i0].GetHelix(6);
4177 Float_t yc0 = helixes[i0].GetHelix(7);
4178 Float_t r0 = helixes[i0].GetHelix(8);
4179 Float_t xc1 = helixes[i1].GetHelix(6);
4180 Float_t yc1 = helixes[i1].GetHelix(7);
4181 Float_t r1 = helixes[i1].GetHelix(8);
4182
4183 Float_t rmean = (r0+r1)*0.5;
4184 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
81e97e0d 4185 //if (delta>30) continue;
eea478d3 4186 if (delta>rmean*0.25) continue;
4187 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
4188 //
4189 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4190 if (npoints==0) continue;
4191 helixes[i0].GetClosestPhases(helixes[i1], phase);
4192 //
4193 Double_t xyz0[3];
4194 Double_t xyz1[3];
4195 Double_t hangles[3];
4196 helixes[i0].Evaluate(phase[0][0],xyz0);
4197 helixes[i1].Evaluate(phase[0][1],xyz1);
4198
4199 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
4200 Double_t deltah[2],deltabest;
4201 if (hangles[2]<2.8) continue;
4202 /*
4203 cstream<<"C"<<track0->fLab<<track1->fLab<<
4204 track0->fP3<<track1->fP3<<
4205 track0->fP4<<track1->fP4<<
4206 delta<<rmean<<npoints<<
4207 hangles[0]<<hangles[2]<<
4208 xyz0[2]<<xyz1[2]<<radius[0]<<"\n";
4209 */
4210 if (npoints>0){
4211 Int_t ibest=0;
81e97e0d 4212 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
eea478d3 4213 if (npoints==2){
81e97e0d 4214 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
eea478d3 4215 if (deltah[1]<deltah[0]) ibest=1;
4216 }
4217 deltabest = TMath::Sqrt(deltah[ibest]);
4218 helixes[i0].Evaluate(phase[ibest][0],xyz0);
4219 helixes[i1].Evaluate(phase[ibest][1],xyz1);
4220 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
81e97e0d 4221 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
eea478d3 4222 //
81e97e0d 4223 if (deltabest>6) continue;
4224 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
eea478d3 4225 Bool_t sign =kFALSE;
81e97e0d 4226 if (hangles[2]>3.06) sign =kTRUE;
4227 //
eea478d3 4228 if (sign){
4229 circular[i0] = kTRUE;
81e97e0d 4230 circular[i1] = kTRUE;
6c94f330 4231 if (TMath::Abs(track0->Get1Pt())<TMath::Abs(track1->Get1Pt())){
b9671574 4232 track0->SetCircular(track0->GetCircular()+1);
4233 track1->SetCircular(track1->GetCircular()+2);
81e97e0d 4234 }
4235 else{
b9671574 4236 track1->SetCircular(track1->GetCircular()+1);
4237 track0->SetCircular(track0->GetCircular()+2);
81e97e0d 4238 }
4239 }
34acb742 4240 if (sign&&AliTPCReconstructor::StreamLevel()>1){
4241 //debug stream
b9671574 4242 Int_t lab0=track0->GetLabel();
4243 Int_t lab1=track1->GetLabel();
81e97e0d 4244 cstream<<"Curling"<<
b9671574 4245 "lab0="<<lab0<<
4246 "lab1="<<lab1<<
81e97e0d 4247 "Tr0.="<<track0<<
4248 "Tr1.="<<track1<<
4249 "dca0="<<dca[i0]<<
4250 "dca1="<<dca[i1]<<
4251 "mindcar="<<mindcar<<
4252 "mindcaz="<<mindcaz<<
4253 "delta="<<delta<<
4254 "rmean="<<rmean<<
4255 "npoints="<<npoints<<
4256 "hangles0="<<hangles[0]<<
4257 "hangles2="<<hangles[2]<<
4258 "xyz0="<<xyz0[2]<<
4259 "xyzz1="<<xyz1[2]<<
4260 "z0="<<z0[i0]<<
4261 "z1="<<z0[i1]<<
4262 "radius="<<radiusbest<<
4263 "deltabest="<<deltabest<<
4264 "phase0="<<phase[ibest][0]<<
4265 "phase1="<<phase[ibest][1]<<
4266 "\n";
eea478d3 4267 }
4268 }
4269 }
4270 }
4271 //
81e97e0d 4272 // Finf kinks loop
4273 //
51ad6848 4274 //
4275 for (Int_t i =0;i<nentries;i++){
4276 if (sign[i]==0) continue;
4277 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
4278 ntracks++;
4279 //
4280 Double_t cradius0 = 40*40;
4281 Double_t cradius1 = 270*270;
4282 Double_t cdist1=8.;
4283 Double_t cdist2=8.;
4284 Double_t cdist3=0.55;
4285 for (Int_t j =i+1;j<nentries;j++){
4286 nall++;
4287 if (sign[j]*sign[i]<1) continue;
4288 if ( (nclusters[i]+nclusters[j])>200) continue;
4289 if ( (nclusters[i]+nclusters[j])<80) continue;
4290 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
4291 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
4292 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
4293 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
4294 if (npoints<1) continue;
4295 // cuts on radius
4296 if (npoints==1){
4297 if (radius[0]<cradius0||radius[0]>cradius1) continue;
4298 }
4299 else{
4300 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
4301 }
4302 //
4303 Double_t delta1=10000,delta2=10000;
4304 // cuts on the intersection radius
4305 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
4306 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
4307 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
4308 if (npoints==2){
4309 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
4310 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
4311 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
4312 }
4313 //
4314 Double_t distance1 = TMath::Min(delta1,delta2);
4315 if (distance1>cdist1) continue; // cut on DCA linear approximation
4316 //
4317 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
4318 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
4319 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
4320 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
4321 //
4322 if (npoints==2){
4323 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
4324 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
4325 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
4326 }
4327 distance1 = TMath::Min(delta1,delta2);
4328 Float_t rkink =0;
4329 if (delta1<delta2){
4330 rkink = TMath::Sqrt(radius[0]);
4331 }
4332 else{
4333 rkink = TMath::Sqrt(radius[1]);
4334 }
4335 if (distance1>cdist2) continue;
4336 //
4337 //
4338 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
4339 //
4340 //
4341 Int_t row0 = GetRowNumber(rkink);
4342 if (row0<10) continue;
4343 if (row0>150) continue;
4344 //
4345 //
4346 Float_t dens00=-1,dens01=-1;
4347 Float_t dens10=-1,dens11=-1;
4348 //
4349 Int_t found,foundable,shared;
4350 track0->GetClusterStatistic(0,row0-5, found, foundable,shared,kFALSE);
4351 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
4352 track0->GetClusterStatistic(row0+5,155, found, foundable,shared,kFALSE);
4353 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
4354 //
4355 track1->GetClusterStatistic(0,row0-5, found, foundable,shared,kFALSE);
4356 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
4357 track1->GetClusterStatistic(row0+5,155, found, foundable,shared,kFALSE);
4358 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
eea478d3 4359 //
51ad6848 4360 if (dens00<dens10 && dens01<dens11) continue;
4361 if (dens00>dens10 && dens01>dens11) continue;
4362 if (TMath::Max(dens00,dens10)<0.1) continue;
4363 if (TMath::Max(dens01,dens11)<0.3) continue;
4364 //
4365 if (TMath::Min(dens00,dens10)>0.6) continue;
4366 if (TMath::Min(dens01,dens11)>0.6) continue;
4367
4368 //
4369 AliTPCseed * ktrack0, *ktrack1;
4370 if (dens00>dens10){
4371 ktrack0 = track0;
4372 ktrack1 = track1;
4373 }
4374 else{
4375 ktrack0 = track1;
4376 ktrack1 = track0;
4377 }
4378 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
4379 AliExternalTrackParam paramm(*ktrack0);
4380 AliExternalTrackParam paramd(*ktrack1);
c9ec41e8 4381 if (row0>60&&ktrack1->GetReference().GetX()>90.) new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
51ad6848 4382 //
4383 //
4384 kink->SetMother(paramm);
4385 kink->SetDaughter(paramd);
4386 kink->Update();
4387
eea478d3 4388 Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
51ad6848 4389 Int_t index[4];
4390 fParam->Transform0to1(x,index);
4391 fParam->Transform1to2(x,index);
4392 row0 = GetRowNumber(x[0]);
4393
eea478d3 4394 if (kink->GetR()<100) continue;
4395 if (kink->GetR()>240) continue;
4396 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
4397 if (kink->GetDistance()>cdist3) continue;
4398 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
51ad6848 4399 if (dird<0) continue;
4400
eea478d3 4401 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
51ad6848 4402 if (dirm<0) continue;
eea478d3 4403 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
51ad6848 4404 if (mpt<0.2) continue;
4405
eea478d3 4406 if (mpt<1){
4407 //for high momenta momentum not defined well in first iteration
6c94f330 4408 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
eea478d3 4409 if (qt>0.35) continue;
4410 }
51ad6848 4411
eea478d3 4412 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
4413 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
51ad6848 4414 if (dens00>dens10){
eea478d3 4415 kink->SetTPCDensity(dens00,0,0);
4416 kink->SetTPCDensity(dens01,0,1);
4417 kink->SetTPCDensity(dens10,1,0);
4418 kink->SetTPCDensity(dens11,1,1);
4419 kink->SetIndex(i,0);
4420 kink->SetIndex(j,1);
51ad6848 4421 }
4422 else{
eea478d3 4423 kink->SetTPCDensity(dens10,0,0);
4424 kink->SetTPCDensity(dens11,0,1);
4425 kink->SetTPCDensity(dens00,1,0);
4426 kink->SetTPCDensity(dens01,1,1);
4427 kink->SetIndex(j,0);
4428 kink->SetIndex(i,1);
51ad6848 4429 }
51ad6848 4430
eea478d3 4431 if (mpt<1||kink->GetAngle(2)>0.1){
4432 // angle and densities not defined yet
4433 if (kink->GetTPCDensityFactor()<0.8) continue;
4434 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
6c94f330 4435 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
eea478d3 4436 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
4437 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
4438
6c94f330 4439 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
4440 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
eea478d3 4441 criticalangle= 3*TMath::Sqrt(criticalangle);
4442 if (criticalangle>0.02) criticalangle=0.02;
4443 if (kink->GetAngle(2)<criticalangle) continue;
4444 }
51ad6848 4445 //
eea478d3 4446 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
51ad6848 4447 Float_t shapesum =0;
4448 Float_t sum = 0;
4449 for ( Int_t row = row0-drow; row<row0+drow;row++){
4450 if (row<0) continue;
4451 if (row>155) continue;
b9671574 4452 if (ktrack0->GetClusterPointer(row)){
51ad6848 4453 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
4454 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
4455 sum++;
4456 }
b9671574 4457 if (ktrack1->GetClusterPointer(row)){
51ad6848 4458 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
4459 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
4460 sum++;
4461 }
4462 }
4463 if (sum<4){
eea478d3 4464 kink->SetShapeFactor(-1.);
51ad6848 4465 }
4466 else{
eea478d3 4467 kink->SetShapeFactor(shapesum/sum);
4468 }
51ad6848 4469 // esd->AddKink(kink);
4470 kinks->AddLast(kink);
6c94f330 4471 kink = new AliKink;
51ad6848 4472 ncandidates++;
4473 }
4474 }
eea478d3 4475 //
4476 // sort the kinks according quality - and refit them towards vertex
4477 //
4478 Int_t nkinks = kinks->GetEntriesFast();
4479 Float_t *quality = new Float_t[nkinks];
4480 Int_t *indexes = new Int_t[nkinks];
4481 AliTPCseed *mothers = new AliTPCseed[nkinks];
4482 AliTPCseed *daughters = new AliTPCseed[nkinks];
4483 //
4484 //
51ad6848 4485 for (Int_t i=0;i<nkinks;i++){
4486 quality[i] =100000;
6c94f330 4487 AliKink *kink = (AliKink*)kinks->At(i);
eea478d3 4488 //
4489 // refit kinks towards vertex
4490 //
4491 Int_t index0 = kink->GetIndex(0);
4492 Int_t index1 = kink->GetIndex(1);
4493 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
4494 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
4495 //
b9671574 4496 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
eea478d3 4497 //
4498 // Refit Kink under if too small angle
4499 //
4500 if (kink->GetAngle(2)<0.05){
4501 kink->SetTPCRow0(GetRowNumber(kink->GetR()));
4502 Int_t row0 = kink->GetTPCRow0();
4503 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2)));
4504 //
4505 //
4506 Int_t last = row0-drow;
4507 if (last<40) last=40;
b9671574 4508 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
eea478d3 4509 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
4510 //
4511 //
4512 Int_t first = row0+drow;
4513 if (first>130) first=130;
b9671574 4514 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
eea478d3 4515 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
4516 //
4517 if (seed0 && seed1){
4518 kink->SetStatus(1,8);
4519 if (RefitKink(*seed0,*seed1,*kink)) kink->SetStatus(1,9);
4520 row0 = GetRowNumber(kink->GetR());
b9671574 4521 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
eea478d3 4522 new (&mothers[i]) AliTPCseed(*seed0);
4523 new (&daughters[i]) AliTPCseed(*seed1);
4524 }
4525 else{
4526 delete kinks->RemoveAt(i);
4527 if (seed0) delete seed0;
4528 if (seed1) delete seed1;
4529 continue;
4530 }
4531 if (kink->GetDistance()>0.5 || kink->GetR()<110 || kink->GetR()>240) {
4532 delete kinks->RemoveAt(i);
4533 if (seed0) delete seed0;
4534 if (seed1) delete seed1;
4535 continue;
4536 }
4537 //
4538 delete seed0;
4539 delete seed1;
4540 }
4541 //
4542 if (kink) quality[i] = 160*((0.1+kink->GetDistance())*(2.-kink->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
51ad6848 4543 }
4544 TMath::Sort(nkinks,quality,indexes,kFALSE);
eea478d3 4545 //
4546 //remove double find kinks
4547 //
4548 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
6c94f330 4549 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
eea478d3 4550 if (!kink0) continue;
4551 //
4552 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
4553 if (!kink0) continue;
6c94f330 4554 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
eea478d3 4555 if (!kink1) continue;
4556 // if not close kink continue
4557 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
4558 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
4559 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
4560 //
4561 AliTPCseed &mother0 = mothers[indexes[ikink0]];
4562 AliTPCseed &daughter0 = daughters[indexes[ikink0]];
4563 AliTPCseed &mother1 = mothers[indexes[ikink1]];
4564 AliTPCseed &daughter1 = daughters[indexes[ikink1]];
4565 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
4566 //
4567 Int_t same = 0;
4568 Int_t both = 0;
4569 Int_t samem = 0;
4570 Int_t bothm = 0;
4571 Int_t samed = 0;
4572 Int_t bothd = 0;
4573 //
4574 for (Int_t i=0;i<row0;i++){
b9671574 4575 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
eea478d3 4576 both++;
4577 bothm++;
b9671574 4578 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
eea478d3 4579 same++;
4580 samem++;
4581 }
4582 }
4583 }
4584
4585 for (Int_t i=row0;i<158;i++){
b9671574 4586 if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){
eea478d3 4587 both++;
4588 bothd++;
b9671574 4589 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
eea478d3 4590 same++;
4591 samed++;
4592 }
4593 }
4594 }
4595 Float_t ratio = Float_t(same+1)/Float_t(both+1);
4596 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
4597 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
4598 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
b9671574 4599 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
4600 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
eea478d3 4601 if (sum1>sum0){
4602 shared[kink0->GetIndex(0)]= kTRUE;
4603 shared[kink0->GetIndex(1)]= kTRUE;
4604 delete kinks->RemoveAt(indexes[ikink0]);
4605 }
4606 else{
4607 shared[kink1->GetIndex(0)]= kTRUE;
4608 shared[kink1->GetIndex(1)]= kTRUE;
4609 delete kinks->RemoveAt(indexes[ikink1]);
4610 }
4611 }
4612 }
4613 }
4614
4615
51ad6848 4616 for (Int_t i=0;i<nkinks;i++){
6c94f330 4617 AliKink * kink = (AliKink*) kinks->At(indexes[i]);
eea478d3 4618 if (!kink) continue;
4619 kink->SetTPCRow0(GetRowNumber(kink->GetR()));
4620 Int_t index0 = kink->GetIndex(0);
4621 Int_t index1 = kink->GetIndex(1);
4622 if (circular[index0]||circular[index1]&&kink->GetDistance()>0.2) continue;
4623 kink->SetMultiple(usage[index0],0);
4624 kink->SetMultiple(usage[index1],1);
4625 if (kink->GetMultiple()[0]+kink->GetMultiple()[1]>2) continue;
4626 if (kink->GetMultiple()[0]+kink->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
4627 if (kink->GetMultiple()[0]+kink->GetMultiple()[1]>0 && kink->GetDistance()>0.2) continue;
4628 if (circular[index0]||circular[index1]&&kink->GetDistance()>0.1) continue;
51ad6848 4629
51ad6848 4630 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
4631 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
eea478d3 4632 if (!ktrack0 || !ktrack1) continue;
4633 Int_t index = esd->AddKink(kink);
4634 //
4635 //
b9671574 4636 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
4637 if (mothers[indexes[i]].GetNumberOfClusters()>20 && daughters[indexes[i]].GetNumberOfClusters()>20 && (mothers[indexes[i]].GetNumberOfClusters()+daughters[indexes[i]].GetNumberOfClusters())>100){
eea478d3 4638 new (ktrack0) AliTPCseed(mothers[indexes[i]]);
4639 new (ktrack1) AliTPCseed(daughters[indexes[i]]);
4640 }
4641 }
4642 //
b9671574 4643 ktrack0->SetKinkIndex(usage[index0],-(index+1));
4644 ktrack1->SetKinkIndex(usage[index1], (index+1));
51ad6848 4645 usage[index0]++;
4646 usage[index1]++;
4647 }
eea478d3 4648 //
4649 // Remove tracks corresponding to shared kink's
4650 //
4651 for (Int_t i=0;i<nentries;i++){
4652 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
4653 if (!track0) continue;
b9671574 4654 if (track0->GetKinkIndex(0)!=0) continue;
eea478d3 4655 if (shared[i]) delete array->RemoveAt(i);
4656 }
51ad6848 4657
eea478d3 4658 //
4659 //
4660 RemoveUsed2(array,0.5,0.4,30);
4661 UnsignClusters();
81e97e0d 4662 for (Int_t i=0;i<nentries;i++){
4663 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
4664 if (!track0) continue;
4665 track0->CookdEdx(0.02,0.6);
4666 track0->CookPID();
4667 }
eea478d3 4668 //
4669 for (Int_t i=0;i<nentries;i++){
4670 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
4671 if (!track0) continue;
6c94f330 4672 if (track0->GetPt()<1.4) continue;
eea478d3 4673 //remove double high momenta tracks - overlapped with kink candidates
4674 Int_t shared=0;
4675 Int_t all =0;
b9671574 4676 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
4677 if (track0->GetClusterPointer(icl)!=0){
eea478d3 4678 all++;
b9671574 4679 if (track0->GetClusterPointer(icl)->IsUsed(10)) shared++;
eea478d3 4680 }
4681 }
4682 if (Float_t(shared+1)/Float_t(nall+1)>0.5) {
4683 delete array->RemoveAt(i);
f99dc368 4684 continue;
eea478d3 4685 }
4686 //
b9671574 4687 if (track0->GetKinkIndex(0)!=0) continue;
eea478d3 4688 if (track0->GetNumberOfClusters()<80) continue;
4a12af72 4689
4690 AliTPCseed *pmother = new AliTPCseed();
4691 AliTPCseed *pdaughter = new AliTPCseed();
6c94f330 4692 AliKink *pkink = new AliKink;
4a12af72 4693
4694 AliTPCseed & mother = *pmother;
4695 AliTPCseed & daughter = *pdaughter;
6c94f330 4696 AliKink & kink = *pkink;
eea478d3 4697 if (CheckKinkPoint(track0,mother,daughter, kink)){
b9671574 4698 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
4a12af72 4699 delete pmother;
4700 delete pdaughter;
4701 delete pkink;
4702 continue; //too short tracks
4703 }
6c94f330 4704 if (mother.GetPt()<1.4) {
4a12af72 4705 delete pmother;
4706 delete pdaughter;
4707 delete pkink;
4708 continue;
4709 }
eea478d3 4710 Int_t row0= kink.GetTPCRow0();
4711 if (kink.GetDistance()>0.5 || kink.GetR()<110. || kink.GetR()>240.) {
4a12af72 4712 delete pmother;
4713 delete pdaughter;
4714 delete pkink;
eea478d3 4715 continue;
4716 }
4717 //
4718 Int_t index = esd->AddKink(&kink);
b9671574 4719 mother.SetKinkIndex(0,-(index+1));
4720 daughter.SetKinkIndex(0,index+1);
4721 if (mother.GetNumberOfClusters()>50) {
eea478d3 4722 delete array->RemoveAt(i);
4723 array->AddAt(new AliTPCseed(mother),i);
4724 }
4725 else{
4726 array->AddLast(new AliTPCseed(mother));
4727 }
4728 array->AddLast(new AliTPCseed(daughter));
4729 for (Int_t icl=0;icl<row0;icl++) {
b9671574 4730 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
eea478d3 4731 }
4732 //
4733 for (Int_t icl=row0;icl<158;icl++) {
b9671574 4734 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
eea478d3 4735 }
4736 //
4737 }
4a12af72 4738 delete pmother;
4739 delete pdaughter;
4740 delete pkink;
eea478d3 4741 }
4742
4743 delete [] daughters;
4744 delete [] mothers;
4745 //
4746 //
81e97e0d 4747 delete [] dca;
eea478d3 4748 delete []circular;
4749 delete []shared;
4750 delete []quality;
4751 delete []indexes;
4752 //
4753 delete kink;
4754 delete[]fim;
51ad6848 4755 delete[] zm;
eea478d3 4756 delete[] z0;
51ad6848 4757 delete [] usage;
4758 delete[] alpha;
4759 delete[] nclusters;
4760 delete[] sign;
4761 delete[] helixes;
4762 kinks->Delete();
4763 delete kinks;
4764
eea478d3 4765 printf("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall);
51ad6848 4766 timer.Print();
4767}
4768
81e97e0d 4769void AliTPCtrackerMI::FindV0s(TObjArray * array, AliESD *esd)
4770{
4771 //
4772 // find V0s
4773 //
4774 //
4775 TObjArray *tpcv0s = new TObjArray(100000);
4776 Int_t nentries = array->GetEntriesFast();
4777 AliHelix *helixes = new AliHelix[nentries];
4778 Int_t *sign = new Int_t[nentries];
4779 Float_t *alpha = new Float_t[nentries];
4780 Float_t *z0 = new Float_t[nentries];
4781 Float_t *dca = new Float_t[nentries];
4782 Float_t *sdcar = new Float_t[nentries];
4783 Float_t *cdcar = new Float_t[nentries];
4784 Float_t *pulldcar = new Float_t[nentries];
4785 Float_t *pulldcaz = new Float_t[nentries];
4786 Float_t *pulldca = new Float_t[nentries];
4787 Bool_t *isPrim = new Bool_t[nentries];
4788 const AliESDVertex * primvertex = esd->GetVertex();
4789 Double_t zvertex = primvertex->GetZv();
4790 //
4791 // nentries = array->GetEntriesFast();
4792 //
4793 for (Int_t i=0;i<nentries;i++){
4794 sign[i]=0;
4795 isPrim[i]=0;
4796 AliTPCseed* track = (AliTPCseed*)array->At(i);
4797 if (!track) continue;
4798 track->GetV0Indexes()[0] = 0; //rest v0 indexes
4799 track->GetV0Indexes()[1] = 0; //rest v0 indexes
4800 track->GetV0Indexes()[2] = 0; //rest v0 indexes
4801 //
4802 alpha[i] = track->GetAlpha();
4803 new (&helixes[i]) AliHelix(*track);
4804 Double_t xyz[3];
4805 helixes[i].Evaluate(0,xyz);
4806 sign[i] = (track->GetC()>0) ? -1:1;
4807 Double_t x,y,z;
4808 x=160;
4809 z0[i]=1000;
4810 if (track->GetProlongation(0,y,z)) z0[i] = z;
4811 dca[i] = track->GetD(0,0);
4812 //
4813 // dca error parrameterezation + pulls
4814 //
6c94f330 4815 sdcar[i] = TMath::Sqrt(0.150*0.150+(100*track->GetC())*(100*track->GetC()));
4816 if (TMath::Abs(track->GetTgl())>1) sdcar[i]*=2.5;
4817 cdcar[i] = TMath::Exp((TMath::Abs(track->GetC())-0.0106)*525.3);
81e97e0d 4818 pulldcar[i] = (dca[i]-cdcar[i])/sdcar[i];
4819 pulldcaz[i] = (z0[i]-zvertex)/sdcar[i];
4820 pulldca[i] = TMath::Sqrt(pulldcar[i]*pulldcar[i]+pulldcaz[i]*pulldcaz[i]);
b9671574 4821 if (track->TPCrPID(1)+track->TPCrPID(2)+track->TPCrPID(3)>0.5) {
81e97e0d 4822 if (pulldca[i]<3.) isPrim[i]=kTRUE; //pion, muon and Kaon 3 sigma cut
4823 }
b9671574 4824 if (track->TPCrPID(4)>0.5) {
81e97e0d 4825 if (pulldca[i]<0.5) isPrim[i]=kTRUE; //proton 0.5 sigma cut
4826 }
b9671574 4827 if (track->TPCrPID(0)>0.4) {
81e97e0d 4828 isPrim[i]=kFALSE; //electron no sigma cut
4829 }
4830 }
4831 //
4832 //
4833 TStopwatch timer;
4834 timer.Start();
4835 Int_t ncandidates =0;
4836 Int_t nall =0;
4837 Int_t ntracks=0;
4838 Double_t phase[2][2],radius[2];
4839 //
4840 // Finf V0s loop
4841 //
4842 //
4843 // //
4844 TTreeSRedirector &cstream = *fDebugStreamer;
4845 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
6c94f330 4846 AliV0 vertex;
81e97e0d 4847 Double_t cradius0 = 10*10;
4848 Double_t cradius1 = 200*200;
4849 Double_t cdist1=3.;
4850 Double_t cdist2=4.;
4851 Double_t cpointAngle = 0.95;
4852 //
4853 Double_t delta[2]={10000,10000};
4854 for (Int_t i =0;i<nentries;i++){
4855 if (sign[i]==0) continue;
4856 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
4857 if (!track0) continue;
34acb742 4858 if (AliTPCReconstructor::StreamLevel()>0){
4859 cstream<<"Tracks"<<
4860 "Tr0.="<<track0<<
4861 "dca="<<dca[i]<<
4862 "z0="<<z0[i]<<
4863 "zvertex="<<zvertex<<
4864 "sdcar0="<<sdcar[i]<<
4865 "cdcar0="<<cdcar[i]<<
4866 "pulldcar0="<<pulldcar[i]<<
4867 "pulldcaz0="<<pulldcaz[i]<<
4868 "pulldca0="<<pulldca[i]<<
4869 "isPrim="<<isPrim[i]<<
4870 "\n";
4871 }
81e97e0d 4872 //
6c94f330 4873 if (track0->Get1Pt()<0) continue;
81e97e0d 4874 if (track0->GetKinkIndex(0)>0||isPrim[i]) continue; //daughter kink
4875 //
4876 if (TMath::Abs(helixes[i].GetHelix(4))<0.000000001) continue;
4877 ntracks++;
4878 // debug output
4879
4880
4881 for (Int_t j =0;j<nentries;j++){
4882 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
4883 if (!track1) continue;
4884 if (track1->GetKinkIndex(0)>0 || isPrim[j]) continue; //daughter kink
4885 if (sign[j]*sign[i]>0) continue;
4886 if (TMath::Abs(helixes[j].GetHelix(4))<0.000001) continue;
b9671574 4887 if (track0->GetCircular()+track1->GetCircular()>1) continue; //circling -returning track
81e97e0d 4888 nall++;
4889 //
4890 // DCA to prim vertex cut
4891 //
4892 //
4893 delta[0]=10000;
4894 delta[1]=10000;
4895
4896 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,cdist2);
4897 if (npoints<1) continue;
4898 Int_t iclosest=0;
4899 // cuts on radius
4900 if (npoints==1){
4901 if (radius[0]<cradius0||radius[0]>cradius1) continue;
4902 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta[0]);
4903 if (delta[0]>cdist1) continue;
4904 }
4905 else{
4906 if (TMath::Max(radius[0],radius[1])<cradius0|| TMath::Min(radius[0],radius[1])>cradius1) continue;
4907 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta[0]);
4908 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta[1]);
4909 if (delta[1]<delta[0]) iclosest=1;
4910 if (delta[iclosest]>cdist1) continue;
4911 }
4912 helixes[i].ParabolicDCA(helixes[j],phase[iclosest][0],phase[iclosest][1],radius[iclosest],delta[iclosest]);
4913 if (radius[iclosest]<cradius0 || radius[iclosest]>cradius1 || delta[iclosest]>cdist1) continue;
4914 //
4915 Double_t pointAngle = helixes[i].GetPointAngle(helixes[j],phase[iclosest],fprimvertex);
4916 if (pointAngle<cpointAngle) continue;
4917 //
4918 Bool_t isGamma = kFALSE;
b75d63a7 4919 vertex.SetParamP(*track0); //track0 - plus
4920 vertex.SetParamN(*track1); //track1 - minus
81e97e0d 4921 vertex.Update(fprimvertex);
b9671574 4922 if (track0->TPCrPID(0)>0.3&&track1->TPCrPID(0)>0.3&&vertex.GetAnglep()[2]<0.15) isGamma=kTRUE; // gamma conversion candidate
b75d63a7 4923 Double_t pointAngle2 = vertex.GetV0CosineOfPointingAngle();
81e97e0d 4924 //continue;
b75d63a7 4925 if (vertex.GetV0CosineOfPointingAngle()<cpointAngle && (!isGamma)) continue;// point angle cut
4926 //Bo: if (vertex.GetDist2()>2&&(!isGamma)) continue; // point angle cut
4927 if (vertex.GetDcaV0Daughters()>2&&(!isGamma)) continue;//Bo: // point angle cut
81e97e0d 4928 Float_t sigmae = 0.15*0.15;
4929 if (vertex.GetRr()<80)
4930 sigmae += (sdcar[i]*sdcar[i]+sdcar[j]*sdcar[j])*(1.-vertex.GetRr()/80.)*(1.-vertex.GetRr()/80.);
4931 sigmae+= TMath::Sqrt(sigmae);
b75d63a7 4932 //Bo: if (vertex.GetDist2()/sigmae>3.&&(!isGamma)) continue;
4933 if (vertex.GetDcaV0Daughters()/sigmae>3.&&(!isGamma)) continue;
81e97e0d 4934 Float_t densb0=0,densb1=0,densa0=0,densa1=0;
4935 Int_t row0 = GetRowNumber(vertex.GetRr());
4936 if (row0>15){
b75d63a7 4937 //Bo: if (vertex.GetDist2()>0.2) continue;
4938 if (vertex.GetDcaV0Daughters()>0.2) continue;
81e97e0d 4939 densb0 = track0->Density2(0,row0-5);
4940 densb1 = track1->Density2(0,row0-5);
4941 if (densb0>0.3|| densb1>0.3) continue; //clusters before vertex
4942 densa0 = track0->Density2(row0+5,row0+40);
4943 densa1 = track1->Density2(row0+5,row0+40);
4944 if ((densa0<0.4|| densa1<0.4)&&(!isGamma)) continue; //missing clusters after vertex
4945 }
4946 else{
4947 densa0 = track0->Density2(0,40); //cluster density
4948 densa1 = track1->Density2(0,40); //cluster density
4949 if ((vertex.GetRr()<80&&densa0+densa1<1.)&&(!isGamma)) continue;
4950 }
b75d63a7 4951//Bo: vertex.SetLab(0,track0->GetLabel());
4952//Bo: vertex.SetLab(1,track1->GetLabel());
81e97e0d 4953 vertex.SetChi2After((densa0+densa1)*0.5);
4954 vertex.SetChi2Before((densb0+densb1)*0.5);
4955 vertex.SetIndex(0,i);
4956 vertex.SetIndex(1,j);
b75d63a7 4957//Bo: vertex.SetStatus(1); // TPC v0 candidate
4958 vertex.SetOnFlyStatus(2);//Bo: // TPC v0 candidate
4959//Bo: vertex.SetRp(track0->TPCrPIDs());
4960//Bo: vertex.SetRm(track1->TPCrPIDs());
d6a49f20 4961 tpcv0s->AddLast(new AliESDv0(vertex));
81e97e0d 4962 ncandidates++;
4963 {
31fd97b2 4964 Int_t eventNr = esd->GetEventNumberInFile(); // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
81e97e0d 4965 Double_t radiusm= (delta[0]<delta[1])? TMath::Sqrt(radius[0]):TMath::Sqrt(radius[1]);
4966 Double_t deltam= (delta[0]<delta[1])? TMath::Sqrt(delta[0]):TMath::Sqrt(delta[1]);
b9671574 4967 if (AliTPCReconstructor::StreamLevel()>0) {
4968 Int_t lab0=track0->GetLabel();
4969 Int_t lab1=track1->GetLabel();
4970 Char_t c0=track0->GetCircular();
4971 Char_t c1=track1->GetCircular();
34acb742 4972 cstream<<"V0"<<
81e97e0d 4973 "Event="<<eventNr<<
4974 "vertex.="<<&vertex<<
4975 "Tr0.="<<track0<<
b9671574 4976 "lab0="<<lab0<<
81e97e0d 4977 "Helix0.="<<&helixes[i]<<
4978 "Tr1.="<<track1<<
b9671574 4979 "lab1="<<lab1<<
81e97e0d 4980 "Helix1.="<<&helixes[j]<<
4981 "pointAngle="<<pointAngle<<
4982 "pointAngle2="<<pointAngle2<<
4983 "dca0="<<dca[i]<<
4984 "dca1="<<dca[j]<<
4985 "z0="<<z0[i]<<
4986 "z1="<<z0[j]<<
4987 "zvertex="<<zvertex<<
b9671574 4988 "circular0="<<c0<<
4989 "circular1="<<c1<<
81e97e0d 4990 "npoints="<<npoints<<
4991 "radius0="<<radius[0]<<
4992 "delta0="<<delta[0]<<
4993 "radius1="<<radius[1]<<
4994 "delta1="<<delta[1]<<
4995 "radiusm="<<radiusm<<
4996 "deltam="<<deltam<<
4997 "sdcar0="<<sdcar[i]<<
4998 "sdcar1="<<sdcar[j]<<
4999 "cdcar0="<<cdcar[i]<<
5000 "cdcar1="<<cdcar[j]<<
5001 "pulldcar0="<<pulldcar[i]<<
5002 "pulldcar1="<<pulldcar[j]<<
5003 "pulldcaz0="<<pulldcaz[i]<<
5004 "pulldcaz1="<<pulldcaz[j]<<
5005 "pulldca0="<<pulldca[i]<<
5006 "pulldca1="<<pulldca[j]<<
5007 "densb0="<<densb0<<
5008 "densb1="<<densb1<<
5009 "densa0="<<densa0<<
5010 "densa1="<<densa1<<
5011 "sigmae="<<sigmae<<
b9671574 5012 "\n";}
81e97e0d 5013 }
5014 }
5015 }
5016 Float_t *quality = new Float_t[ncandidates];
5017 Int_t *indexes = new Int_t[ncandidates];
5018 Int_t naccepted =0;
5019 for (Int_t i=0;i<ncandidates;i++){
5020 quality[i] = 0;
d6a49f20 5021 AliESDv0 *v0 = (AliESDv0*)tpcv0s->At(i);
b75d63a7 5022 quality[i] = 1./(1.00001-v0->GetV0CosineOfPointingAngle()); //base point angle
81e97e0d 5023 // quality[i] /= (0.5+v0->GetDist2());
5024 // quality[i] *= v0->GetChi2After(); //density factor
b75d63a7 5025
81e97e0d 5026 Int_t index0 = v0->GetIndex(0);
5027 Int_t index1 = v0->GetIndex(1);
b75d63a7 5028 //Bo: Double_t minpulldca = TMath::Min(2.+pulldca[v0->GetIndex(0)],(2.+pulldca[v0->GetIndex(1)]) ); //pull
5029 Double_t minpulldca = TMath::Min(2.+pulldca[index0],(2.+pulldca[index1]) );//Bo:
5030
5031
5032
81e97e0d 5033 AliTPCseed * track0 = (AliTPCseed*)array->At(index0);
5034 AliTPCseed * track1 = (AliTPCseed*)array->At(index1);
b9671574 5035 if (track0->TPCrPID(0)>0.3&&track1->TPCrPID(0)>0.3&&v0->GetAnglep()[2]<0.15) quality[i]+=1000000; // gamma conversion candidate
5036 if (track0->TPCrPID(4)>0.9||track1->TPCrPID(4)>0.9&&minpulldca>4) quality[i]*=10; // lambda candidate candidate
81e97e0d 5037 }
5038
5039 TMath::Sort(ncandidates,quality,indexes,kTRUE);
5040 //
5041 //
5042 for (Int_t i=0;i<ncandidates;i++){
d6a49f20 5043 AliESDv0 * v0 = (AliESDv0*)tpcv0s->At(indexes[i]);
81e97e0d 5044 if (!v0) continue;
5045 Int_t index0 = v0->GetIndex(0);
5046 Int_t index1 = v0->GetIndex(1);
5047 AliTPCseed * track0 = (AliTPCseed*)array->At(index0);
5048 AliTPCseed * track1 = (AliTPCseed*)array->At(index1);
5049 if (!track0||!track1) {
5050 printf("Bug\n");
5051 continue;
5052 }
5053 Bool_t accept =kTRUE; //default accept
5054 Int_t *v0indexes0 = track0->GetV0Indexes();
5055 Int_t *v0indexes1 = track1->GetV0Indexes();
5056 //
5057 Int_t order0 = (v0indexes0[0]!=0) ? 1:0;
5058 Int_t order1 = (v0indexes1[0]!=0) ? 1:0;
5059 if (v0indexes0[1]!=0) order0 =2;
5060 if (v0indexes1[1]!=0) order1 =2;
5061 //
5062 if (v0indexes0[2]!=0) {order0=3; accept=kFALSE;}
5063 if (v0indexes0[2]!=0) {order1=3; accept=kFALSE;}
5064 //
d6a49f20 5065 AliESDv0 * v02 = v0;
81e97e0d 5066 if (accept){
b75d63a7 5067 //Bo: v0->SetOrder(0,order0);
5068 //Bo: v0->SetOrder(1,order1);
5069 //Bo: v0->SetOrder(1,order0+order1);
d6a49f20 5070 v0->SetOnFlyStatus(kTRUE);
5071 Int_t index = esd->AddV0(v0);
5072 v02 = esd->GetV0(index);
81e97e0d 5073 v0indexes0[order0]=index;
5074 v0indexes1[order1]=index;
5075 naccepted++;
5076 }
5077 {
31fd97b2 5078 Int_t eventNr = esd->GetEventNumberInFile(); // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
b9671574 5079 if (AliTPCReconstructor::StreamLevel()>0) {
5080 Int_t lab0=track0->GetLabel();
5081 Int_t lab1=track1->GetLabel();
34acb742 5082 cstream<<"V02"<<
81e97e0d 5083 "Event="<<eventNr<<
5084 "vertex.="<<v0<<
5085 "vertex2.="<<v02<<
5086 "Tr0.="<<track0<<
b9671574 5087 "lab0="<<lab0<<
81e97e0d 5088 "Tr1.="<<track1<<
b9671574 5089 "lab1="<<lab1<<
81e97e0d 5090 "dca0="<<dca[index0]<<
5091 "dca1="<<dca[index1]<<
5092 "order0="<<order0<<
5093 "order1="<<order1<<
5094 "accept="<<accept<<
5095 "quality="<<quality[i]<<
5096 "pulldca0="<<pulldca[index0]<<
5097 "pulldca1="<<pulldca[index1]<<
5098 "index="<<i<<
b9671574 5099 "\n";}
81e97e0d 5100 }
5101 }
5102
5103
5104 //
5105 //
5106 delete []quality;
5107 delete []indexes;
5108//
5109 delete [] isPrim;
5110 delete [] pulldca;
5111 delete [] pulldcaz;
5112 delete [] pulldcar;
5113 delete [] cdcar;
5114 delete [] sdcar;
5115 delete [] dca;
5116 //
5117 delete[] z0;
5118 delete[] alpha;
5119 delete[] sign;
5120 delete[] helixes;
5121 printf("TPC V0 finder : naccepted\t%d\tncandidates\t%d\tntracks\t%d\tnall\t%d\n",naccepted,ncandidates,ntracks,nall);
5122 timer.Print();
5123}
5124
6c94f330 5125Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, AliESDkink &knk)
eea478d3 5126{
5127 //
5128 // refit kink towards to the vertex
5129 //
5130 //
6c94f330 5131 AliKink &kink=(AliKink &)knk;
5132
eea478d3 5133 Int_t row0 = GetRowNumber(kink.GetR());
5134 FollowProlongation(mother,0);
5135 mother.Reset(kFALSE);
5136 //
5137 FollowProlongation(daughter,row0);
5138 daughter.Reset(kFALSE);
5139 FollowBackProlongation(daughter,158);
5140 daughter.Reset(kFALSE);
5141 Int_t first = TMath::Max(row0-20,30);
5142 Int_t last = TMath::Min(row0+20,140);
5143 //
5144 const Int_t kNdiv =5;
5145 AliTPCseed param0[kNdiv]; // parameters along the track
5146 AliTPCseed param1[kNdiv]; // parameters along the track
6c94f330 5147 AliKink kinks[kNdiv]; // corresponding kink parameters
eea478d3 5148 //
5149 Int_t rows[kNdiv];
5150 for (Int_t irow=0; irow<kNdiv;irow++){
5151 rows[irow] = first +((last-first)*irow)/(kNdiv-1);
5152 }
5153 // store parameters along the track
5154 //
5155 for (Int_t irow=0;irow<kNdiv;irow++){
5156 FollowBackProlongation(mother, rows[irow]);
5157 FollowProlongation(daughter,rows[kNdiv-1-irow]);
5158 new(&param0[irow]) AliTPCseed(mother);
5159 new(&param1[kNdiv-1-irow]) AliTPCseed(daughter);
5160 }
5161 //
5162 // define kinks
5163 for (Int_t irow=0; irow<kNdiv-1;irow++){
b9671574 5164 if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
eea478d3 5165 kinks[irow].SetMother(param0[irow]);
5166 kinks[irow].SetDaughter(param1[irow]);
5167 kinks[irow].Update();
5168 }
5169 //
5170 // choose kink with best "quality"
5171 Int_t index =-1;
5172 Double_t mindist = 10000;
5173 for (Int_t irow=0;irow<kNdiv;irow++){
b9671574 5174 if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
eea478d3 5175 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
5176 if (TMath::Abs(kinks[irow].GetR())<100.) continue;
5177 //
6c94f330 5178 Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
b9671574 5179 normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
eea478d3 5180 if (normdist < mindist){
5181 mindist = normdist;
5182 index = irow;
5183 }
5184 }
5185 //
5186 if (index==-1) return 0;
5187 //
5188 //
5189 param0[index].Reset(kTRUE);
5190 FollowProlongation(param0[index],0);
5191 //
5192 new (&mother) AliTPCseed(param0[index]);
5193 new (&daughter) AliTPCseed(param1[index]); // daughter in vertex
5194 //
5195 kink.SetMother(mother);
5196 kink.SetDaughter(daughter);
5197 kink.Update();
5198 kink.SetTPCRow0(GetRowNumber(kink.GetR()));
b9671574 5199 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
5200 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
eea478d3 5201 kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
5202 kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
5203 mother.SetLabel(kink.GetLabel(0));
5204 daughter.SetLabel(kink.GetLabel(1));
5205
5206 return 1;
5207}
51ad6848 5208
5209
5210void AliTPCtrackerMI::UpdateKinkQualityM(AliTPCseed * seed){
5211 //
5212 // update Kink quality information for mother after back propagation
5213 //
5214 if (seed->GetKinkIndex(0)>=0) return;
5215 for (Int_t ikink=0;ikink<3;ikink++){
5216 Int_t index = seed->GetKinkIndex(ikink);
5217 if (index>=0) break;
5218 index = TMath::Abs(index)-1;
5219 AliESDkink * kink = fEvent->GetKink(index);
eea478d3 5220 //kink->fTPCdensity2[0][0]=-1;
5221 //kink->fTPCdensity2[0][1]=-1;
5222 kink->SetTPCDensity2(-1,0,0);
5223 kink->SetTPCDensity2(1,0,1);
51ad6848 5224 //
eea478d3 5225 Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 5226 if (row0<15) row0=15;
5227 //
eea478d3 5228 Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
51ad6848 5229 if (row1>145) row1=145;
5230 //
5231 Int_t found,foundable,shared;
5232 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
eea478d3 5233 if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),0,0);
51ad6848 5234 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
eea478d3 5235 if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),0,1);
51ad6848 5236 }
5237
5238}
5239
eea478d3 5240void AliTPCtrackerMI::UpdateKinkQualityD(AliTPCseed * seed){
91162307 5241 //
eea478d3 5242 // update Kink quality information for daughter after refit
91162307 5243 //
eea478d3 5244 if (seed->GetKinkIndex(0)<=0) return;
5245 for (Int_t ikink=0;ikink<3;ikink++){
5246 Int_t index = seed->GetKinkIndex(ikink);
5247 if (index<=0) break;
5248 index = TMath::Abs(index)-1;
5249 AliESDkink * kink = fEvent->GetKink(index);
5250 kink->SetTPCDensity2(-1,1,0);
5251 kink->SetTPCDensity2(-1,1,1);
91162307 5252 //
eea478d3 5253 Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5254 if (row0<15) row0=15;
5255 //
5256 Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5257 if (row1>145) row1=145;
5258 //
5259 Int_t found,foundable,shared;
5260 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
5261 if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),1,0);
5262 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
5263 if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),1,1);
91162307 5264 }
eea478d3 5265
5266}
5267
5268
6c94f330 5269Int_t AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, AliESDkink &knk)
eea478d3 5270{
91162307 5271 //
eea478d3 5272 // check kink point for given track
5273 // if return value=0 kink point not found
5274 // otherwise seed0 correspond to mother particle
5275 // seed1 correspond to daughter particle
5276 // kink parameter of kink point
6c94f330 5277 AliKink &kink=(AliKink &)knk;
91162307 5278
b9671574 5279 Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
5280 Int_t first = seed->GetFirstPoint();
5281 Int_t last = seed->GetLastPoint();
eea478d3 5282 if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
91162307 5283
eea478d3 5284
5285 AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
5286 if (!seed1) return 0;
b9671574 5287 FollowProlongation(*seed1,seed->GetLastPoint()-20);
eea478d3 5288 seed1->Reset(kTRUE);
5289 FollowProlongation(*seed1,158);
5290 seed1->Reset(kTRUE);
b9671574 5291 last = seed1->GetLastPoint();
eea478d3 5292 //
5293 AliTPCseed *seed0 = new AliTPCseed(*seed);
5294 seed0->Reset(kFALSE);
5295 seed0->Reset();
5296 //
5297 AliTPCseed param0[20]; // parameters along the track
5298 AliTPCseed param1[20]; // parameters along the track
6c94f330 5299 AliKink kinks[20]; // corresponding kink parameters
eea478d3 5300 Int_t rows[20];
5301 for (Int_t irow=0; irow<20;irow++){
5302 rows[irow] = first +((last-first)*irow)/19;
5303 }
5304 // store parameters along the track
5305 //
5306 for (Int_t irow=0;irow<20;irow++){
5307 FollowBackProlongation(*seed0, rows[irow]);
5308 FollowProlongation(*seed1,rows[19-irow]);
5309 new(&param0[irow]) AliTPCseed(*seed0);
5310 new(&param1[19-irow]) AliTPCseed(*seed1);
5311 }
5312 //
5313 // define kinks
5314 for (Int_t irow=0; irow<19;irow++){
5315 kinks[irow].SetMother(param0[irow]);
5316 kinks[irow].SetDaughter(param1[irow]);
5317 kinks[irow].Update();
5318 }
5319 //
5320 // choose kink with biggest change of angle
5321 Int_t index =-1;
5322 Double_t maxchange= 0;
5323 for (Int_t irow=1;irow<19;irow++){
5324 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
5325 if (TMath::Abs(kinks[irow].GetR())<110.) continue;
6c94f330 5326 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 5327 if ( quality > maxchange){
5328 maxchange = quality;
5329 index = irow;
5330 //
91162307 5331 }
5332 }
eea478d3 5333 delete seed0;
5334 delete seed1;
5335 if (index<0) return 0;
5336 //
5337 Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
5338 seed0 = new AliTPCseed(param0[index]);
5339 seed1 = new AliTPCseed(param1[index]);
5340 seed0->Reset(kFALSE);
5341 seed1->Reset(kFALSE);
6c94f330 5342 seed0->ResetCovariance(10.);
5343 seed1->ResetCovariance(10.);
eea478d3 5344 FollowProlongation(*seed0,0);
5345 FollowBackProlongation(*seed1,158);
5346 new (&mother) AliTPCseed(*seed0); // backup mother at position 0
5347 seed0->Reset(kFALSE);
5348 seed1->Reset(kFALSE);
6c94f330 5349 seed0->ResetCovariance(10.);
5350 seed1->ResetCovariance(10.);
eea478d3 5351 //
5352 first = TMath::Max(row0-20,0);
5353 last = TMath::Min(row0+20,158);
5354 //
5355 for (Int_t irow=0; irow<20;irow++){
5356 rows[irow] = first +((last-first)*irow)/19;
5357 }
5358 // store parameters along the track
5359 //
5360 for (Int_t irow=0;irow<20;irow++){
5361 FollowBackProlongation(*seed0, rows[irow]);
5362 FollowProlongation(*seed1,rows[19-irow]);
5363 new(&param0[irow]) AliTPCseed(*seed0);
5364 new(&param1[19-irow]) AliTPCseed(*seed1);
5365 }
5366 //
5367 // define kinks
5368 for (Int_t irow=0; irow<19;irow++){
5369 kinks[irow].SetMother(param0[irow]);
5370 kinks[irow].SetDaughter(param1[irow]);
5371 // param0[irow].Dump();
5372 //param1[irow].Dump();
5373 kinks[irow].Update();
5374 }
5375 //
5376 // choose kink with biggest change of angle
5377 index =-1;
5378 maxchange= 0;
5379 for (Int_t irow=0;irow<20;irow++){
5380 if (TMath::Abs(kinks[irow].GetR())>250.) continue;
5381 if (TMath::Abs(kinks[irow].GetR())<90.) continue;
6c94f330 5382 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
eea478d3 5383 if ( quality > maxchange){
5384 maxchange = quality;
5385 index = irow;
5386 //
91162307 5387 }
5388 }
5389 //
5390 //
b9671574 5391 if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
eea478d3 5392 delete seed0;
5393 delete seed1;
5394 return 0;
1627d1c4 5395 }
eea478d3 5396 // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
1627d1c4 5397
eea478d3 5398 kink.SetMother(param0[index]);
5399 kink.SetDaughter(param1[index]);
5400 kink.Update();
5401 row0 = GetRowNumber(kink.GetR());
5402 kink.SetTPCRow0(row0);
5403 kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
5404 kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
5405 kink.SetIndex(-10,0);
b9671574 5406 kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
5407 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
5408 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
eea478d3 5409 //
5410 //
5411 // new (&mother) AliTPCseed(param0[index]);
5412 new (&daughter) AliTPCseed(param1[index]);
5413 daughter.SetLabel(kink.GetLabel(1));
5414 param0[index].Reset(kTRUE);
5415 FollowProlongation(param0[index],0);
5416 new (&mother) AliTPCseed(param0[index]);
5417 mother.SetLabel(kink.GetLabel(0));
5418 delete seed0;
5419 delete seed1;
5420 //
5421 return 1;
1627d1c4 5422}
5423
5424
5425
5426
91162307 5427AliTPCseed* AliTPCtrackerMI::ReSeed(AliTPCseed *t)
5428{
5429 //
5430 // reseed - refit - track
5431 //
5432 Int_t first = 0;
5433 // Int_t last = fSectors->GetNRows()-1;
5434 //
5435 if (fSectors == fOuterSec){
b9671574 5436 first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
91162307 5437 //last =
5438 }
5439 else
b9671574 5440 first = t->GetFirstPoint();
91162307 5441 //
5442 AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
5443 FollowBackProlongation(*t,fSectors->GetNRows()-1);
5444 t->Reset(kFALSE);
5445 FollowProlongation(*t,first);
5446 return seed;
5447}
5448
5449
5450
5451
5452
5453
5454
1c53abe2 5455//_____________________________________________________________________________
5456Int_t AliTPCtrackerMI::ReadSeeds(const TFile *inp) {
5457 //-----------------------------------------------------------------
5458 // This function reades track seeds.
5459 //-----------------------------------------------------------------
5460 TDirectory *savedir=gDirectory;
5461
5462 TFile *in=(TFile*)inp;
5463 if (!in->IsOpen()) {
5464 cerr<<"AliTPCtrackerMI::ReadSeeds(): input file is not open !\n";
5465 return 1;
5466 }
5467
5468 in->cd();
5469 TTree *seedTree=(TTree*)in->Get("Seeds");
5470 if (!seedTree) {
5471 cerr<<"AliTPCtrackerMI::ReadSeeds(): ";
5472 cerr<<"can't get a tree with track seeds !\n";
5473 return 2;
5474 }
5475 AliTPCtrack *seed=new AliTPCtrack;
5476 seedTree->SetBranchAddress("tracks",&seed);
5477
5478 if (fSeeds==0) fSeeds=new TObjArray(15000);
5479
5480 Int_t n=(Int_t)seedTree->GetEntries();
5481 for (Int_t i=0; i<n; i++) {
5482 seedTree->GetEvent(i);
bbc6cd2c 5483 fSeeds->AddLast(new AliTPCseed(*seed/*,seed->GetAlpha()*/));
1c53abe2 5484 }
5485
5486 delete seed;
5487 delete seedTree;
5488 savedir->cd();
5489 return 0;
5490}
5491
d26d9159 5492Int_t AliTPCtrackerMI::Clusters2Tracks (AliESD *esd)
5493{
5494 //
d9b8978b 5495 if (fSeeds) DeleteSeeds();
d26d9159 5496 fEvent = esd;
5497 Clusters2Tracks();
5498 if (!fSeeds) return 1;
5499 FillESD(fSeeds);
5500 return 0;
5501 //
5502}
5503
5504
1c53abe2 5505//_____________________________________________________________________________
f8aae377 5506Int_t AliTPCtrackerMI::Clusters2Tracks() {
1c53abe2 5507 //-----------------------------------------------------------------
5508 // This is a track finder.
5509 //-----------------------------------------------------------------
91162307 5510 TDirectory *savedir=gDirectory;
1c53abe2 5511 TStopwatch timer;
d26d9159 5512
91162307 5513 fIteration = 0;
5514 fSeeds = Tracking();
1c53abe2 5515
6bdc18d6 5516 if (fDebug>0){
5517 Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
5518 }
91162307 5519 //activate again some tracks
5520 for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
5521 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
5522 if (!pt) continue;
5523 Int_t nc=t.GetNumberOfClusters();
5524 if (nc<20) {
5525 delete fSeeds->RemoveAt(i);
5526 continue;
eea478d3 5527 }
5528 CookLabel(pt,0.1);
b9671574 5529 if (pt->GetRemoval()==10) {
91162307 5530 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
5531 pt->Desactivate(10); // make track again active
5532 else{
5533 pt->Desactivate(20);
5534 delete fSeeds->RemoveAt(i);
5535 }
5536 }
5537 }
51ad6848 5538 //
5539 RemoveUsed2(fSeeds,0.85,0.85,0);
a3232aae 5540 if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
81e97e0d 5541 RemoveUsed2(fSeeds,0.5,0.4,20);
5542 // //
5543// // refit short tracks
5544// //
5545 Int_t nseed=fSeeds->GetEntriesFast();
5546// for (Int_t i=0; i<nseed; i++) {
5547// AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
5548// if (!pt) continue;
5549// Int_t nc=t.GetNumberOfClusters();
5550// if (nc<15) {
5551// delete fSeeds->RemoveAt(i);
5552// continue;
5553// }
5554// if (pt->GetKinkIndexes()[0]!=0) continue; // ignore kink candidates
5555// if (nc>100) continue; // hopefully, enough for ITS
5556// AliTPCseed *seed2 = new AliTPCseed(*pt);
5557// //seed2->Reset(kFALSE);
5558// //pt->ResetCovariance();
5559// seed2->Modify(1);
5560// FollowBackProlongation(*seed2,158);
5561// //seed2->Reset(kFALSE);
5562// seed2->Modify(10);
5563// FollowProlongation(*seed2,0);
5564// TTreeSRedirector &cstream = *fDebugStreamer;
5565// cstream<<"Crefit"<<
5566// "Tr0.="<<pt<<
5567// "Tr1.="<<seed2<<
5568// "\n";
5569// if (seed2->fN>pt->fN){
5570// delete fSeeds->RemoveAt(i);
5571// fSeeds->AddAt(seed2,i);
5572// }else{
5573// delete seed2;
5574// }
5575// }
5576// RemoveUsed2(fSeeds,0.6,0.6,50);
5577
5578// FindV0s(fSeeds,fEvent);
51ad6848 5579 //RemoveDouble(fSeeds,0.2,0.6,11);
c9427e08 5580
1c53abe2 5581 //
91162307 5582 Int_t found = 0;
5583 for (Int_t i=0; i<nseed; i++) {
5584 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
5585 if (!pt) continue;
5586 Int_t nc=t.GetNumberOfClusters();
5587 if (nc<15) {
5588 delete fSeeds->RemoveAt(i);
5589 continue;
5590 }
5591 CookLabel(pt,0.1); //For comparison only
5592 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 5593 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
d9b8978b 5594 found++;
5595 if (fDebug>0) cerr<<found<<'\r';
b9671574 5596 pt->SetLab2(i);
91162307 5597 }
5598 else
5599 delete fSeeds->RemoveAt(i);
91162307 5600 }
5601
5602
5603 //RemoveOverlap(fSeeds,0.99,7,kTRUE);
5604 SignShared(fSeeds);
5605 //RemoveUsed(fSeeds,0.9,0.9,6);
1c53abe2 5606 //
91162307 5607 nseed=fSeeds->GetEntriesFast();
5608 found = 0;
5609 for (Int_t i=0; i<nseed; i++) {
5610 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
5611 if (!pt) continue;
5612 Int_t nc=t.GetNumberOfClusters();
5613 if (nc<15) {
5614 delete fSeeds->RemoveAt(i);
5615 continue;
5616 }
5617 t.SetUniqueID(i);
5618 t.CookdEdx(0.02,0.6);
5619 // CheckKinkPoint(&t,0.05);
5620 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
b9671574 5621 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6bdc18d6 5622 found++;
5623 if (fDebug>0){
5624 cerr<<found<<'\r';
5625 }
b9671574 5626 pt->SetLab2(i);
91162307 5627 }
5628 else
5629 delete fSeeds->RemoveAt(i);
d26d9159 5630 //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
5631 //if (seed1){
5632 // FollowProlongation(*seed1,0);
5633 // Int_t n = seed1->GetNumberOfClusters();
5634 // printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
5635 // printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
5636 //
5637 //}
5638 //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
5639
91162307 5640 }
5641
5642 SortTracks(fSeeds, 1);
1c53abe2 5643
982aff31 5644 /*
91162307 5645 fIteration = 1;
982aff31 5646 PrepareForBackProlongation(fSeeds,5.);
91162307 5647 PropagateBack(fSeeds);
5648 printf("Time for back propagation: \t");timer.Print();timer.Start();
5649
5650 fIteration = 2;
1c53abe2 5651
982aff31 5652 PrepareForProlongation(fSeeds,5.);
5653 PropagateForward2(fSeeds);
d26d9159 5654
91162307 5655 printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
5656 // RemoveUsed(fSeeds,0.7,0.7,6);
5657 //RemoveOverlap(fSeeds,0.9,7,kTRUE);
d26d9159 5658
1c53abe2 5659 nseed=fSeeds->GetEntriesFast();
91162307 5660 found = 0;
5661 for (Int_t i=0; i<nseed; i++) {
1c53abe2 5662 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
5663 if (!pt) continue;
5664 Int_t nc=t.GetNumberOfClusters();
91162307 5665 if (nc<15) {
5666 delete fSeeds->RemoveAt(i);
5667 continue;
5668 }
1c53abe2 5669 t.CookdEdx(0.02,0.6);
91162307 5670 // CookLabel(pt,0.1); //For comparison only
5671 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
5672 if ((pt->IsActive() || (pt->fRemoval==10) )){
5673 cerr<<found++<<'\r';
5674 }
5675 else
5676 delete fSeeds->RemoveAt(i);
5677 pt->fLab2 = i;
1c53abe2 5678 }
91162307 5679 */
5680
c9427e08 5681 // fNTracks = found;
6bdc18d6 5682 if (fDebug>0){
5683 Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
5684 }
91162307 5685 //
6bdc18d6 5686 // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
5687 Info("Clusters2Tracks","Number of found tracks %d",found);
91162307 5688 savedir->cd();
91162307 5689 // UnloadClusters();
d26d9159 5690 //
1c53abe2 5691 return 0;
5692}
5693
91162307 5694void AliTPCtrackerMI::Tracking(TObjArray * arr)
5695{
5696 //
5697 // tracking of the seeds
5698 //
5699
5700 fSectors = fOuterSec;
5701 ParallelTracking(arr,150,63);
5702 fSectors = fOuterSec;
5703 ParallelTracking(arr,63,0);
5704}
5705
5706TObjArray * AliTPCtrackerMI::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
5707{
5708 //
5709 //
5710 //tracking routine
5711 TObjArray * arr = new TObjArray;
5712 //
5713 fSectors = fOuterSec;
5714 TStopwatch timer;
5715 timer.Start();
5716 for (Int_t sec=0;sec<fkNOS;sec++){
5717 if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
5718 if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);
5719 if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
5720 }
5721 if (fDebug>0){
6bdc18d6 5722 Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
91162307 5723 timer.Print();
5724 timer.Start();
5725 }
5726 Tracking(arr);
5727 if (fDebug>0){
5728 timer.Print();
5729 }
5730
5731 return arr;
5732}
5733
5734TObjArray * AliTPCtrackerMI::Tracking()
5735{
5736 //
5737 //
a3232aae 5738 if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
91162307 5739 TStopwatch timer;
5740 timer.Start();
5741 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
5742
5743 TObjArray * seeds = new TObjArray;
5744 TObjArray * arr=0;
5745
5746 Int_t gap =20;
5747 Float_t cuts[4];
5748 cuts[0] = 0.002;
5749 cuts[1] = 1.5;
5750 cuts[2] = 3.;
5751 cuts[3] = 3.;
5752 Float_t fnumber = 3.0;
5753 Float_t fdensity = 3.0;
5754
5755 //
5756 //find primaries
5757 cuts[0]=0.0066;
5758 for (Int_t delta = 0; delta<18; delta+=6){
5759 //
5760 cuts[0]=0.0070;
5761 cuts[1] = 1.5;
5762 arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
5763 SumTracks(seeds,arr);
5764 SignClusters(seeds,fnumber,fdensity);
5765 //
5766 for (Int_t i=2;i<6;i+=2){
5767 // seed high pt tracks
5768 cuts[0]=0.0022;
5769 cuts[1]=0.3;
5770 arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
5771 SumTracks(seeds,arr);
5772 SignClusters(seeds,fnumber,fdensity);
5773 }
5774 }
5775 fnumber = 4;
5776 fdensity = 4.;
5777 // RemoveUsed(seeds,0.9,0.9,1);
5778 // UnsignClusters();
5779 // SignClusters(seeds,fnumber,fdensity);
5780
5781 //find primaries
5782 cuts[0]=0.0077;
5783 for (Int_t delta = 20; delta<120; delta+=10){
5784 //
5785 // seed high pt tracks
5786 cuts[0]=0.0060;
5787 cuts[1]=0.3;
5788 cuts[2]=6.;
5789 arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
5790 SumTracks(seeds,arr);
5791 SignClusters(seeds,fnumber,fdensity);
5792
5793 cuts[0]=0.003;
5794 cuts[1]=0.3;
5795 cuts[2]=6.;
5796 arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
5797 SumTracks(seeds,arr);
5798 SignClusters(seeds,fnumber,fdensity);
5799 }
5800
5801 cuts[0] = 0.01;
5802 cuts[1] = 2.0;
5803 cuts[2] = 3.;
5804 cuts[3] = 2.0;
5805 fnumber = 2.;
5806 fdensity = 2.;
5807
5808 if (fDebug>0){
6bdc18d6 5809 Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 5810 timer.Print();
5811 timer.Start();
5812 }
5813 // RemoveUsed(seeds,0.75,0.75,1);
5814 //UnsignClusters();
5815 //SignClusters(seeds,fnumber,fdensity);
5816
5817 // find secondaries
5818
5819 cuts[0] = 0.3;
5820 cuts[1] = 1.5;
5821 cuts[2] = 3.;
5822 cuts[3] = 1.5;
5823
5824 arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
5825 SumTracks(seeds,arr);
5826 SignClusters(seeds,fnumber,fdensity);
5827 //
5828 arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
5829 SumTracks(seeds,arr);
5830 SignClusters(seeds,fnumber,fdensity);
5831 //
5832 arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
5833 SumTracks(seeds,arr);
5834 SignClusters(seeds,fnumber,fdensity);
5835 //
5836
5837
5838 for (Int_t delta = 3; delta<30; delta+=5){
5839 //
5840 cuts[0] = 0.3;
5841 cuts[1] = 1.5;
5842 cuts[2] = 3.;
5843 cuts[3] = 1.5;
5844 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
5845 SumTracks(seeds,arr);
5846 SignClusters(seeds,fnumber,fdensity);
5847 //
5848 arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
5849 SumTracks(seeds,arr);
5850 SignClusters(seeds,fnumber,fdensity);
5851 //
5852 }
5853 fnumber = 1;
5854 fdensity = 1;
5855 //
5856 // change cuts
5857 fnumber = 2.;
5858 fdensity = 2.;
5859 cuts[0]=0.0080;
5860
5861 // find secondaries
2bd61959 5862 for (Int_t delta = 30; delta<90; delta+=10){
91162307 5863 //
5864 cuts[0] = 0.3;
2bd61959 5865 cuts[1] = 3.5;
91162307 5866 cuts[2] = 3.;
2bd61959 5867 cuts[3] = 3.5;
91162307 5868 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
5869 SumTracks(seeds,arr);
5870 SignClusters(seeds,fnumber,fdensity);
5871 //
5872 arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
5873 SumTracks(seeds,arr);
5874 SignClusters(seeds,fnumber,fdensity);
5875 }
5876
5877 if (fDebug>0){
6bdc18d6 5878 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
91162307 5879 timer.Print();
5880 timer.Start();
5881 }
5882
5883 return seeds;
5884 //
5885
5886}
5887
5888
a3232aae 5889TObjArray * AliTPCtrackerMI::TrackingSpecial()
5890{
5891 //
5892 // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
5893 // no primary vertex seeding tried
5894 //
5895 TStopwatch timer;
5896 timer.Start();
5897 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
5898
5899 TObjArray * seeds = new TObjArray;
5900 TObjArray * arr=0;
5901
5902 Int_t gap = 15;
5903 Float_t cuts[4];
5904 Float_t fnumber = 3.0;
5905 Float_t fdensity = 3.0;
5906
5907 // find secondaries
5908 cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC(); // max curvature
5909 cuts[1] = 3.5; // max tan(phi) angle for seeding
5910 cuts[2] = 3.; // not used (cut on z primary vertex)
5911 cuts[3] = 3.5; // max tan(theta) angle for seeding
5912
5913 for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
5914 //
5915 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
5916 SumTracks(seeds,arr);
5917 SignClusters(seeds,fnumber,fdensity);
5918 }
5919
5920 if (fDebug>0){
5921 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
5922 timer.Print();
5923 timer.Start();
5924 }
5925
5926 return seeds;
5927 //
5928
5929}
5930
5931
47966a6d 5932void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *arr2) const
91162307 5933{
5934 //
5935 //sum tracks to common container
5936 //remove suspicious tracks
5937 Int_t nseed = arr2->GetEntriesFast();
5938 for (Int_t i=0;i<nseed;i++){
5939 AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);
5940 if (pt){
a3232aae 5941 //
5942 // remove tracks with too big curvature
5943 //
5944 if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
5945 delete arr2->RemoveAt(i);
5946 continue;
5947 }
ca142b1f 5948 // REMOVE VERY SHORT TRACKS
5949 if (pt->GetNumberOfClusters()<20){
5950 delete arr2->RemoveAt(i);
5951 continue;
5952 }// patch 28 fev06
91162307 5953 // NORMAL ACTIVE TRACK
5954 if (pt->IsActive()){
5955 arr1->AddLast(arr2->RemoveAt(i));
5956 continue;
5957 }
5958 //remove not usable tracks
b9671574 5959 if (pt->GetRemoval()!=10){
91162307 5960 delete arr2->RemoveAt(i);
5961 continue;
5962 }
ca142b1f 5963
91162307 5964 // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
5965 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
5966 arr1->AddLast(arr2->RemoveAt(i));
5967 else{
5968 delete arr2->RemoveAt(i);
5969 }
5970 }
5971 }
5972 delete arr2;
5973}
5974
5975
1c53abe2 5976
91162307 5977void AliTPCtrackerMI::ParallelTracking(TObjArray * arr, Int_t rfirst, Int_t rlast)
1c53abe2 5978{
5979 //
5980 // try to track in parralel
5981
91162307 5982 Int_t nseed=arr->GetEntriesFast();
1c53abe2 5983 //prepare seeds for tracking
5984 for (Int_t i=0; i<nseed; i++) {
91162307 5985 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 5986 if (!pt) continue;
5987 if (!t.IsActive()) continue;
5988 // follow prolongation to the first layer
b9671574 5989 if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fParam->GetNRowLow()>rfirst+1) )
c9427e08 5990 FollowProlongation(t, rfirst+1);
1c53abe2 5991 }
5992
5993
5994 //
982aff31 5995 for (Int_t nr=rfirst; nr>=rlast; nr--){
5996 if (nr<fInnerSec->GetNRows())
5997 fSectors = fInnerSec;
5998 else
5999 fSectors = fOuterSec;
1c53abe2 6000 // make indexes with the cluster tracks for given
1c53abe2 6001
6002 // find nearest cluster
6003 for (Int_t i=0; i<nseed; i++) {
91162307 6004 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
1c53abe2 6005 if (!pt) continue;
51ad6848 6006 if (nr==80) pt->UpdateReference();
1c53abe2 6007 if (!pt->IsActive()) continue;
91162307 6008 // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
b9671574 6009 if (pt->GetRelativeSector()>17) {
1627d1c4 6010 continue;
6011 }
91162307 6012 UpdateClusters(t,nr);
1c53abe2 6013 }
6014 // prolonagate to the nearest cluster - if founded
6015 for (Int_t i=0; i<nseed; i++) {
91162307 6016 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
1c53abe2 6017 if (!pt) continue;
1627d1c4 6018 if (!pt->IsActive()) continue;
91162307 6019 // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
b9671574 6020 if (pt->GetRelativeSector()>17) {
1627d1c4 6021 continue;
6022 }
91162307 6023 FollowToNextCluster(*pt,nr);
1c53abe2 6024 }
91162307 6025 }
6026}
6027
47966a6d 6028void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray * arr,Float_t fac) const
91162307 6029{
6030 //
6031 //
6032 // if we use TPC track itself we have to "update" covariance
6033 //
6034 Int_t nseed= arr->GetEntriesFast();
6035 for (Int_t i=0;i<nseed;i++){
6036 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6037 if (pt) {
6038 pt->Modify(fac);
6039 //
6040 //rotate to current local system at first accepted point
b9671574 6041 Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
91162307 6042 Int_t sec = (index&0xff000000)>>24;
6043 sec = sec%18;
6044 Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
6045 if (angle1>TMath::Pi())
6046 angle1-=2.*TMath::Pi();
6047 Float_t angle2 = pt->GetAlpha();
6048
6049 if (TMath::Abs(angle1-angle2)>0.001){
6050 pt->Rotate(angle1-angle2);
6051 //angle2 = pt->GetAlpha();
6052 //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
6053 //if (pt->GetAlpha()<0)
6054 // pt->fRelativeSector+=18;
6055 //sec = pt->fRelativeSector;
6056 }
6057
6058 }
6059
6060 }
6061
6062
6063}
47966a6d 6064void AliTPCtrackerMI::PrepareForProlongation(TObjArray * arr, Float_t fac) const
91162307 6065{
6066 //
6067 //
6068 // if we use TPC track itself we have to "update" covariance
6069 //
6070 Int_t nseed= arr->GetEntriesFast();
6071 for (Int_t i=0;i<nseed;i++){
6072 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6073 if (pt) {
6074 pt->Modify(fac);
b9671574 6075 pt->SetFirstPoint(pt->GetLastPoint());
91162307 6076 }
6077
6078 }
6079
6080
6081}
6082
6083Int_t AliTPCtrackerMI::PropagateBack(TObjArray * arr)
6084{
6085 //
6086 // make back propagation
6087 //
6088 Int_t nseed= arr->GetEntriesFast();
6089 for (Int_t i=0;i<nseed;i++){
6090 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
51ad6848 6091 if (pt&& pt->GetKinkIndex(0)<=0) {
d9b8978b 6092 //AliTPCseed *pt2 = new AliTPCseed(*pt);
91162307 6093 fSectors = fInnerSec;
d26d9159 6094 //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
6095 //fSectors = fOuterSec;
4d158c36 6096 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
6097 //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
d9b8978b 6098 // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
4d158c36 6099 // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
d9b8978b 6100 //}
51ad6848 6101 }
6102 if (pt&& pt->GetKinkIndex(0)>0) {
6103 AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
b9671574 6104 pt->SetFirstPoint(kink->GetTPCRow0());
51ad6848 6105 fSectors = fInnerSec;
6106 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
6107 }
6108
91162307 6109 }
6110 return 0;
6111}
6112
6113
6114Int_t AliTPCtrackerMI::PropagateForward2(TObjArray * arr)
6115{
6116 //
6117 // make forward propagation
6118 //
6119 Int_t nseed= arr->GetEntriesFast();
4d158c36 6120 //
91162307 6121 for (Int_t i=0;i<nseed;i++){
6122 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6123 if (pt) {
91162307 6124 FollowProlongation(*pt,0);
4d158c36 6125 }
91162307 6126 }
6127 return 0;
6128}
6129
6130
6131Int_t AliTPCtrackerMI::PropagateForward()
6132{
b67e07dc 6133 //
6134 // propagate track forward
4d158c36 6135 //UnsignClusters();
d26d9159 6136 Int_t nseed = fSeeds->GetEntriesFast();
6137 for (Int_t i=0;i<nseed;i++){
6138 AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
6139 if (pt){
6140 AliTPCseed &t = *pt;
6141 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
6142 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
6143 if (alpha < 0. ) alpha += 2.*TMath::Pi();
b9671574 6144 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
d26d9159 6145 }
6146 }
6147
91162307 6148 fSectors = fOuterSec;
d26d9159 6149 ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
91162307 6150 fSectors = fInnerSec;
d26d9159 6151 ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
91162307 6152 //WriteTracks();
6153 return 1;
6154}
6155
6156
6157
6158
6159
6160
6161Int_t AliTPCtrackerMI::PropagateBack(AliTPCseed * pt, Int_t row0, Int_t row1)
6162{
6163 //
6164 // make back propagation, in between row0 and row1
6165 //
1c53abe2 6166
91162307 6167 if (pt) {
6168 fSectors = fInnerSec;
6169 Int_t r1;
6170 //
6171 if (row1<fSectors->GetNRows())
6172 r1 = row1;
6173 else
6174 r1 = fSectors->GetNRows()-1;
6175
6176 if (row0<fSectors->GetNRows()&& r1>0 )
6177 FollowBackProlongation(*pt,r1);
6178 if (row1<=fSectors->GetNRows())
6179 return 0;
6180 //
6181 r1 = row1 - fSectors->GetNRows();
6182 if (r1<=0) return 0;
6183 if (r1>=fOuterSec->GetNRows()) return 0;
6184 fSectors = fOuterSec;
6185 return FollowBackProlongation(*pt,r1);
6186 }
6187 return 0;
6188}
6189
6190
6191
6192
6193void AliTPCtrackerMI::GetShape(AliTPCseed * seed, Int_t row)
6194{
6195 //
6196 //
6197 Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
6198 // Float_t padlength = fParam->GetPadPitchLength(seed->fSector);
6199 Float_t padlength = GetPadPitchLength(row);
6200 //
b9671574 6201 Float_t sresy = (seed->GetSector() < fParam->GetNSector()/2) ? 0.2 :0.3;
3f82c4f2 6202 Double_t angulary = seed->GetSnp();
91162307 6203 angulary = angulary*angulary/(1-angulary*angulary);
b9671574 6204 seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
91162307 6205 //
6206 Float_t sresz = fParam->GetZSigma();
6207 Float_t angularz = seed->GetTgl();
b9671574 6208 seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
91162307 6209 /*
6210 Float_t wy = GetSigmaY(seed);
6211 Float_t wz = GetSigmaZ(seed);
6212 wy*=wy;
6213 wz*=wz;
6214 if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
6215 printf("problem\n");
6216 }
6217 */
1c53abe2 6218}
6219
91162307 6220
1c53abe2 6221Float_t AliTPCtrackerMI::GetSigmaY(AliTPCseed * seed)
6222{
6223 //
6224 //
c9427e08 6225 Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
b9671574 6226 Float_t padlength = fParam->GetPadPitchLength(seed->GetSector());
6227 Float_t sres = (seed->GetSector() < fParam->GetNSector()/2) ? 0.2 :0.3;
1c53abe2 6228 Float_t angular = seed->GetSnp();
6229 angular = angular*angular/(1-angular*angular);
6230 // angular*=angular;
6231 //angular = TMath::Sqrt(angular/(1-angular));
6232 Float_t res = TMath::Sqrt(sd2+padlength*padlength*angular/12.+sres*sres);
6233 return res;
6234}
6235Float_t AliTPCtrackerMI::GetSigmaZ(AliTPCseed * seed)
6236{
6237 //
6238 //
c9427e08 6239 Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
b9671574 6240 Float_t padlength = fParam->GetPadPitchLength(seed->GetSector());
1c53abe2 6241 Float_t sres = fParam->GetZSigma();
6242 Float_t angular = seed->GetTgl();
6243 Float_t res = TMath::Sqrt(sd2+padlength*padlength*angular*angular/12.+sres*sres);
6244 return res;
6245}
6246
6247
1c53abe2 6248//__________________________________________________________________________
af32720d 6249void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
1c53abe2 6250 //--------------------------------------------------------------------
6251 //This function "cooks" a track label. If label<0, this track is fake.
6252 //--------------------------------------------------------------------
af32720d 6253 AliTPCseed * t = (AliTPCseed*)tk;
1c53abe2 6254 Int_t noc=t->GetNumberOfClusters();
91162307 6255 if (noc<10){
d26d9159 6256 //printf("\nnot founded prolongation\n\n\n");
6257 //t->Dump();
91162307 6258 return ;
6259 }
6260 Int_t lb[160];
6261 Int_t mx[160];
6262 AliTPCclusterMI *clusters[160];
6263 //
6264 for (Int_t i=0;i<160;i++) {
6265 clusters[i]=0;
6266 lb[i]=mx[i]=0;
6267 }
1c53abe2 6268
6269 Int_t i;
91162307 6270 Int_t current=0;
6271 for (i=0; i<160 && current<noc; i++) {
6272
6273 Int_t index=t->GetClusterIndex2(i);
6274 if (index<=0) continue;
6275 if (index&0x8000) continue;
6276 //
6277 //clusters[current]=GetClusterMI(index);
b9671574 6278 if (t->GetClusterPointer(i)){
6279 clusters[current]=t->GetClusterPointer(i);
91162307 6280 current++;
6281 }
1c53abe2 6282 }
91162307 6283 noc = current;
1c53abe2 6284
6285 Int_t lab=123456789;
6286 for (i=0; i<noc; i++) {
6287 AliTPCclusterMI *c=clusters[i];
91162307 6288 if (!c) continue;
1c53abe2 6289 lab=TMath::Abs(c->GetLabel(0));
6290 Int_t j;
6291 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
6292 lb[j]=lab;
6293 (mx[j])++;
6294 }
6295
6296 Int_t max=0;
6297 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
6298
6299 for (i=0; i<noc; i++) {
9918f10a 6300 AliTPCclusterMI *c=clusters[i];
91162307 6301 if (!c) continue;
1c53abe2 6302 if (TMath::Abs(c->GetLabel(1)) == lab ||
6303 TMath::Abs(c->GetLabel(2)) == lab ) max++;
6304 }
6305
6306 if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
6307
6308 else {
6309 Int_t tail=Int_t(0.10*noc);
6310 max=0;
91162307 6311 Int_t ind=0;
6312 for (i=1; i<=160&&ind<tail; i++) {
6313 // AliTPCclusterMI *c=clusters[noc-i];
6314 AliTPCclusterMI *c=clusters[i];
6315 if (!c) continue;
1c53abe2 6316 if (lab == TMath::Abs(c->GetLabel(0)) ||
6317 lab == TMath::Abs(c->GetLabel(1)) ||
6318 lab == TMath::Abs(c->GetLabel(2))) max++;
91162307 6319 ind++;
1c53abe2 6320 }
6321 if (max < Int_t(0.5*tail)) lab=-lab;
6322 }
6323
6324 t->SetLabel(lab);
6325
91162307 6326 // delete[] lb;
6327 //delete[] mx;
6328 //delete[] clusters;
1c53abe2 6329}
6330
47966a6d 6331
51ad6848 6332//__________________________________________________________________________
6333Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong,Int_t first, Int_t last) const {
6334 //--------------------------------------------------------------------
6335 //This function "cooks" a track label. If label<0, this track is fake.
6336 //--------------------------------------------------------------------
6337 Int_t noc=t->GetNumberOfClusters();
6338 if (noc<10){
6339 //printf("\nnot founded prolongation\n\n\n");
6340 //t->Dump();
6341 return -1;
6342 }
6343 Int_t lb[160];
6344 Int_t mx[160];
6345 AliTPCclusterMI *clusters[160];
6346 //
6347 for (Int_t i=0;i<160;i++) {
6348 clusters[i]=0;
6349 lb[i]=mx[i]=0;
6350 }
6351
6352 Int_t i;
6353 Int_t current=0;
6354 for (i=0; i<160 && current<noc; i++) {
6355 if (i<first) continue;
6356 if (i>last) continue;
6357 Int_t index=t->GetClusterIndex2(i);
6358 if (index<=0) continue;
6359 if (index&0x8000) continue;
6360 //
6361 //clusters[current]=GetClusterMI(index);
b9671574 6362 if (t->GetClusterPointer(i)){
6363 clusters[current]=t->GetClusterPointer(i);
51ad6848 6364 current++;
6365 }
6366 }
6367 noc = current;
6368 if (noc<5) return -1;
6369 Int_t lab=123456789;
6370 for (i=0; i<noc; i++) {
6371 AliTPCclusterMI *c=clusters[i];
6372 if (!c) continue;
6373 lab=TMath::Abs(c->GetLabel(0));
6374 Int_t j;
6375 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
6376 lb[j]=lab;
6377 (mx[j])++;
6378 }
6379
6380 Int_t max=0;
6381 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
6382
6383 for (i=0; i<noc; i++) {
6384 AliTPCclusterMI *c=clusters[i];
6385 if (!c) continue;
6386 if (TMath::Abs(c->GetLabel(1)) == lab ||
6387 TMath::Abs(c->GetLabel(2)) == lab ) max++;
6388 }
6389
6390 if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
6391
6392 else {
6393 Int_t tail=Int_t(0.10*noc);
6394 max=0;
6395 Int_t ind=0;
6396 for (i=1; i<=160&&ind<tail; i++) {
6397 // AliTPCclusterMI *c=clusters[noc-i];
6398 AliTPCclusterMI *c=clusters[i];
6399 if (!c) continue;
6400 if (lab == TMath::Abs(c->GetLabel(0)) ||
6401 lab == TMath::Abs(c->GetLabel(1)) ||
6402 lab == TMath::Abs(c->GetLabel(2))) max++;
6403 ind++;
6404 }
6405 if (max < Int_t(0.5*tail)) lab=-lab;
6406 }
6407
6408 // t->SetLabel(lab);
6409 return lab;
6410 // delete[] lb;
6411 //delete[] mx;
6412 //delete[] clusters;
6413}
6414
6415
47966a6d 6416Int_t AliTPCtrackerMI::AliTPCSector::GetRowNumber(Double_t x) const
6417{
6418 //return pad row number for this x
6419 Double_t r;
6420 if (fN < 64){
6421 r=fRow[fN-1].GetX();
6422 if (x > r) return fN;
6423 r=fRow[0].GetX();
6424 if (x < r) return -1;
6425 return Int_t((x-r)/fPadPitchLength + 0.5);}
6426 else{
6427 r=fRow[fN-1].GetX();
6428 if (x > r) return fN;
6429 r=fRow[0].GetX();
6430 if (x < r) return -1;
6431 Double_t r1=fRow[64].GetX();
6432 if(x<r1){
6433 return Int_t((x-r)/f1PadPitchLength + 0.5);}
6434 else{
6435 return (Int_t((x-r1)/f2PadPitchLength + 0.5)+64);}
6436 }
6437}
6438
eea478d3 6439Int_t AliTPCtrackerMI::GetRowNumber(Double_t x[3]) const
6440{
6441 //return pad row number for given x vector
6442 Float_t phi = TMath::ATan2(x[1],x[0]);
6443 if(phi<0) phi=2.*TMath::Pi()+phi;
6444 // Get the local angle in the sector philoc
6445 const Float_t kRaddeg = 180/3.14159265358979312;
6446 Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
6447 Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
6448 return GetRowNumber(localx);
6449}
6450
1c53abe2 6451//_________________________________________________________________________
6452void AliTPCtrackerMI::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) {
6453 //-----------------------------------------------------------------------
6454 // Setup inner sector
6455 //-----------------------------------------------------------------------
6456 if (f==0) {
6457 fAlpha=par->GetInnerAngle();
6458 fAlphaShift=par->GetInnerAngleShift();
6459 fPadPitchWidth=par->GetInnerPadPitchWidth();
6460 fPadPitchLength=par->GetInnerPadPitchLength();
6461 fN=par->GetNRowLow();
6462 fRow=new AliTPCRow[fN];
6463 for (Int_t i=0; i<fN; i++) {
6464 fRow[i].SetX(par->GetPadRowRadiiLow(i));
b9671574 6465 fRow[i].SetDeadZone(1.5); //1.5 cm of dead zone
1c53abe2 6466 }
6467 } else {
6468 fAlpha=par->GetOuterAngle();
6469 fAlphaShift=par->GetOuterAngleShift();
6470 fPadPitchWidth = par->GetOuterPadPitchWidth();
6471 fPadPitchLength = par->GetOuter1PadPitchLength();
6472 f1PadPitchLength = par->GetOuter1PadPitchLength();
6473 f2PadPitchLength = par->GetOuter2PadPitchLength();
6474
6475 fN=par->GetNRowUp();
6476 fRow=new AliTPCRow[fN];
6477 for (Int_t i=0; i<fN; i++) {
6478 fRow[i].SetX(par->GetPadRowRadiiUp(i));
b9671574 6479 fRow[i].SetDeadZone(1.5); // 1.5 cm of dead zone
1c53abe2 6480 }
6481 }
6482}
6483
e046d791 6484AliTPCtrackerMI::AliTPCRow::AliTPCRow():
6485 fDeadZone(0.),
6486 fClusters1(0),
6487 fN1(0),
6488 fClusters2(0),
6489 fN2(0),
6490 fN(0),
6491 fX(0.)
6492{
b67e07dc 6493 //
6494 // default constructor
e046d791 6495 //
b67e07dc 6496}
1c53abe2 6497
6498AliTPCtrackerMI::AliTPCRow::~AliTPCRow(){
6499 //
b67e07dc 6500
1c53abe2 6501}
6502
6503
6504
1c53abe2 6505//_________________________________________________________________________
6506void
6507AliTPCtrackerMI::AliTPCRow::InsertCluster(const AliTPCclusterMI* c, UInt_t index) {
6508 //-----------------------------------------------------------------------
6509 // Insert a cluster into this pad row in accordence with its y-coordinate
6510 //-----------------------------------------------------------------------
6511 if (fN==kMaxClusterPerRow) {
6512 cerr<<"AliTPCRow::InsertCluster(): Too many clusters !\n"; return;
6513 }
6514 if (fN==0) {fIndex[0]=index; fClusters[fN++]=c; return;}
6515 Int_t i=Find(c->GetZ());
6516 memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliTPCclusterMI*));
6517 memmove(fIndex +i+1 ,fIndex +i,(fN-i)*sizeof(UInt_t));
6518 fIndex[i]=index; fClusters[i]=c; fN++;
6519}
6520
982aff31 6521void AliTPCtrackerMI::AliTPCRow::ResetClusters() {
6522 //
6523 // reset clusters
6524 fN = 0;
6525 fN1 = 0;
6526 fN2 = 0;
6527 //delete[] fClusterArray;
6528 if (fClusters1) delete []fClusters1;
6529 if (fClusters2) delete []fClusters2;
6530 //fClusterArray=0;
6531 fClusters1 = 0;
6532 fClusters2 = 0;
6533}
6534
91162307 6535
1c53abe2 6536//___________________________________________________________________
6537Int_t AliTPCtrackerMI::AliTPCRow::Find(Double_t z) const {
6538 //-----------------------------------------------------------------------
6539 // Return the index of the nearest cluster
6540 //-----------------------------------------------------------------------
6541 if (fN==0) return 0;
6542 if (z <= fClusters[0]->GetZ()) return 0;
6543 if (z > fClusters[fN-1]->GetZ()) return fN;
6544 Int_t b=0, e=fN-1, m=(b+e)/2;
6545 for (; b<e; m=(b+e)/2) {
6546 if (z > fClusters[m]->GetZ()) b=m+1;
6547 else e=m;
6548 }
6549 return m;
6550}
6551
6552
6553
1627d1c4 6554//___________________________________________________________________
6555AliTPCclusterMI * AliTPCtrackerMI::AliTPCRow::FindNearest(Double_t y, Double_t z, Double_t roady, Double_t roadz) const {
6556 //-----------------------------------------------------------------------
6557 // Return the index of the nearest cluster in z y
6558 //-----------------------------------------------------------------------
6559 Float_t maxdistance = roady*roady + roadz*roadz;
6560
6561 AliTPCclusterMI *cl =0;
6562 for (Int_t i=Find(z-roadz); i<fN; i++) {
6563 AliTPCclusterMI *c=(AliTPCclusterMI*)(fClusters[i]);
6564 if (c->GetZ() > z+roadz) break;
6565 if ( (c->GetY()-y) > roady ) continue;
6566 Float_t distance = (c->GetZ()-z)*(c->GetZ()-z)+(c->GetY()-y)*(c->GetY()-y);
6567 if (maxdistance>distance) {
6568 maxdistance = distance;
6569 cl=c;
6570 }
6571 }
6572 return cl;
6573}
6574
91162307 6575AliTPCclusterMI * AliTPCtrackerMI::AliTPCRow::FindNearest2(Double_t y, Double_t z, Double_t roady, Double_t roadz,UInt_t & index) const
6576{
6577 //-----------------------------------------------------------------------
6578 // Return the index of the nearest cluster in z y
6579 //-----------------------------------------------------------------------
6580 Float_t maxdistance = roady*roady + roadz*roadz;
91162307 6581 AliTPCclusterMI *cl =0;
3381b665 6582
6583 //PH Check boundaries. 510 is the size of fFastCluster
6584 Int_t iz1 = Int_t(z-roadz+254.5);
6585 if (iz1<0 || iz1>=510) return cl;
b9671574 6586 iz1 = TMath::Max(GetFastCluster(iz1)-1,0);
3381b665 6587 Int_t iz2 = Int_t(z+roadz+255.5);
6588 if (iz2<0 || iz2>=510) return cl;
b9671574 6589 iz2 = TMath::Min(GetFastCluster(iz2)+1,fN);
3381b665 6590
91162307 6591 //FindNearest3(y,z,roady,roadz,index);
6592 // for (Int_t i=Find(z-roadz); i<fN; i++) {
6593 for (Int_t i=iz1; i<iz2; i++) {
6594 AliTPCclusterMI *c=(AliTPCclusterMI*)(fClusters[i]);
6595 if (c->GetZ() > z+roadz) break;
6596 if ( c->GetY()-y > roady ) continue;
6597 if ( y-c->GetY() > roady ) continue;
6598 Float_t distance = (c->GetZ()-z)*(c->GetZ()-z)+(c->GetY()-y)*(c->GetY()-y);
6599 if (maxdistance>distance) {
6600 maxdistance = distance;
6601 cl=c;
6602 index =i;
6603 //roady = TMath::Sqrt(maxdistance);
6604 }
6605 }
6606 return cl;
6607}
6608
6609
6610
6611AliTPCclusterMI * AliTPCtrackerMI::AliTPCRow::FindNearest3(Double_t y, Double_t z, Double_t roady, Double_t roadz,UInt_t & index) const
6612{
6613 //-----------------------------------------------------------------------
6614 // Return the index of the nearest cluster in z y
6615 //-----------------------------------------------------------------------
6616 Float_t maxdistance = roady*roady + roadz*roadz;
6617 // Int_t iz = Int_t(z+255.);
6618 AliTPCclusterMI *cl =0;
6619 for (Int_t i=Find(z-roadz); i<fN; i++) {
6620 //for (Int_t i=fFastCluster[iz-2]; i<fFastCluster[iz+2]; i++) {
6621 AliTPCclusterMI *c=(AliTPCclusterMI*)(fClusters[i]);
6622 if (c->GetZ() > z+roadz) break;
6623 if ( c->GetY()-y > roady ) continue;
6624 if ( y-c->GetY() > roady ) continue;
6625 Float_t distance = (c->GetZ()-z)*(c->GetZ()-z)+(c->GetY()-y)*(c->GetY()-y);
6626 if (maxdistance>distance) {
6627 maxdistance = distance;
6628 cl=c;
6629 index =i;
6630 //roady = TMath::Sqrt(maxdistance);
6631 }
6632 }
6633 return cl;
6634}
1627d1c4 6635
6636
6637
6638
91162307 6639
81e97e0d 6640// AliTPCTrackerPoint * AliTPCseed::GetTrackPoint(Int_t i)
6641// {
6642// //
6643// //
6644// return &fTrackPoints[i];
6645// }
91162307 6646
91162307 6647