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