]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/UPGRADE/AliITSUTrackerGlo.cxx
Made chi2-cut, road definitions AliITSUTrackCond and layer dependent
[u/mrichter/AliRoot.git] / ITS / UPGRADE / AliITSUTrackerGlo.cxx
CommitLineData
32d38de2 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 TO CHECK
18 GetBz usage
19
20 */
21
22//-------------------------------------------------------------------------
23// Implementation of the ITS Upgrade tracker mother class.
24//-------------------------------------------------------------------------
25#include <TTree.h>
26#include <Riostream.h>
27#include <TMath.h>
76390254 28#include <TFile.h>
32d38de2 29
30#include "AliITSUTrackerGlo.h"
31#include "AliESDEvent.h"
32#include "AliESDtrack.h"
33#include "AliITSURecoDet.h"
34#include "AliITSURecoSens.h"
35#include "AliITSUReconstructor.h"
36#include "AliITSReconstructor.h"
37#include "AliITSUSeed.h"
38#include "AliITSUAux.h"
c61e50c3 39#include "AliITSUClusterPix.h"
cb50e082 40#include "AliITSUGeomTGeo.h"
32d38de2 41using namespace AliITSUAux;
42using namespace TMath;
43
c8d1f258 44//----------------- tmp stuff -----------------
c8d1f258 45
32d38de2 46ClassImp(AliITSUTrackerGlo)
e2d2481c 47
48const Double_t AliITSUTrackerGlo::fgkToler = 1e-6;// tolerance for layer on-surface check
49
50
32d38de2 51//_________________________________________________________________________
52AliITSUTrackerGlo::AliITSUTrackerGlo(AliITSUReconstructor* rec)
53: fReconstructor(rec)
54 ,fITS(0)
0091e9f0 55 ,fCurrESDtrack(0)
0ddbf657 56 ,fCurrESDtrMClb(kDummyLabel)
32d38de2 57 ,fCurrMass(kPionMass)
0ddbf657 58 ,fCountProlongationTrials(0)
59 ,fCountITSin(0)
60 ,fCountITSout(0)
61 ,fCountITSrefit(0)
716ccba7 62 ,fHypStore(100)
38997c3c 63 ,fNBranchesAdded(0)
64 ,fNCandidatesAdded(0)
716ccba7 65 ,fCurrHyp(0)
c61e50c3 66 ,fSeedsPool("AliITSUSeed",0)
b8b59e05 67 ,fFreeSeedsID(0)
68 ,fNFreeSeeds(0)
69 ,fLastSeedID(0)
42c3d4bd 70 ,fDefTrackConds(0)
71 ,fCurrTrackCond(0)
c51c3124 72 ,fTrackPhase(-1)
8b16dbae 73 ,fClInfo(0)
53870004 74#ifdef _FILL_CONTROL_HISTOS_
75 ,fCHistoArr(0)
76#endif
32d38de2 77{
78 // Default constructor
79 if (rec) Init(rec);
80}
81
82//_________________________________________________________________________
83AliITSUTrackerGlo::~AliITSUTrackerGlo()
84{
85 // Default destructor
86 //
8b16dbae 87 delete[] fClInfo;
32d38de2 88 //
76390254 89#ifdef _FILL_CONTROL_HISTOS_
53870004 90 if (fCHistoArr) {
76390254 91 TFile* ctrOut = TFile::Open("itsuControlHistos.root","recreate");
92 ctrOut->cd();
93 AliInfo("Storing control histos");
53870004 94 fCHistoArr->Print();
95 // ctrOut->WriteObject(fCHistoArr,"controlH","kSingleKey");
96 fCHistoArr->Write();
76390254 97 ctrOut->Close();
98 delete ctrOut;
53870004 99 fCHistoArr = 0;
76390254 100 }
101#endif
102 //
32d38de2 103}
104
105//_________________________________________________________________________
106void AliITSUTrackerGlo::Init(AliITSUReconstructor* rec)
107{
108 // init with external reconstructor
c61e50c3 109 //
3d4dc3e2 110 fITS = rec->GetITSInterface();
8b16dbae 111 int nLr = fITS->GetNLayersActive();
112 fClInfo = new Int_t[nLr<<1];
c61e50c3 113 //
114 fSeedsPool.ExpandCreateFast(1000); // RS TOCHECK
b8b59e05 115 fFreeSeedsID.Set(1000);
c61e50c3 116 //
32d38de2 117}
118
42c3d4bd 119//_________________________________________________________________________
120void AliITSUTrackerGlo::CreateDefaultTrackCond()
121{
122 // creates default tracking conditions to be used when recoparam does not provide them
123 int nLr = fITS->GetNLayersActive();
124 fClInfo = new Int_t[nLr<<1];
125 //
126 AliITSUTrackCond* cond = new AliITSUTrackCond();
127 //
128 cond->SetNLayers(fITS->GetNLayersActive());
129 cond->AddNewCondition(nLr);
130 cond->AddGroupPattern( 0xffff ); // require all layers hit
ee54014a 131 cond->Init();
42c3d4bd 132 //
133 fDefTrackConds.AddLast(cond);
134 //
135 AliInfo("Created conditions: ");
136 for (int i=0;i<fDefTrackConds.GetEntriesFast();i++) fDefTrackConds[i]->Print();
137 //
138}
139
140
32d38de2 141//_________________________________________________________________________
142Int_t AliITSUTrackerGlo::Clusters2Tracks(AliESDEvent *esdEv)
143{
144 //
76390254 145 SetTrackingPhase(kClus2Tracks);
146 //
147#ifdef _FILL_CONTROL_HISTOS_
53870004 148 if (!fCHistoArr) BookControlHistos();
76390254 149#endif
150
42c3d4bd 151 TObjArray *trackConds = 0;
32d38de2 152 //
0ddbf657 153 fCountProlongationTrials = 0;
154 fCountITSin = 0;
155 fCountITSout = 0;
156 fCountITSrefit = 0;
157 //
b8b59e05 158 ResetSeedsPool();
716ccba7 159 int nTrESD = esdEv->GetNumberOfTracks();
c51c3124 160 AliInfo(Form("Will try to find prolongations for %d tracks",nTrESD));
42c3d4bd 161 int nTrackCond = AliITSUReconstructor::GetRecoParam()->GetNTrackingConditions();
162 if (nTrackCond<1) {
163 if (!fDefTrackConds.GetEntriesFast()) {
164 AliInfo("No tracking conditions found in recoparams, creating default one requesting all layers hit");
165 CreateDefaultTrackCond();
166 }
167 trackConds = &fDefTrackConds;
168 nTrackCond = trackConds->GetEntriesFast();
169 }
170 else trackConds = AliITSUReconstructor::GetRecoParam()->GetTrackingConditions();
171 //
15b02d69 172 static Bool_t first = kTRUE;
173 if (first) {
174 AliITSUReconstructor::GetRecoParam()->Print();
175 first = kFALSE;
176 }
177 fHypStore.Delete();
178 if (fHypStore.GetSize()<nTrESD) fHypStore.Expand(nTrESD+100);
179 //
180 fITS->ProcessClusters();
181 //
53870004 182 FlagSplitClusters(); // tmp RS
183 //
42c3d4bd 184 for (int icnd=0;icnd<nTrackCond;icnd++) {
185 fCurrTrackCond = (AliITSUTrackCond*)trackConds->UncheckedAt(icnd);
ee54014a 186 if (!fCurrTrackCond->IsInitDone()) fCurrTrackCond->Init();
42c3d4bd 187 // select ESD tracks to propagate
188 for (int itr=0;itr<nTrESD;itr++) {
0ddbf657 189 fCurrESDtrack = esdEv->GetTrack(itr);
190 fCurrESDtrMClb = fCurrESDtrack->GetLabel();
191 //
192 if (!NeedToProlong(fCurrESDtrack)) continue; // are we interested in this track?
38997c3c 193 AliDebug(+1,Form("Processing track %d | M=%.3f Pt=%.3f | MCLabel: %d",itr,fCurrESDtrack->GetMass(kTRUE),fCurrESDtrack->Pt(),fCurrESDtrMClb));//RS
0ddbf657 194 FindTrack(fCurrESDtrack, itr);
42c3d4bd 195 }
196 //
38997c3c 197 if (AliDebugLevelClass()>+2) {
15b02d69 198 AliInfo(Form("SeedsPool: %d, BookedUpTo: %d, free: %d",fSeedsPool.GetSize(),fSeedsPool.GetEntriesFast(),fNFreeSeeds));
199 fHypStore.Print();
200 }
42c3d4bd 201 FinalizeHypotheses();
202 }
716ccba7 203 //
0ddbf657 204 AliInfo(Form("%d ITSin for %d tried TPC seeds out of %d ESD tracks\n",fCountITSin,fCountProlongationTrials,nTrESD));
32d38de2 205 return 0;
206}
207
208//_________________________________________________________________________
c51c3124 209Int_t AliITSUTrackerGlo::PropagateBack(AliESDEvent *esdEv)
32d38de2 210{
211 //
c51c3124 212 // Do outward fits in ITS
213 //
e7d83d38 214 SetTrackingPhase(kPropBack);
c51c3124 215 int nTrESD = esdEv->GetNumberOfTracks();
15b02d69 216 AliDebug(1,Form("Will propagate back %d tracks",nTrESD));
c51c3124 217 //
218 double bz0 = GetBz();
219 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
220 AliITSUTrackHyp dummyTr,*currTr=0;
221 const double kWatchStep=10.; // for larger steps watch arc vs segment difference
222 Double_t times[AliPID::kSPECIES];
223 //
224 //
225 for (int itr=0;itr<nTrESD;itr++) {
0ddbf657 226 fCurrESDtrack = esdEv->GetTrack(itr);
227 fCurrESDtrMClb = fCurrESDtrack->GetLabel();
c51c3124 228 // Start time integral and add distance from current position to vertex
0ddbf657 229 if (fCurrESDtrack->IsOn(AliESDtrack::kITSout)) continue; // already done
c51c3124 230 //
0ddbf657 231 fCurrESDtrack->GetXYZ(xyzTrk);
c51c3124 232 Double_t dst = 0.; // set initial track lenght, tof
233 {
234 double dxs = xyzTrk[0] - xyzVtx[0];
235 double dys = xyzTrk[1] - xyzVtx[1];
236 double dzs = xyzTrk[2] - xyzVtx[2];
237 // RS: for large segment steps d use approximation of cicrular arc s by
238 // s = 2R*asin(d/2R) = d/p asin(p) \approx d/p (p + 1/6 p^3) = d (1+1/6 p^2)
239 // where R is the track radius, p = d/2R = 2C*d (C is the abs curvature)
240 // Hence s^2/d^2 = (1+1/6 p^2)^2
241 dst = dxs*dxs + dys*dys;
242 if (dst > kWatchStep*kWatchStep) { // correct circular part for arc/segment factor
0ddbf657 243 double crv = Abs(fCurrESDtrack->GetC(bz0));
c51c3124 244 double fcarc = 1.+crv*crv*dst/6.;
245 dst *= fcarc*fcarc;
246 }
247 dst += dzs*dzs;
248 dst = Sqrt(dst);
249 }
250 //
0ddbf657 251 fCurrESDtrack->SetStatus(AliESDtrack::kTIME);
c51c3124 252 //
0ddbf657 253 if (!fCurrESDtrack->IsOn(AliESDtrack::kITSin)) { // case of tracks w/o ITS prolongation: just set the time integration
254 dummyTr.AliExternalTrackParam::operator=(*fCurrESDtrack);
c51c3124 255 dummyTr.StartTimeIntegral();
e2d2481c 256 dummyTr.AddTimeStep(dst);
c51c3124 257 dummyTr.GetIntegratedTimes(times);
0ddbf657 258 fCurrESDtrack->SetIntegratedTimes(times);
259 fCurrESDtrack->SetIntegratedLength(dummyTr.GetIntegratedLength());
c51c3124 260 continue;
261 }
262 //
263 currTr = GetTrackHyp(itr);
264 currTr->StartTimeIntegral();
265 currTr->AddTimeStep(dst);
15b02d69 266 // printf("Before resetCov: "); currTr->AliExternalTrackParam::Print();
e2d2481c 267 currTr->ResetCovariance(10000);
68a0f687 268 if (RefitTrack(currTr,fITS->GetRMax())) { // propagate to exit from the ITS/TPC screen
269 UpdateESDTrack(currTr,AliESDtrack::kITSout);
0ddbf657 270 fCountITSout++;
68a0f687 271 }
e7d83d38 272 else {
0ddbf657 273 AliDebug(2,Form("Refit Failed for track %d | ESDtrack#%d (MClb:%d)",itr,fCurrESDtrack->GetID(),fCurrESDtrMClb));
274 //currTr->AliExternalTrackParam::Print();
275 //currTr->GetWinner()->Print();
e7d83d38 276 }
c51c3124 277 //
278 }
32d38de2 279 //
0ddbf657 280 AliInfo(Form("%d ITSout in %d ITSin tracks for %d tried TPC seeds out of %d ESD tracks\n",
281 fCountITSout,fCountITSin,fCountProlongationTrials,nTrESD));
282 //
32d38de2 283 return 0;
284}
285
286//_________________________________________________________________________
e7d83d38 287Int_t AliITSUTrackerGlo::RefitInward(AliESDEvent *esdEv)
32d38de2 288{
289 //
e7d83d38 290 // refit the tracks inward, using current cov.matrix
291 //
292 SetTrackingPhase(kRefitInw);
293 Int_t nTrESD = esdEv->GetNumberOfTracks();
b515ad7e 294 // AliLog::SetClassDebugLevel("AliITSUTrackerGlo",10);
295
15b02d69 296 AliDebug(1,Form("Will refit inward %d tracks",nTrESD));
e7d83d38 297 AliITSUTrackHyp *currTr=0;
298 //
299 for (int itr=0;itr<nTrESD;itr++) {
0ddbf657 300 fCurrESDtrack = esdEv->GetTrack(itr);
301 fCurrESDtrMClb = fCurrESDtrack->GetLabel();
e7d83d38 302 // Start time integral and add distance from current position to vertex
0ddbf657 303 UInt_t trStat = fCurrESDtrack->GetStatus();
e7d83d38 304 if ( !(trStat & AliESDtrack::kITSout) ) continue;
305 if ( trStat & AliESDtrack::kITSrefit ) continue; // already done
306 if ( (trStat & AliESDtrack::kTPCout) && !(trStat & AliESDtrack::kTPCrefit) ) continue;
307 //
308 currTr = GetTrackHyp(itr);
0ddbf657 309 currTr->AliExternalTrackParam::operator=(*fCurrESDtrack); // fetch current ESDtrack kinematics
e7d83d38 310 if (RefitTrack(currTr,fITS->GetRMin())) { // propagate up to inside radius of the beam pipe
311 UpdateESDTrack(currTr,AliESDtrack::kITSrefit);
0ddbf657 312 fCountITSrefit++;
e7d83d38 313 }
314 else {
0ddbf657 315 AliDebug(2,Form("Refit Failed for track %d |ESDtrack#%d (MClb:%d)",itr,fCurrESDtrack->GetID(),fCurrESDtrMClb));
e7d83d38 316 }
317 }
32d38de2 318 //
0ddbf657 319 AliInfo(Form("%d ITSrefit in %d ITSout in %d ITSin tracks for %d tried TPC seeds out of %d ESD tracks\n",
320 fCountITSrefit,fCountITSout,fCountITSin,fCountProlongationTrials,nTrESD));
321 //
b515ad7e 322 // AliLog::SetClassDebugLevel("AliITSUTrackerGlo",0);
32d38de2 323 return 0;
324}
325
326//_________________________________________________________________________
327Int_t AliITSUTrackerGlo::LoadClusters(TTree * treeRP)
328{
329 // read from tree (if pointer provided) or directly from the ITS reco interface
330 //
331 return fReconstructor->LoadClusters(treeRP);
332}
333
334//_________________________________________________________________________
335void AliITSUTrackerGlo::UnloadClusters()
336{
337 //
338 // To be implemented
339 //
340
341 Info("UnloadClusters","To be implemented");
342}
343//_________________________________________________________________________
344AliCluster * AliITSUTrackerGlo::GetCluster(Int_t /*index*/) const
345{
346 //
347 // To be implemented
348 //
349
350 Info("GetCluster","To be implemented");
351 return 0x0;
352}
353
354//_________________________________________________________________________
355Bool_t AliITSUTrackerGlo::NeedToProlong(AliESDtrack* esdTr)
356{
357 // do we need to match this track to ITS?
358 //
359 static double bz = GetBz();
360 if (!esdTr->IsOn(AliESDtrack::kTPCin) ||
361 esdTr->IsOn(AliESDtrack::kTPCout) ||
362 esdTr->IsOn(AliESDtrack::kITSin) ||
363 esdTr->GetKinkIndex(0)>0) return kFALSE;
364 //
c61e50c3 365 if (esdTr->Pt()<AliITSUReconstructor::GetRecoParam()->GetMinPtForProlongation()) return kFALSE;
32d38de2 366 //
367 float dtz[2];
368 esdTr->GetDZ(GetX(),GetY(),GetZ(),bz,dtz);
369 // if track is not V0 candidata but has large offset wrt IP, reject it. RS TOCHECK
c61e50c3 370 if ( !(esdTr->GetV0Index(0)>0 && dtz[0]>AliITSUReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation())
371 && (Abs(dtz[0])>AliITSUReconstructor::GetRecoParam()->GetMaxDForProlongation() ||
372 Abs(dtz[1])>AliITSUReconstructor::GetRecoParam()->GetMaxDZForProlongation())) return kFALSE;
32d38de2 373 //
cb50e082 374 // if (esdTr->Pt()<3) return kFALSE;//RS
32d38de2 375 return kTRUE;
376}
377
378//_________________________________________________________________________
716ccba7 379void AliITSUTrackerGlo::FindTrack(AliESDtrack* esdTr, Int_t esdID)
32d38de2 380{
381 // find prolongaion candidates finding for single seed
382 //
3e4e3c23 383 AliITSUSeed seedUC; // copy of the seed from the upper layer
384 AliITSUSeed seedT; // transient seed between the seedUC and new prolongation hypothesis
385 //
3e4e3c23 386 if (!InitHypothesis(esdTr,esdID)) return; // initialize prolongations hypotheses tree
32d38de2 387 //
173b3073 388 AliITSURecoSens *hitSens[AliITSURecoSens::kNNeighbors+1];
f8832015 389 //
c61e50c3 390 TObjArray clArr; // container for transfer of clusters matching to seed
32d38de2 391 //
3e4e3c23 392 int nLrActive = fITS->GetNLayersActive();
393 for (int ila=nLrActive;ila--;) {
32d38de2 394 int ilaUp = ila+1; // prolong seeds from layer above
3e4e3c23 395 //
396 // for the outermost layer the seed is created from the ESD track
397 int nSeedsUp = (ilaUp==nLrActive) ? 1 : fCurrHyp->GetNSeeds(ilaUp);
38997c3c 398 int maxNBranches = fCurrTrackCond->GetMaxBranches(ila);
399 int maxNCandidates = fCurrTrackCond->GetMaxCandidates(ila);
3e4e3c23 400 //
32d38de2 401 for (int isd=0;isd<nSeedsUp;isd++) {
3e4e3c23 402 AliITSUSeed* seedU;
403 if (ilaUp==nLrActive) {
404 seedU = 0;
405 seedUC.InitFromESDTrack(esdTr);
406 }
407 else {
408 seedU = fCurrHyp->GetSeed(ilaUp,isd); // seed on prev.active layer to prolong
409 seedUC = *seedU; // its copy will be prolonged
b8b59e05 410 seedUC.SetParent(seedU);
3e4e3c23 411 }
943e1898 412 seedUC.ResetFMatrix(); // reset the matrix for propagation to next layer
32d38de2 413 // go till next active layer
0ddbf657 414 AliDebug(2,Form("working on Lr:%d Seed:%d of %d for esdID=%d (MClb:%d) | pT=%.3f",ila,isd,nSeedsUp,esdID,fCurrESDtrMClb,seedUC.Pt()));
f8832015 415 if (!TransportToLayer(&seedUC, fITS->GetLrIDActive(ilaUp), fITS->GetLrIDActive(ila)) ) {
32d38de2 416 //
0ddbf657 417 AliDebug(2,Form("Transport failed | esdID=%d (MClb:%d)",esdID,fCurrESDtrMClb));
32d38de2 418 // Check if the seed satisfies to track definition
b8b59e05 419 if (NeedToKill(&seedUC,kTransportFailed) && seedU) KillSeed(seedU,kTRUE);
32d38de2 420 continue; // RS TODO: decide what to do with tracks stopped on higher layers w/o killing
421 }
422 AliITSURecoLayer* lrA = fITS->GetLayerActive(ila);
f8832015 423 if (!GetRoadWidth(&seedUC, ila)) { // failed to find road width on the layer
b8b59e05 424 if (NeedToKill(&seedUC,kRWCheckFailed) && seedU) KillSeed(seedU,kTRUE);
32d38de2 425 continue;
426 }
5785a9d8 427 /*
428 //RS toremove
429 int mcquest = -1;
430 if (!seedUC.ContainsFake()) {
431 mcquest = fCurrESDtrMClb;
432 seedUC.Print("etp");
433 printf("FSParams: "); for (int ip=0;ip<kNTrImpData;ip++) printf("%+e ",fTrImpData[ip]); printf("\n");
434 }
435 //
436 int nsens = lrA->FindSensors(&fTrImpData[kTrPhi0], hitSens, mcquest); // find detectors which may be hit by the track
437 */
173b3073 438 int nsens = lrA->FindSensors(&fTrImpData[kTrPhi0], hitSens); // find detectors which may be hit by the track
0ddbf657 439 AliDebug(2,Form("Will check %d sensors on lr:%d | esdID=%d (MClb:%d)",nsens,ila,esdID,fCurrESDtrMClb));
32d38de2 440 //
38997c3c 441 seedUC.SetLr(ila);
442 //
943e1898 443 double bz = GetBz();
32d38de2 444 for (int isn=nsens;isn--;) {
c61e50c3 445 AliITSURecoSens* sens = hitSens[isn];
38997c3c 446 int ncl = sens->GetNClusters();
447 if (!ncl) continue;
448 seedT = seedUC;
f8832015 449 //
53870004 450 // We need to propagate the seed to sensor on lrA staying in the frame of the sensor from prev.layer,
943e1898 451 // since the transport matrix should be defined in this frame.
452 double xs; // X in the TF of current seed, corresponding to intersection with sensor plane
53870004 453 if (!seedT.GetTrackingXAtXAlpha(sens->GetXTF(),sens->GetPhiTF(),bz, xs)) {
454 if (AliDebugLevelClass()>2) {
455 printf("Failed on GetTrackingXAtXAlpha: X=%.4f alp=%.3f\n",sens->GetXTF(),sens->GetPhiTF());
456 seedT.Print("etp");
457 }
458 continue;
459 }
460 if (xs<seedT.GetX()) {
461 if (!PropagateSeed(&seedT,xs,fCurrMass)) continue;
462 }
463 else { // some low precision tracks may hit the sensor plane outside of the layer radius
464 if (AliDebugLevelClass()>2) {
465 if (!seedT.ContainsFake()) {
466 printf("WRONG PROP on L%d, sens%d of %d: %.4f > %.4f\n",ila,isn,nsens,xs,seedT.GetX());
467 sens->Print();
468 seedT.Print("etp");
469 }
470 }
471 if (!seedT.PropagateParamOnlyTo(xs,bz)) continue;
472 }
8b16dbae 473 // if (!seedT.PropagateToX(xs,bz)) continue;
716ccba7 474 // if (!seedT.Rotate(sens->GetPhiTF())) continue;
475 if (!seedT.RotateToAlpha(sens->GetPhiTF())) continue;
943e1898 476 //
f8832015 477 int clID0 = sens->GetFirstClusterId();
cb50e082 478 for (int icl=ncl;icl--;) { // don't change the order, clusters are sorted
53870004 479 // AliLog::SetClassDebugLevel("AliITSUTrackerGlo",10);
f8832015 480 int res = CheckCluster(&seedT,ila,clID0+icl);
53870004 481 // AliLog::SetClassDebugLevel("AliITSUTrackerGlo", 0);
f8832015 482 //
483 if (res==kStopSearchOnSensor) break; // stop looking on this sensor
484 if (res==kClusterNotMatching) continue; // cluster does not match
485 // cluster is matching and it was added to the hypotheses tree
c61e50c3 486 }
32d38de2 487 }
38997c3c 488 // cluster search is done. Do we need to have a version of this seed skipping current layer
489 if (!NeedToKill(&seedUC,kMissingCluster)) {
b2d3bc3a 490 AliITSUSeed* seedSkp = NewSeedFromPool(&seedUC);
ee54014a 491 double penalty = -fCurrTrackCond->GetMissPenalty(ila);
716ccba7 492 // to do: make penalty to account for probability to miss the cluster for good reason
493 seedSkp->SetChi2Cl(penalty);
494 AddProlongationHypothesis(seedSkp,ila);
495 }
38997c3c 496 // transfer the new branches of the seed to the hypothesis container
497 if (fNBranchesAdded) ValidateAllowedBranches(maxNBranches);
498 //
32d38de2 499 }
38997c3c 500 if (fNCandidatesAdded) ValidateAllowedCandidates(ila,maxNCandidates);
501 // ((TObjArray*)fCurrHyp->GetLayerSeeds(ila))->Sort();
502 if (AliDebugLevelClass()>2) { //RS
15b02d69 503 printf(">>> All hypotheses on lr %d: \n",ila);
504 for (int ih=0;ih<fCurrHyp->GetNSeeds(ila);ih++) {printf(" #%3d ",ih); fCurrHyp->GetSeed(ila,ih)->Print();}
505 }
506 //
507 /*
716ccba7 508 for (int ih=0;ih<fCurrHyp->GetNSeeds(ila);ih++) {
716ccba7 509 if (ila!=0) continue;
510 double vecL[5] = {0};
511 double matL[15] = {0};
512 AliITSUSeed* sp = fCurrHyp->GetSeed(ila,ih);
513 while(sp->GetParent()) {
514 sp->Smooth(vecL,matL);
515 if (sp->GetLayerID()>=fITS->GetNLayersActive()-1) break;
516 sp = (AliITSUSeed*)sp->GetParent();
517 }
518 */
32d38de2 519 }
520 //
716ccba7 521 SaveCurrentTrackHypotheses();
522 //
32d38de2 523}
524
525//_________________________________________________________________________
3e4e3c23 526Bool_t AliITSUTrackerGlo::InitHypothesis(AliESDtrack *esdTr, Int_t esdID)
32d38de2 527{
c61e50c3 528 // init prolongaion candidates finding for single seed
716ccba7 529 fCurrHyp = GetTrackHyp(esdID);
530 if (fCurrHyp) return kTRUE;
531 //
0ddbf657 532 fCountProlongationTrials++;
533 //
32d38de2 534 fCurrMass = esdTr->GetMass();
535 if (fCurrMass<kPionMass*0.9) fCurrMass = kPionMass; // don't trust to mu, e identification from TPCin
c61e50c3 536 //
3e4e3c23 537 fCurrHyp = new AliITSUTrackHyp(fITS->GetNLayersActive());
538 fCurrHyp->SetESDTrack(esdTr);
716ccba7 539 fCurrHyp->SetUniqueID(esdID);
c51c3124 540 fCurrHyp->SetMass(fCurrMass);
716ccba7 541 SetTrackHyp(fCurrHyp,esdID);
3e4e3c23 542 //
32d38de2 543 return kTRUE;
544 // TO DO
545}
546
547//_________________________________________________________________________
548Bool_t AliITSUTrackerGlo::TransportToLayer(AliITSUSeed* seed, Int_t lFrom, Int_t lTo)
549{
0ddbf657 550 // transport seed from layerFrom to the entrance (along the direction of the track) of layerTo
32d38de2 551 //
8b16dbae 552 //
553 if (lTo==lFrom) AliFatal(Form("was called with lFrom=%d lTo=%d",lFrom,lTo));
554 //
32d38de2 555 int dir = lTo > lFrom ? 1:-1;
556 AliITSURecoLayer* lrFr = fITS->GetLayer(lFrom); // this can be 0 when extrapolation from TPC to ITS is requested
557 Bool_t checkFirst = kTRUE;
558 while(lFrom!=lTo) {
32d38de2 559 if (lrFr) {
b2d3bc3a 560 if (!GoToExitFromLayer(seed,lrFr,dir,checkFirst)) {
0ddbf657 561 //printf("FailHere0 Dir=%d\n",dir);
562 //seed->Print("etp");
b2d3bc3a 563 return kFALSE; // go till the end of current layer
564 }
e2d2481c 565 checkFirst = kFALSE;
32d38de2 566 }
567 AliITSURecoLayer* lrTo = fITS->GetLayer( (lFrom+=dir) );
568 if (!lrTo) AliFatal(Form("Layer %d does not exist",lFrom));
569 //
570 // go the entrance of the layer, assuming no materials in between
8b16dbae 571 double xToGo = lrTo->GetR(-dir);
0ddbf657 572 // double xts = xToGo;
b2d3bc3a 573 if (!seed->GetXatLabR(xToGo,xToGo,GetBz(),dir)) {
0ddbf657 574 //printf("FailHere1: %f %f %d\n",xts,xToGo,dir);
575 //seed->Print("etp");
576 //
577
b2d3bc3a 578 return kFALSE;
579 }
b515ad7e 580 AliDebug(2,Form("go in dir=%d to R=%.4f(X:%.4f)",dir,lrTo->GetR(-dir), xToGo));
b2d3bc3a 581 if (!PropagateSeed(seed,xToGo,fCurrMass,100, kFALSE )) {
0ddbf657 582 //printf("FailHere2: %f %f %d\n",xts,xToGo,dir);
583 //seed->Print("etp");
b2d3bc3a 584 return kFALSE;
585 }
32d38de2 586 lrFr = lrTo;
587 }
588 return kTRUE;
589 //
590}
591
3e4e3c23 592//_________________________________________________________________________
593Bool_t AliITSUTrackerGlo::TransportToLayer(AliExternalTrackParam* seed, Int_t lFrom, Int_t lTo)
594{
595 // transport track from layerFrom to the entrance of layerTo
596 //
8b16dbae 597 if (lTo==lFrom) AliFatal(Form("was called with lFrom=%d lTo=%d",lFrom,lTo));
598 //
3e4e3c23 599 int dir = lTo > lFrom ? 1:-1;
600 AliITSURecoLayer* lrFr = fITS->GetLayer(lFrom); // this can be 0 when extrapolation from TPC to ITS is requested
601 Bool_t checkFirst = kTRUE;
602 while(lFrom!=lTo) {
3e4e3c23 603 if (lrFr) {
e2d2481c 604 if (!GoToExitFromLayer(seed,lrFr,dir,checkFirst)) return kFALSE; // go till the end of current layer
605 checkFirst = kFALSE;
3e4e3c23 606 }
607 AliITSURecoLayer* lrTo = fITS->GetLayer( (lFrom+=dir) );
608 if (!lrTo) AliFatal(Form("Layer %d does not exist",lFrom));
609 //
0ddbf657 610 // go the entrance of the layer, assuming no materials in between
611 double xToGo = lrTo->GetR(-dir);
612 // double xts = xToGo;
613 if (!seed->GetXatLabR(xToGo,xToGo,GetBz(),dir)) {
614 // printf("FailHere1: %f %f %d\n",xts,xToGo,dir);
615 // seed->Print("etp");
616 return kFALSE;
617 }
b515ad7e 618 AliDebug(2,Form("go in dir=%d to R=%.4f(X:%.4f)",dir,lrTo->GetR(-dir), xToGo));
619 if (!PropagateSeed(seed,xToGo,fCurrMass,100, kFALSE )) {
620 //printf("FailHere2: %f %f %d\n",xts,xToGo,dir);
621 //seed->Print("etp");
622 return kFALSE;
623 }
624 lrFr = lrTo;
625 }
626 return kTRUE;
627 //
628}
629
630//_________________________________________________________________________
631Bool_t AliITSUTrackerGlo::TransportToLayerX(AliExternalTrackParam* seed, Int_t lFrom, Int_t lTo, Double_t xStop)
632{
633 // transport track from layerFrom to the entrance of layerTo but do not pass control parameter X
634 //
635 if (lTo==lFrom) AliFatal(Form("was called with lFrom=%d lTo=%d",lFrom,lTo));
636 //
637 int dir = lTo > lFrom ? 1:-1;
638 AliITSURecoLayer* lrFr = fITS->GetLayer(lFrom); // this can be 0 when extrapolation from TPC to ITS is requested
639 Bool_t checkFirst = kTRUE;
640 while(lFrom!=lTo) {
641 if (lrFr) {
642 if (!GoToExitFromLayer(seed,lrFr,dir,checkFirst)) return kFALSE; // go till the end of current layer
643 checkFirst = kFALSE;
644 }
645 AliITSURecoLayer* lrTo = fITS->GetLayer( (lFrom+=dir) );
646 if (!lrTo) AliFatal(Form("Layer %d does not exist",lFrom));
647 //
648 // go the entrance of the layer, assuming no materials in between
649 double xToGo = lrTo->GetR(-dir); // R of the entrance to layer
650 //
651 // double xts = xToGo;
652 if (!seed->GetXatLabR(xToGo,xToGo,GetBz(),dir)) {
653 // printf("FailHere1: %f %f %d\n",xts,xToGo,dir);
654 // seed->Print("etp");
655 return kFALSE;
656 }
657 if ( (dir>0&&xToGo>xStop) || (dir<0&&xToGo<xStop) ) xToGo = xStop;
658 //
659 AliDebug(2,Form("go in dir=%d to R=%.4f(X:%.4f)",dir,lrTo->GetR(-dir), xToGo));
0ddbf657 660 if (!PropagateSeed(seed,xToGo,fCurrMass,100, kFALSE )) {
661 //printf("FailHere2: %f %f %d\n",xts,xToGo,dir);
662 //seed->Print("etp");
663 return kFALSE;
664 }
3e4e3c23 665 lrFr = lrTo;
666 }
667 return kTRUE;
668 //
669}
670
e2d2481c 671//_________________________________________________________________________
672Bool_t AliITSUTrackerGlo::GoToExitFromLayer(AliITSUSeed* seed, AliITSURecoLayer* lr, Int_t dir, Bool_t check)
673{
674 // go to the exit from lr in direction dir, applying material corrections in steps specific for this layer
675 // If check is requested, do this only provided the track has not exited the layer already
676 double xToGo = lr->GetR(dir);
677 if (check) { // do we need to track till the surface of the current layer ?
678 double curR2 = seed->GetX()*seed->GetX() + seed->GetY()*seed->GetY(); // current radius
15b02d69 679 AliDebug(3,Form(" dir:%d Cur: %e Tgt: %e",dir,Sqrt(curR2),xToGo));
0ddbf657 680 if (dir>0) { if (curR2-xToGo*xToGo>-fgkToler) return kTRUE; } // on the surface or outside of the layer
681 else if (dir<0) { if (xToGo*xToGo-curR2>-fgkToler) return kTRUE; } // on the surface or outside of the layer
e2d2481c 682 }
683 if (!seed->GetXatLabR(xToGo,xToGo,GetBz(),dir)) return kFALSE;
684 // go via layer to its boundary, applying material correction.
685 if (!PropagateSeed(seed,xToGo,fCurrMass, lr->GetMaxStep())) return kFALSE;
e7d83d38 686 //
e2d2481c 687 return kTRUE;
688 //
689}
690
691//_________________________________________________________________________
692Bool_t AliITSUTrackerGlo::GoToExitFromLayer(AliExternalTrackParam* seed, AliITSURecoLayer* lr, Int_t dir, Bool_t check)
693{
694 // go to the exit from lr in direction dir, applying material corrections in steps specific for this layer
695 // If check is requested, do this only provided the track has not exited the layer already
696 double xToGo = lr->GetR(dir);
697 if (check) { // do we need to track till the surface of the current layer ?
698 double curR2 = seed->GetX()*seed->GetX() + seed->GetY()*seed->GetY(); // current radius
0ddbf657 699 if (dir>0) { if (curR2-xToGo*xToGo>-fgkToler) return kTRUE; } // on the surface or outside of the layer
700 else if (dir<0) { if (xToGo*xToGo-curR2>-fgkToler) return kTRUE; } // on the surface or outside of the layer
e2d2481c 701 }
b515ad7e 702 AliDebug(2,Form(" dir=%d : from R=%.4f -> R=%.4f",dir,Sqrt(seed->GetX()*seed->GetX() + seed->GetY()*seed->GetY()), xToGo));
e2d2481c 703 if (!seed->GetXatLabR(xToGo,xToGo,GetBz(),dir)) return kFALSE;
704 // go via layer to its boundary, applying material correction.
705 if (!PropagateSeed(seed,xToGo,fCurrMass, lr->GetMaxStep())) return kFALSE;
e7d83d38 706 //
e2d2481c 707 return kTRUE;
708 //
709}
710
711
712//_________________________________________________________________________
713Bool_t AliITSUTrackerGlo::GoToEntranceToLayer(AliITSUSeed* seed, AliITSURecoLayer* lr, Int_t dir, Bool_t check)
714{
715 // go to the entrance of lr in direction dir, w/o applying material corrections.
716 // If check is requested, do this only provided the track did not reach the layer already
717 double xToGo = lr->GetR(-dir);
718 if (check) { // do we need to track till the surface of the current layer ?
719 double curR2 = seed->GetX()*seed->GetX() + seed->GetY()*seed->GetY(); // current radius
0ddbf657 720 if (dir>0) { if (curR2-xToGo*xToGo>-fgkToler) return kTRUE; } // already passed
721 else if (dir<0) { if (xToGo*xToGo-curR2>-fgkToler) return kTRUE; } // already passed
e2d2481c 722 }
723 if (!seed->GetXatLabR(xToGo,xToGo,GetBz(),dir)) return kFALSE;
724 // go via layer to its boundary, applying material correction.
725 if (!PropagateSeed(seed,xToGo,fCurrMass, 100, kFALSE)) return kFALSE;
726 return kTRUE;
727 //
728}
729
730//_________________________________________________________________________
731Bool_t AliITSUTrackerGlo::GoToEntranceToLayer(AliExternalTrackParam* seed, AliITSURecoLayer* lr, Int_t dir, Bool_t check)
732{
733 // go to the entrance of lr in direction dir, w/o applying material corrections.
734 // If check is requested, do this only provided the track did not reach the layer already
735 double xToGo = lr->GetR(-dir);
736 if (check) { // do we need to track till the surface of the current layer ?
737 double curR2 = seed->GetX()*seed->GetX() + seed->GetY()*seed->GetY(); // current radius
0ddbf657 738 if (dir>0) { if (curR2-xToGo*xToGo>-fgkToler) return kTRUE; } // already passed
739 else if (dir<0) { if (xToGo*xToGo-curR2>-fgkToler) return kTRUE; } // already passed
e2d2481c 740 }
741 if (!seed->GetXatLabR(xToGo,xToGo,GetBz(),dir)) return kFALSE;
742 // go via layer to its boundary, applying material correction.
743 if (!PropagateSeed(seed,xToGo,fCurrMass, 100, kFALSE)) return kFALSE;
744 return kTRUE;
745 //
746}
747
32d38de2 748//_________________________________________________________________________
c61e50c3 749Bool_t AliITSUTrackerGlo::GetRoadWidth(AliITSUSeed* seed, int ilrA)
32d38de2 750{
751 // calculate road width in terms of phi and z for the track which MUST be on the external radius of the layer
752 // as well as some aux info
753 double bz = GetBz();
754 AliITSURecoLayer* lrA = fITS->GetLayerActive(ilrA);
c61e50c3 755 seed->GetXYZ(&fTrImpData[kTrXIn]); // lab position at the entrance from above
53870004 756 static AliExternalTrackParam sc; // seed copy for manipulations
943e1898 757 sc = *seed;
32d38de2 758 //
c61e50c3 759 fTrImpData[kTrPhiIn] = ATan2(fTrImpData[kTrYIn],fTrImpData[kTrXIn]);
943e1898 760 if (!sc.Rotate(fTrImpData[kTrPhiIn])) return kFALSE; // go to the frame of the entry point into the layer
c61e50c3 761 double dr = lrA->GetDR(); // approximate X dist at the inner radius
943e1898 762 if (!sc.GetXYZAt(sc.GetX()-dr, bz, fTrImpData + kTrXOut)) {
32d38de2 763 // special case: track does not reach inner radius, might be tangential
943e1898 764 double r = sc.GetD(0,0,bz);
32d38de2 765 double x;
943e1898 766 if (!sc.GetXatLabR(r,x,bz,-1)) {
767 sc.Print();
768 AliFatal(Form("This should not happen: r=%f",r));
32d38de2 769 }
943e1898 770 dr = Abs(sc.GetX() - x);
771 if (!sc.GetXYZAt(x, bz, fTrImpData + kTrXOut)) {
772 sc.Print();
773 AliFatal(Form("This should not happen: x=%f",x));
32d38de2 774 }
775 }
776 //
c61e50c3 777 fTrImpData[kTrPhiOut] = ATan2(fTrImpData[kTrYOut],fTrImpData[kTrXOut]);
943e1898 778 double sgy = sc.GetSigmaY2() + dr*dr*sc.GetSigmaSnp2() + AliITSUReconstructor::GetRecoParam()->GetSigmaY2(ilrA);
779 double sgz = sc.GetSigmaZ2() + dr*dr*sc.GetSigmaTgl2() + AliITSUReconstructor::GetRecoParam()->GetSigmaZ2(ilrA);
ee54014a 780 sgy = Sqrt(sgy)*fCurrTrackCond->GetNSigmaRoadY(ilrA);
781 sgz = Sqrt(sgz)*fCurrTrackCond->GetNSigmaRoadZ(ilrA);
5785a9d8 782 double dphi0 = 0.5*Abs(fTrImpData[kTrPhiOut]-fTrImpData[kTrPhiIn]);
783 double phi0 = 0.5*(fTrImpData[kTrPhiOut]+fTrImpData[kTrPhiIn]);
784 if ( dphi0>(0.5*Pi()) ) {
785 // special case of angles around pi
786 dphi0 = Abs(phi0);
787 phi0 += Pi();
788 }
789
790 fTrImpData[kTrPhi0] = phi0;
173b3073 791 fTrImpData[kTrZ0] = 0.5*(fTrImpData[kTrZOut]+fTrImpData[kTrZIn]);
5785a9d8 792 fTrImpData[kTrDPhi] = dphi0 + sgy/lrA->GetR();
173b3073 793 fTrImpData[kTrDZ] = 0.5*Abs(fTrImpData[kTrZOut]-fTrImpData[kTrZIn]) + sgz;
32d38de2 794 //
795 return kTRUE;
796}
797
b8b59e05 798//________________________________________
799void AliITSUTrackerGlo::ResetSeedsPool()
800{
801 // mark all seeds in the pool as unused
0ddbf657 802 AliDebug(-1,Form("CurrentSize: %d, BookedUpTo: %d, free: %d",fSeedsPool.GetSize(),fSeedsPool.GetEntriesFast(),fNFreeSeeds));
b8b59e05 803 fNFreeSeeds = 0;
804 fSeedsPool.Clear(); // seeds don't allocate memory
805}
806
807
808//________________________________________
809void AliITSUTrackerGlo::MarkSeedFree(AliITSUSeed *sd)
32d38de2 810{
b8b59e05 811 // account that this seed is "deleted"
812 int id = sd->GetPoolID();
813 if (id<0) {
814 AliError(Form("Freeing of seed %p NOT from the pool is requested",sd));
815 return;
816 }
817 // AliInfo(Form("%d %p",id, seed));
818 fSeedsPool.RemoveAt(id);
819 if (fFreeSeedsID.GetSize()<=fNFreeSeeds) fFreeSeedsID.Set( 2*fNFreeSeeds + 100 );
820 fFreeSeedsID.GetArray()[fNFreeSeeds++] = id;
32d38de2 821}
f8832015 822
823//_________________________________________________________________________
824Int_t AliITSUTrackerGlo::CheckCluster(AliITSUSeed* track, Int_t lr, Int_t clID)
825{
826 // Check if the cluster (in tracking frame!) is matching to track.
827 // The track must be already propagated to sensor tracking frame.
828 // Returns: kStopSearchOnSensor if the search on given sensor should be stopped,
829 // kClusterMatching if the cluster is matching
830 // kClusterMatching otherwise
831 //
f8832015 832 const double kTolerX = 5e-4;
833 AliCluster *cl = fITS->GetLayerActive(lr)->GetCluster(clID);
834 //
c8d1f258 835 Bool_t goodCl = kFALSE;
0ddbf657 836 int currLabel = Abs(fCurrESDtrMClb);
716ccba7 837 //
8b16dbae 838 if (cl->GetLabel(0)>=0) {
839 for (int i=0;i<3;i++) if (cl->GetLabel(i)>=0 && cl->GetLabel(i)==currLabel) {goodCl = kTRUE; break;}
840 }
53870004 841 Bool_t goodSeed = !track->ContainsFake();
c8d1f258 842 //
f8832015 843 if (TMath::Abs(cl->GetX())>kTolerX) { // if due to the misalingment X is large, propagate track only
c8d1f258 844 if (!track->PropagateParamOnlyTo(track->GetX()+cl->GetX(),GetBz())) {
53870004 845 if (goodCl&&goodSeed && AliDebugLevelClass()>2 ) {
846 AliDebug(2,Form("Lost good cl on L:%d failed propagation. |ESDtrack#%d (MClb:%d)",lr,fCurrESDtrack->GetID(),fCurrESDtrMClb));
847 track->Print("etp");
15b02d69 848 cl->Print();
849 }
c8d1f258 850 return kStopSearchOnSensor; // propagation failed, seedT is intact
851 }
f8832015 852 }
3dd9c283 853 double dy = cl->GetY()-track->GetY();
c8d1f258 854 double dz = cl->GetZ()-track->GetZ();
0091e9f0 855 //
76390254 856#ifdef _FILL_CONTROL_HISTOS_
857 int hcOffs = fTrackPhase*kHistosPhase + lr;
858 double htrPt=-1;
cb50e082 859 if (goodCl && (((AliITSUClusterPix*)cl)->GetNPix()>1 || !((AliITSUClusterPix*)cl)->IsSplit()) && goodSeed && fCHistoArr /* && track->GetChi2Penalty()<1e-5*/) {
76390254 860 htrPt = track->Pt();
53870004 861 ((TH2*)fCHistoArr->At(kHResY+hcOffs))->Fill(htrPt,dy);
862 ((TH2*)fCHistoArr->At(kHResZ+hcOffs))->Fill(htrPt,dz);
76390254 863 double errY = track->GetSigmaY2();
864 double errZ = track->GetSigmaZ2();
53870004 865 if (errY>0) ((TH2*)fCHistoArr->At(kHResYP+hcOffs))->Fill(htrPt,dy/Sqrt(errY));
866 if (errZ>0) ((TH2*)fCHistoArr->At(kHResZP+hcOffs))->Fill(htrPt,dz/Sqrt(errZ));
76390254 867 }
868#endif
869 //
f8832015 870 double dy2 = dy*dy;
871 double tol2 = (track->GetSigmaY2() + AliITSUReconstructor::GetRecoParam()->GetSigmaY2(lr))*
ee54014a 872 fCurrTrackCond->GetNSigmaRoadY(lr)*fCurrTrackCond->GetNSigmaRoadY(lr); // RS TOOPTIMIZE
f8832015 873 if (dy2>tol2) { // the clusters are sorted in Z(col) then in Y(row).
53870004 874 if (goodCl&&goodSeed && AliDebugLevelClass()>2) {
875 AliDebug(2,Form("Lost good cl: dy2=%e > tol2=%e |ESDtrack#%d (MClb:%d)",dy2,tol2,fCurrESDtrack->GetID(),fCurrESDtrMClb));
876 track->Print("etp");
15b02d69 877 cl->Print();
53870004 878 PrintSeedClusters(track);
15b02d69 879 }
cb50e082 880 // clusters are sorted in increasing Y and the loop goes from last (highers Y) to 1st.
881 // if the track has too large y for this cluster (dy<0) it will be so for all other clusters of the sensor
882 if (dy<0) return kStopSearchOnSensor; // No chance that other cluster of this sensor will match (all Y's will be even larger)
f8832015 883 else return kClusterNotMatching; // Other clusters may match
884 }
c8d1f258 885 double dz2 = dz*dz;
f8832015 886 tol2 = (track->GetSigmaZ2() + AliITSUReconstructor::GetRecoParam()->GetSigmaZ2(lr))*
ee54014a 887 fCurrTrackCond->GetNSigmaRoadZ(lr)*fCurrTrackCond->GetNSigmaRoadZ(lr); // RS TOOPTIMIZE
c8d1f258 888 if (dz2>tol2) {
53870004 889 if (goodCl&&goodSeed && AliDebugLevelClass()>2) {
890 AliDebug(2,Form("Lost good cl on L:%d : dz2=%e > tol2=%e |ESDtrack#%d (MClb:%d)",lr,dz2,tol2,fCurrESDtrack->GetID(),fCurrESDtrMClb));
891 track->Print("etp");
15b02d69 892 cl->Print();
53870004 893 PrintSeedClusters(track);
15b02d69 894 }
c8d1f258 895 return kClusterNotMatching; // Other clusters may match
896 }
f8832015 897 //
898 // check chi2
899 Double_t p[2]={cl->GetY(), cl->GetZ()};
900 Double_t cov[3]={cl->GetSigmaY2(), cl->GetSigmaYZ(), cl->GetSigmaZ2()};
901 double chi2 = track->GetPredictedChi2(p,cov);
76390254 902 //
903#ifdef _FILL_CONTROL_HISTOS_
904 if (htrPt>0) {
53870004 905 ((TH2*)fCHistoArr->At(kHChi2Cl+hcOffs))->Fill(htrPt,chi2);
76390254 906 }
907#endif
908 //
ee54014a 909 if (chi2>fCurrTrackCond->GetMaxTr2ClChi2(lr)) {
53870004 910 if (goodCl&&goodSeed && AliDebugLevelClass()>2) {
911 AliDebug(2,Form("Lost good cl on L:%d : Chi2=%e > Chi2Max=%e |dy: %+.3e dz: %+.3e |ESDtrack#%d (MClb:%d)\n",
ee54014a 912 lr,chi2,fCurrTrackCond->GetMaxTr2ClChi2(lr),dy,dz,fCurrESDtrack->GetID(),fCurrESDtrMClb));
3dd9c283 913 track->Print("etp");
914 cl->Print("");
53870004 915 PrintSeedClusters(track);
3dd9c283 916 }
c8d1f258 917 return kClusterNotMatching;
918 }
f8832015 919 //
920 track = NewSeedFromPool(track); // input track will be reused, use its clone for updates
943e1898 921 if (!track->Update()) {
53870004 922 if (goodCl&&goodSeed && AliDebugLevelClass()>2) {
923 AliDebug(2,Form("Lost good cluster on L:%d : failed to update",lr));
38997c3c 924 track->Print("etp");
925 cl->Print("");
53870004 926 PrintSeedClusters(track);
38997c3c 927 }
b8b59e05 928 MarkSeedFree(track);
c8d1f258 929 return kClusterNotMatching;
930 }
f8832015 931 track->SetChi2Cl(chi2);
932 track->SetLrClusterID(lr,clID);
933 cl->IncreaseClusterUsage();
934 //
716ccba7 935 track->SetFake(!goodCl);
936 //
0ddbf657 937 AliDebug(2,Form("AddCl(%d) Cl%d lr:%d: dY:%+8.4f dZ:%+8.4f (MC: %5d %5d %5d) |Chi2=%f(%c)| ",
716ccba7 938 goodCl,clID,lr,dy,dz2,cl->GetLabel(0),cl->GetLabel(1),cl->GetLabel(2), chi2, track->IsFake() ? '-':'+'));
c8d1f258 939 //
38997c3c 940 AddSeedBranch(track);
f8832015 941 //
942 return kClusterMatching;
943}
c8d1f258 944
945//_________________________________________________________________________
946Bool_t AliITSUTrackerGlo::NeedToKill(AliITSUSeed *seed, Int_t flag)
947{
948 // check if the seed should not be discarded
949 const UShort_t kMask = 0xffff;
950 if (flag==kMissingCluster) {
951 int lastChecked = seed->GetLayerID();
952 UShort_t patt = seed->GetHitsPattern();
953 if (lastChecked) patt |= ~(kMask<<lastChecked); // not all layers were checked, complete unchecked once by potential hits
42c3d4bd 954 Bool_t seedOK = fCurrTrackCond->CheckPattern(patt);
c8d1f258 955 return !seedOK;
956 }
957 return kTRUE;
958}
44785f3e 959
960//______________________________________________________________________________
961Bool_t AliITSUTrackerGlo::PropagateSeed(AliITSUSeed *seed, Double_t xToGo, Double_t mass, Double_t maxStep, Bool_t matCorr)
962{
963 // propagate seed to given x applying material correction if requested
964 const Double_t kEpsilon = 1e-5;
965 Double_t xpos = seed->GetX();
966 Int_t dir = (xpos<xToGo) ? 1:-1;
967 Double_t xyz0[3],xyz1[3],param[7];
968 //
8b16dbae 969 Bool_t updTime = dir>0 && seed->IsStartedTimeIntegral();
f497470c 970 if (matCorr || updTime) seed->GetXYZ(xyz1); //starting global position
44785f3e 971 while ( (xToGo-xpos)*dir > kEpsilon){
972 Double_t step = dir*TMath::Min(TMath::Abs(xToGo-xpos), maxStep);
973 Double_t x = xpos+step;
974 Double_t bz=GetBz(); // getting the local Bz
0ddbf657 975 if (!seed->PropagateToX(x,bz)) return kFALSE;
8b16dbae 976 double ds = 0;
977 if (matCorr || updTime) {
44785f3e 978 xyz0[0]=xyz1[0]; // global pos at the beginning of step
979 xyz0[1]=xyz1[1];
980 xyz0[2]=xyz1[2];
981 seed->GetXYZ(xyz1); // // global pos at the end of step
8b16dbae 982 if (matCorr) {
983 MeanMaterialBudget(xyz0,xyz1,param);
984 Double_t xrho=param[0]*param[4], xx0=param[1];
985 if (dir>0) xrho = -xrho; // outward should be negative
b2d3bc3a 986 if (!seed->ApplyMaterialCorrection(xx0,xrho,mass,kFALSE)) {AliInfo("Fail2"); seed->Print("etp"); return kFALSE;}
8b16dbae 987 ds = param[4];
988 }
989 else { // matCorr is not requested but time integral is
990 double d0 = xyz1[0]-xyz0[0];
991 double d1 = xyz1[1]-xyz0[1];
992 double d2 = xyz1[2]-xyz0[2];
993 ds = TMath::Sqrt(d0*d0+d1*d1+d2*d2);
994 }
44785f3e 995 }
8b16dbae 996 if (updTime) seed->AddTimeStep(ds);
44785f3e 997 xpos = seed->GetX();
998 }
999 return kTRUE;
1000}
716ccba7 1001
3e4e3c23 1002//______________________________________________________________________________
1003Bool_t AliITSUTrackerGlo::PropagateSeed(AliExternalTrackParam *seed, Double_t xToGo, Double_t mass, Double_t maxStep, Bool_t matCorr)
1004{
1005 // propagate seed to given x applying material correction if requested
1006 const Double_t kEpsilon = 1e-5;
1007 Double_t xpos = seed->GetX();
1008 Int_t dir = (xpos<xToGo) ? 1:-1;
1009 Double_t xyz0[3],xyz1[3],param[7];
1010 //
b515ad7e 1011 if (AliDebugLevelClass()>1) {
1012 AliDebug(2,Form("Before Propagate to X=%f with M=%.3f MaxStep=%.4f MatCorr=%d",xToGo,mass,maxStep,matCorr));
1013 seed->AliExternalTrackParam::Print();
1014 }
3e4e3c23 1015 Bool_t updTime = dir>0 && seed->IsStartedTimeIntegral();
1016 if (matCorr || updTime) seed->GetXYZ(xyz1); //starting global position
1017 while ( (xToGo-xpos)*dir > kEpsilon){
1018 Double_t step = dir*TMath::Min(TMath::Abs(xToGo-xpos), maxStep);
1019 Double_t x = xpos+step;
1020 Double_t bz=GetBz(); // getting the local Bz
1021 if (!seed->PropagateTo(x,bz)) return kFALSE;
1022 double ds = 0;
1023 if (matCorr || updTime) {
1024 xyz0[0]=xyz1[0]; // global pos at the beginning of step
1025 xyz0[1]=xyz1[1];
1026 xyz0[2]=xyz1[2];
1027 seed->GetXYZ(xyz1); // // global pos at the end of step
1028 //
1029 if (matCorr) {
1030 MeanMaterialBudget(xyz0,xyz1,param);
1031 Double_t xrho=param[0]*param[4], xx0=param[1];
1032 if (dir>0) xrho = -xrho; // outward should be negative
1033 if (!seed->CorrectForMeanMaterial(xx0,xrho,mass)) return kFALSE;
1034 ds = param[4];
1035 }
1036 else { // matCorr is not requested but time integral is
1037 double d0 = xyz1[0]-xyz0[0];
1038 double d1 = xyz1[1]-xyz0[1];
1039 double d2 = xyz1[2]-xyz0[2];
1040 ds = TMath::Sqrt(d0*d0+d1*d1+d2*d2);
1041 }
1042 }
1043 if (updTime) seed->AddTimeStep(ds);
1044 //
1045 xpos = seed->GetX();
1046 }
b515ad7e 1047 if (AliDebugLevelClass()>1) {
1048 AliDebug(2,Form("After Propagate to X=%f",xToGo));
1049 seed->AliExternalTrackParam::Print();
1050 }
3e4e3c23 1051 return kTRUE;
1052}
1053
716ccba7 1054//______________________________________________________________________________
1055void AliITSUTrackerGlo::SaveCurrentTrackHypotheses()
1056{
1057 // RS: shall we clean up killed seeds?
38997c3c 1058 ((TObjArray*)fCurrHyp->GetLayerSeeds(0))->Sort();
716ccba7 1059 fCurrHyp = 0;
1060 // TODO
1061
1062}
3e4e3c23 1063
1064//______________________________________________________________________________
1065void AliITSUTrackerGlo::FinalizeHypotheses()
1066{
1067 // select winner for each hypothesis, remove cl. sharing conflicts
15b02d69 1068 AliDebug(2,"TODO");
3e4e3c23 1069 //
1070 int nh = fHypStore.GetEntriesFast();
1071 for (int ih=0;ih<nh;ih++) {
1072 AliITSUTrackHyp* hyp = (AliITSUTrackHyp*) fHypStore.UncheckedAt(ih);
69e0f089 1073 if (!hyp || !hyp->DefineWinner()) continue; // TODO
0ddbf657 1074 if (hyp->GetESDTrack()->IsOn(AliESDtrack::kITSin)) continue;
1075 fCountITSin++;
68a0f687 1076 CookMCLabel(hyp);
1077 UpdateESDTrack(hyp,AliESDtrack::kITSin);
3e4e3c23 1078 }
1079
1080}
c51c3124 1081
1082//______________________________________________________________________________
68a0f687 1083void AliITSUTrackerGlo::UpdateESDTrack(AliITSUTrackHyp* hyp,Int_t flag)
c51c3124 1084{
1085 // update ESD track with current best hypothesis
1086 AliESDtrack* esdTr = hyp->GetESDTrack();
1087 if (!esdTr) return;
1088 AliITSUSeed* win = hyp->GetWinner();
1089 if (!win) return;
68a0f687 1090 switch (flag) {
1091 case AliESDtrack::kITSin:
1092 esdTr->UpdateTrackParams(hyp,flag); // update kinematics
1093 // TODO: set cluster info
1094 break;
1095 //
1096 case AliESDtrack::kITSout:
1097 esdTr->UpdateTrackParams(hyp,flag); // update kinematics
1098 // TODO: avoid setting friend
1099 break;
1100 //
1101 case AliESDtrack::kITSrefit:
1102 esdTr->UpdateTrackParams(hyp,flag); // update kinematics
1103 // TODO: avoid setting cluster info
1104 break;
1105 default:
1106 AliFatal(Form("Unknown flag %d",flag));
1107 }
c51c3124 1108 //
1109 // transfer module indices
1110 // TODO
1111}
1112
1113//______________________________________________________________________________
68a0f687 1114Bool_t AliITSUTrackerGlo::RefitTrack(AliITSUTrackHyp* trc, Double_t rDest, Bool_t stopAtLastCl)
c51c3124 1115{
1116 // refit track till radius rDest
8b16dbae 1117 AliITSUTrackHyp tmpTr;
1118 //
c51c3124 1119 double rCurr = Sqrt(trc->GetX()*trc->GetX() + trc->GetY()*trc->GetY());
1120 int dir,lrStart,lrStop;
1121 //
8b16dbae 1122 dir = rCurr<rDest ? 1 : -1;
1123 lrStart = fITS->FindFirstLayerID(rCurr,dir);
1124 lrStop = fITS->FindLastLayerID(rDest,dir);
15b02d69 1125 if (AliDebugLevelClass()>2) {
1126 printf("Refit %d: Lr:%d (%f) -> Lr:%d (%f)\n",dir,lrStart,rCurr, lrStop,rDest);
1127 printf("Before refit: "); trc->AliExternalTrackParam::Print();
1128 }
8b16dbae 1129 if (lrStop<0 || lrStart<0) AliFatal(Form("Failed to find start(%d) or last(%d) layers. Track from %.3f to %.3f",lrStart,lrStop,rCurr,rDest));
1130 //
68a0f687 1131 int ncl = trc->FetchClusterInfo(fClInfo);
8b16dbae 1132 fCurrMass = trc->GetMass();
1133 tmpTr.AliKalmanTrack::operator=(*trc);
1134 tmpTr.SetChi2(0);
68a0f687 1135 int iclLr[2],nclLr,clCount=0;
c51c3124 1136 //
1137 for (int ilr=lrStart;ilr!=lrStop;ilr+=dir) {
1138 AliITSURecoLayer* lr = fITS->GetLayer(ilr);
1139 if ( dir*(rCurr-lr->GetR(dir))>0) continue; // this layer is already passed
8b16dbae 1140 int ilrA2,ilrA = lr->GetActiveID();
1141 // passive layer or active w/o hits will be traversed on the way to next cluster
1142 if (!lr->IsActive() || fClInfo[ilrA2=(ilrA<<1)]<0) continue;
1143 //
8b16dbae 1144 // select the order in which possible 2 clusters (in case of the overlap) will be traversed and fitted
1145 nclLr=0;
1146 if (dir>0) { // clusters are stored in increasing radius order
1147 iclLr[nclLr++]=fClInfo[ilrA2++];
1148 if (fClInfo[ilrA2]>=0) iclLr[nclLr++]=fClInfo[ilrA2];
1149 }
1150 else {
1151 if ( fClInfo[ilrA2+1]>=0 ) iclLr[nclLr++]=fClInfo[ilrA2+1];
1152 iclLr[nclLr++]=fClInfo[ilrA2];
1153 }
1154 //
b515ad7e 1155 Bool_t transportedToLayer = kFALSE;
8b16dbae 1156 for (int icl=0;icl<nclLr;icl++) {
1157 AliITSUClusterPix* clus = (AliITSUClusterPix*)lr->GetCluster(iclLr[icl]);
1158 AliITSURecoSens* sens = lr->GetSensorFromID(clus->GetVolumeId());
e7d83d38 1159 if (!tmpTr.Rotate(sens->GetPhiTF())) {
0ddbf657 1160 AliDebug(2,Form("Failed on rotate to %f | ESDtrack#%d (MClb:%d)",sens->GetPhiTF(),fCurrESDtrack->GetID(),fCurrESDtrMClb));
e7d83d38 1161 return kFALSE;
1162 }
b515ad7e 1163 //
1164 double xClus = sens->GetXTF()+clus->GetX();
1165 if (!transportedToLayer) {
1166 if (ilr!=lrStart && !TransportToLayerX(&tmpTr,lrStart,ilr,xClus)) {
1167 AliDebug(2,Form("Failed to transport %d -> %d | ESDtrack#%d (MClb:%d)\n",lrStart,ilr,fCurrESDtrack->GetID(),fCurrESDtrMClb));
1168 //tmpTr.AliExternalTrackParam::Print(); trc->GetWinner()->Print("etp");
1169 return kFALSE; // go to the entrance to the layer
1170 }
1171 lrStart = ilr;
1172 transportedToLayer = kTRUE;
1173 }
1174 //
1175 if (AliDebugLevelClass()>1) {
1176 AliDebug(2,Form("Propagate to cl:%d on lr %d Need to go %.4f -> %.4f",icl,ilrA,tmpTr.GetX(),xClus));
1177 // printf("Before: "); tmpTr.AliExternalTrackParam::Print();
1178 }
1179 //
1180 if (!PropagateSeed(&tmpTr,xClus,fCurrMass)) {
1181 AliDebug(2,Form("Failed on propagate to %f (dir=%d) | ESDtrack#%d (MClb:%d)",xClus,dir,fCurrESDtrack->GetID(),fCurrESDtrMClb));
1182 //tmpTr.AliExternalTrackParam::Print(""); trc->GetWinner()->Print("etp");
e7d83d38 1183 return kFALSE;
1184 }
76390254 1185 //
1186#ifdef _FILL_CONTROL_HISTOS_
1187 int hcOffs = fTrackPhase*kHistosPhase + ilrA;
1188 double htrPt=-1;
53870004 1189 if (fCHistoArr && trc->GetLabel()>=0/* && trc->Charge()>0*/) {
76390254 1190 htrPt = tmpTr.Pt();
1191 double dy = clus->GetY()-tmpTr.GetY();
1192 double dz = clus->GetZ()-tmpTr.GetZ();
53870004 1193 ((TH2*)fCHistoArr->At(kHResY+hcOffs))->Fill(htrPt,dy);
1194 ((TH2*)fCHistoArr->At(kHResZ+hcOffs))->Fill(htrPt,dz);
76390254 1195 double errY = tmpTr.GetSigmaY2();
1196 double errZ = tmpTr.GetSigmaZ2();
53870004 1197 if (errY>0) ((TH2*)fCHistoArr->At(kHResYP+hcOffs))->Fill(htrPt,dy/Sqrt(errY));
1198 if (errZ>0) ((TH2*)fCHistoArr->At(kHResZP+hcOffs))->Fill(htrPt,dz/Sqrt(errZ));
76390254 1199 }
1200#endif
1201 //
1202 double chi2;
1203 if ( (chi2=tmpTr.Update(clus))<0 ) {
0ddbf657 1204 AliDebug(2,Form("Failed on Update | ESDtrack#%d (MClb:%d)",fCurrESDtrack->GetID(),fCurrESDtrMClb));
e7d83d38 1205 return kFALSE;
1206 }
76390254 1207#ifdef _FILL_CONTROL_HISTOS_
1208 if (htrPt>0) {
53870004 1209 ((TH2*)fCHistoArr->At(kHChi2Cl+hcOffs))->Fill(htrPt,chi2);
76390254 1210 }
1211#endif
b515ad7e 1212 if (AliDebugLevelClass()>1) {
1213 printf("AfterRefit: "); tmpTr.AliExternalTrackParam::Print();
1214 }
68a0f687 1215 if (stopAtLastCl && ++clCount==ncl) return kTRUE; // it was requested to not propagate after last update
8b16dbae 1216 }
c51c3124 1217 //
1218 }
8b16dbae 1219 // All clusters were succesfully fitted. Even if the track does not reach rDest, this is enough to validate it.
1220 // Still, try to go as close as possible to rDest.
1221 //
1222 if (lrStart!=lrStop) {
e7d83d38 1223 //printf("Going to last layer %d -> %d\n",lrStart,lrStop);
1224 if (!TransportToLayer(&tmpTr,lrStart,lrStop)) {
0ddbf657 1225 AliDebug(1,Form("Failed on TransportToLayer %d->%d | ESDtrack#%d (MClb:%d)",lrStart,lrStop,fCurrESDtrack->GetID(),fCurrESDtrMClb));
1226 //tmpTr.AliExternalTrackParam::Print();
1227 //trc->GetWinner()->Print("etp");
e7d83d38 1228 return kTRUE;
1229 }
1230 if (!GoToExitFromLayer(&tmpTr,fITS->GetLayer(lrStop),dir)) {
0ddbf657 1231 AliDebug(3,Form("Failed on GoToExitFromLayer %d | ESDtrack#%d (MClb:%d)",lrStop,fCurrESDtrack->GetID(),fCurrESDtrMClb));
e7d83d38 1232 return kTRUE; // go till the exit from layer
1233 }
e2d2481c 1234 //
e7d83d38 1235 //printf("On exit from last layer\n");
15b02d69 1236 //tmpTr.AliExternalTrackParam::Print();
e2d2481c 1237 // go to the destination radius
1238 if (!tmpTr.GetXatLabR(rDest,rDest,GetBz(),dir)) return kTRUE;
1239 if (!PropagateSeed(&tmpTr,rDest,fCurrMass, 100, kFALSE)) return kTRUE;
8b16dbae 1240 }
1241 trc->AliKalmanTrack::operator=(tmpTr);
15b02d69 1242 if (AliDebugLevelClass()>2) {
b515ad7e 1243 printf("After refit (now at lr %d): ",lrStop); trc->AliExternalTrackParam::Print();
15b02d69 1244 }
8b16dbae 1245 return kTRUE;
c51c3124 1246}
dd2117a2 1247
1248//__________________________________________________________________
1249void AliITSUTrackerGlo::CookMCLabel(AliITSUTrackHyp* hyp)
1250{
1251 // build MC label
1252 //
1253 const int kMaxLbPerCl = 3;
1254 int lbID[kMaxLayers*6],lbStat[kMaxLayers*6];
1255 Int_t lr,nLab=0,nCl=0;
1256 AliITSUSeed *seed = hyp->GetWinner();
1257 while(seed) {
1258 int clID = seed->GetLrCluster(lr);
1259 if (clID>=0) {
1260 AliCluster *cl = fITS->GetLayerActive(lr)->GetCluster(clID);
1261 nCl++;
1262 for (int imc=0;imc<kMaxLbPerCl;imc++) { // labels within single cluster
1263 int trLb = cl->GetLabel(imc);
704d9398 1264 if (trLb<0) break;
dd2117a2 1265 // search this mc track in already accounted ones
1266 int iLab;
1267 for (iLab=0;iLab<nLab;iLab++) if (lbID[iLab]==trLb) break;
1268 if (iLab<nLab) lbStat[iLab]++;
1269 else {
1270 lbID[nLab] = trLb;
1271 lbStat[nLab++] = 1;
1272 }
1273 } // loop over given cluster's labels
1274 }
1275 seed = (AliITSUSeed*)seed->GetParent();
1276 } // loop over clusters
1277 //
5785a9d8 1278 AliESDtrack* esdTr = hyp->GetESDTrack();
1279 int tpcLab = esdTr ? Abs(esdTr->GetTPCLabel()) : -kDummyLabel;
41343470 1280 if (nCl && nLab) {
dd2117a2 1281 int maxLab=0,nTPCok=0;
dd2117a2 1282 for (int ilb=nLab;ilb--;) {
1283 int st = lbStat[ilb];
1284 if (lbStat[maxLab]<st) maxLab=ilb;
1285 if (tpcLab==lbID[ilb]) nTPCok += st;
1286 }
1287 hyp->SetFakeRatio(1.-float(nTPCok)/nCl);
1288 hyp->SetLabel( nTPCok==nCl ? tpcLab : -tpcLab);
1289 hyp->SetITSLabel( lbStat[maxLab]==nCl ? lbStat[maxLab] : -lbStat[maxLab]); // winner label
1290 return;
1291 }
1292 //
1293 hyp->SetFakeRatio(-1.);
5785a9d8 1294 hyp->SetLabel( -tpcLab );
dd2117a2 1295 hyp->SetITSLabel( kDummyLabel );
1296}
38997c3c 1297
1298//__________________________________________________________________
1299Bool_t AliITSUTrackerGlo::AddSeedBranch(AliITSUSeed* seed)
1300{
1301 // add new prolongation branch for the seed to temporary array. The seeds are sorted according to Compare f-n
1302 if (fNCandidatesAdded+fNBranchesAdded>=AliITSUTrackCond::kMaxCandidates ) {
1303 AliError(Form("Number of candidates for current seed reached limit of AliITSUTrackCond::kMaxCandidates=%d, increase it",AliITSUTrackCond::kMaxCandidates));
1304 return kFALSE;
1305 }
1306 AliITSUSeed** branches = &fLayerCandidates[fNCandidatesAdded]; // note: fNCandidatesAdded is incremented after adding all branches of current seed
1307 int slot=fNBranchesAdded++;
1308 for (int slotF=slot;slotF--;) { // slotF is always slot-1
1309 AliITSUSeed* si = branches[slotF];
1310 if (si->Compare(seed)<0) break; // found the last seed with better quality
1311 // otherwise, shift the worse seed to the next slot
1312 branches[slot] = si;
1313 slot = slotF; // slot should be slotF+1
1314 }
1315 // if needed, move worse seeds
1316 branches[slot] = seed;
1317 return kTRUE;
1318 //
1319}
1320
1321//__________________________________________________________________
1322void AliITSUTrackerGlo::ValidateAllowedBranches(Int_t acceptMax)
1323{
1324 // keep allowed number of branches for current seed and disable extras
1325 int nb = Min(fNBranchesAdded,acceptMax);
1326 // if (nb<fNBranchesAdded) printf("ValidateAllowedBranches: %d of %d (%d) on lr %d\n",nb,fNBranchesAdded,fNCandidatesAdded,ilr);
1327 // disable unused branches
1328 AliITSUSeed** branches = &fLayerCandidates[fNCandidatesAdded];
1329 for (int ib=nb;ib<fNBranchesAdded;ib++) {
1330 /*
1331 if (!branches[ib]->ContainsFake()) {
1332 printf("Suppress good branch as %d of %d |",ib,fNBranchesAdded); branches[ib]->Print();
1333 printf("Survivors : \n");
1334 for (int j=0;j<nb;j++) branches[j]->Print();
1335 }
1336 */
1337 MarkSeedFree(branches[ib]);
1338 }
1339 fNCandidatesAdded += nb; // update total candidates counter
1340 fNBranchesAdded = 0; // reset branches counter
1341 //
1342}
1343
1344//__________________________________________________________________
1345void AliITSUTrackerGlo::ValidateAllowedCandidates(Int_t ilr, Int_t acceptMax)
1346{
1347 // transfer allowed number of branches to hypothesis container
1348 //
1349 // sort candidates in increasing order of chi2
1350 Int_t index[AliITSUTrackCond::kMaxCandidates];
1351 Float_t chi2[AliITSUTrackCond::kMaxCandidates];
1352 for (int i=fNCandidatesAdded;i--;) chi2[i] = fLayerCandidates[i]->GetChi2GloNrm();
1353 Sort(fNCandidatesAdded,chi2,index,kFALSE);
1354 //
1355 int nb = Min(fNCandidatesAdded,acceptMax);
1356 // if (nb<fNCandidatesAdded) printf("ValidateAllowedCandidates: %d of %d on lr %d\n",nb,fNCandidatesAdded,ilr);
1357 //
1358 for (int ib=0;ib<nb;ib++) AddProlongationHypothesis(fLayerCandidates[index[ib]],ilr);
1359 // disable unused candidates
1360 for (int ib=nb;ib<fNCandidatesAdded;ib++) {
1361 /*
1362 if (!fLayerCandidates[index[ib]]->ContainsFake()) {
1363 printf("Suppress good candidate as %d of %d |",index[ib],fNCandidatesAdded); fLayerCandidates[index[ib]]->Print();
1364 }
1365 */
1366 MarkSeedFree(fLayerCandidates[index[ib]]);
1367 }
1368 fNCandidatesAdded = 0; // reset candidates counter
1369 //
1370}
1371
53870004 1372//__________________________________________________________________
1373void AliITSUTrackerGlo::FlagSplitClusters()
1374{
1375 // set special bit on split clusters using MC info
1376 for (int ilr=fITS->GetNLayersActive();ilr--;) {
1377 int nsplit=0;
1378 AliITSURecoLayer* lr = fITS->GetLayerActive(ilr);
1379 for (int isn=lr->GetNSensors();isn--;) {
1380 AliITSURecoSens* sens = lr->GetSensor(isn);
1381 int nCl = sens->GetNClusters();
1382 if (!nCl) continue;
1383 int cl0 = sens->GetFirstClusterId();
1384 for (int icl=nCl;icl--;) {
1385 AliITSUClusterPix *cl = (AliITSUClusterPix*)lr->GetCluster(cl0+icl);
1386 for (int icl1=icl;icl1--;) {
1387 AliITSUClusterPix *cl1 = (AliITSUClusterPix*)lr->GetCluster(cl0+icl1);
1388 if (cl->HasCommonTrack(cl1)) {
1389 if (!cl->IsSplit()) nsplit++;
1390 if (!cl1->IsSplit()) nsplit++;
1391 cl->SetSplit();
1392 cl1->SetSplit();
1393 }
1394 }
1395 }
1396 }
1397 AliInfo(Form("%4d out of %4d clusters are split",nsplit,lr->GetNClusters()));
1398 }
1399 //
1400}
1401
1402//__________________________________________________________________
1403Bool_t AliITSUTrackerGlo::ContainsSplitCluster(const AliITSUSeed* seed, Int_t maxSize)
1404{
1405 // check if the seed contains split cluster with size < maxSize
1406 int lrID,clID;
1407 if ( (clID=seed->GetLrCluster(lrID))>=0 ) {
1408 AliITSUClusterPix* cl = (AliITSUClusterPix*)fITS->GetLayerActive(lrID)->GetCluster(clID);
1409 if (cl->IsSplit() && cl->GetNPix()<maxSize ) return kTRUE;
1410 }
1411 return seed->GetParent() ? ContainsSplitCluster((AliITSUSeed*)seed->GetParent(),maxSize) : kFALSE;
1412 //
1413}
1414
1415//__________________________________________________________________
1416void AliITSUTrackerGlo::PrintSeedClusters(const AliITSUSeed* seed, Option_t* option)
1417{
1418 // print seeds clusters
1419 int lrID,clID;
1420 if ( (clID=seed->GetLrCluster(lrID))>=0 ) {
1421 AliITSUClusterPix* cl = (AliITSUClusterPix*)fITS->GetLayerActive(lrID)->GetCluster(clID);
1422 cl->Print(option);
1423 }
1424 if (seed->GetParent()) PrintSeedClusters((AliITSUSeed*)seed->GetParent(), option);
1425 //
1426}
1427
1428#ifdef _FILL_CONTROL_HISTOS_
1429//__________________________________________________________________
1430void AliITSUTrackerGlo::BookControlHistos()
1431{
1432 // book special control histos
1433 if (!fCHistoArr) { // create control histos
1434 const int kNResDef=7;
1435 const double kResDef[kNResDef]={0.05,0.05,0.3, 0.05,1,0.5,1.5};
1436 fCHistoArr = new TObjArray();
1437 fCHistoArr->SetOwner(kTRUE);
1438 const double ptMax=10;
1439 const double plMax=10;
1440 const double chiMax=100;
1441 const int nptbins=50;
1442 const int nresbins=400;
1443 const int nplbins=50;
1444 const int nchbins=200;
1445 int nblr = fITS->GetNLayersActive();
1446 TString ttl;
1447 for (int stp=0;stp<kNTrackingPhases;stp++) {
1448 for (int ilr=0;ilr<nblr;ilr++) {
1449 int hoffs = stp*kHistosPhase + ilr;
1450 double mxdf = ilr>=kNResDef ? kResDef[kNResDef-1] : kResDef[ilr];
1451 ttl = Form("S%d_residY%d",stp,ilr);
1452 TH2F* hdy = new TH2F(ttl.Data(),ttl.Data(),nptbins,0,ptMax,nresbins,-mxdf,mxdf);
1453 fCHistoArr->AddAtAndExpand(hdy,hoffs + kHResY);
1454 hdy->SetDirectory(0);
1455 //
1456 ttl = Form("S%d_residYPull%d",stp,ilr);
1457 TH2F* hdyp = new TH2F(ttl.Data(),ttl.Data(),nptbins,0,ptMax,nplbins,-plMax,plMax);
1458 fCHistoArr->AddAtAndExpand(hdyp,hoffs + kHResYP);
1459 hdyp->SetDirectory(0);
1460 //
1461 ttl = Form("S%d_residZ%d",stp,ilr);
1462 TH2F* hdz = new TH2F(ttl.Data(),ttl.Data(),nptbins,0,ptMax,nresbins,-mxdf,mxdf);
1463 fCHistoArr->AddAtAndExpand(hdz,hoffs + kHResZ);
1464 hdz->SetDirectory(0);
1465 //
1466 ttl = Form("S%d_residZPull%d",stp,ilr);
1467 TH2F* hdzp = new TH2F(ttl.Data(),ttl.Data(),nptbins,0,ptMax,nplbins,-plMax,plMax);
1468 hdzp->SetDirectory(0);
1469 fCHistoArr->AddAtAndExpand(hdzp,hoffs + kHResZP);
1470 //
1471 ttl = Form("S%d_chi2Cl%d",stp,ilr);
1472 TH2F* hchi = new TH2F(ttl.Data(),ttl.Data(),nptbins,0,ptMax, nchbins,0.,chiMax);
1473 hchi->SetDirectory(0);
1474 fCHistoArr->AddAtAndExpand(hchi,hoffs + kHChi2Cl);
1475 }
1476 }
1477 }
1478 //
1479}
1480#endif