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