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