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