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