]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - TPC/AliTPCtrackerMI.cxx
Adding task for checking of the TPC dEdx and PID performance
[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 AliTPCseed * seed = new AliTPCseed();
2853 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
2854 Double_t cs=cos(alpha), sn=sin(alpha);
2855 //
2856 // Double_t x1 =fOuterSec->GetX(i1);
2857 //Double_t xx2=fOuterSec->GetX(i2);
2858
2859 Double_t x1 =GetXrow(i1);
2860 Double_t xx2=GetXrow(i2);
2861
2862 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
2863
2864 Int_t imiddle = (i2+i1)/2; //middle pad row index
2865 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
2866 const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
2867 //
2868 Int_t ns =sec;
2869
2870 const AliTPCtrackerRow& kr1=GetRow(ns,i1);
2871 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
2872 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
2873
2874 //
2875 // change cut on curvature if it can't reach this layer
2876 // maximal curvature set to reach it
2877 Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
2878 if (dvertexmax*0.5*cuts[0]>0.85){
2879 cuts[0] = 0.85/(dvertexmax*0.5+1.);
2880 }
2881 Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
2882
2883 // Int_t ddsec = 1;
2884 if (deltay>0) ddsec = 0;
2885 // loop over clusters
2886 for (Int_t is=0; is < kr1; is++) {
2887 //
2888 if (kr1[is]->IsUsed(10)) continue;
2889 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
2890 //if (TMath::Abs(y1)>ymax) continue;
2891
2892 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
2893
2894 // find possible directions
2895 Float_t anglez = (z1-z3)/(x1-x3);
2896 Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
2897 //
2898 //
2899 //find rotation angles relative to line given by vertex and point 1
2900 Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
2901 Double_t dvertex = TMath::Sqrt(dvertex2);
2902 Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
2903 Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
2904
2905 //
2906 // loop over 2 sectors
2907 Int_t dsec1=-ddsec;
2908 Int_t dsec2= ddsec;
2909 if (y1<0) dsec2= 0;
2910 if (y1>0) dsec1= 0;
2911
2912 Double_t dddz1=0; // direction of delta inclination in z axis
2913 Double_t dddz2=0;
2914 if ( (z1-z3)>0)
2915 dddz1 =1;
2916 else
2917 dddz2 =1;
2918 //
2919 for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
2920 Int_t sec2 = sec + dsec;
2921 //
2922 // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
2923 //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
2924 AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
2925 AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
2926 Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
2927 Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
2928
2929 // rotation angles to p1-p3
2930 Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
2931 Double_t x2, y2, z2;
2932 //
2933 // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
2934
2935 //
2936 Double_t dxx0 = (xx2-x3)*cs13r;
2937 Double_t dyy0 = (xx2-x3)*sn13r;
2938 for (Int_t js=index1; js < index2; js++) {
2939 const AliTPCclusterMI *kcl = kr2[js];
2940 if (kcl->IsUsed(10)) continue;
2941 //
2942 //calcutate parameters
2943 //
2944 Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
2945 // stright track
2946 if (TMath::Abs(yy0)<0.000001) continue;
2947 Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
2948 Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
2949 Double_t r02 = (0.25+y0*y0)*dvertex2;
2950 //curvature (radius) cut
2951 if (r02<r2min) continue;
2952
2953 nin0++;
2954 //
2955 Double_t c0 = 1/TMath::Sqrt(r02);
2956 if (yy0>0) c0*=-1.;
2957
2958
2959 //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
2960 //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
2961 Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
2962 Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
2963 //
2964 //
2965 Double_t z0 = kcl->GetZ();
2966 Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
2967 if (TMath::Abs(zzzz2-z0)>0.5) continue;
2968 nin1++;
2969 //
2970 Double_t dip = (z1-z0)*c0/dfi1;
2971 Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
2972 //
2973 y2 = kcl->GetY();
2974 if (dsec==0){
2975 x2 = xx2;
2976 z2 = kcl->GetZ();
2977 }
2978 else
2979 {
2980 // rotation
2981 z2 = kcl->GetZ();
2982 x2= xx2*cs-y2*sn*dsec;
2983 y2=+xx2*sn*dsec+y2*cs;
2984 }
2985
2986 x[0] = y1;
2987 x[1] = z1;
2988 x[2] = x0;
2989 x[3] = dip;
2990 x[4] = c0;
2991 //
2992 //
2993 // do we have cluster at the middle ?
2994 Double_t ym,zm;
2995 GetProlongation(x1,xm,x,ym,zm);
2996 UInt_t dummy;
2997 AliTPCclusterMI * cm=0;
2998 if (TMath::Abs(ym)-ymaxm<0){
2999 cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3000 if ((!cm) || (cm->IsUsed(10))) {
3001 continue;
3002 }
3003 }
3004 else{
3005 // rotate y1 to system 0
3006 // get state vector in rotated system
3007 Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
3008 Double_t xr2 = x0*cs+yr1*sn*dsec;
3009 Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3010 //
3011 GetProlongation(xx2,xm,xr,ym,zm);
3012 if (TMath::Abs(ym)-ymaxm<0){
3013 cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3014 if ((!cm) || (cm->IsUsed(10))) {
3015 continue;
3016 }
3017 }
3018 }
3019
3020
3021 Double_t dym = 0;
3022 Double_t dzm = 0;
3023 if (cm){
3024 dym = ym - cm->GetY();
3025 dzm = zm - cm->GetZ();
3026 }
3027 nin2++;
3028
3029
3030 //
3031 //
3032 Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
3033 Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
3034 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
3035 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3036 //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
3037
3038 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3039 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3040 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3041 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3042 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3043 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3044
3045 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3046 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3047 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3048 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
3049
3050 c[0]=sy1;
3051 c[1]=0.; c[2]=sz1;
3052 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3053 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3054 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3055 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3056 c[13]=f30*sy1*f40+f32*sy2*f42;
3057 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3058
3059 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3060
3061 UInt_t index=kr1.GetIndex(is);
3062 seed->~AliTPCseed(); // this does not set the pointer to 0...
3063 AliTPCseed *track=new(seed) AliTPCseed(x1, ns*alpha+shift, x, c, index);
3064
3065 track->SetIsSeeding(kTRUE);
3066 track->SetSeed1(i1);
3067 track->SetSeed2(i2);
3068 track->SetSeedType(3);
3069
3070
3071 //if (dsec==0) {
3072 FollowProlongation(*track, (i1+i2)/2,1);
3073 Int_t foundable,found,shared;
3074 track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
3075 if ((found<0.55*foundable) || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
3076 seed->Reset();
3077 seed->~AliTPCseed();
3078 continue;
3079 }
3080 //}
3081
3082 nin++;
3083 FollowProlongation(*track, i2,1);
3084
3085
3086 //Int_t rc = 1;
3087 track->SetBConstrain(1);
3088 // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
3089 track->SetLastPoint(i1); // first cluster in track position
3090 track->SetFirstPoint(track->GetLastPoint());
3091
3092 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3093 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3094 track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
3095 seed->Reset();
3096 seed->~AliTPCseed();
3097 continue;
3098 }
3099 nout1++;
3100 // Z VERTEX CONDITION
3101 Double_t zv, bz=GetBz();
3102 if ( !track->GetZAt(0.,bz,zv) ) continue;
3103 if (TMath::Abs(zv-z3)>cuts[2]) {
3104 FollowProlongation(*track, TMath::Max(i2-20,0));
3105 if ( !track->GetZAt(0.,bz,zv) ) continue;
3106 if (TMath::Abs(zv-z3)>cuts[2]){
3107 FollowProlongation(*track, TMath::Max(i2-40,0));
3108 if ( !track->GetZAt(0.,bz,zv) ) continue;
3109 if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
3110 // make seed without constrain
3111 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
3112 FollowProlongation(*track2, i2,1);
3113 track2->SetBConstrain(kFALSE);
3114 track2->SetSeedType(1);
3115 arr->AddLast(track2);
3116 seed->Reset();
3117 seed->~AliTPCseed();
3118 continue;
3119 }
3120 else{
3121 seed->Reset();
3122 seed->~AliTPCseed();
3123 continue;
3124
3125 }
3126 }
3127 }
3128
3129 track->SetSeedType(0);
3130 arr->AddLast(track);
3131 seed = new AliTPCseed;
3132 nout2++;
3133 // don't consider other combinations
3134 if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
3135 break;
3136 }
3137 }
3138 }
3139 if (fDebug>3){
3140 Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
3141 }
3142 delete seed;
3143}
3144
3145
3146void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
3147 Float_t deltay) {
3148
3149
3150
3151 //-----------------------------------------------------------------
3152 // This function creates track seeds.
3153 //-----------------------------------------------------------------
3154 // cuts[0] - fP4 cut
3155 // cuts[1] - tan(phi) cut
3156 // cuts[2] - zvertex cut
3157 // cuts[3] - fP3 cut
3158
3159
3160 Int_t nin0 = 0;
3161 Int_t nin1 = 0;
3162 Int_t nin2 = 0;
3163 Int_t nin = 0;
3164 Int_t nout1 = 0;
3165 Int_t nout2 = 0;
3166 Int_t nout3 =0;
3167 Double_t x[5], c[15];
3168 //
3169 // make temporary seed
3170 AliTPCseed * seed = new AliTPCseed;
3171 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3172 // Double_t cs=cos(alpha), sn=sin(alpha);
3173 //
3174 //
3175
3176 // first 3 padrows
3177 Double_t x1 = GetXrow(i1-1);
3178 const AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
3179 Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
3180 //
3181 Double_t x1p = GetXrow(i1);
3182 const AliTPCtrackerRow& kr1p=GetRow(sec,i1);
3183 //
3184 Double_t x1m = GetXrow(i1-2);
3185 const AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
3186
3187 //
3188 //last 3 padrow for seeding
3189 AliTPCtrackerRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
3190 Double_t x3 = GetXrow(i1-7);
3191 // Double_t y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;
3192 //
3193 AliTPCtrackerRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
3194 Double_t x3p = GetXrow(i1-6);
3195 //
3196 AliTPCtrackerRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
3197 Double_t x3m = GetXrow(i1-8);
3198
3199 //
3200 //
3201 // middle padrow
3202 Int_t im = i1-4; //middle pad row index
3203 Double_t xm = GetXrow(im); // radius of middle pad-row
3204 const AliTPCtrackerRow& krm=GetRow(sec,im); //middle pad -row
3205 // Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;
3206 //
3207 //
3208 Double_t deltax = x1-x3;
3209 Double_t dymax = deltax*cuts[1];
3210 Double_t dzmax = deltax*cuts[3];
3211 //
3212 // loop over clusters
3213 for (Int_t is=0; is < kr1; is++) {
3214 //
3215 if (kr1[is]->IsUsed(10)) continue;
3216 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3217 //
3218 if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3219 //
3220 Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
3221 Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
3222 //
3223 Double_t y3, z3;
3224 //
3225 //
3226 UInt_t index;
3227 for (Int_t js=index1; js < index2; js++) {
3228 const AliTPCclusterMI *kcl = kr3[js];
3229 if (kcl->IsUsed(10)) continue;
3230 y3 = kcl->GetY();
3231 // apply angular cuts
3232 if (TMath::Abs(y1-y3)>dymax) continue;
3233 x3 = x3;
3234 z3 = kcl->GetZ();
3235 if (TMath::Abs(z1-z3)>dzmax) continue;
3236 //
3237 Double_t angley = (y1-y3)/(x1-x3);
3238 Double_t anglez = (z1-z3)/(x1-x3);
3239 //
3240 Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
3241 Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
3242 //
3243 Double_t yyym = angley*(xm-x1)+y1;
3244 Double_t zzzm = anglez*(xm-x1)+z1;
3245
3246 const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
3247 if (!kcm) continue;
3248 if (kcm->IsUsed(10)) continue;
3249
3250 erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
3251 errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
3252 //
3253 //
3254 //
3255 Int_t used =0;
3256 Int_t found =0;
3257 //
3258 // look around first
3259 const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
3260 anglez*(x1m-x1)+z1,
3261 erry,errz,index);
3262 //
3263 if (kc1m){
3264 found++;
3265 if (kc1m->IsUsed(10)) used++;
3266 }
3267 const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
3268 anglez*(x1p-x1)+z1,
3269 erry,errz,index);
3270 //
3271 if (kc1p){
3272 found++;
3273 if (kc1p->IsUsed(10)) used++;
3274 }
3275 if (used>1) continue;
3276 if (found<1) continue;
3277
3278 //
3279 // look around last
3280 const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
3281 anglez*(x3m-x3)+z3,
3282 erry,errz,index);
3283 //
3284 if (kc3m){
3285 found++;
3286 if (kc3m->IsUsed(10)) used++;
3287 }
3288 else
3289 continue;
3290 const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
3291 anglez*(x3p-x3)+z3,
3292 erry,errz,index);
3293 //
3294 if (kc3p){
3295 found++;
3296 if (kc3p->IsUsed(10)) used++;
3297 }
3298 else
3299 continue;
3300 if (used>1) continue;
3301 if (found<3) continue;
3302 //
3303 Double_t x2,y2,z2;
3304 x2 = xm;
3305 y2 = kcm->GetY();
3306 z2 = kcm->GetZ();
3307 //
3308
3309 x[0]=y1;
3310 x[1]=z1;
3311 x[4]=F1(x1,y1,x2,y2,x3,y3);
3312 //if (TMath::Abs(x[4]) >= cuts[0]) continue;
3313 nin0++;
3314 //
3315 x[2]=F2(x1,y1,x2,y2,x3,y3);
3316 nin1++;
3317 //
3318 x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
3319 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3320 nin2++;
3321 //
3322 //
3323 Double_t sy1=0.1, sz1=0.1;
3324 Double_t sy2=0.1, sz2=0.1;
3325 Double_t sy3=0.1, sy=0.1, sz=0.1;
3326
3327 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3328 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3329 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3330 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3331 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3332 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3333
3334 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3335 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3336 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3337 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
3338
3339 c[0]=sy1;
3340 c[1]=0.; c[2]=sz1;
3341 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3342 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3343 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3344 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3345 c[13]=f30*sy1*f40+f32*sy2*f42;
3346 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3347
3348 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3349
3350 index=kr1.GetIndex(is);
3351 seed->~AliTPCseed();
3352 AliTPCseed *track=new(seed) AliTPCseed(x1, sec*alpha+shift, x, c, index);
3353
3354 track->SetIsSeeding(kTRUE);
3355
3356 nin++;
3357 FollowProlongation(*track, i1-7,1);
3358 if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
3359 track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
3360 seed->Reset();
3361 seed->~AliTPCseed();
3362 continue;
3363 }
3364 nout1++;
3365 nout2++;
3366 //Int_t rc = 1;
3367 FollowProlongation(*track, i2,1);
3368 track->SetBConstrain(0);
3369 track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
3370 track->SetFirstPoint(track->GetLastPoint());
3371
3372 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3373 track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
3374 track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
3375 seed->Reset();
3376 seed->~AliTPCseed();
3377 continue;
3378 }
3379
3380 {
3381 FollowProlongation(*track, TMath::Max(i2-10,0),1);
3382 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
3383 FollowProlongation(*track2, i2,1);
3384 track2->SetBConstrain(kFALSE);
3385 track2->SetSeedType(4);
3386 arr->AddLast(track2);
3387 seed->Reset();
3388 seed->~AliTPCseed();
3389 }
3390
3391
3392 //arr->AddLast(track);
3393 //seed = new AliTPCseed;
3394 nout3++;
3395 }
3396 }
3397
3398 if (fDebug>3){
3399 Info("MakeSeeds5","\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
3400 }
3401 delete seed;
3402}
3403
3404
3405//_____________________________________________________________________________
3406void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
3407 Float_t deltay, Bool_t /*bconstrain*/) {
3408 //-----------------------------------------------------------------
3409 // This function creates track seeds - without vertex constraint
3410 //-----------------------------------------------------------------
3411 // cuts[0] - fP4 cut - not applied
3412 // cuts[1] - tan(phi) cut
3413 // cuts[2] - zvertex cut - not applied
3414 // cuts[3] - fP3 cut
3415 Int_t nin0=0;
3416 Int_t nin1=0;
3417 Int_t nin2=0;
3418 Int_t nin3=0;
3419 // Int_t nin4=0;
3420 //Int_t nin5=0;
3421
3422
3423
3424 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3425 // Double_t cs=cos(alpha), sn=sin(alpha);
3426 Int_t row0 = (i1+i2)/2;
3427 Int_t drow = (i1-i2)/2;
3428 const AliTPCtrackerRow& kr0=fSectors[sec][row0];
3429 AliTPCtrackerRow * kr=0;
3430
3431 AliTPCpolyTrack polytrack;
3432 Int_t nclusters=fSectors[sec][row0];
3433 AliTPCseed * seed = new AliTPCseed;
3434
3435 Int_t sumused=0;
3436 Int_t cused=0;
3437 Int_t cnused=0;
3438 for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
3439 Int_t nfound =0;
3440 Int_t nfoundable =0;
3441 for (Int_t iter =1; iter<2; iter++){ //iterations
3442 const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
3443 const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];
3444 const AliTPCclusterMI * cl= kr0[is];
3445
3446 if (cl->IsUsed(10)) {
3447 cused++;
3448 }
3449 else{
3450 cnused++;
3451 }
3452 Double_t x = kr0.GetX();
3453 // Initialization of the polytrack
3454 nfound =0;
3455 nfoundable =0;
3456 polytrack.Reset();
3457 //
3458 Double_t y0= cl->GetY();
3459 Double_t z0= cl->GetZ();
3460 Float_t erry = 0;
3461 Float_t errz = 0;
3462
3463 Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
3464 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
3465
3466 erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
3467 errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
3468 polytrack.AddPoint(x,y0,z0,erry, errz);
3469
3470 sumused=0;
3471 if (cl->IsUsed(10)) sumused++;
3472
3473
3474 Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
3475 Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
3476 //
3477 x = krm.GetX();
3478 AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
3479 if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
3480 erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
3481 errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
3482 if (cl1->IsUsed(10)) sumused++;
3483 polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
3484 }
3485 //
3486 x = krp.GetX();
3487 AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
3488 if (cl2) {
3489 erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
3490 errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
3491 if (cl2->IsUsed(10)) sumused++;
3492 polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
3493 }
3494 //
3495 if (sumused>0) continue;
3496 nin0++;
3497 polytrack.UpdateParameters();
3498 // follow polytrack
3499 roadz = 1.2;
3500 roady = 1.2;
3501 //
3502 Double_t yn,zn;
3503 nfoundable = polytrack.GetN();
3504 nfound = nfoundable;
3505 //
3506 for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
3507 Float_t maxdist = 0.8*(1.+3./(ddrow));
3508 for (Int_t delta = -1;delta<=1;delta+=2){
3509 Int_t row = row0+ddrow*delta;
3510 kr = &(fSectors[sec][row]);
3511 Double_t xn = kr->GetX();
3512 Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
3513 polytrack.GetFitPoint(xn,yn,zn);
3514 if (TMath::Abs(yn)>ymax1) continue;
3515 nfoundable++;
3516 AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
3517 if (cln) {
3518 Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
3519 if (dist<maxdist){
3520 /*
3521 erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3522 errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3523 if (cln->IsUsed(10)) {
3524 // printf("used\n");
3525 sumused++;
3526 erry*=2;
3527 errz*=2;
3528 }
3529 */
3530 erry=0.1;
3531 errz=0.1;
3532 polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
3533 nfound++;
3534 }
3535 }
3536 }
3537 if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
3538 polytrack.UpdateParameters();
3539 }
3540 }
3541 if ( (sumused>3) || (sumused>0.5*nfound)) {
3542 //printf("sumused %d\n",sumused);
3543 continue;
3544 }
3545 nin1++;
3546 Double_t dy,dz;
3547 polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
3548 AliTPCpolyTrack track2;
3549
3550 polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
3551 if (track2.GetN()<0.5*nfoundable) continue;
3552 nin2++;
3553
3554 if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
3555 //
3556 // test seed with and without constrain
3557 for (Int_t constrain=0; constrain<=0;constrain++){
3558 // add polytrack candidate
3559
3560 Double_t x[5], c[15];
3561 Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
3562 track2.GetBoundaries(x3,x1);
3563 x2 = (x1+x3)/2.;
3564 track2.GetFitPoint(x1,y1,z1);
3565 track2.GetFitPoint(x2,y2,z2);
3566 track2.GetFitPoint(x3,y3,z3);
3567 //
3568 //is track pointing to the vertex ?
3569 Double_t x0,y0,z0;
3570 x0=0;
3571 polytrack.GetFitPoint(x0,y0,z0);
3572
3573 if (constrain) {
3574 x2 = x3;
3575 y2 = y3;
3576 z2 = z3;
3577
3578 x3 = 0;
3579 y3 = 0;
3580 z3 = 0;
3581 }
3582 x[0]=y1;
3583 x[1]=z1;
3584 x[4]=F1(x1,y1,x2,y2,x3,y3);
3585
3586 // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
3587 x[2]=F2(x1,y1,x2,y2,x3,y3);
3588
3589 //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
3590 //x[3]=F3(x1,y1,x2,y2,z1,z2);
3591 x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
3592 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3593
3594
3595 Double_t sy =0.1, sz =0.1;
3596 Double_t sy1=0.02, sz1=0.02;
3597 Double_t sy2=0.02, sz2=0.02;
3598 Double_t sy3=0.02;
3599
3600 if (constrain){
3601 sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3602 }
3603
3604 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3605 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3606 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3607 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3608 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3609 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3610
3611 Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
3612 Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
3613 Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
3614 Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
3615
3616
3617 c[0]=sy1;
3618 c[1]=0.; c[2]=sz1;
3619 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3620 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3621 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3622 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3623 c[13]=f30*sy1*f40+f32*sy2*f42;
3624 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3625
3626 //Int_t row1 = fSectors->GetRowNumber(x1);
3627 Int_t row1 = GetRowNumber(x1);
3628
3629 UInt_t index=0;
3630 //kr0.GetIndex(is);
3631 seed->~AliTPCseed();
3632 AliTPCseed *track=new(seed) AliTPCseed(x1,sec*alpha+shift,x,c,index);
3633 track->SetIsSeeding(kTRUE);
3634 Int_t rc=FollowProlongation(*track, i2);
3635 if (constrain) track->SetBConstrain(1);
3636 else
3637 track->SetBConstrain(0);
3638 track->SetLastPoint(row1+fInnerSec->GetNRows()); // first cluster in track position
3639 track->SetFirstPoint(track->GetLastPoint());
3640
3641 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3642 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3643 track->GetNShared()>0.4*track->GetNumberOfClusters()) {
3644 //delete track;
3645 seed->Reset();
3646 seed->~AliTPCseed();
3647 }
3648 else {
3649 arr->AddLast(track);
3650 seed = new AliTPCseed;
3651 }
3652 nin3++;
3653 }
3654 } // if accepted seed
3655 }
3656 if (fDebug>3){
3657 Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
3658 }
3659 delete seed;
3660}
3661
3662
3663AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
3664{
3665 //
3666 //
3667 //reseed using track points
3668 Int_t p0 = int(r0*track->GetNumberOfClusters()); // point 0
3669 Int_t p1 = int(r1*track->GetNumberOfClusters());
3670 Int_t p2 = int(r2*track->GetNumberOfClusters()); // last point
3671 Int_t pp2=0;
3672 Double_t x0[3],x1[3],x2[3];
3673 for (Int_t i=0;i<3;i++){
3674 x0[i]=-1;
3675 x1[i]=-1;
3676 x2[i]=-1;
3677 }
3678
3679 // find track position at given ratio of the length
3680 Int_t sec0=0, sec1=0, sec2=0;
3681 Int_t index=-1;
3682 Int_t clindex;
3683 for (Int_t i=0;i<160;i++){
3684 if (track->GetClusterPointer(i)){
3685 index++;
3686 AliTPCTrackerPoint *trpoint =track->GetTrackPoint(i);
3687 if ( (index<p0) || x0[0]<0 ){
3688 if (trpoint->GetX()>1){
3689 clindex = track->GetClusterIndex2(i);
3690 if (clindex>0){
3691 x0[0] = trpoint->GetX();
3692 x0[1] = trpoint->GetY();
3693 x0[2] = trpoint->GetZ();
3694 sec0 = ((clindex&0xff000000)>>24)%18;
3695 }
3696 }
3697 }
3698
3699 if ( (index<p1) &&(trpoint->GetX()>1)){
3700 clindex = track->GetClusterIndex2(i);
3701 if (clindex>0){
3702 x1[0] = trpoint->GetX();
3703 x1[1] = trpoint->GetY();
3704 x1[2] = trpoint->GetZ();
3705 sec1 = ((clindex&0xff000000)>>24)%18;
3706 }
3707 }
3708 if ( (index<p2) &&(trpoint->GetX()>1)){
3709 clindex = track->GetClusterIndex2(i);
3710 if (clindex>0){
3711 x2[0] = trpoint->GetX();
3712 x2[1] = trpoint->GetY();
3713 x2[2] = trpoint->GetZ();
3714 sec2 = ((clindex&0xff000000)>>24)%18;
3715 pp2 = i;
3716 }
3717 }
3718 }
3719 }
3720
3721 Double_t alpha, cs,sn, xx2,yy2;
3722 //
3723 alpha = (sec1-sec2)*fSectors->GetAlpha();
3724 cs = TMath::Cos(alpha);
3725 sn = TMath::Sin(alpha);
3726 xx2= x1[0]*cs-x1[1]*sn;
3727 yy2= x1[0]*sn+x1[1]*cs;
3728 x1[0] = xx2;
3729 x1[1] = yy2;
3730 //
3731 alpha = (sec0-sec2)*fSectors->GetAlpha();
3732 cs = TMath::Cos(alpha);
3733 sn = TMath::Sin(alpha);
3734 xx2= x0[0]*cs-x0[1]*sn;
3735 yy2= x0[0]*sn+x0[1]*cs;
3736 x0[0] = xx2;
3737 x0[1] = yy2;
3738 //
3739 //
3740 //
3741 Double_t x[5],c[15];
3742 //
3743 x[0]=x2[1];
3744 x[1]=x2[2];
3745 x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
3746 // if (x[4]>1) return 0;
3747 x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
3748 x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
3749 //if (TMath::Abs(x[3]) > 2.2) return 0;
3750 //if (TMath::Abs(x[2]) > 1.99) return 0;
3751 //
3752 Double_t sy =0.1, sz =0.1;
3753 //
3754 Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
3755 Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
3756 Double_t sy3=0.01+track->GetSigmaY2();
3757 //
3758 Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
3759 Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
3760 Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
3761 Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
3762 Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
3763 Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
3764 //
3765 Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
3766 Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
3767 Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
3768 Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
3769
3770
3771 c[0]=sy1;
3772 c[1]=0.; c[2]=sz1;
3773 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3774 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3775 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3776 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3777 c[13]=f30*sy1*f40+f32*sy2*f42;
3778 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3779
3780 // Int_t row1 = fSectors->GetRowNumber(x2[0]);
3781 AliTPCseed *seed=new AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
3782 // Double_t y0,z0,y1,z1, y2,z2;
3783 //seed->GetProlongation(x0[0],y0,z0);
3784 // seed->GetProlongation(x1[0],y1,z1);
3785 //seed->GetProlongation(x2[0],y2,z2);
3786 // seed =0;
3787 seed->SetLastPoint(pp2);
3788 seed->SetFirstPoint(pp2);
3789
3790
3791 return seed;
3792}
3793
3794
3795AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
3796{
3797 //
3798 //
3799 //reseed using founded clusters
3800 //
3801 // Find the number of clusters
3802 Int_t nclusters = 0;
3803 for (Int_t irow=0;irow<160;irow++){
3804 if (track->GetClusterIndex(irow)>0) nclusters++;
3805 }
3806 //
3807 Int_t ipos[3];
3808 ipos[0] = TMath::Max(int(r0*nclusters),0); // point 0 cluster
3809 ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1); //
3810 ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1); // last point
3811 //
3812 //
3813 Double_t xyz[3][3];
3814 Int_t row[3],sec[3]={0,0,0};
3815 //
3816 // find track row position at given ratio of the length
3817 Int_t index=-1;
3818 for (Int_t irow=0;irow<160;irow++){
3819 if (track->GetClusterIndex2(irow)<0) continue;
3820 index++;
3821 for (Int_t ipoint=0;ipoint<3;ipoint++){
3822 if (index<=ipos[ipoint]) row[ipoint] = irow;
3823 }
3824 }
3825 //
3826 //Get cluster and sector position
3827 for (Int_t ipoint=0;ipoint<3;ipoint++){
3828 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
3829 AliTPCclusterMI * cl = GetClusterMI(clindex);
3830 if (cl==0) {
3831 //Error("Bug\n");
3832 // AliTPCclusterMI * cl = GetClusterMI(clindex);
3833 return 0;
3834 }
3835 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
3836 xyz[ipoint][0] = GetXrow(row[ipoint]);
3837 xyz[ipoint][1] = cl->GetY();
3838 xyz[ipoint][2] = cl->GetZ();
3839 }
3840 //
3841 //
3842 // Calculate seed state vector and covariance matrix
3843
3844 Double_t alpha, cs,sn, xx2,yy2;
3845 //
3846 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
3847 cs = TMath::Cos(alpha);
3848 sn = TMath::Sin(alpha);
3849 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
3850 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
3851 xyz[1][0] = xx2;
3852 xyz[1][1] = yy2;
3853 //
3854 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
3855 cs = TMath::Cos(alpha);
3856 sn = TMath::Sin(alpha);
3857 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
3858 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
3859 xyz[0][0] = xx2;
3860 xyz[0][1] = yy2;
3861 //
3862 //
3863 //
3864 Double_t x[5],c[15];
3865 //
3866 x[0]=xyz[2][1];
3867 x[1]=xyz[2][2];
3868 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
3869 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
3870 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
3871 //
3872 Double_t sy =0.1, sz =0.1;
3873 //
3874 Double_t sy1=0.2, sz1=0.2;
3875 Double_t sy2=0.2, sz2=0.2;
3876 Double_t sy3=0.2;
3877 //
3878 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;
3879 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;
3880 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;
3881 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;
3882 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;
3883 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;
3884 //
3885 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;
3886 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;
3887 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;
3888 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;
3889
3890
3891 c[0]=sy1;
3892 c[1]=0.; c[2]=sz1;
3893 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3894 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3895 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3896 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3897 c[13]=f30*sy1*f40+f32*sy2*f42;
3898 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3899
3900 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
3901 AliTPCseed *seed=new AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
3902 seed->SetLastPoint(row[2]);
3903 seed->SetFirstPoint(row[2]);
3904 return seed;
3905}
3906
3907
3908AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
3909{
3910 //
3911 //
3912 //reseed using founded clusters
3913 //
3914 Double_t xyz[3][3];
3915 Int_t row[3]={0,0,0};
3916 Int_t sec[3]={0,0,0};
3917 //
3918 // forward direction
3919 if (forward){
3920 for (Int_t irow=r0;irow<160;irow++){
3921 if (track->GetClusterIndex(irow)>0){
3922 row[0] = irow;
3923 break;
3924 }
3925 }
3926 for (Int_t irow=160;irow>r0;irow--){
3927 if (track->GetClusterIndex(irow)>0){
3928 row[2] = irow;
3929 break;
3930 }
3931 }
3932 for (Int_t irow=row[2]-15;irow>row[0];irow--){
3933 if (track->GetClusterIndex(irow)>0){
3934 row[1] = irow;
3935 break;
3936 }
3937 }
3938 //
3939 }
3940 if (!forward){
3941 for (Int_t irow=0;irow<r0;irow++){
3942 if (track->GetClusterIndex(irow)>0){
3943 row[0] = irow;
3944 break;
3945 }
3946 }
3947 for (Int_t irow=r0;irow>0;irow--){
3948 if (track->GetClusterIndex(irow)>0){
3949 row[2] = irow;
3950 break;
3951 }
3952 }
3953 for (Int_t irow=row[2]-15;irow>row[0];irow--){
3954 if (track->GetClusterIndex(irow)>0){
3955 row[1] = irow;
3956 break;
3957 }
3958 }
3959 }
3960 //
3961 if ((row[2]-row[0])<20) return 0;
3962 if (row[1]==0) return 0;
3963 //
3964 //
3965 //Get cluster and sector position
3966 for (Int_t ipoint=0;ipoint<3;ipoint++){
3967 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
3968 AliTPCclusterMI * cl = GetClusterMI(clindex);
3969 if (cl==0) {
3970 //Error("Bug\n");
3971 // AliTPCclusterMI * cl = GetClusterMI(clindex);
3972 return 0;
3973 }
3974 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
3975 xyz[ipoint][0] = GetXrow(row[ipoint]);
3976 AliTPCTrackerPoint * point = track->GetTrackPoint(row[ipoint]);
3977 if (point&&ipoint<2){
3978 //
3979 xyz[ipoint][1] = point->GetY();
3980 xyz[ipoint][2] = point->GetZ();
3981 }
3982 else{
3983 xyz[ipoint][1] = cl->GetY();
3984 xyz[ipoint][2] = cl->GetZ();
3985 }
3986 }
3987 //
3988 //
3989 //
3990 //
3991 // Calculate seed state vector and covariance matrix
3992
3993 Double_t alpha, cs,sn, xx2,yy2;
3994 //
3995 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
3996 cs = TMath::Cos(alpha);
3997 sn = TMath::Sin(alpha);
3998 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
3999 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4000 xyz[1][0] = xx2;
4001 xyz[1][1] = yy2;
4002 //
4003 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4004 cs = TMath::Cos(alpha);
4005 sn = TMath::Sin(alpha);
4006 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4007 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4008 xyz[0][0] = xx2;
4009 xyz[0][1] = yy2;
4010 //
4011 //
4012 //
4013 Double_t x[5],c[15];
4014 //
4015 x[0]=xyz[2][1];
4016 x[1]=xyz[2][2];
4017 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4018 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4019 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4020 //
4021 Double_t sy =0.1, sz =0.1;
4022 //
4023 Double_t sy1=0.2, sz1=0.2;
4024 Double_t sy2=0.2, sz2=0.2;
4025 Double_t sy3=0.2;
4026 //
4027 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;
4028 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;
4029 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;
4030 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;
4031 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;
4032 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;
4033 //
4034 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;
4035 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;
4036 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;
4037 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;
4038
4039
4040 c[0]=sy1;
4041 c[1]=0.; c[2]=sz1;
4042 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4043 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4044 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4045 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4046 c[13]=f30*sy1*f40+f32*sy2*f42;
4047 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4048
4049 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
4050 AliTPCseed *seed=new AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4051 seed->SetLastPoint(row[2]);
4052 seed->SetFirstPoint(row[2]);
4053 for (Int_t i=row[0];i<row[2];i++){
4054 seed->SetClusterIndex(i, track->GetClusterIndex(i));
4055 }
4056
4057 return seed;
4058}
4059
4060
4061
4062void AliTPCtrackerMI::FindMultiMC(TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
4063{
4064 //
4065 // find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
4066 // USES MC LABELS
4067 // Use AliTPCReconstructor::StreamLevel()>2 if you want to tune parameters - cuts
4068 //
4069 // Two reasons to have multiple find tracks
4070 // 1. Curling tracks can be find more than once
4071 // 2. Splitted tracks
4072 // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
4073 // b.) Edge effect on the sector boundaries
4074 //
4075 //
4076 // Algorithm done in 2 phases - because of CPU consumption
4077 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4078 //
4079 // Algorihm for curling tracks sign:
4080 // 1 phase -makes a very rough fast cuts to minimize combinatorics
4081 // a.) opposite sign
4082 // b.) one of the tracks - not pointing to the primary vertex -
4083 // c.) delta tan(theta)
4084 // d.) delta phi
4085 // 2 phase - calculates DCA between tracks - time consument
4086
4087 //
4088 // fast cuts
4089 //
4090 // General cuts - for splitted tracks and for curling tracks
4091 //
4092 const Float_t kMaxdPhi = 0.2; // maximal distance in phi
4093 //
4094 // Curling tracks cuts
4095 //
4096 //
4097 //
4098 //
4099 Int_t nentries = array->GetEntriesFast();
4100 AliHelix *helixes = new AliHelix[nentries];
4101 Float_t *xm = new Float_t[nentries];
4102 Float_t *dz0 = new Float_t[nentries];
4103 Float_t *dz1 = new Float_t[nentries];
4104 //
4105 //
4106 TStopwatch timer;
4107 timer.Start();
4108 //
4109 // Find track COG in x direction - point with best defined parameters
4110 //
4111 for (Int_t i=0;i<nentries;i++){
4112 AliTPCseed* track = (AliTPCseed*)array->At(i);
4113 if (!track) continue;
4114 track->SetCircular(0);
4115 new (&helixes[i]) AliHelix(*track);
4116 Int_t ncl=0;
4117 xm[i]=0;
4118 Float_t dz[2];
4119 track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
4120 dz0[i]=dz[0];
4121 dz1[i]=dz[1];
4122 for (Int_t icl=0; icl<160; icl++){
4123 AliTPCclusterMI * cl = track->GetClusterPointer(icl);
4124 if (cl) {
4125 xm[i]+=cl->GetX();
4126 ncl++;
4127 }
4128 }
4129 if (ncl>0) xm[i]/=Float_t(ncl);
4130 }
4131 //
4132 for (Int_t i0=0;i0<nentries;i0++){
4133 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4134 if (!track0) continue;
4135 Float_t xc0 = helixes[i0].GetHelix(6);
4136 Float_t yc0 = helixes[i0].GetHelix(7);
4137 Float_t r0 = helixes[i0].GetHelix(8);
4138 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4139 Float_t fi0 = TMath::ATan2(yc0,xc0);
4140
4141 for (Int_t i1=i0+1;i1<nentries;i1++){
4142 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4143 if (!track1) continue;
4144 Int_t lab0=track0->GetLabel();
4145 Int_t lab1=track1->GetLabel();
4146 if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
4147 //
4148 Float_t xc1 = helixes[i1].GetHelix(6);
4149 Float_t yc1 = helixes[i1].GetHelix(7);
4150 Float_t r1 = helixes[i1].GetHelix(8);
4151 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4152 Float_t fi1 = TMath::ATan2(yc1,xc1);
4153 //
4154 Float_t dfi = fi0-fi1;
4155 //
4156 //
4157 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
4158 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
4159 if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
4160 //
4161 // if short tracks with undefined sign
4162 fi1 = -TMath::ATan2(yc1,-xc1);
4163 dfi = fi0-fi1;
4164 }
4165 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4166
4167 //
4168 // debug stream to tune "fast cuts"
4169 //
4170 Double_t dist[3]; // distance at X
4171 Double_t mdist[3]={0,0,0}; // mean distance X+-40cm
4172 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
4173 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4174 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
4175 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4176 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
4177 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4178 for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
4179
4180 Float_t sum =0;
4181 Float_t sums=0;
4182 for (Int_t icl=0; icl<160; icl++){
4183 AliTPCclusterMI * cl0 = track0->GetClusterPointer(icl);
4184 AliTPCclusterMI * cl1 = track1->GetClusterPointer(icl);
4185 if (cl0&&cl1) {
4186 sum++;
4187 if (cl0==cl1) sums++;
4188 }
4189 }
4190 //
4191 if (AliTPCReconstructor::StreamLevel()>0) {
4192 TTreeSRedirector &cstream = *fDebugStreamer;
4193 cstream<<"Multi"<<
4194 "iter="<<iter<<
4195 "lab0="<<lab0<<
4196 "lab1="<<lab1<<
4197 "Tr0.="<<track0<< // seed0
4198 "Tr1.="<<track1<< // seed1
4199 "h0.="<<&helixes[i0]<<
4200 "h1.="<<&helixes[i1]<<
4201 //
4202 "sum="<<sum<< //the sum of rows with cl in both
4203 "sums="<<sums<< //the sum of shared clusters
4204 "xm0="<<xm[i0]<< // the center of track
4205 "xm1="<<xm[i1]<< // the x center of track
4206 // General cut variables
4207 "dfi="<<dfi<< // distance in fi angle
4208 "dtheta="<<dtheta<< // distance int theta angle
4209 //
4210 "dz00="<<dz0[i0]<<
4211 "dz01="<<dz0[i1]<<
4212 "dz10="<<dz1[i1]<<
4213 "dz11="<<dz1[i1]<<
4214 "dist0="<<dist[0]<< //distance x
4215 "dist1="<<dist[1]<< //distance y
4216 "dist2="<<dist[2]<< //distance z
4217 "mdist0="<<mdist[0]<< //distance x
4218 "mdist1="<<mdist[1]<< //distance y
4219 "mdist2="<<mdist[2]<< //distance z
4220 //
4221 "r0="<<r0<<
4222 "rc0="<<rc0<<
4223 "fi0="<<fi0<<
4224 "fi1="<<fi1<<
4225 "r1="<<r1<<
4226 "rc1="<<rc1<<
4227 "\n";
4228 }
4229 }
4230 }
4231 delete [] helixes;
4232 delete [] xm;
4233 if (AliTPCReconstructor::StreamLevel()>1) {
4234 AliInfo("Time for curling tracks removal DEBUGGING MC");
4235 timer.Print();
4236 }
4237}
4238
4239
4240void AliTPCtrackerMI::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
4241{
4242 //
4243 //
4244 // Two reasons to have multiple find tracks
4245 // 1. Curling tracks can be find more than once
4246 // 2. Splitted tracks
4247 // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
4248 // b.) Edge effect on the sector boundaries
4249 //
4250 // This function tries to find tracks closed in the parametric space
4251 //
4252 // cut logic if distance is bigger than cut continue - Do Nothing
4253 const Float_t kMaxdTheta = 0.05; // maximal distance in theta
4254 const Float_t kMaxdPhi = 0.05; // maximal deistance in phi
4255 const Float_t kdelta = 40.; //delta r to calculate track distance
4256 //
4257 // const Float_t kMaxDist0 = 1.; // maximal distance 0
4258 //const Float_t kMaxDist1 = 0.3; // maximal distance 1 - cut if track in separate rows
4259 //
4260 /*
4261 TCut csec("csec","abs(Tr0.fRelativeSector-Tr1.fRelativeSector)<2");
4262 TCut cdtheta("cdtheta","abs(dtheta)<0.05");
4263 */
4264 //
4265 //
4266 //
4267 Int_t nentries = array->GetEntriesFast();
4268 AliHelix *helixes = new AliHelix[nentries];
4269 Float_t *xm = new Float_t[nentries];
4270 //
4271 //
4272 TStopwatch timer;
4273 timer.Start();
4274 //
4275 //Sort tracks according quality
4276 //
4277 Int_t nseed = array->GetEntriesFast();
4278 Float_t * quality = new Float_t[nseed];
4279 Int_t * indexes = new Int_t[nseed];
4280 for (Int_t i=0; i<nseed; i++) {
4281 AliTPCseed *pt=(AliTPCseed*)array->UncheckedAt(i);
4282 if (!pt){
4283 quality[i]=-1;
4284 continue;
4285 }
4286 pt->UpdatePoints(); //select first last max dens points
4287 Float_t * points = pt->GetPoints();
4288 if (points[3]<0.8) quality[i] =-1;
4289 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
4290 //prefer high momenta tracks if overlaps
4291 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
4292 }
4293 TMath::Sort(nseed,quality,indexes);
4294
4295
4296 //
4297 // Find track COG in x direction - point with best defined parameters
4298 //
4299 for (Int_t i=0;i<nentries;i++){
4300 AliTPCseed* track = (AliTPCseed*)array->At(i);
4301 if (!track) continue;
4302 track->SetCircular(0);
4303 new (&helixes[i]) AliHelix(*track);
4304 Int_t ncl=0;
4305 xm[i]=0;
4306 for (Int_t icl=0; icl<160; icl++){
4307 AliTPCclusterMI * cl = track->GetClusterPointer(icl);
4308 if (cl) {
4309 xm[i]+=cl->GetX();
4310 ncl++;
4311 }
4312 }
4313 if (ncl>0) xm[i]/=Float_t(ncl);
4314 }
4315 //
4316 for (Int_t is0=0;is0<nentries;is0++){
4317 Int_t i0 = indexes[is0];
4318 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4319 if (!track0) continue;
4320 Float_t xc0 = helixes[i0].GetHelix(6);
4321 Float_t yc0 = helixes[i0].GetHelix(7);
4322 Float_t fi0 = TMath::ATan2(yc0,xc0);
4323
4324 for (Int_t is1=is0+1;is1<nentries;is1++){
4325 Int_t i1 = indexes[is1];
4326 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4327 if (!track1) continue;
4328 //
4329 Int_t dsec = TMath::Abs((track0->GetRelativeSector()%18)-(track1->GetRelativeSector()%18)); // sector distance
4330 if (dsec>1 && dsec<17) continue;
4331
4332 if (track1->GetKinkIndexes()[0] == -track0->GetKinkIndexes()[0]) continue;
4333
4334 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4335 if (TMath::Abs(dtheta)>kMaxdTheta) continue;
4336 //
4337 Float_t xc1 = helixes[i1].GetHelix(6);
4338 Float_t yc1 = helixes[i1].GetHelix(7);
4339 Float_t fi1 = TMath::ATan2(yc1,xc1);
4340 //
4341 Float_t dfi = fi0-fi1;
4342 if (dfi>TMath::Pi()) dfi-=TMath::TwoPi(); // take care about edge effect
4343 if (dfi<-TMath::Pi()) dfi+=TMath::TwoPi(); //
4344 if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
4345 //
4346 // if short tracks with undefined sign
4347 fi1 = -TMath::ATan2(yc1,-xc1);
4348 dfi = fi0-fi1;
4349 if (dfi>TMath::Pi()) dfi-=TMath::TwoPi(); // take care about edge effect
4350 if (dfi<-TMath::Pi()) dfi+=TMath::TwoPi(); //
4351 }
4352 if (TMath::Abs(dfi)>kMaxdPhi) continue;
4353 //
4354 //
4355 Float_t sum =0;
4356 Float_t sums=0;
4357 Float_t sum0=0;
4358 Float_t sum1=0;
4359 for (Int_t icl=0; icl<160; icl++){
4360 Int_t index0=track0->GetClusterIndex2(icl);
4361 Int_t index1=track1->GetClusterIndex2(icl);
4362 Bool_t used0 = (index0>0 && !(index0&0x8000));
4363 Bool_t used1 = (index1>0 && !(index1&0x8000));
4364 //
4365 if (used0) sum0++; // used cluster0
4366 if (used1) sum1++; // used clusters1
4367 if (used0&&used1) sum++;
4368 if (index0==index1 && used0 && used1) sums++;
4369 }
4370
4371 //
4372 if (sums<10) continue;
4373 if (sum<40) continue;
4374 if (sums/Float_t(TMath::Min(sum0,sum1))<0.5) continue;
4375 //
4376 Double_t dist[5][4]; // distance at X
4377 Double_t mdist[4]={0,0,0,0}; // mean distance on range +-delta
4378
4379 //
4380 //
4381 track0->GetDistance(track1,xm[i0],dist[0],AliTracker::GetBz());
4382 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[0][i]);
4383 track0->GetDistance(track1,xm[i1],dist[1],AliTracker::GetBz());
4384 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[1][i]);
4385 //
4386 track0->GetDistance(track1,TMath::Min(xm[i1],xm[i0])-kdelta,dist[2],AliTracker::GetBz());
4387 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[2][i]);
4388 track0->GetDistance(track1,TMath::Max(xm[i1],xm[i0])+kdelta,dist[3],AliTracker::GetBz());
4389 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[3][i]);
4390 //
4391 track0->GetDistance(track1,(xm[i1]+xm[i0])*0.5,dist[4],AliTracker::GetBz());
4392 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[4][i]);
4393 for (Int_t i=0;i<3;i++) mdist[i]*=0.2;
4394 //
4395 //
4396 Int_t lab0=track0->GetLabel();
4397 Int_t lab1=track1->GetLabel();
4398 if( AliTPCReconstructor::StreamLevel()>5){
4399 TTreeSRedirector &cstream = *fDebugStreamer;
4400 cstream<<"Splitted"<<
4401 "iter="<<iter<<
4402 "lab0="<<lab0<<
4403 "lab1="<<lab1<<
4404 "Tr0.="<<track0<< // seed0
4405 "Tr1.="<<track1<< // seed1
4406 "h0.="<<&helixes[i0]<<
4407 "h1.="<<&helixes[i1]<<
4408 //
4409 "sum="<<sum<< //the sum of rows with cl in both
4410 "sum0="<<sum0<< //the sum of rows with cl in 0 track
4411 "sum1="<<sum1<< //the sum of rows with cl in 1 track
4412 "sums="<<sums<< //the sum of shared clusters
4413 "xm0="<<xm[i0]<< // the center of track
4414 "xm1="<<xm[i1]<< // the x center of track
4415 // General cut variables
4416 "dfi="<<dfi<< // distance in fi angle
4417 "dtheta="<<dtheta<< // distance int theta angle
4418 //
4419 //
4420 "dist0="<<dist[4][0]<< //distance x
4421 "dist1="<<dist[4][1]<< //distance y
4422 "dist2="<<dist[4][2]<< //distance z
4423 "mdist0="<<mdist[0]<< //distance x
4424 "mdist1="<<mdist[1]<< //distance y
4425 "mdist2="<<mdist[2]<< //distance z
4426 "\n";
4427 }
4428 delete array->RemoveAt(i1);
4429 }
4430 }
4431 delete [] helixes;
4432 delete [] xm;
4433 delete [] quality;
4434 delete [] indexes;
4435 AliInfo("Time for splitted tracks removal");
4436 timer.Print();
4437}
4438
4439
4440
4441void AliTPCtrackerMI::FindCurling(TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
4442{
4443 //
4444 // find Curling tracks
4445 // Use AliTPCReconstructor::StreamLevel()>1 if you want to tune parameters - cuts
4446 //
4447 //
4448 // Algorithm done in 2 phases - because of CPU consumption
4449 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4450 // see detal in MC part what can be used to cut
4451 //
4452 //
4453 //
4454 const Float_t kMaxC = 400; // maximal curvature to of the track
4455 const Float_t kMaxdTheta = 0.15; // maximal distance in theta
4456 const Float_t kMaxdPhi = 0.15; // maximal distance in phi
4457 const Float_t kPtRatio = 0.3; // ratio between pt
4458 const Float_t kMinDCAR = 2.; // distance to the primary vertex in r - see cpipe cut
4459
4460 //
4461 // Curling tracks cuts
4462 //
4463 //
4464 const Float_t kMaxDeltaRMax = 40; // distance in outer radius
4465 const Float_t kMaxDeltaRMin = 5.; // distance in lower radius - see cpipe cut
4466 const Float_t kMinAngle = 2.9; // angle between tracks
4467 const Float_t kMaxDist = 5; // biggest distance
4468 //
4469 // The cuts can be tuned using the "MC information stored in Multi tree ==> see FindMultiMC
4470 /*
4471 Fast cuts:
4472 TCut csign("csign","Tr0.fP[4]*Tr1.fP[4]<0"); //opposite sign
4473 TCut cmax("cmax","abs(Tr0.GetC())>1/400");
4474 TCut cda("cda","sqrt(dtheta^2+dfi^2)<0.15");
4475 TCut ccratio("ccratio","abs((Tr0.fP[4]+Tr1.fP[4])/(abs(Tr0.fP[4])+abs(Tr1.fP[4])))<0.3");
4476 TCut cpipe("cpipe", "min(abs(r0-rc0),abs(r1-rc1))>5");
4477 //
4478 TCut cdrmax("cdrmax","abs(abs(rc0+r0)-abs(rc1+r1))<40")
4479 TCut cdrmin("cdrmin","abs(abs(rc0+r0)-abs(rc1+r1))<10")
4480 //
4481 Multi->Draw("dfi","iter==0"+csign+cmax+cda+ccratio); ~94% of curling tracks fulfill
4482 Multi->Draw("min(abs(r0-rc0),abs(r1-rc1))","iter==0&&abs(lab1)==abs(lab0)"+csign+cmax+cda+ccratio+cpipe+cdrmin+cdrmax); //80%
4483 //
4484 Curling2->Draw("dfi","iter==0&&abs(lab0)==abs(lab1)"+csign+cmax+cdtheta+cdfi+ccratio)
4485
4486 */
4487 //
4488 //
4489 //
4490 Int_t nentries = array->GetEntriesFast();
4491 AliHelix *helixes = new AliHelix[nentries];
4492 for (Int_t i=0;i<nentries;i++){
4493 AliTPCseed* track = (AliTPCseed*)array->At(i);
4494 if (!track) continue;
4495 track->SetCircular(0);
4496 new (&helixes[i]) AliHelix(*track);
4497 }
4498 //
4499 //
4500 TStopwatch timer;
4501 timer.Start();
4502 Double_t phase[2][2],radius[2];
4503 //
4504 // Find tracks
4505 //
4506 //
4507 for (Int_t i0=0;i0<nentries;i0++){
4508 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4509 if (!track0) continue;
4510 if (TMath::Abs(track0->GetC())<1/kMaxC) continue;
4511 Float_t xc0 = helixes[i0].GetHelix(6);
4512 Float_t yc0 = helixes[i0].GetHelix(7);
4513 Float_t r0 = helixes[i0].GetHelix(8);
4514 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4515 Float_t fi0 = TMath::ATan2(yc0,xc0);
4516
4517 for (Int_t i1=i0+1;i1<nentries;i1++){
4518 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4519 if (!track1) continue;
4520 if (TMath::Abs(track1->GetC())<1/kMaxC) continue;
4521 Float_t xc1 = helixes[i1].GetHelix(6);
4522 Float_t yc1 = helixes[i1].GetHelix(7);
4523 Float_t r1 = helixes[i1].GetHelix(8);
4524 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4525 Float_t fi1 = TMath::ATan2(yc1,xc1);
4526 //
4527 Float_t dfi = fi0-fi1;
4528 //
4529 //
4530 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
4531 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
4532 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4533 //
4534 //
4535 // FIRST fast cuts
4536 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue; // not constrained
4537 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue; // not the same sign
4538 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>kMaxdTheta) continue; //distance in the Theta
4539 if ( TMath::Abs(dfi)>kMaxdPhi) continue; //distance in phi
4540 if ( TMath::Sqrt(dfi*dfi+dtheta*dtheta)>kMaxdPhi) continue; //common angular offset
4541 //
4542 Float_t pt0 = track0->GetSignedPt();
4543 Float_t pt1 = track1->GetSignedPt();
4544 if ((TMath::Abs(pt0+pt1)/(TMath::Abs(pt0)+TMath::Abs(pt1)))>kPtRatio) continue;
4545 if ((iter==1) && TMath::Abs(TMath::Abs(rc0+r0)-TMath::Abs(rc1+r1))>kMaxDeltaRMax) continue;
4546 if ((iter!=1) &&TMath::Abs(TMath::Abs(rc0-r0)-TMath::Abs(rc1-r1))>kMaxDeltaRMin) continue;
4547 if (TMath::Min(TMath::Abs(rc0-r0),TMath::Abs(rc1-r1))<kMinDCAR) continue;
4548 //
4549 //
4550 // Now find closest approach
4551 //
4552 //
4553 //
4554 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4555 if (npoints==0) continue;
4556 helixes[i0].GetClosestPhases(helixes[i1], phase);
4557 //
4558 Double_t xyz0[3];
4559 Double_t xyz1[3];
4560 Double_t hangles[3];
4561 helixes[i0].Evaluate(phase[0][0],xyz0);
4562 helixes[i1].Evaluate(phase[0][1],xyz1);
4563
4564 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
4565 Double_t deltah[2],deltabest;
4566 if (TMath::Abs(hangles[2])<kMinAngle) continue;
4567
4568 if (npoints>0){
4569 Int_t ibest=0;
4570 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
4571 if (npoints==2){
4572 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
4573 if (deltah[1]<deltah[0]) ibest=1;
4574 }
4575 deltabest = TMath::Sqrt(deltah[ibest]);
4576 helixes[i0].Evaluate(phase[ibest][0],xyz0);
4577 helixes[i1].Evaluate(phase[ibest][1],xyz1);
4578 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
4579 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
4580 //
4581 if (deltabest>kMaxDist) continue;
4582 // if (mindcar+mindcaz<40 && (TMath::Abs(hangles[2])<kMinAngle ||deltabest>3)) continue;
4583 Bool_t sign =kFALSE;
4584 if (hangles[2]>kMinAngle) sign =kTRUE;
4585 //
4586 if (sign){
4587 // circular[i0] = kTRUE;
4588 // circular[i1] = kTRUE;
4589 if (track0->OneOverPt()<track1->OneOverPt()){
4590 track0->SetCircular(track0->GetCircular()+1);
4591 track1->SetCircular(track1->GetCircular()+2);
4592 }
4593 else{
4594 track1->SetCircular(track1->GetCircular()+1);
4595 track0->SetCircular(track0->GetCircular()+2);
4596 }
4597 }
4598 if (AliTPCReconstructor::StreamLevel()>1){
4599 //
4600 //debug stream to tune "fine" cuts
4601 Int_t lab0=track0->GetLabel();
4602 Int_t lab1=track1->GetLabel();
4603 TTreeSRedirector &cstream = *fDebugStreamer;
4604 cstream<<"Curling2"<<
4605 "iter="<<iter<<
4606 "lab0="<<lab0<<
4607 "lab1="<<lab1<<
4608 "Tr0.="<<track0<<
4609 "Tr1.="<<track1<<
4610 //
4611 "r0="<<r0<<
4612 "rc0="<<rc0<<
4613 "fi0="<<fi0<<
4614 "r1="<<r1<<
4615 "rc1="<<rc1<<
4616 "fi1="<<fi1<<
4617 "dfi="<<dfi<<
4618 "dtheta="<<dtheta<<
4619 //
4620 "npoints="<<npoints<<
4621 "hangles0="<<hangles[0]<<
4622 "hangles1="<<hangles[1]<<
4623 "hangles2="<<hangles[2]<<
4624 "xyz0="<<xyz0[2]<<
4625 "xyzz1="<<xyz1[2]<<
4626 "radius="<<radiusbest<<
4627 "deltabest="<<deltabest<<
4628 "phase0="<<phase[ibest][0]<<
4629 "phase1="<<phase[ibest][1]<<
4630 "\n";
4631
4632 }
4633 }
4634 }
4635 }
4636 delete [] helixes;
4637 if (AliTPCReconstructor::StreamLevel()>1) {
4638 AliInfo("Time for curling tracks removal");
4639 timer.Print();
4640 }
4641}
4642
4643
4644
4645
4646
4647void AliTPCtrackerMI::FindKinks(TObjArray * array, AliESDEvent *esd)
4648{
4649 //
4650 // find kinks
4651 //
4652 //
4653
4654 TObjArray *kinks= new TObjArray(10000);
4655 // TObjArray *v0s= new TObjArray(10000);
4656 Int_t nentries = array->GetEntriesFast();
4657 AliHelix *helixes = new AliHelix[nentries];
4658 Int_t *sign = new Int_t[nentries];
4659 Int_t *nclusters = new Int_t[nentries];
4660 Float_t *alpha = new Float_t[nentries];
4661 AliKink *kink = new AliKink();
4662 Int_t * usage = new Int_t[nentries];
4663 Float_t *zm = new Float_t[nentries];
4664 Float_t *z0 = new Float_t[nentries];
4665 Float_t *fim = new Float_t[nentries];
4666 Float_t *shared = new Float_t[nentries];
4667 Bool_t *circular = new Bool_t[nentries];
4668 Float_t *dca = new Float_t[nentries];
4669 //const AliESDVertex * primvertex = esd->GetVertex();
4670 //
4671 // nentries = array->GetEntriesFast();
4672 //
4673
4674 //
4675 //
4676 for (Int_t i=0;i<nentries;i++){
4677 sign[i]=0;
4678 usage[i]=0;
4679 AliTPCseed* track = (AliTPCseed*)array->At(i);
4680 if (!track) continue;
4681 track->SetCircular(0);
4682 shared[i] = kFALSE;
4683 track->UpdatePoints();
4684 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
4685 }
4686 nclusters[i]=track->GetNumberOfClusters();
4687 alpha[i] = track->GetAlpha();
4688 new (&helixes[i]) AliHelix(*track);
4689 Double_t xyz[3];
4690 helixes[i].Evaluate(0,xyz);
4691 sign[i] = (track->GetC()>0) ? -1:1;
4692 Double_t x,y,z;
4693 x=160;
4694 if (track->GetProlongation(x,y,z)){
4695 zm[i] = z;
4696 fim[i] = alpha[i]+TMath::ATan2(y,x);
4697 }
4698 else{
4699 zm[i] = track->GetZ();
4700 fim[i] = alpha[i];
4701 }
4702 z0[i]=1000;
4703 circular[i]= kFALSE;
4704 if (track->GetProlongation(0,y,z)) z0[i] = z;
4705 dca[i] = track->GetD(0,0);
4706 }
4707 //
4708 //
4709 TStopwatch timer;
4710 timer.Start();
4711 Int_t ncandidates =0;
4712 Int_t nall =0;
4713 Int_t ntracks=0;
4714 Double_t phase[2][2],radius[2];
4715
4716 //
4717 // Find circling track
4718 //
4719 for (Int_t i0=0;i0<nentries;i0++){
4720 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4721 if (!track0) continue;
4722 if (track0->GetNumberOfClusters()<40) continue;
4723 if (TMath::Abs(1./track0->GetC())>200) continue;
4724 for (Int_t i1=i0+1;i1<nentries;i1++){
4725 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4726 if (!track1) continue;
4727 if (track1->GetNumberOfClusters()<40) continue;
4728 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
4729 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
4730 if (TMath::Abs(1./track1->GetC())>200) continue;
4731 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
4732 if (track1->GetTgl()*track0->GetTgl()>0) continue;
4733 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
4734 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
4735 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
4736 //
4737 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
4738 if (mindcar<5) continue;
4739 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
4740 if (mindcaz<5) continue;
4741 if (mindcar+mindcaz<20) continue;
4742 //
4743 //
4744 Float_t xc0 = helixes[i0].GetHelix(6);
4745 Float_t yc0 = helixes[i0].GetHelix(7);
4746 Float_t r0 = helixes[i0].GetHelix(8);
4747 Float_t xc1 = helixes[i1].GetHelix(6);
4748 Float_t yc1 = helixes[i1].GetHelix(7);
4749 Float_t r1 = helixes[i1].GetHelix(8);
4750
4751 Float_t rmean = (r0+r1)*0.5;
4752 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
4753 //if (delta>30) continue;
4754 if (delta>rmean*0.25) continue;
4755 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
4756 //
4757 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4758 if (npoints==0) continue;
4759 helixes[i0].GetClosestPhases(helixes[i1], phase);
4760 //
4761 Double_t xyz0[3];
4762 Double_t xyz1[3];
4763 Double_t hangles[3];
4764 helixes[i0].Evaluate(phase[0][0],xyz0);
4765 helixes[i1].Evaluate(phase[0][1],xyz1);
4766
4767 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
4768 Double_t deltah[2],deltabest;
4769 if (hangles[2]<2.8) continue;
4770 if (npoints>0){
4771 Int_t ibest=0;
4772 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
4773 if (npoints==2){
4774 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
4775 if (deltah[1]<deltah[0]) ibest=1;
4776 }
4777 deltabest = TMath::Sqrt(deltah[ibest]);
4778 helixes[i0].Evaluate(phase[ibest][0],xyz0);
4779 helixes[i1].Evaluate(phase[ibest][1],xyz1);
4780 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
4781 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
4782 //
4783 if (deltabest>6) continue;
4784 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
4785 Bool_t lsign =kFALSE;
4786 if (hangles[2]>3.06) lsign =kTRUE;
4787 //
4788 if (lsign){
4789 circular[i0] = kTRUE;
4790 circular[i1] = kTRUE;
4791 if (track0->OneOverPt()<track1->OneOverPt()){
4792 track0->SetCircular(track0->GetCircular()+1);
4793 track1->SetCircular(track1->GetCircular()+2);
4794 }
4795 else{
4796 track1->SetCircular(track1->GetCircular()+1);
4797 track0->SetCircular(track0->GetCircular()+2);
4798 }
4799 }
4800 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
4801 //debug stream
4802 Int_t lab0=track0->GetLabel();
4803 Int_t lab1=track1->GetLabel();
4804 TTreeSRedirector &cstream = *fDebugStreamer;
4805 cstream<<"Curling"<<
4806 "lab0="<<lab0<<
4807 "lab1="<<lab1<<
4808 "Tr0.="<<track0<<
4809 "Tr1.="<<track1<<
4810 "dca0="<<dca[i0]<<
4811 "dca1="<<dca[i1]<<
4812 "mindcar="<<mindcar<<
4813 "mindcaz="<<mindcaz<<
4814 "delta="<<delta<<
4815 "rmean="<<rmean<<
4816 "npoints="<<npoints<<
4817 "hangles0="<<hangles[0]<<
4818 "hangles2="<<hangles[2]<<
4819 "xyz0="<<xyz0[2]<<
4820 "xyzz1="<<xyz1[2]<<
4821 "z0="<<z0[i0]<<
4822 "z1="<<z0[i1]<<
4823 "radius="<<radiusbest<<
4824 "deltabest="<<deltabest<<
4825 "phase0="<<phase[ibest][0]<<
4826 "phase1="<<phase[ibest][1]<<
4827 "\n";
4828 }
4829 }
4830 }
4831 }
4832 //
4833 // Finf kinks loop
4834 //
4835 //
4836 for (Int_t i =0;i<nentries;i++){
4837 if (sign[i]==0) continue;
4838 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
4839 if (track0==0) {
4840 AliInfo("seed==0");
4841 continue;
4842 }
4843 ntracks++;
4844 //
4845 Double_t cradius0 = 40*40;
4846 Double_t cradius1 = 270*270;
4847 Double_t cdist1=8.;
4848 Double_t cdist2=8.;
4849 Double_t cdist3=0.55;
4850 for (Int_t j =i+1;j<nentries;j++){
4851 nall++;
4852 if (sign[j]*sign[i]<1) continue;
4853 if ( (nclusters[i]+nclusters[j])>200) continue;
4854 if ( (nclusters[i]+nclusters[j])<80) continue;
4855 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
4856 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
4857 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
4858 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
4859 if (npoints<1) continue;
4860 // cuts on radius
4861 if (npoints==1){
4862 if (radius[0]<cradius0||radius[0]>cradius1) continue;
4863 }
4864 else{
4865 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
4866 }
4867 //
4868 Double_t delta1=10000,delta2=10000;
4869 // cuts on the intersection radius
4870 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
4871 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
4872 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
4873 if (npoints==2){
4874 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
4875 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
4876 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
4877 }
4878 //
4879 Double_t distance1 = TMath::Min(delta1,delta2);
4880 if (distance1>cdist1) continue; // cut on DCA linear approximation
4881 //
4882 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
4883 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
4884 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
4885 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
4886 //
4887 if (npoints==2){
4888 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
4889 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
4890 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
4891 }
4892 distance1 = TMath::Min(delta1,delta2);
4893 Float_t rkink =0;
4894 if (delta1<delta2){
4895 rkink = TMath::Sqrt(radius[0]);
4896 }
4897 else{
4898 rkink = TMath::Sqrt(radius[1]);
4899 }
4900 if (distance1>cdist2) continue;
4901 //
4902 //
4903 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
4904 //
4905 //
4906 Int_t row0 = GetRowNumber(rkink);
4907 if (row0<10) continue;
4908 if (row0>150) continue;
4909 //
4910 //
4911 Float_t dens00=-1,dens01=-1;
4912 Float_t dens10=-1,dens11=-1;
4913 //
4914 Int_t found,foundable,ishared;
4915 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
4916 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
4917 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
4918 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
4919 //
4920 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
4921 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
4922 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
4923 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
4924 //
4925 if (dens00<dens10 && dens01<dens11) continue;
4926 if (dens00>dens10 && dens01>dens11) continue;
4927 if (TMath::Max(dens00,dens10)<0.1) continue;
4928 if (TMath::Max(dens01,dens11)<0.3) continue;
4929 //
4930 if (TMath::Min(dens00,dens10)>0.6) continue;
4931 if (TMath::Min(dens01,dens11)>0.6) continue;
4932
4933 //
4934 AliTPCseed * ktrack0, *ktrack1;
4935 if (dens00>dens10){
4936 ktrack0 = track0;
4937 ktrack1 = track1;
4938 }
4939 else{
4940 ktrack0 = track1;
4941 ktrack1 = track0;
4942 }
4943 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
4944 AliExternalTrackParam paramm(*ktrack0);
4945 AliExternalTrackParam paramd(*ktrack1);
4946 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference());
4947 //
4948 //
4949 kink->SetMother(paramm);
4950 kink->SetDaughter(paramd);
4951 kink->Update();
4952
4953 Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
4954 Int_t index[4];
4955 fParam->Transform0to1(x,index);
4956 fParam->Transform1to2(x,index);
4957 row0 = GetRowNumber(x[0]);
4958
4959 if (kink->GetR()<100) continue;
4960 if (kink->GetR()>240) continue;
4961 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
4962 if (kink->GetDistance()>cdist3) continue;
4963 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
4964 if (dird<0) continue;
4965
4966 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
4967 if (dirm<0) continue;
4968 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
4969 if (mpt<0.2) continue;
4970
4971 if (mpt<1){
4972 //for high momenta momentum not defined well in first iteration
4973 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
4974 if (qt>0.35) continue;
4975 }
4976
4977 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
4978 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
4979 if (dens00>dens10){
4980 kink->SetTPCDensity(dens00,0,0);
4981 kink->SetTPCDensity(dens01,0,1);
4982 kink->SetTPCDensity(dens10,1,0);
4983 kink->SetTPCDensity(dens11,1,1);
4984 kink->SetIndex(i,0);
4985 kink->SetIndex(j,1);
4986 }
4987 else{
4988 kink->SetTPCDensity(dens10,0,0);
4989 kink->SetTPCDensity(dens11,0,1);
4990 kink->SetTPCDensity(dens00,1,0);
4991 kink->SetTPCDensity(dens01,1,1);
4992 kink->SetIndex(j,0);
4993 kink->SetIndex(i,1);
4994 }
4995
4996 if (mpt<1||kink->GetAngle(2)>0.1){
4997 // angle and densities not defined yet
4998 if (kink->GetTPCDensityFactor()<0.8) continue;
4999 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
5000 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
5001 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5002 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5003
5004 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5005 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
5006 criticalangle= 3*TMath::Sqrt(criticalangle);
5007 if (criticalangle>0.02) criticalangle=0.02;
5008 if (kink->GetAngle(2)<criticalangle) continue;
5009 }
5010 //
5011 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
5012 Float_t shapesum =0;
5013 Float_t sum = 0;
5014 for ( Int_t row = row0-drow; row<row0+drow;row++){
5015 if (row<0) continue;
5016 if (row>155) continue;
5017 if (ktrack0->GetClusterPointer(row)){
5018 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5019 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5020 sum++;
5021 }
5022 if (ktrack1->GetClusterPointer(row)){
5023 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5024 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5025 sum++;
5026 }
5027 }
5028 if (sum<4){
5029 kink->SetShapeFactor(-1.);
5030 }
5031 else{
5032 kink->SetShapeFactor(shapesum/sum);
5033 }
5034 // esd->AddKink(kink);
5035 kinks->AddLast(kink);
5036 kink = new AliKink;
5037 ncandidates++;
5038 }
5039 }
5040 //
5041 // sort the kinks according quality - and refit them towards vertex
5042 //
5043 Int_t nkinks = kinks->GetEntriesFast();
5044 Float_t *quality = new Float_t[nkinks];
5045 Int_t *indexes = new Int_t[nkinks];
5046 AliTPCseed *mothers = new AliTPCseed[nkinks];
5047 AliTPCseed *daughters = new AliTPCseed[nkinks];
5048 //
5049 //
5050 for (Int_t i=0;i<nkinks;i++){
5051 quality[i] =100000;
5052 AliKink *kinkl = (AliKink*)kinks->At(i);
5053 //
5054 // refit kinks towards vertex
5055 //
5056 Int_t index0 = kinkl->GetIndex(0);
5057 Int_t index1 = kinkl->GetIndex(1);
5058 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5059 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5060 //
5061 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
5062 //
5063 // Refit Kink under if too small angle
5064 //
5065 if (kinkl->GetAngle(2)<0.05){
5066 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5067 Int_t row0 = kinkl->GetTPCRow0();
5068 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
5069 //
5070 //
5071 Int_t last = row0-drow;
5072 if (last<40) last=40;
5073 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
5074 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
5075 //
5076 //
5077 Int_t first = row0+drow;
5078 if (first>130) first=130;
5079 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
5080 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
5081 //
5082 if (seed0 && seed1){
5083 kinkl->SetStatus(1,8);
5084 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
5085 row0 = GetRowNumber(kinkl->GetR());
5086 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
5087 mothers[i] = *seed0;
5088 daughters[i] = *seed1;
5089 }
5090 else{
5091 delete kinks->RemoveAt(i);
5092 if (seed0) delete seed0;
5093 if (seed1) delete seed1;
5094 continue;
5095 }
5096 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
5097 delete kinks->RemoveAt(i);
5098 if (seed0) delete seed0;
5099 if (seed1) delete seed1;
5100 continue;
5101 }
5102 //
5103 delete seed0;
5104 delete seed1;
5105 }
5106 //
5107 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
5108 }
5109 TMath::Sort(nkinks,quality,indexes,kFALSE);
5110 //
5111 //remove double find kinks
5112 //
5113 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
5114 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
5115 if (!kink0) continue;
5116 //
5117 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
5118 if (!kink0) continue;
5119 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
5120 if (!kink1) continue;
5121 // if not close kink continue
5122 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
5123 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
5124 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
5125 //
5126 AliTPCseed &mother0 = mothers[indexes[ikink0]];
5127 AliTPCseed &daughter0 = daughters[indexes[ikink0]];
5128 AliTPCseed &mother1 = mothers[indexes[ikink1]];
5129 AliTPCseed &daughter1 = daughters[indexes[ikink1]];
5130 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
5131 //
5132 Int_t same = 0;
5133 Int_t both = 0;
5134 Int_t samem = 0;
5135 Int_t bothm = 0;
5136 Int_t samed = 0;
5137 Int_t bothd = 0;
5138 //
5139 for (Int_t i=0;i<row0;i++){
5140 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
5141 both++;
5142 bothm++;
5143 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
5144 same++;
5145 samem++;
5146 }
5147 }
5148 }
5149
5150 for (Int_t i=row0;i<158;i++){
5151 if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){
5152 both++;
5153 bothd++;
5154 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
5155 same++;
5156 samed++;
5157 }
5158 }
5159 }
5160 Float_t ratio = Float_t(same+1)/Float_t(both+1);
5161 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
5162 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
5163 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
5164 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
5165 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
5166 if (sum1>sum0){
5167 shared[kink0->GetIndex(0)]= kTRUE;
5168 shared[kink0->GetIndex(1)]= kTRUE;
5169 delete kinks->RemoveAt(indexes[ikink0]);
5170 }
5171 else{
5172 shared[kink1->GetIndex(0)]= kTRUE;
5173 shared[kink1->GetIndex(1)]= kTRUE;
5174 delete kinks->RemoveAt(indexes[ikink1]);
5175 }
5176 }
5177 }
5178 }
5179
5180
5181 for (Int_t i=0;i<nkinks;i++){
5182 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
5183 if (!kinkl) continue;
5184 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5185 Int_t index0 = kinkl->GetIndex(0);
5186 Int_t index1 = kinkl->GetIndex(1);
5187 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
5188 kinkl->SetMultiple(usage[index0],0);
5189 kinkl->SetMultiple(usage[index1],1);
5190 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
5191 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
5192 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
5193 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
5194
5195 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5196 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5197 if (!ktrack0 || !ktrack1) continue;
5198 Int_t index = esd->AddKink(kinkl);
5199 //
5200 //
5201 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
5202 if (mothers[indexes[i]].GetNumberOfClusters()>20 && daughters[indexes[i]].GetNumberOfClusters()>20 && (mothers[indexes[i]].GetNumberOfClusters()+daughters[indexes[i]].GetNumberOfClusters())>100){
5203 *ktrack0 = mothers[indexes[i]];
5204 *ktrack1 = daughters[indexes[i]];
5205 }
5206 }
5207 //
5208 ktrack0->SetKinkIndex(usage[index0],-(index+1));
5209 ktrack1->SetKinkIndex(usage[index1], (index+1));
5210 usage[index0]++;
5211 usage[index1]++;
5212 }
5213 //
5214 // Remove tracks corresponding to shared kink's
5215 //
5216 for (Int_t i=0;i<nentries;i++){
5217 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5218 if (!track0) continue;
5219 if (track0->GetKinkIndex(0)!=0) continue;
5220 if (shared[i]) delete array->RemoveAt(i);
5221 }
5222
5223 //
5224 //
5225 RemoveUsed2(array,0.5,0.4,30);
5226 UnsignClusters();
5227 for (Int_t i=0;i<nentries;i++){
5228 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5229 if (!track0) continue;
5230 track0->CookdEdx(0.02,0.6);
5231 track0->CookPID();
5232 }
5233 //
5234 for (Int_t i=0;i<nentries;i++){
5235 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5236 if (!track0) continue;
5237 if (track0->Pt()<1.4) continue;
5238 //remove double high momenta tracks - overlapped with kink candidates
5239 Int_t ishared=0;
5240 Int_t all =0;
5241 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
5242 if (track0->GetClusterPointer(icl)!=0){
5243 all++;
5244 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
5245 }
5246 }
5247 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
5248 delete array->RemoveAt(i);
5249 continue;
5250 }
5251 //
5252 if (track0->GetKinkIndex(0)!=0) continue;
5253 if (track0->GetNumberOfClusters()<80) continue;
5254
5255 AliTPCseed *pmother = new AliTPCseed();
5256 AliTPCseed *pdaughter = new AliTPCseed();
5257 AliKink *pkink = new AliKink;
5258
5259 AliTPCseed & mother = *pmother;
5260 AliTPCseed & daughter = *pdaughter;
5261 AliKink & kinkl = *pkink;
5262 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
5263 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
5264 delete pmother;
5265 delete pdaughter;
5266 delete pkink;
5267 continue; //too short tracks
5268 }
5269 if (mother.Pt()<1.4) {
5270 delete pmother;
5271 delete pdaughter;
5272 delete pkink;
5273 continue;
5274 }
5275 Int_t row0= kinkl.GetTPCRow0();
5276 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
5277 delete pmother;
5278 delete pdaughter;
5279 delete pkink;
5280 continue;
5281 }
5282 //
5283 Int_t index = esd->AddKink(&kinkl);
5284 mother.SetKinkIndex(0,-(index+1));
5285 daughter.SetKinkIndex(0,index+1);
5286 if (mother.GetNumberOfClusters()>50) {
5287 delete array->RemoveAt(i);
5288 array->AddAt(new AliTPCseed(mother),i);
5289 }
5290 else{
5291 array->AddLast(new AliTPCseed(mother));
5292 }
5293 array->AddLast(new AliTPCseed(daughter));
5294 for (Int_t icl=0;icl<row0;icl++) {
5295 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
5296 }
5297 //
5298 for (Int_t icl=row0;icl<158;icl++) {
5299 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
5300 }
5301 //
5302 }
5303 delete pmother;
5304 delete pdaughter;
5305 delete pkink;
5306 }
5307
5308 delete [] daughters;
5309 delete [] mothers;
5310 //
5311 //
5312 delete [] dca;
5313 delete []circular;
5314 delete []shared;
5315 delete []quality;
5316 delete []indexes;
5317 //
5318 delete kink;
5319 delete[]fim;
5320 delete[] zm;
5321 delete[] z0;
5322 delete [] usage;
5323 delete[] alpha;
5324 delete[] nclusters;
5325 delete[] sign;
5326 delete[] helixes;
5327 kinks->Delete();
5328 delete kinks;
5329
5330 printf("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall);
5331 timer.Print();
5332}
5333
5334void AliTPCtrackerMI::FindV0s(TObjArray * array, AliESDEvent *esd)
5335{
5336 //
5337 // find V0s
5338 //
5339 //
5340 TObjArray *tpcv0s = new TObjArray(100000);
5341 Int_t nentries = array->GetEntriesFast();
5342 AliHelix *helixes = new AliHelix[nentries];
5343 Int_t *sign = new Int_t[nentries];
5344 Float_t *alpha = new Float_t[nentries];
5345 Float_t *z0 = new Float_t[nentries];
5346 Float_t *dca = new Float_t[nentries];
5347 Float_t *sdcar = new Float_t[nentries];
5348 Float_t *cdcar = new Float_t[nentries];
5349 Float_t *pulldcar = new Float_t[nentries];
5350 Float_t *pulldcaz = new Float_t[nentries];
5351 Float_t *pulldca = new Float_t[nentries];
5352 Bool_t *isPrim = new Bool_t[nentries];
5353 const AliESDVertex * primvertex = esd->GetVertex();
5354 Double_t zvertex = primvertex->GetZv();
5355 //
5356 // nentries = array->GetEntriesFast();
5357 //
5358 for (Int_t i=0;i<nentries;i++){
5359 sign[i]=0;
5360 isPrim[i]=0;
5361 AliTPCseed* track = (AliTPCseed*)array->At(i);
5362 if (!track) continue;
5363 track->GetV0Indexes()[0] = 0; //rest v0 indexes
5364 track->GetV0Indexes()[1] = 0; //rest v0 indexes
5365 track->GetV0Indexes()[2] = 0; //rest v0 indexes
5366 //
5367 alpha[i] = track->GetAlpha();
5368 new (&helixes[i]) AliHelix(*track);
5369 Double_t xyz[3];
5370 helixes[i].Evaluate(0,xyz);
5371 sign[i] = (track->GetC()>0) ? -1:1;
5372 Double_t x,y,z;
5373 x=160;
5374 z0[i]=1000;
5375 if (track->GetProlongation(0,y,z)) z0[i] = z;
5376 dca[i] = track->GetD(0,0);
5377 //
5378 // dca error parrameterezation + pulls
5379 //
5380 sdcar[i] = TMath::Sqrt(0.150*0.150+(100*track->GetC())*(100*track->GetC()));
5381 if (TMath::Abs(track->GetTgl())>1) sdcar[i]*=2.5;
5382 cdcar[i] = TMath::Exp((TMath::Abs(track->GetC())-0.0106)*525.3);
5383 pulldcar[i] = (dca[i]-cdcar[i])/sdcar[i];
5384 pulldcaz[i] = (z0[i]-zvertex)/sdcar[i];
5385 pulldca[i] = TMath::Sqrt(pulldcar[i]*pulldcar[i]+pulldcaz[i]*pulldcaz[i]);
5386 if (track->TPCrPID(1)+track->TPCrPID(2)+track->TPCrPID(3)>0.5) {
5387 if (pulldca[i]<3.) isPrim[i]=kTRUE; //pion, muon and Kaon 3 sigma cut
5388 }
5389 if (track->TPCrPID(4)>0.5) {
5390 if (pulldca[i]<0.5) isPrim[i]=kTRUE; //proton 0.5 sigma cut
5391 }
5392 if (track->TPCrPID(0)>0.4) {
5393 isPrim[i]=kFALSE; //electron no sigma cut
5394 }
5395 }
5396 //
5397 //
5398 TStopwatch timer;
5399 timer.Start();
5400 Int_t ncandidates =0;
5401 Int_t nall =0;
5402 Int_t ntracks=0;
5403 Double_t phase[2][2],radius[2];
5404 //
5405 // Finf V0s loop
5406 //
5407 //
5408 // //
5409 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
5410 AliV0 vertex;
5411 Double_t cradius0 = 10*10;
5412 Double_t cradius1 = 200*200;
5413 Double_t cdist1=3.;
5414 Double_t cdist2=4.;
5415 Double_t cpointAngle = 0.95;
5416 //
5417 Double_t delta[2]={10000,10000};
5418 for (Int_t i =0;i<nentries;i++){
5419 if (sign[i]==0) continue;
5420 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5421 if (!track0) continue;
5422 if (AliTPCReconstructor::StreamLevel()>1){
5423 TTreeSRedirector &cstream = *fDebugStreamer;
5424 cstream<<"Tracks"<<
5425 "Tr0.="<<track0<<
5426 "dca="<<dca[i]<<
5427 "z0="<<z0[i]<<
5428 "zvertex="<<zvertex<<
5429 "sdcar0="<<sdcar[i]<<
5430 "cdcar0="<<cdcar[i]<<
5431 "pulldcar0="<<pulldcar[i]<<
5432 "pulldcaz0="<<pulldcaz[i]<<
5433 "pulldca0="<<pulldca[i]<<
5434 "isPrim="<<isPrim[i]<<
5435 "\n";
5436 }
5437 //
5438 if (track0->GetSigned1Pt()<0) continue;
5439 if (track0->GetKinkIndex(0)>0||isPrim[i]) continue; //daughter kink
5440 //
5441 if (TMath::Abs(helixes[i].GetHelix(4))<0.000000001) continue;
5442 ntracks++;
5443 // debug output
5444
5445
5446 for (Int_t j =0;j<nentries;j++){
5447 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5448 if (!track1) continue;
5449 if (track1->GetKinkIndex(0)>0 || isPrim[j]) continue; //daughter kink
5450 if (sign[j]*sign[i]>0) continue;
5451 if (TMath::Abs(helixes[j].GetHelix(4))<0.000001) continue;
5452 if (track0->GetCircular()+track1->GetCircular()>1) continue; //circling -returning track
5453 nall++;
5454 //
5455 // DCA to prim vertex cut
5456 //
5457 //
5458 delta[0]=10000;
5459 delta[1]=10000;
5460
5461 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,cdist2);
5462 if (npoints<1) continue;
5463 Int_t iclosest=0;
5464 // cuts on radius
5465 if (npoints==1){
5466 if (radius[0]<cradius0||radius[0]>cradius1) continue;
5467 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta[0]);
5468 if (delta[0]>cdist1) continue;
5469 }
5470 else{
5471 if (TMath::Max(radius[0],radius[1])<cradius0|| TMath::Min(radius[0],radius[1])>cradius1) continue;
5472 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta[0]);
5473 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta[1]);
5474 if (delta[1]<delta[0]) iclosest=1;
5475 if (delta[iclosest]>cdist1) continue;
5476 }
5477 helixes[i].ParabolicDCA(helixes[j],phase[iclosest][0],phase[iclosest][1],radius[iclosest],delta[iclosest]);
5478 if (radius[iclosest]<cradius0 || radius[iclosest]>cradius1 || delta[iclosest]>cdist1) continue;
5479 //
5480 Double_t pointAngle = helixes[i].GetPointAngle(helixes[j],phase[iclosest],fprimvertex);
5481 if (pointAngle<cpointAngle) continue;
5482 //
5483 Bool_t isGamma = kFALSE;
5484 vertex.SetParamP(*track0); //track0 - plus
5485 vertex.SetParamN(*track1); //track1 - minus
5486 vertex.Update(fprimvertex);
5487 if (track0->TPCrPID(0)>0.3&&track1->TPCrPID(0)>0.3&&vertex.GetAnglep()[2]<0.15) isGamma=kTRUE; // gamma conversion candidate
5488 Double_t pointAngle2 = vertex.GetV0CosineOfPointingAngle();
5489 //continue;
5490 if (vertex.GetV0CosineOfPointingAngle()<cpointAngle && (!isGamma)) continue;// point angle cut
5491 //Bo: if (vertex.GetDist2()>2&&(!isGamma)) continue; // point angle cut
5492 if (vertex.GetDcaV0Daughters()>2&&(!isGamma)) continue;//Bo: // point angle cut
5493 Float_t sigmae = 0.15*0.15;
5494 if (vertex.GetRr()<80)
5495 sigmae += (sdcar[i]*sdcar[i]+sdcar[j]*sdcar[j])*(1.-vertex.GetRr()/80.)*(1.-vertex.GetRr()/80.);
5496 sigmae+= TMath::Sqrt(sigmae);
5497 //Bo: if (vertex.GetDist2()/sigmae>3.&&(!isGamma)) continue;
5498 if (vertex.GetDcaV0Daughters()/sigmae>3.&&(!isGamma)) continue;
5499 Float_t densb0=0,densb1=0,densa0=0,densa1=0;
5500 Int_t row0 = GetRowNumber(vertex.GetRr());
5501 if (row0>15){
5502 //Bo: if (vertex.GetDist2()>0.2) continue;
5503 if (vertex.GetDcaV0Daughters()>0.2) continue;
5504 densb0 = track0->Density2(0,row0-5);
5505 densb1 = track1->Density2(0,row0-5);
5506 if (densb0>0.3|| densb1>0.3) continue; //clusters before vertex
5507 densa0 = track0->Density2(row0+5,row0+40);
5508 densa1 = track1->Density2(row0+5,row0+40);
5509 if ((densa0<0.4|| densa1<0.4)&&(!isGamma)) continue; //missing clusters after vertex
5510 }
5511 else{
5512 densa0 = track0->Density2(0,40); //cluster density
5513 densa1 = track1->Density2(0,40); //cluster density
5514 if ((vertex.GetRr()<80&&densa0+densa1<1.)&&(!isGamma)) continue;
5515 }
5516//Bo: vertex.SetLab(0,track0->GetLabel());
5517//Bo: vertex.SetLab(1,track1->GetLabel());
5518 vertex.SetChi2After((densa0+densa1)*0.5);
5519 vertex.SetChi2Before((densb0+densb1)*0.5);
5520 vertex.SetIndex(0,i);
5521 vertex.SetIndex(1,j);
5522//Bo: vertex.SetStatus(1); // TPC v0 candidate
5523 vertex.SetOnFlyStatus(2);//Bo: // TPC v0 candidate
5524//Bo: vertex.SetRp(track0->TPCrPIDs());
5525//Bo: vertex.SetRm(track1->TPCrPIDs());
5526 tpcv0s->AddLast(new AliESDv0(vertex));
5527 ncandidates++;
5528 {
5529 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
5530 Double_t radiusm= (delta[0]<delta[1])? TMath::Sqrt(radius[0]):TMath::Sqrt(radius[1]);
5531 Double_t deltam= (delta[0]<delta[1])? TMath::Sqrt(delta[0]):TMath::Sqrt(delta[1]);
5532 if (AliTPCReconstructor::StreamLevel()>1) {
5533 Int_t lab0=track0->GetLabel();
5534 Int_t lab1=track1->GetLabel();
5535 Char_t c0=track0->GetCircular();
5536 Char_t c1=track1->GetCircular();
5537 TTreeSRedirector &cstream = *fDebugStreamer;
5538 cstream<<"V0"<<
5539 "Event="<<eventNr<<
5540 "vertex.="<<&vertex<<
5541 "Tr0.="<<track0<<
5542 "lab0="<<lab0<<
5543 "Helix0.="<<&helixes[i]<<
5544 "Tr1.="<<track1<<
5545 "lab1="<<lab1<<
5546 "Helix1.="<<&helixes[j]<<
5547 "pointAngle="<<pointAngle<<
5548 "pointAngle2="<<pointAngle2<<
5549 "dca0="<<dca[i]<<
5550 "dca1="<<dca[j]<<
5551 "z0="<<z0[i]<<
5552 "z1="<<z0[j]<<
5553 "zvertex="<<zvertex<<
5554 "circular0="<<c0<<
5555 "circular1="<<c1<<
5556 "npoints="<<npoints<<
5557 "radius0="<<radius[0]<<
5558 "delta0="<<delta[0]<<
5559 "radius1="<<radius[1]<<
5560 "delta1="<<delta[1]<<
5561 "radiusm="<<radiusm<<
5562 "deltam="<<deltam<<
5563 "sdcar0="<<sdcar[i]<<
5564 "sdcar1="<<sdcar[j]<<
5565 "cdcar0="<<cdcar[i]<<
5566 "cdcar1="<<cdcar[j]<<
5567 "pulldcar0="<<pulldcar[i]<<
5568 "pulldcar1="<<pulldcar[j]<<
5569 "pulldcaz0="<<pulldcaz[i]<<
5570 "pulldcaz1="<<pulldcaz[j]<<
5571 "pulldca0="<<pulldca[i]<<
5572 "pulldca1="<<pulldca[j]<<
5573 "densb0="<<densb0<<
5574 "densb1="<<densb1<<
5575 "densa0="<<densa0<<
5576 "densa1="<<densa1<<
5577 "sigmae="<<sigmae<<
5578 "\n";}
5579 }
5580 }
5581 }
5582 Float_t *quality = new Float_t[ncandidates];
5583 Int_t *indexes = new Int_t[ncandidates];
5584 Int_t naccepted =0;
5585 for (Int_t i=0;i<ncandidates;i++){
5586 quality[i] = 0;
5587 AliESDv0 *v0 = (AliESDv0*)tpcv0s->At(i);
5588 quality[i] = 1./(1.00001-v0->GetV0CosineOfPointingAngle()); //base point angle
5589 // quality[i] /= (0.5+v0->GetDist2());
5590 // quality[i] *= v0->GetChi2After(); //density factor
5591
5592 Int_t index0 = v0->GetIndex(0);
5593 Int_t index1 = v0->GetIndex(1);
5594 //Bo: Double_t minpulldca = TMath::Min(2.+pulldca[v0->GetIndex(0)],(2.+pulldca[v0->GetIndex(1)]) ); //pull
5595 Double_t minpulldca = TMath::Min(2.+pulldca[index0],(2.+pulldca[index1]) );//Bo:
5596
5597
5598
5599 AliTPCseed * track0 = (AliTPCseed*)array->At(index0);
5600 AliTPCseed * track1 = (AliTPCseed*)array->At(index1);
5601 if (track0->TPCrPID(0)>0.3&&track1->TPCrPID(0)>0.3&&v0->GetAnglep()[2]<0.15) quality[i]+=1000000; // gamma conversion candidate
5602 if (track0->TPCrPID(4)>0.9||(track1->TPCrPID(4)>0.9&&minpulldca>4)) quality[i]*=10; // lambda candidate candidate
5603 }
5604
5605 TMath::Sort(ncandidates,quality,indexes,kTRUE);
5606 //
5607 //
5608 for (Int_t i=0;i<ncandidates;i++){
5609 AliESDv0 * v0 = (AliESDv0*)tpcv0s->At(indexes[i]);
5610 if (!v0) continue;
5611 Int_t index0 = v0->GetIndex(0);
5612 Int_t index1 = v0->GetIndex(1);
5613 AliTPCseed * track0 = (AliTPCseed*)array->At(index0);
5614 AliTPCseed * track1 = (AliTPCseed*)array->At(index1);
5615 if (!track0||!track1) {
5616 printf("Bug\n");
5617 continue;
5618 }
5619 Bool_t accept =kTRUE; //default accept
5620 Int_t *v0indexes0 = track0->GetV0Indexes();
5621 Int_t *v0indexes1 = track1->GetV0Indexes();
5622 //
5623 Int_t order0 = (v0indexes0[0]!=0) ? 1:0;
5624 Int_t order1 = (v0indexes1[0]!=0) ? 1:0;
5625 if (v0indexes0[1]!=0) order0 =2;
5626 if (v0indexes1[1]!=0) order1 =2;
5627 //
5628 if (v0indexes0[2]!=0) {order0=3; accept=kFALSE;}
5629 if (v0indexes0[2]!=0) {order1=3; accept=kFALSE;}
5630 //
5631 AliESDv0 * v02 = v0;
5632 if (accept){
5633 //Bo: v0->SetOrder(0,order0);
5634 //Bo: v0->SetOrder(1,order1);
5635 //Bo: v0->SetOrder(1,order0+order1);
5636 v0->SetOnFlyStatus(kTRUE);
5637 Int_t index = esd->AddV0(v0);
5638 v02 = esd->GetV0(index);
5639 v0indexes0[order0]=index;
5640 v0indexes1[order1]=index;
5641 naccepted++;
5642 }
5643 {
5644 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
5645 if (AliTPCReconstructor::StreamLevel()>1) {
5646 Int_t lab0=track0->GetLabel();
5647 Int_t lab1=track1->GetLabel();
5648 TTreeSRedirector &cstream = *fDebugStreamer;
5649 cstream<<"V02"<<
5650 "Event="<<eventNr<<
5651 "vertex.="<<v0<<
5652 "vertex2.="<<v02<<
5653 "Tr0.="<<track0<<
5654 "lab0="<<lab0<<
5655 "Tr1.="<<track1<<
5656 "lab1="<<lab1<<
5657 "dca0="<<dca[index0]<<
5658 "dca1="<<dca[index1]<<
5659 "order0="<<order0<<
5660 "order1="<<order1<<
5661 "accept="<<accept<<
5662 "quality="<<quality[i]<<
5663 "pulldca0="<<pulldca[index0]<<
5664 "pulldca1="<<pulldca[index1]<<
5665 "index="<<i<<
5666 "\n";}
5667 }
5668 }
5669
5670
5671 //
5672 //
5673 delete []quality;
5674 delete []indexes;
5675//
5676 delete [] isPrim;
5677 delete [] pulldca;
5678 delete [] pulldcaz;
5679 delete [] pulldcar;
5680 delete [] cdcar;
5681 delete [] sdcar;
5682 delete [] dca;
5683 //
5684 delete[] z0;
5685 delete[] alpha;
5686 delete[] sign;
5687 delete[] helixes;
5688 printf("TPC V0 finder : naccepted\t%d\tncandidates\t%d\tntracks\t%d\tnall\t%d\n",naccepted,ncandidates,ntracks,nall);
5689 timer.Print();
5690}
5691
5692Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, AliESDkink &knk)
5693{
5694 //
5695 // refit kink towards to the vertex
5696 //
5697 //
5698 AliKink &kink=(AliKink &)knk;
5699
5700 Int_t row0 = GetRowNumber(kink.GetR());
5701 FollowProlongation(mother,0);
5702 mother.Reset(kFALSE);
5703 //
5704 FollowProlongation(daughter,row0);
5705 daughter.Reset(kFALSE);
5706 FollowBackProlongation(daughter,158);
5707 daughter.Reset(kFALSE);
5708 Int_t first = TMath::Max(row0-20,30);
5709 Int_t last = TMath::Min(row0+20,140);
5710 //
5711 const Int_t kNdiv =5;
5712 AliTPCseed param0[kNdiv]; // parameters along the track
5713 AliTPCseed param1[kNdiv]; // parameters along the track
5714 AliKink kinks[kNdiv]; // corresponding kink parameters
5715 //
5716 Int_t rows[kNdiv];
5717 for (Int_t irow=0; irow<kNdiv;irow++){
5718 rows[irow] = first +((last-first)*irow)/(kNdiv-1);
5719 }
5720 // store parameters along the track
5721 //
5722 for (Int_t irow=0;irow<kNdiv;irow++){
5723 FollowBackProlongation(mother, rows[irow]);
5724 FollowProlongation(daughter,rows[kNdiv-1-irow]);
5725 param0[irow] = mother;
5726 param1[kNdiv-1-irow] = daughter;
5727 }
5728 //
5729 // define kinks
5730 for (Int_t irow=0; irow<kNdiv-1;irow++){
5731 if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
5732 kinks[irow].SetMother(param0[irow]);
5733 kinks[irow].SetDaughter(param1[irow]);
5734 kinks[irow].Update();
5735 }
5736 //
5737 // choose kink with best "quality"
5738 Int_t index =-1;
5739 Double_t mindist = 10000;
5740 for (Int_t irow=0;irow<kNdiv;irow++){
5741 if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
5742 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
5743 if (TMath::Abs(kinks[irow].GetR())<100.) continue;
5744 //
5745 Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
5746 normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
5747 if (normdist < mindist){
5748 mindist = normdist;
5749 index = irow;
5750 }
5751 }
5752 //
5753 if (index==-1) return 0;
5754 //
5755 //
5756 param0[index].Reset(kTRUE);
5757 FollowProlongation(param0[index],0);
5758 //
5759 mother = param0[index];
5760 daughter = param1[index]; // daughter in vertex
5761 //
5762 kink.SetMother(mother);
5763 kink.SetDaughter(daughter);
5764 kink.Update();
5765 kink.SetTPCRow0(GetRowNumber(kink.GetR()));
5766 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
5767 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
5768 kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
5769 kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
5770 mother.SetLabel(kink.GetLabel(0));
5771 daughter.SetLabel(kink.GetLabel(1));
5772
5773 return 1;
5774}
5775
5776
5777void AliTPCtrackerMI::UpdateKinkQualityM(AliTPCseed * seed){
5778 //
5779 // update Kink quality information for mother after back propagation
5780 //
5781 if (seed->GetKinkIndex(0)>=0) return;
5782 for (Int_t ikink=0;ikink<3;ikink++){
5783 Int_t index = seed->GetKinkIndex(ikink);
5784 if (index>=0) break;
5785 index = TMath::Abs(index)-1;
5786 AliESDkink * kink = fEvent->GetKink(index);
5787 kink->SetTPCDensity(-1,0,0);
5788 kink->SetTPCDensity(1,0,1);
5789 //
5790 Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5791 if (row0<15) row0=15;
5792 //
5793 Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5794 if (row1>145) row1=145;
5795 //
5796 Int_t found,foundable,shared;
5797 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
5798 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,0);
5799 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
5800 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,1);
5801 }
5802
5803}
5804
5805void AliTPCtrackerMI::UpdateKinkQualityD(AliTPCseed * seed){
5806 //
5807 // update Kink quality information for daughter after refit
5808 //
5809 if (seed->GetKinkIndex(0)<=0) return;
5810 for (Int_t ikink=0;ikink<3;ikink++){
5811 Int_t index = seed->GetKinkIndex(ikink);
5812 if (index<=0) break;
5813 index = TMath::Abs(index)-1;
5814 AliESDkink * kink = fEvent->GetKink(index);
5815 kink->SetTPCDensity(-1,1,0);
5816 kink->SetTPCDensity(-1,1,1);
5817 //
5818 Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5819 if (row0<15) row0=15;
5820 //
5821 Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5822 if (row1>145) row1=145;
5823 //
5824 Int_t found,foundable,shared;
5825 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
5826 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,0);
5827 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
5828 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,1);
5829 }
5830
5831}
5832
5833
5834Int_t AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, AliESDkink &knk)
5835{
5836 //
5837 // check kink point for given track
5838 // if return value=0 kink point not found
5839 // otherwise seed0 correspond to mother particle
5840 // seed1 correspond to daughter particle
5841 // kink parameter of kink point
5842 AliKink &kink=(AliKink &)knk;
5843
5844 Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
5845 Int_t first = seed->GetFirstPoint();
5846 Int_t last = seed->GetLastPoint();
5847 if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
5848
5849
5850 AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
5851 if (!seed1) return 0;
5852 FollowProlongation(*seed1,seed->GetLastPoint()-20);
5853 seed1->Reset(kTRUE);
5854 FollowProlongation(*seed1,158);
5855 seed1->Reset(kTRUE);
5856 last = seed1->GetLastPoint();
5857 //
5858 AliTPCseed *seed0 = new AliTPCseed(*seed);
5859 seed0->Reset(kFALSE);
5860 seed0->Reset();
5861 //
5862 AliTPCseed param0[20]; // parameters along the track
5863 AliTPCseed param1[20]; // parameters along the track
5864 AliKink kinks[20]; // corresponding kink parameters
5865 Int_t rows[20];
5866 for (Int_t irow=0; irow<20;irow++){
5867 rows[irow] = first +((last-first)*irow)/19;
5868 }
5869 // store parameters along the track
5870 //
5871 for (Int_t irow=0;irow<20;irow++){
5872 FollowBackProlongation(*seed0, rows[irow]);
5873 FollowProlongation(*seed1,rows[19-irow]);
5874 param0[irow] = *seed0;
5875 param1[19-irow] = *seed1;
5876 }
5877 //
5878 // define kinks
5879 for (Int_t irow=0; irow<19;irow++){
5880 kinks[irow].SetMother(param0[irow]);
5881 kinks[irow].SetDaughter(param1[irow]);
5882 kinks[irow].Update();
5883 }
5884 //
5885 // choose kink with biggest change of angle
5886 Int_t index =-1;
5887 Double_t maxchange= 0;
5888 for (Int_t irow=1;irow<19;irow++){
5889 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
5890 if (TMath::Abs(kinks[irow].GetR())<110.) continue;
5891 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
5892 if ( quality > maxchange){
5893 maxchange = quality;
5894 index = irow;
5895 //
5896 }
5897 }
5898 delete seed0;
5899 delete seed1;
5900 if (index<0) return 0;
5901 //
5902 Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
5903 seed0 = new AliTPCseed(param0[index]);
5904 seed1 = new AliTPCseed(param1[index]);
5905 seed0->Reset(kFALSE);
5906 seed1->Reset(kFALSE);
5907 seed0->ResetCovariance(10.);
5908 seed1->ResetCovariance(10.);
5909 FollowProlongation(*seed0,0);
5910 FollowBackProlongation(*seed1,158);
5911 mother = *seed0; // backup mother at position 0
5912 seed0->Reset(kFALSE);
5913 seed1->Reset(kFALSE);
5914 seed0->ResetCovariance(10.);
5915 seed1->ResetCovariance(10.);
5916 //
5917 first = TMath::Max(row0-20,0);
5918 last = TMath::Min(row0+20,158);
5919 //
5920 for (Int_t irow=0; irow<20;irow++){
5921 rows[irow] = first +((last-first)*irow)/19;
5922 }
5923 // store parameters along the track
5924 //
5925 for (Int_t irow=0;irow<20;irow++){
5926 FollowBackProlongation(*seed0, rows[irow]);
5927 FollowProlongation(*seed1,rows[19-irow]);
5928 param0[irow] = *seed0;
5929 param1[19-irow] = *seed1;
5930 }
5931 //
5932 // define kinks
5933 for (Int_t irow=0; irow<19;irow++){
5934 kinks[irow].SetMother(param0[irow]);
5935 kinks[irow].SetDaughter(param1[irow]);
5936 // param0[irow].Dump();
5937 //param1[irow].Dump();
5938 kinks[irow].Update();
5939 }
5940 //
5941 // choose kink with biggest change of angle
5942 index =-1;
5943 maxchange= 0;
5944 for (Int_t irow=0;irow<20;irow++){
5945 if (TMath::Abs(kinks[irow].GetR())>250.) continue;
5946 if (TMath::Abs(kinks[irow].GetR())<90.) continue;
5947 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
5948 if ( quality > maxchange){
5949 maxchange = quality;
5950 index = irow;
5951 //
5952 }
5953 }
5954 //
5955 //
5956 if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
5957 delete seed0;
5958 delete seed1;
5959 return 0;
5960 }
5961 // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
5962
5963 kink.SetMother(param0[index]);
5964 kink.SetDaughter(param1[index]);
5965 kink.Update();
5966 row0 = GetRowNumber(kink.GetR());
5967 kink.SetTPCRow0(row0);
5968 kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
5969 kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
5970 kink.SetIndex(-10,0);
5971 kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
5972 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
5973 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
5974 //
5975 //
5976 // new (&mother) AliTPCseed(param0[index]);
5977 daughter = param1[index];
5978 daughter.SetLabel(kink.GetLabel(1));
5979 param0[index].Reset(kTRUE);
5980 FollowProlongation(param0[index],0);
5981 mother = param0[index];
5982 mother.SetLabel(kink.GetLabel(0));
5983 delete seed0;
5984 delete seed1;
5985 //
5986 return 1;
5987}
5988
5989
5990
5991
5992AliTPCseed* AliTPCtrackerMI::ReSeed(AliTPCseed *t)
5993{
5994 //
5995 // reseed - refit - track
5996 //
5997 Int_t first = 0;
5998 // Int_t last = fSectors->GetNRows()-1;
5999 //
6000 if (fSectors == fOuterSec){
6001 first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
6002 //last =
6003 }
6004 else
6005 first = t->GetFirstPoint();
6006 //
6007 AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
6008 FollowBackProlongation(*t,fSectors->GetNRows()-1);
6009 t->Reset(kFALSE);
6010 FollowProlongation(*t,first);
6011 return seed;
6012}
6013
6014
6015
6016
6017
6018
6019
6020//_____________________________________________________________________________
6021Int_t AliTPCtrackerMI::ReadSeeds(const TFile *inp) {
6022 //-----------------------------------------------------------------
6023 // This function reades track seeds.
6024 //-----------------------------------------------------------------
6025 TDirectory *savedir=gDirectory;
6026
6027 TFile *in=(TFile*)inp;
6028 if (!in->IsOpen()) {
6029 cerr<<"AliTPCtrackerMI::ReadSeeds(): input file is not open !\n";
6030 return 1;
6031 }
6032
6033 in->cd();
6034 TTree *seedTree=(TTree*)in->Get("Seeds");
6035 if (!seedTree) {
6036 cerr<<"AliTPCtrackerMI::ReadSeeds(): ";
6037 cerr<<"can't get a tree with track seeds !\n";
6038 return 2;
6039 }
6040 AliTPCtrack *seed=new AliTPCtrack;
6041 seedTree->SetBranchAddress("tracks",&seed);
6042
6043 if (fSeeds==0) fSeeds=new TObjArray(15000);
6044
6045 Int_t n=(Int_t)seedTree->GetEntries();
6046 for (Int_t i=0; i<n; i++) {
6047 seedTree->GetEvent(i);
6048 fSeeds->AddLast(new AliTPCseed(*seed/*,seed->GetAlpha()*/));
6049 }
6050
6051 delete seed;
6052 delete seedTree;
6053 savedir->cd();
6054 return 0;
6055}
6056
6057Int_t AliTPCtrackerMI::Clusters2Tracks (AliESDEvent *esd)
6058{
6059 //
6060 if (fSeeds) DeleteSeeds();
6061 fEvent = esd;
6062 Clusters2Tracks();
6063 if (!fSeeds) return 1;
6064 FillESD(fSeeds);
6065 return 0;
6066 //
6067}
6068
6069
6070//_____________________________________________________________________________
6071Int_t AliTPCtrackerMI::Clusters2Tracks() {
6072 //-----------------------------------------------------------------
6073 // This is a track finder.
6074 //-----------------------------------------------------------------
6075 TDirectory *savedir=gDirectory;
6076 TStopwatch timer;
6077
6078 fIteration = 0;
6079 fSeeds = Tracking();
6080
6081 if (fDebug>0){
6082 Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
6083 }
6084 //activate again some tracks
6085 for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
6086 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6087 if (!pt) continue;
6088 Int_t nc=t.GetNumberOfClusters();
6089 if (nc<20) {
6090 delete fSeeds->RemoveAt(i);
6091 continue;
6092 }
6093 CookLabel(pt,0.1);
6094 if (pt->GetRemoval()==10) {
6095 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
6096 pt->Desactivate(10); // make track again active
6097 else{
6098 pt->Desactivate(20);
6099 delete fSeeds->RemoveAt(i);
6100 }
6101 }
6102 }
6103 //
6104 RemoveUsed2(fSeeds,0.85,0.85,0);
6105 if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
6106 //FindCurling(fSeeds, fEvent,0);
6107 if (AliTPCReconstructor::StreamLevel()>2) FindMultiMC(fSeeds, fEvent,-1); // find multi found tracks
6108 RemoveUsed2(fSeeds,0.5,0.4,20);
6109 FindSplitted(fSeeds, fEvent,0); // find multi found tracks
6110 if (AliTPCReconstructor::StreamLevel()>2) FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
6111
6112 // //
6113// // refit short tracks
6114// //
6115 Int_t nseed=fSeeds->GetEntriesFast();
6116 //
6117 Int_t found = 0;
6118 for (Int_t i=0; i<nseed; i++) {
6119 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6120 if (!pt) continue;
6121 Int_t nc=t.GetNumberOfClusters();
6122 if (nc<15) {
6123 delete fSeeds->RemoveAt(i);
6124 continue;
6125 }
6126 CookLabel(pt,0.1); //For comparison only
6127 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6128 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6129 found++;
6130 if (fDebug>0) cerr<<found<<'\r';
6131 pt->SetLab2(i);
6132 }
6133 else
6134 delete fSeeds->RemoveAt(i);
6135 }
6136
6137
6138 //RemoveOverlap(fSeeds,0.99,7,kTRUE);
6139 SignShared(fSeeds);
6140 //RemoveUsed(fSeeds,0.9,0.9,6);
6141 //
6142 nseed=fSeeds->GetEntriesFast();
6143 found = 0;
6144 for (Int_t i=0; i<nseed; i++) {
6145 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6146 if (!pt) continue;
6147 Int_t nc=t.GetNumberOfClusters();
6148 if (nc<15) {
6149 delete fSeeds->RemoveAt(i);
6150 continue;
6151 }
6152 t.SetUniqueID(i);
6153 t.CookdEdx(0.02,0.6);
6154 // CheckKinkPoint(&t,0.05);
6155 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6156 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6157 found++;
6158 if (fDebug>0){
6159 cerr<<found<<'\r';
6160 }
6161 pt->SetLab2(i);
6162 }
6163 else
6164 delete fSeeds->RemoveAt(i);
6165 //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
6166 //if (seed1){
6167 // FollowProlongation(*seed1,0);
6168 // Int_t n = seed1->GetNumberOfClusters();
6169 // printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
6170 // printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
6171 //
6172 //}
6173 //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
6174
6175 }
6176
6177 SortTracks(fSeeds, 1);
6178
6179 /*
6180 fIteration = 1;
6181 PrepareForBackProlongation(fSeeds,5.);
6182 PropagateBack(fSeeds);
6183 printf("Time for back propagation: \t");timer.Print();timer.Start();
6184
6185 fIteration = 2;
6186
6187 PrepareForProlongation(fSeeds,5.);
6188 PropagateForward2(fSeeds);
6189
6190 printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
6191 // RemoveUsed(fSeeds,0.7,0.7,6);
6192 //RemoveOverlap(fSeeds,0.9,7,kTRUE);
6193
6194 nseed=fSeeds->GetEntriesFast();
6195 found = 0;
6196 for (Int_t i=0; i<nseed; i++) {
6197 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6198 if (!pt) continue;
6199 Int_t nc=t.GetNumberOfClusters();
6200 if (nc<15) {
6201 delete fSeeds->RemoveAt(i);
6202 continue;
6203 }
6204 t.CookdEdx(0.02,0.6);
6205 // CookLabel(pt,0.1); //For comparison only
6206 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6207 if ((pt->IsActive() || (pt->fRemoval==10) )){
6208 cerr<<found++<<'\r';
6209 }
6210 else
6211 delete fSeeds->RemoveAt(i);
6212 pt->fLab2 = i;
6213 }
6214 */
6215
6216 // fNTracks = found;
6217 if (fDebug>0){
6218 Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
6219 }
6220 //
6221 // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
6222 Info("Clusters2Tracks","Number of found tracks %d",found);
6223 savedir->cd();
6224 // UnloadClusters();
6225 //
6226 return 0;
6227}
6228
6229void AliTPCtrackerMI::Tracking(TObjArray * arr)
6230{
6231 //
6232 // tracking of the seeds
6233 //
6234
6235 fSectors = fOuterSec;
6236 ParallelTracking(arr,150,63);
6237 fSectors = fOuterSec;
6238 ParallelTracking(arr,63,0);
6239}
6240
6241TObjArray * AliTPCtrackerMI::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
6242{
6243 //
6244 //
6245 //tracking routine
6246 TObjArray * arr = new TObjArray;
6247 //
6248 fSectors = fOuterSec;
6249 TStopwatch timer;
6250 timer.Start();
6251 for (Int_t sec=0;sec<fkNOS;sec++){
6252 if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
6253 if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);
6254 if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
6255 }
6256 if (fDebug>0){
6257 Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
6258 timer.Print();
6259 timer.Start();
6260 }
6261 Tracking(arr);
6262 if (fDebug>0){
6263 timer.Print();
6264 }
6265
6266 return arr;
6267}
6268
6269TObjArray * AliTPCtrackerMI::Tracking()
6270{
6271 //
6272 //
6273 if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
6274 TStopwatch timer;
6275 timer.Start();
6276 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
6277
6278 TObjArray * seeds = new TObjArray;
6279 TObjArray * arr=0;
6280
6281 Int_t gap =20;
6282 Float_t cuts[4];
6283 cuts[0] = 0.002;
6284 cuts[1] = 1.5;
6285 cuts[2] = 3.;
6286 cuts[3] = 3.;
6287 Float_t fnumber = 3.0;
6288 Float_t fdensity = 3.0;
6289
6290 //
6291 //find primaries
6292 cuts[0]=0.0066;
6293 for (Int_t delta = 0; delta<18; delta+=6){
6294 //
6295 cuts[0]=0.0070;
6296 cuts[1] = 1.5;
6297 arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
6298 SumTracks(seeds,arr);
6299 SignClusters(seeds,fnumber,fdensity);
6300 //
6301 for (Int_t i=2;i<6;i+=2){
6302 // seed high pt tracks
6303 cuts[0]=0.0022;
6304 cuts[1]=0.3;
6305 arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
6306 SumTracks(seeds,arr);
6307 SignClusters(seeds,fnumber,fdensity);
6308 }
6309 }
6310 fnumber = 4;
6311 fdensity = 4.;
6312 // RemoveUsed(seeds,0.9,0.9,1);
6313 // UnsignClusters();
6314 // SignClusters(seeds,fnumber,fdensity);
6315
6316 //find primaries
6317 cuts[0]=0.0077;
6318 for (Int_t delta = 20; delta<120; delta+=10){
6319 //
6320 // seed high pt tracks
6321 cuts[0]=0.0060;
6322 cuts[1]=0.3;
6323 cuts[2]=6.;
6324 arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
6325 SumTracks(seeds,arr);
6326 SignClusters(seeds,fnumber,fdensity);
6327
6328 cuts[0]=0.003;
6329 cuts[1]=0.3;
6330 cuts[2]=6.;
6331 arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
6332 SumTracks(seeds,arr);
6333 SignClusters(seeds,fnumber,fdensity);
6334 }
6335
6336 cuts[0] = 0.01;
6337 cuts[1] = 2.0;
6338 cuts[2] = 3.;
6339 cuts[3] = 2.0;
6340 fnumber = 2.;
6341 fdensity = 2.;
6342
6343 if (fDebug>0){
6344 Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
6345 timer.Print();
6346 timer.Start();
6347 }
6348 // RemoveUsed(seeds,0.75,0.75,1);
6349 //UnsignClusters();
6350 //SignClusters(seeds,fnumber,fdensity);
6351
6352 // find secondaries
6353
6354 cuts[0] = 0.3;
6355 cuts[1] = 1.5;
6356 cuts[2] = 3.;
6357 cuts[3] = 1.5;
6358
6359 arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
6360 SumTracks(seeds,arr);
6361 SignClusters(seeds,fnumber,fdensity);
6362 //
6363 arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
6364 SumTracks(seeds,arr);
6365 SignClusters(seeds,fnumber,fdensity);
6366 //
6367 arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
6368 SumTracks(seeds,arr);
6369 SignClusters(seeds,fnumber,fdensity);
6370 //
6371
6372
6373 for (Int_t delta = 3; delta<30; delta+=5){
6374 //
6375 cuts[0] = 0.3;
6376 cuts[1] = 1.5;
6377 cuts[2] = 3.;
6378 cuts[3] = 1.5;
6379 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
6380 SumTracks(seeds,arr);
6381 SignClusters(seeds,fnumber,fdensity);
6382 //
6383 arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
6384 SumTracks(seeds,arr);
6385 SignClusters(seeds,fnumber,fdensity);
6386 //
6387 }
6388 fnumber = 1;
6389 fdensity = 1;
6390 //
6391 // change cuts
6392 fnumber = 2.;
6393 fdensity = 2.;
6394 cuts[0]=0.0080;
6395
6396 Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
6397
6398 // find secondaries
6399 for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=10){
6400 //
6401 cuts[0] = 0.3;
6402 cuts[1] = 3.5;
6403 cuts[2] = 3.;
6404 cuts[3] = 3.5;
6405 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
6406 SumTracks(seeds,arr);
6407 SignClusters(seeds,fnumber,fdensity);
6408 //
6409 arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
6410 SumTracks(seeds,arr);
6411 SignClusters(seeds,fnumber,fdensity);
6412 }
6413
6414 if (fDebug>0){
6415 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
6416 timer.Print();
6417 timer.Start();
6418 }
6419
6420 return seeds;
6421 //
6422
6423}
6424
6425
6426TObjArray * AliTPCtrackerMI::TrackingSpecial()
6427{
6428 //
6429 // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
6430 // no primary vertex seeding tried
6431 //
6432 TStopwatch timer;
6433 timer.Start();
6434 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
6435
6436 TObjArray * seeds = new TObjArray;
6437 TObjArray * arr=0;
6438
6439 Int_t gap = 15;
6440 Float_t cuts[4];
6441 Float_t fnumber = 3.0;
6442 Float_t fdensity = 3.0;
6443
6444 // find secondaries
6445 cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC(); // max curvature
6446 cuts[1] = 3.5; // max tan(phi) angle for seeding
6447 cuts[2] = 3.; // not used (cut on z primary vertex)
6448 cuts[3] = 3.5; // max tan(theta) angle for seeding
6449
6450 for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
6451 //
6452 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
6453 SumTracks(seeds,arr);
6454 SignClusters(seeds,fnumber,fdensity);
6455 }
6456
6457 if (fDebug>0){
6458 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
6459 timer.Print();
6460 timer.Start();
6461 }
6462
6463 return seeds;
6464 //
6465
6466}
6467
6468
6469void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *&arr2) const
6470{
6471 //
6472 //sum tracks to common container
6473 //remove suspicious tracks
6474 Int_t nseed = arr2->GetEntriesFast();
6475 for (Int_t i=0;i<nseed;i++){
6476 AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);
6477 if (pt){
6478 //
6479 // remove tracks with too big curvature
6480 //
6481 if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
6482 delete arr2->RemoveAt(i);
6483 continue;
6484 }
6485 // REMOVE VERY SHORT TRACKS
6486 if (pt->GetNumberOfClusters()<20){
6487 delete arr2->RemoveAt(i);
6488 continue;
6489 }// patch 28 fev06
6490 // NORMAL ACTIVE TRACK
6491 if (pt->IsActive()){
6492 arr1->AddLast(arr2->RemoveAt(i));
6493 continue;
6494 }
6495 //remove not usable tracks
6496 if (pt->GetRemoval()!=10){
6497 delete arr2->RemoveAt(i);
6498 continue;
6499 }
6500
6501 // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
6502 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
6503 arr1->AddLast(arr2->RemoveAt(i));
6504 else{
6505 delete arr2->RemoveAt(i);
6506 }
6507 }
6508 }
6509 delete arr2; arr2 = 0;
6510}
6511
6512
6513
6514void AliTPCtrackerMI::ParallelTracking(TObjArray * arr, Int_t rfirst, Int_t rlast)
6515{
6516 //
6517 // try to track in parralel
6518
6519 Int_t nseed=arr->GetEntriesFast();
6520 //prepare seeds for tracking
6521 for (Int_t i=0; i<nseed; i++) {
6522 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
6523 if (!pt) continue;
6524 if (!t.IsActive()) continue;
6525 // follow prolongation to the first layer
6526 if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fParam->GetNRowLow()>rfirst+1) )
6527 FollowProlongation(t, rfirst+1);
6528 }
6529
6530
6531 //
6532 for (Int_t nr=rfirst; nr>=rlast; nr--){
6533 if (nr<fInnerSec->GetNRows())
6534 fSectors = fInnerSec;
6535 else
6536 fSectors = fOuterSec;
6537 // make indexes with the cluster tracks for given
6538
6539 // find nearest cluster
6540 for (Int_t i=0; i<nseed; i++) {
6541 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
6542 if (!pt) continue;
6543 if (nr==80) pt->UpdateReference();
6544 if (!pt->IsActive()) continue;
6545 // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
6546 if (pt->GetRelativeSector()>17) {
6547 continue;
6548 }
6549 UpdateClusters(t,nr);
6550 }
6551 // prolonagate to the nearest cluster - if founded
6552 for (Int_t i=0; i<nseed; i++) {
6553 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
6554 if (!pt) continue;
6555 if (!pt->IsActive()) continue;
6556 // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
6557 if (pt->GetRelativeSector()>17) {
6558 continue;
6559 }
6560 FollowToNextCluster(*pt,nr);
6561 }
6562 }
6563}
6564
6565void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray * arr,Float_t fac) const
6566{
6567 //
6568 //
6569 // if we use TPC track itself we have to "update" covariance
6570 //
6571 Int_t nseed= arr->GetEntriesFast();
6572 for (Int_t i=0;i<nseed;i++){
6573 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6574 if (pt) {
6575 pt->Modify(fac);
6576 //
6577 //rotate to current local system at first accepted point
6578 Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
6579 Int_t sec = (index&0xff000000)>>24;
6580 sec = sec%18;
6581 Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
6582 if (angle1>TMath::Pi())
6583 angle1-=2.*TMath::Pi();
6584 Float_t angle2 = pt->GetAlpha();
6585
6586 if (TMath::Abs(angle1-angle2)>0.001){
6587 pt->Rotate(angle1-angle2);
6588 //angle2 = pt->GetAlpha();
6589 //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
6590 //if (pt->GetAlpha()<0)
6591 // pt->fRelativeSector+=18;
6592 //sec = pt->fRelativeSector;
6593 }
6594
6595 }
6596
6597 }
6598
6599
6600}
6601void AliTPCtrackerMI::PrepareForProlongation(TObjArray * arr, Float_t fac) const
6602{
6603 //
6604 //
6605 // if we use TPC track itself we have to "update" covariance
6606 //
6607 Int_t nseed= arr->GetEntriesFast();
6608 for (Int_t i=0;i<nseed;i++){
6609 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6610 if (pt) {
6611 pt->Modify(fac);
6612 pt->SetFirstPoint(pt->GetLastPoint());
6613 }
6614
6615 }
6616
6617
6618}
6619
6620Int_t AliTPCtrackerMI::PropagateBack(TObjArray * arr)
6621{
6622 //
6623 // make back propagation
6624 //
6625 Int_t nseed= arr->GetEntriesFast();
6626 for (Int_t i=0;i<nseed;i++){
6627 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6628 if (pt&& pt->GetKinkIndex(0)<=0) {
6629 //AliTPCseed *pt2 = new AliTPCseed(*pt);
6630 fSectors = fInnerSec;
6631 //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
6632 //fSectors = fOuterSec;
6633 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
6634 //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
6635 // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
6636 // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
6637 //}
6638 }
6639 if (pt&& pt->GetKinkIndex(0)>0) {
6640 AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
6641 pt->SetFirstPoint(kink->GetTPCRow0());
6642 fSectors = fInnerSec;
6643 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
6644 }
6645 CookLabel(pt,0.3);
6646 }
6647 return 0;
6648}
6649
6650
6651Int_t AliTPCtrackerMI::PropagateForward2(TObjArray * arr)
6652{
6653 //
6654 // make forward propagation
6655 //
6656 Int_t nseed= arr->GetEntriesFast();
6657 //
6658 for (Int_t i=0;i<nseed;i++){
6659 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6660 if (pt) {
6661 FollowProlongation(*pt,0);
6662 CookLabel(pt,0.3);
6663 }
6664
6665 }
6666 return 0;
6667}
6668
6669
6670Int_t AliTPCtrackerMI::PropagateForward()
6671{
6672 //
6673 // propagate track forward
6674 //UnsignClusters();
6675 Int_t nseed = fSeeds->GetEntriesFast();
6676 for (Int_t i=0;i<nseed;i++){
6677 AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
6678 if (pt){
6679 AliTPCseed &t = *pt;
6680 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
6681 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
6682 if (alpha < 0. ) alpha += 2.*TMath::Pi();
6683 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
6684 }
6685 }
6686
6687 fSectors = fOuterSec;
6688 ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
6689 fSectors = fInnerSec;
6690 ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
6691 return 1;
6692}
6693
6694
6695
6696
6697
6698
6699Int_t AliTPCtrackerMI::PropagateBack(AliTPCseed * pt, Int_t row0, Int_t row1)
6700{
6701 //
6702 // make back propagation, in between row0 and row1
6703 //
6704
6705 if (pt) {
6706 fSectors = fInnerSec;
6707 Int_t r1;
6708 //
6709 if (row1<fSectors->GetNRows())
6710 r1 = row1;
6711 else
6712 r1 = fSectors->GetNRows()-1;
6713
6714 if (row0<fSectors->GetNRows()&& r1>0 )
6715 FollowBackProlongation(*pt,r1);
6716 if (row1<=fSectors->GetNRows())
6717 return 0;
6718 //
6719 r1 = row1 - fSectors->GetNRows();
6720 if (r1<=0) return 0;
6721 if (r1>=fOuterSec->GetNRows()) return 0;
6722 fSectors = fOuterSec;
6723 return FollowBackProlongation(*pt,r1);
6724 }
6725 return 0;
6726}
6727
6728
6729
6730
6731void AliTPCtrackerMI::GetShape(AliTPCseed * seed, Int_t row)
6732{
6733 //
6734 //
6735 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
6736 Float_t zdrift = TMath::Abs((fParam->GetZLength(0)-TMath::Abs(seed->GetZ())));
6737 Int_t type = (seed->GetSector() < fParam->GetNSector()/2) ? 0: (row>126) ? 1:2;
6738 Double_t angulary = seed->GetSnp();
6739 angulary = angulary*angulary/(1.-angulary*angulary);
6740 Double_t angularz = seed->GetTgl()*seed->GetTgl()*(1.+angulary);
6741
6742 Double_t sigmay = clparam->GetRMS0(0,type,zdrift,TMath::Sqrt(TMath::Abs(angulary)));
6743 Double_t sigmaz = clparam->GetRMS0(1,type,zdrift,TMath::Sqrt(TMath::Abs(angularz)));
6744 seed->SetCurrentSigmaY2(sigmay*sigmay);
6745 seed->SetCurrentSigmaZ2(sigmaz*sigmaz);
6746 // Float_t sd2 = TMath::Abs((fParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
6747// // Float_t padlength = fParam->GetPadPitchLength(seed->fSector);
6748// Float_t padlength = GetPadPitchLength(row);
6749// //
6750// Float_t sresy = (seed->GetSector() < fParam->GetNSector()/2) ? 0.2 :0.3;
6751// seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
6752// //
6753// Float_t sresz = fParam->GetZSigma();
6754// seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
6755 /*
6756 Float_t wy = GetSigmaY(seed);
6757 Float_t wz = GetSigmaZ(seed);
6758 wy*=wy;
6759 wz*=wz;
6760 if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
6761 printf("problem\n");
6762 }
6763 */
6764}
6765
6766
6767
6768//__________________________________________________________________________
6769void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
6770 //--------------------------------------------------------------------
6771 //This function "cooks" a track label. If label<0, this track is fake.
6772 //--------------------------------------------------------------------
6773 AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
6774 if(!t){
6775 printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
6776 return;
6777 }
6778
6779 Int_t noc=t->GetNumberOfClusters();
6780 if (noc<10){
6781 //printf("\nnot founded prolongation\n\n\n");
6782 //t->Dump();
6783 return ;
6784 }
6785 Int_t lb[160];
6786 Int_t mx[160];
6787 AliTPCclusterMI *clusters[160];
6788 //
6789 for (Int_t i=0;i<160;i++) {
6790 clusters[i]=0;
6791 lb[i]=mx[i]=0;
6792 }
6793
6794 Int_t i;
6795 Int_t current=0;
6796 for (i=0; i<160 && current<noc; i++) {
6797
6798 Int_t index=t->GetClusterIndex2(i);
6799 if (index<=0) continue;
6800 if (index&0x8000) continue;
6801 //
6802 //clusters[current]=GetClusterMI(index);
6803 if (t->GetClusterPointer(i)){
6804 clusters[current]=t->GetClusterPointer(i);
6805 current++;
6806 }
6807 }
6808 noc = current;
6809
6810 Int_t lab=123456789;
6811 for (i=0; i<noc; i++) {
6812 AliTPCclusterMI *c=clusters[i];
6813 if (!c) continue;
6814 lab=TMath::Abs(c->GetLabel(0));
6815 Int_t j;
6816 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
6817 lb[j]=lab;
6818 (mx[j])++;
6819 }
6820
6821 Int_t max=0;
6822 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
6823
6824 for (i=0; i<noc; i++) {
6825 AliTPCclusterMI *c=clusters[i];
6826 if (!c) continue;
6827 if (TMath::Abs(c->GetLabel(1)) == lab ||
6828 TMath::Abs(c->GetLabel(2)) == lab ) max++;
6829 }
6830
6831 if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
6832
6833 else {
6834 Int_t tail=Int_t(0.10*noc);
6835 max=0;
6836 Int_t ind=0;
6837 for (i=1; i<=160&&ind<tail; i++) {
6838 // AliTPCclusterMI *c=clusters[noc-i];
6839 AliTPCclusterMI *c=clusters[i];
6840 if (!c) continue;
6841 if (lab == TMath::Abs(c->GetLabel(0)) ||
6842 lab == TMath::Abs(c->GetLabel(1)) ||
6843 lab == TMath::Abs(c->GetLabel(2))) max++;
6844 ind++;
6845 }
6846 if (max < Int_t(0.5*tail)) lab=-lab;
6847 }
6848
6849 t->SetLabel(lab);
6850
6851 // delete[] lb;
6852 //delete[] mx;
6853 //delete[] clusters;
6854}
6855
6856
6857//__________________________________________________________________________
6858Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong,Int_t first, Int_t last) const {
6859 //--------------------------------------------------------------------
6860 //This function "cooks" a track label. If label<0, this track is fake.
6861 //--------------------------------------------------------------------
6862 Int_t noc=t->GetNumberOfClusters();
6863 if (noc<10){
6864 //printf("\nnot founded prolongation\n\n\n");
6865 //t->Dump();
6866 return -1;
6867 }
6868 Int_t lb[160];
6869 Int_t mx[160];
6870 AliTPCclusterMI *clusters[160];
6871 //
6872 for (Int_t i=0;i<160;i++) {
6873 clusters[i]=0;
6874 lb[i]=mx[i]=0;
6875 }
6876
6877 Int_t i;
6878 Int_t current=0;
6879 for (i=0; i<160 && current<noc; i++) {
6880 if (i<first) continue;
6881 if (i>last) continue;
6882 Int_t index=t->GetClusterIndex2(i);
6883 if (index<=0) continue;
6884 if (index&0x8000) continue;
6885 //
6886 //clusters[current]=GetClusterMI(index);
6887 if (t->GetClusterPointer(i)){
6888 clusters[current]=t->GetClusterPointer(i);
6889 current++;
6890 }
6891 }
6892 noc = current;
6893 if (noc<5) return -1;
6894 Int_t lab=123456789;
6895 for (i=0; i<noc; i++) {
6896 AliTPCclusterMI *c=clusters[i];
6897 if (!c) continue;
6898 lab=TMath::Abs(c->GetLabel(0));
6899 Int_t j;
6900 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
6901 lb[j]=lab;
6902 (mx[j])++;
6903 }
6904
6905 Int_t max=0;
6906 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
6907
6908 for (i=0; i<noc; i++) {
6909 AliTPCclusterMI *c=clusters[i];
6910 if (!c) continue;
6911 if (TMath::Abs(c->GetLabel(1)) == lab ||
6912 TMath::Abs(c->GetLabel(2)) == lab ) max++;
6913 }
6914
6915 if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
6916
6917 else {
6918 Int_t tail=Int_t(0.10*noc);
6919 max=0;
6920 Int_t ind=0;
6921 for (i=1; i<=160&&ind<tail; i++) {
6922 // AliTPCclusterMI *c=clusters[noc-i];
6923 AliTPCclusterMI *c=clusters[i];
6924 if (!c) continue;
6925 if (lab == TMath::Abs(c->GetLabel(0)) ||
6926 lab == TMath::Abs(c->GetLabel(1)) ||
6927 lab == TMath::Abs(c->GetLabel(2))) max++;
6928 ind++;
6929 }
6930 if (max < Int_t(0.5*tail)) lab=-lab;
6931 }
6932
6933 // t->SetLabel(lab);
6934 return lab;
6935 // delete[] lb;
6936 //delete[] mx;
6937 //delete[] clusters;
6938}
6939
6940
6941Int_t AliTPCtrackerMI::GetRowNumber(Double_t x[3]) const
6942{
6943 //return pad row number for given x vector
6944 Float_t phi = TMath::ATan2(x[1],x[0]);
6945 if(phi<0) phi=2.*TMath::Pi()+phi;
6946 // Get the local angle in the sector philoc
6947 const Float_t kRaddeg = 180/3.14159265358979312;
6948 Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
6949 Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
6950 return GetRowNumber(localx);
6951}
6952
6953
6954
6955void AliTPCtrackerMI::MakeBitmaps(AliTPCseed *t)
6956{
6957 //-----------------------------------------------------------------------
6958 // Fill the cluster and sharing bitmaps of the track
6959 //-----------------------------------------------------------------------
6960
6961 Int_t firstpoint = 0;
6962 Int_t lastpoint = 159;
6963 AliTPCTrackerPoint *point;
6964 AliTPCclusterMI *cluster;
6965
6966 for (int iter=firstpoint; iter<lastpoint; iter++) {
6967 // Change to cluster pointers to see if we have a cluster at given padrow
6968 cluster = t->GetClusterPointer(iter);
6969 if (cluster) {
6970 t->SetClusterMapBit(iter, kTRUE);
6971 point = t->GetTrackPoint(iter);
6972 if (point->IsShared())
6973 t->SetSharedMapBit(iter,kTRUE);
6974 else
6975 t->SetSharedMapBit(iter, kFALSE);
6976 }
6977 else {
6978 t->SetClusterMapBit(iter, kFALSE);
6979 t->SetSharedMapBit(iter, kFALSE);
6980 }
6981 }
6982}
6983
6984Bool_t AliTPCtrackerMI::IsFindable(AliTPCseed & track){
6985 //
6986 // return flag if there is findable cluster at given position
6987 //
6988 Float_t kDeltaZ=10;
6989 Float_t z = track.GetZ();
6990
6991 if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*track.GetX()+kDeltaZ) &&
6992 TMath::Abs(z)<fParam->GetZLength(0) &&
6993 (TMath::Abs(track.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
6994 return kTRUE;
6995 return kFALSE;
6996}
6997
6998
6999void AliTPCtrackerMI::AddCovariance(AliTPCseed * seed){
7000 //
7001 // Adding systematic error
7002 // !!!! the systematic error for element 4 is in 1/cm not in pt
7003
7004 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
7005 Double_t covar[15];
7006 for (Int_t i=0;i<15;i++) covar[i]=0;
7007 // 0
7008 // 1 2
7009 // 3 4 5
7010 // 6 7 8 9
7011 // 10 11 12 13 14
7012 covar[0] = param[0]*param[0];
7013 covar[2] = param[1]*param[1];
7014 covar[5] = param[2]*param[2];
7015 covar[9] = param[3]*param[3];
7016 Double_t facC = AliTracker::GetBz()*kB2C;
7017 covar[14]= param[4]*param[4]*facC*facC;
7018 seed->AddCovariance(covar);
7019}