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