Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 :
16 :
17 : //-------------------------------------------------------
18 : // Implementation of the TPC tracker
19 : //
20 : // Origin: Marian Ivanov Marian.Ivanov@cern.ch
21 : //
22 : // AliTPC parallel tracker
23 : //
24 : // The track fitting is based on Kalman filtering approach
25 : // The track finding steps:
26 : // 1. Seeding - with and without vertex constraint
27 : // - seeding with vertex constain done at first n^2 proble
28 : // - seeding without vertex constraint n^3 problem
29 : // 2. Tracking - follow prolongation road - find cluster - update kalman track
30 : // The seeding and tracking is repeated several times, in different seeding region.
31 : // This approach enables to find the track which cannot be seeded in some region of TPC
32 : // 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) ...
33 :
34 : // With this approach we reach almost 100 % efficiency also for high occupancy events.
35 : // (If the seeding efficiency in a region is about 90 % than with logical or of several
36 : // regions we will reach 100% (in theory - supposing independence)
37 :
38 : // Repeating several seeding - tracking procedures some of the tracks can be find
39 : // several times.
40 :
41 : // The procedures to remove multi find tacks are impremented:
42 : // RemoveUsed2 - fast procedure n problem -
43 : // Algorithm - Sorting tracks according quality
44 : // remove tracks with some shared fraction
45 : // Sharing in respect to all tacks
46 : // Signing clusters in gold region
47 : // FindSplitted - slower algorithm n^2
48 : // Sort the tracks according quality
49 : // Loop over pair of tracks
50 : // If overlap with other track bigger than threshold - remove track
51 : //
52 : // FindCurling - Finds the pair of tracks which are curling
53 : // - About 10% of tracks can be find with this procedure
54 : // The combinatorial background is too big to be used in High
55 : // multiplicity environment
56 : // - n^2 problem - Slow procedure - currently it is disabled because of
57 : // low efficiency
58 : //
59 : // The number of splitted tracks can be reduced disabling the sharing of the cluster.
60 : // tpcRecoParam-> SetClusterSharing(kFALSE);
61 : // IT IS HIGHLY non recomended to use it in high flux enviroonment
62 : // Even using this switch some tracks can be found more than once
63 : // (because of multiple seeding and low quality tracks which will not cross full chamber)
64 : //
65 : //
66 : // The tracker itself can be debugged - the information about tracks can be stored in several // phases of the reconstruction
67 : // To enable storage of the TPC tracks in the ESD friend track
68 : // use AliTPCReconstructor::SetStreamLevel(n);
69 : //
70 : // The debug level - different procedure produce tree for numerical debugging of code and data (see comments foEStreamFlags in AliTPCtracker.h )
71 : //
72 :
73 : //
74 : // Adding systematic errors to the covariance:
75 : //
76 : // The systematic errors due to the misalignment and miscalibration are added to the covariance matrix
77 : // of the tracks (not to the clusters as they are dependent):
78 : // The parameters form AliTPCRecoParam are used AliTPCRecoParam::GetSystematicError
79 : // The systematic errors are expressed there in RMS - position (cm), angle (rad), curvature (1/GeV)
80 : // The default values are 0.
81 : //
82 : // The systematic errors are added to the covariance matrix in following places:
83 : //
84 : // 1. During fisrt itteration - AliTPCtracker::FillESD
85 : // 2. Second iteration -
86 : // 2.a ITS->TPC - AliTPCtracker::ReadSeeds
87 : // 2.b TPC->TRD - AliTPCtracker::PropagateBack
88 : // 3. Third iteration -
89 : // 3.a TRD->TPC - AliTPCtracker::ReadSeeds
90 : // 3.b TPC->ITS - AliTPCtracker::RefitInward
91 : //
92 :
93 : /* $Id$ */
94 :
95 : #include "Riostream.h"
96 : #include <TClonesArray.h>
97 : #include <TFile.h>
98 : #include <TObjArray.h>
99 : #include <TTree.h>
100 : #include <TMatrixD.h>
101 : #include <TGraphErrors.h>
102 : #include <TTimeStamp.h>
103 : #include "AliLog.h"
104 : #include "AliComplexCluster.h"
105 : #include "AliESDEvent.h"
106 : #include "AliESDtrack.h"
107 : #include "AliESDVertex.h"
108 : #include "AliKink.h"
109 : #include "AliV0.h"
110 : #include "AliHelix.h"
111 : #include "AliRunLoader.h"
112 : #include "AliTPCClustersRow.h"
113 : #include "AliTPCParam.h"
114 : #include "AliTPCReconstructor.h"
115 : #include "AliTPCpolyTrack.h"
116 : #include "AliTPCreco.h"
117 : //#include "AliTPCseed.h"
118 :
119 : #include "AliTPCtrackerSector.h"
120 : #include "AliTPCtracker.h"
121 : #include "TStopwatch.h"
122 : #include "AliTPCReconstructor.h"
123 : #include "AliAlignObj.h"
124 : #include "AliTrackPointArray.h"
125 : #include "TRandom.h"
126 : #include "AliTPCcalibDB.h"
127 : #include "AliTPCcalibDButil.h"
128 : #include "AliTPCTransform.h"
129 : #include "AliTPCClusterParam.h"
130 : #include "AliTPCdEdxInfo.h"
131 : #include "AliDCSSensorArray.h"
132 : #include "AliDCSSensor.h"
133 : #include "AliDAQ.h"
134 : #include "AliCosmicTracker.h"
135 : #include "AliTPCROC.h"
136 : #include "AliMathBase.h"
137 : #include <math.h>
138 : //
139 : #include "AliESDfriendTrack.h"
140 :
141 : using std::cout;
142 : using std::cerr;
143 : using std::endl;
144 16 : ClassImp(AliTPCtracker)
145 :
146 : //__________________________________________________________________
147 : AliTPCtracker::AliTPCtracker()
148 0 : :AliTracker(),
149 0 : fkNIS(0),
150 0 : fInnerSec(0),
151 0 : fkNOS(0),
152 0 : fOuterSec(0),
153 0 : fN(0),
154 0 : fSectors(0),
155 0 : fInput(0),
156 0 : fOutput(0),
157 0 : fSeedTree(0),
158 0 : fTreeDebug(0),
159 0 : fEvent(0),
160 0 : fEventHLT(0),
161 0 : fDebug(0),
162 0 : fNewIO(kFALSE),
163 0 : fNtracks(0),
164 0 : fSeeds(0),
165 0 : fIteration(0),
166 0 : fkParam(0),
167 0 : fDebugStreamer(0),
168 0 : fUseHLTClusters(4),
169 0 : fClExtraRoadY(0.),
170 0 : fClExtraRoadZ(0.),
171 0 : fExtraClErrYZ2(0),
172 0 : fExtraClErrY2(0),
173 0 : fExtraClErrZ2(0),
174 0 : fPrimaryDCAZCut(-1),
175 0 : fPrimaryDCAYCut(-1),
176 0 : fDisableSecondaries(kFALSE),
177 0 : fCrossTalkSignalArray(0),
178 0 : fClPointersPool(0),
179 0 : fClPointersPoolPtr(0),
180 0 : fClPointersPoolSize(0),
181 0 : fSeedsPool(0),
182 0 : fHelixPool(0),
183 0 : fETPPool(0),
184 0 : fFreeSeedsID(500),
185 0 : fNFreeSeeds(0),
186 0 : fLastSeedID(-1),
187 0 : fAccountDistortions(0)
188 0 : {
189 : //
190 : // default constructor
191 : //
192 0 : for (Int_t irow=0; irow<200; irow++){
193 0 : fXRow[irow]=0;
194 0 : fYMax[irow]=0;
195 0 : fPadLength[irow]=0;
196 : }
197 0 : }
198 : //_____________________________________________________________________
199 :
200 :
201 :
202 : Int_t AliTPCtracker::UpdateTrack(AliTPCseed * track, Int_t accept){
203 : //
204 : //update track information using current cluster - track->fCurrentCluster
205 :
206 :
207 206720 : AliTPCclusterMI* c =track->GetCurrentCluster();
208 206720 : if (accept > 0) //sign not accepted clusters
209 107472 : track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() | 0x8000);
210 : else // unsign accpeted clusters
211 99248 : track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() & 0xffff7fff);
212 103360 : UInt_t i = track->GetCurrentClusterIndex1();
213 :
214 103360 : Int_t sec=(i&0xff000000)>>24;
215 103360 : Int_t row = (i&0x00ff0000)>>16;
216 167432 : if (sec>=fkParam->GetNInnerSector()) row += fkParam->GetNRowLow();
217 103360 : track->SetRow(row);
218 103360 : track->SetSector(sec);
219 103360 : track->SetClusterIndex2(row, i);
220 : //track->fFirstPoint = row;
221 : //if ( track->fLastPoint<row) track->fLastPoint =row;
222 : // if (track->fRow<0 || track->fRow>=kMaxRow) {
223 : // printf("problem\n");
224 : //}
225 103360 : if (track->GetFirstPoint()>row)
226 38460 : track->SetFirstPoint(row);
227 103360 : if (track->GetLastPoint()<row)
228 17776 : track->SetLastPoint(row);
229 :
230 103360 : Double_t angle2 = track->GetSnp()*track->GetSnp();
231 : //
232 : //SET NEW Track Point
233 : //
234 103360 : if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
235 : {
236 103360 : angle2 = TMath::Sqrt(angle2/(1-angle2));
237 103360 : AliTPCTrackerPoints::Point &point =*((AliTPCTrackerPoints::Point*)track->GetTrackPoint(row));
238 : //
239 103360 : point.SetSigmaY(c->GetSigmaY2()/track->GetCurrentSigmaY2());
240 103360 : point.SetSigmaZ(c->GetSigmaZ2()/track->GetCurrentSigmaZ2());
241 103360 : point.SetErrY(sqrt(track->GetErrorY2()));
242 103360 : point.SetErrZ(sqrt(track->GetErrorZ2()));
243 : //
244 103360 : point.SetX(track->GetX());
245 103360 : point.SetY(track->GetY());
246 103360 : point.SetZ(track->GetZ());
247 103360 : point.SetAngleY(angle2);
248 103360 : point.SetAngleZ(track->GetTgl());
249 103360 : if (track->IsShared(row)){
250 0 : track->SetErrorY2(track->GetErrorY2()*4);
251 0 : track->SetErrorZ2(track->GetErrorZ2()*4);
252 0 : }
253 103360 : }
254 :
255 107472 : if (accept>0) return 0;
256 99248 : Double_t chi2 = track->GetPredictedChi2(track->GetCurrentCluster());
257 : //
258 : // track->SetErrorY2(track->GetErrorY2()*1.3);
259 : // track->SetErrorY2(track->GetErrorY2()+0.01);
260 : // track->SetErrorZ2(track->GetErrorZ2()*1.3);
261 : // track->SetErrorZ2(track->GetErrorZ2()+0.005);
262 : //}
263 99248 : if (track->GetNumberOfClusters()%20==0){
264 : // if (track->fHelixIn){
265 : // TClonesArray & larr = *(track->fHelixIn);
266 : // Int_t ihelix = larr.GetEntriesFast();
267 : // new(larr[ihelix]) AliHelix(*track) ;
268 : //}
269 : }
270 99248 : if (AliTPCReconstructor::StreamLevel()&kStreamUpdateTrack) {
271 0 : Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
272 0 : AliExternalTrackParam param(*track);
273 0 : TTreeSRedirector &cstream = *fDebugStreamer;
274 0 : cstream<<"UpdateTrack"<<
275 0 : "cl.="<<c<<
276 0 : "event="<<event<<
277 0 : "track.="<<¶m<<
278 : "\n";
279 0 : }
280 99248 : track->SetNoCluster(0);
281 99248 : return track->Update(c,chi2,i);
282 103360 : }
283 :
284 :
285 :
286 : Int_t AliTPCtracker::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster)
287 : {
288 : //
289 : // decide according desired precision to accept given
290 : // cluster for tracking
291 209276 : Double_t yt = seed->GetY(),zt = seed->GetZ();
292 : // RS: use propagation only if the seed in far from the cluster
293 : const double kTolerance = 10e-4; // assume track is at cluster X if X-distance below this
294 175082 : if (TMath::Abs(seed->GetX()-cluster->GetX())>kTolerance) seed->GetProlongation(cluster->GetX(),yt,zt);
295 104638 : Double_t sy2=0;//ErrY2(seed,cluster);
296 104638 : Double_t sz2=0;//ErrZ2(seed,cluster);
297 104638 : ErrY2Z2(seed,cluster,sy2,sz2);
298 :
299 104638 : Double_t sdistancey2 = sy2+seed->GetSigmaY2();
300 104638 : Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
301 104638 : Double_t dy=seed->GetCurrentCluster()->GetY()-yt;
302 104638 : Double_t dz=seed->GetCurrentCluster()->GetZ()-zt;
303 104638 : Double_t rdistancey2 = dy*dy/sdistancey2;
304 104638 : Double_t rdistancez2 = dz*dz/sdistancez2;
305 :
306 104638 : Double_t rdistance2 = rdistancey2+rdistancez2;
307 : //Int_t accept =0;
308 :
309 104638 : if (AliTPCReconstructor::StreamLevel()>2 && ( (fIteration>0)|| (seed->GetNumberOfClusters()>20))) {
310 : // if (AliTPCReconstructor::StreamLevel()>2 && seed->GetNumberOfClusters()>20) {
311 0 : Float_t rmsy2 = seed->GetCurrentSigmaY2();
312 0 : Float_t rmsz2 = seed->GetCurrentSigmaZ2();
313 0 : Float_t rmsy2p30 = seed->GetCMeanSigmaY2p30();
314 0 : Float_t rmsz2p30 = seed->GetCMeanSigmaZ2p30();
315 0 : Float_t rmsy2p30R = seed->GetCMeanSigmaY2p30R();
316 0 : Float_t rmsz2p30R = seed->GetCMeanSigmaZ2p30R();
317 0 : AliExternalTrackParam param(*seed);
318 0 : static TVectorD gcl(3),gtr(3);
319 0 : Float_t gclf[3];
320 0 : param.GetXYZ(gcl.GetMatrixArray());
321 0 : cluster->GetGlobalXYZ(gclf);
322 0 : gcl[0]=gclf[0]; gcl[1]=gclf[1]; gcl[2]=gclf[2];
323 0 : Int_t nclSeed=seed->GetNumberOfClusters();
324 0 : int seedType = seed->GetSeedType();
325 0 : if (AliTPCReconstructor::StreamLevel()&kStreamErrParam) { // flag:stream in debug mode cluster and track extrapolation at given row together with error nad shape estimate
326 0 : Int_t eventNr = fEvent->GetEventNumberInFile();
327 :
328 0 : (*fDebugStreamer)<<"ErrParam"<<
329 0 : "iter="<<fIteration<<
330 0 : "eventNr="<<eventNr<<
331 0 : "Cl.="<<cluster<<
332 0 : "nclSeed="<<nclSeed<<
333 0 : "seedType="<<seedType<<
334 0 : "T.="<<¶m<<
335 0 : "dy="<<dy<<
336 0 : "dz="<<dz<<
337 0 : "yt="<<yt<<
338 0 : "zt="<<zt<<
339 0 : "gcl.="<<&gcl<<
340 0 : "gtr.="<<>r<<
341 0 : "erry2="<<sy2<<
342 0 : "errz2="<<sz2<<
343 0 : "rmsy2="<<rmsy2<<
344 0 : "rmsz2="<<rmsz2<<
345 0 : "rmsy2p30="<<rmsy2p30<<
346 0 : "rmsz2p30="<<rmsz2p30<<
347 0 : "rmsy2p30R="<<rmsy2p30R<<
348 0 : "rmsz2p30R="<<rmsz2p30R<<
349 : // normalize distance -
350 0 : "rdisty="<<rdistancey2<<
351 0 : "rdistz="<<rdistancez2<<
352 0 : "rdist="<<rdistance2<< //
353 : "\n";
354 0 : }
355 0 : }
356 : //return 0; // temporary
357 105918 : if (rdistance2>32) return 3;
358 :
359 :
360 107702 : if ((rdistancey2>9. || rdistancez2>9.) && cluster->GetType()==0)
361 3832 : return 2; //suspisiouce - will be changed
362 :
363 103838 : if ((rdistancey2>6.25 || rdistancez2>6.25) && cluster->GetType()>0)
364 : // strict cut on overlaped cluster
365 662 : return 2; //suspisiouce - will be changed
366 :
367 130849 : if ( (rdistancey2>1. || rdistancez2>6.25 )
368 31985 : && cluster->GetType()<0){
369 54 : seed->SetNFoundable(seed->GetNFoundable()-1);
370 54 : return 2;
371 : }
372 :
373 197620 : if (fUseHLTClusters == 3 || fUseHLTClusters == 4) {
374 0 : if (fIteration==2){
375 0 : if(!AliTPCReconstructor::GetRecoParam()->GetUseHLTOnePadCluster()) {
376 0 : if (TMath::Abs(cluster->GetSigmaY2()) < kAlmost0)
377 0 : return 2;
378 : }
379 : }
380 : }
381 :
382 98810 : return 0;
383 104638 : }
384 :
385 :
386 :
387 :
388 :
389 : //_____________________________________________________________________________
390 : AliTPCtracker::AliTPCtracker(const AliTPCParam *par):
391 2 : AliTracker(),
392 2 : fkNIS(par->GetNInnerSector()/2),
393 2 : fInnerSec(0),
394 2 : fkNOS(par->GetNOuterSector()/2),
395 2 : fOuterSec(0),
396 2 : fN(0),
397 2 : fSectors(0),
398 2 : fInput(0),
399 2 : fOutput(0),
400 2 : fSeedTree(0),
401 2 : fTreeDebug(0),
402 2 : fEvent(0),
403 2 : fEventHLT(0),
404 2 : fDebug(0),
405 2 : fNewIO(0),
406 2 : fNtracks(0),
407 2 : fSeeds(0),
408 2 : fIteration(0),
409 2 : fkParam(0),
410 2 : fDebugStreamer(0),
411 2 : fUseHLTClusters(4),
412 2 : fClExtraRoadY(0.),
413 2 : fClExtraRoadZ(0.),
414 2 : fExtraClErrYZ2(0),
415 2 : fExtraClErrY2(0),
416 2 : fExtraClErrZ2(0),
417 2 : fPrimaryDCAZCut(-1),
418 2 : fPrimaryDCAYCut(-1),
419 2 : fDisableSecondaries(kFALSE),
420 2 : fCrossTalkSignalArray(0),
421 2 : fClPointersPool(0),
422 2 : fClPointersPoolPtr(0),
423 2 : fClPointersPoolSize(0),
424 2 : fSeedsPool(0),
425 2 : fHelixPool(0),
426 2 : fETPPool(0),
427 2 : fFreeSeedsID(500),
428 2 : fNFreeSeeds(0),
429 2 : fLastSeedID(-1),
430 2 : fAccountDistortions(0)
431 10 : {
432 : //---------------------------------------------------------------------
433 : // The main TPC tracker constructor
434 : //---------------------------------------------------------------------
435 80 : fInnerSec=new AliTPCtrackerSector[fkNIS];
436 80 : fOuterSec=new AliTPCtrackerSector[fkNOS];
437 :
438 : Int_t i;
439 112 : for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
440 112 : for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
441 :
442 2 : fkParam = par;
443 2 : Int_t nrowlow = par->GetNRowLow();
444 2 : Int_t nrowup = par->GetNRowUp();
445 :
446 :
447 256 : for (i=0;i<nrowlow;i++){
448 252 : fXRow[i] = par->GetPadRowRadiiLow(i);
449 126 : fPadLength[i]= par->GetPadPitchLength(0,i);
450 252 : fYMax[i] = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
451 : }
452 :
453 :
454 388 : for (i=0;i<nrowup;i++){
455 384 : fXRow[i+nrowlow] = par->GetPadRowRadiiUp(i);
456 192 : fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
457 384 : fYMax[i+nrowlow] = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
458 : }
459 :
460 2 : if (AliTPCReconstructor::StreamLevel()>0) {
461 0 : fDebugStreamer = new TTreeSRedirector("TPCdebug.root","recreate");
462 0 : AliTPCReconstructor::SetDebugStreamer(fDebugStreamer);
463 0 : }
464 : //
465 6 : fSeedsPool = new TClonesArray("AliTPCseed",1000);
466 4 : fClPointersPool = new AliTPCclusterMI*[kMaxFriendTracks*kMaxRow];
467 2 : memset(fClPointersPool,0,kMaxFriendTracks*kMaxRow*sizeof(AliTPCclusterMI*));
468 2 : fClPointersPoolPtr = fClPointersPool;
469 2 : fClPointersPoolSize = kMaxFriendTracks;
470 : //
471 : // crosstalk array and matrix initialization
472 : Int_t nROCs = 72;
473 4 : Int_t nTimeBinsAll = AliTPCcalibDB::Instance()->GetMaxTimeBinAllPads() ;
474 : Int_t nWireSegments = 11;
475 6 : fCrossTalkSignalArray = new TObjArray(nROCs*4); //
476 2 : fCrossTalkSignalArray->SetOwner(kTRUE);
477 1156 : for (Int_t isector=0; isector<4*nROCs; isector++){
478 1152 : TMatrixD * crossTalkSignal = new TMatrixD(nWireSegments,nTimeBinsAll);
479 13824 : for (Int_t imatrix = 0; imatrix<11; imatrix++)
480 12177792 : for (Int_t jmatrix = 0; jmatrix<nTimeBinsAll; jmatrix++){
481 18247680 : (*crossTalkSignal)[imatrix][jmatrix]=0.;
482 : }
483 576 : fCrossTalkSignalArray->AddAt(crossTalkSignal,isector);
484 : }
485 :
486 4 : }
487 : //________________________________________________________________________
488 : AliTPCtracker::AliTPCtracker(const AliTPCtracker &t):
489 0 : AliTracker(t),
490 0 : fkNIS(t.fkNIS),
491 0 : fInnerSec(0),
492 0 : fkNOS(t.fkNOS),
493 0 : fOuterSec(0),
494 0 : fN(0),
495 0 : fSectors(0),
496 0 : fInput(0),
497 0 : fOutput(0),
498 0 : fSeedTree(0),
499 0 : fTreeDebug(0),
500 0 : fEvent(0),
501 0 : fEventHLT(0),
502 0 : fDebug(0),
503 0 : fNewIO(kFALSE),
504 0 : fNtracks(0),
505 0 : fSeeds(0),
506 0 : fIteration(0),
507 0 : fkParam(0),
508 0 : fDebugStreamer(0),
509 0 : fUseHLTClusters(4),
510 0 : fClExtraRoadY(0.),
511 0 : fClExtraRoadZ(0.),
512 0 : fExtraClErrYZ2(0),
513 0 : fExtraClErrY2(0),
514 0 : fExtraClErrZ2(0),
515 0 : fPrimaryDCAZCut(-1),
516 0 : fPrimaryDCAYCut(-1),
517 0 : fDisableSecondaries(kFALSE),
518 0 : fCrossTalkSignalArray(0),
519 0 : fClPointersPool(0),
520 0 : fClPointersPoolPtr(0),
521 0 : fClPointersPoolSize(0),
522 0 : fSeedsPool(0),
523 0 : fHelixPool(0),
524 0 : fETPPool(0),
525 0 : fFreeSeedsID(500),
526 0 : fNFreeSeeds(0),
527 0 : fLastSeedID(-1),
528 0 : fAccountDistortions(0)
529 0 : {
530 : //------------------------------------
531 : // dummy copy constructor
532 : //------------------------------------------------------------------
533 0 : fOutput=t.fOutput;
534 0 : for (Int_t irow=0; irow<200; irow++){
535 0 : fXRow[irow]=0;
536 0 : fYMax[irow]=0;
537 0 : fPadLength[irow]=0;
538 : }
539 :
540 0 : }
541 : AliTPCtracker & AliTPCtracker::operator=(const AliTPCtracker& /*r*/)
542 : {
543 : //------------------------------
544 : // dummy
545 : //--------------------------------------------------------------
546 0 : return *this;
547 : }
548 : //_____________________________________________________________________________
549 12 : AliTPCtracker::~AliTPCtracker() {
550 : //------------------------------------------------------------------
551 : // TPC tracker destructor
552 : //------------------------------------------------------------------
553 42 : delete[] fInnerSec;
554 42 : delete[] fOuterSec;
555 2 : if (fSeeds) {
556 2 : fSeeds->Clear();
557 4 : delete fSeeds;
558 : }
559 4 : delete[] fClPointersPool;
560 6 : if (fCrossTalkSignalArray) delete fCrossTalkSignalArray;
561 2 : if (fDebugStreamer) delete fDebugStreamer;
562 2 : if (fSeedsPool) {
563 62 : for (int isd=fSeedsPool->GetEntriesFast();isd--;) {
564 56 : AliTPCseed* seed = (AliTPCseed*)fSeedsPool->At(isd);
565 28 : if (seed) {
566 28 : seed->SetClusterOwner(kFALSE);
567 28 : seed->SetClustersArrayTMP(0);
568 28 : }
569 : }
570 4 : delete fSeedsPool;
571 : }
572 4 : if (fHelixPool) fHelixPool->Delete();
573 4 : delete fHelixPool;
574 4 : if (fETPPool) fETPPool->Delete();
575 4 : delete fETPPool;
576 6 : }
577 :
578 :
579 : void AliTPCtracker::FillESD(const TObjArray* arr)
580 : {
581 : //
582 : //
583 : //fill esds using updated tracks
584 :
585 16 : if (!fEvent) return;
586 :
587 8 : AliESDtrack iotrack;
588 :
589 : // write tracks to the event
590 : // store index of the track
591 8 : Int_t nseed=arr->GetEntriesFast();
592 : //FindKinks(arr,fEvent);
593 288 : for (Int_t i=0; i<nseed; i++) {
594 136 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
595 136 : if (!pt) continue;
596 136 : pt->UpdatePoints();
597 136 : AddCovariance(pt);
598 136 : if (AliTPCReconstructor::StreamLevel()&kStreamFillESD) {
599 0 : (*fDebugStreamer)<<"FillESD"<< // flag: stream track information in FillESD function (after track Iteration 0)
600 0 : "Tr0.="<<pt<<
601 : "\n";
602 : }
603 : // pt->PropagateTo(fkParam->GetInnerRadiusLow());
604 272 : if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
605 132 : pt->PropagateTo(fkParam->GetInnerRadiusLow());
606 132 : pt->SetRow(0); // RS: memorise row
607 132 : }
608 :
609 272 : if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
610 136 : iotrack.~AliESDtrack();
611 272 : new(&iotrack) AliESDtrack;
612 136 : iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
613 136 : iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
614 136 : iotrack.SetTPCPoints(pt->GetPoints());
615 136 : iotrack.SetKinkIndexes(pt->GetKinkIndexes());
616 136 : iotrack.SetV0Indexes(pt->GetV0Indexes());
617 : // iotrack.SetTPCpid(pt->fTPCr);
618 : //iotrack.SetTPCindex(i);
619 136 : MakeESDBitmaps(pt, &iotrack);
620 136 : fEvent->AddTrack(&iotrack);
621 136 : continue;
622 : }
623 :
624 0 : if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
625 0 : iotrack.~AliESDtrack();
626 0 : new(&iotrack) AliESDtrack;
627 0 : iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
628 0 : iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
629 0 : iotrack.SetTPCPoints(pt->GetPoints());
630 : //iotrack.SetTPCindex(i);
631 0 : iotrack.SetKinkIndexes(pt->GetKinkIndexes());
632 0 : iotrack.SetV0Indexes(pt->GetV0Indexes());
633 0 : MakeESDBitmaps(pt, &iotrack);
634 : // iotrack.SetTPCpid(pt->fTPCr);
635 0 : fEvent->AddTrack(&iotrack);
636 0 : continue;
637 : }
638 : //
639 : // short tracks - maybe decays
640 :
641 : //RS Seed don't keep their cluster pointers, cache cluster usage stat. for fast evaluation
642 : // FillSeedClusterStatCache(pt); // RS use this slow method only if info on shared statistics is needed
643 :
644 0 : if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
645 0 : Int_t found,foundable; //,shared;
646 : //GetCachedSeedClusterStatistic(0,60,found, foundable,shared,kFALSE); // RS make sure FillSeedClusterStatCache is called
647 : //pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE); //RS: avoid this method: seed does not keep clusters
648 0 : pt->GetClusterStatistic(0,60,found, foundable);
649 0 : if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
650 0 : iotrack.~AliESDtrack();
651 0 : new(&iotrack) AliESDtrack;
652 0 : iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
653 0 : iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
654 : //iotrack.SetTPCindex(i);
655 0 : iotrack.SetTPCPoints(pt->GetPoints());
656 0 : iotrack.SetKinkIndexes(pt->GetKinkIndexes());
657 0 : iotrack.SetV0Indexes(pt->GetV0Indexes());
658 0 : MakeESDBitmaps(pt, &iotrack);
659 : //iotrack.SetTPCpid(pt->fTPCr);
660 0 : fEvent->AddTrack(&iotrack);
661 0 : continue;
662 : }
663 0 : }
664 :
665 0 : if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
666 0 : Int_t found,foundable;//,shared;
667 : //RS GetCachedSeedClusterStatistic(0,60,found, foundable,shared,kFALSE); // RS make sure FillSeedClusterStatCache is called
668 : //pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE); //RS: avoid this method: seed does not keep clusters
669 0 : pt->GetClusterStatistic(0,60,found,foundable);
670 0 : if (found<20) continue;
671 0 : if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
672 : //
673 0 : iotrack.~AliESDtrack();
674 0 : new(&iotrack) AliESDtrack;
675 0 : iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
676 0 : iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
677 0 : iotrack.SetTPCPoints(pt->GetPoints());
678 0 : iotrack.SetKinkIndexes(pt->GetKinkIndexes());
679 0 : iotrack.SetV0Indexes(pt->GetV0Indexes());
680 0 : MakeESDBitmaps(pt, &iotrack);
681 : //iotrack.SetTPCpid(pt->fTPCr);
682 : //iotrack.SetTPCindex(i);
683 0 : fEvent->AddTrack(&iotrack);
684 0 : continue;
685 0 : }
686 : // short tracks - secondaties
687 : //
688 0 : if ( (pt->GetNumberOfClusters()>30) ) {
689 0 : Int_t found,foundable;//,shared;
690 : //GetCachedSeedClusterStatistic(128,158,found, foundable,shared,kFALSE); // RS make sure FillSeedClusterStatCache is called
691 : //pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE); //RS: avoid this method: seed does not keep clusters
692 0 : pt->GetClusterStatistic(128,158,found, foundable);
693 0 : if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
694 0 : iotrack.~AliESDtrack();
695 0 : new(&iotrack) AliESDtrack;
696 0 : iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
697 0 : iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
698 0 : iotrack.SetTPCPoints(pt->GetPoints());
699 0 : iotrack.SetKinkIndexes(pt->GetKinkIndexes());
700 0 : iotrack.SetV0Indexes(pt->GetV0Indexes());
701 0 : MakeESDBitmaps(pt, &iotrack);
702 : //iotrack.SetTPCpid(pt->fTPCr);
703 : //iotrack.SetTPCindex(i);
704 0 : fEvent->AddTrack(&iotrack);
705 0 : continue;
706 : }
707 0 : }
708 :
709 0 : if ( (pt->GetNumberOfClusters()>15)) {
710 0 : Int_t found,foundable,shared;
711 : //GetCachedSeedClusterStatistic(138,158,found, foundable,shared,kFALSE); // RS make sure FillSeedClusterStatCache is called
712 : //RS pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE); //RS: avoid this method: seed does not keep clusters
713 0 : pt->GetClusterStatistic(138,158,found, foundable);
714 0 : if (found<15) continue;
715 0 : if (foundable<=0) continue;
716 0 : if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
717 0 : if (float(found)/float(foundable)<0.8) continue;
718 : //
719 0 : iotrack.~AliESDtrack();
720 0 : new(&iotrack) AliESDtrack;
721 0 : iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
722 0 : iotrack.SetTPCsignal(pt->GetdEdx(), pt->GetSDEDX(0), pt->GetNCDEDX(0));
723 0 : iotrack.SetTPCPoints(pt->GetPoints());
724 0 : iotrack.SetKinkIndexes(pt->GetKinkIndexes());
725 0 : iotrack.SetV0Indexes(pt->GetV0Indexes());
726 0 : MakeESDBitmaps(pt, &iotrack);
727 : // iotrack.SetTPCpid(pt->fTPCr);
728 : //iotrack.SetTPCindex(i);
729 0 : fEvent->AddTrack(&iotrack);
730 0 : continue;
731 0 : }
732 0 : }
733 : // >> account for suppressed tracks in the kink indices (RS)
734 8 : int nESDtracks = fEvent->GetNumberOfTracks();
735 152 : for (int it=nESDtracks;it--;) {
736 136 : AliESDtrack* esdTr = fEvent->GetTrack(it);
737 536 : if (!esdTr || !esdTr->GetKinkIndex(0)) continue;
738 32 : for (int ik=0;ik<3;ik++) {
739 : int knkId=0;
740 40 : if (!(knkId=esdTr->GetKinkIndex(ik))) break; // no more kinks for this track
741 8 : AliESDkink* kink = fEvent->GetKink(TMath::Abs(knkId)-1);
742 8 : if (!kink) {
743 0 : AliError(Form("ESDTrack%d refers to non-existing kink %d",it,TMath::Abs(knkId)-1));
744 0 : continue;
745 : }
746 8 : kink->SetIndex(it, knkId<0 ? 0:1); // update track index of the kink: mother at 0, daughter at 1
747 8 : }
748 8 : }
749 :
750 : // << account for suppressed tracks in the kink indices (RS)
751 32 : AliInfo(Form("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks()));
752 :
753 16 : }
754 :
755 : //_____________________________________________________________________________________
756 : void AliTPCtracker::ErrY2Z2(AliTPCseed* seed, const AliTPCclusterMI * cl, double &erry2, double &errz2)
757 : {
758 : //
759 : //
760 : // Use calibrated cluster error from OCDB
761 : //
762 209276 : const AliTPCRecoParam* rp = AliTPCReconstructor::GetRecoParam();
763 104638 : AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
764 : //
765 104638 : Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
766 104638 : Int_t ctype = cl->GetType();
767 231950 : Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
768 104638 : double snp2 = seed->GetSnp()*seed->GetSnp();
769 104638 : if (snp2>1.-1e-6) snp2 = 1.-1e-6;
770 104638 : double tgp2 = snp2/(1.f-snp2);
771 104638 : double tgp = TMath::Sqrt(tgp2);
772 104638 : double tgl2m = seed->GetTgl()*seed->GetTgl()*(1+tgp2);
773 104638 : Double_t tglm = TMath::Sqrt(tgl2m);
774 104638 : erry2 = clparam->GetError0Par(0,type, z,tgp);
775 104638 : errz2 = clparam->GetError0Par(1,type, z,tglm);
776 104638 : if (ctype<0) { // edge cluster
777 2622 : erry2+=0.5;
778 2622 : errz2+=0.5;
779 2622 : }
780 104638 : erry2 *= erry2;
781 104638 : errz2 *= errz2;
782 : // additional systematic error on the cluster
783 104638 : double serry2=0,serrz2=0;
784 104638 : AliTPCcalibDB::Instance()->GetTransform()->ErrY2Z2Syst(cl, tgp, seed->GetTgl(), serry2,serrz2);
785 104638 : erry2 += serry2;
786 104638 : errz2 += serrz2;
787 104638 : seed->SetErrorY2(erry2);
788 104638 : seed->SetErrorZ2(errz2);
789 : //
790 104638 : }
791 :
792 :
793 :
794 : //_____________________________________________________________________________________
795 : Double_t AliTPCtracker::ErrY2(AliTPCseed* seed, const AliTPCclusterMI * cl){
796 : //
797 : //
798 : // Use calibrated cluster error from OCDB
799 : //
800 0 : const AliTPCRecoParam* rp = AliTPCReconstructor::GetRecoParam();
801 0 : AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
802 : //
803 0 : Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
804 0 : Int_t ctype = cl->GetType();
805 0 : Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
806 0 : double angle2 = seed->GetSnp()*seed->GetSnp();
807 0 : double angle = TMath::Sqrt(TMath::Abs(angle2/(1.f-angle2)));
808 0 : Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
809 0 : if (ctype<0) {
810 0 : erry2+=0.5; // edge cluster
811 0 : }
812 0 : erry2 *= erry2;
813 : // additional systematic error on the cluster
814 0 : erry2 += AliTPCcalibDB::Instance()->GetTransform()->ErrY2Syst(cl, angle);
815 0 : seed->SetErrorY2(erry2);
816 : //
817 0 : return erry2;
818 :
819 : //calculate look-up table at the beginning
820 : // static Bool_t ginit = kFALSE;
821 : // static Float_t gnoise1,gnoise2,gnoise3;
822 : // static Float_t ggg1[10000];
823 : // static Float_t ggg2[10000];
824 : // static Float_t ggg3[10000];
825 : // static Float_t glandau1[10000];
826 : // static Float_t glandau2[10000];
827 : // static Float_t glandau3[10000];
828 : // //
829 : // static Float_t gcor01[500];
830 : // static Float_t gcor02[500];
831 : // static Float_t gcorp[500];
832 : // //
833 :
834 : // //
835 : // if (ginit==kFALSE){
836 : // for (Int_t i=1;i<500;i++){
837 : // Float_t rsigma = float(i)/100.;
838 : // gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
839 : // gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
840 : // gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
841 : // }
842 :
843 : // //
844 : // for (Int_t i=3;i<10000;i++){
845 : // //
846 : // //
847 : // // inner sector
848 : // Float_t amp = float(i);
849 : // Float_t padlength =0.75;
850 : // gnoise1 = 0.0004/padlength;
851 : // Float_t nel = 0.268*amp;
852 : // Float_t nprim = 0.155*amp;
853 : // ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
854 : // glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
855 : // if (glandau1[i]>1) glandau1[i]=1;
856 : // glandau1[i]*=padlength*padlength/12.;
857 : // //
858 : // // outer short
859 : // padlength =1.;
860 : // gnoise2 = 0.0004/padlength;
861 : // nel = 0.3*amp;
862 : // nprim = 0.133*amp;
863 : // ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
864 : // glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
865 : // if (glandau2[i]>1) glandau2[i]=1;
866 : // glandau2[i]*=padlength*padlength/12.;
867 : // //
868 : // //
869 : // // outer long
870 : // padlength =1.5;
871 : // gnoise3 = 0.0004/padlength;
872 : // nel = 0.3*amp;
873 : // nprim = 0.133*amp;
874 : // ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
875 : // glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
876 : // if (glandau3[i]>1) glandau3[i]=1;
877 : // glandau3[i]*=padlength*padlength/12.;
878 : // //
879 : // }
880 : // ginit = kTRUE;
881 : // }
882 : // //
883 : // //
884 : // //
885 : // Int_t amp = int(TMath::Abs(cl->GetQ()));
886 : // if (amp>9999) {
887 : // seed->SetErrorY2(1.);
888 : // return 1.;
889 : // }
890 : // Float_t snoise2;
891 : // Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
892 : // Int_t ctype = cl->GetType();
893 : // Float_t padlength= GetPadPitchLength(seed->GetRow());
894 : // Double_t angle2 = seed->GetSnp()*seed->GetSnp();
895 : // angle2 = angle2/(1-angle2);
896 : // //
897 : // //cluster "quality"
898 : // Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
899 : // Float_t res;
900 : // //
901 : // if (fSectors==fInnerSec){
902 : // snoise2 = gnoise1;
903 : // res = ggg1[amp]*z+glandau1[amp]*angle2;
904 : // if (ctype==0) res *= gcor01[rsigmay];
905 : // if ((ctype>0)){
906 : // res+=0.002;
907 : // res*= gcorp[rsigmay];
908 : // }
909 : // }
910 : // else {
911 : // if (padlength<1.1){
912 : // snoise2 = gnoise2;
913 : // res = ggg2[amp]*z+glandau2[amp]*angle2;
914 : // if (ctype==0) res *= gcor02[rsigmay];
915 : // if ((ctype>0)){
916 : // res+=0.002;
917 : // res*= gcorp[rsigmay];
918 : // }
919 : // }
920 : // else{
921 : // snoise2 = gnoise3;
922 : // res = ggg3[amp]*z+glandau3[amp]*angle2;
923 : // if (ctype==0) res *= gcor02[rsigmay];
924 : // if ((ctype>0)){
925 : // res+=0.002;
926 : // res*= gcorp[rsigmay];
927 : // }
928 : // }
929 : // }
930 :
931 : // if (ctype<0){
932 : // res+=0.005;
933 : // res*=2.4; // overestimate error 2 times
934 : // }
935 : // res+= snoise2;
936 :
937 : // if (res<2*snoise2)
938 : // res = 2*snoise2;
939 :
940 : // seed->SetErrorY2(res);
941 : // return res;
942 :
943 :
944 : }
945 :
946 :
947 : //__________________________________________________________________________________
948 : Double_t AliTPCtracker::ErrZ2(AliTPCseed* seed, const AliTPCclusterMI * cl){
949 : //
950 : //
951 : // Use calibrated cluster error from OCDB
952 : //
953 0 : const AliTPCRecoParam* rp = AliTPCReconstructor::GetRecoParam();
954 0 : AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
955 : //
956 0 : Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
957 0 : Int_t ctype = cl->GetType();
958 0 : Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
959 : //
960 0 : double angle2 = seed->GetSnp()*seed->GetSnp();
961 0 : angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
962 0 : Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
963 0 : Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
964 0 : if (ctype<0) {
965 0 : errz2+=0.5; // edge cluster
966 0 : }
967 0 : errz2*=errz2;
968 : // additional systematic error on the cluster
969 0 : errz2 += AliTPCcalibDB::Instance()->GetTransform()->ErrZ2Syst(cl, seed->GetTgl());
970 0 : seed->SetErrorZ2(errz2);
971 : //
972 0 : return errz2;
973 :
974 :
975 :
976 : // //seed->SetErrorY2(0.1);
977 : // //return 0.1;
978 : // //calculate look-up table at the beginning
979 : // static Bool_t ginit = kFALSE;
980 : // static Float_t gnoise1,gnoise2,gnoise3;
981 : // static Float_t ggg1[10000];
982 : // static Float_t ggg2[10000];
983 : // static Float_t ggg3[10000];
984 : // static Float_t glandau1[10000];
985 : // static Float_t glandau2[10000];
986 : // static Float_t glandau3[10000];
987 : // //
988 : // static Float_t gcor01[1000];
989 : // static Float_t gcor02[1000];
990 : // static Float_t gcorp[1000];
991 : // //
992 :
993 : // //
994 : // if (ginit==kFALSE){
995 : // for (Int_t i=1;i<1000;i++){
996 : // Float_t rsigma = float(i)/100.;
997 : // gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
998 : // gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
999 : // gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
1000 : // }
1001 :
1002 : // //
1003 : // for (Int_t i=3;i<10000;i++){
1004 : // //
1005 : // //
1006 : // // inner sector
1007 : // Float_t amp = float(i);
1008 : // Float_t padlength =0.75;
1009 : // gnoise1 = 0.0004/padlength;
1010 : // Float_t nel = 0.268*amp;
1011 : // Float_t nprim = 0.155*amp;
1012 : // ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
1013 : // glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
1014 : // if (glandau1[i]>1) glandau1[i]=1;
1015 : // glandau1[i]*=padlength*padlength/12.;
1016 : // //
1017 : // // outer short
1018 : // padlength =1.;
1019 : // gnoise2 = 0.0004/padlength;
1020 : // nel = 0.3*amp;
1021 : // nprim = 0.133*amp;
1022 : // ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
1023 : // glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
1024 : // if (glandau2[i]>1) glandau2[i]=1;
1025 : // glandau2[i]*=padlength*padlength/12.;
1026 : // //
1027 : // //
1028 : // // outer long
1029 : // padlength =1.5;
1030 : // gnoise3 = 0.0004/padlength;
1031 : // nel = 0.3*amp;
1032 : // nprim = 0.133*amp;
1033 : // ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
1034 : // glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
1035 : // if (glandau3[i]>1) glandau3[i]=1;
1036 : // glandau3[i]*=padlength*padlength/12.;
1037 : // //
1038 : // }
1039 : // ginit = kTRUE;
1040 : // }
1041 : // //
1042 : // //
1043 : // //
1044 : // Int_t amp = int(TMath::Abs(cl->GetQ()));
1045 : // if (amp>9999) {
1046 : // seed->SetErrorY2(1.);
1047 : // return 1.;
1048 : // }
1049 : // Float_t snoise2;
1050 : // Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
1051 : // Int_t ctype = cl->GetType();
1052 : // Float_t padlength= GetPadPitchLength(seed->GetRow());
1053 : // //
1054 : // Double_t angle2 = seed->GetSnp()*seed->GetSnp();
1055 : // // if (angle2<0.6) angle2 = 0.6;
1056 : // angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
1057 : // //
1058 : // //cluster "quality"
1059 : // Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
1060 : // Float_t res;
1061 : // //
1062 : // if (fSectors==fInnerSec){
1063 : // snoise2 = gnoise1;
1064 : // res = ggg1[amp]*z+glandau1[amp]*angle2;
1065 : // if (ctype==0) res *= gcor01[rsigmaz];
1066 : // if ((ctype>0)){
1067 : // res+=0.002;
1068 : // res*= gcorp[rsigmaz];
1069 : // }
1070 : // }
1071 : // else {
1072 : // if (padlength<1.1){
1073 : // snoise2 = gnoise2;
1074 : // res = ggg2[amp]*z+glandau2[amp]*angle2;
1075 : // if (ctype==0) res *= gcor02[rsigmaz];
1076 : // if ((ctype>0)){
1077 : // res+=0.002;
1078 : // res*= gcorp[rsigmaz];
1079 : // }
1080 : // }
1081 : // else{
1082 : // snoise2 = gnoise3;
1083 : // res = ggg3[amp]*z+glandau3[amp]*angle2;
1084 : // if (ctype==0) res *= gcor02[rsigmaz];
1085 : // if ((ctype>0)){
1086 : // res+=0.002;
1087 : // res*= gcorp[rsigmaz];
1088 : // }
1089 : // }
1090 : // }
1091 :
1092 : // if (ctype<0){
1093 : // res+=0.002;
1094 : // res*=1.3;
1095 : // }
1096 : // if ((ctype<0) &&<70){
1097 : // res+=0.002;
1098 : // res*=1.3;
1099 : // }
1100 : // res += snoise2;
1101 : // if (res<2*snoise2)
1102 : // res = 2*snoise2;
1103 : // if (res>3) res =3;
1104 : // seed->SetErrorZ2(res);
1105 : // return res;
1106 : }
1107 :
1108 :
1109 :
1110 :
1111 :
1112 : void AliTPCtracker::RotateToLocal(AliTPCseed *seed)
1113 : {
1114 : //rotate to track "local coordinata
1115 0 : Float_t x = seed->GetX();
1116 0 : Float_t y = seed->GetY();
1117 0 : Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
1118 :
1119 0 : if (y > ymax) {
1120 0 : seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
1121 0 : if (!seed->Rotate(fSectors->GetAlpha()))
1122 0 : return;
1123 0 : } else if (y <-ymax) {
1124 0 : seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
1125 0 : if (!seed->Rotate(-fSectors->GetAlpha()))
1126 0 : return;
1127 : }
1128 :
1129 0 : }
1130 :
1131 :
1132 :
1133 : //_____________________________________________________________________________
1134 : Double_t AliTPCtracker::F1old(Double_t x1,Double_t y1,
1135 : Double_t x2,Double_t y2,
1136 : Double_t x3,Double_t y3) const
1137 : {
1138 : //-----------------------------------------------------------------
1139 : // Initial approximation of the track curvature
1140 : //-----------------------------------------------------------------
1141 0 : Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1142 0 : Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1143 0 : (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1144 0 : Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1145 0 : (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1146 :
1147 0 : Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1148 0 : if ( xr*xr+yr*yr<=0.00000000000001) return 100;
1149 0 : return -xr*yr/sqrt(xr*xr+yr*yr);
1150 0 : }
1151 :
1152 :
1153 :
1154 : //_____________________________________________________________________________
1155 : Double_t AliTPCtracker::F1(Double_t x1,Double_t y1,
1156 : Double_t x2,Double_t y2,
1157 : Double_t x3,Double_t y3) const
1158 : {
1159 : //-----------------------------------------------------------------
1160 : // Initial approximation of the track curvature
1161 : //-----------------------------------------------------------------
1162 5144 : x3 -=x1;
1163 2572 : x2 -=x1;
1164 2572 : y3 -=y1;
1165 2572 : y2 -=y1;
1166 : //
1167 2572 : Double_t det = x3*y2-x2*y3;
1168 2572 : if (TMath::Abs(det)<1e-10){
1169 0 : return 100;
1170 : }
1171 : //
1172 2572 : Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1173 2572 : Double_t x0 = x3*0.5-y3*u;
1174 2572 : Double_t y0 = y3*0.5+x3*u;
1175 2572 : Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1176 3854 : if (det<0) c2*=-1;
1177 : return c2;
1178 2572 : }
1179 :
1180 :
1181 : Double_t AliTPCtracker::F2(Double_t x1,Double_t y1,
1182 : Double_t x2,Double_t y2,
1183 : Double_t x3,Double_t y3) const
1184 : {
1185 : //-----------------------------------------------------------------
1186 : // Initial approximation of the track curvature
1187 : //-----------------------------------------------------------------
1188 5144 : x3 -=x1;
1189 2572 : x2 -=x1;
1190 2572 : y3 -=y1;
1191 2572 : y2 -=y1;
1192 : //
1193 2572 : Double_t det = x3*y2-x2*y3;
1194 2572 : if (TMath::Abs(det)<1e-10) {
1195 0 : return 100;
1196 : }
1197 : //
1198 2572 : Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1199 2572 : Double_t x0 = x3*0.5-y3*u;
1200 2572 : Double_t y0 = y3*0.5+x3*u;
1201 2572 : Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1202 3854 : if (det<0) c2*=-1;
1203 2572 : x0+=x1;
1204 2572 : x0*=c2;
1205 : return x0;
1206 2572 : }
1207 :
1208 :
1209 :
1210 : //_____________________________________________________________________________
1211 : Double_t AliTPCtracker::F2old(Double_t x1,Double_t y1,
1212 : Double_t x2,Double_t y2,
1213 : Double_t x3,Double_t y3) const
1214 : {
1215 : //-----------------------------------------------------------------
1216 : // Initial approximation of the track curvature times center of curvature
1217 : //-----------------------------------------------------------------
1218 0 : Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1219 0 : Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1220 0 : (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1221 0 : Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1222 0 : (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1223 :
1224 0 : Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1225 :
1226 0 : return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1227 : }
1228 :
1229 : //_____________________________________________________________________________
1230 : Double_t AliTPCtracker::F3(Double_t x1,Double_t y1,
1231 : Double_t x2,Double_t y2,
1232 : Double_t z1,Double_t z2) const
1233 : {
1234 : //-----------------------------------------------------------------
1235 : // Initial approximation of the tangent of the track dip angle
1236 : //-----------------------------------------------------------------
1237 5600 : return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1238 : }
1239 :
1240 :
1241 : Double_t AliTPCtracker::F3n(Double_t x1,Double_t y1,
1242 : Double_t x2,Double_t y2,
1243 : Double_t z1,Double_t z2, Double_t c) const
1244 : {
1245 : //-----------------------------------------------------------------
1246 : // Initial approximation of the tangent of the track dip angle
1247 : //-----------------------------------------------------------------
1248 :
1249 : // Double_t angle1;
1250 :
1251 : //angle1 = (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1252 : //
1253 944 : Double_t d = TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1254 472 : if (TMath::Abs(d*c*0.5)>1) return 0;
1255 472 : Double_t angle2 = asinf(d*c*0.5);
1256 :
1257 472 : angle2 = (z1-z2)*c/(angle2*2.);
1258 : return angle2;
1259 472 : }
1260 :
1261 : Bool_t AliTPCtracker::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
1262 : {//-----------------------------------------------------------------
1263 : // This function find proloncation of a track to a reference plane x=x2.
1264 : //-----------------------------------------------------------------
1265 :
1266 668 : Double_t dx=x2-x1;
1267 334 : Double_t c1=x[4]*x1 - x[2];
1268 334 : if (TMath::Abs(c1) >= 0.999) return kFALSE;
1269 334 : Double_t c2=x[4]*x2 - x[2];
1270 334 : if (TMath::Abs(c2) >= 0.999) return kFALSE;
1271 334 : Double_t r1=TMath::Sqrt((1.-c1)*(1.+c1)),r2=TMath::Sqrt((1.-c2)*(1.+c2));
1272 334 : y = x[0];
1273 334 : z = x[1];
1274 :
1275 334 : Double_t dy = dx*(c1+c2)/(r1+r2);
1276 : //
1277 334 : Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1278 334 : Double_t dz = x[3]*asinf(delta)/x[4];
1279 :
1280 334 : y+=dy;
1281 334 : z+=dz;
1282 :
1283 : return kTRUE;
1284 334 : }
1285 :
1286 : Bool_t AliTPCtracker::GetProlongationLine(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
1287 : {//-----------------------------------------------------------------
1288 : // This function find straight line prolongation of a track to a reference plane x=x2.
1289 : //-----------------------------------------------------------------
1290 :
1291 0 : if (TMath::Abs(x[2]) >= 0.999) return kFALSE;
1292 0 : Double_t c1=- x[2], dx2r = (x2-x1)/TMath::Sqrt((1.-c1)*(1.+c1));
1293 0 : y = x[0] + dx2r*c1;
1294 0 : z = x[1] + dx2r*x[3];
1295 : return kTRUE;
1296 0 : }
1297 :
1298 :
1299 : Int_t AliTPCtracker::LoadClusters (TTree *const tree)
1300 : {
1301 : // load clusters
1302 : //
1303 16 : fInput = tree;
1304 8 : return LoadClusters();
1305 : }
1306 :
1307 :
1308 : Int_t AliTPCtracker::LoadClusters(const TObjArray *arr)
1309 : {
1310 : //
1311 : // load clusters to the memory
1312 : AliTPCClustersRow *clrow = 0; //RS: why this new? new AliTPCClustersRow("AliTPCclusterMI");
1313 0 : Int_t lower = arr->LowerBound();
1314 0 : Int_t entries = arr->GetEntriesFast();
1315 :
1316 0 : AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1317 0 : AliTPCTransform *transform = calibDB->GetTransform() ;
1318 0 : transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
1319 0 : transform->SetCurrentTimeStamp( GetTimeStamp());
1320 0 : transform->SetCurrentRun( GetRunNumber() );
1321 :
1322 0 : AliWarning("Sector Change ins not checked in LoadClusters(const TObjArray *arr)");
1323 :
1324 0 : for (Int_t i=lower; i<entries; i++) {
1325 0 : clrow = (AliTPCClustersRow*) arr->At(i);
1326 0 : if(!clrow) continue;
1327 0 : TClonesArray* arr = clrow->GetArray();
1328 0 : if(!arr) continue;
1329 0 : int ncl = arr->GetEntriesFast();
1330 0 : if (ncl<1) continue;
1331 : //
1332 0 : Int_t sec,row;
1333 0 : fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
1334 :
1335 0 : for (Int_t icl=ncl; icl--;) {
1336 0 : Transform((AliTPCclusterMI*)(arr->At(icl)));
1337 : }
1338 : //
1339 : // RS: Check for possible sector change due to the distortions: TODO
1340 : //
1341 : AliTPCtrackerRow * tpcrow=0;
1342 : Int_t left=0;
1343 0 : if (sec<fkNIS*2){
1344 0 : tpcrow = &(fInnerSec[sec%fkNIS][row]);
1345 0 : left = sec/fkNIS;
1346 0 : }
1347 : else{
1348 0 : tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1349 0 : left = (sec-fkNIS*2)/fkNOS;
1350 : }
1351 0 : if (left ==0){
1352 0 : tpcrow->SetN1(ncl);
1353 0 : for (Int_t j=0;j<ncl;++j)
1354 0 : tpcrow->SetCluster1(j, *(AliTPCclusterMI*)(arr->At(j)));
1355 0 : }
1356 0 : if (left ==1){
1357 0 : tpcrow->SetN2(ncl);
1358 0 : for (Int_t j=0;j<ncl;++j)
1359 0 : tpcrow->SetCluster2(j, *(AliTPCclusterMI*)(arr->At(j)));
1360 0 : }
1361 0 : clrow->GetArray()->Clear(); // RS AliTPCclusterMI does not allocate memory
1362 0 : }
1363 : //
1364 : // delete clrow;
1365 0 : LoadOuterSectors();
1366 0 : LoadInnerSectors();
1367 0 : return 0;
1368 : }
1369 :
1370 : Int_t AliTPCtracker::LoadClusters(const TClonesArray *arr)
1371 : {
1372 : //
1373 : // load clusters to the memory from one
1374 : // TClonesArray
1375 : //
1376 : // RS: Check for possible sector change due to the distortions: TODO
1377 0 : AliWarning("Sector Change ins not checked in LoadClusters(const TClonesArray *arr)");
1378 : //
1379 :
1380 0 : AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1381 0 : AliTPCTransform *transform = calibDB->GetTransform() ;
1382 0 : transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
1383 0 : transform->SetCurrentTimeStamp( GetTimeStamp());
1384 0 : transform->SetCurrentRun( GetRunNumber() );
1385 : //
1386 : AliTPCclusterMI *clust=0;
1387 0 : Int_t count[72][96] = { {0} , {0} };
1388 :
1389 : // loop over clusters
1390 0 : for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1391 0 : clust = (AliTPCclusterMI*)arr->At(icl);
1392 0 : if(!clust) continue;
1393 : //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
1394 :
1395 : // transform clusters
1396 0 : Transform(clust);
1397 :
1398 : // count clusters per pad row
1399 0 : count[clust->GetDetector()][clust->GetRow()]++;
1400 0 : }
1401 :
1402 : // insert clusters to sectors
1403 0 : for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1404 0 : clust = (AliTPCclusterMI*)arr->At(icl);
1405 0 : if(!clust) continue;
1406 :
1407 0 : Int_t sec = clust->GetDetector();
1408 0 : Int_t row = clust->GetRow();
1409 :
1410 : // filter overlapping pad rows needed by HLT
1411 0 : if(sec<fkNIS*2) { //IROCs
1412 0 : if(row == 30) continue;
1413 : }
1414 : else { // OROCs
1415 0 : if(row == 27 || row == 76) continue;
1416 : }
1417 :
1418 : // Int_t left=0;
1419 0 : if (sec<fkNIS*2){
1420 : // left = sec/fkNIS;
1421 0 : fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fkParam);
1422 0 : }
1423 : else{
1424 : // left = (sec-fkNIS*2)/fkNOS;
1425 0 : fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fkParam);
1426 : }
1427 0 : }
1428 :
1429 : // Load functions must be called behind LoadCluster(TClonesArray*)
1430 : // needed by HLT
1431 : //LoadOuterSectors();
1432 : //LoadInnerSectors();
1433 :
1434 0 : return 0;
1435 0 : }
1436 :
1437 : Int_t AliTPCtracker::LoadClusters()
1438 : {
1439 : //
1440 : // load clusters to the memory
1441 24 : static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
1442 : //
1443 :
1444 8 : AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1445 8 : AliTPCTransform *transform = calibDB->GetTransform() ;
1446 8 : transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
1447 8 : transform->SetCurrentTimeStamp( GetTimeStamp());
1448 8 : transform->SetCurrentRun( GetRunNumber() );
1449 :
1450 : // TTree * tree = fClustersArray.GetTree();
1451 8 : AliInfo("LoadClusters()\n");
1452 :
1453 8 : fNClusters = 0;
1454 :
1455 8 : TTree * tree = fInput;
1456 8 : TBranch * br = tree->GetBranch("Segment");
1457 8 : br->SetAddress(&clrow);
1458 :
1459 : // Conversion of pad, row coordinates in local tracking coords.
1460 : // Could be skipped here; is already done in clusterfinder
1461 :
1462 8 : double cutZ2X = AliTPCReconstructor::GetPrimaryZ2XCut();
1463 8 : double cutZOutSector = AliTPCReconstructor::GetZOutSectorCut();
1464 8 : if (cutZOutSector>0 && AliTPCReconstructor::GetExtendedRoads())
1465 0 : cutZOutSector += AliTPCReconstructor::GetExtendedRoads()[1];
1466 : //
1467 8 : if (cutZ2X>0 || cutZOutSector>0) {
1468 0 : AliInfoF("Cut on cluster |Z/X| : %s, on cluster Z on wrong CE side: %s",
1469 : cutZ2X>0 ? Form("%.3f",cutZ2X) : "N/A",
1470 : cutZOutSector>0 ? Form("%.3f",cutZOutSector) : "N/A");
1471 0 : }
1472 8 : Int_t j=Int_t(tree->GetEntries());
1473 91474 : for (Int_t i=0; i<j; i++) {
1474 45729 : br->GetEntry(i);
1475 : //
1476 45729 : TClonesArray* clArr = clrow->GetArray();
1477 45729 : int nClus = clArr->GetEntriesFast();
1478 45729 : Int_t sec,row;
1479 45729 : fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
1480 221354 : for (Int_t icl=nClus; icl--;) Transform((AliTPCclusterMI*)(clArr->At(icl)));
1481 : //
1482 : AliTPCtrackerRow * tpcrow=0;
1483 : Int_t left=0;
1484 45729 : if (sec<fkNIS*2){
1485 18081 : tpcrow = &(fInnerSec[sec%fkNIS][row]);
1486 18081 : left = sec/fkNIS;
1487 18081 : }
1488 : else{
1489 27648 : tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1490 27648 : left = (sec-fkNIS*2)/fkNOS;
1491 : }
1492 : int nClusAdd = 0;
1493 45729 : if (left ==0){ // A side
1494 113132 : for (int k=0;k<nClus;k++) {
1495 33670 : const AliTPCclusterMI& cl = *((AliTPCclusterMI*)clArr->At(k));
1496 33670 : if (cutZOutSector>0 && cl.GetZ()<-cutZOutSector) continue;
1497 33670 : if (cutZ2X>0 && cl.GetZ()/cl.GetX() > cutZ2X) continue;
1498 33670 : tpcrow->SetCluster1(nClusAdd++, cl);
1499 33670 : }
1500 22896 : tpcrow->SetN1(nClusAdd);
1501 22896 : }
1502 45729 : if (left ==1){ // C side
1503 108222 : for (int k=0;k<nClus;k++) {
1504 31278 : const AliTPCclusterMI& cl = *((AliTPCclusterMI*)clArr->At(k));
1505 31278 : if (cutZOutSector>0 && cl.GetZ()>cutZOutSector) continue;
1506 31278 : if (cutZ2X>0 && cl.GetZ()/cl.GetX() < -cutZ2X) continue;
1507 31278 : tpcrow->SetCluster2(nClusAdd++, cl);
1508 31278 : }
1509 22833 : tpcrow->SetN2(nClusAdd);
1510 22833 : }
1511 45729 : fNClusters += nClusAdd;
1512 45729 : }
1513 : //
1514 : //clrow->Clear("C");
1515 8 : clrow->Clear(); // RS AliTPCclusterMI does not allocate memory
1516 8 : LoadOuterSectors();
1517 8 : LoadInnerSectors();
1518 :
1519 8 : cout << " =================================================================================================================================== " << endl;
1520 8 : cout << " AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection() = " << AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection() << endl;
1521 8 : cout << " AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection() = " << AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection() << endl;
1522 8 : cout << " =================================================================================================================================== " << endl;
1523 :
1524 8 : if (AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection()) ApplyTailCancellation();
1525 8 : if (AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection()!=0.) CalculateXtalkCorrection();
1526 8 : if (AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrection()!=0.) ApplyXtalkCorrection();
1527 : //if (AliTPCReconstructor::GetRecoParam()->GetUseOulierClusterFilter()) FilterOutlierClusters();
1528 :
1529 : /*
1530 : static int maxClus[18][2][kMaxRow]={0};
1531 : int maxAcc=0,nclEv=0, capacity=0;
1532 : for (int isec=0;isec<18;isec++) {
1533 : for (int irow=0;irow<kMaxRow;irow++) {
1534 : AliTPCtrackerRow * tpcrow = irow>62 ? &(fOuterSec[isec][irow-63]) : &(fInnerSec[isec][irow]);
1535 : maxClus[isec][0][irow] = TMath::Max(maxClus[isec][0][irow], tpcrow->GetN1());
1536 : maxClus[isec][1][irow] = TMath::Max(maxClus[isec][1][irow], tpcrow->GetN2());
1537 : maxAcc += maxClus[isec][0][irow]+maxClus[isec][1][irow];
1538 : nclEv += tpcrow->GetN();
1539 : capacity += tpcrow->GetClusters1()->Capacity();
1540 : capacity += tpcrow->GetClusters2()->Capacity();
1541 : }
1542 : }
1543 : printf("RS:AccumulatedSpace: %d for %d | pointers: %d\n",maxAcc,nclEv,capacity);
1544 : */
1545 8 : return 0;
1546 0 : }
1547 :
1548 : void AliTPCtracker::CalculateXtalkCorrection(){
1549 : //
1550 : // Calculate crosstalk estimate
1551 : //
1552 0 : TStopwatch sw;
1553 0 : sw.Start();
1554 : const Int_t nROCs = 72;
1555 : const Int_t nIterations=3; //
1556 : // 0.) reset crosstalk matrix
1557 : //
1558 0 : for (Int_t isector=0; isector<nROCs*4; isector++){ //set all ellemts of crosstalk matrix to 0
1559 0 : TMatrixD * crossTalkMatrix = (TMatrixD*)fCrossTalkSignalArray->At(isector);
1560 0 : if (crossTalkMatrix)(*crossTalkMatrix)*=0;
1561 : }
1562 :
1563 : //
1564 : // 1.) Filling part -- loop over clusters
1565 : //
1566 0 : Double_t missingChargeFactor= AliTPCReconstructor::GetRecoParam()->GetCrosstalkCorrectionMissingCharge();
1567 0 : for (Int_t iter=0; iter<nIterations;iter++){
1568 0 : for (Int_t isector=0; isector<36; isector++){ // loop over sectors
1569 0 : for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1570 0 : AliTPCtrackerSector §or= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1571 0 : Int_t nrows = sector.GetNRows();
1572 : Int_t sec=0;
1573 0 : if (isector<18) sec=isector+18*iside;
1574 0 : if (isector>=18) sec=18+isector+18*iside;
1575 0 : for (Int_t row = 0;row<nrows;row++){ // loop over rows
1576 : //
1577 : //
1578 0 : Int_t wireSegmentID = fkParam->GetWireSegment(sec,row);
1579 0 : Float_t nPadsPerSegment = (Float_t)(fkParam->GetNPadsPerSegment(wireSegmentID));
1580 0 : TMatrixD &crossTalkSignal = *((TMatrixD*)fCrossTalkSignalArray->At(sec));
1581 0 : TMatrixD &crossTalkSignalCache = *((TMatrixD*)fCrossTalkSignalArray->At(sec+nROCs*2)); // this is the cache value of the crosstalk from previous iteration
1582 0 : TMatrixD &crossTalkSignalBelow = *((TMatrixD*)fCrossTalkSignalArray->At(sec+nROCs));
1583 0 : Int_t nCols=crossTalkSignal.GetNcols();
1584 : //
1585 0 : AliTPCtrackerRow& tpcrow = sector[row];
1586 0 : Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1587 0 : if (iside>0) ncl=tpcrow.GetN2();
1588 0 : for (Int_t i=0;i<ncl;i++) { // loop over clusters
1589 0 : AliTPCclusterMI *clXtalk= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1590 :
1591 0 : Int_t timeBinXtalk = clXtalk->GetTimeBin();
1592 0 : Double_t rmsPadMin2=0.5*0.5+(fkParam->GetDiffT()*fkParam->GetDiffT())*(TMath::Abs((clXtalk->GetZ()-fkParam->GetZLength())))/(fkParam->GetPadPitchWidth(sec)*fkParam->GetPadPitchWidth(sec)); // minimal PRF width - 0.5 is the PRF in the pad units - we should et it from fkparam getters
1593 0 : Double_t rmsTimeMin2=1+(fkParam->GetDiffL()*fkParam->GetDiffL())*(TMath::Abs((clXtalk->GetZ()-fkParam->GetZLength())))/(fkParam->GetZWidth()*fkParam->GetZWidth()); // minimal PRF width - 1 is the TRF in the time bin units - we should et it from fkParam getters
1594 0 : Double_t rmsTime2 = clXtalk->GetSigmaZ2()/(fkParam->GetZWidth()*fkParam->GetZWidth());
1595 0 : Double_t rmsPad2 = clXtalk->GetSigmaY2()/(fkParam->GetPadPitchWidth(sec)*fkParam->GetPadPitchWidth(sec));
1596 0 : if (rmsPadMin2>rmsPad2){
1597 : rmsPad2=rmsPadMin2;
1598 0 : }
1599 0 : if (rmsTimeMin2>rmsTime2){
1600 : rmsTime2=rmsTimeMin2;
1601 0 : }
1602 :
1603 0 : Double_t norm= 2.*TMath::Exp(-1.0/(2.*rmsTime2))+2.*TMath::Exp(-4.0/(2.*rmsTime2))+1.;
1604 : Double_t qTotXtalk = 0.;
1605 : Double_t qTotXtalkMissing = 0.;
1606 0 : for (Int_t itb=timeBinXtalk-2, idelta=-2; itb<=timeBinXtalk+2; itb++,idelta++) {
1607 0 : if (itb<0 || itb>=nCols) continue;
1608 : Double_t missingCharge=0;
1609 0 : Double_t trf= TMath::Exp(-idelta*idelta/(2.*rmsTime2));
1610 0 : if (missingChargeFactor>0) {
1611 0 : for (Int_t dpad=-2; dpad<=2; dpad++){
1612 0 : Double_t qPad = clXtalk->GetMax()*TMath::Exp(-dpad*dpad/(2.*rmsPad2))*trf;
1613 0 : if (TMath::Nint(qPad-crossTalkSignalCache[wireSegmentID][itb])<=fkParam->GetZeroSup()){
1614 0 : missingCharge+=qPad+crossTalkSignalCache[wireSegmentID][itb];
1615 0 : }else{
1616 0 : missingCharge+=crossTalkSignalCache[wireSegmentID][itb];
1617 : }
1618 : }
1619 0 : }
1620 0 : qTotXtalk = clXtalk->GetQ()*trf/norm+missingCharge*missingChargeFactor;
1621 : qTotXtalkMissing = missingCharge;
1622 0 : crossTalkSignal[wireSegmentID][itb]+= qTotXtalk/nPadsPerSegment;
1623 0 : crossTalkSignalBelow[wireSegmentID][itb]+= qTotXtalkMissing/nPadsPerSegment;
1624 0 : } // end of time bin loop
1625 : } // end of cluster loop
1626 : } // end of rows loop
1627 : } // end of side loop
1628 : } // end of sector loop
1629 : //
1630 : // copy crosstalk matrix to cached used for next itteration
1631 : //
1632 : //
1633 : // 2.) dump the crosstalk matrices to tree for further investigation
1634 : // a.) to estimate fluctuation of pedestal in indiviula wire segments
1635 : // b.) to check correlation between regions
1636 : // c.) to check relative conribution of signal below threshold to crosstalk
1637 :
1638 0 : if (AliTPCReconstructor::StreamLevel()&kStreamCrosstalkMatrix) {
1639 0 : for (Int_t isector=0; isector<nROCs; isector++){ //set all ellemts of crosstalk matrix to 0
1640 0 : TMatrixD * crossTalkMatrix = (TMatrixD*)fCrossTalkSignalArray->At(isector);
1641 0 : TMatrixD * crossTalkMatrixBelow = (TMatrixD*)fCrossTalkSignalArray->At(isector+nROCs);
1642 0 : TMatrixD * crossTalkMatrixCache = (TMatrixD*)fCrossTalkSignalArray->At(isector+nROCs*2);
1643 0 : TVectorD vecAll(crossTalkMatrix->GetNrows());
1644 0 : TVectorD vecBelow(crossTalkMatrix->GetNrows());
1645 0 : TVectorD vecCache(crossTalkMatrixCache->GetNrows());
1646 : //
1647 0 : for (Int_t itime=0; itime<crossTalkMatrix->GetNcols(); itime++){
1648 0 : for (Int_t iwire=0; iwire<crossTalkMatrix->GetNrows(); iwire++){
1649 0 : vecAll[iwire]=(*crossTalkMatrix)(iwire,itime);
1650 0 : vecBelow[iwire]=(*crossTalkMatrixBelow)(iwire,itime);
1651 0 : vecCache[iwire]=(*crossTalkMatrixCache)(iwire,itime);
1652 : }
1653 0 : (*fDebugStreamer)<<"crosstalkMatrix"<<
1654 0 : "iter="<<iter<< //iteration
1655 0 : "sector="<<isector<< // sector
1656 0 : "itime="<<itime<< // time bin index
1657 0 : "vecAll.="<<&vecAll<< // crosstalk charge + charge below threshold
1658 0 : "vecCache.="<<&vecCache<< // crosstalk charge + charge below threshold
1659 0 : "vecBelow.="<<&vecBelow<< // crosstalk contribution from signal below threshold
1660 : "\n";
1661 : }
1662 0 : }
1663 0 : }
1664 0 : if (iter<nIterations-1) for (Int_t isector=0; isector<nROCs*2; isector++){ //set all ellemts of crosstalk matrix to 0
1665 0 : TMatrixD * crossTalkMatrix = (TMatrixD*)fCrossTalkSignalArray->At(isector);
1666 0 : TMatrixD * crossTalkMatrixCache = (TMatrixD*)fCrossTalkSignalArray->At(isector+nROCs*2);
1667 0 : if (crossTalkMatrix){
1668 0 : (*crossTalkMatrixCache)*=0;
1669 0 : (*crossTalkMatrixCache)+=(*crossTalkMatrix);
1670 0 : (*crossTalkMatrix)*=0;
1671 : }
1672 0 : }
1673 : }
1674 :
1675 0 : sw.Stop();
1676 0 : AliInfoF("timing: %e/%e real/cpu",sw.RealTime(),sw.CpuTime());
1677 : //
1678 0 : }
1679 :
1680 :
1681 :
1682 :
1683 : void AliTPCtracker::FilterOutlierClusters(){
1684 : //
1685 : // filter outlier clusters
1686 : //
1687 : /*
1688 : 1.)..... booking part
1689 : nSectors=72;
1690 : nTimeBins=fParam->Get....
1691 : TH2F hisTime("","", sector,0,sector, nTimeBins,0,nTimeBins);
1692 : TH2F hisPadRow("","", sector,0,sector, nPadRows,0,nPadRows);
1693 : 2.) .... filling part
1694 : .... cluster loop { hisTime.Fill(cluster->GetDetector(),cluster->GetTimeBin()); }
1695 :
1696 : 3.) ...filtering part
1697 : sector loop { calculate median,mean80 and rms80 of the nclusters per time bin; calculate median,mean80 and rms80 of the nclusters per par row; .... export values to the debug streamers - to decide which threshold to be used... }
1698 :
1699 : sector loop
1700 : { disable clusters in time bins > mean+ n rms80+ offsetTime disable clusters in padRow > mean+ n rms80+ offsetPadRow // how to dislable clusters? - new bit to introduce }
1701 : //
1702 : 4. Disabling clusters
1703 :
1704 : */
1705 :
1706 : //
1707 : // 1.) booking part
1708 : //
1709 : // AliTPCcalibDB *db=AliTPCcalibDB::Instance();
1710 0 : Int_t nSectors=AliTPCROC::Instance()->GetNSectors();
1711 : Int_t nTimeBins= 1100; // *Bug here - we should get NTimeBins from ALTRO - Parameters not relyable
1712 0 : Int_t nPadRows=(AliTPCROC::Instance()->GetNRows(0) + AliTPCROC::Instance()->GetNRows(36));
1713 : // parameters for filtering
1714 : const Double_t nSigmaCut=9.; // should be in recoParam ?
1715 : const Double_t offsetTime=100; // should be in RecoParam ? -
1716 : const Double_t offsetPadRow=300; // should be in RecoParam ?
1717 : const Double_t offsetTimeAccept=8; // should be in RecoParam ? - obtained as mean +1 rms in high IR pp
1718 0 : TH2F hisTime("hisSectorTime","hisSectorTime", nSectors,0,nSectors, nTimeBins,0,nTimeBins);
1719 0 : TH2F hisPadRow("hisSectorRow","hisSectorRow", nSectors,0,nSectors, nPadRows,0,nPadRows);
1720 : //
1721 : // 2.) Filling part -- loop over clusters
1722 : //
1723 0 : for (Int_t isector=0; isector<36; isector++){ // loop over sectors
1724 0 : for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1725 0 : AliTPCtrackerSector §or= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1726 0 : Int_t nrows = sector.GetNRows();
1727 0 : for (Int_t row = 0;row<nrows;row++){ // loop over rows
1728 0 : AliTPCtrackerRow& tpcrow = sector[row];
1729 0 : Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1730 0 : if (iside>0) ncl=tpcrow.GetN2();
1731 0 : for (Int_t i=0;i<ncl;i++) { // loop over clusters
1732 0 : AliTPCclusterMI *cluster= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1733 0 : hisTime.Fill(cluster->GetDetector(),cluster->GetTimeBin());
1734 0 : hisPadRow.Fill(cluster->GetDetector(),cluster->GetRow());
1735 : }
1736 : }
1737 : }
1738 : }
1739 :
1740 : //
1741 : // 3. Filtering part
1742 : //
1743 0 : TVectorD vecTime(nTimeBins);
1744 0 : TVectorD vecPadRow(nPadRows);
1745 0 : TVectorD vecMedianSectorTime(nSectors);
1746 0 : TVectorD vecRMSSectorTime(nSectors);
1747 0 : TVectorD vecMedianSectorTimeOut6(nSectors);
1748 0 : TVectorD vecMedianSectorTimeOut9(nSectors);//
1749 0 : TVectorD vecMedianSectorTimeOut(nSectors);//
1750 0 : TVectorD vecMedianSectorPadRow(nSectors);
1751 0 : TVectorD vecRMSSectorPadRow(nSectors);
1752 0 : TVectorD vecMedianSectorPadRowOut6(nSectors);
1753 0 : TVectorD vecMedianSectorPadRowOut9(nSectors);
1754 0 : TVectorD vecMedianSectorPadRowOut(nSectors);
1755 0 : TVectorD vecSectorOut6(nSectors);
1756 0 : TVectorD vecSectorOut9(nSectors);
1757 0 : TMatrixD matSectorCluster(nSectors,2);
1758 : //
1759 : // 3.a) median, rms calculations for hisTime
1760 : //
1761 0 : for (Int_t isec=0; isec<nSectors; isec++){
1762 0 : vecMedianSectorTimeOut6[isec]=0;
1763 0 : vecMedianSectorTimeOut9[isec]=0;
1764 0 : for (Int_t itime=0; itime<nTimeBins; itime++){
1765 0 : vecTime[itime]=hisTime.GetBinContent(isec+1, itime+1);
1766 : }
1767 0 : Double_t median= TMath::Mean(nTimeBins,vecTime.GetMatrixArray());
1768 0 : Double_t rms= TMath::RMS(nTimeBins,vecTime.GetMatrixArray());
1769 0 : vecMedianSectorTime[isec]=median;
1770 0 : vecRMSSectorTime[isec]=rms;
1771 0 : if ((AliTPCReconstructor::StreamLevel()&kStreamFilterClusterInfo)>0) AliInfo(TString::Format("Sector TimeStat: %d\t%8.0f\t%8.0f",isec,median,rms).Data());
1772 : //
1773 : // declare outliers
1774 0 : for (Int_t itime=0; itime<nTimeBins; itime++){
1775 0 : Double_t entries= hisTime.GetBinContent(isec+1, itime+1);
1776 0 : if (entries>median+6.*rms+offsetTime) {
1777 0 : vecMedianSectorTimeOut6[isec]+=1;
1778 0 : }
1779 0 : if (entries>median+9.*rms+offsetTime) {
1780 0 : vecMedianSectorTimeOut9[isec]+=1;
1781 0 : }
1782 : }
1783 : }
1784 : //
1785 : // 3.b) median, rms calculations for hisPadRow
1786 : //
1787 0 : for (Int_t isec=0; isec<nSectors; isec++){
1788 0 : vecMedianSectorPadRowOut6[isec]=0;
1789 0 : vecMedianSectorPadRowOut9[isec]=0;
1790 0 : for (Int_t ipadrow=0; ipadrow<nPadRows; ipadrow++){
1791 0 : vecPadRow[ipadrow]=hisPadRow.GetBinContent(isec+1, ipadrow+1);
1792 : }
1793 0 : Int_t nPadRowsSector= AliTPCROC::Instance()->GetNRows(isec);
1794 0 : Double_t median= TMath::Mean(nPadRowsSector,vecPadRow.GetMatrixArray());
1795 0 : Double_t rms= TMath::RMS(nPadRowsSector,vecPadRow.GetMatrixArray());
1796 0 : vecMedianSectorPadRow[isec]=median;
1797 0 : vecRMSSectorPadRow[isec]=rms;
1798 0 : if ((AliTPCReconstructor::StreamLevel()&kStreamFilterClusterInfo)>0) AliInfo(TString::Format("Sector PadRowStat: %d\t%8.0f\t%8.0f",isec,median,rms).Data());
1799 : //
1800 : // declare outliers
1801 0 : for (Int_t ipadrow=0; ipadrow<nPadRows; ipadrow++){
1802 0 : Double_t entries= hisPadRow.GetBinContent(isec+1, ipadrow+1);
1803 0 : if (entries>median+6.*rms+offsetPadRow) {
1804 0 : vecMedianSectorPadRowOut6[isec]+=1;
1805 0 : }
1806 0 : if (entries>median+9.*rms+offsetPadRow) {
1807 0 : vecMedianSectorPadRowOut9[isec]+=1;
1808 0 : }
1809 : }
1810 : }
1811 : //
1812 : // 3.c) filter outlier sectors
1813 : //
1814 0 : Double_t medianSectorTime = TMath::Median(nSectors, vecTime.GetMatrixArray());
1815 0 : Double_t mean69SectorTime, rms69SectorTime=0;
1816 0 : AliMathBase::EvaluateUni(nSectors, vecTime.GetMatrixArray(), mean69SectorTime,rms69SectorTime,69);
1817 0 : for (Int_t isec=0; isec<nSectors; isec++){
1818 0 : vecSectorOut6[isec]=0;
1819 0 : vecSectorOut9[isec]=0;
1820 0 : matSectorCluster(isec,0)=0;
1821 0 : matSectorCluster(isec,1)=0;
1822 0 : if (TMath::Abs(vecMedianSectorTime[isec])>(mean69SectorTime+6.*(rms69SectorTime+ offsetTimeAccept))) {
1823 0 : vecSectorOut6[isec]=1;
1824 0 : }
1825 0 : if (TMath::Abs(vecMedianSectorTime[isec])>(mean69SectorTime+9.*(rms69SectorTime+ offsetTimeAccept))){
1826 0 : vecSectorOut9[isec]=1;
1827 0 : }
1828 : }
1829 : // light version of export variable
1830 0 : Int_t filteredSector= vecSectorOut9.Sum(); // light version of export variable
1831 0 : Int_t filteredSectorTime= vecMedianSectorTimeOut9.Sum();
1832 0 : Int_t filteredSectorPadRow= vecMedianSectorPadRowOut9.Sum();
1833 0 : if (fEvent) if (fEvent->GetHeader()){
1834 0 : fEvent->GetHeader()->SetTPCNoiseFilterCounter(0,TMath::Min(filteredSector,255));
1835 0 : fEvent->GetHeader()->SetTPCNoiseFilterCounter(1,TMath::Min(filteredSectorTime,255));
1836 0 : fEvent->GetHeader()->SetTPCNoiseFilterCounter(2,TMath::Min(filteredSectorPadRow,255));
1837 0 : }
1838 :
1839 : //
1840 : // 4. Disabling clusters in outlier layers
1841 : //
1842 0 : Int_t counterAll=0;
1843 0 : Int_t counterOut=0;
1844 0 : for (Int_t isector=0; isector<36; isector++){ // loop over sectors
1845 0 : for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
1846 0 : AliTPCtrackerSector §or= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
1847 0 : Int_t nrows = sector.GetNRows();
1848 0 : for (Int_t row = 0;row<nrows;row++){ // loop over rows
1849 0 : AliTPCtrackerRow& tpcrow = sector[row];
1850 0 : Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
1851 0 : if (iside>0) ncl=tpcrow.GetN2();
1852 0 : for (Int_t i=0;i<ncl;i++) { // loop over clusters
1853 0 : AliTPCclusterMI *cluster= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
1854 0 : Double_t medianTime=vecMedianSectorTime[cluster->GetDetector()];
1855 0 : Double_t medianPadRow=vecMedianSectorPadRow[cluster->GetDetector()];
1856 0 : Double_t rmsTime=vecRMSSectorTime[cluster->GetDetector()];
1857 0 : Double_t rmsPadRow=vecRMSSectorPadRow[cluster->GetDetector()];
1858 0 : Int_t entriesPadRow=hisPadRow.GetBinContent(cluster->GetDetector()+1, cluster->GetRow()+1);
1859 0 : Int_t entriesTime=hisTime.GetBinContent(cluster->GetDetector()+1, cluster->GetTimeBin()+1);
1860 : Bool_t isOut=kFALSE;
1861 0 : if (vecSectorOut9[cluster->GetDetector()]>0.5) {
1862 : isOut=kTRUE;
1863 0 : }
1864 :
1865 0 : if (entriesTime>medianTime+nSigmaCut*rmsTime+offsetTime) {
1866 : isOut=kTRUE;
1867 0 : vecMedianSectorTimeOut[cluster->GetDetector()]++;
1868 0 : }
1869 0 : if (entriesPadRow>medianPadRow+nSigmaCut*rmsPadRow+offsetPadRow) {
1870 : isOut=kTRUE;
1871 0 : vecMedianSectorPadRowOut[cluster->GetDetector()]++;
1872 0 : }
1873 0 : counterAll++;
1874 0 : matSectorCluster(cluster->GetDetector(),0)+=1;
1875 0 : if (isOut){
1876 0 : cluster->Disable();
1877 0 : counterOut++;
1878 0 : matSectorCluster(cluster->GetDetector(),1)+=1;
1879 0 : }
1880 : }
1881 : }
1882 : }
1883 : }
1884 0 : for (Int_t isec=0; isec<nSectors; isec++){
1885 0 : if ((AliTPCReconstructor::StreamLevel()&kStreamFilterClusterInfo)>0) AliInfo(TString::Format("Sector Stat: %d\t%8.0f\t%8.0f",isec,matSectorCluster(isec,1),matSectorCluster(isec,0)).Data());
1886 : }
1887 : //
1888 : // dump info to streamer - for later tuning of cuts
1889 : //
1890 0 : if ((AliTPCReconstructor::StreamLevel()&kStreamFilterClusterInfo)>0) { // stream TPC data ouliers filtering infomation
1891 0 : AliLog::Flush();
1892 0 : AliInfo(TString::Format("Cluster counter: (%d/%d) (Filtered/All)",counterOut,counterAll).Data());
1893 0 : for (Int_t iSec=0; iSec<nSectors; iSec++){
1894 0 : if (vecSectorOut9[iSec]>0 || matSectorCluster(iSec,1)>0) {
1895 0 : AliInfo(TString::Format("Filtered sector\t%d",iSec).Data());
1896 0 : Double_t vecMedTime =TMath::Median(72,vecMedianSectorTime.GetMatrixArray());
1897 0 : Double_t vecMedPadRow =TMath::Median(72,vecMedianSectorPadRow.GetMatrixArray());
1898 0 : Double_t vecMedCluster=(counterAll-counterOut)/72;
1899 0 : AliInfo(TString::Format("VecMedianSectorTime\t(%4.4f/%4.4f/%4.4f)", vecMedianSectorTimeOut[iSec],vecMedianSectorTime[iSec],vecMedTime).Data());
1900 0 : AliInfo(TString::Format("VecMedianSectorPadRow\t(%4.4f/%4.4f/%4.4f)", vecMedianSectorPadRowOut[iSec],vecMedianSectorPadRow[iSec],vecMedPadRow).Data());
1901 0 : AliInfo(TString::Format("MatSectorCluster\t(%4.4f/%4.4f/%4.4f)\n", matSectorCluster(iSec,1), matSectorCluster(iSec,0), vecMedCluster).Data());
1902 0 : AliLog::Flush();
1903 0 : }
1904 : }
1905 0 : AliLog::Flush();
1906 0 : Int_t eventNr = fEvent->GetEventNumberInFile();
1907 0 : (*fDebugStreamer)<<"filterClusterInfo"<<
1908 : // minimal set variables for the ESDevent
1909 0 : "eventNr="<<eventNr<<
1910 0 : "counterAll="<<counterAll<<
1911 0 : "counterOut="<<counterOut<<
1912 0 : "matSectotCluster.="<<&matSectorCluster<< //
1913 : //
1914 0 : "filteredSector="<<filteredSector<< // counter filtered sectors
1915 0 : "filteredSectorTime="<<filteredSectorTime<< // counter filtered time bins
1916 0 : "filteredSectorPadRow="<<filteredSectorPadRow<< // counter filtered pad-rows
1917 : // per sector outlier information
1918 0 : "medianSectorTime="<<medianSectorTime<< // median number of clusters per sector/timebin
1919 0 : "mean69SectorTime="<<mean69SectorTime<< // LTM statistic mean of clusters per sector/timebin
1920 0 : "rms69SectorTime="<<rms69SectorTime<< // LTM statistic RMS of clusters per sector/timebin
1921 0 : "vecSectorOut6.="<<&vecSectorOut6<< // flag array sector - 6 sigma +accept margin outlier
1922 0 : "vecSectorOut9.="<<&vecSectorOut9<< // flag array sector - 9 sigma + accept margin outlier
1923 : // per sector/timebin outlier detection
1924 0 : "vecMedianSectorTime.="<<&vecMedianSectorTime<<
1925 0 : "vecRMSSectorTime.="<<&vecRMSSectorTime<<
1926 0 : "vecMedianSectorTimeOut6.="<<&vecMedianSectorTimeOut6<<
1927 0 : "vecMedianSectorTimeOut9.="<<&vecMedianSectorTimeOut9<<
1928 0 : "vecMedianSectorTimeOut0.="<<&vecMedianSectorTimeOut<<
1929 : // per sector/pad-row outlier detection
1930 0 : "vecMedianSectorPadRow.="<<&vecMedianSectorPadRow<<
1931 0 : "vecRMSSectorPadRow.="<<&vecRMSSectorPadRow<<
1932 0 : "vecMedianSectorPadRowOut6.="<<&vecMedianSectorPadRowOut6<<
1933 0 : "vecMedianSectorPadRowOut9.="<<&vecMedianSectorPadRowOut9<<
1934 0 : "vecMedianSectorPadRowOut9.="<<&vecMedianSectorPadRowOut<<
1935 : "\n";
1936 0 : ((*fDebugStreamer)<<"filterClusterInfo").GetTree()->Write();
1937 0 : fDebugStreamer->GetFile()->Flush();
1938 0 : }
1939 0 : }
1940 :
1941 : void AliTPCtracker::UnloadClusters()
1942 : {
1943 : //
1944 : // unload clusters from the memory
1945 : //
1946 16 : Int_t nrows = fOuterSec->GetNRows();
1947 304 : for (Int_t sec = 0;sec<fkNOS;sec++)
1948 27936 : for (Int_t row = 0;row<nrows;row++){
1949 13824 : AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1950 : // if (tpcrow){
1951 : // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1952 : // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1953 : //}
1954 13824 : tpcrow->ResetClusters();
1955 : }
1956 : //
1957 8 : nrows = fInnerSec->GetNRows();
1958 304 : for (Int_t sec = 0;sec<fkNIS;sec++)
1959 18432 : for (Int_t row = 0;row<nrows;row++){
1960 9072 : AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1961 : //if (tpcrow){
1962 : // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1963 : //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1964 : //}
1965 9072 : tpcrow->ResetClusters();
1966 : }
1967 :
1968 8 : fNClusters = 0;
1969 : return ;
1970 8 : }
1971 :
1972 : void AliTPCtracker::FillClusterArray(TObjArray* array) const{
1973 : //
1974 : // Filling cluster to the array - For visualization purposes
1975 : //
1976 : Int_t nrows=0;
1977 0 : nrows = fOuterSec->GetNRows();
1978 0 : for (Int_t sec = 0;sec<fkNOS;sec++)
1979 0 : for (Int_t row = 0;row<nrows;row++){
1980 0 : AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1981 0 : if (!tpcrow) continue;
1982 0 : for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1983 0 : array->AddLast((TObject*)((*tpcrow)[icl]));
1984 : }
1985 0 : }
1986 0 : nrows = fInnerSec->GetNRows();
1987 0 : for (Int_t sec = 0;sec<fkNIS;sec++)
1988 0 : for (Int_t row = 0;row<nrows;row++){
1989 0 : AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1990 0 : if (!tpcrow) continue;
1991 0 : for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1992 0 : array->AddLast((TObject*)(*tpcrow)[icl]);
1993 : }
1994 0 : }
1995 0 : }
1996 :
1997 :
1998 : void AliTPCtracker::Transform(AliTPCclusterMI * cluster){
1999 : //
2000 : // transformation
2001 : //
2002 129896 : const double kMaxY2X = AliTPCTransform::GetMaxY2X(); // tg of sector angular span
2003 64948 : const double kSinSect = TMath::Sin(TMath::Pi()/9), kCosSect = TMath::Cos(TMath::Pi()/9);
2004 : //
2005 64948 : AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
2006 64948 : AliTPCTransform *transform = calibDB->GetTransform() ;
2007 64948 : if (!transform) {
2008 0 : AliFatal("Tranformations not in calibDB");
2009 0 : return;
2010 : }
2011 : // if (!transform->GetCurrentRecoParam()) transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
2012 64948 : Double_t x[3]={static_cast<Double_t>(cluster->GetRow()),static_cast<Double_t>(cluster->GetPad()),static_cast<Double_t>(cluster->GetTimeBin())};
2013 64948 : Int_t idROC = cluster->GetDetector();
2014 64948 : transform->Transform(x,&idROC,0,1);
2015 64948 : const float* clCorr = transform->GetLastMapCorrection();
2016 64948 : const float* clCorrRef = transform->GetLastMapCorrectionRef();
2017 : //
2018 129896 : cluster->SetDistortions(clCorr[0]-clCorrRef[0],
2019 64948 : clCorr[1]-clCorrRef[1],
2020 64948 : clCorr[2]-clCorrRef[2]); // memorize distortions (difference to reference one)
2021 : // store the dispersion difference
2022 64948 : cluster->SetDistortionDispersion(clCorr[3]); // ref error is already subtracted
2023 : //
2024 64948 : cluster->SetX(x[0]);
2025 64948 : cluster->SetY(x[1]);
2026 64948 : cluster->SetZ(x[2]);
2027 : // in debug mode check the transformation
2028 : //
2029 64948 : if ((AliTPCReconstructor::StreamLevel()&kStreamTransform)>0) {
2030 0 : Float_t gx[3];
2031 0 : cluster->GetGlobalXYZ(gx);
2032 0 : Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
2033 0 : TTreeSRedirector &cstream = *fDebugStreamer;
2034 0 : Int_t timeStamp=transform->GetCurrentTimeStamp();
2035 0 : float* nCclCorr = (float*)transform->GetLastMapCorrection();
2036 0 : float* nCclCorrRef = (float*)transform->GetLastMapCorrectionRef();
2037 0 : transform->SetDebugStreamer(fDebugStreamer);
2038 :
2039 0 : cstream<<"Transform"<< // needed for debugging of the cluster transformation, resp. used for later visualization
2040 0 : "event="<<event<<
2041 0 : "timeStamp="<<timeStamp<<
2042 0 : "x0="<<x[0]<<
2043 0 : "x1="<<x[1]<<
2044 0 : "x2="<<x[2]<<
2045 0 : "gx0="<<gx[0]<<
2046 0 : "gx1="<<gx[1]<<
2047 0 : "gx2="<<gx[2]<<
2048 0 : "dx="<<nCclCorr[0]<<
2049 0 : "dy="<<nCclCorr[1]<<
2050 0 : "dz="<<nCclCorr[2]<<
2051 0 : "dxRef="<<nCclCorrRef[0]<<
2052 0 : "dyRef="<<nCclCorrRef[1]<<
2053 0 : "dzRef="<<nCclCorrRef[2]<<
2054 0 : "Cl.="<<cluster<<
2055 : "\n";
2056 0 : }
2057 : // The old stuff:
2058 : //
2059 : //
2060 : //
2061 : //if (!fkParam->IsGeoRead()) fkParam->ReadGeoMatrices();
2062 129896 : if (AliTPCReconstructor::GetRecoParam()->GetUseSectorAlignment() && (!calibDB->HasAlignmentOCDB())){
2063 64948 : TGeoHMatrix *mat = fkParam->GetClusterMatrix(cluster->GetDetector());
2064 : //TGeoHMatrix mat;
2065 64948 : Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
2066 64948 : Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
2067 129896 : if (mat) mat->LocalToMaster(pos,posC);
2068 : else{
2069 : // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
2070 : }
2071 64948 : cluster->SetX(posC[0]);
2072 64948 : cluster->SetY(posC[1]);
2073 64948 : cluster->SetZ(posC[2]);
2074 64948 : }
2075 129896 : }
2076 :
2077 : void AliTPCtracker::ApplyXtalkCorrection(){
2078 : //
2079 : // ApplyXtalk correction
2080 : // Loop over all clusters
2081 : // add to each cluster signal corresponding to common Xtalk mode for given time bin at given wire segment
2082 : // cluster loop
2083 0 : TStopwatch sw;
2084 0 : sw.Start();
2085 0 : for (Int_t isector=0; isector<36; isector++){ //loop tracking sectors
2086 0 : for (Int_t iside=0; iside<2; iside++){ // loop over sides A/C
2087 0 : AliTPCtrackerSector §or= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
2088 0 : Int_t nrows = sector.GetNRows();
2089 0 : for (Int_t row = 0;row<nrows;row++){ // loop over rows
2090 0 : AliTPCtrackerRow& tpcrow = sector[row]; // row object
2091 0 : Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
2092 0 : if (iside>0) ncl=tpcrow.GetN2();
2093 0 : Int_t xSector=0; // sector number in the TPC convention 0-72
2094 0 : if (isector<18){ //if IROC
2095 0 : xSector=isector+(iside>0)*18;
2096 0 : }else{
2097 0 : xSector=isector+18; // isector -18 +36
2098 0 : if (iside>0) xSector+=18;
2099 : }
2100 0 : TMatrixD &crossTalkMatrix= *((TMatrixD*)fCrossTalkSignalArray->At(xSector));
2101 0 : Int_t wireSegmentID = fkParam->GetWireSegment(xSector,row);
2102 0 : for (Int_t i=0;i<ncl;i++) {
2103 0 : AliTPCclusterMI *cluster= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
2104 0 : Int_t iTimeBin=TMath::Nint(cluster->GetTimeBin());
2105 0 : Double_t xTalk= crossTalkMatrix[wireSegmentID][iTimeBin];
2106 0 : cluster->SetMax(cluster->GetMax()+xTalk);
2107 : const Double_t kDummy=4;
2108 0 : Double_t sumxTalk=xTalk*kDummy; // should be calculated via time response function
2109 0 : cluster->SetQ(cluster->GetQ()+sumxTalk);
2110 :
2111 :
2112 0 : if ((AliTPCReconstructor::StreamLevel()&kStreamXtalk)>0) { // flag: stream crosstalk correctio as applied to cluster
2113 0 : TTreeSRedirector &cstream = *fDebugStreamer;
2114 0 : if (gRandom->Rndm() > 0.){
2115 0 : cstream<<"Xtalk"<<
2116 0 : "isector=" << isector << // sector [0,36]
2117 0 : "iside=" << iside << // side A or C
2118 0 : "row=" << row << // padrow
2119 0 : "i=" << i << // index of the cluster
2120 0 : "xSector=" << xSector << // sector [0,72]
2121 0 : "wireSegmentID=" << wireSegmentID << // anode wire segment id [0,10]
2122 0 : "iTimeBin=" << iTimeBin << // timebin of the corrected cluster
2123 0 : "xTalk=" << xTalk << // Xtalk contribution added to Qmax
2124 0 : "sumxTalk=" << sumxTalk << // Xtalk contribution added to Qtot (roughly 3*Xtalk)
2125 0 : "cluster.=" << cluster << // corrected cluster object
2126 : "\n";
2127 : }
2128 0 : }// dump the results to the debug streamer if in debug mode
2129 0 : }
2130 0 : }
2131 : }
2132 : }
2133 0 : sw.Stop();
2134 0 : AliInfoF("timing: %e/%e real/cpu",sw.RealTime(),sw.CpuTime());
2135 : //
2136 0 : }
2137 :
2138 : void AliTPCtracker::ApplyTailCancellation(){
2139 : //
2140 : // Correct the cluster charge for the ion tail effect
2141 : // The TimeResponse function accessed via AliTPCcalibDB (TPC/Calib/IonTail)
2142 : //
2143 0 : TStopwatch sw;
2144 0 : sw.Start();
2145 : // Retrieve
2146 0 : TObjArray *ionTailArr = (TObjArray*)AliTPCcalibDB::Instance()->GetIonTailArray();
2147 0 : if (!ionTailArr) {AliFatal("TPC - Missing IonTail OCDB object");}
2148 0 : TObject *rocFactorIROC = ionTailArr->FindObject("factorIROC");
2149 0 : TObject *rocFactorOROC = ionTailArr->FindObject("factorOROC");
2150 0 : Float_t factorIROC = (atof(rocFactorIROC->GetTitle()));
2151 0 : Float_t factorOROC = (atof(rocFactorOROC->GetTitle()));
2152 :
2153 : // find the number of clusters for the whole TPC (nclALL)
2154 0 : Int_t nclALL=0;
2155 0 : for (Int_t isector=0; isector<36; isector++){
2156 0 : AliTPCtrackerSector §or= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
2157 0 : nclALL += sector.GetNClInSector(0);
2158 0 : nclALL += sector.GetNClInSector(1);
2159 : }
2160 :
2161 : //RS changed from heap allocation in the loop to stack allocation
2162 0 : TGraphErrors * graphRes[20];
2163 0 : Float_t indexAmpGraphs[20];
2164 : // AliTPCclusterMI* rowClusterArray[kMaxClusterPerRow]; // caches clusters for each row // RS avoid trashing the heap
2165 :
2166 : // start looping over all clusters
2167 0 : for (Int_t iside=0; iside<2; iside++){ // loop over sides
2168 : //
2169 : //
2170 0 : for (Int_t secType=0; secType<2; secType++){ //loop over inner or outer sector
2171 : // cache experimantal tuning factor for the different chamber type
2172 0 : const Float_t ampfactor = (secType==0)?factorIROC:factorOROC;
2173 : // std::cout << " ampfactor = " << ampfactor << std::endl;
2174 : //
2175 0 : for (Int_t sec = 0;sec<fkNOS;sec++){ //loop overs sectors
2176 : //
2177 : //
2178 : // Cache time response functions and their positons to COG of the cluster
2179 : // TGraphErrors ** graphRes = new TGraphErrors *[20]; // RS avoid heap allocations if stack can be used
2180 : // Float_t * indexAmpGraphs = new Float_t[20]; // RS Moved outside of the loop
2181 0 : memset(graphRes,0,20*sizeof(TGraphErrors*));
2182 0 : memset(indexAmpGraphs,0,20*sizeof(float));
2183 : //for (Int_t icache=0; icache<20; icache++) //RS
2184 : //{
2185 : // graphRes[icache] = NULL;
2186 : // indexAmpGraphs[icache] = 0;
2187 : // }
2188 : ///////////////////////////// --> position fo sie loop
2189 0 : if (!AliTPCcalibDB::Instance()->GetTailcancelationGraphs(sec+36*secType+18*iside,graphRes,indexAmpGraphs))
2190 : {
2191 : continue;
2192 : }
2193 :
2194 : // set time range from graph
2195 0 : const Int_t timeRangeMax=graphRes[0]?graphRes[0]->GetN():600;
2196 : // std::cout << " timeRangeMax = " << timeRangeMax << std::endl;
2197 :
2198 0 : AliTPCtrackerSector §or= (secType==0)?fInnerSec[sec]:fOuterSec[sec];
2199 0 : Int_t nrows = sector.GetNRows(); // number of rows
2200 0 : Int_t nclSector = sector.GetNClInSector(iside); // ncl per sector to be used for debugging
2201 :
2202 0 : for (Int_t row = 0;row<nrows;row++){ // loop over rows
2203 :
2204 0 : AliTPCtrackerRow& tpcrow = sector[row]; // row object
2205 0 : Int_t ncl = tpcrow.GetN1(); // number of clusters in the row
2206 0 : if (iside>0) ncl=tpcrow.GetN2();
2207 :
2208 : // Order clusters in time for the proper correction of ion tail
2209 0 : Float_t qTotArray[ncl]; // arrays to be filled with modified Qtot and Qmax values in order to avoid float->int conversion
2210 0 : Float_t qMaxArray[ncl];
2211 0 : Int_t sortedClusterIndex[ncl];
2212 0 : Float_t sortedClusterTimeBin[ncl];
2213 : //TObjArray *rowClusterArray = new TObjArray(ncl); // cache clusters for each row // RS avoid trashing the heap
2214 0 : AliTPCclusterMI* rowClusterArray[ncl]; // caches clusters for each row // RS avoid trashing the heap
2215 : // memset(rowClusterArray,0,sizeof(AliTPCclusterMI*)*ncl); //.Clear();
2216 : //if (rowClusterArray.GetSize()<ncl) rowClusterArray.Expand(ncl);
2217 0 : for (Int_t i=0;i<ncl;i++)
2218 : {
2219 0 : qTotArray[i]=0;
2220 0 : qMaxArray[i]=0;
2221 0 : sortedClusterIndex[i]=i;
2222 0 : AliTPCclusterMI *rowcl= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
2223 0 : rowClusterArray[i] = rowcl;
2224 : //if (rowcl) {
2225 : // rowClusterArray.AddAt(rowcl,i);
2226 : //} else {
2227 : // rowClusterArray.RemoveAt(i);
2228 : //}
2229 : // Fill the timebin info to the array in order to sort wrt tb
2230 0 : if (!rowcl) {
2231 0 : sortedClusterTimeBin[i]=0.0;
2232 0 : } else {
2233 0 : sortedClusterTimeBin[i] = rowcl->GetTimeBin();
2234 : }
2235 :
2236 : }
2237 0 : TMath::Sort(ncl,sortedClusterTimeBin,sortedClusterIndex,kFALSE); // sort clusters in time
2238 :
2239 : // Main cluster correction loops over clusters
2240 0 : for (Int_t icl0=0; icl0<ncl;icl0++){ // first loop over clusters
2241 :
2242 0 : AliTPCclusterMI *cl0= rowClusterArray[sortedClusterIndex[icl0]]; //RS static_cast<AliTPCclusterMI*>(rowClusterArray.At(sortedClusterIndex[icl0]));
2243 :
2244 0 : if (!cl0) continue;
2245 0 : Int_t nclPad=0;
2246 : //for (Int_t icl1=0; icl1<ncl;icl1++){ // second loop over clusters
2247 : // RS: time increases with index since sorted -> cl0->GetTimeBin()>cl1->GetTimeBin() means that icl0>icl1
2248 0 : for (Int_t icl1=0; icl1<icl0;icl1++){ // second loop over clusters
2249 0 : AliTPCclusterMI *cl1= rowClusterArray[sortedClusterIndex[icl1]];//RS static_cast<AliTPCclusterMI*>(rowClusterArray.At(sortedClusterIndex[icl1]));
2250 0 : if (!cl1) continue;
2251 : // RS no needed with proper loop organization
2252 : //if (cl0->GetTimeBin()<= cl1->GetTimeBin()) continue; // no contibution to the tail if later
2253 :
2254 0 : int dpad = TMath::Abs(cl0->GetPad()-cl1->GetPad());
2255 0 : if (dpad>4) continue; // no contribution if far away in pad direction
2256 :
2257 : // RS no point in iterating further with sorted clusters once large distance reached
2258 0 : if (cl0->GetTimeBin()-cl1->GetTimeBin()>=timeRangeMax) continue; // out of the range of response function
2259 :
2260 : // RS: what about dpad=4?
2261 0 : if (dpad<4) nclPad++; // count ncl for every pad for debugging
2262 :
2263 : // Get the correction values for Qmax and Qtot and find total correction for a given cluster
2264 0 : Double_t ionTailMax=0.;
2265 0 : Double_t ionTailTotal=0.;
2266 0 : GetTailValue(ampfactor,ionTailMax,ionTailTotal,graphRes,indexAmpGraphs,cl0,cl1);
2267 0 : ionTailMax=TMath::Abs(ionTailMax);
2268 0 : ionTailTotal=TMath::Abs(ionTailTotal);
2269 0 : qTotArray[icl0]+=ionTailTotal;
2270 0 : qMaxArray[icl0]+=ionTailMax;
2271 :
2272 : // Dump some info for debugging while clusters are being corrected
2273 0 : if ((AliTPCReconstructor::StreamLevel()&kStreamIonTail)>0) { // flag: stream ion tail correction as applied to cluster
2274 0 : TTreeSRedirector &cstream = *fDebugStreamer;
2275 0 : if (gRandom->Rndm() > 0.999){
2276 0 : cstream<<"IonTail"<<
2277 0 : "cl0.=" <<cl0 << // cluster 0 (to be corrected)
2278 0 : "cl1.=" <<cl1 << // cluster 1 (previous cluster)
2279 0 : "ionTailTotal=" <<ionTailTotal << // ion Tail from cluster 1 contribution to cluster0
2280 0 : "ionTailMax=" <<ionTailMax << // ion Tail from cluster 1 contribution to cluster0
2281 : "\n";
2282 : }
2283 0 : }// dump the results to the debug streamer if in debug mode
2284 :
2285 0 : }//end of second loop over clusters
2286 :
2287 : // Set corrected values of the corrected cluster
2288 0 : cl0->SetQ(TMath::Nint(Float_t(cl0->GetQ())+Float_t(qTotArray[icl0])));
2289 0 : cl0->SetMax(TMath::Nint(Float_t(cl0->GetMax())+qMaxArray[icl0]));
2290 :
2291 : // Dump some info for debugging after clusters are corrected
2292 0 : if ((AliTPCReconstructor::StreamLevel()&kStreamIonTail)>0) {
2293 0 : TTreeSRedirector &cstream = *fDebugStreamer;
2294 0 : if (gRandom->Rndm() > 0.999){
2295 0 : cstream<<"IonTailCorrected"<<
2296 0 : "cl0.=" << cl0 << // cluster 0 with huge Qmax
2297 0 : "ionTailTotalPerCluster=" << qTotArray[icl0] <<
2298 0 : "ionTailMaxPerCluster=" << qMaxArray[icl0] <<
2299 0 : "nclALL=" << nclALL <<
2300 0 : "nclSector=" << nclSector <<
2301 0 : "nclRow=" << ncl <<
2302 0 : "nclPad=" << nclPad <<
2303 0 : "row=" << row <<
2304 0 : "sector=" << sec <<
2305 0 : "icl0=" << icl0 <<
2306 : "\n";
2307 : }
2308 0 : }// dump the results to the debug streamer if in debug mode
2309 :
2310 0 : }//end of first loop over cluster
2311 : // delete rowClusterArray; // RS was moved to stack allocation
2312 0 : }//end of loop over rows
2313 0 : for (int i=0; i<20; i++) delete graphRes[i];
2314 : // delete [] graphRes; //RS was changed to stack allocation
2315 : // delete [] indexAmpGraphs;
2316 :
2317 0 : }//end of loop over sectors
2318 : }//end of loop over IROC/OROC
2319 : }// end of side loop
2320 0 : sw.Stop();
2321 0 : AliInfoF("timing: %e/%e real/cpu",sw.RealTime(),sw.CpuTime());
2322 : //
2323 0 : }
2324 : //_____________________________________________________________________________
2325 : void AliTPCtracker::GetTailValue(Float_t ampfactor,Double_t &ionTailMax, Double_t &ionTailTotal,TGraphErrors **graphRes,Float_t *indexAmpGraphs,AliTPCclusterMI *cl0,AliTPCclusterMI *cl1){
2326 :
2327 : //
2328 : // Function in order to calculate the amount of the correction to be added for a given cluster, return values are ionTailTaoltal and ionTailMax
2329 : // Parameters:
2330 : // cl0 - cluster to be modified
2331 : // cl1 - source cluster ion tail of this cluster will be added to the cl0 (accroding time and pad response function)
2332 : //
2333 : const float kMinPRF = 0.5f; // minimal PRF width
2334 0 : ionTailTotal = 0.; // correction value to be added to Qtot of cl0
2335 0 : ionTailMax = 0.; // correction value to be added to Qmax of cl0
2336 :
2337 0 : Float_t qTot0 = cl0->GetQ(); // cl0 Qtot info
2338 0 : Float_t qTot1 = cl1->GetQ(); // cl1 Qtot info
2339 0 : Int_t sectorPad = cl1->GetDetector(); // sector number
2340 0 : Int_t padcl0 = TMath::Nint(cl0->GetPad()); // pad0
2341 0 : Int_t padcl1 = TMath::Nint(cl1->GetPad()); // pad1
2342 0 : Float_t padWidth = (sectorPad < 36)?0.4:0.6; // pad width in cm
2343 0 : const Int_t deltaTimebin = TMath::Nint(TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin()))+12; //distance between pads of cl1 and cl0 increased by 12 bins
2344 0 : float rmsPad1I = (cl1->GetSigmaY2()==0)?0.5f/kMinPRF:(0.5f*padWidth/sqrtf(cl1->GetSigmaY2()));
2345 0 : float rmsPad0I = (cl0->GetSigmaY2()==0)?0.5f/kMinPRF:(0.5f*padWidth/sqrtf(cl0->GetSigmaY2()));
2346 :
2347 : // RS avoid useless calculations
2348 : //Double_t sumAmp1=0.;
2349 : //for (Int_t idelta =-2; idelta<=2;idelta++){
2350 : // sumAmp1+=TMath::Exp(-idelta*idelta*rmsPad1I);
2351 : //}
2352 : // Double_t sumAmp0=0.;
2353 : //for (Int_t idelta =-2; idelta<=2;idelta++){
2354 : // sumAmp0+=TMath::Exp(-idelta*idelta*rmsPad0I));
2355 : //}
2356 :
2357 0 : float tmp = expf(-rmsPad1I);
2358 0 : float sumAmp1 = 1.f/(1.f+2.f*tmp*(1.f+tmp*tmp*tmp));
2359 0 : tmp = expf(-rmsPad0I);
2360 0 : float sumAmp0 = 1.f/(1.f+2.f*tmp*(1.f+tmp*tmp*tmp));
2361 :
2362 : // Apply the correction --> cl1 corrects cl0 (loop over cl1's pads and find which pads of cl0 are going to be corrected)
2363 : Int_t padScan=2; // +-2 pad-timebin window will be scanned
2364 0 : for (Int_t ipad1=padcl1-padScan; ipad1<=padcl1+padScan; ipad1++) {
2365 : //
2366 : //
2367 0 : Float_t deltaPad1 = TMath::Abs(cl1->GetPad()-(Float_t)ipad1);
2368 0 : Float_t amp1 = TMath::Exp(-(deltaPad1*deltaPad1)*rmsPad1I)*sumAmp1; // normalized pad response function
2369 0 : Float_t qTotPad1 = amp1*qTot1; // used as a factor to multipliy the response function
2370 :
2371 : // find closest value of cl1 to COG (among the time response functions' amplitude array --> to select proper t.r.f.)
2372 : Int_t ampIndex = 0;
2373 0 : Float_t diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[0]);
2374 0 : for (Int_t j=0;j<20;j++) {
2375 0 : if (diffAmp > TMath::Abs(deltaPad1-indexAmpGraphs[j]) && indexAmpGraphs[j]!=0)
2376 : {
2377 0 : diffAmp = TMath::Abs(deltaPad1-indexAmpGraphs[j]);
2378 : ampIndex = j;
2379 0 : }
2380 : }
2381 0 : if (!graphRes[ampIndex]) continue;
2382 0 : if (deltaTimebin+2 >= graphRes[ampIndex]->GetN()) continue;
2383 0 : if (graphRes[ampIndex]->GetY()[deltaTimebin+2]>=0) continue;
2384 :
2385 0 : for (Int_t ipad0=padcl0-padScan; ipad0<=padcl0+padScan; ipad0++) {
2386 : //
2387 : //
2388 0 : if (ipad1!=ipad0) continue; // check if ipad1 channel sees ipad0 channel, if not no correction to be applied.
2389 :
2390 0 : Float_t deltaPad0 = TMath::Abs(cl0->GetPad()-(Float_t)ipad0);
2391 0 : Float_t amp0 = expf(-(deltaPad0*deltaPad0)*rmsPad0I)*sumAmp0; // normalized pad resp function
2392 0 : Float_t qMaxPad0 = amp0*qTot0;
2393 :
2394 : // Add 5 timebin range contribution around the max peak (-+2 tb window)
2395 0 : for (Int_t itb=deltaTimebin-2; itb<=deltaTimebin+2; itb++) {
2396 :
2397 0 : if (itb<0) continue;
2398 0 : if (itb>=graphRes[ampIndex]->GetN()) continue;
2399 :
2400 : // calculate contribution to qTot
2401 0 : Float_t tailCorr = TMath::Abs((qTotPad1*ampfactor)*(graphRes[ampIndex])->GetY()[itb]);
2402 0 : if (ipad1!=padcl0) {
2403 0 : ionTailTotal += TMath::Min(qMaxPad0,tailCorr); // for side pad
2404 0 : } else {
2405 0 : ionTailTotal += tailCorr; // for center pad
2406 : }
2407 : // calculate contribution to qMax
2408 0 : if (itb == deltaTimebin && ipad1 == padcl0) ionTailMax += tailCorr;
2409 :
2410 0 : } // end of tb correction loop which is applied over 5 tb range
2411 :
2412 0 : } // end of cl0 loop
2413 0 : } // end of cl1 loop
2414 :
2415 0 : }
2416 :
2417 : //_____________________________________________________________________________
2418 : Int_t AliTPCtracker::LoadOuterSectors() {
2419 : //-----------------------------------------------------------------
2420 : // This function fills outer TPC sectors with clusters.
2421 : //-----------------------------------------------------------------
2422 16 : Int_t nrows = fOuterSec->GetNRows();
2423 : UInt_t index=0;
2424 304 : for (Int_t sec = 0;sec<fkNOS;sec++)
2425 27936 : for (Int_t row = 0;row<nrows;row++){
2426 13824 : AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
2427 13824 : Int_t sec2 = sec+2*fkNIS;
2428 : //left
2429 13824 : Int_t ncl = tpcrow->GetN1();
2430 43732 : while (ncl--) {
2431 8042 : AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
2432 8042 : index=(((sec2<<8)+row)<<16)+ncl;
2433 8042 : tpcrow->InsertCluster(c,index);
2434 : }
2435 : //right
2436 13824 : ncl = tpcrow->GetN2();
2437 49260 : while (ncl--) {
2438 10806 : AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
2439 10806 : index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
2440 10806 : tpcrow->InsertCluster(c,index);
2441 : }
2442 : //
2443 : // write indexes for fast acces
2444 : //
2445 14128128 : for (Int_t i=510;i--;) tpcrow->SetFastCluster(i,-1);
2446 65344 : for (Int_t i=0;i<tpcrow->GetN();i++){
2447 18848 : Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
2448 18848 : tpcrow->SetFastCluster(zi,i); // write index
2449 : }
2450 : Int_t last = 0;
2451 14128128 : for (Int_t i=0;i<510;i++){
2452 7050240 : if (tpcrow->GetFastCluster(i)<0)
2453 7033150 : tpcrow->SetFastCluster(i,last);
2454 : else
2455 17090 : last = tpcrow->GetFastCluster(i);
2456 : }
2457 : }
2458 8 : fN=fkNOS;
2459 8 : fSectors=fOuterSec;
2460 8 : return 0;
2461 : }
2462 :
2463 :
2464 : //_____________________________________________________________________________
2465 : Int_t AliTPCtracker::LoadInnerSectors() {
2466 : //-----------------------------------------------------------------
2467 : // This function fills inner TPC sectors with clusters.
2468 : //-----------------------------------------------------------------
2469 16 : Int_t nrows = fInnerSec->GetNRows();
2470 : UInt_t index=0;
2471 304 : for (Int_t sec = 0;sec<fkNIS;sec++)
2472 18432 : for (Int_t row = 0;row<nrows;row++){
2473 9072 : AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
2474 : //
2475 : //left
2476 9072 : Int_t ncl = tpcrow->GetN1();
2477 69400 : while (ncl--) {
2478 25628 : AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
2479 25628 : index=(((sec<<8)+row)<<16)+ncl;
2480 25628 : tpcrow->InsertCluster(c,index);
2481 : }
2482 : //right
2483 9072 : ncl = tpcrow->GetN2();
2484 59088 : while (ncl--) {
2485 20472 : AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
2486 20472 : index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
2487 20472 : tpcrow->InsertCluster(c,index);
2488 : }
2489 : //
2490 : // write indexes for fast acces
2491 : //
2492 9271584 : for (Int_t i=0;i<510;i++)
2493 4626720 : tpcrow->SetFastCluster(i,-1);
2494 110344 : for (Int_t i=0;i<tpcrow->GetN();i++){
2495 46100 : Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
2496 46100 : tpcrow->SetFastCluster(zi,i); // write index
2497 : }
2498 : Int_t last = 0;
2499 9271584 : for (Int_t i=0;i<510;i++){
2500 4626720 : if (tpcrow->GetFastCluster(i)<0)
2501 4586956 : tpcrow->SetFastCluster(i,last);
2502 : else
2503 39764 : last = tpcrow->GetFastCluster(i);
2504 : }
2505 :
2506 : }
2507 :
2508 8 : fN=fkNIS;
2509 8 : fSectors=fInnerSec;
2510 8 : return 0;
2511 : }
2512 :
2513 :
2514 :
2515 : //_________________________________________________________________________
2516 : AliTPCclusterMI *AliTPCtracker::GetClusterMI(Int_t index) const {
2517 : //--------------------------------------------------------------------
2518 : // Return pointer to a given cluster
2519 : //--------------------------------------------------------------------
2520 883542 : if (index<0) return 0; // no cluster
2521 441771 : Int_t sec=(index&0xff000000)>>24;
2522 441771 : Int_t row=(index&0x00ff0000)>>16;
2523 441771 : Int_t ncl=(index&0x00007fff)>>00;
2524 :
2525 : const AliTPCtrackerRow * tpcrow=0;
2526 : TClonesArray * clrow =0;
2527 :
2528 883542 : if (sec<0 || sec>=fkNIS*4) {
2529 0 : AliWarning(Form("Wrong sector %d",sec));
2530 0 : return 0x0;
2531 : }
2532 :
2533 441771 : if (sec<fkNIS*2){
2534 172991 : AliTPCtrackerSector& tracksec = fInnerSec[sec%fkNIS];
2535 172991 : if (tracksec.GetNRows()<=row) return 0;
2536 172991 : tpcrow = &(tracksec[row]);
2537 172991 : if (tpcrow==0) return 0;
2538 :
2539 172991 : if (sec<fkNIS) {
2540 84911 : if (tpcrow->GetN1()<=ncl) return 0;
2541 84911 : clrow = tpcrow->GetClusters1();
2542 84911 : }
2543 : else {
2544 88080 : if (tpcrow->GetN2()<=ncl) return 0;
2545 88080 : clrow = tpcrow->GetClusters2();
2546 : }
2547 172991 : }
2548 : else {
2549 268780 : AliTPCtrackerSector& tracksec = fOuterSec[(sec-fkNIS*2)%fkNOS];
2550 268780 : if (tracksec.GetNRows()<=row) return 0;
2551 268780 : tpcrow = &(tracksec[row]);
2552 268780 : if (tpcrow==0) return 0;
2553 :
2554 268780 : if (sec-2*fkNIS<fkNOS) {
2555 135699 : if (tpcrow->GetN1()<=ncl) return 0;
2556 135699 : clrow = tpcrow->GetClusters1();
2557 135699 : }
2558 : else {
2559 133081 : if (tpcrow->GetN2()<=ncl) return 0;
2560 133081 : clrow = tpcrow->GetClusters2();
2561 : }
2562 268780 : }
2563 :
2564 441771 : return (AliTPCclusterMI*)clrow->At(ncl);
2565 :
2566 441771 : }
2567 :
2568 :
2569 :
2570 : Int_t AliTPCtracker::FollowToNext(AliTPCseed& t, Int_t nr) {
2571 : //-----------------------------------------------------------------
2572 : // This function tries to find a track prolongation to next pad row
2573 : //-----------------------------------------------------------------
2574 : //
2575 : const double kRoadY = 1., kRoadZ = 1.;
2576 179588 : Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
2577 : //
2578 : //
2579 : AliTPCclusterMI *cl=0;
2580 89794 : Int_t tpcindex= t.GetClusterIndex2(nr);
2581 : //
2582 : // update current shape info every 5 pad-row
2583 : // if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
2584 89794 : GetShape(&t,nr);
2585 : //}
2586 : //
2587 89794 : if (fIteration>0 && tpcindex>=-1){ //if we have already clusters
2588 : //
2589 37240 : if (tpcindex==-1) return 0; //track in dead zone
2590 33152 : if (tpcindex >= 0){ //
2591 33152 : cl = t.GetClusterPointer(nr); // cluster might not be there during track finding, but is attached in refits
2592 66304 : if (cl==0) cl = GetClusterMI(tpcindex);
2593 33152 : t.SetCurrentClusterIndex1(tpcindex);
2594 33152 : }
2595 33152 : if (cl){
2596 33152 : Int_t relativesector = ((tpcindex&0xff000000)>>24)%18; // if previously accepted cluster in different sector
2597 33152 : Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
2598 : //
2599 33152 : if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
2600 44776 : if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
2601 :
2602 33152 : if (TMath::Abs(angle-t.GetAlpha())>0.001){
2603 130 : Double_t rotation = angle-t.GetAlpha();
2604 130 : t.SetRelativeSector(relativesector);
2605 130 : if (!t.Rotate(rotation)) {
2606 0 : t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
2607 0 : return 0;
2608 : }
2609 130 : }
2610 33152 : if (!t.PropagateTo(cl->GetX())) { // RS: go directly to cluster X
2611 0 : t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
2612 0 : return 0;
2613 : }
2614 : //
2615 33152 : t.SetCurrentCluster(cl);
2616 33152 : t.SetRow(nr); // RS: memorise row
2617 33152 : Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
2618 33152 : if ((tpcindex&0x8000)==0) accept =0;
2619 33152 : if (accept<3) {
2620 : //if founded cluster is acceptible
2621 33098 : if (cl->IsUsed(11)) { // id cluster is shared inrease uncertainty
2622 652 : t.SetErrorY2(t.GetErrorY2()+0.03);
2623 652 : t.SetErrorZ2(t.GetErrorZ2()+0.03);
2624 652 : t.SetErrorY2(t.GetErrorY2()*3);
2625 652 : t.SetErrorZ2(t.GetErrorZ2()*3);
2626 652 : }
2627 33098 : t.SetNFoundable(t.GetNFoundable()+1);
2628 33098 : UpdateTrack(&t,accept);
2629 33098 : return 1;
2630 : }
2631 : else { // Remove old cluster from track
2632 54 : t.SetClusterIndex(nr, -3);
2633 : //RS t.SetClusterPointer(nr, 0);
2634 : }
2635 54 : }
2636 : }
2637 57422 : if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0; // cut on angle
2638 53892 : if (fIteration>1 && IsFindable(t)){
2639 : // not look for new cluster during refitting
2640 2010 : t.SetNFoundable(t.GetNFoundable()+1);
2641 2010 : return 0;
2642 : }
2643 : //
2644 49872 : UInt_t index=0;
2645 : // if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
2646 : //
2647 49872 : if (fAccountDistortions && !DistortX(&t,x,nr)) {if (fIteration==0) t.SetRemoval(10); return 0;}
2648 49908 : if (!t.PropagateTo(x)) {if (fIteration==0) t.SetRemoval(10); return 0;}
2649 49860 : t.SetRow(nr); //RS:? memorise reached row?
2650 : //
2651 49860 : double y=t.GetY(), z=t.GetZ();
2652 : double yEdgeDist = y;
2653 49860 : if (fAccountDistortions) yEdgeDist -= GetYSectEdgeDist(t.GetRelativeSector(),nr,y,z);
2654 : Bool_t rot = kFALSE;
2655 68230 : if (y>0 && yEdgeDist>ymax) { //RS y sign here is used to deduce which edge is used
2656 82 : t.SetRelativeSector((t.GetRelativeSector() + 1) % fN);
2657 86 : if (!t.Rotate(fSectors->GetAlpha())) return 0;
2658 : rot = kTRUE;
2659 78 : }
2660 81268 : else if (y<0 && yEdgeDist<-ymax) {
2661 126 : t.SetRelativeSector((t.GetRelativeSector() + fN - 1) % fN);
2662 134 : if (!t.Rotate(-fSectors->GetAlpha())) return 0;
2663 : rot = kTRUE;
2664 118 : }
2665 49848 : if (rot) {
2666 196 : x = GetXrow(nr);
2667 196 : if (fAccountDistortions && !DistortX(&t,x,nr)) {if (fIteration==0) t.SetRemoval(10); return 0;}
2668 202 : if (!t.PropagateTo(x)) {if (fIteration==0) t.SetRemoval(10); return 0; }
2669 194 : y = t.GetY();
2670 : yEdgeDist = y;
2671 194 : if (fAccountDistortions) yEdgeDist -= GetYSectEdgeDist(t.GetRelativeSector(),nr,y,z);
2672 : }
2673 : //
2674 49846 : if (!IsActive(t.GetRelativeSector(),nr)) { // RS:? How distortions affect this
2675 1320 : t.SetInDead(kTRUE);
2676 1320 : t.SetClusterIndex2(nr,-1);
2677 1320 : return 0;
2678 : }
2679 : //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
2680 48526 : Bool_t isActive = IsActive(t.GetRelativeSector(),nr); //RS:? Why do we check this again?
2681 194104 : Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ?
2682 129288 : fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0 :
2683 16290 : fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
2684 :
2685 97052 : if (!isActive || !isActive2) return 0;
2686 :
2687 48526 : const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
2688 97052 : if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
2689 : //
2690 : // RS: account for eventual modifications in dead zone definition due to distortions
2691 48526 : double margin = (y>0 ? ymax-yEdgeDist : ymax + yEdgeDist);
2692 48526 : if (margin<krow.GetDeadZone()){
2693 1062 : t.SetInDead(kTRUE);
2694 1062 : t.SetClusterIndex2(nr,-1);
2695 1062 : return 0;
2696 : }
2697 : else {
2698 94850 : if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
2699 78 : else return 0;
2700 : }
2701 : //calculate
2702 137358 : if (krow && (cl=krow.FindNearest2(y,z,kRoadY+fClExtraRoadY,kRoadZ+fClExtraRoadZ,index)) ) t.SetCurrentClusterIndex1(krow.GetIndex(index));
2703 47386 : if (cl) {
2704 42586 : t.SetCurrentCluster(cl);
2705 : // t.SetRow(nr); //RS: memorise row | already set at propagation
2706 42586 : if (fIteration==2&&cl->IsUsed(10)) return 0;
2707 42586 : Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
2708 42586 : if (fIteration==2&&cl->IsUsed(11)) {
2709 0 : t.SetErrorY2(t.GetErrorY2()+0.03);
2710 0 : t.SetErrorZ2(t.GetErrorZ2()+0.03);
2711 0 : t.SetErrorY2(t.GetErrorY2()*3);
2712 0 : t.SetErrorZ2(t.GetErrorZ2()*3);
2713 0 : }
2714 : /*
2715 : if (t.fCurrentCluster->IsUsed(10)){
2716 : //
2717 : //
2718 :
2719 : t.fNShared++;
2720 : if (t.fNShared>0.7*t.GetNumberOfClusters()) {
2721 : t.fRemoval =10;
2722 : return 0;
2723 : }
2724 : }
2725 : */
2726 84422 : if (accept<3) UpdateTrack(&t,accept);
2727 :
2728 42586 : } else {
2729 8820 : if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
2730 :
2731 : }
2732 47386 : return 1;
2733 139666 : }
2734 :
2735 :
2736 :
2737 : //_________________________________________________________________________
2738 : Bool_t AliTPCtracker::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
2739 : {
2740 : // Get track space point by index
2741 : // return false in case the cluster doesn't exist
2742 16802 : AliTPCclusterMI *cl = GetClusterMI(index);
2743 8401 : if (!cl) return kFALSE;
2744 8401 : Int_t sector = (index&0xff000000)>>24;
2745 : // Int_t row = (index&0x00ff0000)>>16;
2746 : Float_t xyz[3];
2747 : // xyz[0] = fkParam->GetPadRowRadii(sector,row);
2748 8401 : xyz[0] = cl->GetX();
2749 8401 : xyz[1] = cl->GetY();
2750 8401 : xyz[2] = cl->GetZ();
2751 8401 : Float_t sin,cos;
2752 8401 : fkParam->AdjustCosSin(sector,cos,sin);
2753 8401 : Float_t x = cos*xyz[0]-sin*xyz[1];
2754 8401 : Float_t y = cos*xyz[1]+sin*xyz[0];
2755 8401 : Float_t cov[6];
2756 8401 : Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
2757 11738 : if (sector < fkParam->GetNInnerSector()) sigmaY2 *= 2.07;
2758 8401 : Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
2759 11738 : if (sector < fkParam->GetNInnerSector()) sigmaZ2 *= 1.77;
2760 8401 : cov[0] = sin*sin*sigmaY2;
2761 8401 : cov[1] = -sin*cos*sigmaY2;
2762 8401 : cov[2] = 0.;
2763 8401 : cov[3] = cos*cos*sigmaY2;
2764 8401 : cov[4] = 0.;
2765 8401 : cov[5] = sigmaZ2;
2766 8401 : p.SetXYZ(x,y,xyz[2],cov);
2767 : AliGeomManager::ELayerID iLayer;
2768 : Int_t idet;
2769 8401 : if (sector < fkParam->GetNInnerSector()) {
2770 : iLayer = AliGeomManager::kTPC1;
2771 : idet = sector;
2772 3337 : }
2773 : else {
2774 : iLayer = AliGeomManager::kTPC2;
2775 5064 : idet = sector - fkParam->GetNInnerSector();
2776 : }
2777 8401 : UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
2778 8401 : p.SetVolumeID(volid);
2779 : return kTRUE;
2780 16802 : }
2781 :
2782 :
2783 :
2784 : Int_t AliTPCtracker::UpdateClusters(AliTPCseed& t, Int_t nr) {
2785 : //-----------------------------------------------------------------
2786 : // This function tries to find a track prolongation to next pad row
2787 : //-----------------------------------------------------------------
2788 87280 : t.SetCurrentCluster(0);
2789 43640 : t.SetCurrentClusterIndex1(-3);
2790 :
2791 130920 : Int_t row = (fAccountDistortions ? GetRowNumber(&t):GetRowNumber(t.GetX()))-1; //RS: with distortions cannot rely on X
2792 43640 : Double_t ymax= GetMaxY(nr);
2793 :
2794 53738 : if (row < nr) return 1; // don't prolongate if not information until now -
2795 :
2796 : const double kRoadY = 1., kRoadZ = 1.;
2797 :
2798 33542 : Double_t x= GetXrow(nr);
2799 33542 : if (fAccountDistortions && !DistortX(&t,x,nr)) return 0; // RS: if needed, account distortion
2800 : //
2801 34110 : if (!t.PropagateTo(x)) return 0;
2802 32974 : t.SetRow(nr); //RS: memorise row
2803 : //
2804 32974 : double y=t.GetY(), z=t.GetZ();
2805 : double yEdgeDist = y;
2806 32974 : if (fAccountDistortions) yEdgeDist -= GetYSectEdgeDist(t.GetRelativeSector(),nr,y,z);
2807 46872 : if (y>0 && yEdgeDist>ymax) { //RS y sign is used to determine which edge is used
2808 38 : t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
2809 40 : if (!t.Rotate(fSectors->GetAlpha())) return 0;
2810 36 : t.SetRow(-1); //RS: after rotation the row is not known
2811 36 : return 1;
2812 : }
2813 52012 : else if (y<0 && yEdgeDist<-ymax) {
2814 96 : t.SetRelativeSector((t.GetRelativeSector()+fN-1) % fN);
2815 142 : if (!t.Rotate(-fSectors->GetAlpha())) return 0;
2816 50 : t.SetRow(-1); //RS: after rotation the row is not known
2817 50 : return 1;
2818 : }
2819 : //
2820 32860 : if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
2821 :
2822 32820 : if (!IsActive(t.GetRelativeSector(),nr)) {
2823 714 : t.SetInDead(kTRUE);
2824 714 : t.SetClusterIndex2(nr,-1);
2825 714 : return 0;
2826 : }
2827 : //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
2828 :
2829 32106 : AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
2830 32106 : double margin = (y>0 ? ymax-yEdgeDist : ymax + yEdgeDist);
2831 32106 : if (margin<krow.GetDeadZone()) {
2832 858 : t.SetInDead(kTRUE);
2833 858 : t.SetClusterIndex2(nr,-1);
2834 858 : return 0;
2835 : }
2836 : else {
2837 : // if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
2838 62492 : if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
2839 4 : else return 0;
2840 : }
2841 :
2842 : // update current
2843 46800 : if ( (nr%2==0) || t.GetNumberOfClusters()<2){
2844 : // t.fCurrentSigmaY = GetSigmaY(&t);
2845 : //t.fCurrentSigmaZ = GetSigmaZ(&t);
2846 15688 : GetShape(&t,nr);
2847 15688 : }
2848 :
2849 : AliTPCclusterMI *cl=0;
2850 : Int_t index=0;
2851 : //
2852 : Double_t roady = 1.;
2853 : Double_t roadz = 1.;
2854 : //
2855 :
2856 31244 : if (!cl){
2857 31244 : index = t.GetClusterIndex2(nr);
2858 31244 : if ( (index >= 0) && (index&0x8000)==0){
2859 : //RS cl = t.GetClusterPointer(nr);
2860 : //RS if ( (cl==0) && (index >= 0)) cl = GetClusterMI(index);
2861 0 : if ( index >= 0 ) cl = GetClusterMI(index);
2862 0 : t.SetCurrentClusterIndex1(index);
2863 0 : if (cl) {
2864 0 : t.SetCurrentCluster(cl);
2865 0 : return 1;
2866 : }
2867 : }
2868 : }
2869 :
2870 : // if (index<0) return 0;
2871 31244 : UInt_t uindex = TMath::Abs(index);
2872 :
2873 31244 : if (krow) {
2874 : //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
2875 31244 : cl = krow.FindNearest2(y,z,kRoadY+fClExtraRoadY,kRoadZ+fClExtraRoadZ,uindex);
2876 31244 : }
2877 :
2878 60144 : if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));
2879 31244 : t.SetCurrentCluster(cl);
2880 :
2881 : return 1;
2882 108426 : }
2883 :
2884 :
2885 : Int_t AliTPCtracker::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
2886 : //-----------------------------------------------------------------
2887 : // This function tries to find a track prolongation to next pad row
2888 : //-----------------------------------------------------------------
2889 :
2890 : //update error according neighborhoud
2891 :
2892 87280 : if (t.GetCurrentCluster()) {
2893 28900 : t.SetRow(nr);
2894 28900 : Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
2895 :
2896 28900 : if (t.GetCurrentCluster()->IsUsed(10)){
2897 : //
2898 : //
2899 : // t.fErrorZ2*=2;
2900 : // t.fErrorY2*=2;
2901 116 : t.SetNShared(t.GetNShared()+1);
2902 116 : if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
2903 6 : t.SetRemoval(10);
2904 6 : return 0;
2905 : }
2906 : }
2907 28894 : if (fIteration>0) accept = 0;
2908 57320 : if (accept<3) UpdateTrack(&t,accept);
2909 :
2910 28894 : } else {
2911 14740 : if (fIteration==0){
2912 : //RS: with distortions related cluster errors the track error may grow, don't use this cut
2913 : //if ( t.GetNumberOfClusters()>18 && ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16 + fExtraClErrYZ2 )) t.SetRemoval(10);
2914 22132 : if ( t.GetNumberOfClusters()>18 && t.GetChi2()/t.GetNumberOfClusters()>6 ) t.SetRemoval(10);
2915 :
2916 29480 : if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
2917 : }
2918 : }
2919 43634 : return 1;
2920 43640 : }
2921 :
2922 :
2923 :
2924 : //_____________________________________________________________________________
2925 : Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step, Bool_t fromSeeds) {
2926 : //-----------------------------------------------------------------
2927 : // This function tries to find a track prolongation.
2928 : //-----------------------------------------------------------------
2929 : // Double_t xt=t.GetX(); // RS: with distortions we cannot rely on rowID from X
2930 : //
2931 3654 : Double_t alpha=t.GetAlpha();
2932 3654 : if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2933 4766 : if (alpha < 0. ) alpha += 2.*TMath::Pi();
2934 : //
2935 3654 : t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
2936 :
2937 10962 : Int_t first = fAccountDistortions ? GetRowNumber(&t):GetRowNumber(t.GetX()); //RS: with distortions cannot rely on X
2938 : //Int_t first = GetRowNumber(xt);
2939 3654 : if (!fromSeeds)
2940 3518 : first -= step;
2941 3654 : if (first < 0)
2942 0 : first = 0;
2943 113624 : for (Int_t nr= first; nr>=rf; nr-=step) {
2944 : // update kink info
2945 51478 : if (t.GetKinkIndexes()[0]>0){
2946 2544 : for (Int_t i=0;i<3;i++){
2947 1272 : Int_t index = t.GetKinkIndexes()[i];
2948 1908 : if (index==0) break;
2949 636 : if (index<0) continue;
2950 : //
2951 636 : AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
2952 636 : if (!kink){
2953 0 : printf("PROBLEM\n");
2954 0 : }
2955 : else{
2956 636 : Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
2957 636 : if (kinkrow==nr){
2958 4 : AliExternalTrackParam paramd(t);
2959 4 : kink->SetDaughter(paramd);
2960 4 : kink->SetStatus(2,5);
2961 4 : kink->Update();
2962 4 : }
2963 : }
2964 636 : }
2965 636 : }
2966 :
2967 51750 : if (nr==80) t.UpdateReference();
2968 51478 : if (nr<fInnerSec->GetNRows())
2969 18682 : fSectors = fInnerSec;
2970 : else
2971 32796 : fSectors = fOuterSec;
2972 51478 : if (FollowToNext(t,nr)==0)
2973 6264 : if (!t.IsActive())
2974 98 : return 0;
2975 :
2976 : }
2977 3556 : return 1;
2978 3654 : }
2979 :
2980 :
2981 :
2982 :
2983 :
2984 :
2985 : Int_t AliTPCtracker::FollowBackProlongation(AliTPCseed& t, Int_t rf, Bool_t fromSeeds) {
2986 : //-----------------------------------------------------------------
2987 : // This function tries to find a track prolongation.
2988 : //-----------------------------------------------------------------
2989 : //
2990 : // Double_t xt=t.GetX(); //RS: with distortions cannot rely on row from X
2991 2268 : Double_t alpha=t.GetAlpha();
2992 2268 : if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2993 2890 : if (alpha < 0. ) alpha += 2.*TMath::Pi();
2994 2268 : t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
2995 :
2996 2268 : Int_t first = t.GetFirstPoint();
2997 6804 : Int_t ri = fAccountDistortions ? GetRowNumber(&t) : GetRowNumber(t.GetX()); //RS: with distortions cannot rely on X
2998 : // Int_t ri = GetRowNumber(xt);
2999 2268 : if (!fromSeeds)
3000 2132 : ri += 1;
3001 :
3002 4390 : if (first<ri) first = ri;
3003 : //
3004 2268 : if (first<0) first=0;
3005 81168 : for (Int_t nr=first; nr<=rf; nr++) {
3006 : // if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
3007 38316 : if (t.GetKinkIndexes()[0]<0){
3008 2544 : for (Int_t i=0;i<3;i++){
3009 1272 : Int_t index = t.GetKinkIndexes()[i];
3010 1908 : if (index==0) break;
3011 636 : if (index>0) continue;
3012 636 : index = TMath::Abs(index);
3013 636 : AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
3014 636 : if (!kink){
3015 0 : printf("PROBLEM\n");
3016 0 : }
3017 : else{
3018 636 : Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
3019 636 : if (kinkrow==nr){
3020 8 : AliExternalTrackParam paramm(t);
3021 8 : kink->SetMother(paramm);
3022 8 : kink->SetStatus(2,1);
3023 8 : kink->Update();
3024 8 : }
3025 : }
3026 636 : }
3027 636 : }
3028 : //
3029 38316 : if (nr<fInnerSec->GetNRows())
3030 14676 : fSectors = fInnerSec;
3031 : else
3032 23640 : fSectors = fOuterSec;
3033 :
3034 38316 : FollowToNext(t,nr);
3035 : }
3036 2268 : return 1;
3037 0 : }
3038 :
3039 :
3040 :
3041 :
3042 :
3043 : Float_t AliTPCtracker::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
3044 : {
3045 : // overlapping factor
3046 : //
3047 0 : sum1=0;
3048 0 : sum2=0;
3049 : Int_t sum=0;
3050 : //
3051 0 : Float_t dz2 =(s1->GetZ() - s2->GetZ());
3052 0 : dz2*=dz2;
3053 :
3054 0 : Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
3055 0 : dy2*=dy2;
3056 0 : Float_t distance = TMath::Sqrt(dz2+dy2);
3057 0 : if (distance>4.) return 0; // if there are far away - not overlap - to reduce combinatorics
3058 :
3059 : // Int_t offset =0;
3060 0 : Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
3061 0 : Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
3062 0 : if (lastpoint>=kMaxRow)
3063 : lastpoint = kMaxRow-1;
3064 0 : if (firstpoint<0)
3065 0 : firstpoint = 0;
3066 0 : if (firstpoint>lastpoint) {
3067 : firstpoint =lastpoint;
3068 : // lastpoint = kMaxRow-1;
3069 0 : }
3070 :
3071 :
3072 : // for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
3073 : // if (s1->GetClusterIndex2(i)>0) sum1++;
3074 : // if (s2->GetClusterIndex2(i)>0) sum2++;
3075 : // if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
3076 : // sum++;
3077 : // }
3078 : // }
3079 : // RS: faster version + fix(?): clusterindex starts from 0
3080 0 : for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
3081 0 : int ind1=s1->GetClusterIndex2(i), ind2=s2->GetClusterIndex2(i);
3082 0 : if (ind1>=0) sum1++;
3083 0 : if (ind2>=0) sum2++;
3084 0 : if (ind1==ind2 && ind1>=0) sum++;
3085 : }
3086 0 : if (sum<5) return 0;
3087 :
3088 0 : Float_t summin = TMath::Min(sum1+1,sum2+1);
3089 0 : Float_t ratio = (sum+1)/Float_t(summin);
3090 : return ratio;
3091 0 : }
3092 :
3093 : void AliTPCtracker::SignShared(AliTPCseed * s1, AliTPCseed * s2)
3094 : {
3095 : // shared clusters
3096 : //
3097 : Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
3098 1418 : if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
3099 262 : Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
3100 262 : Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
3101 :
3102 : //
3103 : Int_t sumshared=0;
3104 : //
3105 : //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
3106 : //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
3107 : Int_t firstpoint = 0;
3108 : Int_t lastpoint = kMaxRow;
3109 : //
3110 : // if (firstpoint>=lastpoint-5) return;;
3111 :
3112 83840 : for (Int_t i=firstpoint;i<lastpoint;i++){
3113 : // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
3114 45484 : if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>=0) {
3115 320 : sumshared++;
3116 320 : }
3117 : }
3118 262 : if (sumshared>cutN0){
3119 : // sign clusters
3120 : //
3121 3200 : for (Int_t i=firstpoint;i<lastpoint;i++){
3122 : // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
3123 1950 : if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>=0) {
3124 288 : const AliTPCTrackerPoints::Point *p1 = s1->GetTrackPoint(i);
3125 288 : const AliTPCTrackerPoints::Point *p2 = s2->GetTrackPoint(i);;
3126 576 : if (s1->IsActive()&&s2->IsActive()){
3127 288 : s1->SetShared(i);
3128 288 : s2->SetShared(i);
3129 288 : }
3130 288 : }
3131 : }
3132 10 : }
3133 : //
3134 262 : if (sumshared>cutN0){
3135 20 : for (Int_t i=0;i<4;i++){
3136 10 : if (s1->GetOverlapLabel(3*i)==0){
3137 10 : s1->SetOverlapLabel(3*i, s2->GetLabel());
3138 10 : s1->SetOverlapLabel(3*i+1,sumshared);
3139 10 : s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
3140 10 : break;
3141 : }
3142 : }
3143 20 : for (Int_t i=0;i<4;i++){
3144 10 : if (s2->GetOverlapLabel(3*i)==0){
3145 10 : s2->SetOverlapLabel(3*i, s1->GetLabel());
3146 10 : s2->SetOverlapLabel(3*i+1,sumshared);
3147 10 : s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
3148 10 : break;
3149 : }
3150 : }
3151 10 : }
3152 822 : }
3153 :
3154 : void AliTPCtracker::SignShared(TObjArray * arr)
3155 : {
3156 : //
3157 : //sort trackss according sectors
3158 : //
3159 836 : for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
3160 394 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3161 516 : if (!pt) continue;
3162 : //if (pt) RotateToLocal(pt);
3163 272 : pt->SetSort(0);
3164 272 : }
3165 16 : arr->UnSort();
3166 16 : arr->Sort(); // sorting according relative sectors
3167 16 : arr->Expand(arr->GetEntries());
3168 : //
3169 : //
3170 16 : Int_t nseed=arr->GetEntriesFast();
3171 576 : for (Int_t i=0; i<nseed; i++) {
3172 272 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3173 272 : if (!pt) continue;
3174 7072 : for (Int_t j=0;j<12;j++){
3175 3264 : pt->SetOverlapLabel(j,0);
3176 : }
3177 272 : }
3178 576 : for (Int_t i=0; i<nseed; i++) {
3179 272 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3180 272 : if (!pt) continue;
3181 272 : if (pt->GetRemoval()>10) continue;
3182 5360 : for (Int_t j=i+1; j<nseed; j++){
3183 2408 : AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
3184 4256 : if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
3185 : // if (pt2){
3186 560 : if (pt2->GetRemoval()<=10) {
3187 : //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
3188 560 : SignShared(pt,pt2);
3189 560 : }
3190 560 : }
3191 272 : }
3192 16 : }
3193 :
3194 :
3195 : void AliTPCtracker::SortTracks(TObjArray * arr, Int_t mode) const
3196 : {
3197 : //
3198 : //sort tracks in array according mode criteria
3199 16 : Int_t nseed = arr->GetEntriesFast();
3200 288 : for (Int_t i=0; i<nseed; i++) {
3201 136 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3202 136 : if (!pt) {
3203 0 : continue;
3204 : }
3205 136 : pt->SetSort(mode);
3206 136 : }
3207 8 : arr->UnSort();
3208 8 : arr->Sort();
3209 8 : }
3210 :
3211 :
3212 : void AliTPCtracker::RemoveUsed2(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t minimal)
3213 : {
3214 : //
3215 : // Loop over all tracks and remove overlaped tracks (with lower quality)
3216 : // Algorithm:
3217 : // 1. Unsign clusters
3218 : // 2. Sort tracks according quality
3219 : // Quality is defined by the number of cluster between first and last points
3220 : //
3221 : // 3. Loop over tracks - decreasing quality order
3222 : // a.) remove - If the fraction of shared cluster less than factor (1- n or 2)
3223 : // b.) remove - If the minimal number of clusters less than minimal and not ITS
3224 : // c.) if track accepted - sign clusters
3225 : //
3226 : //Called in - AliTPCtracker::Clusters2Tracks()
3227 : // - AliTPCtracker::PropagateBack()
3228 : // - AliTPCtracker::RefitInward()
3229 : //
3230 : // Arguments:
3231 : // factor1 - factor for constrained
3232 : // factor2 - for non constrained tracks
3233 : // if (Float_t(shared+1)/Float_t(found+1)>factor) - DELETE
3234 : //
3235 80 : UnsignClusters();
3236 : //
3237 40 : Int_t nseed = arr->GetEntriesFast();
3238 : // Float_t quality = new Float_t[nseed];
3239 : // Int_t * indexes = new Int_t[nseed];
3240 40 : Float_t quality[nseed]; //RS Use stack allocations
3241 40 : Int_t indexes[nseed];
3242 : Int_t good =0;
3243 : //
3244 : //
3245 2236 : for (Int_t i=0; i<nseed; i++) {
3246 1078 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3247 1078 : if (!pt){
3248 242 : quality[i]=-1;
3249 242 : continue;
3250 : }
3251 836 : pt->UpdatePoints(); //select first last max dens points
3252 836 : Float_t * points = pt->GetPoints();
3253 836 : if (points[3]<0.8) quality[i] =-1;
3254 836 : quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
3255 : //prefer high momenta tracks if overlaps
3256 836 : quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
3257 836 : }
3258 40 : TMath::Sort(nseed,quality,indexes);
3259 : //
3260 : //
3261 2236 : for (Int_t itrack=0; itrack<nseed; itrack++) {
3262 1078 : Int_t trackindex = indexes[itrack];
3263 1078 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);
3264 1320 : if (!pt) continue;
3265 : //
3266 836 : if (quality[trackindex]<0){
3267 0 : MarkSeedFree( arr->RemoveAt(trackindex) );
3268 0 : continue;
3269 : }
3270 : //
3271 : //
3272 836 : Int_t first = Int_t(pt->GetPoints()[0]);
3273 836 : Int_t last = Int_t(pt->GetPoints()[2]);
3274 836 : Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
3275 : //
3276 836 : Int_t found,foundable,shared;
3277 836 : GetSeedClusterStatistic(pt, first,last, found, foundable,shared,kFALSE); //RS: seeds don't keep their clusters
3278 : //RS 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
3279 : //MI pt->GetClusterStatistic(0,kMaxRow, found, foundable,shared,kFALSE);
3280 : Bool_t itsgold =kFALSE;
3281 836 : if (pt->GetESD()){
3282 272 : Int_t dummy[12];
3283 416 : if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
3284 272 : }
3285 836 : if (!itsgold){
3286 : //
3287 692 : if (Float_t(shared+1)/Float_t(found+1)>factor){
3288 140 : if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
3289 140 : if( (AliTPCReconstructor::StreamLevel()&kStreamRemoveUsed)>0){ // flag:stream information about TPC tracks which were descarded (double track removal)
3290 0 : TTreeSRedirector &cstream = *fDebugStreamer;
3291 0 : cstream<<"RemoveUsed"<<
3292 0 : "iter="<<fIteration<<
3293 0 : "pt.="<<pt<<
3294 : "\n";
3295 0 : }
3296 140 : MarkSeedFree( arr->RemoveAt(trackindex) );
3297 140 : continue;
3298 : }
3299 606 : if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){ //remove short tracks
3300 8 : if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
3301 8 : if( (AliTPCReconstructor::StreamLevel()&kStreamRemoveShort)>0){ // flag:stream information about TPC tracks which were discarded (short track removal)
3302 0 : TTreeSRedirector &cstream = *fDebugStreamer;
3303 0 : cstream<<"RemoveShort"<<
3304 0 : "iter="<<fIteration<<
3305 0 : "pt.="<<pt<<
3306 : "\n";
3307 0 : }
3308 8 : MarkSeedFree( arr->RemoveAt(trackindex) );
3309 8 : continue;
3310 : }
3311 : }
3312 :
3313 688 : good++;
3314 : //if (sharedfactor>0.4) continue;
3315 700 : if (pt->GetKinkIndexes()[0]>0) continue;
3316 : //Remove tracks with undefined properties - seems
3317 676 : if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ?
3318 : //
3319 159172 : for (Int_t i=first; i<last; i++) {
3320 78910 : Int_t index=pt->GetClusterIndex2(i);
3321 : // if (index<0 || index&0x8000 ) continue;
3322 159922 : if (index<0 || index&0x8000 ) continue;
3323 67942 : AliTPCclusterMI *c= GetClusterMI(index); //RS pt->GetClusterPointer(i);
3324 67942 : if (!c) continue;
3325 67942 : c->Use(10);
3326 67942 : }
3327 1512 : }
3328 40 : fNtracks = good;
3329 40 : if (fDebug>0){
3330 0 : Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
3331 0 : }
3332 : // delete []quality; // RS was moved to stack allocation
3333 : // delete []indexes;
3334 40 : }
3335 :
3336 : void AliTPCtracker::DumpClusters(Int_t iter, TObjArray *trackArray)
3337 : {
3338 : //
3339 : // Dump clusters after reco
3340 : // signed and unsigned cluster can be visualized
3341 : // 1. Unsign all cluster
3342 : // 2. Sign all used clusters
3343 : // 3. Dump clusters
3344 0 : UnsignClusters();
3345 0 : Int_t nseed = trackArray->GetEntries();
3346 0 : for (Int_t i=0; i<nseed; i++){
3347 0 : AliTPCseed *pt=(AliTPCseed*)trackArray->UncheckedAt(i);
3348 0 : if (!pt) {
3349 0 : continue;
3350 : }
3351 0 : Bool_t isKink=pt->GetKinkIndex(0)!=0;
3352 0 : for (Int_t j=0; j<kMaxRow; ++j) {
3353 0 : Int_t index=pt->GetClusterIndex2(j);
3354 0 : if (index<0) continue;
3355 0 : AliTPCclusterMI *c= GetClusterMI(index); //RS pt->GetClusterPointer(j);
3356 0 : if (!c) continue;
3357 0 : if (isKink) c->Use(100); // kink
3358 0 : c->Use(10); // by default usage 10
3359 0 : }
3360 0 : }
3361 : //
3362 0 : Int_t eventNr = fEvent->GetEventNumberInFile();
3363 :
3364 0 : for (Int_t sec=0;sec<fkNIS;sec++){
3365 0 : for (Int_t row=0;row<fInnerSec->GetNRows();row++){
3366 0 : TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
3367 0 : for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++){
3368 0 : AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
3369 0 : Float_t gx[3]; cl->GetGlobalXYZ(gx);
3370 0 : (*fDebugStreamer)<<"clDump"<<
3371 0 : "eventNr="<<eventNr<<
3372 0 : "iter="<<iter<<
3373 0 : "cl.="<<cl<<
3374 0 : "gx0="<<gx[0]<<
3375 0 : "gx1="<<gx[1]<<
3376 0 : "gx2="<<gx[2]<<
3377 : "\n";
3378 0 : }
3379 0 : cla = fInnerSec[sec][row].GetClusters2();
3380 0 : for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++){
3381 0 : AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
3382 0 : Float_t gx[3]; cl->GetGlobalXYZ(gx);
3383 0 : (*fDebugStreamer)<<"clDump"<<
3384 0 : "eventNr="<<eventNr<<
3385 0 : "iter="<<iter<<
3386 0 : "cl.="<<cl<<
3387 0 : "gx0="<<gx[0]<<
3388 0 : "gx1="<<gx[1]<<
3389 0 : "gx2="<<gx[2]<<
3390 : "\n";
3391 0 : }
3392 : }
3393 : }
3394 :
3395 0 : for (Int_t sec=0;sec<fkNOS;sec++){
3396 0 : for (Int_t row=0;row<fOuterSec->GetNRows();row++){
3397 0 : TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
3398 0 : for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++){
3399 0 : Float_t gx[3];
3400 0 : AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
3401 0 : cl->GetGlobalXYZ(gx);
3402 0 : (*fDebugStreamer)<<"clDump"<<
3403 0 : "eventNr="<<eventNr<<
3404 0 : "iter="<<iter<<
3405 0 : "cl.="<<cl<<
3406 0 : "gx0="<<gx[0]<<
3407 0 : "gx1="<<gx[1]<<
3408 0 : "gx2="<<gx[2]<<
3409 : "\n";
3410 0 : }
3411 0 : cla = fOuterSec[sec][row].GetClusters2();
3412 0 : for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++){
3413 0 : Float_t gx[3];
3414 0 : AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
3415 0 : cl->GetGlobalXYZ(gx);
3416 0 : (*fDebugStreamer)<<"clDump"<<
3417 0 : "eventNr="<<eventNr<<
3418 0 : "iter="<<iter<<
3419 0 : "cl.="<<cl<<
3420 0 : "gx0="<<gx[0]<<
3421 0 : "gx1="<<gx[1]<<
3422 0 : "gx2="<<gx[2]<<
3423 : "\n";
3424 0 : }
3425 : }
3426 : }
3427 :
3428 0 : }
3429 : void AliTPCtracker::UnsignClusters()
3430 : {
3431 : //
3432 : // loop over all clusters and unsign them
3433 : //
3434 :
3435 2496 : for (Int_t sec=0;sec<fkNIS;sec++){
3436 147456 : for (Int_t row=0;row<fInnerSec->GetNRows();row++){
3437 72576 : TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
3438 555200 : for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
3439 : // if (cl[icl].IsUsed(10))
3440 205024 : ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
3441 72576 : cla = fInnerSec[sec][row].GetClusters2();
3442 472704 : for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
3443 : //if (cl[icl].IsUsed(10))
3444 163776 : ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
3445 : }
3446 : }
3447 :
3448 2432 : for (Int_t sec=0;sec<fkNOS;sec++){
3449 223488 : for (Int_t row=0;row<fOuterSec->GetNRows();row++){
3450 110592 : TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
3451 349856 : for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
3452 : //if (cl[icl].IsUsed(10))
3453 64336 : ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
3454 110592 : cla = fOuterSec[sec][row].GetClusters2();
3455 394080 : for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
3456 : //if (cl[icl].IsUsed(10))
3457 86448 : ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
3458 : }
3459 : }
3460 :
3461 64 : }
3462 :
3463 :
3464 :
3465 : void AliTPCtracker::SignClusters(const TObjArray * arr, Float_t fnumber, Float_t fdensity)
3466 : {
3467 : //
3468 : //sign clusters to be "used"
3469 : //
3470 : // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
3471 : // loop over "primaries"
3472 :
3473 : Float_t sumdens=0;
3474 : Float_t sumdens2=0;
3475 : Float_t sumn =0;
3476 : Float_t sumn2 =0;
3477 : Float_t sumchi =0;
3478 : Float_t sumchi2 =0;
3479 :
3480 : Float_t sum =0;
3481 :
3482 1392 : TStopwatch timer;
3483 696 : timer.Start();
3484 :
3485 696 : Int_t nseed = arr->GetEntriesFast();
3486 40608 : for (Int_t i=0; i<nseed; i++) {
3487 19608 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3488 19608 : if (!pt) {
3489 0 : continue;
3490 : }
3491 19866 : if (!(pt->IsActive())) continue;
3492 38700 : Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
3493 58042 : if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
3494 18966 : sumdens += dens;
3495 18966 : sumdens2+= dens*dens;
3496 37932 : sumn += pt->GetNumberOfClusters();
3497 56898 : sumn2 += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
3498 37932 : Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
3499 18966 : if (chi2>5) chi2=5;
3500 18966 : sumchi +=chi2;
3501 18966 : sumchi2 +=chi2*chi2;
3502 18966 : sum++;
3503 18966 : }
3504 19350 : }
3505 :
3506 : Float_t mdensity = 0.9;
3507 : Float_t meann = 130;
3508 : Float_t meanchi = 1;
3509 : Float_t sdensity = 0.1;
3510 : Float_t smeann = 10;
3511 : Float_t smeanchi =0.4;
3512 :
3513 :
3514 696 : if (sum>20){
3515 680 : mdensity = sumdens/sum;
3516 680 : meann = sumn/sum;
3517 680 : meanchi = sumchi/sum;
3518 : //
3519 680 : sdensity = sumdens2/sum-mdensity*mdensity;
3520 680 : if (sdensity >= 0)
3521 680 : sdensity = TMath::Sqrt(sdensity);
3522 : else
3523 : sdensity = 0.1;
3524 : //
3525 680 : smeann = sumn2/sum-meann*meann;
3526 680 : if (smeann >= 0)
3527 680 : smeann = TMath::Sqrt(smeann);
3528 : else
3529 : smeann = 10;
3530 : //
3531 680 : smeanchi = sumchi2/sum - meanchi*meanchi;
3532 680 : if (smeanchi >= 0)
3533 680 : smeanchi = TMath::Sqrt(smeanchi);
3534 : else
3535 : smeanchi = 0.4;
3536 : }
3537 :
3538 :
3539 : //REMOVE SHORT DELTAS or tracks going out of sensitive volume of TPC
3540 : //
3541 40608 : for (Int_t i=0; i<nseed; i++) {
3542 19608 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3543 19608 : if (!pt) {
3544 0 : continue;
3545 : }
3546 57722 : if (pt->GetBSigned()) continue;
3547 1512 : if (pt->GetBConstrain()) continue;
3548 : //if (!(pt->IsActive())) continue;
3549 : /*
3550 : Int_t found,foundable,shared;
3551 : pt->GetClusterStatistic(0,kMaxRow,found, foundable,shared);
3552 : if (shared/float(found)>0.3) {
3553 : if (shared/float(found)>0.9 ){
3554 : //MarkSeedFree( arr->RemoveAt(i) );
3555 : }
3556 : continue;
3557 : }
3558 : */
3559 : Bool_t isok =kFALSE;
3560 2768 : if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
3561 76 : isok = kTRUE;
3562 1976 : if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
3563 296 : isok =kTRUE;
3564 2076 : if (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
3565 206 : isok =kTRUE;
3566 1388 : if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
3567 0 : isok =kTRUE;
3568 :
3569 692 : if (isok)
3570 138880 : for (Int_t j=0; j<kMaxRow; ++j) {
3571 69006 : Int_t index=pt->GetClusterIndex2(j);
3572 115568 : if (index<0) continue;
3573 22444 : AliTPCclusterMI *c= GetClusterMI(index);//pt->GetClusterPointer(j);
3574 22444 : if (!c) continue;
3575 : //if (!(c->IsUsed(10))) c->Use();
3576 22444 : c->Use(10);
3577 22878 : }
3578 692 : }
3579 :
3580 :
3581 : //
3582 696 : Double_t maxchi = meanchi+2.*smeanchi;
3583 :
3584 40608 : for (Int_t i=0; i<nseed; i++) {
3585 19608 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
3586 19608 : if (!pt) {
3587 0 : continue;
3588 : }
3589 : //if (!(pt->IsActive())) continue;
3590 57722 : if (pt->GetBSigned()) continue;
3591 2204 : Double_t chi = pt->GetChi2()/pt->GetNumberOfClusters();
3592 1384 : if (chi>maxchi) continue;
3593 :
3594 : Float_t bfactor=1;
3595 1640 : Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
3596 :
3597 : //sign only tracks with enoug big density at the beginning
3598 :
3599 2204 : if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue;
3600 :
3601 :
3602 632 : Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
3603 632 : Double_t minn = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
3604 :
3605 : // if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
3606 808 : if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
3607 0 : minn=0;
3608 :
3609 2126 : if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
3610 : //Int_t noc=pt->GetNumberOfClusters();
3611 230 : pt->SetBSigned(kTRUE);
3612 73600 : for (Int_t j=0; j<kMaxRow; ++j) {
3613 :
3614 36570 : Int_t index=pt->GetClusterIndex2(j);
3615 41778 : if (index<0) continue;
3616 31362 : AliTPCclusterMI *c= GetClusterMI(index); //RS pt->GetClusterPointer(j);
3617 31362 : if (!c) continue;
3618 : // if (!(c->IsUsed(10))) c->Use();
3619 31362 : c->Use(10);
3620 31362 : }
3621 230 : }
3622 632 : }
3623 : // gLastCheck = nseed;
3624 : // arr->Compress();
3625 696 : if (fDebug>0){
3626 0 : timer.Print();
3627 : }
3628 696 : }
3629 :
3630 :
3631 :
3632 : Int_t AliTPCtracker::RefitInward(AliESDEvent *event)
3633 : {
3634 : //
3635 : // back propagation of ESD tracks
3636 : //
3637 : //return 0;
3638 16 : if (!event) return 0;
3639 8 : fEvent = event;
3640 8 : fEventHLT = 0;
3641 : // extract correction object for multiplicity dependence of dEdx
3642 8 : TObjArray * gainCalibArray = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(event->GetRunNumber());
3643 :
3644 8 : AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
3645 8 : if (!transform) {
3646 0 : AliFatal("Tranformations not in RefitInward");
3647 0 : return 0;
3648 : }
3649 8 : transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
3650 8 : const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
3651 8 : Int_t nContribut = event->GetNumberOfTracks();
3652 : TGraphErrors * graphMultDependenceDeDx = 0x0;
3653 16 : if (recoParam && recoParam->GetUseMultiplicityCorrectionDedx() && gainCalibArray) {
3654 0 : if (recoParam->GetUseTotCharge()) {
3655 0 : graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
3656 0 : } else {
3657 0 : graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
3658 : }
3659 : }
3660 : //
3661 8 : ReadSeeds(event,2);
3662 8 : fIteration=2;
3663 : //PrepareForProlongation(fSeeds,1);
3664 8 : PropagateForward2(fSeeds);
3665 8 : RemoveUsed2(fSeeds,0.4,0.4,20);
3666 :
3667 8 : Int_t entriesSeed=fSeeds->GetEntries();
3668 8 : TObjArray arraySeed(entriesSeed);
3669 288 : for (Int_t i=0;i<entriesSeed;i++) {
3670 272 : arraySeed.AddAt(fSeeds->At(i),i);
3671 : }
3672 8 : SignShared(&arraySeed);
3673 : // FindCurling(fSeeds, event,2); // find multi found tracks
3674 8 : FindSplitted(fSeeds, event,2); // find multi found tracks
3675 8 : if ((AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC)>0) FindMultiMC(fSeeds, fEvent,2); // flag: stream MC infomation about the multiple find track (ONLY for MC data)
3676 :
3677 : Int_t ntracks=0;
3678 8 : Int_t nseed = fSeeds->GetEntriesFast();
3679 : //
3680 : // RS: the cluster pointers are not permanently attached to the seed during the tracking, need to attach temporarily
3681 8 : AliTPCclusterMI* seedClusters[kMaxRow];
3682 : int seedsInFriends = 0;
3683 8 : int seedsInFriendsNorm = event->GetNTPCFriend2Store();
3684 12 : if (seedsInFriendsNorm>nseed) seedsInFriendsNorm = nseed; // all friends are stored
3685 : //
3686 8 : fClPointersPoolPtr = fClPointersPool;
3687 : //
3688 288 : for (Int_t i=0;i<nseed;i++) {
3689 136 : AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
3690 136 : if (!seed) continue;
3691 276 : if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
3692 136 : AliESDtrack *esd=event->GetTrack(i);
3693 : //
3694 : //RS: if needed, attach temporary cluster array
3695 136 : const AliTPCclusterMI** seedClustersSave = seed->GetClusters();
3696 136 : if (!seedClustersSave) { //RS: temporary attach clusters
3697 43520 : for (int ir=kMaxRow;ir--;) {
3698 21624 : int idx = seed->GetClusterIndex2(ir);
3699 63404 : seedClusters[ir] = idx<0 ? 0 : GetClusterMI(idx);
3700 : }
3701 136 : seed->SetClustersArrayTMP(seedClusters);
3702 136 : }
3703 : //
3704 : //
3705 302 : if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8) {
3706 2 : AliExternalTrackParam paramIn;
3707 2 : AliExternalTrackParam paramOut;
3708 : //
3709 4 : Int_t ncl = seed->RefitTrack(seed,¶mIn,¶mOut);
3710 : //
3711 2 : if ((AliTPCReconstructor::StreamLevel() & kStreamRecoverIn)>0) { // flag: stream track information for track failing in RefitInward function and recovered back
3712 0 : (*fDebugStreamer)<<"RecoverIn"<<
3713 0 : "seed.="<<seed<<
3714 0 : "esd.="<<esd<<
3715 0 : "pin.="<<¶mIn<<
3716 0 : "pout.="<<¶mOut<<
3717 0 : "ncl="<<ncl<<
3718 : "\n";
3719 : }
3720 2 : if (ncl>15) {
3721 2 : seed->Set(paramIn.GetX(),paramIn.GetAlpha(),paramIn.GetParameter(),paramIn.GetCovariance());
3722 2 : seed->SetNumberOfClusters(ncl);
3723 2 : }
3724 2 : }
3725 :
3726 136 : seed->PropagateTo(fkParam->GetInnerRadiusLow());
3727 136 : seed->SetRow(0);
3728 136 : seed->UpdatePoints();
3729 136 : AddCovariance(seed);
3730 136 : MakeESDBitmaps(seed, esd);
3731 136 : seed->CookdEdx(0.02,0.6);
3732 136 : CookLabel(seed,0.1); //For comparison only
3733 : //
3734 136 : if (((AliTPCReconstructor::StreamLevel()&kStreamRefitInward)>0) && seed!=0) {
3735 0 : TTreeSRedirector &cstream = *fDebugStreamer;
3736 0 : cstream<<"RefitInward"<< // flag: stream track information in RefitInward function (after tracking Iteration 2)
3737 0 : "Esd.="<<esd<<
3738 0 : "Track.="<<seed<<
3739 : "\n";
3740 0 : }
3741 272 : if (seed->GetNumberOfClusters()>15) {
3742 136 : esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
3743 136 : esd->SetTPCPoints(seed->GetPoints());
3744 136 : esd->SetTPCPointsF(seed->GetNFoundable());
3745 136 : Int_t ndedx = seed->GetNCDEDX(0);
3746 136 : Float_t sdedx = seed->GetSDEDX(0);
3747 136 : Float_t dedx = seed->GetdEdx();
3748 : // apply mutliplicity dependent dEdx correction if available
3749 136 : if (graphMultDependenceDeDx) {
3750 0 : Double_t corrGain = AliTPCcalibDButil::EvalGraphConst(graphMultDependenceDeDx, nContribut);
3751 0 : dedx += (1 - corrGain)*50.; // MIP is normalized to 50
3752 0 : }
3753 136 : esd->SetTPCsignal(dedx, sdedx, ndedx);
3754 : //
3755 : // fill new dEdx information
3756 : //
3757 136 : Double32_t signal[4];
3758 136 : Double32_t signalMax[4];
3759 136 : Char_t ncl[3];
3760 136 : Char_t nrows[3];
3761 : //
3762 1088 : for(Int_t iarr=0;iarr<3;iarr++) {
3763 408 : signal[iarr] = seed->GetDEDXregion(iarr+1);
3764 408 : signalMax[iarr] = seed->GetDEDXregion(iarr+5);
3765 408 : ncl[iarr] = seed->GetNCDEDX(iarr+1);
3766 408 : nrows[iarr] = seed->GetNCDEDXInclThres(iarr+1);
3767 : }
3768 136 : signal[3] = seed->GetDEDXregion(4);
3769 136 : signalMax[3] = seed->GetDEDXregion(8);
3770 :
3771 : //
3772 272 : AliTPCdEdxInfo * infoTpcPid = new AliTPCdEdxInfo();
3773 136 : infoTpcPid->SetTPCSignalRegionInfo(signal, ncl, nrows);
3774 136 : infoTpcPid->SetTPCSignalsQmax(signalMax);
3775 136 : esd->SetTPCdEdxInfo(infoTpcPid);
3776 : //
3777 : // add seed to the esd track in Calib level
3778 : //
3779 340 : Bool_t storeFriend = seedsInFriendsNorm>0 && (!esd->GetFriendNotStored())
3780 68 : && seedsInFriends<(kMaxFriendTracks-1)
3781 136 : && gRandom->Rndm()<(kMaxFriendTracks)/Float_t(seedsInFriendsNorm);
3782 : // if (AliTPCReconstructor::StreamLevel()>0 &&storeFriend){
3783 : //AliInfoF("Store: %d Stored %d / %d FrOff: %d",storeFriend,seedsInFriends,seedsInFriendsNorm,esd->GetFriendNotStored());
3784 136 : if (storeFriend){ // RS: seed is needed for calibration, regardless on streamlevel
3785 68 : seedsInFriends++;
3786 : // RS: this is the only place where the seed is created not in the pool,
3787 : // since it should belong to ESDevent
3788 : //AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE);
3789 : //esd->AddCalibObject(seedCopy);
3790 : //
3791 : //RS to avoid the cloning the seeds and clusters we will declare the seed to own its
3792 : // clusters and reattach the clusters pointers from the pool, so they are saved in the friends
3793 68 : seed->SetClusterOwner(kTRUE);
3794 68 : memcpy(fClPointersPoolPtr,seedClusters,kMaxRow*sizeof(AliTPCclusterMI*));
3795 68 : seed->SetClustersArrayTMP(fClPointersPoolPtr);
3796 68 : esd->AddCalibObject(seed);
3797 68 : fClPointersPoolPtr += kMaxRow;
3798 68 : }
3799 68 : else seed->SetClustersArrayTMP((AliTPCclusterMI**)seedClustersSave);
3800 : //
3801 136 : ntracks++;
3802 136 : }
3803 : else{
3804 : //printf("problem\n");
3805 : }
3806 : //
3807 : //RS if seed does not own clusters, then it was not added to friends: detach temporary clusters !!!
3808 340 : if (!seedClustersSave && !seed->GetClusterOwner()) seed->SetClustersArrayTMP(0);
3809 : //
3810 136 : }
3811 : //FindKinks(fSeeds,event);
3812 8 : if ((AliTPCReconstructor::StreamLevel()&kStreamClDump)>0) DumpClusters(2,fSeeds); // dump clusters at the end of process (signed with useage flags)
3813 8 : Info("RefitInward","Number of refitted tracks %d",ntracks);
3814 :
3815 8 : AliCosmicTracker::FindCosmic(event, kTRUE);
3816 :
3817 8 : FillClusterOccupancyInfo();
3818 :
3819 : return 0;
3820 16 : }
3821 :
3822 :
3823 : Int_t AliTPCtracker::PropagateBack(AliESDEvent *event)
3824 : {
3825 : //
3826 : // back propagation of ESD tracks
3827 : //
3828 16 : if (!event) return 0;
3829 8 : fEvent = event;
3830 8 : fEventHLT = 0;
3831 8 : fIteration = 1;
3832 8 : ReadSeeds(event,1);
3833 8 : PropagateBack(fSeeds);
3834 8 : RemoveUsed2(fSeeds,0.4,0.4,20);
3835 : //FindCurling(fSeeds, fEvent,1);
3836 8 : FindSplitted(fSeeds, event,1); // find multi found tracks
3837 8 : if ((AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC)>0) FindMultiMC(fSeeds, fEvent,1); // find multi found tracks
3838 : //
3839 : // RS: the cluster pointers are not permanently attached to the seed during the tracking, need to attach temporarily
3840 8 : AliTPCclusterMI* seedClusters[kMaxRow];
3841 : //
3842 8 : Int_t nseed = fSeeds->GetEntriesFast();
3843 : Int_t ntracks=0;
3844 288 : for (Int_t i=0;i<nseed;i++){
3845 136 : AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
3846 138 : if (!seed) continue;
3847 134 : AliESDtrack *esd=event->GetTrack(i);
3848 134 : if (!esd) continue; //never happen
3849 : //
3850 : //RS: if needed, attach temporary cluster array
3851 134 : const AliTPCclusterMI** seedClustersSave = seed->GetClusters();
3852 134 : if (!seedClustersSave) { //RS: temporary attach clusters
3853 42880 : for (int ir=kMaxRow;ir--;) {
3854 21306 : int idx = seed->GetClusterIndex2(ir);
3855 59486 : seedClusters[ir] = idx<0 ? 0 : GetClusterMI(idx);
3856 : }
3857 134 : seed->SetClustersArrayTMP(seedClusters);
3858 134 : }
3859 : //
3860 138 : if (seed->GetKinkIndex(0)<0) UpdateKinkQualityM(seed); // update quality informations for kinks
3861 134 : seed->UpdatePoints();
3862 134 : AddCovariance(seed);
3863 142 : if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
3864 0 : AliExternalTrackParam paramIn;
3865 0 : AliExternalTrackParam paramOut;
3866 0 : Int_t ncl = seed->RefitTrack(seed,¶mIn,¶mOut);
3867 0 : if ((AliTPCReconstructor::StreamLevel()&kStreamRecoverBack)>0) { // flag: stream track information for track faling PropagateBack function and recovered back (RefitTrack)
3868 0 : (*fDebugStreamer)<<"RecoverBack"<<
3869 0 : "seed.="<<seed<<
3870 0 : "esd.="<<esd<<
3871 0 : "pin.="<<¶mIn<<
3872 0 : "pout.="<<¶mOut<<
3873 0 : "ncl="<<ncl<<
3874 : "\n";
3875 : }
3876 0 : if (ncl>15) {
3877 0 : seed->Set(paramOut.GetX(),paramOut.GetAlpha(),paramOut.GetParameter(),paramOut.GetCovariance());
3878 0 : seed->SetNumberOfClusters(ncl);
3879 0 : }
3880 0 : }
3881 134 : seed->CookdEdx(0.02,0.6);
3882 134 : CookLabel(seed,0.1); //For comparison only
3883 134 : if (seed->GetNumberOfClusters()>15){
3884 134 : esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
3885 134 : esd->SetTPCPoints(seed->GetPoints());
3886 134 : esd->SetTPCPointsF(seed->GetNFoundable());
3887 134 : Int_t ndedx = seed->GetNCDEDX(0);
3888 134 : Float_t sdedx = seed->GetSDEDX(0);
3889 134 : Float_t dedx = seed->GetdEdx();
3890 134 : esd->SetTPCsignal(dedx, sdedx, ndedx);
3891 134 : ntracks++;
3892 134 : Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
3893 : // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
3894 134 : if (((AliTPCReconstructor::StreamLevel()&kStreamCPropagateBack)>0) && esd) {
3895 0 : (*fDebugStreamer)<<"PropagateBack"<< // flag: stream track information in PropagateBack function (after tracking Iteration 1)
3896 0 : "Tr0.="<<seed<<
3897 0 : "esd.="<<esd<<
3898 0 : "EventNrInFile="<<eventnumber<<
3899 : "\n";
3900 0 : }
3901 134 : }
3902 : //
3903 268 : if (!seedClustersSave) seed->SetClustersArrayTMP(0); //RS detach temporary clusters !!!
3904 : //
3905 134 : }
3906 8 : if (AliTPCReconstructor::StreamLevel()&kStreamClDump) DumpClusters(1,fSeeds); // flag:stream clusters at the end of process (signed with usage flag)
3907 : //FindKinks(fSeeds,event);
3908 8 : Info("PropagateBack","Number of back propagated tracks %d",ntracks);
3909 8 : fEvent =0;
3910 8 : fEventHLT = 0;
3911 :
3912 : return 0;
3913 16 : }
3914 :
3915 :
3916 : Int_t AliTPCtracker::PostProcess(AliESDEvent *event)
3917 : {
3918 : //
3919 : // Post process events
3920 : //
3921 16 : if (!event) return 0;
3922 :
3923 : //
3924 : // Set TPC event status
3925 : //
3926 :
3927 : // event affected by HV dip
3928 : // reset TPC status
3929 8 : if(IsTPCHVDipEvent(event)) {
3930 0 : event->ResetDetectorStatus(AliDAQ::kTPC);
3931 0 : }
3932 :
3933 : //printf("Status %d \n", event->IsDetectorOn(AliDAQ::kTPC));
3934 :
3935 8 : return 0;
3936 8 : }
3937 :
3938 :
3939 : void AliTPCtracker::DeleteSeeds()
3940 : {
3941 : //
3942 44 : fSeeds->Clear();
3943 22 : ResetSeedsPool();
3944 : // delete fSeeds; // RS avoid unnecessary deletes
3945 : // fSeeds =0;
3946 22 : }
3947 :
3948 : void AliTPCtracker::ReadSeeds(const AliESDEvent *const event, Int_t direction)
3949 : {
3950 : //
3951 : //read seeds from the event
3952 :
3953 32 : Int_t nentr=event->GetNumberOfTracks();
3954 16 : if (fDebug>0){
3955 0 : Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
3956 0 : }
3957 16 : if (fSeeds)
3958 16 : DeleteSeeds();
3959 16 : if (!fSeeds) fSeeds = new TObjArray(nentr);
3960 24 : else if (fSeeds->GetSize()<nentr) fSeeds->Expand(nentr); //RS reuse array
3961 : //
3962 16 : UnsignClusters();
3963 : // Int_t ntrk=0;
3964 640 : for (Int_t i=0; i<nentr; i++) {
3965 304 : AliESDtrack *esd=event->GetTrack(i);
3966 304 : ULong_t status=esd->GetStatus();
3967 336 : if (!(status&AliESDtrack::kTPCin)) continue;
3968 272 : AliTPCtrack t(*esd);
3969 272 : t.SetNumberOfClusters(0);
3970 : // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
3971 816 : AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(t/*,t.GetAlpha()*/);
3972 272 : seed->SetPoolID(fLastSeedID);
3973 544 : seed->SetUniqueID(esd->GetID());
3974 272 : AddCovariance(seed); //add systematic ucertainty
3975 2176 : for (Int_t ikink=0;ikink<3;ikink++) {
3976 816 : Int_t index = esd->GetKinkIndex(ikink);
3977 816 : seed->GetKinkIndexes()[ikink] = index;
3978 1616 : if (index==0) continue;
3979 16 : index = TMath::Abs(index);
3980 16 : AliESDkink * kink = fEvent->GetKink(index-1);
3981 48 : if (kink&&esd->GetKinkIndex(ikink)<0){
3982 8 : if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
3983 8 : if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,0);
3984 : }
3985 48 : if (kink&&esd->GetKinkIndex(ikink)>0){
3986 8 : if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
3987 8 : if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,4);
3988 : }
3989 :
3990 16 : }
3991 : // RS: resetting is done in the AliTPCtrack constructor
3992 : // if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.);
3993 : // if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
3994 : //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
3995 : // fSeeds->AddAt(0,i);
3996 : // MarkSeedFree( seed );
3997 : // continue;
3998 : //}
3999 :
4000 : //
4001 : //
4002 : // rotate to the local coordinate system
4003 : //
4004 272 : fSectors=fInnerSec; fN=fkNIS;
4005 272 : Double_t alpha=seed->GetAlpha();
4006 272 : if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
4007 370 : if (alpha < 0. ) alpha += 2.*TMath::Pi();
4008 272 : Int_t ns=Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
4009 272 : alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
4010 544 : alpha-=seed->GetAlpha();
4011 272 : if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
4012 370 : if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
4013 272 : if (TMath::Abs(alpha) > 0.001) { // This should not happen normally
4014 0 : AliWarning(Form("Rotating track over %f",alpha));
4015 0 : if (!seed->Rotate(alpha)) {
4016 0 : MarkSeedFree( seed );
4017 0 : continue;
4018 : }
4019 : }
4020 272 : seed->SetESD(esd);
4021 : // sign clusters
4022 544 : if (esd->GetKinkIndex(0)<=0){
4023 84480 : for (Int_t irow=0;irow<kMaxRow;irow++){
4024 41976 : Int_t index = seed->GetClusterIndex2(irow);
4025 41976 : if (index >= 0){
4026 : //
4027 33148 : AliTPCclusterMI * cl = GetClusterMI(index);
4028 : //RS seed->SetClusterPointer(irow,cl);
4029 33148 : if (cl){
4030 66296 : if ((index & 0x8000)==0){
4031 65336 : cl->Use(10); // accepted cluster
4032 : }else{
4033 960 : cl->Use(6); // close cluster not accepted
4034 : }
4035 : }else{
4036 0 : Info("ReadSeeds","Not found cluster");
4037 : }
4038 33148 : }
4039 : }
4040 264 : }
4041 272 : fSeeds->AddAt(seed,i);
4042 544 : }
4043 16 : }
4044 :
4045 : //_____________________________________________________________________________
4046 : void AliTPCtracker::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
4047 : Float_t deltay, Int_t ddsec) {
4048 : //-----------------------------------------------------------------
4049 : // This function creates track seeds.
4050 : // SEEDING WITH VERTEX CONSTRAIN
4051 : //-----------------------------------------------------------------
4052 : // cuts[0] - fP4 cut
4053 : // cuts[1] - tan(phi) cut
4054 : // cuts[2] - zvertex cut
4055 : // cuts[3] - fP3 cut
4056 :
4057 : const double kRoadY = 1., kRoadZ = 0.6;
4058 :
4059 : Int_t nin0 = 0;
4060 : Int_t nin1 = 0;
4061 : Int_t nin2 = 0;
4062 : Int_t nin = 0;
4063 : Int_t nout1 = 0;
4064 : Int_t nout2 = 0;
4065 :
4066 12384 : Double_t x[5], c[15];
4067 : // Int_t di = i1-i2;
4068 : //
4069 6192 : AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed();
4070 6192 : seed->SetPoolID(fLastSeedID);
4071 6192 : Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
4072 6192 : Double_t cs=cos(alpha), sn=sin(alpha);
4073 : //
4074 : // Double_t x1 =fOuterSec->GetX(i1);
4075 : //Double_t xx2=fOuterSec->GetX(i2);
4076 :
4077 6192 : Double_t x1 =GetXrow(i1);
4078 6192 : Double_t xx2=GetXrow(i2);
4079 :
4080 6192 : Double_t x3=GetX(), y3=GetY(), z3=GetZ();
4081 :
4082 6192 : Int_t imiddle = (i2+i1)/2; //middle pad row index
4083 6192 : Double_t xm = GetXrow(imiddle); // radius of middle pad-row
4084 6192 : const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
4085 : //
4086 : Int_t ns =sec;
4087 :
4088 6192 : const AliTPCtrackerRow& kr1=GetRow(ns,i1);
4089 6192 : Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
4090 6192 : Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
4091 :
4092 : //
4093 : // change cut on curvature if it can't reach this layer
4094 : // maximal curvature set to reach it
4095 6192 : Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
4096 6192 : if (dvertexmax*0.5*cuts[0]>0.85){
4097 8 : cuts[0] = 0.85/(dvertexmax*0.5+1.);
4098 8 : }
4099 6192 : Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
4100 :
4101 : // Int_t ddsec = 1;
4102 6192 : if (deltay>0) ddsec = 0;
4103 : // loop over clusters
4104 32836 : for (Int_t is=0; is < kr1; is++) {
4105 : //
4106 10226 : if (kr1[is]->IsUsed(10)) continue;
4107 6708 : if (kr1[is]->IsDisabled()) {
4108 : continue;
4109 : }
4110 :
4111 6708 : Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
4112 : //if (TMath::Abs(y1)>ymax) continue;
4113 :
4114 6708 : if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
4115 :
4116 : // find possible directions
4117 6708 : Float_t anglez = (z1-z3)/(x1-x3);
4118 6708 : Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
4119 : //
4120 : //
4121 : //find rotation angles relative to line given by vertex and point 1
4122 6708 : Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
4123 6708 : Double_t dvertex = TMath::Sqrt(dvertex2);
4124 6708 : Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
4125 6708 : Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
4126 :
4127 : //
4128 : // loop over 2 sectors
4129 6708 : Int_t dsec1=-ddsec;
4130 : Int_t dsec2= ddsec;
4131 11178 : if (y1<0) dsec2= 0;
4132 8946 : if (y1>0) dsec1= 0;
4133 :
4134 : Double_t dddz1=0; // direction of delta inclination in z axis
4135 : Double_t dddz2=0;
4136 6708 : if ( (z1-z3)>0)
4137 3102 : dddz1 =1;
4138 : else
4139 : dddz2 =1;
4140 : //
4141 31116 : for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
4142 8850 : Int_t sec2 = sec + dsec;
4143 : //
4144 : // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
4145 : //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
4146 8850 : AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
4147 8850 : AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
4148 8850 : Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
4149 8850 : Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
4150 :
4151 : // rotation angles to p1-p3
4152 8850 : Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
4153 : Double_t x2, y2, z2;
4154 : //
4155 : // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
4156 :
4157 : //
4158 8850 : Double_t dxx0 = (xx2-x3)*cs13r;
4159 8850 : Double_t dyy0 = (xx2-x3)*sn13r;
4160 41978 : for (Int_t js=index1; js < index2; js++) {
4161 8026 : const AliTPCclusterMI *kcl = kr2[js];
4162 10314 : if (kcl->IsUsed(10)) continue;
4163 5738 : if (kcl->IsDisabled()) {
4164 0 : continue;
4165 : }
4166 : //
4167 : //calcutate parameters
4168 : //
4169 5738 : Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
4170 : // stright track
4171 5738 : if (TMath::Abs(yy0)<0.000001) continue;
4172 5738 : Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
4173 5738 : Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
4174 5738 : Double_t r02 = (0.25+y0*y0)*dvertex2;
4175 : //curvature (radius) cut
4176 9614 : if (r02<r2min) continue;
4177 :
4178 1862 : nin0++;
4179 : //
4180 1862 : Double_t c0 = 1/TMath::Sqrt(r02);
4181 2698 : if (yy0>0) c0*=-1.;
4182 :
4183 :
4184 : //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
4185 : //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
4186 1862 : Double_t dfi0 = 2.*asinf(dvertex*c0*0.5);
4187 1862 : Double_t dfi1 = 2.*asinf(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
4188 : //
4189 : //
4190 1862 : Double_t z0 = kcl->GetZ();
4191 1862 : Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
4192 3416 : if (TMath::Abs(zzzz2-z0)>0.5) continue;
4193 308 : nin1++;
4194 : //
4195 308 : Double_t dip = (z1-z0)*c0/dfi1;
4196 308 : Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
4197 : //
4198 308 : y2 = kcl->GetY();
4199 308 : if (dsec==0){
4200 : x2 = xx2;
4201 282 : z2 = kcl->GetZ();
4202 282 : }
4203 : else
4204 : {
4205 : // rotation
4206 26 : z2 = kcl->GetZ();
4207 26 : x2= xx2*cs-y2*sn*dsec;
4208 26 : y2=+xx2*sn*dsec+y2*cs;
4209 : }
4210 :
4211 308 : x[0] = y1;
4212 308 : x[1] = z1;
4213 308 : x[2] = x0;
4214 308 : x[3] = dip;
4215 308 : x[4] = c0;
4216 : //
4217 : //
4218 : // do we have cluster at the middle ?
4219 308 : Double_t ym,zm;
4220 308 : GetProlongation(x1,xm,x,ym,zm);
4221 308 : UInt_t dummy;
4222 : AliTPCclusterMI * cm=0;
4223 308 : if (TMath::Abs(ym)-ymaxm<0){
4224 282 : cm = krm.FindNearest2(ym,zm,kRoadY+fClExtraRoadY,kRoadZ+fClExtraRoadZ,dummy);
4225 500 : if ((!cm) || (cm->IsUsed(10))) {
4226 78 : continue;
4227 : }
4228 : }
4229 : else{
4230 : // rotate y1 to system 0
4231 : // get state vector in rotated system
4232 26 : Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
4233 26 : Double_t xr2 = x0*cs+yr1*sn*dsec;
4234 26 : Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
4235 : //
4236 26 : GetProlongation(xx2,xm,xr,ym,zm);
4237 26 : if (TMath::Abs(ym)-ymaxm<0){
4238 2 : cm = kr2m.FindNearest2(ym,zm,kRoadY+fClExtraRoadY,kRoadZ+fClExtraRoadZ,dummy);
4239 2 : if ((!cm) || (cm->IsUsed(10))) {
4240 2 : continue;
4241 : }
4242 : }
4243 50 : }
4244 :
4245 :
4246 : // Double_t dym = 0;
4247 : // Double_t dzm = 0;
4248 : // if (cm){
4249 : // dym = ym - cm->GetY();
4250 : // dzm = zm - cm->GetZ();
4251 : // }
4252 228 : nin2++;
4253 :
4254 :
4255 : //
4256 : //
4257 228 : Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
4258 228 : Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
4259 : //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
4260 228 : Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
4261 : //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
4262 :
4263 228 : Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
4264 228 : Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
4265 228 : Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
4266 228 : Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
4267 228 : Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
4268 228 : Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
4269 :
4270 228 : Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
4271 228 : Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
4272 228 : Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
4273 228 : Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
4274 :
4275 228 : c[0]=sy1;
4276 228 : c[1]=0.; c[2]=sz1;
4277 228 : c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4278 228 : c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4279 228 : c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4280 228 : c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4281 228 : c[13]=f30*sy1*f40+f32*sy2*f42;
4282 228 : c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4283 :
4284 : // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
4285 :
4286 228 : UInt_t index=kr1.GetIndex(is);
4287 454 : if (seed) {MarkSeedFree(seed); seed = 0;}
4288 228 : AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, ns*alpha+shift, x, c, index);
4289 228 : seed->SetPoolID(fLastSeedID);
4290 228 : seed->SetRow(i1); //RS: memorise current row
4291 228 : track->SetIsSeeding(kTRUE);
4292 228 : track->SetSeed1(i1);
4293 228 : track->SetSeed2(i2);
4294 228 : track->SetSeedType(3);
4295 :
4296 :
4297 : //if (dsec==0) {
4298 228 : FollowProlongation(*track, (i1+i2)/2,1);
4299 228 : Int_t foundable,found,shared;
4300 228 : GetSeedClusterStatistic(track,(i1+i2)/2,i1, found, foundable, shared, kTRUE); //RS: seeds don't keep their clusters
4301 : //RS track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
4302 680 : if ((found<0.55*foundable) || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
4303 2 : MarkSeedFree(seed); seed = 0;
4304 2 : continue;
4305 : }
4306 : //}
4307 :
4308 226 : nin++;
4309 226 : FollowProlongation(*track, i2,1);
4310 :
4311 :
4312 : //Int_t rc = 1;
4313 226 : track->SetBConstrain(1);
4314 : // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
4315 226 : track->SetLastPoint(i1); // first cluster in track position
4316 226 : track->SetFirstPoint(track->GetLastPoint());
4317 :
4318 440 : if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
4319 214 : track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
4320 214 : track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
4321 12 : MarkSeedFree(seed); seed = 0;
4322 12 : continue;
4323 : }
4324 214 : nout1++;
4325 214 : Double_t zv, bz=GetBz();
4326 214 : if ( !track->GetZAt(0.,bz,zv) ) { MarkSeedFree( seed ); seed = 0; continue; }
4327 : //
4328 214 : if (fDisableSecondaries) {
4329 0 : if (TMath::Abs(zv)>fPrimaryDCAZCut) { MarkSeedFree( seed ); seed = 0; continue; }
4330 0 : double yv;
4331 0 : if ( !track->GetZAt(0.,bz,yv) ) { MarkSeedFree( seed ); seed = 0; continue; }
4332 0 : if (TMath::Abs(zv)>fPrimaryDCAZCut) { MarkSeedFree( seed ); seed = 0; continue; }
4333 0 : }
4334 :
4335 : //
4336 : // Z VERTEX CONDITION
4337 214 : if (TMath::Abs(zv-z3)>cuts[2]) {
4338 4 : FollowProlongation(*track, TMath::Max(i2-20,0));
4339 4 : if ( !track->GetZAt(0.,bz,zv) ) continue;
4340 4 : if (TMath::Abs(zv-z3)>cuts[2]){
4341 2 : FollowProlongation(*track, TMath::Max(i2-40,0));
4342 2 : if ( !track->GetZAt(0.,bz,zv) ) continue;
4343 4 : if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
4344 : // make seed without constrain
4345 2 : AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
4346 2 : FollowProlongation(*track2, i2,1);
4347 2 : track2->SetBConstrain(kFALSE);
4348 2 : track2->SetSeedType(1);
4349 2 : arr->AddLast(track2);
4350 2 : MarkSeedFree( seed ); seed = 0;
4351 : continue;
4352 : }
4353 : else{
4354 0 : MarkSeedFree( seed ); seed = 0;
4355 0 : continue;
4356 :
4357 : }
4358 : }
4359 : }
4360 :
4361 212 : track->SetSeedType(0);
4362 212 : arr->AddLast(track); // note, track is seed, don't free the seed
4363 212 : seed = new( NextFreeSeed() ) AliTPCseed;
4364 212 : seed->SetPoolID(fLastSeedID);
4365 212 : nout2++;
4366 : // don't consider other combinations
4367 212 : if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
4368 208 : break;
4369 754 : }
4370 : }
4371 6708 : }
4372 6192 : if (fDebug>3){
4373 0 : Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
4374 0 : }
4375 12370 : if (seed) MarkSeedFree( seed );
4376 6192 : }
4377 :
4378 : //_____________________________________________________________________________
4379 : void AliTPCtracker::MakeSeeds3Dist(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
4380 : Float_t deltay, Int_t ddsec) {
4381 : //-----------------------------------------------------------------
4382 : // This function creates track seeds, accounting for distortions
4383 : // SEEDING WITH VERTEX CONSTRAIN
4384 : //-----------------------------------------------------------------
4385 : // cuts[0] - fP4 cut
4386 : // cuts[1] - tan(phi) cut
4387 : // cuts[2] - zvertex cut
4388 : // cuts[3] - fP3 cut
4389 : const double kRoadY = 1., kRoadZ = 0.6;
4390 :
4391 : Int_t nin0 = 0;
4392 : Int_t nin1 = 0;
4393 : Int_t nin2 = 0;
4394 : Int_t nin = 0;
4395 : Int_t nout1 = 0;
4396 : Int_t nout2 = 0;
4397 :
4398 0 : Double_t x[5], c[15];
4399 : // Int_t di = i1-i2;
4400 : //
4401 0 : AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed();
4402 0 : seed->SetPoolID(fLastSeedID);
4403 0 : Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
4404 0 : Double_t cs=cos(alpha), sn=sin(alpha);
4405 : //
4406 0 : Double_t x1def = GetXrow(i1);
4407 0 : Double_t xx2def = GetXrow(i2);
4408 :
4409 0 : Double_t x3=GetX(), y3=GetY(), z3=GetZ();
4410 :
4411 0 : Int_t imiddle = (i2+i1)/2; //middle pad row index
4412 0 : const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
4413 : //
4414 : Int_t ns =sec;
4415 :
4416 0 : const AliTPCtrackerRow& kr1=GetRow(ns,i1);
4417 0 : Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
4418 0 : Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
4419 :
4420 : //
4421 : // change cut on curvature if it can't reach this layer
4422 : // maximal curvature set to reach it
4423 0 : Double_t dvertexmax = TMath::Sqrt((x1def-x3)*(x1def-x3)+(ymax+5-y3)*(ymax+5-y3));
4424 0 : if (dvertexmax*0.5*cuts[0]>0.85){
4425 0 : cuts[0] = 0.85/(dvertexmax*0.5+1.);
4426 0 : }
4427 0 : Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
4428 :
4429 : // Int_t ddsec = 1;
4430 0 : if (deltay>0) ddsec = 0;
4431 : // loop over clusters
4432 0 : for (Int_t is=0; is < kr1; is++) {
4433 : //
4434 0 : if (kr1[is]->IsUsed(10)) continue;
4435 0 : if (kr1[is]->IsDisabled()) {
4436 : continue;
4437 : }
4438 0 : const AliTPCclusterMI* clkr1 = kr1[is];
4439 0 : Double_t x1=clkr1->GetX(), y1=clkr1->GetY(), z1=clkr1->GetZ();
4440 : //if (TMath::Abs(y1)>ymax) continue;
4441 : double y1EdgeDist = y1;
4442 0 : if (fAccountDistortions) y1EdgeDist -= GetYSectEdgeDist(sec,ns,y1,z1);
4443 0 : if (deltay>0) {
4444 0 : double margin = (y1>0 ? ymax-y1EdgeDist : ymax + y1EdgeDist);
4445 0 : if (margin<deltay ) continue; // seed only at the edge
4446 0 : }
4447 : //
4448 : // find possible directions
4449 0 : double dx13 = x1-x3, dy13 = y1-y3, dz13 = z1-z3;
4450 0 : double anglez = dz13/dx13;
4451 0 : double extraz = z1 - anglez*(x1-xx2def); // extrapolated z
4452 : //
4453 : //
4454 : //find rotation angles relative to line given by vertex and point 1
4455 0 : Double_t dvertex2 = dx13*dx13+dy13*dy13;
4456 0 : Double_t dvertex = TMath::Sqrt(dvertex2);
4457 0 : Double_t angle13 = TMath::ATan(dy13/dx13);
4458 0 : Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
4459 :
4460 : //
4461 : // loop over 2 sectors
4462 0 : Int_t dsec1=-ddsec;
4463 : Int_t dsec2= ddsec;
4464 0 : if (y1<0) dsec2= 0;
4465 0 : if (y1>0) dsec1= 0;
4466 :
4467 : Double_t dddz1=0; // direction of delta inclination in z axis
4468 : Double_t dddz2=0;
4469 0 : if ( dz13>0 ) dddz1 =1;
4470 : else dddz2 =1;
4471 : //
4472 0 : for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
4473 0 : Int_t sec2 = sec + dsec;
4474 : //
4475 : // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
4476 : //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
4477 0 : AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
4478 0 : AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
4479 0 : Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
4480 0 : Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
4481 :
4482 : // rotation angles to p1-p3
4483 0 : Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
4484 : //
4485 : // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
4486 : //
4487 0 : for (Int_t js=index1; js < index2; js++) {
4488 0 : const AliTPCclusterMI *kcl = kr2[js];
4489 0 : if (kcl->IsUsed(10)) continue;
4490 0 : if (kcl->IsDisabled()) {
4491 0 : continue;
4492 : }
4493 : //
4494 0 : double x2=kcl->GetX(), y2=kcl->GetY(), z2=kcl->GetZ();
4495 0 : double dy23 = y2-y3, dx23 = x2-x3;
4496 : //calcutate parameters
4497 0 : Double_t dxx0 = dx23*cs13r;
4498 0 : Double_t dyy0 = dx23*sn13r;
4499 : //
4500 0 : Double_t yy0 = dyy0 +dy23*cs13r;
4501 : // stright track
4502 0 : if (TMath::Abs(yy0)<0.000001) continue;
4503 0 : Double_t xx0 = dxx0 -dy23*sn13r;
4504 0 : Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
4505 0 : Double_t r02 = (0.25+y0*y0)*dvertex2;
4506 : //curvature (radius) cut
4507 0 : if (r02<r2min) continue;
4508 :
4509 0 : nin0++;
4510 : //
4511 0 : Double_t c0 = 1/TMath::Sqrt(r02);
4512 0 : if (yy0>0) c0*=-1.;
4513 :
4514 0 : Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
4515 0 : Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
4516 : // Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
4517 : // Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
4518 : //
4519 0 : Double_t zzzz2 = z1-dz13*dfi1/dfi0;
4520 0 : if (TMath::Abs(zzzz2-z2)>0.5) continue;
4521 0 : nin1++;
4522 : //
4523 0 : Double_t dip = (z1-z2)*c0/dfi1;
4524 0 : Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
4525 : //
4526 0 : if (dsec!=0) {
4527 : // rotation
4528 : double xt2 = x2;
4529 0 : x2= xt2*cs-y2*sn*dsec;
4530 0 : y2=+xt2*sn*dsec+y2*cs;
4531 0 : }
4532 :
4533 0 : x[0] = y1;
4534 0 : x[1] = z1;
4535 0 : x[2] = x0;
4536 0 : x[3] = dip;
4537 0 : x[4] = c0;
4538 : //
4539 : //
4540 : // do we have cluster at the middle ?
4541 0 : Double_t xm = GetXrow(imiddle), ym, zm; // radius of middle pad-row
4542 0 : GetProlongation(x1,xm,x,ym,zm);
4543 : // account for distortion
4544 0 : double dxDist = GetDistortionX(xm,ym,zm,sec,imiddle);
4545 0 : if (TMath::Abs(dxDist)>0.05) GetProlongation(x1,xm+dxDist,x,ym,zm); //RS:? can we use straight line here?
4546 0 : UInt_t dummy;
4547 : AliTPCclusterMI * cm=0;
4548 0 : double ymEdgeDist = ym;
4549 0 : if (fAccountDistortions) ymEdgeDist -= GetYSectEdgeDist(sec,imiddle,ym,zm); // ym shifted by edge distortion
4550 0 : if ( (ym>0&&ymEdgeDist<ymaxm) || (ym<=0&&ymEdgeDist>-ymaxm) ) { //RS // if (TMath::Abs(ym)-ymaxm<0){
4551 0 : cm = krm.FindNearest2(ym,zm,kRoadY+fClExtraRoadY,kRoadZ+fClExtraRoadZ,dummy);
4552 0 : if ((!cm) || (cm->IsUsed(10))) continue;
4553 : }
4554 : else{
4555 : // rotate y1 to system 0
4556 : // get state vector in rotated system
4557 0 : Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
4558 0 : Double_t xr2 = x0*cs+yr1*sn*dsec;
4559 0 : Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
4560 : //
4561 0 : GetProlongation(kcl->GetX(),xm,xr,ym,zm);
4562 0 : double dxDist = GetDistortionX(xm,ym,zm,sec2,imiddle);
4563 0 : if (TMath::Abs(dxDist)>0.05) GetProlongation(x1,xm+dxDist,x,ym,zm); //RS:? can we use straight line here?
4564 : //
4565 0 : ymEdgeDist = ym;
4566 0 : if (fAccountDistortions) ymEdgeDist -= GetYSectEdgeDist(sec2,imiddle,ym,zm); // ym shifted by edge distortion
4567 0 : if ( (ym>0&&ymEdgeDist<ymaxm) || (ym<=0&&ymEdgeDist>-ymaxm) ) { //RS //if (TMath::Abs(ym)-ymaxm<0){
4568 0 : cm = kr2m.FindNearest2(ym,zm,kRoadY+fClExtraRoadY,kRoadZ+fClExtraRoadZ,dummy);
4569 0 : if ((!cm) || (cm->IsUsed(10))) continue;
4570 : }
4571 0 : }
4572 :
4573 : // Double_t dym = 0;
4574 : // Double_t dzm = 0;
4575 : // if (cm){
4576 : // dym = ym - cm->GetY();
4577 : // dzm = zm - cm->GetZ();
4578 : // }
4579 0 : nin2++;
4580 :
4581 :
4582 : //
4583 : //
4584 0 : Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
4585 0 : Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
4586 : //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
4587 0 : Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
4588 : //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
4589 :
4590 0 : Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
4591 0 : Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
4592 0 : Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
4593 0 : Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
4594 0 : Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
4595 0 : Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
4596 :
4597 0 : Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
4598 0 : Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
4599 0 : Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
4600 0 : Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
4601 :
4602 0 : c[0]=sy1;
4603 0 : c[1]=0.; c[2]=sz1;
4604 0 : c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4605 0 : c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4606 0 : c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4607 0 : c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4608 0 : c[13]=f30*sy1*f40+f32*sy2*f42;
4609 0 : c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4610 :
4611 : // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
4612 :
4613 0 : UInt_t index=kr1.GetIndex(is);
4614 0 : if (seed) {MarkSeedFree(seed); seed = 0;}
4615 0 : AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, ns*alpha+shift, x, c, index);
4616 0 : seed->SetPoolID(fLastSeedID);
4617 0 : seed->SetRow(i1); //RS: memorise current row
4618 0 : track->SetIsSeeding(kTRUE);
4619 0 : track->SetSeed1(i1);
4620 0 : track->SetSeed2(i2);
4621 0 : track->SetSeedType(3);
4622 :
4623 :
4624 : //if (dsec==0) {
4625 0 : FollowProlongation(*track, (i1+i2)/2,1);
4626 0 : Int_t foundable,found,shared;
4627 0 : GetSeedClusterStatistic(track,(i1+i2)/2,i1, found, foundable, shared, kTRUE); //RS: seeds don't keep their clusters
4628 : //RS track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
4629 0 : if ((found<0.55*foundable) || shared>0.5*found) {
4630 : //RS: with distortions related cluster errors the track error may grow, don't use this cut
4631 : //|| (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
4632 0 : MarkSeedFree(seed); seed = 0;
4633 0 : continue;
4634 : }
4635 : //}
4636 :
4637 0 : nin++;
4638 0 : FollowProlongation(*track, i2,1);
4639 :
4640 :
4641 : //Int_t rc = 1;
4642 0 : track->SetBConstrain(1);
4643 : // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
4644 0 : track->SetLastPoint(i1); // first cluster in track position
4645 0 : track->SetFirstPoint(track->GetLastPoint());
4646 :
4647 0 : if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
4648 0 : track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
4649 0 : track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
4650 0 : MarkSeedFree(seed); seed = 0;
4651 0 : continue;
4652 : }
4653 0 : nout1++;
4654 0 : Double_t zv, bz=GetBz();
4655 0 : if ( !track->GetZAt(0.,bz,zv) ) { MarkSeedFree( seed ); seed = 0; continue; }
4656 : //
4657 0 : if (fDisableSecondaries) {
4658 0 : if (TMath::Abs(zv)>fPrimaryDCAZCut) { MarkSeedFree( seed ); seed = 0; continue; }
4659 0 : double yv;
4660 0 : if ( !track->GetZAt(0.,bz,yv) ) { MarkSeedFree( seed ); seed = 0; continue; }
4661 0 : if (TMath::Abs(zv)>fPrimaryDCAZCut) { MarkSeedFree( seed ); seed = 0; continue; }
4662 0 : }
4663 :
4664 : //
4665 : // Z VERTEX CONDITION
4666 0 : if (TMath::Abs(zv-z3)>cuts[2]) {
4667 0 : FollowProlongation(*track, TMath::Max(i2-20,0));
4668 0 : if ( !track->GetZAt(0.,bz,zv) ) continue;
4669 0 : if (TMath::Abs(zv-z3)>cuts[2]){
4670 0 : FollowProlongation(*track, TMath::Max(i2-40,0));
4671 0 : if ( !track->GetZAt(0.,bz,zv) ) continue;
4672 0 : if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
4673 : // make seed without constrain
4674 0 : AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
4675 0 : FollowProlongation(*track2, i2,1);
4676 0 : track2->SetBConstrain(kFALSE);
4677 0 : track2->SetSeedType(1);
4678 0 : arr->AddLast(track2);
4679 0 : MarkSeedFree( seed ); seed = 0;
4680 : continue;
4681 : }
4682 : else{
4683 0 : MarkSeedFree( seed ); seed = 0;
4684 0 : continue;
4685 :
4686 : }
4687 : }
4688 : }
4689 :
4690 0 : track->SetSeedType(0);
4691 0 : arr->AddLast(track); // note, track is seed, don't free the seed
4692 0 : seed = new( NextFreeSeed() ) AliTPCseed;
4693 0 : seed->SetPoolID(fLastSeedID);
4694 0 : nout2++;
4695 : // don't consider other combinations
4696 0 : if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
4697 0 : break;
4698 0 : }
4699 : }
4700 0 : }
4701 0 : if (fDebug>3){
4702 0 : Info("MakeSeeds3Dist","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
4703 0 : }
4704 0 : if (seed) MarkSeedFree( seed );
4705 0 : }
4706 :
4707 :
4708 : void AliTPCtracker::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
4709 : Float_t deltay) {
4710 :
4711 :
4712 :
4713 : //-----------------------------------------------------------------
4714 : // This function creates track seeds.
4715 : //-----------------------------------------------------------------
4716 : // cuts[0] - fP4 cut
4717 : // cuts[1] - tan(phi) cut
4718 : // cuts[2] - zvertex cut
4719 : // cuts[3] - fP3 cut
4720 :
4721 :
4722 : Int_t nin0 = 0;
4723 : Int_t nin1 = 0;
4724 : Int_t nin2 = 0;
4725 : Int_t nin = 0;
4726 : Int_t nout1 = 0;
4727 : Int_t nout2 = 0;
4728 : Int_t nout3 =0;
4729 12672 : Double_t x[5], c[15];
4730 : //
4731 : // make temporary seed
4732 6336 : AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
4733 6336 : seed->SetPoolID(fLastSeedID);
4734 6336 : Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
4735 : // Double_t cs=cos(alpha), sn=sin(alpha);
4736 : //
4737 : //
4738 :
4739 : // first 3 padrows
4740 6336 : Double_t x1 = GetXrow(i1-1);
4741 6336 : const AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
4742 6336 : Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
4743 : //
4744 6336 : Double_t x1p = GetXrow(i1);
4745 6336 : const AliTPCtrackerRow& kr1p=GetRow(sec,i1);
4746 : //
4747 6336 : Double_t x1m = GetXrow(i1-2);
4748 6336 : const AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
4749 :
4750 : //
4751 : //last 3 padrow for seeding
4752 6336 : AliTPCtrackerRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
4753 6336 : Double_t x3 = GetXrow(i1-7);
4754 : // Double_t y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;
4755 : //
4756 6336 : AliTPCtrackerRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
4757 6336 : Double_t x3p = GetXrow(i1-6);
4758 : //
4759 6336 : AliTPCtrackerRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
4760 6336 : Double_t x3m = GetXrow(i1-8);
4761 :
4762 : //
4763 : //
4764 : // middle padrow
4765 6336 : Int_t im = i1-4; //middle pad row index
4766 6336 : Double_t xm = GetXrow(im); // radius of middle pad-row
4767 6336 : const AliTPCtrackerRow& krm=GetRow(sec,im); //middle pad -row
4768 : // Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;
4769 : //
4770 : //
4771 6336 : Double_t deltax = x1-x3;
4772 6336 : Double_t dymax = deltax*cuts[1];
4773 6336 : Double_t dzmax = deltax*cuts[3];
4774 : //
4775 : // loop over clusters
4776 32240 : for (Int_t is=0; is < kr1; is++) {
4777 : //
4778 9784 : if (kr1[is]->IsUsed(10)) continue;
4779 5284 : if (kr1[is]->IsDisabled()) {
4780 : continue;
4781 : }
4782 :
4783 5284 : Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
4784 : //
4785 7728 : if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
4786 : //
4787 4354 : Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
4788 4354 : Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
4789 : //
4790 : Double_t y3, z3;
4791 : //
4792 : //
4793 4354 : UInt_t index;
4794 27000 : for (Int_t js=index1; js < index2; js++) {
4795 9146 : const AliTPCclusterMI *kcl = kr3[js];
4796 9146 : if (kcl->IsDisabled()) {
4797 0 : continue;
4798 : }
4799 :
4800 11272 : if (kcl->IsUsed(10)) continue;
4801 7020 : y3 = kcl->GetY();
4802 : // apply angular cuts
4803 8114 : if (TMath::Abs(y1-y3)>dymax) continue;
4804 : //x3 = x3;
4805 5926 : z3 = kcl->GetZ();
4806 8278 : if (TMath::Abs(z1-z3)>dzmax) continue;
4807 : //
4808 3574 : Double_t angley = (y1-y3)/(x1-x3);
4809 3574 : Double_t anglez = (z1-z3)/(x1-x3);
4810 : //
4811 3574 : Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
4812 3574 : Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
4813 : //
4814 3574 : Double_t yyym = angley*(xm-x1)+y1;
4815 3574 : Double_t zzzm = anglez*(xm-x1)+z1;
4816 :
4817 3574 : const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry+fClExtraRoadY,errz+fClExtraRoadZ,index);
4818 6566 : if (!kcm) continue;
4819 590 : if (kcm->IsUsed(10)) continue;
4820 574 : if (kcm->IsDisabled()) {
4821 0 : continue;
4822 : }
4823 :
4824 574 : erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
4825 574 : errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
4826 : //
4827 : //
4828 : //
4829 : Int_t used =0;
4830 : Int_t found =0;
4831 : //
4832 : // look around first
4833 1148 : const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
4834 574 : anglez*(x1m-x1)+z1,
4835 574 : erry+fClExtraRoadY,errz+fClExtraRoadZ,index);
4836 : //
4837 574 : if (kc1m){
4838 : found++;
4839 460 : if (kc1m->IsUsed(10)) used++;
4840 : }
4841 1148 : const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
4842 574 : anglez*(x1p-x1)+z1,
4843 574 : erry+fClExtraRoadY,errz+fClExtraRoadZ,index);
4844 : //
4845 574 : if (kc1p){
4846 354 : found++;
4847 354 : if (kc1p->IsUsed(10)) used++;
4848 : }
4849 574 : if (used>1) continue;
4850 672 : if (found<1) continue;
4851 :
4852 : //
4853 : // look around last
4854 952 : const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
4855 476 : anglez*(x3m-x3)+z3,
4856 476 : erry+fClExtraRoadY,errz+fClExtraRoadZ,index);
4857 : //
4858 476 : if (kc3m){
4859 348 : found++;
4860 348 : if (kc3m->IsUsed(10)) used++;
4861 : }
4862 : else
4863 128 : continue;
4864 696 : const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
4865 348 : anglez*(x3p-x3)+z3,
4866 348 : erry+fClExtraRoadY,errz+fClExtraRoadZ,index);
4867 : //
4868 348 : if (kc3p){
4869 334 : found++;
4870 334 : if (kc3p->IsUsed(10)) used++;
4871 : }
4872 : else
4873 14 : continue;
4874 334 : if (used>1) continue;
4875 334 : if (found<3) continue;
4876 : //
4877 : Double_t x2,y2,z2;
4878 : x2 = xm;
4879 334 : y2 = kcm->GetY();
4880 334 : z2 = kcm->GetZ();
4881 : //
4882 :
4883 334 : x[0]=y1;
4884 334 : x[1]=z1;
4885 334 : x[4]=F1(x1,y1,x2,y2,x3,y3);
4886 : //if (TMath::Abs(x[4]) >= cuts[0]) continue;
4887 334 : nin0++;
4888 : //
4889 334 : x[2]=F2(x1,y1,x2,y2,x3,y3);
4890 334 : nin1++;
4891 : //
4892 334 : x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
4893 : //if (TMath::Abs(x[3]) > cuts[3]) continue;
4894 334 : nin2++;
4895 : //
4896 : //
4897 : Double_t sy1=0.1, sz1=0.1;
4898 : Double_t sy2=0.1, sz2=0.1;
4899 : Double_t sy3=0.1, sy=0.1, sz=0.1;
4900 :
4901 334 : Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
4902 334 : Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
4903 334 : Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
4904 334 : Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
4905 334 : Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
4906 334 : Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
4907 :
4908 334 : Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
4909 334 : Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
4910 334 : Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
4911 334 : Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
4912 :
4913 334 : c[0]=sy1;
4914 334 : c[1]=0.; c[2]=sz1;
4915 334 : c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4916 334 : c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4917 334 : c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4918 334 : c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4919 334 : c[13]=f30*sy1*f40+f32*sy2*f42;
4920 334 : c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4921 :
4922 : // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
4923 :
4924 334 : index=kr1.GetIndex(is);
4925 504 : if (seed) {MarkSeedFree( seed ); seed = 0;}
4926 334 : AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, sec*alpha+shift, x, c, index);
4927 334 : seed->SetPoolID(fLastSeedID);
4928 334 : seed->SetRow(i1-1); //RS: memorise current row
4929 334 : track->SetIsSeeding(kTRUE);
4930 :
4931 334 : nin++;
4932 334 : FollowProlongation(*track, i1-7,1);
4933 640 : if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
4934 612 : track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6+fExtraClErrYZ2){
4935 28 : MarkSeedFree( seed ); seed = 0;
4936 28 : continue;
4937 : }
4938 306 : nout1++;
4939 306 : nout2++;
4940 : //Int_t rc = 1;
4941 306 : FollowProlongation(*track, i2,1);
4942 306 : track->SetBConstrain(0);
4943 306 : track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
4944 306 : track->SetFirstPoint(track->GetLastPoint());
4945 :
4946 418 : if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
4947 116 : track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
4948 336 : track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5+fExtraClErrYZ2) {
4949 222 : MarkSeedFree( seed ); seed = 0;
4950 222 : continue;
4951 : }
4952 :
4953 : {
4954 84 : FollowProlongation(*track, TMath::Max(i2-10,0),1);
4955 84 : AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
4956 84 : FollowProlongation(*track2, i2,1);
4957 84 : track2->SetBConstrain(kFALSE);
4958 84 : track2->SetSeedType(4);
4959 84 : arr->AddLast(track2);
4960 84 : MarkSeedFree( seed ); seed = 0;
4961 : }
4962 :
4963 :
4964 : //arr->AddLast(track);
4965 : //seed = new AliTPCseed;
4966 84 : nout3++;
4967 84 : }
4968 4354 : }
4969 :
4970 6336 : if (fDebug>3){
4971 0 : Info("MakeSeeds5","\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
4972 0 : }
4973 12502 : if (seed) MarkSeedFree(seed);
4974 6336 : }
4975 :
4976 : void AliTPCtracker::MakeSeeds5Dist(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
4977 : Float_t deltay) {
4978 :
4979 :
4980 :
4981 : //-----------------------------------------------------------------
4982 : // This function creates track seeds, accounting for distortions
4983 : //-----------------------------------------------------------------
4984 : // cuts[0] - fP4 cut
4985 : // cuts[1] - tan(phi) cut
4986 : // cuts[2] - zvertex cut
4987 : // cuts[3] - fP3 cut
4988 :
4989 :
4990 : Int_t nin0 = 0;
4991 : Int_t nin1 = 0;
4992 : Int_t nin2 = 0;
4993 : Int_t nin = 0;
4994 : Int_t nout1 = 0;
4995 : Int_t nout2 = 0;
4996 : Int_t nout3 =0;
4997 0 : Double_t x[5], c[15];
4998 : //
4999 : // make temporary seed
5000 0 : AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
5001 0 : seed->SetPoolID(fLastSeedID);
5002 0 : Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
5003 : // Double_t cs=cos(alpha), sn=sin(alpha);
5004 : //
5005 : //
5006 :
5007 : // first 3 padrows
5008 0 : Double_t x1Def = GetXrow(i1-1);
5009 0 : const AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
5010 0 : Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
5011 : //
5012 0 : Double_t x1pDef = GetXrow(i1);
5013 0 : const AliTPCtrackerRow& kr1p=GetRow(sec,i1);
5014 : //
5015 0 : Double_t x1mDef = GetXrow(i1-2);
5016 0 : const AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
5017 :
5018 0 : double dx11mDef = x1Def-x1mDef;
5019 0 : double dx11pDef = x1Def-x1pDef;
5020 : //
5021 : //last 3 padrow for seeding
5022 0 : AliTPCtrackerRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
5023 0 : Double_t x3Def = GetXrow(i1-7);
5024 : //
5025 0 : AliTPCtrackerRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
5026 0 : Double_t x3pDef = GetXrow(i1-6);
5027 : //
5028 0 : AliTPCtrackerRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
5029 0 : Double_t x3mDef = GetXrow(i1-8);
5030 :
5031 : //
5032 0 : double dx33mDef = x3Def-x3mDef;
5033 0 : double dx33pDef = x3Def-x3pDef;
5034 :
5035 : //
5036 : // middle padrow
5037 0 : Int_t im = i1-4; //middle pad row index
5038 0 : Double_t xmDef = GetXrow(im); // radius of middle pad-row
5039 0 : const AliTPCtrackerRow& krm=GetRow(sec,im); //middle pad -row
5040 : //
5041 : //
5042 0 : Double_t deltax = x1Def-x3Def;
5043 0 : Double_t dymax = deltax*cuts[1];
5044 0 : Double_t dzmax = deltax*cuts[3];
5045 : //
5046 : // loop over clusters
5047 0 : for (Int_t is=0; is < kr1; is++) {
5048 : //
5049 0 : if (kr1[is]->IsUsed(10)) continue;
5050 0 : if (kr1[is]->IsDisabled()) {
5051 : continue;
5052 : }
5053 0 : const AliTPCclusterMI* clkr1 = kr1[is];
5054 0 : Double_t x1=clkr1->GetX(), y1=clkr1->GetY(), z1=clkr1->GetZ();
5055 : //
5056 : double y1EdgeDist = y1;
5057 0 : if (fAccountDistortions) y1EdgeDist -= GetYSectEdgeDist(sec,i1-1,y1,z1);
5058 0 : if (deltay>0) {
5059 0 : double margin = (y1>0 ? y1max-y1EdgeDist : y1max + y1EdgeDist);
5060 0 : if (margin<deltay ) continue; // seed only at the edge
5061 0 : }
5062 :
5063 : //
5064 0 : Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
5065 0 : Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
5066 : //
5067 : Double_t x3,y3,z3;
5068 : //
5069 : //
5070 0 : UInt_t index;
5071 0 : for (Int_t js=index1; js < index2; js++) {
5072 0 : const AliTPCclusterMI *kcl = kr3[js];
5073 0 : if (kcl->IsDisabled()) {
5074 0 : continue;
5075 : }
5076 :
5077 0 : if (kcl->IsUsed(10)) continue;
5078 0 : y3 = kcl->GetY();
5079 : // apply angular cuts
5080 0 : if (TMath::Abs(y1-y3)>dymax) continue;
5081 : //x3 = x3;
5082 0 : z3 = kcl->GetZ();
5083 0 : if (TMath::Abs(z1-z3)>dzmax) continue;
5084 :
5085 0 : x3 = kcl->GetX();
5086 : //
5087 0 : double dx13 = x1-x3;
5088 0 : if (TMath::Abs(dx13)<0.1) {
5089 : //AliErrorF("Wrong X correction? Sec%d : row%d@X=%.2f->%.2f (z=%.2f) row%d@X=%.2f->%.2f (z=%.2f)\n",sec,
5090 : // i1-1,x1Def,x1,z1, i1-7,x3Def,x3,z3);
5091 0 : continue; // distortions should not make distance so small
5092 : }
5093 :
5094 0 : Double_t angley = (y1-y3)/dx13;
5095 0 : Double_t anglez = (z1-z3)/dx13;
5096 : //
5097 0 : Double_t erry = TMath::Abs(angley)*dx11mDef*0.5+0.5; // RS: use ideal X differences assuming
5098 0 : Double_t errz = TMath::Abs(anglez)*dx11mDef*0.5+0.5; // that the distortions are ~same on close rows
5099 : //
5100 0 : Double_t yyym = angley*(xmDef-x1Def)+y1; // RS: idem, assume distortions cancels in the difference
5101 0 : Double_t zzzm = anglez*(xmDef-x1Def)+z1;
5102 :
5103 0 : const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry+fClExtraRoadY,errz+fClExtraRoadZ,index);
5104 0 : if (!kcm) continue;
5105 0 : if (kcm->IsUsed(10)) continue;
5106 0 : if (kcm->IsDisabled()) {
5107 0 : continue;
5108 : }
5109 :
5110 0 : erry = TMath::Abs(angley)*dx11mDef*0.4+0.5;
5111 0 : errz = TMath::Abs(anglez)*dx11mDef*0.4+0.5;
5112 : //
5113 : //
5114 : //
5115 : Int_t used =0;
5116 : Int_t found =0;
5117 : //
5118 : // look around first
5119 0 : const AliTPCclusterMI *kc1m = kr1m.FindNearest2(-angley*dx11mDef+y1, // RS: idem, assume distortions cancels in the difference
5120 0 : -anglez*dx11mDef+z1,
5121 0 : erry+fClExtraRoadY,errz+fClExtraRoadZ,index);
5122 : //
5123 0 : if (kc1m){
5124 : found++;
5125 0 : if (kc1m->IsUsed(10)) used++;
5126 : }
5127 0 : const AliTPCclusterMI *kc1p = kr1p.FindNearest2(-angley*dx11pDef+y1, // RS: idem, assume distortions cancels in the difference
5128 0 : -anglez*dx11pDef+z1,
5129 0 : erry+fClExtraRoadY,errz+fClExtraRoadZ,index);
5130 : //
5131 0 : if (kc1p){
5132 0 : found++;
5133 0 : if (kc1p->IsUsed(10)) used++;
5134 : }
5135 0 : if (used>1) continue;
5136 0 : if (found<1) continue;
5137 :
5138 : //
5139 : // look around last
5140 0 : const AliTPCclusterMI *kc3m = kr3m.FindNearest2(-angley*dx33mDef+y3, // RS: idem, assume distortions cancels in the difference
5141 0 : -anglez*dx33mDef+z3,
5142 0 : erry+fClExtraRoadY,errz+fClExtraRoadZ,index);
5143 : //
5144 0 : if (kc3m){
5145 0 : found++;
5146 0 : if (kc3m->IsUsed(10)) used++;
5147 : }
5148 : else
5149 0 : continue;
5150 0 : const AliTPCclusterMI *kc3p = kr3p.FindNearest2(-angley*dx33pDef+y3, // RS: idem, assume distortions cancels in the difference
5151 0 : -anglez*dx33pDef+z3,
5152 0 : erry+fClExtraRoadY,errz+fClExtraRoadZ,index);
5153 : //
5154 0 : if (kc3p){
5155 0 : found++;
5156 0 : if (kc3p->IsUsed(10)) used++;
5157 : }
5158 : else
5159 0 : continue;
5160 0 : if (used>1) continue;
5161 0 : if (found<3) continue;
5162 : //
5163 : Double_t x2,y2,z2;
5164 0 : x2 = kcm->GetX();
5165 0 : y2 = kcm->GetY();
5166 0 : z2 = kcm->GetZ();
5167 : //
5168 :
5169 0 : x[0]=y1;
5170 0 : x[1]=z1;
5171 0 : x[4]=F1(x1,y1,x2,y2,x3,y3);
5172 : //if (TMath::Abs(x[4]) >= cuts[0]) continue;
5173 0 : nin0++;
5174 : //
5175 0 : x[2]=F2(x1,y1,x2,y2,x3,y3);
5176 0 : nin1++;
5177 : //
5178 0 : x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
5179 : //if (TMath::Abs(x[3]) > cuts[3]) continue;
5180 0 : nin2++;
5181 : //
5182 : //
5183 : Double_t sy1=0.1, sz1=0.1;
5184 : Double_t sy2=0.1, sz2=0.1;
5185 : Double_t sy3=0.1, sy=0.1, sz=0.1;
5186 :
5187 0 : Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
5188 0 : Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
5189 0 : Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
5190 0 : Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
5191 0 : Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
5192 0 : Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
5193 :
5194 0 : Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
5195 0 : Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
5196 0 : Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
5197 0 : Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
5198 :
5199 0 : c[0]=sy1;
5200 0 : c[1]=0.; c[2]=sz1;
5201 0 : c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
5202 0 : c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
5203 0 : c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
5204 0 : c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
5205 0 : c[13]=f30*sy1*f40+f32*sy2*f42;
5206 0 : c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
5207 :
5208 : // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
5209 :
5210 0 : index=kr1.GetIndex(is);
5211 0 : if (seed) {MarkSeedFree( seed ); seed = 0;}
5212 0 : AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, sec*alpha+shift, x, c, index);
5213 0 : seed->SetPoolID(fLastSeedID);
5214 0 : seed->SetRow(i1-1); // RS: memorise current row
5215 0 : track->SetIsSeeding(kTRUE);
5216 :
5217 0 : nin++;
5218 0 : FollowProlongation(*track, i1-7,1);
5219 0 : if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
5220 0 : track->GetNShared()>0.6*track->GetNumberOfClusters()) {
5221 : //RS: with distortions related cluster errors the track error may grow, don't use this cut
5222 : //|| ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
5223 0 : MarkSeedFree( seed ); seed = 0;
5224 0 : continue;
5225 : }
5226 0 : nout1++;
5227 0 : nout2++;
5228 : //Int_t rc = 1;
5229 0 : FollowProlongation(*track, i2,1);
5230 0 : track->SetBConstrain(0);
5231 0 : track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
5232 0 : track->SetFirstPoint(track->GetLastPoint());
5233 :
5234 0 : if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
5235 0 : track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
5236 0 : track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6) {
5237 : //RS: with distortions related cluster errors the track error may grow, don't use this cut
5238 : //|| ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
5239 0 : MarkSeedFree( seed ); seed = 0;
5240 0 : continue;
5241 : }
5242 :
5243 : {
5244 0 : FollowProlongation(*track, TMath::Max(i2-10,0),1);
5245 0 : AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
5246 0 : FollowProlongation(*track2, i2,1);
5247 0 : track2->SetBConstrain(kFALSE);
5248 0 : track2->SetSeedType(4);
5249 0 : arr->AddLast(track2);
5250 0 : MarkSeedFree( seed ); seed = 0;
5251 : }
5252 :
5253 :
5254 : //arr->AddLast(track);
5255 : //seed = new AliTPCseed;
5256 0 : nout3++;
5257 0 : }
5258 0 : }
5259 :
5260 0 : if (fDebug>3){
5261 0 : Info("MakeSeeds5Dist","\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
5262 0 : }
5263 0 : if (seed) MarkSeedFree(seed);
5264 0 : }
5265 :
5266 :
5267 : //_____________________________________________________________________________
5268 : void AliTPCtracker::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
5269 : Float_t deltay, Bool_t /*bconstrain*/) {
5270 : //-----------------------------------------------------------------
5271 : // This function creates track seeds - without vertex constraint
5272 : //-----------------------------------------------------------------
5273 : // cuts[0] - fP4 cut - not applied
5274 : // cuts[1] - tan(phi) cut
5275 : // cuts[2] - zvertex cut - not applied
5276 : // cuts[3] - fP3 cut
5277 : const double kRoadZ = 1.2, kRoadY = 1.2;
5278 :
5279 : Int_t nin0=0;
5280 : Int_t nin1=0;
5281 : Int_t nin2=0;
5282 : Int_t nin3=0;
5283 : // Int_t nin4=0;
5284 : //Int_t nin5=0;
5285 :
5286 :
5287 :
5288 0 : Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
5289 : // Double_t cs=cos(alpha), sn=sin(alpha);
5290 0 : Int_t row0 = (i1+i2)/2;
5291 0 : Int_t drow = (i1-i2)/2;
5292 0 : const AliTPCtrackerRow& kr0=fSectors[sec][row0];
5293 : AliTPCtrackerRow * kr=0;
5294 :
5295 0 : AliTPCpolyTrack polytrack;
5296 0 : Int_t nclusters=fSectors[sec][row0];
5297 0 : AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
5298 0 : seed->SetPoolID(fLastSeedID);
5299 :
5300 : Int_t sumused=0;
5301 : Int_t cused=0;
5302 : Int_t cnused=0;
5303 0 : for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
5304 : Int_t nfound =0;
5305 : Int_t nfoundable =0;
5306 0 : for (Int_t iter =1; iter<2; iter++){ //iterations
5307 0 : const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
5308 0 : const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];
5309 0 : const AliTPCclusterMI * cl= kr0[is];
5310 0 : if (cl->IsDisabled()) {
5311 0 : continue;
5312 : }
5313 :
5314 0 : if (cl->IsUsed(10)) {
5315 0 : cused++;
5316 0 : }
5317 : else{
5318 0 : cnused++;
5319 : }
5320 0 : Double_t x = kr0.GetX();
5321 : // Initialization of the polytrack
5322 : nfound =0;
5323 : nfoundable =0;
5324 0 : polytrack.Reset();
5325 : //
5326 0 : Double_t y0= cl->GetY();
5327 0 : Double_t z0= cl->GetZ();
5328 : Float_t erry = 0;
5329 : Float_t errz = 0;
5330 :
5331 0 : Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
5332 0 : if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
5333 :
5334 0 : erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
5335 0 : errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
5336 0 : polytrack.AddPoint(x,y0,z0,erry, errz);
5337 :
5338 : sumused=0;
5339 0 : if (cl->IsUsed(10)) sumused++;
5340 :
5341 :
5342 0 : Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
5343 0 : Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
5344 : //
5345 0 : x = krm.GetX();
5346 0 : AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady+fClExtraRoadY,roadz+fClExtraRoadZ);
5347 0 : if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
5348 0 : erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
5349 0 : errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
5350 0 : if (cl1->IsUsed(10)) sumused++;
5351 0 : polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
5352 : }
5353 : //
5354 0 : x = krp.GetX();
5355 0 : AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady+fClExtraRoadY,roadz+fClExtraRoadZ);
5356 0 : if (cl2) {
5357 0 : erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
5358 0 : errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
5359 0 : if (cl2->IsUsed(10)) sumused++;
5360 0 : polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
5361 : }
5362 : //
5363 0 : if (sumused>0) continue;
5364 0 : nin0++;
5365 0 : polytrack.UpdateParameters();
5366 : // follow polytrack
5367 : //
5368 0 : Double_t yn,zn;
5369 0 : nfoundable = polytrack.GetN();
5370 : nfound = nfoundable;
5371 : //
5372 0 : for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
5373 0 : Float_t maxdist = 0.8*(1.+3./(ddrow));
5374 0 : for (Int_t delta = -1;delta<=1;delta+=2){
5375 0 : Int_t row = row0+ddrow*delta;
5376 0 : kr = &(fSectors[sec][row]);
5377 0 : Double_t xn = kr->GetX();
5378 0 : Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
5379 0 : polytrack.GetFitPoint(xn,yn,zn);
5380 0 : if (TMath::Abs(yn)>ymax1) continue;
5381 0 : nfoundable++;
5382 0 : AliTPCclusterMI * cln = kr->FindNearest(yn,zn,kRoadY+fClExtraRoadY,kRoadZ+fClExtraRoadZ);
5383 0 : if (cln) {
5384 0 : Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
5385 0 : if (dist<maxdist){
5386 : /*
5387 : erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
5388 : errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
5389 : if (cln->IsUsed(10)) {
5390 : // printf("used\n");
5391 : sumused++;
5392 : erry*=2;
5393 : errz*=2;
5394 : }
5395 : */
5396 : erry=0.1;
5397 : errz=0.1;
5398 0 : polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
5399 0 : nfound++;
5400 0 : }
5401 0 : }
5402 0 : }
5403 0 : if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
5404 0 : polytrack.UpdateParameters();
5405 0 : }
5406 0 : }
5407 0 : if ( (sumused>3) || (sumused>0.5*nfound)) {
5408 : //printf("sumused %d\n",sumused);
5409 0 : continue;
5410 : }
5411 0 : nin1++;
5412 0 : Double_t dy,dz;
5413 0 : polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
5414 0 : AliTPCpolyTrack track2;
5415 :
5416 0 : polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
5417 0 : if (track2.GetN()<0.5*nfoundable) continue;
5418 0 : nin2++;
5419 :
5420 0 : if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
5421 : //
5422 : // test seed with and without constrain
5423 0 : for (Int_t constrain=0; constrain<=0;constrain++){
5424 : // add polytrack candidate
5425 :
5426 0 : Double_t x[5], c[15];
5427 0 : Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
5428 0 : track2.GetBoundaries(x3,x1);
5429 0 : x2 = (x1+x3)/2.;
5430 0 : track2.GetFitPoint(x1,y1,z1);
5431 0 : track2.GetFitPoint(x2,y2,z2);
5432 0 : track2.GetFitPoint(x3,y3,z3);
5433 : //
5434 : //is track pointing to the vertex ?
5435 0 : Double_t x0,y0,z0;
5436 : x0=0;
5437 0 : polytrack.GetFitPoint(x0,y0,z0);
5438 :
5439 0 : if (constrain) {
5440 0 : x2 = x3;
5441 0 : y2 = y3;
5442 0 : z2 = z3;
5443 :
5444 0 : x3 = 0;
5445 0 : y3 = 0;
5446 0 : z3 = 0;
5447 0 : }
5448 0 : x[0]=y1;
5449 0 : x[1]=z1;
5450 0 : x[4]=F1(x1,y1,x2,y2,x3,y3);
5451 :
5452 : // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
5453 0 : x[2]=F2(x1,y1,x2,y2,x3,y3);
5454 :
5455 : //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
5456 : //x[3]=F3(x1,y1,x2,y2,z1,z2);
5457 0 : x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
5458 : //if (TMath::Abs(x[3]) > cuts[3]) continue;
5459 :
5460 :
5461 : Double_t sy =0.1, sz =0.1;
5462 : Double_t sy1=0.02, sz1=0.02;
5463 : Double_t sy2=0.02, sz2=0.02;
5464 : Double_t sy3=0.02;
5465 :
5466 0 : if (constrain){
5467 0 : sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
5468 0 : }
5469 :
5470 0 : Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
5471 0 : Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
5472 0 : Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
5473 0 : Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
5474 0 : Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
5475 0 : Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
5476 :
5477 0 : Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
5478 0 : Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
5479 0 : Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
5480 0 : Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
5481 :
5482 :
5483 0 : c[0]=sy1;
5484 0 : c[1]=0.; c[2]=sz1;
5485 0 : c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
5486 0 : c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
5487 0 : c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
5488 0 : c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
5489 0 : c[13]=f30*sy1*f40+f32*sy2*f42;
5490 0 : c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
5491 :
5492 : //Int_t row1 = fSectors->GetRowNumber(x1);
5493 0 : Int_t row1 = GetRowNumber(x1);
5494 :
5495 : UInt_t index=0;
5496 : //kr0.GetIndex(is);
5497 0 : if (seed) {MarkSeedFree( seed ); seed = 0;}
5498 0 : AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1,sec*alpha+shift,x,c,index);
5499 0 : seed->SetPoolID(fLastSeedID);
5500 0 : track->SetIsSeeding(kTRUE);
5501 0 : Int_t rc=FollowProlongation(*track, i2);
5502 0 : if (constrain) track->SetBConstrain(1);
5503 : else
5504 0 : track->SetBConstrain(0);
5505 0 : track->SetLastPoint(row1+fInnerSec->GetNRows()); // first cluster in track position
5506 0 : track->SetFirstPoint(track->GetLastPoint());
5507 :
5508 0 : if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
5509 0 : track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
5510 0 : track->GetNShared()>0.4*track->GetNumberOfClusters()) {
5511 0 : MarkSeedFree( seed ); seed = 0;
5512 0 : }
5513 : else {
5514 0 : arr->AddLast(track); // track IS seed, don't free seed
5515 0 : seed = new( NextFreeSeed() ) AliTPCseed;
5516 0 : seed->SetPoolID(fLastSeedID);
5517 : }
5518 0 : nin3++;
5519 0 : }
5520 0 : } // if accepted seed
5521 0 : }
5522 0 : if (fDebug>3){
5523 0 : Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
5524 : }
5525 0 : if (seed) MarkSeedFree( seed );
5526 0 : }
5527 :
5528 : //_____________________________________________________________________________
5529 : void AliTPCtracker::MakeSeeds2Dist(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
5530 : Float_t deltay, Bool_t /*bconstrain*/) {
5531 : //-----------------------------------------------------------------
5532 : // This function creates track seeds, accounting for distortions - without vertex constraint
5533 : //-----------------------------------------------------------------
5534 : // cuts[0] - fP4 cut - not applied
5535 : // cuts[1] - tan(phi) cut
5536 : // cuts[2] - zvertex cut - not applied
5537 : // cuts[3] - fP3 cut
5538 : const double kRoadZ = 1.2, kRoadY = 1.2;
5539 :
5540 : Int_t nin0=0;
5541 : Int_t nin1=0;
5542 : Int_t nin2=0;
5543 : Int_t nin3=0;
5544 : // Int_t nin4=0;
5545 : //Int_t nin5=0;
5546 :
5547 0 : AliFatal("This method is still not fully aware of distortions, should not be used");
5548 0 : Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
5549 : // Double_t cs=cos(alpha), sn=sin(alpha);
5550 0 : Int_t row0 = (i1+i2)/2;
5551 0 : Int_t drow = (i1-i2)/2;
5552 0 : const AliTPCtrackerRow& kr0=fSectors[sec][row0];
5553 : AliTPCtrackerRow * kr=0;
5554 :
5555 0 : AliTPCpolyTrack polytrack;
5556 0 : Int_t nclusters=fSectors[sec][row0];
5557 0 : AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
5558 0 : seed->SetPoolID(fLastSeedID);
5559 :
5560 : Int_t sumused=0;
5561 : Int_t cused=0;
5562 : Int_t cnused=0;
5563 : Int_t rowMax = -1;
5564 : //
5565 0 : for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
5566 : Int_t nfound =0;
5567 : Int_t nfoundable =0;
5568 0 : for (Int_t iter =1; iter<2; iter++){ //iterations
5569 0 : const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
5570 0 : const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];
5571 0 : const AliTPCclusterMI * cl= kr0[is];
5572 0 : if (cl->IsDisabled()) {
5573 0 : continue;
5574 : }
5575 :
5576 0 : if (cl->IsUsed(10)) {
5577 0 : cused++;
5578 0 : }
5579 : else{
5580 0 : cnused++;
5581 : }
5582 :
5583 0 : Double_t x = cl->GetX(), xDist = x - kr0.GetX(); // approximate X distortion in proximity of cl
5584 : // Initialization of the polytrack
5585 : nfound =0;
5586 : nfoundable =0;
5587 0 : polytrack.Reset();
5588 : //
5589 0 : Double_t y0= cl->GetY();
5590 0 : Double_t z0= cl->GetZ();
5591 : Float_t erry = 0;
5592 : Float_t errz = 0;
5593 :
5594 0 : Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5; // RS: watch dead zones
5595 0 : if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
5596 :
5597 0 : erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
5598 0 : errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
5599 0 : polytrack.AddPoint(x,y0,z0,erry, errz);
5600 : rowMax = row0;
5601 : sumused=0;
5602 0 : if (cl->IsUsed(10)) sumused++;
5603 :
5604 :
5605 0 : Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
5606 0 : Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
5607 : //
5608 0 : x = krm.GetX() + xDist; // RS: assume distortion at krm is similar to that at kr
5609 0 : AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady+fClExtraRoadY,roadz+fClExtraRoadZ);
5610 0 : if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
5611 0 : erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
5612 0 : errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
5613 0 : if (cl1->IsUsed(10)) sumused++;
5614 : //RS: use real cluster X instead of approximately distorted
5615 0 : polytrack.AddPoint(cl1->GetX(),cl1->GetY(),cl1->GetZ(),erry,errz);
5616 : }
5617 : //
5618 0 : x = krp.GetX() + xDist; // RS: assume distortion at krp is similar to that at kr
5619 0 : AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady+fClExtraRoadY,roadz+fClExtraRoadZ);
5620 0 : if (cl2) {
5621 0 : erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
5622 0 : errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
5623 0 : if (cl2->IsUsed(10)) sumused++;
5624 : //RS: use real cluster X instead of approximately distorted
5625 0 : polytrack.AddPoint(cl2->GetX(),cl2->GetY(),cl2->GetZ(),erry,errz);
5626 : rowMax = row0+iter;
5627 0 : }
5628 : //
5629 0 : if (sumused>0) continue;
5630 0 : nin0++;
5631 0 : polytrack.UpdateParameters();
5632 : // follow polytrack
5633 : //
5634 0 : Double_t yn,zn;
5635 0 : nfoundable = polytrack.GetN();
5636 : nfound = nfoundable;
5637 : //
5638 0 : for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
5639 0 : Float_t maxdist = 0.8*(1.+3./(ddrow));
5640 0 : for (Int_t delta = -1;delta<=1;delta+=2){
5641 0 : Int_t row = row0+ddrow*delta;
5642 0 : kr = &(fSectors[sec][row]);
5643 0 : Double_t xn = kr->GetX(); //RS: use row X as a first guess about distorted cluster x
5644 0 : Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5; // RS: watch dead zones
5645 0 : polytrack.GetFitPoint(xn,yn,zn);
5646 0 : double dxn = GetDistortionX(xn, yn, zn, sec, row);
5647 0 : if (TMath::Abs(dxn)>0.1) { //RS: account for distortion
5648 0 : xn += dxn;
5649 0 : polytrack.GetFitPoint(xn,yn,zn);
5650 0 : }
5651 : //
5652 0 : if (TMath::Abs(yn)>ymax1) continue; // RS:? watch dead zones
5653 0 : nfoundable++;
5654 0 : AliTPCclusterMI * cln = kr->FindNearest(yn,zn,kRoadY+fClExtraRoadY,kRoadZ+fClExtraRoadZ);
5655 0 : if (cln) {
5656 0 : Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
5657 0 : if (dist<maxdist){
5658 : /*
5659 : erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
5660 : errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
5661 : if (cln->IsUsed(10)) {
5662 : // printf("used\n");
5663 : sumused++;
5664 : erry*=2;
5665 : errz*=2;
5666 : }
5667 : */
5668 : erry=0.1;
5669 : errz=0.1;
5670 0 : polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
5671 0 : if (row>rowMax) rowMax = row;
5672 0 : nfound++;
5673 0 : }
5674 0 : }
5675 0 : }
5676 0 : if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
5677 0 : polytrack.UpdateParameters();
5678 0 : }
5679 0 : }
5680 0 : if ( (sumused>3) || (sumused>0.5*nfound)) {
5681 : //printf("sumused %d\n",sumused);
5682 0 : continue;
5683 : }
5684 0 : nin1++;
5685 0 : Double_t dy,dz;
5686 0 : polytrack.GetFitDerivation(kr0.GetX(),dy,dz); // RS: Note: derivative is at ideal row X
5687 0 : AliTPCpolyTrack track2;
5688 :
5689 0 : polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
5690 0 : if (track2.GetN()<0.5*nfoundable) continue;
5691 0 : nin2++;
5692 :
5693 0 : if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
5694 : //
5695 : // test seed with and without constrain
5696 0 : for (Int_t constrain=0; constrain<=0;constrain++){
5697 : // add polytrack candidate
5698 :
5699 0 : Double_t x[5], c[15];
5700 0 : Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
5701 0 : track2.GetBoundaries(x3,x1);
5702 0 : x2 = (x1+x3)/2.;
5703 0 : track2.GetFitPoint(x1,y1,z1);
5704 0 : track2.GetFitPoint(x2,y2,z2);
5705 0 : track2.GetFitPoint(x3,y3,z3);
5706 : //
5707 : //is track pointing to the vertex ?
5708 0 : Double_t x0,y0,z0;
5709 : x0=0;
5710 0 : polytrack.GetFitPoint(x0,y0,z0);
5711 :
5712 0 : if (constrain) {
5713 0 : x2 = x3;
5714 0 : y2 = y3;
5715 0 : z2 = z3;
5716 :
5717 0 : x3 = 0;
5718 0 : y3 = 0;
5719 0 : z3 = 0;
5720 0 : }
5721 0 : x[0]=y1;
5722 0 : x[1]=z1;
5723 0 : x[4]=F1(x1,y1,x2,y2,x3,y3);
5724 :
5725 : // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
5726 0 : x[2]=F2(x1,y1,x2,y2,x3,y3);
5727 :
5728 : //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
5729 : //x[3]=F3(x1,y1,x2,y2,z1,z2);
5730 0 : x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
5731 : //if (TMath::Abs(x[3]) > cuts[3]) continue;
5732 :
5733 :
5734 : Double_t sy =0.1, sz =0.1;
5735 : Double_t sy1=0.02, sz1=0.02;
5736 : Double_t sy2=0.02, sz2=0.02;
5737 : Double_t sy3=0.02;
5738 :
5739 0 : if (constrain){
5740 0 : sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
5741 0 : }
5742 :
5743 0 : Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
5744 0 : Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
5745 0 : Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
5746 0 : Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
5747 0 : Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
5748 0 : Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
5749 :
5750 0 : Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
5751 0 : Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
5752 0 : Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
5753 0 : Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
5754 :
5755 :
5756 0 : c[0]=sy1;
5757 0 : c[1]=0.; c[2]=sz1;
5758 0 : c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
5759 0 : c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
5760 0 : c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
5761 0 : c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
5762 0 : c[13]=f30*sy1*f40+f32*sy2*f42;
5763 0 : c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
5764 :
5765 : //Int_t row1 = GetRowNumber(x1); // RS: this is now substituted by rowMax
5766 :
5767 : UInt_t index=0;
5768 : //kr0.GetIndex(is);
5769 0 : if (seed) {MarkSeedFree( seed ); seed = 0;}
5770 0 : AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1,sec*alpha+shift,x,c,index);
5771 0 : seed->SetPoolID(fLastSeedID);
5772 0 : seed->SetRow(rowMax); //RS: memorise row of x1
5773 0 : track->SetIsSeeding(kTRUE);
5774 0 : Int_t rc=FollowProlongation(*track, i2);
5775 0 : if (constrain) track->SetBConstrain(1);
5776 : else
5777 0 : track->SetBConstrain(0);
5778 0 : track->SetLastPoint(rowMax); //row1+fInnerSec->GetNRows()); // first cluster in track position
5779 0 : track->SetFirstPoint(track->GetLastPoint());
5780 :
5781 0 : if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
5782 0 : track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
5783 0 : track->GetNShared()>0.4*track->GetNumberOfClusters()) {
5784 0 : MarkSeedFree( seed ); seed = 0;
5785 0 : }
5786 : else {
5787 0 : arr->AddLast(track); // track IS seed, don't free seed
5788 0 : seed = new( NextFreeSeed() ) AliTPCseed;
5789 0 : seed->SetPoolID(fLastSeedID);
5790 : }
5791 0 : nin3++;
5792 0 : }
5793 0 : } // if accepted seed
5794 0 : }
5795 0 : if (fDebug>3){
5796 0 : Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
5797 : }
5798 0 : if (seed) MarkSeedFree( seed );
5799 0 : }
5800 :
5801 :
5802 : AliTPCseed *AliTPCtracker::MakeSeed(AliTPCseed *const track, Float_t r0, Float_t r1, Float_t r2)
5803 : {
5804 : //
5805 : //
5806 : //reseed using track points
5807 172 : Int_t p0 = int(r0*track->GetNumberOfClusters()); // point 0
5808 86 : Int_t p1 = int(r1*track->GetNumberOfClusters());
5809 86 : Int_t p2 = int(r2*track->GetNumberOfClusters()); // last point
5810 : Int_t pp2=0;
5811 86 : Double_t x0[3],x1[3],x2[3];
5812 688 : for (Int_t i=0;i<3;i++){
5813 258 : x0[i]=-1;
5814 258 : x1[i]=-1;
5815 258 : x2[i]=-1;
5816 : }
5817 :
5818 : // find track position at given ratio of the length
5819 : Int_t sec0=0, sec1=0, sec2=0;
5820 : Int_t index=-1;
5821 : Int_t clindex;
5822 27520 : for (Int_t i=0;i<kMaxRow;i++){
5823 13674 : if (track->GetClusterIndex2(i)>=0){
5824 2068 : index++;
5825 2068 : const AliTPCTrackerPoints::Point *trpoint =track->GetTrackPoint(i);
5826 3756 : if ( (index<p0) || x0[0]<0 ){
5827 380 : if (trpoint->GetX()>1){
5828 380 : clindex = track->GetClusterIndex2(i);
5829 380 : if (clindex >= 0){
5830 380 : x0[0] = trpoint->GetX();
5831 380 : x0[1] = trpoint->GetY();
5832 380 : x0[2] = trpoint->GetZ();
5833 380 : sec0 = ((clindex&0xff000000)>>24)%18;
5834 380 : }
5835 : }
5836 : }
5837 :
5838 3084 : if ( (index<p1) &&(trpoint->GetX()>1)){
5839 1016 : clindex = track->GetClusterIndex2(i);
5840 1016 : if (clindex >= 0){
5841 1016 : x1[0] = trpoint->GetX();
5842 1016 : x1[1] = trpoint->GetY();
5843 1016 : x1[2] = trpoint->GetZ();
5844 1016 : sec1 = ((clindex&0xff000000)>>24)%18;
5845 1016 : }
5846 : }
5847 3912 : if ( (index<p2) &&(trpoint->GetX()>1)){
5848 1844 : clindex = track->GetClusterIndex2(i);
5849 1844 : if (clindex >= 0){
5850 1844 : x2[0] = trpoint->GetX();
5851 1844 : x2[1] = trpoint->GetY();
5852 1844 : x2[2] = trpoint->GetZ();
5853 1844 : sec2 = ((clindex&0xff000000)>>24)%18;
5854 : pp2 = i;
5855 1844 : }
5856 : }
5857 2068 : }
5858 : }
5859 :
5860 : Double_t alpha, cs,sn, xx2,yy2;
5861 : //
5862 86 : alpha = (sec1-sec2)*fSectors->GetAlpha();
5863 86 : cs = TMath::Cos(alpha);
5864 86 : sn = TMath::Sin(alpha);
5865 86 : xx2= x1[0]*cs-x1[1]*sn;
5866 86 : yy2= x1[0]*sn+x1[1]*cs;
5867 86 : x1[0] = xx2;
5868 86 : x1[1] = yy2;
5869 : //
5870 86 : alpha = (sec0-sec2)*fSectors->GetAlpha();
5871 86 : cs = TMath::Cos(alpha);
5872 86 : sn = TMath::Sin(alpha);
5873 86 : xx2= x0[0]*cs-x0[1]*sn;
5874 86 : yy2= x0[0]*sn+x0[1]*cs;
5875 86 : x0[0] = xx2;
5876 86 : x0[1] = yy2;
5877 : //
5878 : //
5879 : //
5880 86 : Double_t x[5],c[15];
5881 : //
5882 86 : x[0]=x2[1];
5883 86 : x[1]=x2[2];
5884 86 : x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
5885 : // if (x[4]>1) return 0;
5886 86 : x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
5887 86 : x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
5888 : //if (TMath::Abs(x[3]) > 2.2) return 0;
5889 : //if (TMath::Abs(x[2]) > 1.99) return 0;
5890 : //
5891 : Double_t sy =0.1, sz =0.1;
5892 : //
5893 86 : Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
5894 86 : Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
5895 86 : Double_t sy3=0.01+track->GetSigmaY2();
5896 : //
5897 86 : Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
5898 86 : Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
5899 86 : Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
5900 86 : Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
5901 86 : Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
5902 86 : Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
5903 : //
5904 86 : Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
5905 86 : Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
5906 86 : Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
5907 86 : Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
5908 :
5909 :
5910 86 : c[0]=sy1;
5911 86 : c[1]=0.; c[2]=sz1;
5912 86 : c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
5913 86 : c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
5914 86 : c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
5915 86 : c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
5916 86 : c[13]=f30*sy1*f40+f32*sy2*f42;
5917 86 : c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
5918 :
5919 : // Int_t row1 = fSectors->GetRowNumber(x2[0]);
5920 86 : AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
5921 86 : seed->SetPoolID(fLastSeedID);
5922 86 : seed->SetRow(pp2); //RS: memorise current row
5923 : // Double_t y0,z0,y1,z1, y2,z2;
5924 : //seed->GetProlongation(x0[0],y0,z0);
5925 : // seed->GetProlongation(x1[0],y1,z1);
5926 : //seed->GetProlongation(x2[0],y2,z2);
5927 : // seed =0;
5928 86 : seed->SetLastPoint(pp2);
5929 86 : seed->SetFirstPoint(pp2);
5930 :
5931 :
5932 86 : return seed;
5933 86 : }
5934 :
5935 :
5936 : AliTPCseed *AliTPCtracker::ReSeed(const AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
5937 : {
5938 : //
5939 : //
5940 : //reseed using founded clusters
5941 : //
5942 : // Find the number of clusters
5943 : Int_t nclusters = 0;
5944 0 : for (Int_t irow=0;irow<kMaxRow;irow++){
5945 0 : if (track->GetClusterIndex(irow)>0) nclusters++;
5946 : }
5947 : //
5948 0 : Int_t ipos[3];
5949 0 : ipos[0] = TMath::Max(int(r0*nclusters),0); // point 0 cluster
5950 0 : ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1); //
5951 0 : ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1); // last point
5952 : //
5953 : //
5954 0 : Double_t xyz[3][3]={{0}};
5955 0 : Int_t row[3]={0},sec[3]={0,0,0};
5956 : //
5957 : // find track row position at given ratio of the length
5958 : Int_t index=-1;
5959 0 : for (Int_t irow=0;irow<kMaxRow;irow++){
5960 0 : if (track->GetClusterIndex2(irow)<0) continue;
5961 0 : index++;
5962 0 : for (Int_t ipoint=0;ipoint<3;ipoint++){
5963 0 : if (index<=ipos[ipoint]) row[ipoint] = irow;
5964 : }
5965 0 : }
5966 : //
5967 : //Get cluster and sector position
5968 0 : for (Int_t ipoint=0;ipoint<3;ipoint++){
5969 0 : Int_t clindex = track->GetClusterIndex2(row[ipoint]);
5970 0 : AliTPCclusterMI * cl = clindex<0 ? 0:GetClusterMI(clindex);
5971 0 : if (cl==0) {
5972 : //Error("Bug\n");
5973 : // AliTPCclusterMI * cl = GetClusterMI(clindex);
5974 0 : return 0;
5975 : }
5976 0 : sec[ipoint] = ((clindex&0xff000000)>>24)%18;
5977 0 : xyz[ipoint][0] = GetXrow(row[ipoint]);
5978 0 : xyz[ipoint][1] = cl->GetY();
5979 0 : xyz[ipoint][2] = cl->GetZ();
5980 0 : }
5981 : //
5982 : //
5983 : // Calculate seed state vector and covariance matrix
5984 :
5985 : Double_t alpha, cs,sn, xx2,yy2;
5986 : //
5987 0 : alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
5988 0 : cs = TMath::Cos(alpha);
5989 0 : sn = TMath::Sin(alpha);
5990 0 : xx2= xyz[1][0]*cs-xyz[1][1]*sn;
5991 0 : yy2= xyz[1][0]*sn+xyz[1][1]*cs;
5992 0 : xyz[1][0] = xx2;
5993 0 : xyz[1][1] = yy2;
5994 : //
5995 0 : alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
5996 0 : cs = TMath::Cos(alpha);
5997 0 : sn = TMath::Sin(alpha);
5998 0 : xx2= xyz[0][0]*cs-xyz[0][1]*sn;
5999 0 : yy2= xyz[0][0]*sn+xyz[0][1]*cs;
6000 0 : xyz[0][0] = xx2;
6001 0 : xyz[0][1] = yy2;
6002 : //
6003 : //
6004 : //
6005 0 : Double_t x[5],c[15];
6006 : //
6007 0 : x[0]=xyz[2][1];
6008 0 : x[1]=xyz[2][2];
6009 0 : x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
6010 0 : x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
6011 0 : x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
6012 : //
6013 : Double_t sy =0.1, sz =0.1;
6014 : //
6015 : Double_t sy1=0.2, sz1=0.2;
6016 : Double_t sy2=0.2, sz2=0.2;
6017 : Double_t sy3=0.2;
6018 : //
6019 0 : 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;
6020 0 : 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;
6021 0 : 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;
6022 0 : 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;
6023 0 : 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;
6024 0 : 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;
6025 : //
6026 0 : 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;
6027 0 : 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;
6028 0 : 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;
6029 0 : 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;
6030 :
6031 :
6032 0 : c[0]=sy1;
6033 0 : c[1]=0.; c[2]=sz1;
6034 0 : c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
6035 0 : c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
6036 0 : c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
6037 0 : c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
6038 0 : c[13]=f30*sy1*f40+f32*sy2*f42;
6039 0 : c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
6040 :
6041 : // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
6042 0 : AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
6043 0 : seed->SetPoolID(fLastSeedID);
6044 0 : seed->SetRow(row[2]); //RS: memorise row
6045 0 : seed->SetLastPoint(row[2]);
6046 0 : seed->SetFirstPoint(row[2]);
6047 : return seed;
6048 0 : }
6049 :
6050 :
6051 : AliTPCseed *AliTPCtracker::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
6052 : {
6053 : //
6054 : //
6055 : //reseed using founded clusters
6056 : //
6057 52 : Double_t xyz[3][3];
6058 52 : Int_t row[3]={0,0,0};
6059 52 : Int_t sec[3]={0,0,0};
6060 : //
6061 : // forward direction
6062 52 : if (forward){
6063 112 : for (Int_t irow=r0;irow<kMaxRow;irow++){
6064 56 : if (track->GetClusterIndex(irow)>0){
6065 52 : row[0] = irow;
6066 52 : break;
6067 : }
6068 : }
6069 384 : for (Int_t irow=kMaxRow;irow>r0;irow--){
6070 192 : if (track->GetClusterIndex(irow)>0){
6071 52 : row[2] = irow;
6072 52 : break;
6073 : }
6074 : }
6075 104 : for (Int_t irow=row[2]-15;irow>row[0];irow--){
6076 52 : if (track->GetClusterIndex(irow)>0){
6077 52 : row[1] = irow;
6078 52 : break;
6079 : }
6080 : }
6081 : //
6082 52 : }
6083 52 : if (!forward){
6084 0 : for (Int_t irow=0;irow<r0;irow++){
6085 0 : if (track->GetClusterIndex(irow)>0){
6086 0 : row[0] = irow;
6087 0 : break;
6088 : }
6089 : }
6090 0 : for (Int_t irow=r0;irow>0;irow--){
6091 0 : if (track->GetClusterIndex(irow)>0){
6092 0 : row[2] = irow;
6093 0 : break;
6094 : }
6095 : }
6096 0 : for (Int_t irow=row[2]-15;irow>row[0];irow--){
6097 0 : if (track->GetClusterIndex(irow)>0){
6098 0 : row[1] = irow;
6099 0 : break;
6100 : }
6101 : }
6102 0 : }
6103 : //
6104 52 : if ((row[2]-row[0])<20) return 0;
6105 52 : if (row[1]==0) return 0;
6106 : //
6107 : //
6108 : //Get cluster and sector position
6109 468 : for (Int_t ipoint=0;ipoint<3;ipoint++){
6110 156 : Int_t clindex = track->GetClusterIndex2(row[ipoint]);
6111 468 : AliTPCclusterMI * cl = clindex<0 ? 0:GetClusterMI(clindex);
6112 156 : if (cl==0) {
6113 : //Error("Bug\n");
6114 : // AliTPCclusterMI * cl = GetClusterMI(clindex);
6115 0 : return 0;
6116 : }
6117 156 : sec[ipoint] = ((clindex&0xff000000)>>24)%18;
6118 156 : xyz[ipoint][0] = GetXrow(row[ipoint]);
6119 156 : const AliTPCTrackerPoints::Point * point = track->GetTrackPoint(row[ipoint]);
6120 156 : if (point&&ipoint<2){
6121 : //
6122 104 : xyz[ipoint][1] = point->GetY();
6123 104 : xyz[ipoint][2] = point->GetZ();
6124 104 : }
6125 : else{
6126 52 : xyz[ipoint][1] = cl->GetY();
6127 52 : xyz[ipoint][2] = cl->GetZ();
6128 : }
6129 156 : }
6130 : //
6131 : //
6132 : //
6133 : //
6134 : // Calculate seed state vector and covariance matrix
6135 :
6136 : Double_t alpha, cs,sn, xx2,yy2;
6137 : //
6138 52 : alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
6139 52 : cs = TMath::Cos(alpha);
6140 52 : sn = TMath::Sin(alpha);
6141 52 : xx2= xyz[1][0]*cs-xyz[1][1]*sn;
6142 52 : yy2= xyz[1][0]*sn+xyz[1][1]*cs;
6143 52 : xyz[1][0] = xx2;
6144 52 : xyz[1][1] = yy2;
6145 : //
6146 52 : alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
6147 52 : cs = TMath::Cos(alpha);
6148 52 : sn = TMath::Sin(alpha);
6149 52 : xx2= xyz[0][0]*cs-xyz[0][1]*sn;
6150 52 : yy2= xyz[0][0]*sn+xyz[0][1]*cs;
6151 52 : xyz[0][0] = xx2;
6152 52 : xyz[0][1] = yy2;
6153 : //
6154 : //
6155 : //
6156 52 : Double_t x[5],c[15];
6157 : //
6158 52 : x[0]=xyz[2][1];
6159 52 : x[1]=xyz[2][2];
6160 52 : x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
6161 52 : x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
6162 52 : x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
6163 : //
6164 : Double_t sy =0.1, sz =0.1;
6165 : //
6166 : Double_t sy1=0.2, sz1=0.2;
6167 : Double_t sy2=0.2, sz2=0.2;
6168 : Double_t sy3=0.2;
6169 : //
6170 52 : 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;
6171 52 : 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;
6172 52 : 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;
6173 52 : 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;
6174 52 : 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;
6175 52 : 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;
6176 : //
6177 52 : 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;
6178 52 : 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;
6179 52 : 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;
6180 52 : 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;
6181 :
6182 :
6183 52 : c[0]=sy1;
6184 52 : c[1]=0.; c[2]=sz1;
6185 52 : c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
6186 52 : c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
6187 52 : c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
6188 52 : c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
6189 52 : c[13]=f30*sy1*f40+f32*sy2*f42;
6190 52 : c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
6191 :
6192 : // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
6193 52 : AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
6194 52 : seed->SetPoolID(fLastSeedID);
6195 52 : seed->SetRow(row[2]); //RS: memorise row
6196 52 : seed->SetLastPoint(row[2]);
6197 52 : seed->SetFirstPoint(row[2]);
6198 6100 : for (Int_t i=row[0];i<row[2];i++){
6199 2998 : seed->SetClusterIndex(i, track->GetClusterIndex(i));
6200 : }
6201 :
6202 : return seed;
6203 104 : }
6204 :
6205 :
6206 :
6207 : void AliTPCtracker::FindMultiMC(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
6208 : {
6209 : //
6210 : // find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
6211 : // USES MC LABELS
6212 : // Use AliTPCReconstructor::StreamLevel()& kStreamFindMultiMC if you want to tune parameters - cuts
6213 : //
6214 : // Two reasons to have multiple find tracks
6215 : // 1. Curling tracks can be find more than once
6216 : // 2. Splitted tracks
6217 : // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
6218 : // b.) Edge effect on the sector boundaries
6219 : //
6220 : //
6221 : // Algorithm done in 2 phases - because of CPU consumption
6222 : // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
6223 : //
6224 : // Algorihm for curling tracks sign:
6225 : // 1 phase -makes a very rough fast cuts to minimize combinatorics
6226 : // a.) opposite sign
6227 : // b.) one of the tracks - not pointing to the primary vertex -
6228 : // c.) delta tan(theta)
6229 : // d.) delta phi
6230 : // 2 phase - calculates DCA between tracks - time consument
6231 :
6232 : //
6233 : // fast cuts
6234 : //
6235 : // General cuts - for splitted tracks and for curling tracks
6236 : //
6237 : const Float_t kMaxdPhi = 0.2; // maximal distance in phi
6238 : //
6239 : // Curling tracks cuts
6240 : //
6241 : //
6242 : //
6243 : //
6244 0 : Int_t nentries = array->GetEntriesFast();
6245 0 : if (!fHelixPool) fHelixPool = new TClonesArray("AliHelix",nentries+50);
6246 0 : fHelixPool->Clear();
6247 0 : TClonesArray& helixes = *fHelixPool;
6248 0 : Float_t xm[nentries];
6249 0 : Float_t dz0[nentries];
6250 0 : Float_t dz1[nentries];
6251 : //
6252 : //
6253 0 : TStopwatch timer;
6254 0 : timer.Start();
6255 : //
6256 : // Find track COG in x direction - point with best defined parameters
6257 : //
6258 0 : for (Int_t i=0;i<nentries;i++){
6259 0 : AliTPCseed* track = (AliTPCseed*)array->At(i);
6260 0 : if (!track) continue;
6261 0 : track->SetCircular(0);
6262 0 : new (helixes[i]) AliHelix(*track);
6263 : Int_t ncl=0;
6264 0 : xm[i]=0;
6265 0 : Float_t dz[2];
6266 0 : track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
6267 0 : dz0[i]=dz[0];
6268 0 : dz1[i]=dz[1];
6269 0 : for (Int_t icl=0; icl<kMaxRow; icl++){
6270 0 : int tpcindex= track->GetClusterIndex2(icl);
6271 0 : const AliTPCclusterMI * cl = (tpcindex<0) ? 0:GetClusterMI(tpcindex);
6272 : //RS AliTPCclusterMI * cl = track->GetClusterPointer(icl);
6273 0 : if (cl) {
6274 0 : xm[i]+=cl->GetX();
6275 0 : ncl++;
6276 0 : }
6277 : }
6278 0 : if (ncl>0) xm[i]/=Float_t(ncl);
6279 0 : }
6280 : //
6281 0 : for (Int_t i0=0;i0<nentries;i0++){
6282 0 : AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
6283 0 : if (!track0) continue;
6284 0 : AliHelix* hlxi0 = (AliHelix*)helixes[i0];
6285 0 : Float_t xc0 = hlxi0->GetHelix(6);
6286 0 : Float_t yc0 = hlxi0->GetHelix(7);
6287 0 : Float_t r0 = hlxi0->GetHelix(8);
6288 0 : Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
6289 0 : Float_t fi0 = TMath::ATan2(yc0,xc0);
6290 :
6291 0 : for (Int_t i1=i0+1;i1<nentries;i1++){
6292 0 : AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
6293 0 : if (!track1) continue;
6294 0 : Int_t lab0=track0->GetLabel();
6295 0 : Int_t lab1=track1->GetLabel();
6296 0 : if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
6297 : //
6298 0 : AliHelix* hlxi1 = (AliHelix*)helixes[i1];
6299 0 : Float_t xc1 = hlxi1->GetHelix(6);
6300 0 : Float_t yc1 = hlxi1->GetHelix(7);
6301 0 : Float_t r1 = hlxi1->GetHelix(8);
6302 0 : Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
6303 0 : Float_t fi1 = TMath::ATan2(yc1,xc1);
6304 : //
6305 0 : Float_t dfi = fi0-fi1;
6306 : //
6307 : //
6308 0 : if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
6309 0 : if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
6310 0 : if (TMath::Abs(dfi)>kMaxdPhi&&hlxi0->GetHelix(4)*hlxi1->GetHelix(4)<0){
6311 : //
6312 : // if short tracks with undefined sign
6313 0 : fi1 = -TMath::ATan2(yc1,-xc1);
6314 0 : dfi = fi0-fi1;
6315 0 : }
6316 0 : Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
6317 :
6318 : //
6319 : // debug stream to tune "fast cuts"
6320 : //
6321 0 : Double_t dist[3]; // distance at X
6322 0 : Double_t mdist[3]={0,0,0}; // mean distance X+-40cm
6323 0 : track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
6324 0 : for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
6325 0 : track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
6326 0 : for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
6327 0 : track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
6328 0 : for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
6329 0 : for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
6330 :
6331 0 : Float_t sum =0;
6332 0 : Float_t sums=0;
6333 0 : for (Int_t icl=0; icl<kMaxRow; icl++){
6334 0 : Int_t tpcindex0 = track0->GetClusterIndex2(icl);
6335 0 : Int_t tpcindex1 = track1->GetClusterIndex2(icl);
6336 : //RS AliTPCclusterMI * cl0 = track0->GetClusterPointer(icl);
6337 : //RS AliTPCclusterMI * cl1 = track1->GetClusterPointer(icl);
6338 : //RS if (cl0&&cl1) {
6339 0 : if (tpcindex0>=0 && tpcindex1>=0) {
6340 0 : sum++;
6341 0 : if (tpcindex0==tpcindex1) sums++; //RS if (cl0==cl1) sums++;
6342 : }
6343 : }
6344 : //
6345 0 : if ((AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC)>0) { // flag: stream MC infomation about the multiple find track (ONLY for MC data)
6346 0 : TTreeSRedirector &cstream = *fDebugStreamer;
6347 0 : cstream<<"Multi"<<
6348 0 : "iter="<<iter<<
6349 0 : "lab0="<<lab0<<
6350 0 : "lab1="<<lab1<<
6351 0 : "Tr0.="<<track0<< // seed0
6352 0 : "Tr1.="<<track1<< // seed1
6353 0 : "h0.="<<hlxi0<<
6354 0 : "h1.="<<hlxi1<<
6355 : //
6356 0 : "sum="<<sum<< //the sum of rows with cl in both
6357 0 : "sums="<<sums<< //the sum of shared clusters
6358 0 : "xm0="<<xm[i0]<< // the center of track
6359 0 : "xm1="<<xm[i1]<< // the x center of track
6360 : // General cut variables
6361 0 : "dfi="<<dfi<< // distance in fi angle
6362 0 : "dtheta="<<dtheta<< // distance int theta angle
6363 : //
6364 0 : "dz00="<<dz0[i0]<<
6365 0 : "dz01="<<dz0[i1]<<
6366 0 : "dz10="<<dz1[i1]<<
6367 0 : "dz11="<<dz1[i1]<<
6368 0 : "dist0="<<dist[0]<< //distance x
6369 0 : "dist1="<<dist[1]<< //distance y
6370 0 : "dist2="<<dist[2]<< //distance z
6371 0 : "mdist0="<<mdist[0]<< //distance x
6372 0 : "mdist1="<<mdist[1]<< //distance y
6373 0 : "mdist2="<<mdist[2]<< //distance z
6374 : //
6375 0 : "r0="<<r0<<
6376 0 : "rc0="<<rc0<<
6377 0 : "fi0="<<fi0<<
6378 0 : "fi1="<<fi1<<
6379 0 : "r1="<<r1<<
6380 0 : "rc1="<<rc1<<
6381 : "\n";
6382 0 : }
6383 0 : }
6384 0 : }
6385 0 : if (fHelixPool) fHelixPool->Clear();
6386 : // delete [] helixes; // RS moved to stack
6387 : // delete [] xm;
6388 : // delete [] dz0;
6389 : // delete [] dz1;
6390 0 : if (AliTPCReconstructor::StreamLevel()>0) {
6391 0 : AliInfo("Time for curling tracks removal DEBUGGING MC");
6392 0 : timer.Print();
6393 : }
6394 0 : }
6395 :
6396 :
6397 :
6398 : void AliTPCtracker::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t /*iter*/){
6399 : //
6400 : // Find Splitted tracks and remove the one with worst quality
6401 : // Corresponding debug streamer to tune selections - "Splitted2"
6402 : // Algorithm:
6403 : // 0. Sort tracks according quality
6404 : // 1. Propagate the tracks to the reference radius
6405 : // 2. Double_t loop to select close tracks (only to speed up process)
6406 : // 3. Calculate cluster overlap ratio - and remove the track if bigger than a threshold
6407 : // 4. Delete temporary parameters
6408 : //
6409 48 : const Double_t xref=GetXrow(63); // reference radius -IROC/OROC boundary
6410 : // rough cuts
6411 : const Double_t kCutP1=10; // delta Z cut 10 cm
6412 : const Double_t kCutP2=0.15; // delta snp(fi) cut 0.15
6413 : const Double_t kCutP3=0.15; // delta tgl(theta) cut 0.15
6414 : const Double_t kCutAlpha=0.15; // delta alpha cut
6415 : Int_t firstpoint = 0;
6416 : Int_t lastpoint = kMaxRow;
6417 : //
6418 24 : Int_t nentries = array->GetEntriesFast();
6419 28 : if (!fETPPool) fETPPool = new TClonesArray("AliExternalTrackParam",nentries+50);
6420 22 : else fETPPool->Clear();
6421 24 : TClonesArray ¶ms = *fETPPool;
6422 : //
6423 : //
6424 24 : TStopwatch timer;
6425 24 : timer.Start();
6426 : //
6427 : //0. Sort tracks according quality
6428 : //1. Propagate the ext. param to reference radius
6429 24 : Int_t nseed = array->GetEntriesFast();
6430 24 : if (nseed<=0) return;
6431 24 : Float_t quality[nseed];
6432 24 : Int_t indexes[nseed];
6433 1108 : for (Int_t i=0; i<nseed; i++) {
6434 530 : AliTPCseed *pt=(AliTPCseed*)array->UncheckedAt(i);
6435 530 : if (!pt){
6436 124 : quality[i]=-1;
6437 124 : continue;
6438 : }
6439 406 : pt->UpdatePoints(); //select first last max dens points
6440 406 : Float_t * points = pt->GetPoints();
6441 406 : if (points[3]<0.8) quality[i] =-1;
6442 812 : quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
6443 : //prefer high momenta tracks if overlaps
6444 812 : quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
6445 1218 : AliExternalTrackParam* parI = new (params[i]) AliExternalTrackParam(*pt);
6446 : // params[i]=(*pt);
6447 406 : AliTracker::PropagateTrackParamOnlyToBxByBz(parI,xref,5.,kTRUE);
6448 : // AliTracker::PropagateTrackToBxByBz(parI,xref,pt->GetMass(),1.,kTRUE); //RS What is the point of 2nd propagation
6449 406 : }
6450 24 : TMath::Sort(nseed,quality,indexes);
6451 : //
6452 : // 3. Loop over pair of tracks
6453 : //
6454 1108 : for (Int_t i0=0; i0<nseed; i0++) {
6455 530 : Int_t index0=indexes[i0];
6456 654 : if (!(array->UncheckedAt(index0))) continue;
6457 406 : AliTPCseed *s1 = (AliTPCseed*)array->UncheckedAt(index0);
6458 406 : if (!s1->IsActive()) continue;
6459 812 : AliExternalTrackParam &par0=*(AliExternalTrackParam*)params[index0];
6460 12324 : for (Int_t i1=i0+1; i1<nseed; i1++) {
6461 5756 : Int_t index1=indexes[i1];
6462 7922 : if (!(array->UncheckedAt(index1))) continue;
6463 3590 : AliTPCseed *s2 = (AliTPCseed*)array->UncheckedAt(index1);
6464 3590 : if (!s2->IsActive()) continue;
6465 3590 : if (s2->GetKinkIndexes()[0]!=0)
6466 186 : if (s2->GetKinkIndexes()[0] == -s1->GetKinkIndexes()[0]) continue;
6467 7156 : AliExternalTrackParam &par1=*(AliExternalTrackParam*)params[index1];
6468 12378 : if (TMath::Abs(par0.GetParameter()[3]-par1.GetParameter()[3])>kCutP3) continue;
6469 6930 : if (TMath::Abs(par0.GetParameter()[1]-par1.GetParameter()[1])>kCutP1) continue;
6470 2788 : if (TMath::Abs(par0.GetParameter()[2]-par1.GetParameter()[2])>kCutP2) continue;
6471 1308 : Double_t dAlpha= TMath::Abs(par0.GetAlpha()-par1.GetAlpha());
6472 508 : if (dAlpha>TMath::Pi()) dAlpha-=TMath::Pi();
6473 804 : if (TMath::Abs(dAlpha)>kCutAlpha) continue;
6474 : //
6475 68 : Int_t sumShared=0;
6476 68 : Int_t nall0=0;
6477 68 : Int_t nall1=0;
6478 68 : Int_t firstShared=lastpoint, lastShared=firstpoint;
6479 68 : Int_t firstRow=lastpoint, lastRow=firstpoint;
6480 : //
6481 : // for (Int_t i=firstpoint;i<lastpoint;i++){
6482 : // if (s1->GetClusterIndex2(i)>0) nall0++;
6483 : // if (s2->GetClusterIndex2(i)>0) nall1++;
6484 : // if (s1->GetClusterIndex2(i)>0 && s2->GetClusterIndex2(i)>0) {
6485 : // if (i<firstRow) firstRow=i;
6486 : // if (i>lastRow) lastRow=i;
6487 : // }
6488 : // if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
6489 : // if (i<firstShared) firstShared=i;
6490 : // if (i>lastShared) lastShared=i;
6491 : // sumShared++;
6492 : // }
6493 : // }
6494 : //
6495 : // RS: faster version + fix(?) ">" -> ">="
6496 21760 : for (Int_t i=firstpoint;i<lastpoint;i++){
6497 10812 : int ind1=s1->GetClusterIndex2(i),ind2=s2->GetClusterIndex2(i);
6498 20246 : if (ind1>=0) nall0++; // RS: ">" -> ">="
6499 18092 : if (ind2>=0) nall1++;
6500 10812 : if (ind1>=0 && ind2>=0) {
6501 6762 : if (i<firstRow) firstRow=i;
6502 13344 : if (i>lastRow) lastRow=i;
6503 : }
6504 10812 : if ( (ind1==ind2) && ind1>=0) {
6505 354 : if (i<firstShared) firstShared=i;
6506 664 : if (i>lastShared) lastShared=i;
6507 338 : sumShared++;
6508 338 : }
6509 : }
6510 :
6511 68 : Double_t ratio0 = Float_t(sumShared)/Float_t(TMath::Min(nall0+1,nall1+1));
6512 68 : Double_t ratio1 = Float_t(sumShared)/Float_t(TMath::Max(nall0+1,nall1+1));
6513 :
6514 68 : if ((AliTPCReconstructor::StreamLevel()&kStreamSplitted2)>0){ // flag:stream information about discarded TPC tracks pair algorithm
6515 0 : TTreeSRedirector &cstream = *fDebugStreamer;
6516 0 : Int_t n0=s1->GetNumberOfClusters();
6517 0 : Int_t n1=s2->GetNumberOfClusters();
6518 0 : Int_t n0F=s1->GetNFoundable();
6519 0 : Int_t n1F=s2->GetNFoundable();
6520 0 : Int_t lab0=s1->GetLabel();
6521 0 : Int_t lab1=s2->GetLabel();
6522 :
6523 0 : cstream<<"Splitted2"<< // flag:stream information about discarded TPC tracks pair algorithm
6524 0 : "iter="<<fIteration<<
6525 0 : "lab0="<<lab0<< // MC label if exist
6526 0 : "lab1="<<lab1<< // MC label if exist
6527 0 : "index0="<<index0<<
6528 0 : "index1="<<index1<<
6529 0 : "ratio0="<<ratio0<< // shared ratio
6530 0 : "ratio1="<<ratio1<< // shared ratio
6531 0 : "p0.="<<&par0<< // track parameters
6532 0 : "p1.="<<&par1<<
6533 0 : "s0.="<<s1<< // full seed
6534 0 : "s1.="<<s2<<
6535 0 : "n0="<<n0<< // number of clusters track 0
6536 0 : "n1="<<n1<< // number of clusters track 1
6537 0 : "nall0="<<nall0<< // number of clusters track 0
6538 0 : "nall1="<<nall1<< // number of clusters track 1
6539 0 : "n0F="<<n0F<< // number of findable
6540 0 : "n1F="<<n1F<< // number of findable
6541 0 : "shared="<<sumShared<< // number of shared clusters
6542 0 : "firstS="<<firstShared<< // first and the last shared row
6543 0 : "lastS="<<lastShared<<
6544 0 : "firstRow="<<firstRow<< // first and the last row with cluster
6545 0 : "lastRow="<<lastRow<< //
6546 : "\n";
6547 0 : }
6548 : //
6549 : // remove track with lower quality
6550 : //
6551 204 : if (ratio0>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(0) ||
6552 136 : ratio1>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(1)){
6553 : //
6554 : //
6555 : //
6556 0 : MarkSeedFree( array->RemoveAt(index1) );
6557 : }
6558 5824 : }
6559 936 : }
6560 : //
6561 : // 4. Delete temporary array
6562 : //
6563 48 : if (fETPPool) fETPPool->Clear();
6564 : // delete [] params; // RS moved to stack
6565 : // delete [] quality;
6566 : // delete [] indexes;
6567 :
6568 48 : }
6569 :
6570 :
6571 :
6572 : void AliTPCtracker::FindCurling(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
6573 : {
6574 : //
6575 : // find Curling tracks
6576 : // Use AliTPCReconstructor::StreamLevel()&kStreamFindCurling if you want to tune parameters - cuts
6577 : //
6578 : //
6579 : // Algorithm done in 2 phases - because of CPU consumption
6580 : // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
6581 : // see detal in MC part what can be used to cut
6582 : //
6583 : //
6584 : //
6585 : const Float_t kMaxC = 400; // maximal curvature to of the track
6586 : const Float_t kMaxdTheta = 0.15; // maximal distance in theta
6587 : const Float_t kMaxdPhi = 0.15; // maximal distance in phi
6588 : const Float_t kPtRatio = 0.3; // ratio between pt
6589 : const Float_t kMinDCAR = 2.; // distance to the primary vertex in r - see cpipe cut
6590 :
6591 : //
6592 : // Curling tracks cuts
6593 : //
6594 : //
6595 : const Float_t kMaxDeltaRMax = 40; // distance in outer radius
6596 : const Float_t kMaxDeltaRMin = 5.; // distance in lower radius - see cpipe cut
6597 : const Float_t kMinAngle = 2.9; // angle between tracks
6598 : const Float_t kMaxDist = 5; // biggest distance
6599 : //
6600 : // The cuts can be tuned using the "MC information stored in Multi tree ==> see FindMultiMC
6601 : /*
6602 : Fast cuts:
6603 : TCut csign("csign","Tr0.fP[4]*Tr1.fP[4]<0"); //opposite sign
6604 : TCut cmax("cmax","abs(Tr0.GetC())>1/400");
6605 : TCut cda("cda","sqrt(dtheta^2+dfi^2)<0.15");
6606 : TCut ccratio("ccratio","abs((Tr0.fP[4]+Tr1.fP[4])/(abs(Tr0.fP[4])+abs(Tr1.fP[4])))<0.3");
6607 : TCut cpipe("cpipe", "min(abs(r0-rc0),abs(r1-rc1))>5");
6608 : //
6609 : TCut cdrmax("cdrmax","abs(abs(rc0+r0)-abs(rc1+r1))<40")
6610 : TCut cdrmin("cdrmin","abs(abs(rc0+r0)-abs(rc1+r1))<10")
6611 : //
6612 : Multi->Draw("dfi","iter==0"+csign+cmax+cda+ccratio); ~94% of curling tracks fulfill
6613 : Multi->Draw("min(abs(r0-rc0),abs(r1-rc1))","iter==0&&abs(lab1)==abs(lab0)"+csign+cmax+cda+ccratio+cpipe+cdrmin+cdrmax); //80%
6614 : //
6615 : Curling2->Draw("dfi","iter==0&&abs(lab0)==abs(lab1)"+csign+cmax+cdtheta+cdfi+ccratio)
6616 :
6617 : */
6618 : //
6619 : //
6620 : //
6621 0 : Int_t nentries = array->GetEntriesFast();
6622 0 : if (!fHelixPool) fHelixPool = new TClonesArray("AliHelix",nentries+100);
6623 0 : fHelixPool->Clear();
6624 0 : TClonesArray& helixes = *fHelixPool;
6625 :
6626 0 : for (Int_t i=0;i<nentries;i++){
6627 0 : AliTPCseed* track = (AliTPCseed*)array->At(i);
6628 0 : if (!track) continue;
6629 0 : track->SetCircular(0);
6630 0 : new (helixes[i]) AliHelix(*track);
6631 0 : }
6632 : //
6633 : //
6634 0 : TStopwatch timer;
6635 0 : timer.Start();
6636 0 : Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
6637 :
6638 : //
6639 : // Find tracks
6640 : //
6641 : //
6642 0 : for (Int_t i0=0;i0<nentries;i0++){
6643 0 : AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
6644 0 : if (!track0) continue;
6645 0 : if (TMath::Abs(track0->GetC())<1/kMaxC) continue;
6646 0 : AliHelix* hlxi0 = (AliHelix*)helixes[i0];
6647 0 : Float_t xc0 = hlxi0->GetHelix(6);
6648 0 : Float_t yc0 = hlxi0->GetHelix(7);
6649 0 : Float_t r0 = hlxi0->GetHelix(8);
6650 0 : Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
6651 0 : Float_t fi0 = TMath::ATan2(yc0,xc0);
6652 :
6653 0 : for (Int_t i1=i0+1;i1<nentries;i1++){
6654 0 : AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
6655 0 : if (!track1) continue;
6656 0 : if (TMath::Abs(track1->GetC())<1/kMaxC) continue;
6657 0 : AliHelix* hlxi1 = (AliHelix*)helixes[i1];
6658 0 : Float_t xc1 = hlxi1->GetHelix(6);
6659 0 : Float_t yc1 = hlxi1->GetHelix(7);
6660 0 : Float_t r1 = hlxi1->GetHelix(8);
6661 0 : Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
6662 0 : Float_t fi1 = TMath::ATan2(yc1,xc1);
6663 : //
6664 0 : Float_t dfi = fi0-fi1;
6665 : //
6666 : //
6667 0 : if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
6668 0 : if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
6669 0 : Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
6670 : //
6671 : //
6672 : // FIRST fast cuts
6673 0 : if (track0->GetBConstrain()&&track1->GetBConstrain()) continue; // not constrained
6674 0 : if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue; // not the same sign
6675 0 : if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>kMaxdTheta) continue; //distance in the Theta
6676 0 : if ( TMath::Abs(dfi)>kMaxdPhi) continue; //distance in phi
6677 0 : if ( TMath::Sqrt(dfi*dfi+dtheta*dtheta)>kMaxdPhi) continue; //common angular offset
6678 : //
6679 0 : Float_t pt0 = track0->GetSignedPt();
6680 0 : Float_t pt1 = track1->GetSignedPt();
6681 0 : if ((TMath::Abs(pt0+pt1)/(TMath::Abs(pt0)+TMath::Abs(pt1)))>kPtRatio) continue;
6682 0 : if ((iter==1) && TMath::Abs(TMath::Abs(rc0+r0)-TMath::Abs(rc1+r1))>kMaxDeltaRMax) continue;
6683 0 : if ((iter!=1) &&TMath::Abs(TMath::Abs(rc0-r0)-TMath::Abs(rc1-r1))>kMaxDeltaRMin) continue;
6684 0 : if (TMath::Min(TMath::Abs(rc0-r0),TMath::Abs(rc1-r1))<kMinDCAR) continue;
6685 : //
6686 : //
6687 : // Now find closest approach
6688 : //
6689 : //
6690 : //
6691 0 : Int_t npoints = hlxi0->GetRPHIintersections(*hlxi1, phase, radius,10);
6692 0 : if (npoints==0) continue;
6693 0 : hlxi0->GetClosestPhases(*hlxi1, phase);
6694 : //
6695 0 : Double_t xyz0[3];
6696 0 : Double_t xyz1[3];
6697 0 : Double_t hangles[3];
6698 0 : hlxi0->Evaluate(phase[0][0],xyz0);
6699 0 : hlxi1->Evaluate(phase[0][1],xyz1);
6700 :
6701 0 : hlxi0->GetAngle(phase[0][0],*hlxi1,phase[0][1],hangles);
6702 0 : Double_t deltah[2],deltabest;
6703 0 : if (TMath::Abs(hangles[2])<kMinAngle) continue;
6704 :
6705 0 : if (npoints>0){
6706 : Int_t ibest=0;
6707 0 : hlxi0->ParabolicDCA(*hlxi1,phase[0][0],phase[0][1],radius[0],deltah[0],2);
6708 0 : if (npoints==2){
6709 0 : hlxi0->ParabolicDCA(*hlxi1,phase[1][0],phase[1][1],radius[1],deltah[1],2);
6710 0 : if (deltah[1]<deltah[0]) ibest=1;
6711 : }
6712 0 : deltabest = TMath::Sqrt(deltah[ibest]);
6713 0 : hlxi0->Evaluate(phase[ibest][0],xyz0);
6714 0 : hlxi1->Evaluate(phase[ibest][1],xyz1);
6715 0 : hlxi0->GetAngle(phase[ibest][0],*hlxi1,phase[ibest][1],hangles);
6716 0 : Double_t radiusbest = TMath::Sqrt(radius[ibest]);
6717 : //
6718 0 : if (deltabest>kMaxDist) continue;
6719 : // if (mindcar+mindcaz<40 && (TMath::Abs(hangles[2])<kMinAngle ||deltabest>3)) continue;
6720 : Bool_t sign =kFALSE;
6721 0 : if (hangles[2]>kMinAngle) sign =kTRUE;
6722 : //
6723 0 : if (sign){
6724 : // circular[i0] = kTRUE;
6725 : // circular[i1] = kTRUE;
6726 0 : if (track0->OneOverPt()<track1->OneOverPt()){
6727 0 : track0->SetCircular(track0->GetCircular()+1);
6728 0 : track1->SetCircular(track1->GetCircular()+2);
6729 0 : }
6730 : else{
6731 0 : track1->SetCircular(track1->GetCircular()+1);
6732 0 : track0->SetCircular(track0->GetCircular()+2);
6733 : }
6734 : }
6735 0 : if ((AliTPCReconstructor::StreamLevel()&kStreamFindCurling)>0){ // flag: stream track infroamtion if the FindCurling tracks method
6736 : //
6737 : //debug stream to tune "fine" cuts
6738 0 : Int_t lab0=track0->GetLabel();
6739 0 : Int_t lab1=track1->GetLabel();
6740 0 : TTreeSRedirector &cstream = *fDebugStreamer;
6741 0 : cstream<<"Curling2"<<
6742 0 : "iter="<<iter<<
6743 0 : "lab0="<<lab0<<
6744 0 : "lab1="<<lab1<<
6745 0 : "Tr0.="<<track0<<
6746 0 : "Tr1.="<<track1<<
6747 : //
6748 0 : "r0="<<r0<<
6749 0 : "rc0="<<rc0<<
6750 0 : "fi0="<<fi0<<
6751 0 : "r1="<<r1<<
6752 0 : "rc1="<<rc1<<
6753 0 : "fi1="<<fi1<<
6754 0 : "dfi="<<dfi<<
6755 0 : "dtheta="<<dtheta<<
6756 : //
6757 0 : "npoints="<<npoints<<
6758 0 : "hangles0="<<hangles[0]<<
6759 0 : "hangles1="<<hangles[1]<<
6760 0 : "hangles2="<<hangles[2]<<
6761 0 : "xyz0="<<xyz0[2]<<
6762 0 : "xyzz1="<<xyz1[2]<<
6763 0 : "radius="<<radiusbest<<
6764 0 : "deltabest="<<deltabest<<
6765 0 : "phase0="<<phase[ibest][0]<<
6766 0 : "phase1="<<phase[ibest][1]<<
6767 : "\n";
6768 :
6769 0 : }
6770 0 : }
6771 0 : }
6772 0 : }
6773 0 : if (fHelixPool) fHelixPool->Clear();
6774 : // delete [] helixes; //RS moved to stack
6775 0 : if (AliTPCReconstructor::StreamLevel()>1) {
6776 0 : AliInfo("Time for curling tracks removal");
6777 0 : timer.Print();
6778 : }
6779 0 : }
6780 :
6781 :
6782 : void AliTPCtracker::FindKinks(TObjArray * array, AliESDEvent *esd)
6783 : {
6784 : //
6785 : // find kinks
6786 : //
6787 : //
6788 : // RS something is wrong in this routine: not all seeds are assigned to daughters and mothers array, but they all are queried
6789 : // to check later
6790 :
6791 16 : TObjArray kinks(10000);
6792 8 : Int_t nentries = array->GetEntriesFast();
6793 8 : Char_t sign[nentries];
6794 8 : UChar_t nclusters[nentries];
6795 8 : Float_t alpha[nentries];
6796 8 : UChar_t usage[nentries];
6797 8 : Float_t zm[nentries];
6798 8 : Float_t z0[nentries];
6799 8 : Float_t fim[nentries];
6800 8 : Bool_t shared[nentries];
6801 8 : Bool_t circular[nentries];
6802 8 : Float_t dca[nentries];
6803 16 : AliKink *kink = new AliKink();
6804 : //
6805 14 : if (!fHelixPool) fHelixPool = new TClonesArray("AliHelix",nentries+100);
6806 8 : fHelixPool->Clear();
6807 8 : TClonesArray& helixes = *fHelixPool;
6808 :
6809 : //const AliESDVertex * primvertex = esd->GetVertex();
6810 : //
6811 : // nentries = array->GetEntriesFast();
6812 : //
6813 :
6814 : //
6815 : //
6816 552 : for (Int_t i=0;i<nentries;i++){
6817 268 : sign[i]=0;
6818 268 : usage[i]=0;
6819 536 : AliTPCseed* track = (AliTPCseed*)array->At(i);
6820 388 : if (!track) continue;
6821 148 : track->SetCircular(0);
6822 148 : shared[i] = kFALSE;
6823 148 : track->UpdatePoints();
6824 296 : if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
6825 : }
6826 296 : nclusters[i]=track->GetNumberOfClusters();
6827 296 : alpha[i] = track->GetAlpha();
6828 444 : AliHelix* hlxi = new (helixes[i]) AliHelix(*track);
6829 148 : Double_t xyz[3];
6830 148 : hlxi->Evaluate(0,xyz);
6831 296 : sign[i] = (track->GetC()>0) ? -1:1;
6832 148 : Double_t x,y,z;
6833 : x=160;
6834 296 : if (track->GetProlongation(x,y,z)){
6835 122 : zm[i] = z;
6836 122 : fim[i] = alpha[i]+TMath::ATan2(y,x);
6837 122 : }
6838 : else{
6839 52 : zm[i] = track->GetZ();
6840 26 : fim[i] = alpha[i];
6841 : }
6842 148 : z0[i]=1000;
6843 148 : circular[i]= kFALSE;
6844 434 : if (track->GetProlongation(0,y,z)) z0[i] = z;
6845 296 : dca[i] = track->GetD(0,0);
6846 148 : }
6847 : //
6848 : //
6849 8 : TStopwatch timer;
6850 8 : timer.Start();
6851 : Int_t ncandidates =0;
6852 : Int_t nall =0;
6853 : Int_t ntracks=0;
6854 8 : Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
6855 :
6856 : //
6857 : // Find circling track
6858 : //
6859 552 : for (Int_t i0=0;i0<nentries;i0++){
6860 536 : AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
6861 388 : if (!track0) continue;
6862 310 : if (track0->GetNumberOfClusters()<40) continue;
6863 370 : if (TMath::Abs(1./track0->GetC())>200) continue;
6864 64 : AliHelix* hlxi0 = (AliHelix*)helixes[i0];
6865 : //
6866 632 : for (Int_t i1=i0+1;i1<nentries;i1++){
6867 568 : AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
6868 328 : if (!track1) continue;
6869 576 : if (track1->GetNumberOfClusters()<40) continue;
6870 442 : if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
6871 134 : if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
6872 268 : if (TMath::Abs(1./track1->GetC())>200) continue;
6873 462 : if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
6874 250 : if (track1->GetTgl()*track0->GetTgl()>0) continue;
6875 138 : if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
6876 46 : if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
6877 46 : if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
6878 : //
6879 46 : Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
6880 46 : if (mindcar<5) continue;
6881 46 : Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
6882 60 : if (mindcaz<5) continue;
6883 32 : if (mindcar+mindcaz<20) continue;
6884 : //
6885 64 : AliHelix* hlxi1 = (AliHelix*)helixes[i1];
6886 : //
6887 32 : Float_t xc0 = hlxi0->GetHelix(6);
6888 32 : Float_t yc0 = hlxi0->GetHelix(7);
6889 32 : Float_t r0 = hlxi0->GetHelix(8);
6890 32 : Float_t xc1 = hlxi1->GetHelix(6);
6891 32 : Float_t yc1 = hlxi1->GetHelix(7);
6892 32 : Float_t r1 = hlxi1->GetHelix(8);
6893 :
6894 32 : Float_t rmean = (r0+r1)*0.5;
6895 32 : Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
6896 : //if (delta>30) continue;
6897 50 : if (delta>rmean*0.25) continue;
6898 14 : if (TMath::Abs(r0-r1)/rmean>0.3) continue;
6899 : //
6900 28 : Int_t npoints = hlxi0->GetRPHIintersections(*hlxi1, phase, radius,10);
6901 14 : if (npoints==0) continue;
6902 14 : hlxi0->GetClosestPhases(*hlxi1, phase);
6903 : //
6904 14 : Double_t xyz0[3];
6905 14 : Double_t xyz1[3];
6906 14 : Double_t hangles[3];
6907 14 : hlxi0->Evaluate(phase[0][0],xyz0);
6908 14 : hlxi1->Evaluate(phase[0][1],xyz1);
6909 :
6910 14 : hlxi0->GetAngle(phase[0][0],*hlxi1,phase[0][1],hangles);
6911 14 : Double_t deltah[2],deltabest;
6912 14 : if (hangles[2]<2.8) continue;
6913 14 : if (npoints>0){
6914 : Int_t ibest=0;
6915 14 : hlxi0->ParabolicDCA(*hlxi1,phase[0][0],phase[0][1],radius[0],deltah[0],2);
6916 14 : if (npoints==2){
6917 12 : hlxi0->ParabolicDCA(*hlxi1,phase[1][0],phase[1][1],radius[1],deltah[1],2);
6918 22 : if (deltah[1]<deltah[0]) ibest=1;
6919 : }
6920 14 : deltabest = TMath::Sqrt(deltah[ibest]);
6921 14 : hlxi0->Evaluate(phase[ibest][0],xyz0);
6922 14 : hlxi1->Evaluate(phase[ibest][1],xyz1);
6923 14 : hlxi0->GetAngle(phase[ibest][0],*hlxi1,phase[ibest][1],hangles);
6924 14 : Double_t radiusbest = TMath::Sqrt(radius[ibest]);
6925 : //
6926 14 : if (deltabest>6) continue;
6927 32 : if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
6928 : Bool_t lsign =kFALSE;
6929 16 : if (hangles[2]>3.06) lsign =kTRUE;
6930 : //
6931 8 : if (lsign){
6932 8 : circular[i0] = kTRUE;
6933 8 : circular[i1] = kTRUE;
6934 24 : if (track0->OneOverPt()<track1->OneOverPt()){
6935 2 : track0->SetCircular(track0->GetCircular()+1);
6936 2 : track1->SetCircular(track1->GetCircular()+2);
6937 2 : }
6938 : else{
6939 6 : track1->SetCircular(track1->GetCircular()+1);
6940 6 : track0->SetCircular(track0->GetCircular()+2);
6941 : }
6942 : }
6943 16 : if (lsign&&((AliTPCReconstructor::StreamLevel()&kStreamFindCurling)>0)){
6944 : //debug stream
6945 0 : Int_t lab0=track0->GetLabel();
6946 0 : Int_t lab1=track1->GetLabel();
6947 0 : TTreeSRedirector &cstream = *fDebugStreamer;
6948 0 : cstream<<"Curling"<<
6949 0 : "lab0="<<lab0<<
6950 0 : "lab1="<<lab1<<
6951 0 : "Tr0.="<<track0<<
6952 0 : "Tr1.="<<track1<<
6953 0 : "dca0="<<dca[i0]<<
6954 0 : "dca1="<<dca[i1]<<
6955 0 : "mindcar="<<mindcar<<
6956 0 : "mindcaz="<<mindcaz<<
6957 0 : "delta="<<delta<<
6958 0 : "rmean="<<rmean<<
6959 0 : "npoints="<<npoints<<
6960 0 : "hangles0="<<hangles[0]<<
6961 0 : "hangles2="<<hangles[2]<<
6962 0 : "xyz0="<<xyz0[2]<<
6963 0 : "xyzz1="<<xyz1[2]<<
6964 0 : "z0="<<z0[i0]<<
6965 0 : "z1="<<z0[i1]<<
6966 0 : "radius="<<radiusbest<<
6967 0 : "deltabest="<<deltabest<<
6968 0 : "phase0="<<phase[ibest][0]<<
6969 0 : "phase1="<<phase[ibest][1]<<
6970 : "\n";
6971 0 : }
6972 22 : }
6973 160 : }
6974 32 : }
6975 : //
6976 : // Finf kinks loop
6977 : //
6978 : //
6979 552 : for (Int_t i =0;i<nentries;i++){
6980 268 : if (sign[i]==0) continue;
6981 296 : AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6982 148 : if (track0==0) {
6983 0 : AliInfo("seed==0");
6984 0 : continue;
6985 : }
6986 148 : ntracks++;
6987 : //
6988 : Double_t cradius0 = 40*40;
6989 : Double_t cradius1 = 270*270;
6990 : Double_t cdist1=8.;
6991 : Double_t cdist2=8.;
6992 : Double_t cdist3=0.55;
6993 296 : AliHelix* hlxi = (AliHelix*)helixes[i];
6994 5720 : for (Int_t j =i+1;j<nentries;j++){
6995 2712 : nall++;
6996 2712 : if (sign[j]*sign[i]<1) continue;
6997 722 : int ncltot = nclusters[i];
6998 722 : ncltot += nclusters[j];
6999 1124 : if ( ncltot>200) continue;
7000 340 : if ( ncltot<80) continue;
7001 386 : if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
7002 534 : if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
7003 : //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
7004 108 : AliHelix* hlxj = (AliHelix*)helixes[j];
7005 54 : Int_t npoints = hlxi->GetRPHIintersections(*hlxj, phase, radius,20);
7006 54 : if (npoints<1) continue;
7007 : // cuts on radius
7008 108 : if (npoints==1){
7009 114 : if (radius[0]<cradius0||radius[0]>cradius1) continue;
7010 : }
7011 : else{
7012 70 : if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
7013 : }
7014 : //
7015 20 : Double_t delta1=10000,delta2=10000;
7016 : // cuts on the intersection radius
7017 20 : hlxi->LinearDCA(*hlxj,phase[0][0],phase[0][1],radius[0],delta1);
7018 20 : if (radius[0]<20&&delta1<1) continue; //intersection at vertex
7019 20 : if (radius[0]<10&&delta1<3) continue; //intersection at vertex
7020 20 : if (npoints==2){
7021 16 : hlxi->LinearDCA(*hlxj,phase[1][0],phase[1][1],radius[1],delta2);
7022 16 : if (radius[1]<20&&delta2<1) continue; //intersection at vertex
7023 16 : if (radius[1]<10&&delta2<3) continue; //intersection at vertex
7024 : }
7025 : //
7026 20 : Double_t distance1 = TMath::Min(delta1,delta2);
7027 30 : if (distance1>cdist1) continue; // cut on DCA linear approximation
7028 : //
7029 10 : npoints = hlxi->GetRPHIintersections(*hlxj, phase, radius,20);
7030 10 : hlxi->ParabolicDCA(*hlxj,phase[0][0],phase[0][1],radius[0],delta1);
7031 10 : if (radius[0]<20&&delta1<1) continue; //intersection at vertex
7032 10 : if (radius[0]<10&&delta1<3) continue; //intersection at vertex
7033 : //
7034 10 : if (npoints==2){
7035 8 : hlxi->ParabolicDCA(*hlxj,phase[1][0],phase[1][1],radius[1],delta2);
7036 8 : if (radius[1]<20&&delta2<1) continue; //intersection at vertex
7037 8 : if (radius[1]<10&&delta2<3) continue; //intersection at vertex
7038 : }
7039 10 : distance1 = TMath::Min(delta1,delta2);
7040 : Float_t rkink =0;
7041 10 : if (delta1<delta2){
7042 8 : rkink = TMath::Sqrt(radius[0]);
7043 8 : }
7044 : else{
7045 2 : rkink = TMath::Sqrt(radius[1]);
7046 : }
7047 10 : if (distance1>cdist2) continue;
7048 : //
7049 : //
7050 20 : AliTPCseed * track1 = (AliTPCseed*)array->At(j);
7051 : //
7052 : //
7053 10 : Int_t row0 = GetRowNumber(rkink);
7054 12 : if (row0<10) continue;
7055 8 : if (row0>150) continue;
7056 : //
7057 : //
7058 : Float_t dens00=-1,dens01=-1;
7059 : Float_t dens10=-1,dens11=-1;
7060 : //
7061 8 : Int_t found,foundable;//,ishared;
7062 : //RS Seed don't keep their cluster pointers, cache cluster usage stat. for fast evaluation
7063 : // FillSeedClusterStatCache(track0); // RS: Use this slow method only if sharing stat. is needed and used
7064 : //
7065 : //GetCachedSeedClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE); // RS make sure FillSeedClusterStatCache is called
7066 : //RS track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
7067 8 : track0->GetClusterStatistic(0,row0-5, found, foundable);
7068 16 : if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
7069 : //
7070 : //GetCachedSeedClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE); // RS make sure FillSeedClusterStatCache is called
7071 : //RS track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
7072 8 : track0->GetClusterStatistic(row0+5,155, found, foundable);
7073 16 : if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
7074 : //
7075 : //
7076 : //RS Seed don't keep their cluster pointers, cache cluster usage stat. for fast evaluation
7077 : // FillSeedClusterStatCache(track1); // RS: Use this slow method only if sharing stat. is needed and used
7078 : //
7079 : //GetCachedSeedClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE); // RS make sure FillSeedClusterStatCache is called
7080 : //RS track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
7081 8 : track1->GetClusterStatistic(0,row0-5, found, foundable);
7082 16 : if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
7083 : //
7084 : //GetCachedSeedClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE); // RS make sure FillSeedClusterStatCache is called
7085 : //RS track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
7086 8 : track1->GetClusterStatistic(row0+5,155, found, foundable);
7087 16 : if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
7088 : //
7089 8 : if (dens00<dens10 && dens01<dens11) continue;
7090 18 : if (dens00>dens10 && dens01>dens11) continue;
7091 6 : if (TMath::Max(dens00,dens10)<0.1) continue;
7092 6 : if (TMath::Max(dens01,dens11)<0.3) continue;
7093 : //
7094 6 : if (TMath::Min(dens00,dens10)>0.6) continue;
7095 8 : if (TMath::Min(dens01,dens11)>0.6) continue;
7096 :
7097 : //
7098 : AliTPCseed * ktrack0, *ktrack1;
7099 4 : if (dens00>dens10){
7100 : ktrack0 = track0;
7101 : ktrack1 = track1;
7102 4 : }
7103 : else{
7104 : ktrack0 = track1;
7105 : ktrack1 = track0;
7106 : }
7107 8 : if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
7108 4 : AliExternalTrackParam paramm(*ktrack0);
7109 4 : AliExternalTrackParam paramd(*ktrack1);
7110 20 : if (row0>60&&ktrack1->GetReference().GetX()>90.)new (¶md) AliExternalTrackParam(ktrack1->GetReference());
7111 : //
7112 : //
7113 4 : kink->SetMother(paramm);
7114 4 : kink->SetDaughter(paramd);
7115 4 : kink->Update();
7116 :
7117 4 : Float_t x[3] = { static_cast<Float_t>(kink->GetPosition()[0]),static_cast<Float_t>(kink->GetPosition()[1]),static_cast<Float_t>(kink->GetPosition()[2])};
7118 4 : Int_t index[4];
7119 4 : fkParam->Transform0to1(x,index);
7120 4 : fkParam->Transform1to2(x,index);
7121 4 : row0 = GetRowNumber(x[0]);
7122 :
7123 4 : if (kink->GetR()<100) continue;
7124 4 : if (kink->GetR()>240) continue;
7125 8 : if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
7126 4 : if (kink->GetDistance()>cdist3) continue;
7127 4 : Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
7128 4 : if (dird<0) continue;
7129 :
7130 4 : Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
7131 4 : if (dirm<0) continue;
7132 4 : Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
7133 4 : if (mpt<0.2) continue;
7134 :
7135 4 : if (mpt<1){
7136 : //for high momenta momentum not defined well in first iteration
7137 8 : Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
7138 4 : if (qt>0.35) continue;
7139 4 : }
7140 :
7141 8 : kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
7142 8 : kink->SetLabel(CookLabel(ktrack1,0.4,row0,kMaxRow),1);
7143 4 : if (dens00>dens10){
7144 4 : kink->SetTPCDensity(dens00,0,0);
7145 4 : kink->SetTPCDensity(dens01,0,1);
7146 4 : kink->SetTPCDensity(dens10,1,0);
7147 4 : kink->SetTPCDensity(dens11,1,1);
7148 4 : kink->SetIndex(i,0);
7149 4 : kink->SetIndex(j,1);
7150 4 : }
7151 : else{
7152 0 : kink->SetTPCDensity(dens10,0,0);
7153 0 : kink->SetTPCDensity(dens11,0,1);
7154 0 : kink->SetTPCDensity(dens00,1,0);
7155 0 : kink->SetTPCDensity(dens01,1,1);
7156 0 : kink->SetIndex(j,0);
7157 0 : kink->SetIndex(i,1);
7158 : }
7159 :
7160 4 : if (mpt<1||kink->GetAngle(2)>0.1){
7161 : // angle and densities not defined yet
7162 8 : if (kink->GetTPCDensityFactor()<0.8) continue;
7163 8 : if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
7164 8 : if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
7165 4 : if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
7166 4 : if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
7167 :
7168 8 : Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
7169 8 : criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
7170 4 : criticalangle= 3*TMath::Sqrt(criticalangle);
7171 6 : if (criticalangle>0.02) criticalangle=0.02;
7172 8 : if (kink->GetAngle(2)<criticalangle) continue;
7173 0 : }
7174 : //
7175 0 : Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
7176 : Float_t shapesum =0;
7177 : Float_t sum = 0;
7178 0 : for ( Int_t row = row0-drow; row<row0+drow;row++){
7179 0 : if (row<0) continue;
7180 0 : if (row>155) continue;
7181 : //RS if (ktrack0->GetClusterPointer(row)) {
7182 0 : if (ktrack0->GetClusterIndex2(row)>=0) {
7183 0 : const AliTPCTrackerPoints::Point *point = ktrack0->GetTrackPoint(row);
7184 0 : shapesum+=point->GetSigmaY()+point->GetSigmaZ();
7185 0 : sum++;
7186 0 : }
7187 : //RS if (ktrack1->GetClusterPointer(row)){
7188 0 : if (ktrack1->GetClusterIndex2(row)>=0) {
7189 0 : const AliTPCTrackerPoints::Point *point =ktrack1->GetTrackPoint(row);
7190 0 : shapesum+=point->GetSigmaY()+point->GetSigmaZ();
7191 0 : sum++;
7192 0 : }
7193 : }
7194 0 : if (sum<4){
7195 0 : kink->SetShapeFactor(-1.);
7196 0 : }
7197 : else{
7198 0 : kink->SetShapeFactor(shapesum/sum);
7199 : }
7200 : // esd->AddKink(kink);
7201 : //
7202 : // kink->SetMother(paramm);
7203 : //kink->SetDaughter(paramd);
7204 :
7205 0 : Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
7206 0 : chi2P2*=chi2P2;
7207 0 : chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
7208 0 : Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
7209 0 : chi2P3*=chi2P3;
7210 0 : chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
7211 : //
7212 0 : if ((AliTPCReconstructor::StreamLevel()&kStreamFindKinks)>0) { // flag: stream track infroamtion in the FindKinks method
7213 0 : (*fDebugStreamer)<<"kinkLpt"<<
7214 0 : "chi2P2="<<chi2P2<<
7215 0 : "chi2P3="<<chi2P3<<
7216 0 : "p0.="<<¶mm<<
7217 0 : "p1.="<<¶md<<
7218 0 : "k.="<<kink<<
7219 : "\n";
7220 : }
7221 0 : if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
7222 0 : continue;
7223 : }
7224 : //
7225 0 : kinks.AddLast(kink);
7226 0 : kink = new AliKink;
7227 0 : ncandidates++;
7228 32 : }
7229 148 : }
7230 : //
7231 : // sort the kinks according quality - and refit them towards vertex
7232 : //
7233 8 : Int_t nkinks = kinks.GetEntriesFast();
7234 8 : Float_t quality[nkinks];
7235 8 : Int_t indexes[nkinks];
7236 8 : AliTPCseed *mothers[nkinks];
7237 8 : AliTPCseed *daughters[nkinks];
7238 8 : memset(mothers,0,nkinks*sizeof(AliTPCseed*));
7239 8 : memset(daughters,0,nkinks*sizeof(AliTPCseed*));
7240 : //
7241 : //
7242 16 : for (Int_t i=0;i<nkinks;i++){
7243 0 : quality[i] =100000;
7244 0 : AliKink *kinkl = (AliKink*)kinks.At(i);
7245 : //
7246 : // refit kinks towards vertex
7247 : //
7248 0 : Int_t index0 = kinkl->GetIndex(0);
7249 0 : Int_t index1 = kinkl->GetIndex(1);
7250 0 : AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
7251 0 : AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
7252 : //
7253 0 : Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
7254 : //
7255 : // Refit Kink under if too small angle
7256 : //
7257 0 : if (kinkl->GetAngle(2)<0.05){
7258 : //
7259 : // RS: if possible, remove kink before reseeding
7260 0 : if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
7261 0 : delete kinks.RemoveAt(i);
7262 0 : continue;
7263 : }
7264 : //
7265 0 : kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
7266 0 : Int_t row0 = kinkl->GetTPCRow0();
7267 0 : Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
7268 : //
7269 0 : Int_t last = row0-drow;
7270 0 : if (last<40) last=40;
7271 0 : if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
7272 0 : AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
7273 : //
7274 0 : Int_t first = row0+drow;
7275 0 : if (first>130) first=130;
7276 0 : if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
7277 0 : AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
7278 : //
7279 0 : if (seed0 && seed1) {
7280 0 : kinkl->SetStatus(1,8);
7281 0 : if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
7282 0 : row0 = GetRowNumber(kinkl->GetR());
7283 0 : sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
7284 0 : mothers[i] = seed0;
7285 0 : daughters[i] = seed1;
7286 : }
7287 : else {
7288 0 : delete kinks.RemoveAt(i);
7289 0 : if (seed0) MarkSeedFree( seed0 );
7290 0 : if (seed1) MarkSeedFree( seed1 );
7291 0 : continue;
7292 : }
7293 0 : }
7294 : //
7295 0 : if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
7296 0 : }
7297 8 : TMath::Sort(nkinks,quality,indexes,kFALSE);
7298 : //
7299 : //remove double find kinks
7300 : //
7301 16 : for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
7302 0 : AliKink * kink0 = (AliKink*) kinks.At(indexes[ikink0]);
7303 0 : if (!kink0) continue;
7304 : //
7305 0 : for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
7306 0 : kink0 = (AliKink*) kinks.At(indexes[ikink0]);
7307 0 : if (!kink0) continue;
7308 0 : AliKink * kink1 = (AliKink*) kinks.At(indexes[ikink1]);
7309 0 : if (!kink1) continue;
7310 : // if not close kink continue
7311 0 : if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
7312 0 : if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
7313 0 : if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
7314 : //
7315 0 : AliTPCseed &mother0 = mothers[indexes[ikink0]] ? *mothers[indexes[ikink0]] : *((AliTPCseed*)array->At(kink0->GetIndex(0)));
7316 0 : AliTPCseed &daughter0 = daughters[indexes[ikink0]] ? *daughters[indexes[ikink0]] : *((AliTPCseed*)array->At(kink0->GetIndex(1)));
7317 0 : AliTPCseed &mother1 = mothers[indexes[ikink1]] ? *mothers[indexes[ikink1]] : *((AliTPCseed*)array->At(kink1->GetIndex(0)));
7318 0 : AliTPCseed &daughter1 = daughters[indexes[ikink1]] ? *daughters[indexes[ikink1]] : *((AliTPCseed*)array->At(kink1->GetIndex(1)));
7319 :
7320 0 : Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
7321 : //
7322 : Int_t same = 0;
7323 : Int_t both = 0;
7324 : Int_t samem = 0;
7325 : Int_t bothm = 0;
7326 : Int_t samed = 0;
7327 : Int_t bothd = 0;
7328 : //
7329 0 : for (Int_t i=0;i<row0;i++){
7330 0 : if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
7331 0 : both++;
7332 0 : bothm++;
7333 0 : if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
7334 0 : same++;
7335 0 : samem++;
7336 0 : }
7337 : }
7338 : }
7339 :
7340 0 : for (Int_t i=row0;i<158;i++){
7341 : //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
7342 0 : if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
7343 0 : both++;
7344 0 : bothd++;
7345 0 : if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
7346 0 : same++;
7347 0 : samed++;
7348 0 : }
7349 : }
7350 : }
7351 0 : Float_t ratio = Float_t(same+1)/Float_t(both+1);
7352 0 : Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
7353 0 : Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
7354 0 : if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
7355 0 : Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
7356 0 : Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
7357 0 : if (sum1>sum0){
7358 0 : shared[kink0->GetIndex(0)]= kTRUE;
7359 0 : shared[kink0->GetIndex(1)]= kTRUE;
7360 0 : delete kinks.RemoveAt(indexes[ikink0]);
7361 0 : break;
7362 : }
7363 : else{
7364 0 : shared[kink1->GetIndex(0)]= kTRUE;
7365 0 : shared[kink1->GetIndex(1)]= kTRUE;
7366 0 : delete kinks.RemoveAt(indexes[ikink1]);
7367 : }
7368 0 : }
7369 0 : }
7370 0 : }
7371 :
7372 :
7373 16 : for (Int_t i=0;i<nkinks;i++){
7374 0 : AliKink * kinkl = (AliKink*) kinks.At(indexes[i]);
7375 0 : if (!kinkl) continue;
7376 0 : kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
7377 0 : Int_t index0 = kinkl->GetIndex(0);
7378 0 : Int_t index1 = kinkl->GetIndex(1);
7379 0 : if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
7380 0 : kinkl->SetMultiple(usage[index0],0);
7381 0 : kinkl->SetMultiple(usage[index1],1);
7382 0 : if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
7383 0 : if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
7384 0 : if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
7385 0 : if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
7386 :
7387 0 : AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
7388 0 : AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
7389 0 : if (!ktrack0 || !ktrack1) continue;
7390 0 : Int_t index = esd->AddKink(kinkl);
7391 : //
7392 : //
7393 0 : if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
7394 0 : if ( (mothers[indexes[i]]) && daughters[indexes[i]] &&
7395 0 : mothers[indexes[i]]->GetNumberOfClusters()>20 && // where they reseeded?
7396 0 : daughters[indexes[i]]->GetNumberOfClusters()>20 &&
7397 0 : (mothers[indexes[i]]->GetNumberOfClusters()+daughters[indexes[i]]->GetNumberOfClusters())>100){
7398 0 : *ktrack0 = *mothers[indexes[i]];
7399 0 : *ktrack1 = *daughters[indexes[i]];
7400 : }
7401 : }
7402 : //
7403 0 : ktrack0->SetKinkIndex(usage[index0],-(index+1));
7404 0 : ktrack1->SetKinkIndex(usage[index1], (index+1));
7405 0 : usage[index0]++;
7406 0 : usage[index1]++;
7407 0 : }
7408 : //
7409 : // Remove tracks corresponding to shared kink's
7410 : //
7411 552 : for (Int_t i=0;i<nentries;i++){
7412 536 : AliTPCseed * track0 = (AliTPCseed*)array->At(i);
7413 388 : if (!track0) continue;
7414 296 : if (track0->GetKinkIndex(0)!=0) continue;
7415 148 : if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
7416 148 : }
7417 :
7418 : //
7419 : //
7420 8 : RemoveUsed2(array,0.5,0.4,30);
7421 8 : UnsignClusters();
7422 552 : for (Int_t i=0;i<nentries;i++){
7423 536 : AliTPCseed * track0 = (AliTPCseed*)array->At(i);
7424 402 : if (!track0) continue;
7425 134 : track0->CookdEdx(0.02,0.6);
7426 134 : track0->CookPID();
7427 134 : }
7428 : //
7429 : // RS use stack allocation instead of the heap
7430 16 : AliTPCseed mother,daughter;
7431 8 : AliKink kinkl;
7432 : //
7433 552 : for (Int_t i=0;i<nentries;i++){
7434 536 : AliTPCseed * track0 = (AliTPCseed*)array->At(i);
7435 400 : if (!track0) continue;
7436 352 : if (track0->Pt()<1.4) continue;
7437 : //remove double high momenta tracks - overlapped with kink candidates
7438 : Int_t ishared=0;
7439 : Int_t all =0;
7440 17220 : for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
7441 8554 : Int_t tpcindex = track0->GetClusterIndex2(icl);
7442 9448 : if (tpcindex<0) continue;
7443 7660 : AliTPCclusterMI *cl = GetClusterMI(tpcindex);
7444 7660 : all++;
7445 7946 : if (cl->IsUsed(10)) ishared++;
7446 7660 : }
7447 56 : if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
7448 4 : MarkSeedFree( array->RemoveAt(i) );
7449 2 : continue;
7450 : }
7451 : //
7452 110 : if (track0->GetKinkIndex(0)!=0) continue;
7453 104 : if (track0->GetNumberOfClusters()<80) continue;
7454 :
7455 : // AliTPCseed *pmother = new AliTPCseed(); // RS use stack allocation
7456 : // AliTPCseed *pdaughter = new AliTPCseed();
7457 : // AliKink *pkink = new AliKink;
7458 : //
7459 104 : if (CheckKinkPoint(track0,mother,daughter, kinkl)){
7460 44 : if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
7461 : // delete pmother; // RS used stack allocation
7462 : // delete pdaughter;
7463 : // delete pkink;
7464 4 : continue; //too short tracks
7465 : }
7466 16 : if (mother.Pt()<1.4) {
7467 : // delete pmother; // RS used stack allocation
7468 : // delete pdaughter;
7469 : // delete pkink;
7470 0 : continue;
7471 : }
7472 8 : Int_t row0= kinkl.GetTPCRow0();
7473 18 : if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
7474 : // delete pmother; // RS used stack allocation
7475 : // delete pdaughter;
7476 : // delete pkink;
7477 4 : continue;
7478 : }
7479 : //
7480 4 : Int_t index = esd->AddKink(&kinkl);
7481 4 : mother.SetKinkIndex(0,-(index+1));
7482 4 : daughter.SetKinkIndex(0,index+1);
7483 8 : if (mother.GetNumberOfClusters()>50) {
7484 8 : MarkSeedFree( array->RemoveAt(i) );
7485 12 : AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
7486 4 : mtc->SetPoolID(fLastSeedID);
7487 4 : array->AddAt(mtc,i);
7488 4 : }
7489 : else{
7490 0 : AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
7491 0 : mtc->SetPoolID(fLastSeedID);
7492 0 : array->AddLast(mtc);
7493 : }
7494 12 : AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
7495 4 : dtc->SetPoolID(fLastSeedID);
7496 4 : array->AddLast(dtc);
7497 732 : for (Int_t icl=0;icl<row0;icl++) {
7498 362 : Int_t tpcindex= mother.GetClusterIndex2(icl);
7499 420 : if (tpcindex<0) continue;
7500 304 : AliTPCclusterMI *cl = GetClusterMI(tpcindex);
7501 608 : if (cl) cl->Use(20);
7502 304 : }
7503 : //
7504 548 : for (Int_t icl=row0;icl<158;icl++) {
7505 270 : Int_t tpcindex= mother.GetClusterIndex2(icl);
7506 404 : if (tpcindex<0) continue;
7507 136 : AliTPCclusterMI *cl = GetClusterMI(tpcindex);
7508 272 : if (cl) cl->Use(20);
7509 136 : }
7510 : //
7511 4 : }
7512 : //delete pmother; // RS used stack allocation
7513 : //delete pdaughter;
7514 : //delete pkink;
7515 44 : }
7516 :
7517 16 : for (int i=nkinks;i--;) {
7518 0 : if (mothers[i]) MarkSeedFree( mothers[i] );
7519 0 : if (daughters[i]) MarkSeedFree( daughters[i] );
7520 : }
7521 : // delete [] daughters;
7522 : // delete [] mothers;
7523 : //
7524 : // RS: most of heap array are converted to stack arrays
7525 : // delete [] dca;
7526 : // delete []circular;
7527 : // delete []shared;
7528 : // delete []quality;
7529 : // delete []indexes;
7530 : //
7531 16 : delete kink;
7532 : // delete[]fim;
7533 : // delete[] zm;
7534 : // delete[] z0;
7535 : // delete [] usage;
7536 : // delete[] alpha;
7537 : // delete[] nclusters;
7538 : // delete[] sign;
7539 : // delete[] helixes;
7540 16 : if (fHelixPool) fHelixPool->Clear();
7541 8 : kinks.Delete();
7542 : //delete kinks;
7543 :
7544 32 : AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
7545 8 : timer.Print();
7546 8 : }
7547 :
7548 : Int_t AliTPCtracker::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
7549 : {
7550 : //
7551 : // refit kink towards to the vertex
7552 : //
7553 : //
7554 0 : AliKink &kink=(AliKink &)knk;
7555 :
7556 0 : Int_t row0 = GetRowNumber(kink.GetR());
7557 0 : FollowProlongation(mother,0);
7558 0 : mother.Reset(kFALSE);
7559 : //
7560 0 : FollowProlongation(daughter,row0);
7561 0 : daughter.Reset(kFALSE);
7562 0 : FollowBackProlongation(daughter,158);
7563 0 : daughter.Reset(kFALSE);
7564 0 : Int_t first = TMath::Max(row0-20,30);
7565 0 : Int_t last = TMath::Min(row0+20,140);
7566 : //
7567 : const Int_t kNdiv =5;
7568 0 : AliTPCseed param0[kNdiv]; // parameters along the track
7569 0 : AliTPCseed param1[kNdiv]; // parameters along the track
7570 0 : AliKink kinks[kNdiv]; // corresponding kink parameters
7571 : //
7572 0 : Int_t rows[kNdiv];
7573 0 : for (Int_t irow=0; irow<kNdiv;irow++){
7574 0 : rows[irow] = first +((last-first)*irow)/(kNdiv-1);
7575 : }
7576 : // store parameters along the track
7577 : //
7578 0 : for (Int_t irow=0;irow<kNdiv;irow++){
7579 0 : FollowBackProlongation(mother, rows[irow]);
7580 0 : FollowProlongation(daughter,rows[kNdiv-1-irow]);
7581 0 : param0[irow] = mother;
7582 0 : param1[kNdiv-1-irow] = daughter;
7583 : }
7584 : //
7585 : // define kinks
7586 0 : for (Int_t irow=0; irow<kNdiv-1;irow++){
7587 0 : if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
7588 0 : kinks[irow].SetMother(param0[irow]);
7589 0 : kinks[irow].SetDaughter(param1[irow]);
7590 0 : kinks[irow].Update();
7591 : }
7592 : //
7593 : // choose kink with best "quality"
7594 : Int_t index =-1;
7595 : Double_t mindist = 10000;
7596 0 : for (Int_t irow=0;irow<kNdiv;irow++){
7597 0 : if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
7598 0 : if (TMath::Abs(kinks[irow].GetR())>240.) continue;
7599 0 : if (TMath::Abs(kinks[irow].GetR())<100.) continue;
7600 : //
7601 0 : Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
7602 0 : normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
7603 0 : if (normdist < mindist){
7604 : mindist = normdist;
7605 : index = irow;
7606 0 : }
7607 0 : }
7608 : //
7609 0 : if (index==-1) return 0;
7610 : //
7611 : //
7612 0 : param0[index].Reset(kTRUE);
7613 0 : FollowProlongation(param0[index],0);
7614 : //
7615 0 : mother = param0[index];
7616 0 : daughter = param1[index]; // daughter in vertex
7617 : //
7618 0 : kink.SetMother(mother);
7619 0 : kink.SetDaughter(daughter);
7620 0 : kink.Update();
7621 0 : kink.SetTPCRow0(GetRowNumber(kink.GetR()));
7622 0 : kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
7623 0 : kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
7624 0 : kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
7625 0 : kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),kMaxRow),1);
7626 0 : mother.SetLabel(kink.GetLabel(0));
7627 0 : daughter.SetLabel(kink.GetLabel(1));
7628 :
7629 0 : return 1;
7630 0 : }
7631 :
7632 :
7633 : void AliTPCtracker::UpdateKinkQualityM(AliTPCseed * seed){
7634 : //
7635 : // update Kink quality information for mother after back propagation
7636 : //
7637 8 : if (seed->GetKinkIndex(0)>=0) return;
7638 16 : for (Int_t ikink=0;ikink<3;ikink++){
7639 8 : Int_t index = seed->GetKinkIndex(ikink);
7640 12 : if (index>=0) break;
7641 4 : index = TMath::Abs(index)-1;
7642 4 : AliESDkink * kink = fEvent->GetKink(index);
7643 4 : kink->SetTPCDensity(-1,0,0);
7644 4 : kink->SetTPCDensity(1,0,1);
7645 : //
7646 4 : Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
7647 4 : if (row0<15) row0=15;
7648 : //
7649 4 : Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
7650 4 : if (row1>145) row1=145;
7651 : //
7652 4 : Int_t found,foundable;//,shared;
7653 : //GetSeedClusterStatistic(seed,0,row0, found, foundable,shared,kFALSE); //RS: seeds don't keep their clusters
7654 : //RS seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
7655 4 : seed->GetClusterStatistic(0,row0, found, foundable);
7656 8 : if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,0);
7657 : //
7658 : //GetSeedClusterStatistic(seed,row1,155, found, foundable,shared,kFALSE); //RS: seeds don't keep their clusters
7659 : //RS seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
7660 4 : seed->GetClusterStatistic(row1,155, found, foundable);
7661 8 : if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,1);
7662 4 : }
7663 :
7664 4 : }
7665 :
7666 : void AliTPCtracker::UpdateKinkQualityD(AliTPCseed * seed){
7667 : //
7668 : // update Kink quality information for daughter after refit
7669 : //
7670 8 : if (seed->GetKinkIndex(0)<=0) return;
7671 16 : for (Int_t ikink=0;ikink<3;ikink++){
7672 8 : Int_t index = seed->GetKinkIndex(ikink);
7673 12 : if (index<=0) break;
7674 4 : index = TMath::Abs(index)-1;
7675 4 : AliESDkink * kink = fEvent->GetKink(index);
7676 4 : kink->SetTPCDensity(-1,1,0);
7677 4 : kink->SetTPCDensity(-1,1,1);
7678 : //
7679 4 : Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
7680 4 : if (row0<15) row0=15;
7681 : //
7682 4 : Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
7683 4 : if (row1>145) row1=145;
7684 : //
7685 4 : Int_t found,foundable;//,shared;
7686 : //GetSeedClusterStatistic(0,row0, found, foundable,shared,kFALS); //RS: seeds don't keep their clusters
7687 : //seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
7688 4 : seed->GetClusterStatistic(0,row0, found, foundable);
7689 8 : if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,0);
7690 : //
7691 : //GetSeedClusterStatistic(row1,155, found, foundable,shared,kFALSE); //RS: seeds don't keep their clusters
7692 : // seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
7693 4 : seed->GetClusterStatistic(row1,155, found, foundable);
7694 8 : if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,1);
7695 4 : }
7696 :
7697 4 : }
7698 :
7699 :
7700 : Int_t AliTPCtracker::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
7701 : {
7702 : //
7703 : // check kink point for given track
7704 : // if return value=0 kink point not found
7705 : // otherwise seed0 correspond to mother particle
7706 : // seed1 correspond to daughter particle
7707 : // kink parameter of kink point
7708 104 : AliKink &kink=(AliKink &)knk;
7709 :
7710 52 : Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
7711 52 : Int_t first = seed->GetFirstPoint();
7712 52 : Int_t last = seed->GetLastPoint();
7713 52 : if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
7714 :
7715 :
7716 52 : AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
7717 52 : if (!seed1) return 0;
7718 52 : FollowProlongation(*seed1,seed->GetLastPoint()-20);
7719 52 : seed1->Reset(kTRUE);
7720 52 : FollowProlongation(*seed1,158);
7721 52 : seed1->Reset(kTRUE);
7722 52 : last = seed1->GetLastPoint();
7723 : //
7724 52 : AliTPCseed *seed0 = new( NextFreeSeed() ) AliTPCseed(*seed);
7725 52 : seed0->SetPoolID(fLastSeedID);
7726 52 : seed0->Reset(kFALSE);
7727 52 : seed0->Reset();
7728 : //
7729 2132 : AliTPCseed param0[20]; // parameters along the track
7730 2132 : AliTPCseed param1[20]; // parameters along the track
7731 2132 : AliKink kinks[20]; // corresponding kink parameters
7732 52 : Int_t rows[20];
7733 2184 : for (Int_t irow=0; irow<20;irow++){
7734 1040 : rows[irow] = first +((last-first)*irow)/19;
7735 : }
7736 : // store parameters along the track
7737 : //
7738 2184 : for (Int_t irow=0;irow<20;irow++){
7739 1040 : FollowBackProlongation(*seed0, rows[irow]);
7740 1040 : FollowProlongation(*seed1,rows[19-irow]);
7741 1040 : param0[irow] = *seed0;
7742 1040 : param1[19-irow] = *seed1;
7743 : }
7744 : //
7745 : // define kinks
7746 2080 : for (Int_t irow=0; irow<19;irow++){
7747 988 : kinks[irow].SetMother(param0[irow]);
7748 988 : kinks[irow].SetDaughter(param1[irow]);
7749 988 : kinks[irow].Update();
7750 : }
7751 : //
7752 : // choose kink with biggest change of angle
7753 : Int_t index =-1;
7754 : Double_t maxchange= 0;
7755 1976 : for (Int_t irow=1;irow<19;irow++){
7756 936 : if (TMath::Abs(kinks[irow].GetR())>240.) continue;
7757 906 : if (TMath::Abs(kinks[irow].GetR())<110.) continue;
7758 1412 : Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
7759 706 : if ( quality > maxchange){
7760 : maxchange = quality;
7761 : index = irow;
7762 : //
7763 258 : }
7764 706 : }
7765 52 : MarkSeedFree( seed0 );
7766 52 : MarkSeedFree( seed1 );
7767 52 : if (index<0) return 0;
7768 : //
7769 52 : Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
7770 156 : seed0 = new( NextFreeSeed() ) AliTPCseed(param0[index]);
7771 52 : seed0->SetPoolID(fLastSeedID);
7772 156 : seed1 = new( NextFreeSeed() ) AliTPCseed(param1[index]);
7773 52 : seed1->SetPoolID(fLastSeedID);
7774 52 : seed0->Reset(kFALSE);
7775 52 : seed1->Reset(kFALSE);
7776 52 : seed0->ResetCovariance(10.);
7777 52 : seed1->ResetCovariance(10.);
7778 52 : FollowProlongation(*seed0,0);
7779 52 : FollowBackProlongation(*seed1,158);
7780 52 : mother = *seed0; // backup mother at position 0
7781 52 : seed0->Reset(kFALSE);
7782 52 : seed1->Reset(kFALSE);
7783 52 : seed0->ResetCovariance(10.);
7784 52 : seed1->ResetCovariance(10.);
7785 : //
7786 52 : first = TMath::Max(row0-20,0);
7787 52 : last = TMath::Min(row0+20,158);
7788 : //
7789 2184 : for (Int_t irow=0; irow<20;irow++){
7790 1040 : rows[irow] = first +((last-first)*irow)/19;
7791 : }
7792 : // store parameters along the track
7793 : //
7794 2184 : for (Int_t irow=0;irow<20;irow++){
7795 1040 : FollowBackProlongation(*seed0, rows[irow]);
7796 1040 : FollowProlongation(*seed1,rows[19-irow]);
7797 1040 : param0[irow] = *seed0;
7798 1040 : param1[19-irow] = *seed1;
7799 : }
7800 : //
7801 : // define kinks
7802 2080 : for (Int_t irow=0; irow<19;irow++){
7803 988 : kinks[irow].SetMother(param0[irow]);
7804 988 : kinks[irow].SetDaughter(param1[irow]);
7805 : // param0[irow].Dump();
7806 : //param1[irow].Dump();
7807 988 : kinks[irow].Update();
7808 : }
7809 : //
7810 : // choose kink with biggest change of angle
7811 : index =-1;
7812 : maxchange= 0;
7813 2184 : for (Int_t irow=0;irow<20;irow++){
7814 1040 : if (TMath::Abs(kinks[irow].GetR())>250.) continue;
7815 1012 : if (TMath::Abs(kinks[irow].GetR())<90.) continue;
7816 1748 : Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
7817 874 : if ( quality > maxchange){
7818 : maxchange = quality;
7819 : index = irow;
7820 : //
7821 266 : }
7822 874 : }
7823 : //
7824 : //
7825 208 : if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
7826 0 : MarkSeedFree( seed0 );
7827 0 : MarkSeedFree( seed1 );
7828 0 : return 0;
7829 : }
7830 :
7831 : // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
7832 :
7833 52 : kink.SetMother(param0[index]);
7834 52 : kink.SetDaughter(param1[index]);
7835 52 : kink.Update();
7836 :
7837 156 : Double_t chi2P2 = param0[index].GetParameter()[2]-param1[index].GetParameter()[2];
7838 52 : chi2P2*=chi2P2;
7839 52 : chi2P2/=param0[index].GetCovariance()[5]+param1[index].GetCovariance()[5];
7840 156 : Double_t chi2P3 = param0[index].GetParameter()[3]-param1[index].GetParameter()[3];
7841 52 : chi2P3*=chi2P3;
7842 52 : chi2P3/=param0[index].GetCovariance()[9]+param1[index].GetCovariance()[9];
7843 : //
7844 52 : if (AliTPCReconstructor::StreamLevel()&kStreamFindKinks) { // flag: stream track infroamtion in the FindKinks method
7845 0 : (*fDebugStreamer)<<"kinkHpt"<<
7846 0 : "chi2P2="<<chi2P2<<
7847 0 : "chi2P3="<<chi2P3<<
7848 0 : "p0.="<<¶m0[index]<<
7849 0 : "p1.="<<¶m1[index]<<
7850 0 : "k.="<<&kink<<
7851 : "\n";
7852 : }
7853 104 : if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
7854 40 : MarkSeedFree( seed0 );
7855 40 : MarkSeedFree( seed1 );
7856 40 : return 0;
7857 : }
7858 :
7859 :
7860 12 : row0 = GetRowNumber(kink.GetR());
7861 12 : kink.SetTPCRow0(row0);
7862 24 : kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
7863 24 : kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
7864 12 : kink.SetIndex(-10,0);
7865 36 : kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
7866 24 : kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
7867 24 : kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
7868 : //
7869 : //
7870 : // new (&mother) AliTPCseed(param0[index]);
7871 12 : daughter = param1[index];
7872 12 : daughter.SetLabel(kink.GetLabel(1));
7873 12 : param0[index].Reset(kTRUE);
7874 12 : FollowProlongation(param0[index],0);
7875 12 : mother = param0[index];
7876 12 : mother.SetLabel(kink.GetLabel(0));
7877 24 : if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(1)){
7878 0 : mother=*seed;
7879 : }
7880 12 : MarkSeedFree( seed0 );
7881 12 : MarkSeedFree( seed1 );
7882 : //
7883 12 : return 1;
7884 3432 : }
7885 :
7886 :
7887 :
7888 :
7889 : AliTPCseed* AliTPCtracker::ReSeed(AliTPCseed *t)
7890 : {
7891 : //
7892 : // reseed - refit - track
7893 : //
7894 : Int_t first = 0;
7895 : // Int_t last = fSectors->GetNRows()-1;
7896 : //
7897 0 : if (fSectors == fOuterSec){
7898 0 : first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
7899 : //last =
7900 0 : }
7901 : else
7902 0 : first = t->GetFirstPoint();
7903 : //
7904 0 : AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
7905 0 : FollowBackProlongation(*t,fSectors->GetNRows()-1);
7906 0 : t->Reset(kFALSE);
7907 0 : FollowProlongation(*t,first);
7908 0 : return seed;
7909 : }
7910 :
7911 :
7912 :
7913 :
7914 :
7915 :
7916 :
7917 : //_____________________________________________________________________________
7918 : Int_t AliTPCtracker::ReadSeeds(const TFile *inp) {
7919 : //-----------------------------------------------------------------
7920 : // This function reades track seeds.
7921 : //-----------------------------------------------------------------
7922 0 : TDirectory *savedir=gDirectory;
7923 :
7924 : TFile *in=(TFile*)inp;
7925 0 : if (!in->IsOpen()) {
7926 0 : cerr<<"AliTPCtracker::ReadSeeds(): input file is not open !\n";
7927 0 : return 1;
7928 : }
7929 :
7930 0 : in->cd();
7931 0 : TTree *seedTree=(TTree*)in->Get("Seeds");
7932 0 : if (!seedTree) {
7933 0 : cerr<<"AliTPCtracker::ReadSeeds(): ";
7934 0 : cerr<<"can't get a tree with track seeds !\n";
7935 0 : return 2;
7936 : }
7937 0 : AliTPCtrack *seed=new AliTPCtrack;
7938 0 : seedTree->SetBranchAddress("tracks",&seed);
7939 :
7940 0 : if (fSeeds==0) fSeeds=new TObjArray(15000);
7941 :
7942 0 : Int_t n=(Int_t)seedTree->GetEntries();
7943 0 : for (Int_t i=0; i<n; i++) {
7944 0 : seedTree->GetEvent(i);
7945 0 : AliTPCseed* sdc = new( NextFreeSeed() ) AliTPCseed(*seed/*,seed->GetAlpha()*/);
7946 0 : sdc->SetPoolID(fLastSeedID);
7947 0 : fSeeds->AddLast(sdc);
7948 : }
7949 :
7950 0 : delete seed; // RS: this seed is not from the pool, delete it !!!
7951 0 : delete seedTree;
7952 0 : savedir->cd();
7953 : return 0;
7954 0 : }
7955 :
7956 : Int_t AliTPCtracker::Clusters2TracksHLT (AliESDEvent *const esd, const AliESDEvent *hltEvent)
7957 : {
7958 : //
7959 : // clusters to tracks
7960 22 : if (fSeeds) DeleteSeeds();
7961 2 : else ResetSeedsPool();
7962 8 : fEvent = esd;
7963 8 : fEventHLT = hltEvent;
7964 8 : fAccountDistortions = AliTPCReconstructor::GetRecoParam()->GetAccountDistortions();
7965 8 : if (AliTPCReconstructor::GetRecoParam()->GetUseOulierClusterFilter()) FilterOutlierClusters();
7966 8 : AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
7967 8 : transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
7968 8 : transform->SetCurrentTimeStamp( GetTimeStamp());
7969 8 : transform->SetCurrentRun( GetRunNumber());
7970 :
7971 : //transform->SetCurrentTimeStamp( esd->GetTimeStamp());
7972 : //transform->SetCurrentRun(esd->GetRunNumber());
7973 : //
7974 8 : if (AliTPCReconstructor::GetExtendedRoads()){
7975 0 : fClExtraRoadY = AliTPCReconstructor::GetExtendedRoads()[0];
7976 0 : fClExtraRoadZ = AliTPCReconstructor::GetExtendedRoads()[1];
7977 0 : AliInfoF("Additional errors for roads: Y:%f Z:%f",fClExtraRoadY,fClExtraRoadZ);
7978 0 : }
7979 24 : const Double_t *errCluster = (AliTPCReconstructor::GetSystematicErrorCluster()) ?
7980 0 : AliTPCReconstructor::GetSystematicErrorCluster() :
7981 8 : AliTPCReconstructor::GetRecoParam()->GetSystematicErrorCluster();
7982 : //
7983 8 : fExtraClErrY2 = errCluster[0]*errCluster[0];
7984 8 : fExtraClErrZ2 = errCluster[1]*errCluster[1];
7985 8 : fExtraClErrYZ2 = fExtraClErrY2 + fExtraClErrZ2;
7986 40 : AliInfoF("Additional errors for clusters: Y:%f Z:%f",errCluster[0],errCluster[1]);
7987 : //
7988 8 : if (AliTPCReconstructor::GetPrimaryDCACut()) {
7989 0 : fPrimaryDCAYCut = AliTPCReconstructor::GetPrimaryDCACut()[0];
7990 0 : fPrimaryDCAZCut = AliTPCReconstructor::GetPrimaryDCACut()[1];
7991 0 : fDisableSecondaries = kTRUE;
7992 0 : AliInfoF("Only primaries will be tracked with DCAY=%f and DCAZ=%f cuts",fPrimaryDCAYCut,fPrimaryDCAZCut);
7993 0 : }
7994 : //
7995 8 : Clusters2Tracks();
7996 8 : fEventHLT = 0;
7997 8 : if (!fSeeds) return 1;
7998 8 : FillESD(fSeeds);
7999 8 : if ((AliTPCReconstructor::StreamLevel()&kStreamClDump)>0) DumpClusters(0,fSeeds);
8000 8 : return 0;
8001 : //
8002 8 : }
8003 :
8004 : Int_t AliTPCtracker::Clusters2Tracks(AliESDEvent *const esd)
8005 : {
8006 : //
8007 : // clusters to tracks
8008 0 : return Clusters2TracksHLT( esd, 0);
8009 : }
8010 :
8011 : //_____________________________________________________________________________
8012 : Int_t AliTPCtracker::Clusters2Tracks() {
8013 : //-----------------------------------------------------------------
8014 : // This is a track finder.
8015 : //-----------------------------------------------------------------
8016 16 : TDirectory *savedir=gDirectory;
8017 8 : TStopwatch timer;
8018 :
8019 8 : fIteration = 0;
8020 16 : fSeeds = Tracking();
8021 :
8022 8 : if (fDebug>0){
8023 0 : Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
8024 : }
8025 : //activate again some tracks
8026 864 : for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
8027 280 : AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
8028 280 : if (!pt) continue;
8029 280 : Int_t nc=t.GetNumberOfClusters();
8030 280 : if (nc<20) {
8031 0 : MarkSeedFree( fSeeds->RemoveAt(i) );
8032 0 : continue;
8033 : }
8034 280 : CookLabel(pt,0.1);
8035 280 : if (pt->GetRemoval()==10) {
8036 12 : if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
8037 6 : pt->Desactivate(10); // make track again active // MvL: should be 0 ?
8038 : else{
8039 0 : pt->Desactivate(20);
8040 0 : MarkSeedFree( fSeeds->RemoveAt(i) );
8041 : }
8042 : }
8043 280 : }
8044 : //
8045 8 : RemoveUsed2(fSeeds,0.85,0.85,0);
8046 24 : if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
8047 : //FindCurling(fSeeds, fEvent,0);
8048 8 : if (AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC) FindMultiMC(fSeeds, fEvent,-1); // find multi found tracks
8049 8 : RemoveUsed2(fSeeds,0.5,0.4,20);
8050 8 : FindSplitted(fSeeds, fEvent,0); // find multi found tracks
8051 8 : if (AliTPCReconstructor::StreamLevel()&kStreamFindMultiMC) FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
8052 :
8053 : // //
8054 : // // refit short tracks
8055 : // //
8056 8 : Int_t nseed=fSeeds->GetEntriesFast();
8057 : //
8058 : Int_t found = 0;
8059 532 : for (Int_t i=0; i<nseed; i++) {
8060 258 : AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
8061 380 : if (!pt) continue;
8062 136 : Int_t nc=t.GetNumberOfClusters();
8063 136 : if (nc<15) {
8064 0 : MarkSeedFree( fSeeds->RemoveAt(i) );
8065 0 : continue;
8066 : }
8067 136 : CookLabel(pt,0.1); //For comparison only
8068 : //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
8069 136 : if ((pt->IsActive() || (pt->GetRemoval()==10) )){
8070 136 : found++;
8071 136 : if (fDebug>0) cerr<<found<<'\r';
8072 136 : pt->SetLab2(i);
8073 136 : }
8074 : else
8075 0 : MarkSeedFree( fSeeds->RemoveAt(i) );
8076 136 : }
8077 :
8078 :
8079 : //RemoveOverlap(fSeeds,0.99,7,kTRUE);
8080 8 : SignShared(fSeeds);
8081 : //RemoveUsed(fSeeds,0.9,0.9,6);
8082 : //
8083 8 : nseed=fSeeds->GetEntriesFast();
8084 : found = 0;
8085 288 : for (Int_t i=0; i<nseed; i++) {
8086 136 : AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
8087 136 : if (!pt) continue;
8088 136 : Int_t nc=t.GetNumberOfClusters();
8089 136 : if (nc<15) {
8090 0 : MarkSeedFree( fSeeds->RemoveAt(i) );
8091 0 : continue;
8092 : }
8093 136 : t.SetUniqueID(i);
8094 136 : t.CookdEdx(0.02,0.6);
8095 : // CheckKinkPoint(&t,0.05);
8096 : //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
8097 136 : if ((pt->IsActive() || (pt->GetRemoval()==10) )){
8098 136 : found++;
8099 136 : if (fDebug>0){
8100 0 : cerr<<found<<'\r';
8101 : }
8102 136 : pt->SetLab2(i);
8103 136 : }
8104 : else
8105 0 : MarkSeedFree( fSeeds->RemoveAt(i) );
8106 : //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
8107 : //if (seed1){
8108 : // FollowProlongation(*seed1,0);
8109 : // Int_t n = seed1->GetNumberOfClusters();
8110 : // printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
8111 : // printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
8112 : //
8113 : //}
8114 : //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
8115 :
8116 136 : }
8117 :
8118 8 : SortTracks(fSeeds, 1);
8119 :
8120 : /*
8121 : fIteration = 1;
8122 : PrepareForBackProlongation(fSeeds,5.);
8123 : PropagateBack(fSeeds);
8124 : printf("Time for back propagation: \t");timer.Print();timer.Start();
8125 :
8126 : fIteration = 2;
8127 :
8128 : PrepareForProlongation(fSeeds,5.);
8129 : PropagateForard2(fSeeds);
8130 :
8131 : printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
8132 : // RemoveUsed(fSeeds,0.7,0.7,6);
8133 : //RemoveOverlap(fSeeds,0.9,7,kTRUE);
8134 :
8135 : nseed=fSeeds->GetEntriesFast();
8136 : found = 0;
8137 : for (Int_t i=0; i<nseed; i++) {
8138 : AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
8139 : if (!pt) continue;
8140 : Int_t nc=t.GetNumberOfClusters();
8141 : if (nc<15) {
8142 : MarkSeedFree( fSeeds->RemoveAt(i) );
8143 : continue;
8144 : }
8145 : t.CookdEdx(0.02,0.6);
8146 : // CookLabel(pt,0.1); //For comparison only
8147 : //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
8148 : if ((pt->IsActive() || (pt->fRemoval==10) )){
8149 : cerr<<found++<<'\r';
8150 : }
8151 : else
8152 : MarkSeedFree( fSeeds->RemoveAt(i) );
8153 : pt->fLab2 = i;
8154 : }
8155 : */
8156 :
8157 : // fNTracks = found;
8158 8 : if (fDebug>0){
8159 0 : Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
8160 : }
8161 : //
8162 : // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
8163 8 : Info("Clusters2Tracks","Number of found tracks %d",found);
8164 8 : savedir->cd();
8165 : // UnloadClusters();
8166 : //
8167 : return 0;
8168 8 : }
8169 :
8170 : void AliTPCtracker::Tracking(TObjArray * arr)
8171 : {
8172 : //
8173 : // tracking of the seeds
8174 : //
8175 1392 : fSectors = fOuterSec;
8176 696 : ParallelTracking(arr,150,63);
8177 696 : fSectors = fOuterSec;
8178 696 : ParallelTracking(arr,63,0);
8179 :
8180 696 : }
8181 :
8182 : TObjArray * AliTPCtracker::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
8183 : {
8184 : //
8185 : //
8186 : //tracking routine
8187 1398 : static TObjArray arrTracks;
8188 : TObjArray * arr = &arrTracks;
8189 : //
8190 : // AliInfoF(">> %d | s:%d i1:%d i2:%d dy:%f dsec:%d",arr->GetEntriesFast(),seedtype,i1,i2,dy,dsec); // RSTMP
8191 :
8192 :
8193 696 : fSectors = fOuterSec;
8194 696 : TStopwatch timer;
8195 696 : timer.Start();
8196 26448 : for (Int_t sec=0;sec<fkNOS;sec++){
8197 25056 : if (fAccountDistortions) {
8198 12528 : if (seedtype==3) MakeSeeds3Dist(arr,sec,i1,i2,cuts,dy, dsec);
8199 0 : if (seedtype==4) MakeSeeds5Dist(arr,sec,i1,i2,cuts,dy);
8200 0 : if (seedtype==2) MakeSeeds2Dist(arr,sec,i1,i2,cuts,dy); //RS
8201 : }
8202 : else {
8203 18720 : if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
8204 18864 : if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);
8205 12528 : if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy); //RS
8206 : }
8207 : //
8208 : }
8209 696 : if (fDebug>0){
8210 0 : Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
8211 0 : timer.Print();
8212 0 : timer.Start();
8213 : }
8214 696 : Tracking(arr);
8215 696 : if (fDebug>0){
8216 0 : timer.Print();
8217 : }
8218 : // AliInfoF("<< %d | s:%d i1:%d i2:%d dy:%f dsec:%d",arr->GetEntriesFast(),seedtype,i1,i2,dy,dsec); // RSTMP
8219 : return arr;
8220 696 : }
8221 :
8222 : TObjArray * AliTPCtracker::Tracking()
8223 : {
8224 : // tracking
8225 : //
8226 16 : if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
8227 8 : TStopwatch timer;
8228 8 : timer.Start();
8229 8 : Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8230 :
8231 8 : TObjArray * seeds = fSeeds;
8232 14 : if (!seeds) seeds = new TObjArray;
8233 6 : else seeds->Clear();
8234 8 : TObjArray * arr=0;
8235 16 : Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
8236 16 : Int_t gapPrim = AliTPCReconstructor::GetRecoParam()->GetSeedGapPrim();
8237 16 : Int_t gapSec = AliTPCReconstructor::GetRecoParam()->GetSeedGapSec();
8238 :
8239 : Int_t gap =20;
8240 8 : Float_t cuts[4];
8241 8 : cuts[0] = 0.002;
8242 8 : cuts[1] = 1.5;
8243 8 : cuts[2] = 3.;
8244 8 : cuts[3] = 3.;
8245 : Float_t fnumber = 3.0;
8246 : Float_t fdensity = 3.0;
8247 :
8248 : // make HLT seeds
8249 16 : if (AliTPCReconstructor::GetRecoParam()->GetUseHLTPreSeeding()) {
8250 0 : arr = MakeSeedsHLT( fEventHLT );
8251 0 : if( arr ){
8252 0 : SumTracks(seeds,arr);
8253 0 : delete arr;
8254 0 : arr=0;
8255 : //cout<<"HLT tracks left after sorting: "<<seeds->GetEntriesFast()<<endl;
8256 : //SignClusters(seeds,fnumber,fdensity);
8257 0 : }
8258 : }
8259 :
8260 : //
8261 : //find primaries
8262 8 : cuts[0]=0.0066;
8263 64 : for (Int_t delta = 0; delta<18; delta+=gapPrim){
8264 : //
8265 24 : cuts[0]=0.0070;
8266 24 : cuts[1] = 1.5;
8267 48 : arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
8268 24 : SumTracks(seeds,arr);
8269 24 : SignClusters(seeds,fnumber,fdensity);
8270 : //
8271 144 : for (Int_t i=2;i<6;i+=2){
8272 : // seed high pt tracks
8273 48 : cuts[0]=0.0022;
8274 48 : cuts[1]=0.3;
8275 96 : arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
8276 48 : SumTracks(seeds,arr);
8277 48 : SignClusters(seeds,fnumber,fdensity);
8278 : }
8279 : }
8280 : fnumber = 4;
8281 : fdensity = 4.;
8282 : // RemoveUsed(seeds,0.9,0.9,1);
8283 : // UnsignClusters();
8284 : // SignClusters(seeds,fnumber,fdensity);
8285 :
8286 : //find primaries
8287 8 : cuts[0]=0.0077;
8288 288 : for (Int_t delta = 20; delta<120; delta+=gapPrim){
8289 : //
8290 : // seed high pt tracks
8291 136 : cuts[0]=0.0060;
8292 136 : cuts[1]=0.3;
8293 136 : cuts[2]=6.;
8294 272 : arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
8295 136 : SumTracks(seeds,arr);
8296 136 : SignClusters(seeds,fnumber,fdensity);
8297 :
8298 136 : cuts[0]=0.003;
8299 136 : cuts[1]=0.3;
8300 136 : cuts[2]=6.;
8301 272 : arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
8302 136 : SumTracks(seeds,arr);
8303 136 : SignClusters(seeds,fnumber,fdensity);
8304 : }
8305 :
8306 8 : cuts[0] = 0.01;
8307 8 : cuts[1] = 2.0;
8308 8 : cuts[2] = 3.;
8309 8 : cuts[3] = 2.0;
8310 : fnumber = 2.;
8311 : fdensity = 2.;
8312 :
8313 8 : if (fDebug>0){
8314 0 : Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
8315 0 : timer.Print();
8316 0 : timer.Start();
8317 : }
8318 : // RemoveUsed(seeds,0.75,0.75,1);
8319 : //UnsignClusters();
8320 : //SignClusters(seeds,fnumber,fdensity);
8321 :
8322 8 : if (fDisableSecondaries) return seeds;
8323 :
8324 : // find secondaries
8325 :
8326 8 : cuts[0] = 0.3;
8327 8 : cuts[1] = 1.5;
8328 8 : cuts[2] = 3.;
8329 8 : cuts[3] = 1.5;
8330 :
8331 16 : arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
8332 8 : SumTracks(seeds,arr);
8333 8 : SignClusters(seeds,fnumber,fdensity);
8334 : //
8335 16 : arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
8336 8 : SumTracks(seeds,arr);
8337 8 : SignClusters(seeds,fnumber,fdensity);
8338 : //
8339 16 : arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
8340 8 : SumTracks(seeds,arr);
8341 8 : SignClusters(seeds,fnumber,fdensity);
8342 : //
8343 16 : arr = Tracking(4,nup-5,nup-5-gap,cuts,-1);
8344 8 : SumTracks(seeds,arr);
8345 8 : SignClusters(seeds,fnumber,fdensity);
8346 : //
8347 16 : arr = Tracking(4,nup-7,nup-7-gap,cuts,-1);
8348 8 : SumTracks(seeds,arr);
8349 8 : SignClusters(seeds,fnumber,fdensity);
8350 : //
8351 : //
8352 16 : arr = Tracking(4,nup-9,nup-9-gap,cuts,-1);
8353 8 : SumTracks(seeds,arr);
8354 8 : SignClusters(seeds,fnumber,fdensity);
8355 : //
8356 :
8357 :
8358 80 : for (Int_t delta = 9; delta<30; delta+=gapSec){
8359 : //
8360 32 : cuts[0] = 0.3;
8361 32 : cuts[1] = 1.5;
8362 32 : cuts[2] = 3.;
8363 32 : cuts[3] = 1.5;
8364 64 : arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
8365 32 : SumTracks(seeds,arr);
8366 32 : SignClusters(seeds,fnumber,fdensity);
8367 : //
8368 64 : arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
8369 32 : SumTracks(seeds,arr);
8370 32 : SignClusters(seeds,fnumber,fdensity);
8371 : //
8372 : }
8373 : fnumber = 1;
8374 : fdensity = 1;
8375 : //
8376 : // change cuts
8377 : fnumber = 2.;
8378 : fdensity = 2.;
8379 8 : cuts[0]=0.0080;
8380 :
8381 :
8382 : // find secondaries
8383 256 : for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=gapSec){
8384 : //
8385 120 : cuts[0] = 0.3;
8386 120 : cuts[1] = 3.5;
8387 120 : cuts[2] = 3.;
8388 120 : cuts[3] = 3.5;
8389 240 : arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
8390 120 : SumTracks(seeds,arr);
8391 120 : SignClusters(seeds,fnumber,fdensity);
8392 : //
8393 240 : arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
8394 120 : SumTracks(seeds,arr);
8395 120 : SignClusters(seeds,fnumber,fdensity);
8396 : }
8397 :
8398 8 : if (fDebug>0){
8399 0 : Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
8400 0 : timer.Print();
8401 0 : timer.Start();
8402 : }
8403 :
8404 8 : return seeds;
8405 : //
8406 :
8407 16 : }
8408 :
8409 :
8410 : TObjArray * AliTPCtracker::TrackingSpecial()
8411 : {
8412 : //
8413 : // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
8414 : // no primary vertex seeding tried
8415 : //
8416 0 : TStopwatch timer;
8417 0 : timer.Start();
8418 0 : Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8419 :
8420 0 : TObjArray * seeds = fSeeds;
8421 0 : if (!seeds) seeds = new TObjArray;
8422 0 : else seeds->Clear();
8423 0 : TObjArray * arr=0;
8424 :
8425 : Int_t gap = 15;
8426 0 : Float_t cuts[4];
8427 : Float_t fnumber = 3.0;
8428 : Float_t fdensity = 3.0;
8429 :
8430 : // find secondaries
8431 0 : cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC(); // max curvature
8432 0 : cuts[1] = 3.5; // max tan(phi) angle for seeding
8433 0 : cuts[2] = 3.; // not used (cut on z primary vertex)
8434 0 : cuts[3] = 3.5; // max tan(theta) angle for seeding
8435 :
8436 0 : for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
8437 : //
8438 0 : arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
8439 0 : SumTracks(seeds,arr);
8440 0 : SignClusters(seeds,fnumber,fdensity);
8441 : }
8442 :
8443 0 : if (fDebug>0){
8444 0 : Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
8445 0 : timer.Print();
8446 0 : timer.Start();
8447 : }
8448 :
8449 : return seeds;
8450 : //
8451 :
8452 0 : }
8453 :
8454 :
8455 : void AliTPCtracker::SumTracks(TObjArray *arr1,TObjArray *&arr2)
8456 : {
8457 : //
8458 : //sum tracks to common container
8459 : //remove suspicious tracks
8460 : // RS: Attention: supplied tracks come in the static array, don't delete them
8461 1392 : Int_t nseed = arr2->GetEntriesFast();
8462 1988 : for (Int_t i=0;i<nseed;i++){
8463 298 : AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);
8464 298 : if (pt){
8465 : //
8466 : // remove tracks with too big curvature
8467 : //
8468 298 : if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
8469 0 : MarkSeedFree( arr2->RemoveAt(i) );
8470 0 : continue;
8471 : }
8472 : // REMOVE VERY SHORT TRACKS
8473 298 : if (pt->GetNumberOfClusters()<20){
8474 18 : MarkSeedFree( arr2->RemoveAt(i) );
8475 18 : continue;
8476 : }// patch 28 fev06
8477 : // NORMAL ACTIVE TRACK
8478 280 : if (pt->IsActive()){
8479 274 : arr1->AddLast(arr2->RemoveAt(i));
8480 274 : continue;
8481 : }
8482 : //remove not usable tracks
8483 6 : if (pt->GetRemoval()!=10){
8484 0 : MarkSeedFree( arr2->RemoveAt(i) );
8485 0 : continue;
8486 : }
8487 :
8488 : // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
8489 6 : if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
8490 6 : arr1->AddLast(arr2->RemoveAt(i));
8491 : else{
8492 0 : MarkSeedFree( arr2->RemoveAt(i) );
8493 : }
8494 : }
8495 6 : }
8496 : // delete arr2; arr2 = 0; // RS: this is static array, don't delete it
8497 696 : }
8498 :
8499 :
8500 :
8501 : void AliTPCtracker::ParallelTracking(TObjArray *const arr, Int_t rfirst, Int_t rlast)
8502 : {
8503 : //
8504 : // try to track in parralel
8505 :
8506 2784 : Int_t nseed=arr->GetEntriesFast();
8507 : //prepare seeds for tracking
8508 3976 : for (Int_t i=0; i<nseed; i++) {
8509 596 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
8510 596 : if (!pt) continue;
8511 612 : if (!t.IsActive()) continue;
8512 : // follow prolongation to the first layer
8513 1160 : if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fkParam->GetNRowLow()>rfirst+1) )
8514 0 : FollowProlongation(t, rfirst+1);
8515 580 : }
8516 :
8517 :
8518 : //
8519 214368 : for (Int_t nr=rfirst; nr>=rlast; nr--){
8520 105792 : if (nr<fInnerSec->GetNRows())
8521 43848 : fSectors = fInnerSec;
8522 : else
8523 61944 : fSectors = fOuterSec;
8524 : // make indexes with the cluster tracks for given
8525 :
8526 : // find nearest cluster
8527 302176 : for (Int_t i=0; i<nseed; i++) {
8528 45296 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
8529 45296 : if (!pt) continue;
8530 45594 : if (nr==80) pt->UpdateReference();
8531 46952 : if (!pt->IsActive()) continue;
8532 : // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
8533 43640 : if (pt->GetRelativeSector()>17) {
8534 0 : continue;
8535 : }
8536 43640 : UpdateClusters(t,nr);
8537 43640 : }
8538 : // prolonagate to the nearest cluster - if founded
8539 302176 : for (Int_t i=0; i<nseed; i++) {
8540 45296 : AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
8541 45296 : if (!pt) continue;
8542 46952 : if (!pt->IsActive()) continue;
8543 : // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
8544 43640 : if (pt->GetRelativeSector()>17) {
8545 0 : continue;
8546 : }
8547 43640 : FollowToNextCluster(*pt,nr);
8548 43640 : }
8549 : }
8550 1392 : }
8551 :
8552 : void AliTPCtracker::PrepareForBackProlongation(const TObjArray *const arr,Float_t fac) const
8553 : {
8554 : //
8555 : //
8556 : // if we use TPC track itself we have to "update" covariance
8557 : //
8558 0 : Int_t nseed= arr->GetEntriesFast();
8559 0 : for (Int_t i=0;i<nseed;i++){
8560 0 : AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
8561 0 : if (pt) {
8562 0 : pt->Modify(fac);
8563 : //
8564 : //rotate to current local system at first accepted point
8565 0 : Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
8566 0 : Int_t sec = (index&0xff000000)>>24;
8567 0 : sec = sec%18;
8568 0 : Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
8569 0 : if (angle1>TMath::Pi())
8570 0 : angle1-=2.*TMath::Pi();
8571 0 : Float_t angle2 = pt->GetAlpha();
8572 :
8573 0 : if (TMath::Abs(angle1-angle2)>0.001){
8574 0 : if (!pt->Rotate(angle1-angle2)) return;
8575 : //angle2 = pt->GetAlpha();
8576 : //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
8577 : //if (pt->GetAlpha()<0)
8578 : // pt->fRelativeSector+=18;
8579 : //sec = pt->fRelativeSector;
8580 : }
8581 :
8582 0 : }
8583 :
8584 0 : }
8585 :
8586 :
8587 0 : }
8588 : void AliTPCtracker::PrepareForProlongation(TObjArray *const arr, Float_t fac) const
8589 : {
8590 : //
8591 : //
8592 : // if we use TPC track itself we have to "update" covariance
8593 : //
8594 0 : Int_t nseed= arr->GetEntriesFast();
8595 0 : for (Int_t i=0;i<nseed;i++){
8596 0 : AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
8597 0 : if (pt) {
8598 0 : pt->Modify(fac);
8599 0 : pt->SetFirstPoint(pt->GetLastPoint());
8600 0 : }
8601 :
8602 : }
8603 :
8604 :
8605 0 : }
8606 :
8607 : Int_t AliTPCtracker::PropagateBack(const TObjArray *const arr)
8608 : {
8609 : //
8610 : // make back propagation
8611 : //
8612 16 : Int_t nseed= arr->GetEntriesFast();
8613 288 : for (Int_t i=0;i<nseed;i++){
8614 136 : AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
8615 272 : if (pt&& pt->GetKinkIndex(0)<=0) {
8616 : //AliTPCseed *pt2 = new AliTPCseed(*pt);
8617 132 : fSectors = fInnerSec;
8618 : //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
8619 : //fSectors = fOuterSec;
8620 132 : FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
8621 : //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
8622 : // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
8623 : // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
8624 : //}
8625 132 : }
8626 272 : if (pt&& pt->GetKinkIndex(0)>0) {
8627 4 : AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
8628 4 : pt->SetFirstPoint(kink->GetTPCRow0());
8629 4 : fSectors = fInnerSec;
8630 4 : FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
8631 4 : }
8632 136 : CookLabel(pt,0.3);
8633 : }
8634 8 : return 0;
8635 : }
8636 :
8637 :
8638 : Int_t AliTPCtracker::PropagateForward2(const TObjArray *const arr)
8639 : {
8640 : //
8641 : // make forward propagation
8642 : //
8643 16 : Int_t nseed= arr->GetEntriesFast();
8644 : //
8645 288 : for (Int_t i=0;i<nseed;i++){
8646 136 : AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
8647 136 : if (pt) {
8648 136 : FollowProlongation(*pt,0,1,1);
8649 136 : CookLabel(pt,0.3);
8650 136 : }
8651 :
8652 : }
8653 8 : return 0;
8654 : }
8655 :
8656 :
8657 : Int_t AliTPCtracker::PropagateForward()
8658 : {
8659 : //
8660 : // propagate track forward
8661 : //UnsignClusters();
8662 0 : Int_t nseed = fSeeds->GetEntriesFast();
8663 0 : for (Int_t i=0;i<nseed;i++){
8664 0 : AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
8665 0 : if (pt){
8666 : AliTPCseed &t = *pt;
8667 0 : Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
8668 0 : if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
8669 0 : if (alpha < 0. ) alpha += 2.*TMath::Pi();
8670 0 : t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
8671 0 : }
8672 : }
8673 :
8674 0 : fSectors = fOuterSec;
8675 0 : ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
8676 0 : fSectors = fInnerSec;
8677 0 : ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
8678 0 : return 1;
8679 : }
8680 :
8681 :
8682 :
8683 :
8684 :
8685 :
8686 : Int_t AliTPCtracker::PropagateBack(AliTPCseed *const pt, Int_t row0, Int_t row1)
8687 : {
8688 : //
8689 : // make back propagation, in between row0 and row1
8690 : //
8691 :
8692 0 : if (pt) {
8693 0 : fSectors = fInnerSec;
8694 : Int_t r1;
8695 : //
8696 0 : if (row1<fSectors->GetNRows())
8697 0 : r1 = row1;
8698 : else
8699 0 : r1 = fSectors->GetNRows()-1;
8700 :
8701 0 : if (row0<fSectors->GetNRows()&& r1>0 )
8702 0 : FollowBackProlongation(*pt,r1);
8703 0 : if (row1<=fSectors->GetNRows())
8704 0 : return 0;
8705 : //
8706 0 : r1 = row1 - fSectors->GetNRows();
8707 0 : if (r1<=0) return 0;
8708 0 : if (r1>=fOuterSec->GetNRows()) return 0;
8709 0 : fSectors = fOuterSec;
8710 0 : return FollowBackProlongation(*pt,r1);
8711 : }
8712 0 : return 0;
8713 0 : }
8714 :
8715 :
8716 :
8717 :
8718 : void AliTPCtracker::GetShape(AliTPCseed * seed, Int_t row)
8719 : {
8720 : // gets cluster shape
8721 : //
8722 210964 : AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
8723 105482 : Float_t zdrift = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())));
8724 274784 : Int_t type = (seed->GetSector() < fkParam->GetNSector()/2) ? 0: (row>126) ? 1:2;
8725 105482 : Double_t angulary = seed->GetSnp();
8726 :
8727 105482 : if (TMath::Abs(angulary)>AliTPCReconstructor::GetMaxSnpTracker()) {
8728 2812 : angulary = TMath::Sign(AliTPCReconstructor::GetMaxSnpTracker(),angulary);
8729 2812 : }
8730 :
8731 105482 : angulary = angulary*angulary/((1.-angulary)*(1.+angulary));
8732 105482 : Double_t angularz = seed->GetTgl()*seed->GetTgl()*(1.+angulary);
8733 :
8734 105482 : Double_t sigmay = clparam->GetRMS0(0,type,zdrift,TMath::Sqrt(TMath::Abs(angulary)));
8735 105482 : Double_t sigmaz = clparam->GetRMS0(1,type,zdrift,TMath::Sqrt(TMath::Abs(angularz)));
8736 105482 : seed->SetCurrentSigmaY2(sigmay*sigmay);
8737 105482 : seed->SetCurrentSigmaZ2(sigmaz*sigmaz);
8738 : // Float_t sd2 = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fkParam->GetDiffL()*fkParam->GetDiffL();
8739 : // // Float_t padlength = fkParam->GetPadPitchLength(seed->fSector);
8740 : // Float_t padlength = GetPadPitchLength(row);
8741 : // //
8742 : // Float_t sresy = (seed->GetSector() < fkParam->GetNSector()/2) ? 0.2 :0.3;
8743 : // seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
8744 : // //
8745 : // Float_t sresz = fkParam->GetZSigma();
8746 : // seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
8747 : /*
8748 : Float_t wy = GetSigmaY(seed);
8749 : Float_t wz = GetSigmaZ(seed);
8750 : wy*=wy;
8751 : wz*=wz;
8752 : if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
8753 : printf("problem\n");
8754 : }
8755 : */
8756 105482 : }
8757 :
8758 :
8759 :
8760 : //__________________________________________________________________________
8761 : void AliTPCtracker::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
8762 : //--------------------------------------------------------------------
8763 : //This function "cooks" a track label. If label<0, this track is fake.
8764 : //--------------------------------------------------------------------
8765 : // AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
8766 : // if(!t){
8767 : // printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
8768 : // return;
8769 : // }
8770 1916 : AliTPCseed * t = (AliTPCseed*)tk; // RS avoid slow dynamic cast
8771 :
8772 958 : Int_t noc=t->GetNumberOfClusters();
8773 958 : if (noc<10){
8774 : //printf("\nnot founded prolongation\n\n\n");
8775 : //t->Dump();
8776 2 : return ;
8777 : }
8778 956 : Int_t lb[kMaxRow];
8779 956 : Int_t mx[kMaxRow];
8780 956 : AliTPCclusterMI *clusters[kMaxRow];
8781 : //
8782 305920 : for (Int_t i=0;i<kMaxRow;i++) {
8783 152004 : clusters[i]=0;
8784 152004 : lb[i]=mx[i]=0;
8785 : }
8786 :
8787 : Int_t i;
8788 : Int_t current=0;
8789 439790 : for (i=0; i<kMaxRow && current<noc; i++) {
8790 :
8791 145912 : Int_t index=t->GetClusterIndex2(i);
8792 174182 : if (index<=0) continue;
8793 121040 : if (index&0x8000) continue;
8794 : //
8795 114244 : clusters[current++]=GetClusterMI(index);
8796 : // if (t->GetClusterPointer(i)){
8797 : // clusters[current]=t->GetClusterPointer(i);
8798 : // current++;
8799 : // }
8800 114244 : }
8801 : noc = current;
8802 :
8803 : Int_t lab=123456789;
8804 230400 : for (i=0; i<noc; i++) {
8805 114244 : AliTPCclusterMI *c=clusters[i];
8806 114244 : if (!c) continue;
8807 114244 : lab=TMath::Abs(c->GetLabel(0));
8808 : Int_t j;
8809 401895 : for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
8810 114244 : lb[j]=lab;
8811 114244 : (mx[j])++;
8812 114244 : }
8813 :
8814 : Int_t max=0;
8815 345662 : for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
8816 :
8817 230400 : for (i=0; i<noc; i++) {
8818 114244 : AliTPCclusterMI *c=clusters[i];
8819 114244 : if (!c) continue;
8820 167618 : if (TMath::Abs(c->GetLabel(1)) == lab ||
8821 114287 : TMath::Abs(c->GetLabel(2)) == lab ) max++;
8822 114244 : }
8823 956 : if (noc<=0) { lab=-1; return;}
8824 967 : if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
8825 :
8826 : else {
8827 945 : Int_t tail=Int_t(0.10*noc);
8828 : max=0;
8829 : Int_t ind=0;
8830 35499 : for (i=1; i<kMaxRow&&ind<tail; i++) {
8831 : // AliTPCclusterMI *c=clusters[noc-i];
8832 10888 : AliTPCclusterMI *c=clusters[i];
8833 10888 : if (!c) continue;
8834 11218 : if (lab == TMath::Abs(c->GetLabel(0)) ||
8835 566 : lab == TMath::Abs(c->GetLabel(1)) ||
8836 10888 : lab == TMath::Abs(c->GetLabel(2))) max++;
8837 10888 : ind++;
8838 10888 : }
8839 955 : if (max < Int_t(0.5*tail)) lab=-lab;
8840 : }
8841 :
8842 956 : t->SetLabel(lab);
8843 :
8844 : // delete[] lb;
8845 : //delete[] mx;
8846 : //delete[] clusters;
8847 2870 : }
8848 :
8849 :
8850 : //__________________________________________________________________________
8851 : Int_t AliTPCtracker::CookLabel(AliTPCseed *const t, Float_t wrong,Int_t first, Int_t last) const {
8852 : //--------------------------------------------------------------------
8853 : //This function "cooks" a track label. If label<0, this track is fake.
8854 : //--------------------------------------------------------------------
8855 64 : Int_t noc=t->GetNumberOfClusters();
8856 32 : if (noc<10){
8857 : //printf("\nnot founded prolongation\n\n\n");
8858 : //t->Dump();
8859 0 : return -1;
8860 : }
8861 32 : Int_t lb[kMaxRow];
8862 32 : Int_t mx[kMaxRow];
8863 32 : AliTPCclusterMI *clusters[kMaxRow];
8864 : //
8865 10240 : for (Int_t i=0;i<kMaxRow;i++) {
8866 5088 : clusters[i]=0;
8867 5088 : lb[i]=mx[i]=0;
8868 : }
8869 :
8870 : Int_t i;
8871 : Int_t current=0;
8872 15236 : for (i=0; i<kMaxRow && current<noc; i++) {
8873 5054 : if (i<first) continue;
8874 3740 : if (i>last) continue;
8875 2544 : Int_t index=t->GetClusterIndex2(i);
8876 3122 : if (index<=0) continue;
8877 2110 : if (index&0x8000) continue;
8878 : //
8879 1822 : clusters[current++]=GetClusterMI(index);
8880 : // if (t->GetClusterPointer(i)){
8881 : // clusters[current]=t->GetClusterPointer(i);
8882 : // current++;
8883 : // }
8884 1822 : }
8885 : noc = current;
8886 : //if (noc<5) return -1;
8887 : Int_t lab=123456789;
8888 3708 : for (i=0; i<noc; i++) {
8889 1822 : AliTPCclusterMI *c=clusters[i];
8890 1822 : if (!c) continue;
8891 1822 : lab=TMath::Abs(c->GetLabel(0));
8892 : Int_t j;
8893 6387 : for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
8894 1822 : lb[j]=lab;
8895 1822 : (mx[j])++;
8896 1822 : }
8897 :
8898 : Int_t max=0;
8899 5565 : for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
8900 :
8901 3708 : for (i=0; i<noc; i++) {
8902 1822 : AliTPCclusterMI *c=clusters[i];
8903 1822 : if (!c) continue;
8904 2688 : if (TMath::Abs(c->GetLabel(1)) == lab ||
8905 1822 : TMath::Abs(c->GetLabel(2)) == lab ) max++;
8906 1822 : }
8907 32 : if (noc<=0) { lab=-1; return -1;}
8908 32 : if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
8909 :
8910 : else {
8911 32 : Int_t tail=Int_t(0.10*noc);
8912 : max=0;
8913 : Int_t ind=0;
8914 600 : for (i=1; i<kMaxRow&&ind<tail; i++) {
8915 : // AliTPCclusterMI *c=clusters[noc-i];
8916 168 : AliTPCclusterMI *c=clusters[i];
8917 168 : if (!c) continue;
8918 178 : if (lab == TMath::Abs(c->GetLabel(0)) ||
8919 15 : lab == TMath::Abs(c->GetLabel(1)) ||
8920 168 : lab == TMath::Abs(c->GetLabel(2))) max++;
8921 168 : ind++;
8922 168 : }
8923 33 : if (max < Int_t(0.5*tail)) lab=-lab;
8924 : }
8925 :
8926 : // t->SetLabel(lab);
8927 32 : return lab;
8928 : // delete[] lb;
8929 : //delete[] mx;
8930 : //delete[] clusters;
8931 64 : }
8932 :
8933 :
8934 : Int_t AliTPCtracker::GetRowNumber(Double_t x[3]) const
8935 : {
8936 : //return pad row number for given x vector
8937 0 : Float_t phi = TMath::ATan2(x[1],x[0]);
8938 0 : if(phi<0) phi=2.*TMath::Pi()+phi;
8939 : // Get the local angle in the sector philoc
8940 : const Float_t kRaddeg = 180/3.14159265358979312;
8941 0 : Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
8942 0 : Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
8943 0 : return GetRowNumber(localx);
8944 : }
8945 :
8946 :
8947 :
8948 : void AliTPCtracker::MakeESDBitmaps(AliTPCseed *t, AliESDtrack *esd)
8949 : {
8950 : //-----------------------------------------------------------------------
8951 : // Fill the cluster and sharing bitmaps of the track
8952 : //-----------------------------------------------------------------------
8953 :
8954 : Int_t firstpoint = 0;
8955 : Int_t lastpoint = kMaxRow;
8956 : // AliTPCclusterMI *cluster;
8957 :
8958 : Int_t nclsf = 0;
8959 544 : TBits clusterMap(kMaxRow);
8960 272 : TBits sharedMap(kMaxRow);
8961 272 : TBits fitMap(kMaxRow);
8962 87040 : for (int iter=firstpoint; iter<lastpoint; iter++) {
8963 : // Change to cluster pointers to see if we have a cluster at given padrow
8964 43248 : Int_t tpcindex= t->GetClusterIndex2(iter);
8965 43248 : if (tpcindex>=0) {
8966 33420 : clusterMap.SetBitNumber(iter, kTRUE);
8967 67416 : if (t->IsShared(iter)) sharedMap.SetBitNumber(iter,kTRUE); // RS shared flag moved to seed
8968 : //
8969 33420 : if ( (tpcindex&0x8000) == 0) {
8970 32534 : fitMap.SetBitNumber(iter, kTRUE);
8971 32534 : nclsf++;
8972 32534 : }
8973 : }
8974 : // if (t->GetClusterIndex(iter) >= 0 && (t->GetClusterIndex(iter) & 0x8000) == 0) {
8975 : // fitMap.SetBitNumber(iter, kTRUE);
8976 : // nclsf++;
8977 : // }
8978 : }
8979 272 : esd->SetTPCClusterMap(clusterMap);
8980 272 : esd->SetTPCSharedMap(sharedMap);
8981 272 : esd->SetTPCFitMap(fitMap);
8982 544 : if (nclsf != t->GetNumberOfClusters())
8983 670 : AliDebug(3,Form("Inconsistency between ncls %d and indices %d (found %d)",t->GetNumberOfClusters(),nclsf,esd->GetTPCClusterMap().CountBits()));
8984 272 : }
8985 :
8986 : Bool_t AliTPCtracker::IsFindable(AliTPCseed & track){
8987 : //
8988 : // return flag if there is findable cluster at given position
8989 : //
8990 : Float_t kDeltaZ=10;
8991 161444 : Float_t z = track.GetZ();
8992 :
8993 161432 : if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*track.GetX()+kDeltaZ) &&
8994 80722 : TMath::Abs(z)<fkParam->GetZLength(0) &&
8995 80710 : (TMath::Abs(track.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
8996 80640 : return kTRUE;
8997 82 : return kFALSE;
8998 80722 : }
8999 :
9000 :
9001 : void AliTPCtracker::AddCovariance(AliTPCseed * seed){
9002 : //
9003 : // Adding systematic error estimate to the covariance matrix
9004 : // !!!! the systematic error for element 4 is in 1/GeV
9005 : // 03.03.2012 MI changed in respect to the previous versions
9006 : // in case systemtic errors defiend statically no correlation added (needed for CPass0)
9007 2712 : const Double_t *param = (AliTPCReconstructor::GetSystematicError()!=NULL) ? AliTPCReconstructor::GetSystematicError():AliTPCReconstructor::GetRecoParam()->GetSystematicError();
9008 : //
9009 : // use only the diagonal part if not specified otherwise
9010 1356 : if (!AliTPCReconstructor::GetRecoParam()->GetUseSystematicCorrelation() || AliTPCReconstructor::GetSystematicError()) return AddCovarianceAdd(seed);
9011 : //
9012 678 : Double_t *covarS= (Double_t*)seed->GetCovariance();
9013 678 : Double_t factor[5]={1,1,1,1,1};
9014 678 : factor[0]= TMath::Sqrt(TMath::Abs((covarS[0] + param[0]*param[0])/covarS[0]));
9015 678 : factor[1]= TMath::Sqrt(TMath::Abs((covarS[2] + param[1]*param[1])/covarS[2]));
9016 678 : factor[2]= TMath::Sqrt(TMath::Abs((covarS[5] + param[2]*param[2])/covarS[5]));
9017 678 : factor[3]= TMath::Sqrt(TMath::Abs((covarS[9] + param[3]*param[3])/covarS[9]));
9018 678 : factor[4]= TMath::Sqrt(TMath::Abs((covarS[14] +param[4]*param[4])/covarS[14]));
9019 : //
9020 678 : factor[0]=factor[2];
9021 678 : factor[4]=factor[2];
9022 : // 0
9023 : // 1 2
9024 : // 3 4 5
9025 : // 6 7 8 9
9026 : // 10 11 12 13 14
9027 8136 : for (Int_t i=0; i<5; i++){
9028 27120 : for (Int_t j=i; j<5; j++){
9029 10170 : Int_t index=seed->GetIndex(i,j);
9030 10170 : covarS[index]*=factor[i]*factor[j];
9031 : }
9032 : }
9033 1356 : }
9034 :
9035 :
9036 : void AliTPCtracker::AddCovarianceAdd(AliTPCseed * seed){
9037 : //
9038 : // Adding systematic error - as additive factor without correlation
9039 : //
9040 : // !!!! the systematic error for element 4 is in 1/GeV
9041 : // 03.03.2012 MI changed in respect to the previous versions
9042 :
9043 0 : const Double_t *param = (AliTPCReconstructor::GetSystematicError()!=NULL) ? AliTPCReconstructor::GetSystematicError():AliTPCReconstructor::GetRecoParam()->GetSystematicError();
9044 0 : Double_t *covarIn= (Double_t*)seed->GetCovariance();
9045 0 : Double_t covar[15];
9046 0 : for (Int_t i=0;i<15;i++) covar[i]=0;
9047 : // 0
9048 : // 1 2
9049 : // 3 4 5
9050 : // 6 7 8 9
9051 : // 10 11 12 13 14
9052 0 : covar[0] = param[0]*param[0];
9053 0 : covar[2] = param[1]*param[1];
9054 0 : covar[5] = param[2]*param[2];
9055 0 : covar[9] = param[3]*param[3];
9056 0 : covar[14]= param[4]*param[4];
9057 : //
9058 0 : covar[1]=TMath::Sqrt((covar[0]*covar[2]))*covarIn[1]/TMath::Sqrt((covarIn[0]*covarIn[2]));
9059 : //
9060 0 : covar[3]=TMath::Sqrt((covar[0]*covar[5]))*covarIn[3]/TMath::Sqrt((covarIn[0]*covarIn[5]));
9061 0 : covar[4]=TMath::Sqrt((covar[2]*covar[5]))*covarIn[4]/TMath::Sqrt((covarIn[2]*covarIn[5]));
9062 : //
9063 0 : covar[6]=TMath::Sqrt((covar[0]*covar[9]))*covarIn[6]/TMath::Sqrt((covarIn[0]*covarIn[9]));
9064 0 : covar[7]=TMath::Sqrt((covar[2]*covar[9]))*covarIn[7]/TMath::Sqrt((covarIn[2]*covarIn[9]));
9065 0 : covar[8]=TMath::Sqrt((covar[5]*covar[9]))*covarIn[8]/TMath::Sqrt((covarIn[5]*covarIn[9]));
9066 : //
9067 0 : covar[10]=TMath::Sqrt((covar[0]*covar[14]))*covarIn[10]/TMath::Sqrt((covarIn[0]*covarIn[14]));
9068 0 : covar[11]=TMath::Sqrt((covar[2]*covar[14]))*covarIn[11]/TMath::Sqrt((covarIn[2]*covarIn[14]));
9069 0 : covar[12]=TMath::Sqrt((covar[5]*covar[14]))*covarIn[12]/TMath::Sqrt((covarIn[5]*covarIn[14]));
9070 0 : covar[13]=TMath::Sqrt((covar[9]*covar[14]))*covarIn[13]/TMath::Sqrt((covarIn[9]*covarIn[14]));
9071 : //
9072 0 : seed->AddCovariance(covar);
9073 0 : }
9074 :
9075 : //_____________________________________________________________________________
9076 : Bool_t AliTPCtracker::IsTPCHVDipEvent(AliESDEvent const *esdEvent)
9077 : {
9078 : //
9079 : // check events affected by TPC HV dip
9080 : //
9081 16 : if(!esdEvent) return kFALSE;
9082 :
9083 : // Init TPC OCDB
9084 8 : AliTPCcalibDB *db=AliTPCcalibDB::Instance();
9085 8 : if(!db) return kFALSE;
9086 8 : db->SetRun(esdEvent->GetRunNumber());
9087 :
9088 : // maximum allowed voltage before an event is identified as a dip event
9089 : // and scanning period
9090 8 : const Double_t kTPCHVdip = db->GetParameters()->GetMaxDipVoltage();
9091 8 : const Double_t dipEventScanPeriod = db->GetParameters()->GetVoltageDipScanPeriod();
9092 8 : const Double_t tevSec = esdEvent->GetTimeStamp();
9093 :
9094 1176 : for(Int_t sector=0; sector<72; sector++)
9095 : {
9096 : // don't use excluded chambers, since the state is not defined at all
9097 576 : if (!db->GetChamberHVStatus(sector)) continue;
9098 :
9099 : // get hv sensor of the chamber
9100 576 : AliDCSSensor *sensor = db->GetChamberHVSensor(sector);
9101 1152 : if (!sensor) continue;
9102 0 : TGraph *grSensor=sensor->GetGraph();
9103 0 : if (!grSensor) continue;
9104 0 : if (grSensor->GetN()<1) continue;
9105 :
9106 : // get median
9107 0 : const Double_t median = db->GetChamberHighVoltageMedian(sector);
9108 0 : if(median < 1.) continue;
9109 :
9110 0 : for (Int_t ipoint=0; ipoint<grSensor->GetN()-1; ++ipoint){
9111 0 : Double_t nextTime=grSensor->GetX()[ipoint+1]*3600+sensor->GetStartTime();
9112 0 : if (tevSec-dipEventScanPeriod>nextTime) continue;
9113 0 : const Float_t deltaV=TMath::Abs(grSensor->GetY()[ipoint]-median);
9114 0 : if (deltaV>kTPCHVdip) {
9115 0 : AliDebug(3,Form("HV dip detected in ROC '%02d' with dV '%.2f' at time stamp '%.0f'",sector,deltaV,tevSec));
9116 0 : return kTRUE;
9117 : }
9118 0 : if (nextTime>tevSec+dipEventScanPeriod) break;
9119 0 : }
9120 0 : }
9121 :
9122 8 : return kFALSE;
9123 8 : }
9124 :
9125 : //________________________________________
9126 : void AliTPCtracker::MarkSeedFree(TObject *sd)
9127 : {
9128 : // account that this seed is "deleted"
9129 : // AliTPCseed* seed = dynamic_cast<AliTPCseed*>(sd);
9130 : // if (!seed) {
9131 : // AliError(Form("Freeing of non-AliTPCseed %p from the pool is requested",sd));
9132 : // return;
9133 : // }
9134 26940 : AliTPCseed* seed = (AliTPCseed*)sd;
9135 13470 : int id = seed->GetPoolID();
9136 13470 : if (id<0) {
9137 0 : AliError(Form("Freeing of seed %p NOT from the pool is requested",sd));
9138 0 : return;
9139 : }
9140 : // AliInfo(Form("%d %p",id, seed));
9141 13470 : fSeedsPool->RemoveAt(id);
9142 13470 : if (fFreeSeedsID.GetSize()<=fNFreeSeeds) fFreeSeedsID.Set( 2*fNFreeSeeds + 100 );
9143 13470 : fFreeSeedsID.GetArray()[fNFreeSeeds++] = id;
9144 26940 : }
9145 :
9146 : //________________________________________
9147 : TObject *&AliTPCtracker::NextFreeSeed()
9148 : {
9149 : // return next free slot where the seed can be created
9150 55504 : fLastSeedID = fNFreeSeeds ? fFreeSeedsID.GetArray()[--fNFreeSeeds] : fSeedsPool->GetEntriesFast();
9151 : // AliInfo(Form("%d",fLastSeedID));
9152 13876 : return (*fSeedsPool)[ fLastSeedID ];
9153 : //
9154 : }
9155 :
9156 : //________________________________________
9157 : void AliTPCtracker::ResetSeedsPool()
9158 : {
9159 : // mark all seeds in the pool as unused
9160 48 : AliInfo(Form("CurrentSize: %d, BookedUpTo: %d, free: %d",fSeedsPool->GetSize(),fSeedsPool->GetEntriesFast(),fNFreeSeeds));
9161 24 : fNFreeSeeds = 0;
9162 24 : fSeedsPool->Clear(); // RS: nominally the seeds may allocate memory...
9163 :
9164 24 : }
9165 :
9166 : Int_t AliTPCtracker::PropagateToRowHLT(AliTPCseed *pt, int nrow)
9167 : {
9168 : AliTPCseed &t=*pt;
9169 0 : Double_t x= GetXrow(nrow);
9170 0 : Double_t ymax= GetMaxY(nrow);
9171 : Int_t rotate = 0;
9172 : Int_t nRotations=0;
9173 : int ret = 1;
9174 0 : do{
9175 : rotate = 0;
9176 0 : if (!t.PropagateTo(x) ){
9177 : //cout<<"can't propagate to row "<<nrow<<", x="<<t.GetX()<<" -> "<<x<<endl;
9178 : //t.Print();
9179 : ret = 0;
9180 0 : break;
9181 : }
9182 0 : t.SetRow(nrow);
9183 0 : Double_t y = t.GetY();
9184 : double yEdgeDist = y;
9185 0 : if (fAccountDistortions) yEdgeDist -= GetYSectEdgeDist(t.GetRelativeSector(),nrow,y,t.GetZ());
9186 0 : if( y>0 && yEdgeDist>ymax) {
9187 0 : if( rotate!=-1 ) rotate=1;
9188 0 : } else if (y<0 && yEdgeDist<-ymax) {
9189 0 : if( rotate!=1 ) rotate = -1;
9190 : }
9191 0 : if( rotate==0 ) break;
9192 : //cout<<"rotate at row "<<nrow<<": "<<rotate<<endl;
9193 0 : if (!t.Rotate( rotate==1 ?fSectors->GetAlpha() :-fSectors->GetAlpha())) {
9194 : //cout<<"can't rotate "<<endl;
9195 : ret=0;
9196 0 : break;
9197 : }
9198 0 : nRotations+= rotate;
9199 0 : }while(rotate!=0);
9200 0 : if( nRotations!=0 ){
9201 0 : int newSec= t.GetRelativeSector()+nRotations;
9202 0 : if( newSec>=fN ) newSec-=fN;
9203 0 : else if( newSec<0 ) newSec +=fN;
9204 : //cout<<"rotate at row "<<nrow<<": "<<nRotations<<" times "<<" sec "
9205 : //<< t.GetRelativeSector()<<" -> "<<newSec<<endl;
9206 0 : t.SetRelativeSector(newSec);
9207 0 : }
9208 0 : return ret;
9209 : }
9210 :
9211 : void AliTPCtracker::TrackFollowingHLT(TObjArray *const arr )
9212 : {
9213 : //
9214 : // try to track in parralel
9215 :
9216 0 : AliFatal("RS: This method is not yet aware of cluster pointers no present in the in-memory tracks");
9217 :
9218 0 : Int_t nRows=fOuterSec->GetNRows()+fInnerSec->GetNRows();
9219 0 : fSectors=fInnerSec;
9220 :
9221 0 : Int_t nseed=arr->GetEntriesFast();
9222 : //cout<<"Parallel tracking My.."<<endl;
9223 0 : double shapeY2[kMaxRow], shapeZ2[kMaxRow];
9224 0 : Int_t clusterIndex[kMaxRow];
9225 :
9226 0 : for (Int_t iSeed=0; iSeed<nseed; iSeed++) {
9227 : //if( iSeed!=1 ) continue;
9228 0 : AliTPCseed *pt=(AliTPCseed*) (arr->UncheckedAt(iSeed));
9229 0 : if (!pt) continue;
9230 : AliTPCseed &t=*pt;
9231 :
9232 : //cout <<"Pt "<<t.GetSigned1Pt()<<endl;
9233 :
9234 : // t.Print();
9235 :
9236 0 : for( int iter=0; iter<3; iter++ ){
9237 :
9238 0 : t.Reset();
9239 0 : t.SetLastPoint(0); // first cluster in track position
9240 0 : t.SetFirstPoint(nRows-1);
9241 0 : t.ResetCovariance(.1);
9242 0 : t.SetNumberOfClusters(0);
9243 0 : for( int i=0; i<nRows; i++ ){
9244 0 : shapeY2[i]=1.;
9245 0 : shapeZ2[i]=1.;
9246 0 : clusterIndex[i]=-1;
9247 0 : t.SetClusterIndex2(i,-1);
9248 0 : t.SetClusterIndex(i,-1);
9249 : }
9250 :
9251 : // pick up the clusters
9252 :
9253 : Double_t roady = 20.;
9254 : Double_t roadz = 20.;
9255 : double roadr = 5;
9256 :
9257 0 : AliTPCseed t0(t);
9258 0 : t0.Reset();
9259 : int nClusters = 0;
9260 : {
9261 0 : t0.SetRelativeSector(t.GetRelativeSector());
9262 0 : t0.SetLastPoint(0); // first cluster in track position
9263 0 : t0.SetFirstPoint(kMaxRow);
9264 0 : for (Int_t nr=0; nr<nRows; nr++){
9265 0 : if( nr<fInnerSec->GetNRows() ) fSectors=fInnerSec;
9266 0 : else fSectors=fOuterSec;
9267 :
9268 0 : if( !PropagateToRowHLT(&t0, nr ) ){ break; }
9269 0 : if (TMath::Abs(t0.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
9270 : //cout<<"Snp is too big: "<<t0.GetSnp()<<endl;
9271 : continue;
9272 : }
9273 0 : if (!IsActive(t0.GetRelativeSector(),nr)) {
9274 : continue;
9275 : }
9276 :
9277 0 : if( iter==0 ){
9278 0 : GetShape(&t0,nr);
9279 0 : shapeY2[nr]=t0.GetCurrentSigmaY2();
9280 0 : shapeZ2[nr]=t0.GetCurrentSigmaZ2();
9281 0 : }
9282 :
9283 0 : AliTPCtrackerRow &krow=GetRow(t0.GetRelativeSector(),nr);
9284 0 : if( !krow ) continue;
9285 :
9286 0 : t.SetClusterIndex2(nr,-3); // foundable
9287 0 : t.SetClusterIndex(nr,-3);
9288 :
9289 : AliTPCclusterMI *cl=0;
9290 0 : UInt_t uindex = 0;
9291 0 : cl = krow.FindNearest2(t0.GetY(),t0.GetZ(),roady+fClExtraRoadY,roadz+fClExtraRoadZ,uindex);
9292 0 : if (!cl ) continue;
9293 0 : double dy = cl->GetY()-t0.GetY();
9294 0 : double dz = cl->GetZ()-t0.GetZ();
9295 0 : double dr = sqrt(dy*dy+dz*dz);
9296 0 : if( dr>roadr ){
9297 : //cout<<"row "<<nr<<", best cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
9298 0 : continue;
9299 : }
9300 : //cout<<"row "<<nr<<", found cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
9301 :
9302 0 : t0.SetClusterPointer(nr, cl);
9303 0 : clusterIndex[nr] = krow.GetIndex(uindex);
9304 0 : if( t0.GetFirstPoint()>nr ) t0.SetFirstPoint(nr);
9305 0 : t0.SetLastPoint(nr);
9306 0 : nClusters++;
9307 0 : }
9308 : }
9309 :
9310 0 : if( nClusters <3 ){
9311 : //cout<<"NOT ENOUGTH CLUSTERS: "<<nClusters<<endl;
9312 0 : break;
9313 : }
9314 0 : Int_t basePoints[3] = {t0.GetFirstPoint(),t0.GetFirstPoint(),t0.GetLastPoint()};
9315 :
9316 : // find midpoint
9317 : {
9318 0 : Int_t midRow = (t0.GetLastPoint()-t0.GetFirstPoint())/2;
9319 : int dist=200;
9320 0 : for( int nr=t0.GetFirstPoint()+1; nr< t0.GetLastPoint(); nr++){
9321 : //if (t0.GetClusterIndex2(nr)<0) continue;
9322 0 : if( !t0.GetClusterPointer(nr) ) continue;
9323 0 : int d = TMath::Abs(nr-midRow);
9324 0 : if( d < dist ){
9325 : dist = d;
9326 0 : basePoints[1] = nr;
9327 0 : }
9328 0 : }
9329 : }
9330 :
9331 : // first fit 3 base points
9332 : if( 1||iter<2 ){
9333 : //cout<<"Fit3: "<<endl;
9334 0 : for( int icl=0; icl<3; icl++){
9335 0 : int nr = basePoints[icl];
9336 : int lr=nr;
9337 0 : if( nr>=fInnerSec->GetNRows()){
9338 0 : lr = nr - fInnerSec->GetNRows();
9339 0 : fSectors=fOuterSec;
9340 0 : } else fSectors=fInnerSec;
9341 :
9342 0 : AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
9343 0 : if(!cl){
9344 : //cout<<"WRONG!!!!"<<endl;
9345 0 : continue;
9346 : }
9347 0 : int iSec = cl->GetDetector() %fkNIS;
9348 0 : int rotate = iSec - t.GetRelativeSector();
9349 0 : if( rotate!=0 ){
9350 : //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
9351 0 : if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
9352 : //cout<<"can't rotate "<<endl;
9353 0 : break;
9354 : }
9355 0 : t.SetRelativeSector(iSec);
9356 0 : }
9357 0 : Double_t x= cl->GetX();
9358 0 : if (!t.PropagateTo(x)){
9359 : //cout<<"can't propagate to x="<<x<<endl;
9360 0 : break;
9361 : }
9362 0 : t.SetRow(nr); // RS: memorise row
9363 0 : if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
9364 : //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
9365 0 : break;
9366 : }
9367 : //cout<<"fit3 : row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
9368 :
9369 0 : t.SetCurrentClusterIndex1(clusterIndex[nr]);
9370 0 : t.SetCurrentCluster(cl);
9371 0 : t.SetRow(lr);
9372 :
9373 0 : t.SetErrorY2(shapeY2[nr]);
9374 0 : t.SetErrorZ2(shapeZ2[nr]);
9375 0 : if( icl==0 ){
9376 0 : double cov[15];
9377 0 : for( int j=0; j<15; j++ ) cov[j]=0;
9378 0 : cov[0]=10;
9379 0 : cov[2]=10;
9380 0 : cov[5]=.5;
9381 0 : cov[9]=.5;
9382 0 : cov[14]=1.;
9383 0 : t.AliExternalTrackParam::AddCovariance(cov);
9384 0 : }
9385 0 : if( !UpdateTrack(&t,0) ){
9386 : //cout<<"Can not update"<<endl;
9387 : //t.Print();
9388 0 : t.SetClusterIndex2(nr,-1);
9389 0 : t.SetClusterIndex(nr,-1);
9390 0 : t.SetClusterPointer(nr,0);
9391 0 : break;
9392 : }
9393 : //t.SetClusterPointer(nr, cl);
9394 0 : }
9395 :
9396 : //t.SetLastPoint(t0.GetLastPoint());
9397 : //t.SetFirstPoint(t0.GetFirstPoint());
9398 :
9399 : //cout<<"Fit: "<<endl;
9400 0 : for (Int_t nr=t0.GetLastPoint(); nr>=t0.GetFirstPoint(); nr-- ){
9401 : int lr=nr;
9402 0 : if( nr>=fInnerSec->GetNRows()){
9403 0 : lr = nr - fInnerSec->GetNRows();
9404 0 : fSectors=fOuterSec;
9405 0 : } else fSectors=fInnerSec;
9406 :
9407 : if(1|| iter<2 ){
9408 0 : if( nr == basePoints[0] ) continue;
9409 0 : if( nr == basePoints[1] ) continue;
9410 0 : if( nr == basePoints[2] ) continue;
9411 : }
9412 0 : AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
9413 0 : if(!cl) continue;
9414 :
9415 0 : int iSec = cl->GetDetector() %fkNIS;
9416 0 : int rotate = iSec - t.GetRelativeSector();
9417 0 : if( rotate!=0 ){
9418 : //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
9419 0 : if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
9420 : //cout<<"can't rotate "<<endl;
9421 0 : break;
9422 : }
9423 0 : t.SetRelativeSector(iSec);
9424 0 : }
9425 0 : Double_t x= cl->GetX();
9426 0 : if (!t.PropagateTo(x)){
9427 : //cout<<"can't propagate to x="<<x<<endl;
9428 0 : break;
9429 : }
9430 0 : if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
9431 : //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
9432 0 : break;
9433 : }
9434 0 : t.SetRow(nr); //RS: memorise row
9435 : //cout<<"fit: row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
9436 :
9437 0 : t.SetCurrentClusterIndex1(clusterIndex[nr]);
9438 0 : t.SetCurrentCluster(cl);
9439 0 : t.SetRow(lr);
9440 0 : t.SetErrorY2(shapeY2[nr]);
9441 0 : t.SetErrorZ2(shapeZ2[nr]);
9442 :
9443 0 : if( !UpdateTrack(&t,0) ){
9444 : //cout<<"Can not update"<<endl;
9445 : //t.Print();
9446 0 : t.SetClusterIndex2(nr,-1);
9447 0 : t.SetClusterIndex(nr,-1);
9448 0 : break;
9449 : }
9450 : //t.SetClusterPointer(nr, cl);
9451 0 : }
9452 : }
9453 : //cout<<"After iter "<<iter<<": N clusters="<<t.GetNumberOfClusters()<<" : "<<nClusters<<endl;
9454 0 : }
9455 :
9456 : //cout<<"fitted track"<<iSeed<<endl;
9457 : //t.Print();
9458 : //cout<<"Statistics: "<<endl;
9459 0 : Int_t foundable,found,shared;
9460 : //t.GetClusterStatistic(0,nRows, found, foundable, shared, kTRUE);
9461 0 : t.GetClusterStatistic(0,nRows, found, foundable); //RS shared info is not used, use faster method
9462 0 : t.SetNFoundable(foundable);
9463 : //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
9464 :
9465 0 : }
9466 0 : }
9467 :
9468 :
9469 : TObjArray * AliTPCtracker::MakeSeedsHLT(const AliESDEvent *hltEvent)
9470 : {
9471 : // tracking
9472 : //
9473 0 : AliFatal("RS: This method is not yet aware of cluster pointers no present in the in-memory tracks");
9474 0 : if( !hltEvent ) return 0;
9475 :
9476 :
9477 0 : Int_t nentr=hltEvent->GetNumberOfTracks();
9478 :
9479 0 : AliInfo(Form("Using %d HLT tracks for seeding",nentr));
9480 :
9481 0 : TObjArray * seeds = new TObjArray(nentr);
9482 :
9483 0 : Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
9484 : Int_t index = 0;
9485 :
9486 0 : Int_t nTr=hltEvent->GetNumberOfTracks();
9487 :
9488 0 : for( int itr=0; itr<nTr; itr++ ){
9489 : //if( itr!=97 ) continue;
9490 0 : const AliExternalTrackParam *param = hltEvent->GetTrack(itr)->GetTPCInnerParam();
9491 0 : if( !param ) continue;
9492 : //if( TMath::Abs(esdTr->GetSigned1Pt())>1 ) continue;
9493 : //if( TMath::Abs(esdTr->GetTgl())>1. ) continue;
9494 0 : AliTPCtrack tr;
9495 0 : tr.Set(param->GetX(),param->GetAlpha(),param->GetParameter(),param->GetCovariance());
9496 0 : tr.SetNumberOfClusters(0);
9497 0 : AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed(tr);
9498 :
9499 0 : Double_t alpha=seed->GetAlpha();// - fSectors->GetAlphaShift();
9500 0 : if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
9501 0 : if (alpha < 0. ) alpha += 2.*TMath::Pi();
9502 : //
9503 0 : seed->SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
9504 0 : Double_t alphaSec = fSectors->GetAlpha() * seed->GetRelativeSector() + fSectors->GetAlphaShift();
9505 :
9506 0 : if (alphaSec >= TMath::Pi()) alphaSec -= 2.*TMath::Pi();
9507 0 : if (alphaSec < -TMath::Pi()) alphaSec += 2.*TMath::Pi();
9508 :
9509 0 : seed->Rotate(alphaSec - alpha);
9510 :
9511 0 : seed->SetPoolID(fLastSeedID);
9512 0 : seed->SetIsSeeding(kTRUE);
9513 0 : seed->SetSeed1(nup-1);
9514 0 : seed->SetSeed2(nup-2);
9515 0 : seed->SetSeedType(0);
9516 0 : seed->SetFirstPoint(-1);
9517 0 : seed->SetLastPoint(-1);
9518 0 : seeds->AddLast(seed); // note, track is seed, don't free the seed
9519 0 : index++;
9520 : //if( index>3 ) break;
9521 0 : }
9522 :
9523 :
9524 0 : fSectors = fOuterSec;
9525 :
9526 0 : TrackFollowingHLT(seeds );
9527 :
9528 0 : nTr = seeds->GetEntriesFast();
9529 0 : for( int itr=0; itr<nTr; itr++ ){
9530 0 : AliTPCseed * seed = (AliTPCseed*) seeds->UncheckedAt(itr);
9531 0 : if( !seed ) continue;
9532 : //FollowBackProlongation(*seed,0);
9533 : // cout<<seed->GetNumberOfClusters()<<endl;
9534 0 : Int_t foundable,found;//,shared;
9535 : // seed->GetClusterStatistic(0,nup, found, foundable, shared, kTRUE); //RS shared info is not used, use faster method
9536 0 : seed->GetClusterStatistic(0,nup, found, foundable);
9537 0 : seed->SetNFoundable(foundable);
9538 : //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
9539 : //if ((found<0.55*foundable) || shared>0.5*found ){// || (seed->GetSigmaY2()+seed->GetSigmaZ2())>0.5){
9540 : //MarkSeedFree(seeds->RemoveAt(itr));
9541 : //continue;
9542 : //}
9543 0 : if (seed->GetNumberOfClusters()<30 ||
9544 0 : seed->GetNumberOfClusters() < seed->GetNFoundable()*0.6 ||
9545 0 : seed->GetNShared()>0.4*seed->GetNumberOfClusters() ) {
9546 0 : MarkSeedFree(seeds->RemoveAt(itr));
9547 0 : continue;
9548 : }
9549 :
9550 0 : for( int ir=0; ir<nup; ir++){
9551 0 : AliTPCclusterMI *c = seed->GetClusterPointer(ir);
9552 0 : if( c ) c->Use(10);
9553 : }
9554 0 : }
9555 0 : std::cout<<"\n\nHLT tracks left: "<<seeds->GetEntries()<<" out of "<<hltEvent->GetNumberOfTracks()<<endl<<endl;
9556 : return seeds;
9557 0 : }
9558 :
9559 : void AliTPCtracker::FillClusterOccupancyInfo()
9560 : {
9561 : //fill the cluster occupancy info into the ESD friend
9562 16 : AliESDfriend* esdFriend = static_cast<AliESDfriend*>(fEvent->FindListObject("AliESDfriend"));
9563 8 : if (!esdFriend) return;
9564 :
9565 304 : for (Int_t isector=0; isector<18; isector++){
9566 144 : AliTPCtrackerSector &iroc = fInnerSec[isector];
9567 144 : AliTPCtrackerSector &oroc = fOuterSec[isector];
9568 : //all clusters
9569 144 : esdFriend->SetNclustersTPC(isector, iroc.GetNClInSector(0));
9570 144 : esdFriend->SetNclustersTPC(isector+18,iroc.GetNClInSector(1));
9571 144 : esdFriend->SetNclustersTPC(isector+36,oroc.GetNClInSector(0));
9572 144 : esdFriend->SetNclustersTPC(isector+54,oroc.GetNClInSector(1));
9573 : //clusters used in tracking
9574 144 : esdFriend->SetNclustersTPCused(isector, iroc.GetNClUsedInSector(0));
9575 144 : esdFriend->SetNclustersTPCused(isector+18, iroc.GetNClUsedInSector(1));
9576 144 : esdFriend->SetNclustersTPCused(isector+36, oroc.GetNClUsedInSector(0));
9577 144 : esdFriend->SetNclustersTPCused(isector+54, oroc.GetNClUsedInSector(1));
9578 : }
9579 16 : }
9580 :
9581 : void AliTPCtracker::FillSeedClusterStatCache(const AliTPCseed* seed)
9582 : {
9583 : //RS fill cache for seed's cluster statistics evaluation buffer
9584 0 : for (int i=kMaxRow;i--;) {
9585 0 : Int_t index = seed->GetClusterIndex2(i);
9586 0 : fClStatFoundable[i] = (index!=-1);
9587 0 : fClStatFound[i] = fClStatShared[i] = kFALSE;
9588 0 : if (index<0 || (index&0x8000)) continue;
9589 0 : const AliTPCclusterMI* cl = GetClusterMI(index);
9590 0 : if (cl->IsUsed(10)) fClStatShared[i] = kTRUE;
9591 0 : }
9592 0 : }
9593 :
9594 : void AliTPCtracker::GetCachedSeedClusterStatistic(Int_t first, Int_t last, Int_t &found, Int_t &foundable, Int_t &shared, Bool_t plus2) const
9595 : {
9596 : //RS calculation of cached seed statistics
9597 0 : found = 0;
9598 0 : foundable = 0;
9599 0 : shared = 0;
9600 : //
9601 0 : for (Int_t i=first;i<last; i++){
9602 0 : if (fClStatFoundable[i]) foundable++;
9603 : else continue;
9604 : //
9605 0 : if (fClStatFound[i]) found++;
9606 : else continue;
9607 : //
9608 0 : if (fClStatShared[i]) {
9609 0 : shared++;
9610 0 : continue;
9611 : }
9612 0 : if (!plus2) continue; //take also neighborhoud
9613 : //
9614 0 : if ( i>0 && fClStatShared[i-1]) {
9615 0 : shared++;
9616 0 : continue;
9617 : }
9618 0 : if ( i<(kMaxRow-1) && fClStatShared[i+1]) {
9619 0 : shared++;
9620 0 : continue;
9621 : }
9622 : }
9623 0 : }
9624 :
9625 : void AliTPCtracker::GetSeedClusterStatistic(const AliTPCseed* seed, Int_t first, Int_t last, Int_t &found, Int_t &foundable, Int_t &shared, Bool_t plus2) const
9626 : {
9627 : // RS: get cluster stat. on given region, faster for small regions than cachin the whole seed stat.
9628 : //
9629 1064 : found = 0;
9630 1064 : foundable = 0;
9631 1064 : shared =0;
9632 196160 : for (Int_t i=first;i<last; i++){
9633 97016 : Int_t index = seed->GetClusterIndex2(i);
9634 189308 : if (index!=-1) foundable++;
9635 110646 : if (index&0x8000) continue;
9636 166772 : if (index>=0) found++;
9637 0 : else continue;
9638 83386 : const AliTPCclusterMI* cl = GetClusterMI(index);
9639 83386 : if (cl->IsUsed(10)) {
9640 13178 : shared++;
9641 13178 : continue;
9642 : }
9643 138350 : if (!plus2) continue; //take also neighborhoud
9644 : //
9645 2066 : if (i>0) {
9646 2066 : index = seed->GetClusterIndex2(i-1);
9647 5944 : cl = index<0 ? 0:GetClusterMI(index);
9648 3878 : if (cl && cl->IsUsed(10)) {
9649 0 : shared++;
9650 0 : continue;
9651 : }
9652 : }
9653 2066 : if (i<(kMaxRow-1)) {
9654 2066 : index = seed->GetClusterIndex2(i+1);
9655 5938 : cl = index<0 ? 0:GetClusterMI(index);
9656 3872 : if (cl && cl->IsUsed(10)) {
9657 0 : shared++;
9658 0 : continue;
9659 : }
9660 : }
9661 :
9662 2066 : }
9663 1064 : }
9664 :
9665 : Bool_t AliTPCtracker::DistortX(const AliTPCseed* seed, double& x, int row)
9666 : {
9667 : // distort X by the distorion at track location on given row
9668 : //
9669 : //RS:? think to unset fAccountDistortions if no maps are used
9670 0 : if (!AliTPCReconstructor::GetRecoParam()->GetUseCorrectionMap()) return kTRUE;
9671 0 : double xyz[3];
9672 : int rowInp = row;//RS
9673 0 : if (!seed->GetYZAt(x,AliTracker::GetBz(),&xyz[1])) return kFALSE; //RS:? Think to cache fBz?
9674 0 : xyz[0] = x;
9675 0 : int roc = seed->GetRelativeSector();
9676 0 : if (seed->GetZ()<0) roc += 18;
9677 0 : if (row>62) {
9678 0 : roc += 36;
9679 0 : row -= 63;
9680 0 : }
9681 0 : AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
9682 0 : AliTPCTransform *transform = calibDB->GetTransform();
9683 0 : if (!transform) AliFatal("Tranformations not in calibDB");
9684 0 : x += transform->GetCorrMapComponent(roc,row,xyz,0);
9685 : return kTRUE;
9686 0 : }
9687 :
9688 : Double_t AliTPCtracker::GetDistortionX(double x, double y, double z, int sec, int row)
9689 : {
9690 : // get X distortion at location on given row
9691 : //
9692 0 : if (!AliTPCReconstructor::GetRecoParam()->GetUseCorrectionMap()) return 0;
9693 0 : double xyz[3] = {x,y,z};
9694 : int rowInp = row;
9695 : int secInp = sec;
9696 0 : if (z<0) sec += 18;
9697 0 : if (row>62) {
9698 0 : sec += 36;
9699 0 : row -= 63;
9700 0 : }
9701 0 : AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
9702 0 : AliTPCTransform *transform = calibDB->GetTransform() ;
9703 0 : if (!transform) AliFatal("Tranformations not in calibDB");
9704 0 : return transform->GetCorrMapComponent(sec,row,xyz,0);
9705 0 : }
9706 :
9707 : Double_t AliTPCtracker::GetYSectEdgeDist(int sec, int row, double y, double z)
9708 : {
9709 : // get the signed shift for maxY of the sector/row accounting for distortion
9710 : // Slow way, to speed up
9711 0 : if (!AliTPCReconstructor::GetRecoParam()->GetUseCorrectionMap()) return 0;
9712 0 : double ymax = 0.9*GetMaxY(row); // evaluate distortions at 5% of pad lenght from the edge
9713 0 : if (y<0) ymax = -ymax;
9714 0 : double xyz[3] = {GetXrow(row),ymax,z};
9715 0 : if (z<0) sec += 18;
9716 0 : if (row>62) {
9717 0 : sec += 36;
9718 0 : row -= 63;
9719 0 : }
9720 0 : AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
9721 0 : AliTPCTransform *transform = calibDB->GetTransform();
9722 0 : if (!transform) AliFatal("Tranformations not in calibDB");
9723 : // change of distance from the edge due to the X shift
9724 0 : double dxtg = transform->GetCorrMapComponent(sec,row,xyz,0)*AliTPCTransform::GetMaxY2X();
9725 0 : double dy = transform->GetCorrMapComponent(sec,row,xyz,1);
9726 0 : return dy + (y>0?dxtg:-dxtg);
9727 : //
9728 0 : }
9729 :
9730 : Int_t AliTPCtracker::GetTrackSector(double alpha)
9731 : {
9732 : //convert alpha to sector
9733 0 : if (alpha<0) alpha += TMath::Pi()*2;
9734 0 : int sec = alpha/(TMath::Pi()/9);
9735 0 : return sec;
9736 : }
9737 :
9738 : void AliTPCtracker::CleanESDFriendsObjects(AliESDEvent* esd)
9739 : {
9740 : // RS: remove seeds stored in friend's calib object contained w/o changing its ownership
9741 : //
9742 16 : AliInfo("Removing own seeds from friend tracks");
9743 8 : AliESDfriend* esdF = esd->FindFriend();
9744 8 : int ntr = esd->GetNumberOfTracks();
9745 158 : for (int itr=ntr;itr--;) {
9746 142 : AliESDtrack* trc = esd->GetTrack(itr);
9747 142 : AliESDfriendTrack* trcF = (AliESDfriendTrack*)trc->GetFriendTrack();
9748 142 : if (!trcF) continue;
9749 142 : AliTPCseed* seed = (AliTPCseed*)trcF->GetTPCseed();
9750 142 : if (seed) {
9751 63 : trcF->RemoveCalibObject((TObject*)seed);
9752 63 : seed->SetClusterOwner(kFALSE);
9753 63 : seed->SetClustersArrayTMP(0);
9754 63 : }
9755 142 : }
9756 : //
9757 8 : }
9758 :
9759 : //__________________________________________________________________
9760 : void AliTPCtracker::CleanESDTracksObjects(TObjArray* trcList)
9761 : {
9762 : // RS: remove seeds stored in friend's calib object contained w/o changing its ownership
9763 : //
9764 8 : int ntr = trcList->GetEntriesFast();
9765 28 : for (int itr=0;itr<ntr;itr++) {
9766 10 : TObject *obj = trcList->At(itr);
9767 30 : AliESDfriendTrack* trcF = (obj->IsA()==AliESDtrack::Class()) ?
9768 10 : (AliESDfriendTrack*)((AliESDtrack*)obj)->GetFriendTrack() : (AliESDfriendTrack*)obj;
9769 10 : if (!trcF) continue;
9770 10 : AliTPCseed* seed = (AliTPCseed*)trcF->GetTPCseed();
9771 10 : if (seed) {
9772 5 : trcF->RemoveCalibObject((TObject*)seed);
9773 5 : seed->SetClusterOwner(kFALSE);
9774 5 : seed->SetClustersArrayTMP(0);
9775 5 : }
9776 10 : }
9777 : //
9778 4 : }
|