]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - TPC/AliTPCtrackerMI.cxx
Fixes for some mem-leaks: most changes where pretty basic (i.e. adding deletes).
[u/mrichter/AliRoot.git] / TPC / AliTPCtrackerMI.cxx
... / ...
CommitLineData
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
16
17//-------------------------------------------------------
18// Implementation of the TPC tracker
19//
20// Origin: Marian Ivanov Marian.Ivanov@cern.ch
21//
22// AliTPC parallel tracker
23//-------------------------------------------------------
24
25
26/* $Id$ */
27
28#include "Riostream.h"
29#include <TClonesArray.h>
30#include <TFile.h>
31#include <TObjArray.h>
32#include <TTree.h>
33#include "AliLog.h"
34#include "AliComplexCluster.h"
35#include "AliESDEvent.h"
36#include "AliESDtrack.h"
37#include "AliESDVertex.h"
38#include "AliKink.h"
39#include "AliV0.h"
40#include "AliHelix.h"
41#include "AliRunLoader.h"
42#include "AliTPCClustersRow.h"
43#include "AliTPCParam.h"
44#include "AliTPCReconstructor.h"
45#include "AliTPCpolyTrack.h"
46#include "AliTPCreco.h"
47#include "AliTPCseed.h"
48#include "AliTPCtrackerMI.h"
49#include "TStopwatch.h"
50#include "AliTPCReconstructor.h"
51#include "AliPID.h"
52#include "TTreeStream.h"
53#include "AliAlignObj.h"
54#include "AliTrackPointArray.h"
55
56//#include "AliTPCTransform.h"
57
58//
59
60ClassImp(AliTPCtrackerMI)
61
62
63class AliTPCFastMath {
64public:
65 AliTPCFastMath();
66 static Double_t FastAsin(Double_t x);
67 private:
68 static Double_t fgFastAsin[20000]; //lookup table for fast asin computation
69};
70
71Double_t AliTPCFastMath::fgFastAsin[20000];
72AliTPCFastMath gAliTPCFastMath; // needed to fill the LUT
73
74AliTPCFastMath::AliTPCFastMath(){
75 //
76 // initialized lookup table;
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 }
81}
82
83Double_t AliTPCFastMath::FastAsin(Double_t x){
84 //
85 // return asin using lookup table
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]);
93}
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//_____________________________________________________________________
121
122
123
124Int_t AliTPCtrackerMI::UpdateTrack(AliTPCseed * track, Int_t accept){
125 //
126 //update track information using current cluster - track->fCurrentCluster
127
128
129 AliTPCclusterMI* c =track->GetCurrentCluster();
130 if (accept>0) track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() | 0x8000); //sign not accepted clusters
131
132 UInt_t i = track->GetCurrentClusterIndex1();
133
134 Int_t sec=(i&0xff000000)>>24;
135 //Int_t row = (i&0x00ff0000)>>16;
136 track->SetRow((i&0x00ff0000)>>16);
137 track->SetSector(sec);
138 // Int_t index = i&0xFFFF;
139 if (sec>=fParam->GetNInnerSector()) track->SetRow(track->GetRow()+fParam->GetNRowLow());
140 track->SetClusterIndex2(track->GetRow(), i);
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 //}
146 if (track->GetFirstPoint()>track->GetRow())
147 track->SetFirstPoint(track->GetRow());
148 if (track->GetLastPoint()<track->GetRow())
149 track->SetLastPoint(track->GetRow());
150
151
152 track->SetClusterPointer(track->GetRow(),c);
153 //
154
155 Double_t angle2 = track->GetSnp()*track->GetSnp();
156 //
157 //SET NEW Track Point
158 //
159 if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
160 {
161 angle2 = TMath::Sqrt(angle2/(1-angle2));
162 AliTPCTrackerPoint &point =*(track->GetTrackPoint(track->GetRow()));
163 //
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()));
168 //
169 point.SetX(track->GetX());
170 point.SetY(track->GetY());
171 point.SetZ(track->GetZ());
172 point.SetAngleY(angle2);
173 point.SetAngleZ(track->GetTgl());
174 if (point.IsShared()){
175 track->SetErrorY2(track->GetErrorY2()*4);
176 track->SetErrorZ2(track->GetErrorZ2()*4);
177 }
178 }
179
180 Double_t chi2 = track->GetPredictedChi2(track->GetCurrentCluster());
181 //
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);
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 //}
194 }
195 track->SetNoCluster(0);
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{
204 //
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;
211
212 Double_t sdistancey2 = sy2+seed->GetSigmaY2();
213 Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
214
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;
219
220 Double_t rdistance2 = rdistancey2+rdistancez2;
221 //Int_t accept =0;
222
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){
235 seed->SetNFoundable(seed->GetNFoundable()-1);
236 return 2;
237 }
238 return 0;
239}
240
241
242
243
244//_____________________________________________________________________________
245AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCParam *par):
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)
265{
266 //---------------------------------------------------------------------
267 // The main TPC tracker constructor
268 //---------------------------------------------------------------------
269 fInnerSec=new AliTPCSector[fkNIS];
270 fOuterSec=new AliTPCSector[fkNOS];
271
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
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 }
293
294 fDebugStreamer = new TTreeSRedirector("TPCdebug.root");
295}
296//________________________________________________________________________
297AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCtrackerMI &t):
298 AliTracker(t),
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)
317{
318 //------------------------------------
319 // dummy copy constructor
320 //------------------------------------------------------------------
321 fOutput=t.fOutput;
322}
323AliTPCtrackerMI & AliTPCtrackerMI::operator=(const AliTPCtrackerMI& /*r*/){
324 //------------------------------
325 // dummy
326 //--------------------------------------------------------------
327 return *this;
328}
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 }
340 if (fDebugStreamer) delete fDebugStreamer;
341}
342
343void AliTPCtrackerMI::SetIO()
344{
345 //
346 fNewIO = kTRUE;
347 fInput = AliRunLoader::GetTreeR("TPC", kFALSE,AliConfig::GetDefaultEventFolderName());
348
349 fOutput = AliRunLoader::GetTreeT("TPC", kTRUE,AliConfig::GetDefaultEventFolderName());
350 if (fOutput){
351 AliTPCtrack *iotrack= new AliTPCtrack;
352 fOutput->Branch("tracks","AliTPCtrack",&iotrack,32000,100);
353 delete iotrack;
354 }
355}
356
357
358void AliTPCtrackerMI::SetIO(TTree * input, TTree * output, AliESDEvent * event)
359{
360
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 //
390 vseed->SetPoints(arrtr);
391 vseed->SetEPoints(arre);
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);
399 }
400
401
402 //set ESD event
403 fEvent = event;
404}
405
406void AliTPCtrackerMI::FillESD(TObjArray* arr)
407{
408 //
409 //
410 //fill esds using updated tracks
411 if (fEvent){
412 // write tracks to the event
413 // store index of the track
414 Int_t nseed=arr->GetEntriesFast();
415 //FindKinks(arr,fEvent);
416 for (Int_t i=0; i<nseed; i++) {
417 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
418 if (!pt) continue;
419 pt->UpdatePoints();
420 // pt->PropagateTo(fParam->GetInnerRadiusLow());
421 if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
422 pt->PropagateTo(fParam->GetInnerRadiusLow());
423 }
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());
430 iotrack.SetV0Indexes(pt->GetV0Indexes());
431 // iotrack.SetTPCpid(pt->fTPCr);
432 //iotrack.SetTPCindex(i);
433 fEvent->AddTrack(&iotrack);
434 continue;
435 }
436
437 if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
438 AliESDtrack iotrack;
439 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
440 iotrack.SetTPCPoints(pt->GetPoints());
441 //iotrack.SetTPCindex(i);
442 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
443 iotrack.SetV0Indexes(pt->GetV0Indexes());
444 // iotrack.SetTPCpid(pt->fTPCr);
445 fEvent->AddTrack(&iotrack);
446 continue;
447 }
448 //
449 // short tracks - maybe decays
450
451 if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
452 Int_t found,foundable,shared;
453 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
454 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
455 AliESDtrack iotrack;
456 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
457 //iotrack.SetTPCindex(i);
458 iotrack.SetTPCPoints(pt->GetPoints());
459 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
460 iotrack.SetV0Indexes(pt->GetV0Indexes());
461 //iotrack.SetTPCpid(pt->fTPCr);
462 fEvent->AddTrack(&iotrack);
463 continue;
464 }
465 }
466
467 if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
468 Int_t found,foundable,shared;
469 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
470 if (found<20) continue;
471 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
472 //
473 AliESDtrack iotrack;
474 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
475 iotrack.SetTPCPoints(pt->GetPoints());
476 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
477 iotrack.SetV0Indexes(pt->GetV0Indexes());
478 //iotrack.SetTPCpid(pt->fTPCr);
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);
488 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
489 AliESDtrack iotrack;
490 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
491 iotrack.SetTPCPoints(pt->GetPoints());
492 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
493 iotrack.SetV0Indexes(pt->GetV0Indexes());
494 //iotrack.SetTPCpid(pt->fTPCr);
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;
505 if (foundable<=0) continue;
506 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
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());
513 iotrack.SetV0Indexes(pt->GetV0Indexes());
514 // iotrack.SetTPCpid(pt->fTPCr);
515 //iotrack.SetTPCindex(i);
516 fEvent->AddTrack(&iotrack);
517 continue;
518 }
519 }
520 }
521 printf("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks());
522}
523
524void AliTPCtrackerMI::WriteTracks(TTree * tree)
525{
526 //
527 // write tracks from seed array to selected tree
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 }
546
547 if (fOutput){
548 AliTPCtrack *iotrack= 0;
549 Int_t nseed=fSeeds->GetEntriesFast();
550 //for (Int_t i=0; i<nseed; i++) {
551 // iotrack= (AliTPCtrack*)fSeeds->UncheckedAt(i);
552 // if (iotrack) break;
553 //}
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;
561 AliTPCtrack * track = new AliTPCtrack(*pt);
562 iotrack = track;
563 pt->SetLab2(i);
564 // br->SetAddress(&iotrack);
565 fOutput->Fill();
566 delete track;
567 iotrack =0;
568 }
569 //fOutput->GetDirectory()->cd();
570 //fOutput->Write();
571 }
572 // delete iotrack;
573 //
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 //
585 vseed->SetPoints(arrtr);
586 vseed->SetEPoints(arre);
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;
596 pt->SetPoints(arrtr);
597 // pt->fClusterPoints = arrcl;
598 pt->SetEPoints(arre);
599 pt->RebuildSeed();
600 vseed = pt;
601 brseed->SetAddress(&vseed);
602 fSeedTree->Fill();
603 pt->SetPoints(0);
604 pt->SetEPoints(0);
605 // pt->fClusterPoints = 0;
606 }
607 fSeedTree->Write();
608 if (fTreeDebug) fTreeDebug->Write();
609 }
610
611}
612
613
614
615
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 //
635
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 }
644
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 }
684 //
685 //
686 //
687 Int_t amp = int(TMath::Abs(cl->GetQ()));
688 if (amp>9999) {
689 seed->SetErrorY2(1.);
690 return 1.;
691 }
692 Float_t snoise2;
693 Float_t z = TMath::Abs(fParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
694 Int_t ctype = cl->GetType();
695 Float_t padlength= GetPadPitchLength(seed->GetRow());
696 Double_t angle2 = seed->GetSnp()*seed->GetSnp();
697 angle2 = angle2/(1-angle2);
698 //
699 //cluster "quality"
700 Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
701 Float_t res;
702 //
703 if (fSectors==fInnerSec){
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 }
711 }
712 else {
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 }
732
733 if (ctype<0){
734 res+=0.005;
735 res*=2.4; // overestimate error 2 times
736 }
737 res+= snoise2;
738
739 if (res<2*snoise2)
740 res = 2*snoise2;
741
742 seed->SetErrorY2(res);
743 return res;
744
745
746}
747
748
749
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];
768 //
769
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 }
778
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;
827 Float_t z = TMath::Abs(fParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
828 Int_t ctype = cl->GetType();
829 Float_t padlength= GetPadPitchLength(seed->GetRow());
830 //
831 Double_t angle2 = seed->GetSnp()*seed->GetSnp();
832 // if (angle2<0.6) angle2 = 0.6;
833 angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
834 //
835 //cluster "quality"
836 Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
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;
895 Float_t z = TMath::Abs(fParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
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
966
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());
973
974 if (y > ymax) {
975 seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
976 if (!seed->Rotate(fSectors->GetAlpha()))
977 return;
978 } else if (y <-ymax) {
979 seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
980 if (!seed->Rotate(-fSectors->GetAlpha()))
981 return;
982 }
983
984}
985
986
987
988//_____________________________________________________________________________
989Double_t AliTPCtrackerMI::F1old(Double_t x1,Double_t y1,
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);
1003 if ( xr*xr+yr*yr<=0.00000000000001) return 100;
1004 return -xr*yr/sqrt(xr*xr+yr*yr);
1005}
1006
1007
1008
1009//_____________________________________________________________________________
1010Double_t AliTPCtrackerMI::F1(Double_t x1,Double_t y1,
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
1036Double_t AliTPCtrackerMI::F2(Double_t x1,Double_t y1,
1037 Double_t x2,Double_t y2,
1038 Double_t x3,Double_t y3)
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//_____________________________________________________________________________
1066Double_t AliTPCtrackerMI::F2old(Double_t x1,Double_t y1,
1067 Double_t x2,Double_t y2,
1068 Double_t x3,Double_t y3)
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//_____________________________________________________________________________
1085Double_t AliTPCtrackerMI::F3(Double_t x1,Double_t y1,
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
1096Double_t AliTPCtrackerMI::F3n(Double_t x1,Double_t y1,
1097 Double_t x2,Double_t y2,
1098 Double_t z1,Double_t z2, Double_t c)
1099{
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));
1107 //
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);
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);
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;
1127 }
1128
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{
1142 dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1143 }
1144
1145 //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1146
1147 y+=dy;
1148 z+=dz;
1149
1150 return kTRUE;
1151}
1152
1153Int_t AliTPCtrackerMI::LoadClusters (TTree *tree)
1154{
1155 //
1156 //
1157 fInput = tree;
1158 return LoadClusters();
1159}
1160
1161Int_t AliTPCtrackerMI::LoadClusters()
1162{
1163 //
1164 // load clusters to the memory
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());
1177 for (Int_t i=0; i<j; i++) {
1178 br->GetEntry(i);
1179 //
1180 Int_t sec,row;
1181 fParam->AdjustSectorRow(clrow->GetID(),sec,row);
1182 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1183 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1184 }
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){
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)));
1201 }
1202 if (left ==1){
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)));
1207 }
1208 }
1209 //
1210 delete clrow;
1211 LoadOuterSectors();
1212 LoadInnerSectors();
1213 return 0;
1214}
1215
1216
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]);
1226 // if (tpcrow){
1227 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1228 // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1229 //}
1230 tpcrow->ResetClusters();
1231 }
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]);
1237 //if (tpcrow){
1238 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1239 //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1240 //}
1241 tpcrow->ResetClusters();
1242 }
1243
1244 return ;
1245}
1246
1247void AliTPCtrackerMI::Transform(AliTPCclusterMI * cluster){
1248 //
1249 //
1250 //
1251// AliTPCTransform trafo;
1252
1253// Double_t x[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1254// Int_t i[1]={cluster->GetDetector()};
1255
1256// trafo.Transform(x,i,0,1);
1257
1258// cluster->SetX(x[0]);
1259// cluster->SetY(x[1]);
1260// cluster->SetZ(x[2]);
1261
1262// return;
1263
1264 // The old stuff:
1265
1266 //
1267 //
1268 //
1269 //if (!fParam->IsGeoRead()) fParam->ReadGeoMatrices();
1270 TGeoHMatrix *mat = fParam->GetClusterMatrix(cluster->GetDetector());
1271 //TGeoHMatrix mat;
1272 Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
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 }
1278 //cluster->SetX(posC[0]);
1279 //cluster->SetY(posC[1]);
1280 //cluster->SetZ(posC[2]);
1281}
1282
1283//_____________________________________________________________________________
1284Int_t AliTPCtrackerMI::LoadOuterSectors() {
1285 //-----------------------------------------------------------------
1286 // This function fills outer TPC sectors with clusters.
1287 //-----------------------------------------------------------------
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
1295 Int_t ncl = tpcrow->GetN1();
1296 while (ncl--) {
1297 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1298 index=(((sec2<<8)+row)<<16)+ncl;
1299 tpcrow->InsertCluster(c,index);
1300 }
1301 //right
1302 ncl = tpcrow->GetN2();
1303 while (ncl--) {
1304 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
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++)
1312 tpcrow->SetFastCluster(i,-1);
1313 for (Int_t i=0;i<tpcrow->GetN();i++){
1314 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1315 tpcrow->SetFastCluster(zi,i); // write index
1316 }
1317 Int_t last = 0;
1318 for (Int_t i=0;i<510;i++){
1319 if (tpcrow->GetFastCluster(i)<0)
1320 tpcrow->SetFastCluster(i,last);
1321 else
1322 last = tpcrow->GetFastCluster(i);
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
1343 Int_t ncl = tpcrow->GetN1();
1344 while (ncl--) {
1345 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1346 index=(((sec<<8)+row)<<16)+ncl;
1347 tpcrow->InsertCluster(c,index);
1348 }
1349 //right
1350 ncl = tpcrow->GetN2();
1351 while (ncl--) {
1352 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
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++)
1360 tpcrow->SetFastCluster(i,-1);
1361 for (Int_t i=0;i<tpcrow->GetN();i++){
1362 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1363 tpcrow->SetFastCluster(zi,i); // write index
1364 }
1365 Int_t last = 0;
1366 for (Int_t i=0;i<510;i++){
1367 if (tpcrow->GetFastCluster(i)<0)
1368 tpcrow->SetFastCluster(i,last);
1369 else
1370 last = tpcrow->GetFastCluster(i);
1371 }
1372
1373 }
1374
1375 fN=fkNIS;
1376 fSectors=fInnerSec;
1377 return 0;
1378}
1379
1380
1381
1382//_________________________________________________________________________
1383AliTPCclusterMI *AliTPCtrackerMI::GetClusterMI(Int_t index) const {
1384 //--------------------------------------------------------------------
1385 // Return pointer to a given cluster
1386 //--------------------------------------------------------------------
1387 if (index<0) return 0; // no cluster
1388 Int_t sec=(index&0xff000000)>>24;
1389 Int_t row=(index&0x00ff0000)>>16;
1390 Int_t ncl=(index&0x00007fff)>>00;
1391
1392 const AliTPCRow * tpcrow=0;
1393 AliTPCclusterMI * clrow =0;
1394
1395 if (sec<0 || sec>=fkNIS*4) {
1396 AliWarning(Form("Wrong sector %d",sec));
1397 return 0x0;
1398 }
1399
1400 if (sec<fkNIS*2){
1401 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1402 if (tpcrow==0) return 0;
1403
1404 if (sec<fkNIS) {
1405 if (tpcrow->GetN1()<=ncl) return 0;
1406 clrow = tpcrow->GetClusters1();
1407 }
1408 else {
1409 if (tpcrow->GetN2()<=ncl) return 0;
1410 clrow = tpcrow->GetClusters2();
1411 }
1412 }
1413 else {
1414 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1415 if (tpcrow==0) return 0;
1416
1417 if (sec-2*fkNIS<fkNOS) {
1418 if (tpcrow->GetN1()<=ncl) return 0;
1419 clrow = tpcrow->GetClusters1();
1420 }
1421 else {
1422 if (tpcrow->GetN2()<=ncl) return 0;
1423 clrow = tpcrow->GetClusters2();
1424 }
1425 }
1426
1427 return &(clrow[ncl]);
1428
1429}
1430
1431
1432
1433Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
1434 //-----------------------------------------------------------------
1435 // This function tries to find a track prolongation to next pad row
1436 //-----------------------------------------------------------------
1437 //
1438 Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
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){ //
1451 cl = t.GetClusterPointer(nr);
1452 if ( (cl==0) ) cl = GetClusterMI(tpcindex);
1453 t.SetCurrentClusterIndex1(tpcindex);
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();
1464 t.SetRelativeSector(relativesector);
1465 if (!t.Rotate(rotation)) return 0;
1466 }
1467 if (!t.PropagateTo(x)) return 0;
1468 //
1469 t.SetCurrentCluster(cl);
1470 t.SetRow(nr);
1471 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster(),1.);
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
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);
1480 }
1481 t.SetNFoundable(t.GetNFoundable()+1);
1482 UpdateTrack(&t,accept);
1483 return 1;
1484 }
1485 }
1486 }
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
1490 t.SetNFoundable(t.GetNFoundable()+1);
1491 return 0;
1492 }
1493 //
1494 UInt_t index=0;
1495 // if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
1496 Double_t y=t.GetYat(x);
1497 if (TMath::Abs(y)>ymax){
1498 if (y > ymax) {
1499 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1500 if (!t.Rotate(fSectors->GetAlpha()))
1501 return 0;
1502 } else if (y <-ymax) {
1503 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1504 if (!t.Rotate(-fSectors->GetAlpha()))
1505 return 0;
1506 }
1507 //return 1;
1508 }
1509 //
1510 if (!t.PropagateTo(x)) {
1511 if (fIteration==0) t.SetRemoval(10);
1512 return 0;
1513 }
1514 y=t.GetY();
1515 Double_t z=t.GetZ();
1516 //
1517
1518 if (!IsActive(t.GetRelativeSector(),nr)) {
1519 t.SetInDead(kTRUE);
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()));
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;
1526
1527 if (!isActive || !isActive2) return 0;
1528
1529 const AliTPCRow &krow=GetRow(t.GetRelativeSector(),nr);
1530 if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
1531 Double_t roady =1.;
1532 Double_t roadz = 1.;
1533 //
1534 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1535 t.SetInDead(kTRUE);
1536 t.SetClusterIndex2(nr,-1);
1537 return 0;
1538 }
1539 else
1540 {
1541 if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
1542 t.SetNFoundable(t.GetNFoundable()+1);
1543 else
1544 return 0;
1545 }
1546 //calculate
1547 if (krow) {
1548 // cl = krow.FindNearest2(y+10.,z,roady,roadz,index);
1549 cl = krow.FindNearest2(y,z,roady,roadz,index);
1550 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
1551 }
1552 if (cl) {
1553 t.SetCurrentCluster(cl);
1554 t.SetRow(nr);
1555 if (fIteration==2&&cl->IsUsed(10)) return 0;
1556 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster(),1.);
1557 if (fIteration==2&&cl->IsUsed(11)) {
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);
1562 }
1563 /*
1564 if (t.fCurrentCluster->IsUsed(10)){
1565 //
1566 //
1567
1568 t.fNShared++;
1569 if (t.fNShared>0.7*t.GetNumberOfClusters()) {
1570 t.fRemoval =10;
1571 return 0;
1572 }
1573 }
1574 */
1575 if (accept<3) UpdateTrack(&t,accept);
1576
1577 } else {
1578 if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
1579
1580 }
1581 return 1;
1582}
1583
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)) {
1592 t.SetRemoval(10);
1593 return 0;
1594 }
1595 //
1596 //
1597 if (TMath::Abs(y)>ymax){
1598
1599 if (y > ymax) {
1600 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1601 if (!t.Rotate(fSectors->GetAlpha()))
1602 return 0;
1603 } else if (y <-ymax) {
1604 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1605 if (!t.Rotate(-fSectors->GetAlpha()))
1606 return 0;
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
1615 if ( (nr%6==0) || t.GetNumberOfClusters()<2 || (t.GetCurrentSigmaY2()<0.0001) ){
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;
1626 const AliTPCRow &krow=GetRow(t.GetRelativeSector(),nr);
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;
1632 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1633 t.SetInDead(kTRUE);
1634 t.SetClusterIndex2(row,-1);
1635 return 0;
1636 }
1637 else
1638 {
1639 if (TMath::Abs(z)>(AliTPCReconstructor::GetCtgRange()*x+10)) t.SetClusterIndex2(row,-1);
1640 }
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
1647 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
1648 }
1649
1650 if (cl) {
1651 t.SetCurrentCluster(cl);
1652 // Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
1653 //if (accept<3){
1654 t.SetClusterIndex2(row,index);
1655 t.SetClusterPointer(row, cl);
1656 //}
1657 }
1658 return 1;
1659}
1660
1661
1662
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;
1671 // Int_t row = (index&0x00ff0000)>>16;
1672 Float_t xyz[3];
1673 // xyz[0] = fParam->GetPadRowRadii(sector,row);
1674 xyz[0] = cl->GetX();
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);
1693 AliGeomManager::ELayerID iLayer;
1694 Int_t idet;
1695 if (sector < fParam->GetNInnerSector()) {
1696 iLayer = AliGeomManager::kTPC1;
1697 idet = sector;
1698 }
1699 else {
1700 iLayer = AliGeomManager::kTPC2;
1701 idet = sector - fParam->GetNInnerSector();
1702 }
1703 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
1704 p.SetVolumeID(volid);
1705 return kTRUE;
1706}
1707
1708
1709
1710Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t, Int_t nr) {
1711 //-----------------------------------------------------------------
1712 // This function tries to find a track prolongation to next pad row
1713 //-----------------------------------------------------------------
1714 t.SetCurrentCluster(0);
1715 t.SetCurrentClusterIndex1(0);
1716
1717 Double_t xt=t.GetX();
1718 Int_t row = GetRowNumber(xt)-1;
1719 Double_t ymax= GetMaxY(nr);
1720
1721 if (row < nr) return 1; // don't prolongate if not information until now -
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
1730
1731 Double_t x= GetXrow(nr);
1732 Double_t y,z;
1733 //t.PropagateTo(x+0.02);
1734 //t.PropagateTo(x+0.01);
1735 if (!t.PropagateTo(x)){
1736 return 0;
1737 }
1738 //
1739 y=t.GetY();
1740 z=t.GetZ();
1741
1742 if (TMath::Abs(y)>ymax){
1743 if (y > ymax) {
1744 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1745 if (!t.Rotate(fSectors->GetAlpha()))
1746 return 0;
1747 } else if (y <-ymax) {
1748 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1749 if (!t.Rotate(-fSectors->GetAlpha()))
1750 return 0;
1751 }
1752 // if (!t.PropagateTo(x)){
1753 // return 0;
1754 //}
1755 return 1;
1756 //y = t.GetY();
1757 }
1758 //
1759 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
1760
1761 if (!IsActive(t.GetRelativeSector(),nr)) {
1762 t.SetInDead(kTRUE);
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
1768 AliTPCRow &krow=GetRow(t.GetRelativeSector(),nr);
1769
1770 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1771 t.SetInDead(kTRUE);
1772 t.SetClusterIndex2(nr,-1);
1773 return 0;
1774 }
1775 else
1776 {
1777 if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker())) t.SetNFoundable(t.GetNFoundable()+1);
1778 else
1779 return 0;
1780 }
1781
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 }
1788
1789 AliTPCclusterMI *cl=0;
1790 Int_t index=0;
1791 //
1792 Double_t roady = 1.;
1793 Double_t roadz = 1.;
1794 //
1795
1796 if (!cl){
1797 index = t.GetClusterIndex2(nr);
1798 if ( (index>0) && (index&0x8000)==0){
1799 cl = t.GetClusterPointer(nr);
1800 if ( (cl==0) && (index>0)) cl = GetClusterMI(index);
1801 t.SetCurrentClusterIndex1(index);
1802 if (cl) {
1803 t.SetCurrentCluster(cl);
1804 return 1;
1805 }
1806 }
1807 }
1808
1809 // if (index<0) return 0;
1810 UInt_t uindex = TMath::Abs(index);
1811
1812 if (krow) {
1813 //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
1814 cl = krow.FindNearest2(y,z,roady,roadz,uindex);
1815 }
1816
1817 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));
1818 t.SetCurrentCluster(cl);
1819
1820 return 1;
1821}
1822
1823
1824Int_t AliTPCtrackerMI::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
1825 //-----------------------------------------------------------------
1826 // This function tries to find a track prolongation to next pad row
1827 //-----------------------------------------------------------------
1828
1829 //update error according neighborhoud
1830
1831 if (t.GetCurrentCluster()) {
1832 t.SetRow(nr);
1833 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster(),1.);
1834
1835 if (t.GetCurrentCluster()->IsUsed(10)){
1836 //
1837 //
1838 // t.fErrorZ2*=2;
1839 // t.fErrorY2*=2;
1840 t.SetNShared(t.GetNShared()+1);
1841 if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
1842 t.SetRemoval(10);
1843 return 0;
1844 }
1845 }
1846 if (fIteration>0) accept = 0;
1847 if (accept<3) UpdateTrack(&t,accept);
1848
1849 } else {
1850 if (fIteration==0){
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);
1853
1854 if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
1855 }
1856 }
1857 return 1;
1858}
1859
1860
1861
1862//_____________________________________________________________________________
1863Int_t AliTPCtrackerMI::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step) {
1864 //-----------------------------------------------------------------
1865 // This function tries to find a track prolongation.
1866 //-----------------------------------------------------------------
1867 Double_t xt=t.GetX();
1868 //
1869 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
1870 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
1871 if (alpha < 0. ) alpha += 2.*TMath::Pi();
1872 //
1873 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1874
1875 Int_t first = GetRowNumber(xt)-1;
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 //
1884 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
1885 if (!kink){
1886 printf("PROBLEM\n");
1887 }
1888 else{
1889 Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
1890 if (kinkrow==nr){
1891 AliExternalTrackParam paramd(t);
1892 kink->SetDaughter(paramd);
1893 kink->SetStatus(2,5);
1894 kink->Update();
1895 }
1896 }
1897 }
1898 }
1899
1900 if (nr==80) t.UpdateReference();
1901 if (nr<fInnerSec->GetNRows())
1902 fSectors = fInnerSec;
1903 else
1904 fSectors = fOuterSec;
1905 if (FollowToNext(t,nr)==0)
1906 if (!t.IsActive())
1907 return 0;
1908
1909 }
1910 return 1;
1911}
1912
1913
1914//_____________________________________________________________________________
1915Int_t AliTPCtrackerMI::FollowProlongationFast(AliTPCseed& t, Int_t rf, Int_t step) {
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();
1924 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
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;
1930
1931 }
1932 return 1;
1933}
1934
1935
1936
1937
1938
1939Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf) {
1940 //-----------------------------------------------------------------
1941 // This function tries to find a track prolongation.
1942 //-----------------------------------------------------------------
1943 //
1944 Double_t xt=t.GetX();
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();
1948 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1949
1950 Int_t first = t.GetFirstPoint();
1951 if (first<GetRowNumber(xt)+1) first = GetRowNumber(xt)+1;
1952 //
1953 if (first<0) first=0;
1954 for (Int_t nr=first; nr<=rf; nr++) {
1955 // if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
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);
1962 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
1963 if (!kink){
1964 printf("PROBLEM\n");
1965 }
1966 else{
1967 Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
1968 if (kinkrow==nr){
1969 AliExternalTrackParam paramm(t);
1970 kink->SetMother(paramm);
1971 kink->SetStatus(2,1);
1972 kink->Update();
1973 }
1974 }
1975 }
1976 }
1977 //
1978 if (nr<fInnerSec->GetNRows())
1979 fSectors = fInnerSec;
1980 else
1981 fSectors = fOuterSec;
1982
1983 FollowToNext(t,nr);
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;
1999 //
2000 Float_t dz2 =(s1->GetZ() - s2->GetZ());
2001 dz2*=dz2;
2002
2003 Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
2004 dy2*=dy2;
2005 Float_t distance = TMath::Sqrt(dz2+dy2);
2006 if (distance>4.) return 0; // if there are far away - not overlap - to reduce combinatorics
2007
2008 // Int_t offset =0;
2009 Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
2010 Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
2011 if (lastpoint>160)
2012 lastpoint =160;
2013 if (firstpoint<0)
2014 firstpoint = 0;
2015 if (firstpoint>lastpoint) {
2016 firstpoint =lastpoint;
2017 // lastpoint =160;
2018 }
2019
2020
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) {
2025 sum++;
2026 }
2027 }
2028 if (sum<5) return 0;
2029
2030 Float_t summin = TMath::Min(sum1+1,sum2+1);
2031 Float_t ratio = (sum+1)/Float_t(summin);
2032 return ratio;
2033}
2034
2035void AliTPCtrackerMI::SignShared(AliTPCseed * s1, AliTPCseed * s2)
2036{
2037 //
2038 //
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));
2043
2044 //
2045 Int_t sumshared=0;
2046 //
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;
2051 //
2052 // if (firstpoint>=lastpoint-5) return;;
2053
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++;
2058 s1->SetSharedMapBit(i, kTRUE);
2059 s2->SetSharedMapBit(i, kTRUE);
2060 }
2061 if (s1->GetClusterIndex2(i)>0)
2062 s1->SetClusterMapBit(i, kTRUE);
2063 }
2064 if (sumshared>cutN0){
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()){
2073 p1->SetShared(kTRUE);
2074 p2->SetShared(kTRUE);
2075 }
2076 }
2077 }
2078 }
2079 //
2080 if (sumshared>cutN0){
2081 for (Int_t i=0;i<4;i++){
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());
2086 break;
2087 }
2088 }
2089 for (Int_t i=0;i<4;i++){
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());
2094 break;
2095 }
2096 }
2097 }
2098}
2099
2100void AliTPCtrackerMI::SignShared(TObjArray * arr)
2101{
2102 //
2103 //sort trackss according sectors
2104 //
2105 for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2106 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2107 if (!pt) continue;
2108 //if (pt) RotateToLocal(pt);
2109 pt->SetSort(0);
2110 }
2111 arr->UnSort();
2112 arr->Sort(); // sorting according z
2113 arr->Expand(arr->GetEntries());
2114 //
2115 //
2116 Int_t nseed=arr->GetEntriesFast();
2117 for (Int_t i=0; i<nseed; i++) {
2118 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2119 if (!pt) continue;
2120 for (Int_t j=0;j<=12;j++){
2121 pt->SetOverlapLabel(j,0);
2122 }
2123 }
2124 for (Int_t i=0; i<nseed; i++) {
2125 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2126 if (!pt) continue;
2127 if (pt->GetRemoval()>10) continue;
2128 for (Int_t j=i+1; j<nseed; j++){
2129 AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
2130 // if (pt2){
2131 if (pt2->GetRemoval()<=10) {
2132 if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
2133 SignShared(pt,pt2);
2134 }
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) {
2145 Info("RemoveDouble","Number of tracks before double removal- %d\n",arr->GetEntries());
2146 }
2147 //
2148 for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2149 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2150 if (!pt) continue;
2151 pt->SetSort(0);
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++){
2165 pt->SetOverlapLabel(j,0);
2166 }
2167 }
2168 //
2169 //sign shared tracks
2170 for (Int_t i=0; i<nseed; i++) {
2171 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2172 if (!pt) continue;
2173 if (pt->GetRemoval()>10) continue;
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){
2178 if (pt2->GetRemoval()<=10) {
2179 if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
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 }
2185 }
2186 }
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;
2192 if (pt->GetRemoval()>10) continue;
2193 //
2194 Int_t sumshared =0;
2195 for (Int_t j=0;j<4;j++){
2196 sumshared = pt->GetOverlapLabel(j*3+1);
2197 }
2198 Float_t factor = factor1;
2199 if (pt->GetRemoval()>0) factor = factor2;
2200 if (sumshared/pt->GetNumberOfClusters()>factor){
2201 for (Int_t j=0;j<4;j++){
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));
2206 if (!pt2) continue;
2207 if (pt2->GetSigma2C()<pt->GetSigma2C()){
2208 // pt->fRemoval = removalindex;
2209 delete arr->RemoveAt(i);
2210 break;
2211 }
2212 }
2213 }
2214 }
2215 arr->Compress();
2216 if (fDebug&1) {
2217 Info("RemoveDouble","Number of tracks after double removal- %d\n",arr->GetEntries());
2218 }
2219}
2220
2221
2222
2223
2224
2225
2226void AliTPCtrackerMI::SortTracks(TObjArray * arr, Int_t mode) const
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 }
2236 pt->SetSort(mode);
2237 }
2238 arr->UnSort();
2239 arr->Sort();
2240}
2241
2242void AliTPCtrackerMI::RemoveUsed(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t removalindex)
2243{
2244
2245 //Loop over all tracks and remove "overlaps"
2246 //
2247 //
2248 Int_t nseed = arr->GetEntriesFast();
2249 Int_t good =0;
2250
2251 for (Int_t i=0; i<nseed; i++) {
2252 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2253 if (!pt) {
2254 delete arr->RemoveAt(i);
2255 }
2256 else{
2257 pt->SetSort(1);
2258 pt->SetBSigned(kFALSE);
2259 }
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;
2281 if (pt->GetBConstrain()) factor = factor1;
2282
2283 if ((Float_t(shared)/Float_t(found))>factor){
2284 pt->Desactivate(removalindex);
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;
2292 AliTPCclusterMI *c= pt->GetClusterPointer(i);
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);
2299 }
2300
2301 }
2302 fNtracks = good;
2303 if (fDebug>0){
2304 Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
2305 }
2306}
2307
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]);
2353 Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
2354 //
2355 Int_t found,foundable,shared;
2356 pt->GetClusterStatistic(first,last, found, foundable,shared,kFALSE);
2357 Float_t sharedfactor = Float_t(shared+1)/Float_t(found+1);
2358 Bool_t itsgold =kFALSE;
2359 if (pt->GetESD()){
2360 Int_t dummy[12];
2361 if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
2362 }
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 }
2375 }
2376
2377 good++;
2378 if (sharedfactor>0.4) continue;
2379 if (pt->GetKinkIndexes()[0]>0) continue;
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;
2384 AliTPCclusterMI *c= pt->GetClusterPointer(i);
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
2397void AliTPCtrackerMI::UnsignClusters()
2398{
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++){
2405 AliTPCclusterMI *cl = fInnerSec[sec][row].GetClusters1();
2406 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
2407 // if (cl[icl].IsUsed(10))
2408 cl[icl].Use(-1);
2409 cl = fInnerSec[sec][row].GetClusters2();
2410 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
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++){
2418 AliTPCclusterMI *cl = fOuterSec[sec][row].GetClusters1();
2419 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
2420 //if (cl[icl].IsUsed(10))
2421 cl[icl].Use(-1);
2422 cl = fOuterSec[sec][row].GetClusters2();
2423 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
2424 //if (cl[icl].IsUsed(10))
2425 cl[icl].Use(-1);
2426 }
2427 }
2428
2429}
2430
2431
2432
2433void AliTPCtrackerMI::SignClusters(TObjArray * arr, Float_t fnumber, Float_t fdensity)
2434{
2435 //
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
2450 TStopwatch timer;
2451 timer.Start();
2452
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;
2460 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
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 }
2472 }
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;
2480
2481
2482 if (sum>20){
2483 mdensity = sumdens/sum;
2484 meann = sumn/sum;
2485 meanchi = sumchi/sum;
2486 //
2487 sdensity = sumdens2/sum-mdensity*mdensity;
2488 if (sdensity >= 0)
2489 sdensity = TMath::Sqrt(sdensity);
2490 else
2491 sdensity = 0.1;
2492 //
2493 smeann = sumn2/sum-meann*meann;
2494 if (smeann >= 0)
2495 smeann = TMath::Sqrt(smeann);
2496 else
2497 smeann = 10;
2498 //
2499 smeanchi = sumchi2/sum - meanchi*meanchi;
2500 if (smeanchi >= 0)
2501 smeanchi = TMath::Sqrt(smeanchi);
2502 else
2503 smeanchi = 0.4;
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;
2513 }
2514 if (pt->GetBSigned()) continue;
2515 if (pt->GetBConstrain()) continue;
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;
2525 }
2526 */
2527 Bool_t isok =kFALSE;
2528 if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
2529 isok = kTRUE;
2530 if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
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;
2541 AliTPCclusterMI *c= pt->GetClusterPointer(i);
2542 if (!c) continue;
2543 //if (!(c->IsUsed(10))) c->Use();
2544 c->Use(10);
2545 }
2546 }
2547
2548
2549 //
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) {
2555 continue;
2556 }
2557 //if (!(pt->IsActive())) continue;
2558 if (pt->GetBSigned()) continue;
2559 Double_t chi = pt->GetChi2()/pt->GetNumberOfClusters();
2560 if (chi>maxchi) continue;
2561
2562 Float_t bfactor=1;
2563 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
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
2570 Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
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);
2574 if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
2575 minn=0;
2576
2577 if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
2578 //Int_t noc=pt->GetNumberOfClusters();
2579 pt->SetBSigned(kTRUE);
2580 for (Int_t i=0; i<160; i++) {
2581
2582 Int_t index=pt->GetClusterIndex2(i);
2583 if (index<0) continue;
2584 AliTPCclusterMI *c= pt->GetClusterPointer(i);
2585 if (!c) continue;
2586 // if (!(c->IsUsed(10))) c->Use();
2587 c->Use(10);
2588 }
2589 }
2590 }
2591 // gLastCheck = nseed;
2592 // arr->Compress();
2593 if (fDebug>0){
2594 timer.Print();
2595 }
2596}
2597
2598
2599void AliTPCtrackerMI::StopNotActive(TObjArray * arr, Int_t row0, Float_t th0, Float_t th1, Float_t th2) const
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}
2615
2616
2617
2618void AliTPCtrackerMI::StopNotActive(AliTPCseed * seed, Int_t row0, Float_t th0, Float_t th1,
2619 Float_t th2) const
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;
2627 Int_t maxindex = seed->GetLastPoint(); //last foundable row
2628 if (seed->GetNFoundable()*th0 > seed->GetNumberOfClusters()) {
2629 seed->Desactivate(10) ;
2630 return;
2631 }
2632
2633 for (Int_t i=row0; i<maxindex; i++){
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}
2651
2652
2653Int_t AliTPCtrackerMI::RefitInward(AliESDEvent *event)
2654{
2655 //
2656 // back propagation of ESD tracks
2657 //
2658 //return 0;
2659 fEvent = event;
2660 ReadSeeds(event,2);
2661 fIteration=2;
2662 //PrepareForProlongation(fSeeds,1);
2663 PropagateForward2(fSeeds);
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);
2669
2670 Int_t ntracks=0;
2671 Int_t nseed = fSeeds->GetEntriesFast();
2672 for (Int_t i=0;i<nseed;i++){
2673 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2674 if (!seed) continue;
2675 if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
2676
2677 seed->PropagateTo(fParam->GetInnerRadiusLow());
2678 seed->UpdatePoints();
2679 MakeBitmaps(seed);
2680 AliESDtrack *esd=event->GetTrack(i);
2681 seed->CookdEdx(0.02,0.6);
2682 CookLabel(seed,0.1); //For comparison only
2683 esd->SetTPCClusterMap(seed->GetClusterMap());
2684 esd->SetTPCSharedMap(seed->GetSharedMap());
2685 //
2686 if (AliTPCReconstructor::StreamLevel()>0 && seed!=0&&esd!=0) {
2687 TTreeSRedirector &cstream = *fDebugStreamer;
2688 cstream<<"Crefit"<<
2689 "Esd.="<<esd<<
2690 "Track.="<<seed<<
2691 "\n";
2692 }
2693
2694 if (seed->GetNumberOfClusters()>15){
2695 esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
2696 esd->SetTPCPoints(seed->GetPoints());
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;
2700 Float_t dedx = seed->GetdEdx();
2701 esd->SetTPCsignal(dedx, sdedx, ndedx);
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 }
2709 ntracks++;
2710 }
2711 else{
2712 //printf("problem\n");
2713 }
2714 }
2715 //FindKinks(fSeeds,event);
2716 Info("RefitInward","Number of refitted tracks %d",ntracks);
2717 fEvent =0;
2718 //WriteTracks();
2719 return 0;
2720}
2721
2722
2723Int_t AliTPCtrackerMI::PropagateBack(AliESDEvent *event)
2724{
2725 //
2726 // back propagation of ESD tracks
2727 //
2728
2729 fEvent = event;
2730 fIteration = 1;
2731 ReadSeeds(event,1);
2732 PropagateBack(fSeeds);
2733 RemoveUsed2(fSeeds,0.4,0.4,20);
2734 //
2735 Int_t nseed = fSeeds->GetEntriesFast();
2736 Int_t ntracks=0;
2737 for (Int_t i=0;i<nseed;i++){
2738 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2739 if (!seed) continue;
2740 if (seed->GetKinkIndex(0)<0) UpdateKinkQualityM(seed); // update quality informations for kinks
2741 seed->UpdatePoints();
2742 AliESDtrack *esd=event->GetTrack(i);
2743 seed->CookdEdx(0.02,0.6);
2744 CookLabel(seed,0.1); //For comparison only
2745 if (seed->GetNumberOfClusters()>15){
2746 esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
2747 esd->SetTPCPoints(seed->GetPoints());
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;
2751 Float_t dedx = seed->GetdEdx();
2752 esd->SetTPCsignal(dedx, sdedx, ndedx);
2753 ntracks++;
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
2756 (*fDebugStreamer)<<"Cback"<<
2757 "Tr0.="<<seed<<
2758 "EventNrInFile="<<eventnumber<<
2759 "\n"; // patch 28 fev 06
2760 }
2761 }
2762 //FindKinks(fSeeds,event);
2763 Info("PropagateBack","Number of back propagated tracks %d",ntracks);
2764 fEvent =0;
2765 //WriteTracks();
2766
2767 return 0;
2768}
2769
2770
2771void AliTPCtrackerMI::DeleteSeeds()
2772{
2773 //
2774 //delete Seeds
2775
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;
2782
2783 fSeeds =0;
2784}
2785
2786void AliTPCtrackerMI::ReadSeeds(AliESDEvent *event, Int_t direction)
2787{
2788 //
2789 //read seeds from the event
2790
2791 Int_t nentr=event->GetNumberOfTracks();
2792 if (fDebug>0){
2793 Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
2794 }
2795 if (fSeeds)
2796 DeleteSeeds();
2797 if (!fSeeds){
2798 fSeeds = new TObjArray(nentr);
2799 }
2800 UnsignClusters();
2801 // Int_t ntrk=0;
2802 for (Int_t i=0; i<nentr; i++) {
2803 AliESDtrack *esd=event->GetTrack(i);
2804 ULong_t status=esd->GetStatus();
2805 if (!(status&AliESDtrack::kTPCin)) continue;
2806 AliTPCtrack t(*esd);
2807 t.SetNumberOfClusters(0);
2808 // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
2809 AliTPCseed *seed = new AliTPCseed(t/*,t.GetAlpha()*/);
2810 seed->SetUniqueID(esd->GetID());
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 }
2827 if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.);
2828 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
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 ) {
2835 Double_t par0[5],par1[5],alpha,x;
2836 esd->GetInnerExternalParameters(alpha,x,par0);
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]);
2840 Double_t trdchi2=0;
2841 if (esd->GetTRDncls()>0) trdchi2 = esd->GetTRDchi2()/esd->GetTRDncls();
2842 //reset covariance if suspicious
2843 if ( (delta1>0.1) || (delta2>0.006) ||trdchi2>7.)
2844 seed->ResetCovariance(10.);
2845 }
2846
2847 //
2848 //
2849 // rotate to the local coordinate system
2850 //
2851 fSectors=fInnerSec; fN=fkNIS;
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();
2857 if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
2858 if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
2859 alpha-=seed->GetAlpha();
2860 if (!seed->Rotate(alpha)) {
2861 delete seed;
2862 continue;
2863 }
2864 seed->SetESD(esd);
2865 // sign clusters
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);
2872 seed->SetClusterPointer(irow,cl);
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 }
2879 }else{
2880 Info("ReadSeeds","Not found cluster");
2881 }
2882 }
2883 }
2884 }
2885 fSeeds->AddAt(seed,i);
2886 }
2887}
2888
2889
2890
2891//_____________________________________________________________________________
2892void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
2893 Float_t deltay, Int_t ddsec) {
2894 //-----------------------------------------------------------------
2895 // This function creates track seeds.
2896 // SEEDING WITH VERTEX CONSTRAIN
2897 //-----------------------------------------------------------------
2898 // cuts[0] - fP4 cut
2899 // cuts[1] - tan(phi) cut
2900 // cuts[2] - zvertex cut
2901 // cuts[3] - fP3 cut
2902 Int_t nin0 = 0;
2903 Int_t nin1 = 0;
2904 Int_t nin2 = 0;
2905 Int_t nin = 0;
2906 Int_t nout1 = 0;
2907 Int_t nout2 = 0;
2908
2909 Double_t x[5], c[15];
2910 // Int_t di = i1-i2;
2911 //
2912 AliTPCseed * seed = new AliTPCseed();
2913 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
2914 Double_t cs=cos(alpha), sn=sin(alpha);
2915 //
2916 // Double_t x1 =fOuterSec->GetX(i1);
2917 //Double_t xx2=fOuterSec->GetX(i2);
2918
2919 Double_t x1 =GetXrow(i1);
2920 Double_t xx2=GetXrow(i2);
2921
2922 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
2923
2924 Int_t imiddle = (i2+i1)/2; //middle pad row index
2925 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
2926 const AliTPCRow& krm=GetRow(sec,imiddle); //middle pad -row
2927 //
2928 Int_t ns =sec;
2929
2930 const AliTPCRow& kr1=GetRow(ns,i1);
2931 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
2932 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
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);
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);
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
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;
3104
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;
3109
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;
3118
3119 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3120
3121 UInt_t index=kr1.GetIndex(is);
3122 seed->~AliTPCseed(); // this does not set the pointer to 0...
3123 AliTPCseed *track=new(seed) AliTPCseed(x1, ns*alpha+shift, x, c, index);
3124
3125 track->SetIsSeeding(kTRUE);
3126 track->SetSeed1(i1);
3127 track->SetSeed2(i2);
3128 track->SetSeedType(3);
3129
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;
3147 track->SetBConstrain(1);
3148 // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
3149 track->SetLastPoint(i1); // first cluster in track position
3150 track->SetFirstPoint(track->GetLastPoint());
3151
3152 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3153 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3154 track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
3155 seed->Reset();
3156 seed->~AliTPCseed();
3157 continue;
3158 }
3159 nout1++;
3160 // Z VERTEX CONDITION
3161 Double_t zv, bz=GetBz();
3162 if ( !track->GetZAt(0.,bz,zv) ) continue;
3163 if (TMath::Abs(zv-z3)>cuts[2]) {
3164 FollowProlongation(*track, TMath::Max(i2-20,0));
3165 if ( !track->GetZAt(0.,bz,zv) ) continue;
3166 if (TMath::Abs(zv-z3)>cuts[2]){
3167 FollowProlongation(*track, TMath::Max(i2-40,0));
3168 if ( !track->GetZAt(0.,bz,zv) ) continue;
3169 if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
3170 // make seed without constrain
3171 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
3172 FollowProlongation(*track2, i2,1);
3173 track2->SetBConstrain(kFALSE);
3174 track2->SetSeedType(1);
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 }
3187 }
3188
3189 track->SetSeedType(0);
3190 arr->AddLast(track);
3191 seed = new AliTPCseed;
3192 nout2++;
3193 // don't consider other combinations
3194 if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
3195 break;
3196 }
3197 }
3198 }
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);
3201 }
3202 delete seed;
3203}
3204
3205
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
3211 //-----------------------------------------------------------------
3212 // This function creates track seeds.
3213 //-----------------------------------------------------------------
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;
3231 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3232 // Double_t cs=cos(alpha), sn=sin(alpha);
3233 //
3234 //
3235
3236 // first 3 padrows
3237 Double_t x1 = GetXrow(i1-1);
3238 const AliTPCRow& kr1=GetRow(sec,i1-1);
3239 Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
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);
3246
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);
3258
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++) {
3274 //
3275 if (kr1[is]->IsUsed(10)) continue;
3276 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3277 //
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;
3284 //
3285 //
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++;
3326 }
3327 const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
3328 anglez*(x1p-x1)+z1,
3329 erry,errz,index);
3330 //
3331 if (kc1p){
3332 found++;
3333 if (kc1p->IsUsed(10)) used++;
3334 }
3335 if (used>1) continue;
3336 if (found<1) continue;
3337
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
3369 x[0]=y1;
3370 x[1]=z1;
3371 x[4]=F1(x1,y1,x2,y2,x3,y3);
3372 //if (TMath::Abs(x[4]) >= cuts[0]) continue;
3373 nin0++;
3374 //
3375 x[2]=F2(x1,y1,x2,y2,x3,y3);
3376 nin1++;
3377 //
3378 x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
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;
3386
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;
3393
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;
3398
3399 c[0]=sy1;
3400 c[1]=0.; c[2]=sz1;
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
3408 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3409
3410 UInt_t index=kr1.GetIndex(is);
3411 seed->~AliTPCseed();
3412 AliTPCseed *track=new(seed) AliTPCseed(x1, sec*alpha+shift, x, c, index);
3413
3414 track->SetIsSeeding(kTRUE);
3415
3416 nin++;
3417 FollowProlongation(*track, i1-7,1);
3418 if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
3419 track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
3420 seed->Reset();
3421 seed->~AliTPCseed();
3422 continue;
3423 }
3424 nout1++;
3425 nout2++;
3426 //Int_t rc = 1;
3427 FollowProlongation(*track, i2,1);
3428 track->SetBConstrain(0);
3429 track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
3430 track->SetFirstPoint(track->GetLastPoint());
3431
3432 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3433 track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
3434 track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
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);
3444 track2->SetBConstrain(kFALSE);
3445 track2->SetSeedType(4);
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
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);
3460 }
3461 delete seed;
3462}
3463
3464
3465//_____________________________________________________________________________
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*/) {
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
3523 Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
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();
3572 Double_t ymax = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
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;
3644 x[4]=F1(x1,y1,x2,y2,x3,y3);
3645
3646 // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
3647 x[2]=F2(x1,y1,x2,y2,x3,y3);
3648
3649 //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
3650 //x[3]=F3(x1,y1,x2,y2,z1,z2);
3651 x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
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
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;
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);
3691 seed->~AliTPCseed();
3692 AliTPCseed *track=new(seed) AliTPCseed(x1,sec*alpha+shift,x,c,index);
3693 track->SetIsSeeding(kTRUE);
3694 Int_t rc=FollowProlongation(*track, i2);
3695 if (constrain) track->SetBConstrain(1);
3696 else
3697 track->SetBConstrain(0);
3698 track->SetLastPoint(row1+fInnerSec->GetNRows()); // first cluster in track position
3699 track->SetFirstPoint(track->GetLastPoint());
3700
3701 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3702 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3703 track->GetNShared()>0.4*track->GetNumberOfClusters()) {
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 }
3716 if (fDebug>3){
3717 Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
3718 }
3719 delete seed;
3720}
3721
3722
3723AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
3724{
3725 //
3726 //
3727 //reseed using track points
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
3731 Int_t pp2=0;
3732 Double_t x0[3],x1[3],x2[3];
3733 for (Int_t i=0;i<3;i++){
3734 x0[i]=-1;
3735 x1[i]=-1;
3736 x2[i]=-1;
3737 }
3738
3739 // find track position at given ratio of the length
3740 Int_t sec0=0, sec1=0, sec2=0;
3741 Int_t index=-1;
3742 Int_t clindex;
3743 for (Int_t i=0;i<160;i++){
3744 if (track->GetClusterPointer(i)){
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];
3805 x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
3806 // if (x[4]>1) return 0;
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]);
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 //
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;
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]);
3841 AliTPCseed *seed=new AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
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;
3847 seed->SetLastPoint(pp2);
3848 seed->SetFirstPoint(pp2);
3849
3850
3851 return seed;
3852}
3853
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) {
3891 //Error("Bug\n");
3892 // AliTPCclusterMI * cl = GetClusterMI(clindex);
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]);
3961 AliTPCseed *seed=new AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
3962 seed->SetLastPoint(row[2]);
3963 seed->SetFirstPoint(row[2]);
3964 return seed;
3965}
3966
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];
3975 Int_t row[3]={0,0,0};
3976 Int_t sec[3]={0,0,0};
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]);
4110 AliTPCseed *seed=new AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4111 seed->SetLastPoint(row[2]);
4112 seed->SetFirstPoint(row[2]);
4113 for (Int_t i=row[0];i<row[2];i++){
4114 seed->SetClusterIndex(i, track->GetClusterIndex(i));
4115 }
4116
4117 return seed;
4118}
4119
4120void AliTPCtrackerMI::FindKinks(TObjArray * array, AliESDEvent *esd)
4121{
4122 //
4123 // find kinks
4124 //
4125 //
4126
4127 TObjArray *kinks= new TObjArray(10000);
4128 // TObjArray *v0s= new TObjArray(10000);
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];
4134 AliKink *kink = new AliKink();
4135 Int_t * usage = new Int_t[nentries];
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];
4141 Float_t *dca = new Float_t[nentries];
4142 //const AliESDVertex * primvertex = esd->GetVertex();
4143 //
4144 // nentries = array->GetEntriesFast();
4145 //
4146
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;
4154 track->SetCircular(0);
4155 shared[i] = kFALSE;
4156 track->UpdatePoints();
4157 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
4158 }
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;
4177 if (track->GetProlongation(0,y,z)) z0[i] = z;
4178 dca[i] = track->GetD(0,0);
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];
4188
4189 //
4190 // Find circling track
4191 TTreeSRedirector &cstream = *fDebugStreamer;
4192 //
4193 for (Int_t i0=0;i0<nentries;i0++){
4194 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4195 if (!track0) continue;
4196 if (track0->GetNumberOfClusters()<40) continue;
4197 if (TMath::Abs(1./track0->GetC())>200) continue;
4198 for (Int_t i1=i0+1;i1<nentries;i1++){
4199 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4200 if (!track1) continue;
4201 if (track1->GetNumberOfClusters()<40) continue;
4202 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
4203 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
4204 if (TMath::Abs(1./track1->GetC())>200) continue;
4205 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
4206 if (track1->GetTgl()*track0->GetTgl()>0) continue;
4207 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
4208 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
4209 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
4210 //
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 //
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));
4227 //if (delta>30) continue;
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;
4254 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
4255 if (npoints==2){
4256 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
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);
4263 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
4264 //
4265 if (deltabest>6) continue;
4266 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
4267 Bool_t sign =kFALSE;
4268 if (hangles[2]>3.06) sign =kTRUE;
4269 //
4270 if (sign){
4271 circular[i0] = kTRUE;
4272 circular[i1] = kTRUE;
4273 if (track0->OneOverPt()<track1->OneOverPt()){
4274 track0->SetCircular(track0->GetCircular()+1);
4275 track1->SetCircular(track1->GetCircular()+2);
4276 }
4277 else{
4278 track1->SetCircular(track1->GetCircular()+1);
4279 track0->SetCircular(track0->GetCircular()+2);
4280 }
4281 }
4282 if (sign&&AliTPCReconstructor::StreamLevel()>1){
4283 //debug stream
4284 Int_t lab0=track0->GetLabel();
4285 Int_t lab1=track1->GetLabel();
4286 cstream<<"Curling"<<
4287 "lab0="<<lab0<<
4288 "lab1="<<lab1<<
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";
4309 }
4310 }
4311 }
4312 }
4313 //
4314 // Finf kinks loop
4315 //
4316 //
4317 for (Int_t i =0;i<nentries;i++){
4318 if (sign[i]==0) continue;
4319 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
4320 if (track0==0) {
4321 AliInfo("seed==0");
4322 continue;
4323 }
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);
4405 //
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);
4427 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
4428 //
4429 //
4430 kink->SetMother(paramm);
4431 kink->SetDaughter(paramd);
4432 kink->Update();
4433
4434 Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
4435 Int_t index[4];
4436 fParam->Transform0to1(x,index);
4437 fParam->Transform1to2(x,index);
4438 row0 = GetRowNumber(x[0]);
4439
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
4445 if (dird<0) continue;
4446
4447 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
4448 if (dirm<0) continue;
4449 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
4450 if (mpt<0.2) continue;
4451
4452 if (mpt<1){
4453 //for high momenta momentum not defined well in first iteration
4454 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
4455 if (qt>0.35) continue;
4456 }
4457
4458 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
4459 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
4460 if (dens00>dens10){
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);
4467 }
4468 else{
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);
4475 }
4476
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;
4481 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
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
4485 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
4486 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
4487 criticalangle= 3*TMath::Sqrt(criticalangle);
4488 if (criticalangle>0.02) criticalangle=0.02;
4489 if (kink->GetAngle(2)<criticalangle) continue;
4490 }
4491 //
4492 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
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;
4498 if (ktrack0->GetClusterPointer(row)){
4499 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
4500 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
4501 sum++;
4502 }
4503 if (ktrack1->GetClusterPointer(row)){
4504 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
4505 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
4506 sum++;
4507 }
4508 }
4509 if (sum<4){
4510 kink->SetShapeFactor(-1.);
4511 }
4512 else{
4513 kink->SetShapeFactor(shapesum/sum);
4514 }
4515 // esd->AddKink(kink);
4516 kinks->AddLast(kink);
4517 kink = new AliKink;
4518 ncandidates++;
4519 }
4520 }
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 //
4531 for (Int_t i=0;i<nkinks;i++){
4532 quality[i] =100000;
4533 AliKink *kink = (AliKink*)kinks->At(i);
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 //
4542 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
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;
4554 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
4555 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
4556 //
4557 //
4558 Int_t first = row0+drow;
4559 if (first>130) first=130;
4560 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
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());
4567 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
4568 mothers[i] = *seed0;
4569 daughters[i] = *seed1;
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
4589 }
4590 TMath::Sort(nkinks,quality,indexes,kFALSE);
4591 //
4592 //remove double find kinks
4593 //
4594 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
4595 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
4596 if (!kink0) continue;
4597 //
4598 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
4599 if (!kink0) continue;
4600 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
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++){
4621 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
4622 both++;
4623 bothm++;
4624 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
4625 same++;
4626 samem++;
4627 }
4628 }
4629 }
4630
4631 for (Int_t i=row0;i<158;i++){
4632 if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){
4633 both++;
4634 bothd++;
4635 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
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) {
4645 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
4646 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
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
4662 for (Int_t i=0;i<nkinks;i++){
4663 AliKink * kink = (AliKink*) kinks->At(indexes[i]);
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;
4675
4676 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
4677 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
4678 if (!ktrack0 || !ktrack1) continue;
4679 Int_t index = esd->AddKink(kink);
4680 //
4681 //
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){
4684 *ktrack0 = mothers[indexes[i]];
4685 *ktrack1 = daughters[indexes[i]];
4686 }
4687 }
4688 //
4689 ktrack0->SetKinkIndex(usage[index0],-(index+1));
4690 ktrack1->SetKinkIndex(usage[index1], (index+1));
4691 usage[index0]++;
4692 usage[index1]++;
4693 }
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;
4700 if (track0->GetKinkIndex(0)!=0) continue;
4701 if (shared[i]) delete array->RemoveAt(i);
4702 }
4703
4704 //
4705 //
4706 RemoveUsed2(array,0.5,0.4,30);
4707 UnsignClusters();
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 }
4714 //
4715 for (Int_t i=0;i<nentries;i++){
4716 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
4717 if (!track0) continue;
4718 if (track0->Pt()<1.4) continue;
4719 //remove double high momenta tracks - overlapped with kink candidates
4720 Int_t shared=0;
4721 Int_t all =0;
4722 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
4723 if (track0->GetClusterPointer(icl)!=0){
4724 all++;
4725 if (track0->GetClusterPointer(icl)->IsUsed(10)) shared++;
4726 }
4727 }
4728 if (Float_t(shared+1)/Float_t(nall+1)>0.5) {
4729 delete array->RemoveAt(i);
4730 continue;
4731 }
4732 //
4733 if (track0->GetKinkIndex(0)!=0) continue;
4734 if (track0->GetNumberOfClusters()<80) continue;
4735
4736 AliTPCseed *pmother = new AliTPCseed();
4737 AliTPCseed *pdaughter = new AliTPCseed();
4738 AliKink *pkink = new AliKink;
4739
4740 AliTPCseed & mother = *pmother;
4741 AliTPCseed & daughter = *pdaughter;
4742 AliKink & kink = *pkink;
4743 if (CheckKinkPoint(track0,mother,daughter, kink)){
4744 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
4745 delete pmother;
4746 delete pdaughter;
4747 delete pkink;
4748 continue; //too short tracks
4749 }
4750 if (mother.Pt()<1.4) {
4751 delete pmother;
4752 delete pdaughter;
4753 delete pkink;
4754 continue;
4755 }
4756 Int_t row0= kink.GetTPCRow0();
4757 if (kink.GetDistance()>0.5 || kink.GetR()<110. || kink.GetR()>240.) {
4758 delete pmother;
4759 delete pdaughter;
4760 delete pkink;
4761 continue;
4762 }
4763 //
4764 Int_t index = esd->AddKink(&kink);
4765 mother.SetKinkIndex(0,-(index+1));
4766 daughter.SetKinkIndex(0,index+1);
4767 if (mother.GetNumberOfClusters()>50) {
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++) {
4776 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
4777 }
4778 //
4779 for (Int_t icl=row0;icl<158;icl++) {
4780 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
4781 }
4782 //
4783 }
4784 delete pmother;
4785 delete pdaughter;
4786 delete pkink;
4787 }
4788
4789 delete [] daughters;
4790 delete [] mothers;
4791 //
4792 //
4793 delete [] dca;
4794 delete []circular;
4795 delete []shared;
4796 delete []quality;
4797 delete []indexes;
4798 //
4799 delete kink;
4800 delete[]fim;
4801 delete[] zm;
4802 delete[] z0;
4803 delete [] usage;
4804 delete[] alpha;
4805 delete[] nclusters;
4806 delete[] sign;
4807 delete[] helixes;
4808 kinks->Delete();
4809 delete kinks;
4810
4811 printf("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall);
4812 timer.Print();
4813}
4814
4815void AliTPCtrackerMI::FindV0s(TObjArray * array, AliESDEvent *esd)
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 //
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);
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]);
4867 if (track->TPCrPID(1)+track->TPCrPID(2)+track->TPCrPID(3)>0.5) {
4868 if (pulldca[i]<3.) isPrim[i]=kTRUE; //pion, muon and Kaon 3 sigma cut
4869 }
4870 if (track->TPCrPID(4)>0.5) {
4871 if (pulldca[i]<0.5) isPrim[i]=kTRUE; //proton 0.5 sigma cut
4872 }
4873 if (track->TPCrPID(0)>0.4) {
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()};
4892 AliV0 vertex;
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;
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 }
4918 //
4919 if (track0->GetSigned1Pt()<0) continue;
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;
4933 if (track0->GetCircular()+track1->GetCircular()>1) continue; //circling -returning track
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;
4965 vertex.SetParamP(*track0); //track0 - plus
4966 vertex.SetParamN(*track1); //track1 - minus
4967 vertex.Update(fprimvertex);
4968 if (track0->TPCrPID(0)>0.3&&track1->TPCrPID(0)>0.3&&vertex.GetAnglep()[2]<0.15) isGamma=kTRUE; // gamma conversion candidate
4969 Double_t pointAngle2 = vertex.GetV0CosineOfPointingAngle();
4970 //continue;
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
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);
4978 //Bo: if (vertex.GetDist2()/sigmae>3.&&(!isGamma)) continue;
4979 if (vertex.GetDcaV0Daughters()/sigmae>3.&&(!isGamma)) continue;
4980 Float_t densb0=0,densb1=0,densa0=0,densa1=0;
4981 Int_t row0 = GetRowNumber(vertex.GetRr());
4982 if (row0>15){
4983 //Bo: if (vertex.GetDist2()>0.2) continue;
4984 if (vertex.GetDcaV0Daughters()>0.2) continue;
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 }
4997//Bo: vertex.SetLab(0,track0->GetLabel());
4998//Bo: vertex.SetLab(1,track1->GetLabel());
4999 vertex.SetChi2After((densa0+densa1)*0.5);
5000 vertex.SetChi2Before((densb0+densb1)*0.5);
5001 vertex.SetIndex(0,i);
5002 vertex.SetIndex(1,j);
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());
5007 tpcv0s->AddLast(new AliESDv0(vertex));
5008 ncandidates++;
5009 {
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
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]);
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();
5018 cstream<<"V0"<<
5019 "Event="<<eventNr<<
5020 "vertex.="<<&vertex<<
5021 "Tr0.="<<track0<<
5022 "lab0="<<lab0<<
5023 "Helix0.="<<&helixes[i]<<
5024 "Tr1.="<<track1<<
5025 "lab1="<<lab1<<
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<<
5034 "circular0="<<c0<<
5035 "circular1="<<c1<<
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<<
5058 "\n";}
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;
5067 AliESDv0 *v0 = (AliESDv0*)tpcv0s->At(i);
5068 quality[i] = 1./(1.00001-v0->GetV0CosineOfPointingAngle()); //base point angle
5069 // quality[i] /= (0.5+v0->GetDist2());
5070 // quality[i] *= v0->GetChi2After(); //density factor
5071
5072 Int_t index0 = v0->GetIndex(0);
5073 Int_t index1 = v0->GetIndex(1);
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
5079 AliTPCseed * track0 = (AliTPCseed*)array->At(index0);
5080 AliTPCseed * track1 = (AliTPCseed*)array->At(index1);
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
5083 }
5084
5085 TMath::Sort(ncandidates,quality,indexes,kTRUE);
5086 //
5087 //
5088 for (Int_t i=0;i<ncandidates;i++){
5089 AliESDv0 * v0 = (AliESDv0*)tpcv0s->At(indexes[i]);
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 //
5111 AliESDv0 * v02 = v0;
5112 if (accept){
5113 //Bo: v0->SetOrder(0,order0);
5114 //Bo: v0->SetOrder(1,order1);
5115 //Bo: v0->SetOrder(1,order0+order1);
5116 v0->SetOnFlyStatus(kTRUE);
5117 Int_t index = esd->AddV0(v0);
5118 v02 = esd->GetV0(index);
5119 v0indexes0[order0]=index;
5120 v0indexes1[order1]=index;
5121 naccepted++;
5122 }
5123 {
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
5125 if (AliTPCReconstructor::StreamLevel()>0) {
5126 Int_t lab0=track0->GetLabel();
5127 Int_t lab1=track1->GetLabel();
5128 cstream<<"V02"<<
5129 "Event="<<eventNr<<
5130 "vertex.="<<v0<<
5131 "vertex2.="<<v02<<
5132 "Tr0.="<<track0<<
5133 "lab0="<<lab0<<
5134 "Tr1.="<<track1<<
5135 "lab1="<<lab1<<
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<<
5145 "\n";}
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
5171Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, AliESDkink &knk)
5172{
5173 //
5174 // refit kink towards to the vertex
5175 //
5176 //
5177 AliKink &kink=(AliKink &)knk;
5178
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
5193 AliKink kinks[kNdiv]; // corresponding kink parameters
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]);
5204 param0[irow] = mother;
5205 param1[kNdiv-1-irow] = daughter;
5206 }
5207 //
5208 // define kinks
5209 for (Int_t irow=0; irow<kNdiv-1;irow++){
5210 if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
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++){
5220 if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
5221 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
5222 if (TMath::Abs(kinks[irow].GetR())<100.) continue;
5223 //
5224 Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
5225 normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
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 //
5238 mother = param0[index];
5239 daughter = param1[index]; // daughter in vertex
5240 //
5241 kink.SetMother(mother);
5242 kink.SetDaughter(daughter);
5243 kink.Update();
5244 kink.SetTPCRow0(GetRowNumber(kink.GetR()));
5245 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
5246 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
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}
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);
5266 //kink->fTPCdensity2[0][0]=-1;
5267 //kink->fTPCdensity2[0][1]=-1;
5268 kink->SetTPCDensity2(-1,0,0);
5269 kink->SetTPCDensity2(1,0,1);
5270 //
5271 Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5272 if (row0<15) row0=15;
5273 //
5274 Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5275 if (row1>145) row1=145;
5276 //
5277 Int_t found,foundable,shared;
5278 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
5279 if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),0,0);
5280 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
5281 if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),0,1);
5282 }
5283
5284}
5285
5286void AliTPCtrackerMI::UpdateKinkQualityD(AliTPCseed * seed){
5287 //
5288 // update Kink quality information for daughter after refit
5289 //
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);
5298 //
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);
5310 }
5311
5312}
5313
5314
5315Int_t AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, AliESDkink &knk)
5316{
5317 //
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
5323 AliKink &kink=(AliKink &)knk;
5324
5325 Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
5326 Int_t first = seed->GetFirstPoint();
5327 Int_t last = seed->GetLastPoint();
5328 if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
5329
5330
5331 AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
5332 if (!seed1) return 0;
5333 FollowProlongation(*seed1,seed->GetLastPoint()-20);
5334 seed1->Reset(kTRUE);
5335 FollowProlongation(*seed1,158);
5336 seed1->Reset(kTRUE);
5337 last = seed1->GetLastPoint();
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
5345 AliKink kinks[20]; // corresponding kink parameters
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]);
5355 param0[irow] = *seed0;
5356 param1[19-irow] = *seed1;
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;
5372 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
5373 if ( quality > maxchange){
5374 maxchange = quality;
5375 index = irow;
5376 //
5377 }
5378 }
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);
5388 seed0->ResetCovariance(10.);
5389 seed1->ResetCovariance(10.);
5390 FollowProlongation(*seed0,0);
5391 FollowBackProlongation(*seed1,158);
5392 mother = *seed0; // backup mother at position 0
5393 seed0->Reset(kFALSE);
5394 seed1->Reset(kFALSE);
5395 seed0->ResetCovariance(10.);
5396 seed1->ResetCovariance(10.);
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]);
5409 param0[irow] = *seed0;
5410 param1[19-irow] = *seed1;
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;
5428 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
5429 if ( quality > maxchange){
5430 maxchange = quality;
5431 index = irow;
5432 //
5433 }
5434 }
5435 //
5436 //
5437 if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
5438 delete seed0;
5439 delete seed1;
5440 return 0;
5441 }
5442 // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
5443
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);
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);
5455 //
5456 //
5457 // new (&mother) AliTPCseed(param0[index]);
5458 daughter = param1[index];
5459 daughter.SetLabel(kink.GetLabel(1));
5460 param0[index].Reset(kTRUE);
5461 FollowProlongation(param0[index],0);
5462 mother = param0[index];
5463 mother.SetLabel(kink.GetLabel(0));
5464 delete seed0;
5465 delete seed1;
5466 //
5467 return 1;
5468}
5469
5470
5471
5472
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){
5482 first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
5483 //last =
5484 }
5485 else
5486 first = t->GetFirstPoint();
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
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);
5529 fSeeds->AddLast(new AliTPCseed(*seed/*,seed->GetAlpha()*/));
5530 }
5531
5532 delete seed;
5533 delete seedTree;
5534 savedir->cd();
5535 return 0;
5536}
5537
5538Int_t AliTPCtrackerMI::Clusters2Tracks (AliESDEvent *esd)
5539{
5540 //
5541 if (fSeeds) DeleteSeeds();
5542 fEvent = esd;
5543 Clusters2Tracks();
5544 if (!fSeeds) return 1;
5545 FillESD(fSeeds);
5546 return 0;
5547 //
5548}
5549
5550
5551//_____________________________________________________________________________
5552Int_t AliTPCtrackerMI::Clusters2Tracks() {
5553 //-----------------------------------------------------------------
5554 // This is a track finder.
5555 //-----------------------------------------------------------------
5556 TDirectory *savedir=gDirectory;
5557 TStopwatch timer;
5558
5559 fIteration = 0;
5560 fSeeds = Tracking();
5561
5562 if (fDebug>0){
5563 Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
5564 }
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;
5573 }
5574 CookLabel(pt,0.1);
5575 if (pt->GetRemoval()==10) {
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 }
5584 //
5585 RemoveUsed2(fSeeds,0.85,0.85,0);
5586 if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
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);
5625 //RemoveDouble(fSeeds,0.2,0.6,11);
5626
5627 //
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){
5639 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
5640 found++;
5641 if (fDebug>0) cerr<<found<<'\r';
5642 pt->SetLab2(i);
5643 }
5644 else
5645 delete fSeeds->RemoveAt(i);
5646 }
5647
5648
5649 //RemoveOverlap(fSeeds,0.99,7,kTRUE);
5650 SignShared(fSeeds);
5651 //RemoveUsed(fSeeds,0.9,0.9,6);
5652 //
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){
5667 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
5668 found++;
5669 if (fDebug>0){
5670 cerr<<found<<'\r';
5671 }
5672 pt->SetLab2(i);
5673 }
5674 else
5675 delete fSeeds->RemoveAt(i);
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
5686 }
5687
5688 SortTracks(fSeeds, 1);
5689
5690 /*
5691 fIteration = 1;
5692 PrepareForBackProlongation(fSeeds,5.);
5693 PropagateBack(fSeeds);
5694 printf("Time for back propagation: \t");timer.Print();timer.Start();
5695
5696 fIteration = 2;
5697
5698 PrepareForProlongation(fSeeds,5.);
5699 PropagateForward2(fSeeds);
5700
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);
5704
5705 nseed=fSeeds->GetEntriesFast();
5706 found = 0;
5707 for (Int_t i=0; i<nseed; i++) {
5708 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
5709 if (!pt) continue;
5710 Int_t nc=t.GetNumberOfClusters();
5711 if (nc<15) {
5712 delete fSeeds->RemoveAt(i);
5713 continue;
5714 }
5715 t.CookdEdx(0.02,0.6);
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;
5724 }
5725 */
5726
5727 // fNTracks = found;
5728 if (fDebug>0){
5729 Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
5730 }
5731 //
5732 // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
5733 Info("Clusters2Tracks","Number of found tracks %d",found);
5734 savedir->cd();
5735 // UnloadClusters();
5736 //
5737 return 0;
5738}
5739
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){
5768 Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
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 //
5784 if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
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){
5855 Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
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
5907 Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
5908
5909 // find secondaries
5910 for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=10){
5911 //
5912 cuts[0] = 0.3;
5913 cuts[1] = 3.5;
5914 cuts[2] = 3.;
5915 cuts[3] = 3.5;
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){
5926 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
5927 timer.Print();
5928 timer.Start();
5929 }
5930
5931 return seeds;
5932 //
5933
5934}
5935
5936
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
5980void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *&arr2) const
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){
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 }
5996 // REMOVE VERY SHORT TRACKS
5997 if (pt->GetNumberOfClusters()<20){
5998 delete arr2->RemoveAt(i);
5999 continue;
6000 }// patch 28 fev06
6001 // NORMAL ACTIVE TRACK
6002 if (pt->IsActive()){
6003 arr1->AddLast(arr2->RemoveAt(i));
6004 continue;
6005 }
6006 //remove not usable tracks
6007 if (pt->GetRemoval()!=10){
6008 delete arr2->RemoveAt(i);
6009 continue;
6010 }
6011
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 }
6020 delete arr2; arr2 = 0;
6021}
6022
6023
6024
6025void AliTPCtrackerMI::ParallelTracking(TObjArray * arr, Int_t rfirst, Int_t rlast)
6026{
6027 //
6028 // try to track in parralel
6029
6030 Int_t nseed=arr->GetEntriesFast();
6031 //prepare seeds for tracking
6032 for (Int_t i=0; i<nseed; i++) {
6033 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
6034 if (!pt) continue;
6035 if (!t.IsActive()) continue;
6036 // follow prolongation to the first layer
6037 if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fParam->GetNRowLow()>rfirst+1) )
6038 FollowProlongation(t, rfirst+1);
6039 }
6040
6041
6042 //
6043 for (Int_t nr=rfirst; nr>=rlast; nr--){
6044 if (nr<fInnerSec->GetNRows())
6045 fSectors = fInnerSec;
6046 else
6047 fSectors = fOuterSec;
6048 // make indexes with the cluster tracks for given
6049
6050 // find nearest cluster
6051 for (Int_t i=0; i<nseed; i++) {
6052 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
6053 if (!pt) continue;
6054 if (nr==80) pt->UpdateReference();
6055 if (!pt->IsActive()) continue;
6056 // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
6057 if (pt->GetRelativeSector()>17) {
6058 continue;
6059 }
6060 UpdateClusters(t,nr);
6061 }
6062 // prolonagate to the nearest cluster - if founded
6063 for (Int_t i=0; i<nseed; i++) {
6064 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
6065 if (!pt) continue;
6066 if (!pt->IsActive()) continue;
6067 // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
6068 if (pt->GetRelativeSector()>17) {
6069 continue;
6070 }
6071 FollowToNextCluster(*pt,nr);
6072 }
6073 }
6074}
6075
6076void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray * arr,Float_t fac) const
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
6089 Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
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}
6112void AliTPCtrackerMI::PrepareForProlongation(TObjArray * arr, Float_t fac) const
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);
6123 pt->SetFirstPoint(pt->GetLastPoint());
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);
6139 if (pt&& pt->GetKinkIndex(0)<=0) {
6140 //AliTPCseed *pt2 = new AliTPCseed(*pt);
6141 fSectors = fInnerSec;
6142 //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
6143 //fSectors = fOuterSec;
6144 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
6145 //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
6146 // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
6147 // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
6148 //}
6149 }
6150 if (pt&& pt->GetKinkIndex(0)>0) {
6151 AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
6152 pt->SetFirstPoint(kink->GetTPCRow0());
6153 fSectors = fInnerSec;
6154 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
6155 }
6156
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();
6168 //
6169 for (Int_t i=0;i<nseed;i++){
6170 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6171 if (pt) {
6172 FollowProlongation(*pt,0);
6173 }
6174 }
6175 return 0;
6176}
6177
6178
6179Int_t AliTPCtrackerMI::PropagateForward()
6180{
6181 //
6182 // propagate track forward
6183 //UnsignClusters();
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();
6192 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
6193 }
6194 }
6195
6196 fSectors = fOuterSec;
6197 ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
6198 fSectors = fInnerSec;
6199 ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
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 //
6214
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 //
6245 Float_t sd2 = TMath::Abs((fParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
6246 // Float_t padlength = fParam->GetPadPitchLength(seed->fSector);
6247 Float_t padlength = GetPadPitchLength(row);
6248 //
6249 Float_t sresy = (seed->GetSector() < fParam->GetNSector()/2) ? 0.2 :0.3;
6250 Double_t angulary = seed->GetSnp();
6251 angulary = angulary*angulary/(1-angulary*angulary);
6252 seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
6253 //
6254 Float_t sresz = fParam->GetZSigma();
6255 Float_t angularz = seed->GetTgl();
6256 seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
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 */
6266}
6267
6268
6269Float_t AliTPCtrackerMI::GetSigmaY(AliTPCseed * seed)
6270{
6271 //
6272 //
6273 Float_t sd2 = TMath::Abs((fParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
6274 Float_t padlength = fParam->GetPadPitchLength(seed->GetSector());
6275 Float_t sres = (seed->GetSector() < fParam->GetNSector()/2) ? 0.2 :0.3;
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 //
6287 Float_t sd2 = TMath::Abs((fParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
6288 Float_t padlength = fParam->GetPadPitchLength(seed->GetSector());
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
6296//__________________________________________________________________________
6297void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
6298 //--------------------------------------------------------------------
6299 //This function "cooks" a track label. If label<0, this track is fake.
6300 //--------------------------------------------------------------------
6301 AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
6302 if(!t){
6303 printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
6304 return;
6305 }
6306
6307 Int_t noc=t->GetNumberOfClusters();
6308 if (noc<10){
6309 //printf("\nnot founded prolongation\n\n\n");
6310 //t->Dump();
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 }
6321
6322 Int_t i;
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);
6331 if (t->GetClusterPointer(i)){
6332 clusters[current]=t->GetClusterPointer(i);
6333 current++;
6334 }
6335 }
6336 noc = current;
6337
6338 Int_t lab=123456789;
6339 for (i=0; i<noc; i++) {
6340 AliTPCclusterMI *c=clusters[i];
6341 if (!c) continue;
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++) {
6353 AliTPCclusterMI *c=clusters[i];
6354 if (!c) continue;
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;
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;
6369 if (lab == TMath::Abs(c->GetLabel(0)) ||
6370 lab == TMath::Abs(c->GetLabel(1)) ||
6371 lab == TMath::Abs(c->GetLabel(2))) max++;
6372 ind++;
6373 }
6374 if (max < Int_t(0.5*tail)) lab=-lab;
6375 }
6376
6377 t->SetLabel(lab);
6378
6379 // delete[] lb;
6380 //delete[] mx;
6381 //delete[] clusters;
6382}
6383
6384
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);
6415 if (t->GetClusterPointer(i)){
6416 clusters[current]=t->GetClusterPointer(i);
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
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
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
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();
6515 if(fRow)delete [] fRow;fRow = 0;
6516 fRow=new AliTPCRow[fN];
6517 for (Int_t i=0; i<fN; i++) {
6518 fRow[i].SetX(par->GetPadRowRadiiLow(i));
6519 fRow[i].SetDeadZone(1.5); //1.5 cm of dead zone
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();
6528 fN=par->GetNRowUp();
6529 if(fRow)delete [] fRow;fRow = 0;
6530 fRow=new AliTPCRow[fN];
6531 for (Int_t i=0; i<fN; i++) {
6532 fRow[i].SetX(par->GetPadRowRadiiUp(i));
6533 fRow[i].SetDeadZone(1.5); // 1.5 cm of dead zone
6534 }
6535 }
6536}
6537
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{
6547 //
6548 // default constructor
6549 //
6550}
6551
6552AliTPCtrackerMI::AliTPCRow::~AliTPCRow(){
6553 //
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;
6560}
6561
6562
6563
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
6580void AliTPCtrackerMI::AliTPCRow::ResetClusters() {
6581 //
6582 // reset clusters
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
6591 fN = 0;
6592 fN1 = 0;
6593 fN2 = 0;
6594 //delete[] fClusterArray;
6595
6596 //fClusterArray=0;
6597}
6598
6599
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
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
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;
6645 AliTPCclusterMI *cl =0;
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;
6650 iz1 = TMath::Max(GetFastCluster(iz1)-1,0);
6651 Int_t iz2 = Int_t(z+roadz+255.5);
6652 if (iz2<0 || iz2>=510) return cl;
6653 iz2 = TMath::Min(GetFastCluster(iz2)+1,fN);
6654
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}
6699
6700
6701
6702
6703
6704// AliTPCTrackerPoint * AliTPCseed::GetTrackPoint(Int_t i)
6705// {
6706// //
6707// //
6708// return &fTrackPoints[i];
6709// }
6710
6711
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}