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