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