1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
22 //-------------------------------------------------------------------------
23 // Implementation of the ITS Upgrade tracker mother class.
24 //-------------------------------------------------------------------------
26 #include <Riostream.h>
29 #include "AliITSUTrackerGlo.h"
30 #include "AliESDEvent.h"
31 #include "AliESDtrack.h"
32 #include "AliITSURecoDet.h"
33 #include "AliITSURecoSens.h"
34 #include "AliITSUReconstructor.h"
35 #include "AliITSReconstructor.h"
36 #include "AliITSUSeed.h"
37 #include "AliITSUAux.h"
38 #include "AliITSUClusterPix.h"
39 using namespace AliITSUAux;
40 using namespace TMath;
43 //----------------- tmp stuff -----------------
47 ClassImp(AliITSUTrackerGlo)
48 //_________________________________________________________________________
49 AliITSUTrackerGlo::AliITSUTrackerGlo(AliITSUReconstructor* rec)
55 ,fSeedsPool("AliITSUSeed",0)
58 // Default constructor
62 //_________________________________________________________________________
63 AliITSUTrackerGlo::~AliITSUTrackerGlo()
72 //_________________________________________________________________________
73 void AliITSUTrackerGlo::Init(AliITSUReconstructor* rec)
75 // init with external reconstructor
77 fITS = new AliITSURecoDet(rec->GetGeom(),"ITSURecoInterface");
78 for (int ilr=fITS->GetNLayersActive();ilr--;) {
79 fITS->GetLayerActive(ilr)->SetClusters(rec->GetClusters(ilr));
82 fSeedsPool.ExpandCreateFast(1000); // RS TOCHECK
83 int n = fITS->GetNLayersActive()+1;
84 fSeedsLr = new TObjArray[n];
86 fTrCond.SetNLayers(fITS->GetNLayersActive());
87 fTrCond.AddNewCondition(5);
88 fTrCond.AddGroupPattern( (0x1<<0)|(0x1<<1) );
89 fTrCond.AddGroupPattern( (0x1<<3)|(0x1<<4) );
90 fTrCond.AddGroupPattern( (0x1<<5)|(0x1<<6) );
92 fTrCond.AddNewCondition(5);
93 fTrCond.AddGroupPattern( (0x1<<0)|(0x1<<2) );
94 fTrCond.AddGroupPattern( (0x1<<3)|(0x1<<4) );
95 fTrCond.AddGroupPattern( (0x1<<5)|(0x1<<6) );
97 fTrCond.AddNewCondition(5);
98 fTrCond.AddGroupPattern( (0x1<<1)|(0x1<<2) );
99 fTrCond.AddGroupPattern( (0x1<<3)|(0x1<<4) );
100 fTrCond.AddGroupPattern( (0x1<<5)|(0x1<<6) );
102 printf("Tracking Conditions: ");
106 //_________________________________________________________________________
107 Int_t AliITSUTrackerGlo::Clusters2Tracks(AliESDEvent *esdEv)
111 AliITSUReconstructor::GetRecoParam()->Print();
113 fITS->ProcessClusters();
114 // select ESD tracks to propagate
115 int nTrESD = esdEv->GetNumberOfTracks();
116 for (int itr=0;itr<nTrESD;itr++) {
117 AliESDtrack *esdTr = esdEv->GetTrack(itr);
118 AliInfo(Form("Processing track %d | MCLabel: %d",itr,esdTr->GetTPCLabel()));
119 currLabel = Abs(esdTr->GetTPCLabel());
126 //_________________________________________________________________________
127 Int_t AliITSUTrackerGlo::PropagateBack(AliESDEvent * /*event*/)
133 Info("PropagateBack","To be implemented");
137 //_________________________________________________________________________
138 Int_t AliITSUTrackerGlo::RefitInward(AliESDEvent * /*event*/)
144 Info("RefitInward","To be implemented");
148 //_________________________________________________________________________
149 Int_t AliITSUTrackerGlo::LoadClusters(TTree * treeRP)
151 // read from tree (if pointer provided) or directly from the ITS reco interface
153 return fReconstructor->LoadClusters(treeRP);
156 //_________________________________________________________________________
157 void AliITSUTrackerGlo::UnloadClusters()
163 Info("UnloadClusters","To be implemented");
165 //_________________________________________________________________________
166 AliCluster * AliITSUTrackerGlo::GetCluster(Int_t /*index*/) const
172 Info("GetCluster","To be implemented");
176 //_________________________________________________________________________
177 Bool_t AliITSUTrackerGlo::NeedToProlong(AliESDtrack* esdTr)
179 // do we need to match this track to ITS?
181 static double bz = GetBz();
182 if (!esdTr->IsOn(AliESDtrack::kTPCin) ||
183 esdTr->IsOn(AliESDtrack::kTPCout) ||
184 esdTr->IsOn(AliESDtrack::kITSin) ||
185 esdTr->GetKinkIndex(0)>0) return kFALSE;
187 if (esdTr->Pt()<AliITSUReconstructor::GetRecoParam()->GetMinPtForProlongation()) return kFALSE;
190 esdTr->GetDZ(GetX(),GetY(),GetZ(),bz,dtz);
191 // if track is not V0 candidata but has large offset wrt IP, reject it. RS TOCHECK
192 if ( !(esdTr->GetV0Index(0)>0 && dtz[0]>AliITSUReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation())
193 && (Abs(dtz[0])>AliITSUReconstructor::GetRecoParam()->GetMaxDForProlongation() ||
194 Abs(dtz[1])>AliITSUReconstructor::GetRecoParam()->GetMaxDZForProlongation())) return kFALSE;
199 //_________________________________________________________________________
200 void AliITSUTrackerGlo::FindTrack(AliESDtrack* esdTr)
202 // find prolongaion candidates finding for single seed
204 if (!NeedToProlong(esdTr)) return; // are we interested in this track?
205 if (!InitSeed(esdTr)) return; // initialize prolongations hypotheses tree
207 AliITSURecoSens *hitSens[AliITSURecoSens::kNNeighbors+1];
208 AliITSUSeed seedUC; // copy of the seed from the upper layer
209 AliITSUSeed seedT; // transient seed between the seedUC and new prolongation hypothesis
211 TObjArray clArr; // container for transfer of clusters matching to seed
213 for (int ila=fITS->GetNLayersActive();ila--;) {
214 int ilaUp = ila+1; // prolong seeds from layer above
215 int nSeedsUp = GetNSeeds(ilaUp);
216 for (int isd=0;isd<nSeedsUp;isd++) {
217 AliITSUSeed* seedU = GetSeed(ilaUp,isd); // seed on prev.active layer to prolong
218 seedUC = *seedU; // its copy will be prolonged
219 seedUC.SetParent(seedU);
220 seedUC.ResetFMatrix(); // reset the matrix for propagation to next layer
221 // go till next active layer
222 AliInfo(Form("working on Lr:%d Seed:%d of %d",ila,isd,nSeedsUp));
223 if (!TransportToLayer(&seedUC, fITS->GetLrIDActive(ilaUp), fITS->GetLrIDActive(ila)) ) {
225 AliInfo("Transport failed");
226 // Check if the seed satisfies to track definition
227 if (NeedToKill(&seedUC,kTransportFailed)) seedU->Kill();
228 continue; // RS TODO: decide what to do with tracks stopped on higher layers w/o killing
230 AliITSURecoLayer* lrA = fITS->GetLayerActive(ila);
231 if (!GetRoadWidth(&seedUC, ila)) { // failed to find road width on the layer
232 if (NeedToKill(&seedUC,kRWCheckFailed)) seedU->Kill();
235 int nsens = lrA->FindSensors(&fTrImpData[kTrPhi0], hitSens); // find detectors which may be hit by the track
236 AliInfo(Form("Will check %d sensors on lr:%d ",nsens,ila));
239 for (int isn=nsens;isn--;) {
241 AliITSURecoSens* sens = hitSens[isn];
243 // We need to propagate the seed to sensor on lrA staying the frame of the sensor from prev.layer,
244 // since the transport matrix should be defined in this frame.
245 double xs; // X in the TF of current seed, corresponding to intersection with sensor plane
246 if (!seedT.GetTrackingXAtXAlpha(sens->GetXTF(),sens->GetPhiTF(),bz, xs)) continue;
247 if (!seedT.PropagateToX(xs,bz)) continue;
248 if (!seedT.Rotate(sens->GetPhiTF())) continue;
250 int clID0 = sens->GetFirstClusterId();
251 for (int icl=sens->GetNClusters();icl--;) {
252 int res = CheckCluster(&seedT,ila,clID0+icl);
254 if (res==kStopSearchOnSensor) break; // stop looking on this sensor
255 if (res==kClusterNotMatching) continue; // cluster does not match
256 // cluster is matching and it was added to the hypotheses tree
259 // cluster search is done. Do we need ta have a version of this seed skipping current layer
261 if (!NeedToKill(&seedT,kMissingCluster)) AddProlongationHypothesis(NewSeedFromPool(&seedT) ,ila);
263 printf(">>> All hypotheses on lr %d: \n",ila);
264 for (int ih=0;ih<GetNSeeds(ila);ih++) {
265 printf(" #%3d ",ih); GetSeed(ila,ih)->Print();
272 //_________________________________________________________________________
273 Bool_t AliITSUTrackerGlo::InitSeed(AliESDtrack *esdTr)
275 // init prolongaion candidates finding for single seed
276 fCurrMass = esdTr->GetMass();
277 fCurrESDtrack = esdTr;
278 if (fCurrMass<kPionMass*0.9) fCurrMass = kPionMass; // don't trust to mu, e identification from TPCin
281 AliITSUSeed* seed = NewSeedFromPool();
282 seed->SetLr(fITS->GetNLayersActive()); // fake layer
283 seed->AliExternalTrackParam::operator=(*esdTr);
284 seed->SetParent(esdTr);
285 AddProlongationHypothesis(seed,fITS->GetNLayersActive());
290 //_________________________________________________________________________
291 void AliITSUTrackerGlo::ResetSeedTree()
293 // reset current hypotheses tree
294 for (int i=fITS->GetNLayersActive()+1;i--;) fSeedsLr[i].Clear();
297 //_________________________________________________________________________
298 Bool_t AliITSUTrackerGlo::TransportToLayer(AliITSUSeed* seed, Int_t lFrom, Int_t lTo)
300 // transport seed from layerFrom to the entrance of layerTo
302 const double kToler = 1e-6; // tolerance for layer on-surface check
304 int dir = lTo > lFrom ? 1:-1;
305 AliITSURecoLayer* lrFr = fITS->GetLayer(lFrom); // this can be 0 when extrapolation from TPC to ITS is requested
306 Bool_t checkFirst = kTRUE;
308 double curR2 = seed->GetX()*seed->GetX() + seed->GetY()*seed->GetY(); // current radius
310 Bool_t doLayer = kTRUE;
311 double xToGo = dir>0 ? lrFr->GetRMax() : lrFr->GetRMin();
312 if (checkFirst) { // do we need to track till the surface of the current layer ?
314 if (dir>0) { if (curR2-xToGo*xToGo>kToler) doLayer = kFALSE; } // on the surface or outside of the layer
315 else if (dir<0) { if (xToGo*xToGo-curR2>kToler) doLayer = kFALSE; } // on the surface or outside of the layer
318 if (!seed->GetXatLabR(xToGo,xToGo,GetBz(),dir)) return kFALSE;
319 // go via layer to its boundary, applying material correction.
320 if (!PropagateSeed(seed,xToGo,fCurrMass, lrFr->GetMaxStep())) return kFALSE;
323 AliITSURecoLayer* lrTo = fITS->GetLayer( (lFrom+=dir) );
324 if (!lrTo) AliFatal(Form("Layer %d does not exist",lFrom));
326 // go the entrance of the layer, assuming no materials in between
327 double xToGo = dir>0 ? lrTo->GetRMin() : lrTo->GetRMax();
328 if (!seed->GetXatLabR(xToGo,xToGo,GetBz(),dir)) return kFALSE;
329 if (!PropagateSeed(seed,xToGo,fCurrMass,100, kFALSE )) return kFALSE;
336 //_________________________________________________________________________
337 Bool_t AliITSUTrackerGlo::GetRoadWidth(AliITSUSeed* seed, int ilrA)
339 // calculate road width in terms of phi and z for the track which MUST be on the external radius of the layer
340 // as well as some aux info
342 AliITSURecoLayer* lrA = fITS->GetLayerActive(ilrA);
343 seed->GetXYZ(&fTrImpData[kTrXIn]); // lab position at the entrance from above
344 static AliExternalTrackParam sc; // seed copy for manipalitions
347 fTrImpData[kTrPhiIn] = ATan2(fTrImpData[kTrYIn],fTrImpData[kTrXIn]);
348 if (!sc.Rotate(fTrImpData[kTrPhiIn])) return kFALSE; // go to the frame of the entry point into the layer
349 double dr = lrA->GetDR(); // approximate X dist at the inner radius
350 if (!sc.GetXYZAt(sc.GetX()-dr, bz, fTrImpData + kTrXOut)) {
351 // special case: track does not reach inner radius, might be tangential
352 double r = sc.GetD(0,0,bz);
354 if (!sc.GetXatLabR(r,x,bz,-1)) {
356 AliFatal(Form("This should not happen: r=%f",r));
358 dr = Abs(sc.GetX() - x);
359 if (!sc.GetXYZAt(x, bz, fTrImpData + kTrXOut)) {
361 AliFatal(Form("This should not happen: x=%f",x));
365 fTrImpData[kTrPhiOut] = ATan2(fTrImpData[kTrYOut],fTrImpData[kTrXOut]);
366 double sgy = sc.GetSigmaY2() + dr*dr*sc.GetSigmaSnp2() + AliITSUReconstructor::GetRecoParam()->GetSigmaY2(ilrA);
367 double sgz = sc.GetSigmaZ2() + dr*dr*sc.GetSigmaTgl2() + AliITSUReconstructor::GetRecoParam()->GetSigmaZ2(ilrA);
368 sgy = Sqrt(sgy)*AliITSUReconstructor::GetRecoParam()->GetNSigmaRoadY();
369 sgz = Sqrt(sgz)*AliITSUReconstructor::GetRecoParam()->GetNSigmaRoadZ();
370 fTrImpData[kTrPhi0] = 0.5*(fTrImpData[kTrPhiOut]+fTrImpData[kTrPhiIn]);
371 fTrImpData[kTrZ0] = 0.5*(fTrImpData[kTrZOut]+fTrImpData[kTrZIn]);
372 fTrImpData[kTrDPhi] = 0.5*Abs(fTrImpData[kTrPhiOut]-fTrImpData[kTrPhiIn]) + sgy/lrA->GetR();
373 fTrImpData[kTrDZ] = 0.5*Abs(fTrImpData[kTrZOut]-fTrImpData[kTrZIn]) + sgz;
378 //_________________________________________________________________________
379 AliITSUSeed* AliITSUTrackerGlo::NewSeedFromPool(const AliITSUSeed* src)
381 // create new seed, optionally copying from the source
383 new(fSeedsPool[fSeedsPool.GetEntriesFast()]) AliITSUSeed(*src) :
384 new(fSeedsPool[fSeedsPool.GetEntriesFast()]) AliITSUSeed();
387 //_________________________________________________________________________
388 Int_t AliITSUTrackerGlo::CheckCluster(AliITSUSeed* track, Int_t lr, Int_t clID)
390 // Check if the cluster (in tracking frame!) is matching to track.
391 // The track must be already propagated to sensor tracking frame.
392 // Returns: kStopSearchOnSensor if the search on given sensor should be stopped,
393 // kClusterMatching if the cluster is matching
394 // kClusterMatching otherwise
396 const double kTolerX = 5e-4;
397 AliCluster *cl = fITS->GetLayerActive(lr)->GetCluster(clID);
399 Bool_t goodCl = kFALSE;
400 for (int i=0;i<3;i++) if (cl->GetLabel(i)>=0 && cl->GetLabel(i)==currLabel) goodCl = kTRUE;
402 if (TMath::Abs(cl->GetX())>kTolerX) { // if due to the misalingment X is large, propagate track only
403 if (!track->PropagateParamOnlyTo(track->GetX()+cl->GetX(),GetBz())) {
404 if (goodCl) {printf("Loose good cl: Failed propagation. |"); cl->Print();}
405 return kStopSearchOnSensor; // propagation failed, seedT is intact
408 double dy = cl->GetY()-track->GetY();
409 double dz = cl->GetZ()-track->GetZ();
412 double tol2 = (track->GetSigmaY2() + AliITSUReconstructor::GetRecoParam()->GetSigmaY2(lr))*
413 AliITSUReconstructor::GetRecoParam()->GetNSigmaRoadY()*AliITSUReconstructor::GetRecoParam()->GetNSigmaRoadY(); // RS TOOPTIMIZE
414 if (dy2>tol2) { // the clusters are sorted in Z(col) then in Y(row).
415 if (goodCl) {printf("Loose good cl: dy2=%e > tol2=%e |",dy2,tol2); cl->Print();}
416 if (dy>0) return kStopSearchOnSensor; // No chance that other cluster of this sensor will match (all Y's will be even larger)
417 else return kClusterNotMatching; // Other clusters may match
420 tol2 = (track->GetSigmaZ2() + AliITSUReconstructor::GetRecoParam()->GetSigmaZ2(lr))*
421 AliITSUReconstructor::GetRecoParam()->GetNSigmaRoadZ()*AliITSUReconstructor::GetRecoParam()->GetNSigmaRoadZ(); // RS TOOPTIMIZE
423 if (goodCl) {printf("Loose good cl: dz2=%e > tol2=%e |",dz2,tol2); cl->Print();}
424 return kClusterNotMatching; // Other clusters may match
428 Double_t p[2]={cl->GetY(), cl->GetZ()};
429 Double_t cov[3]={cl->GetSigmaY2(), cl->GetSigmaYZ(), cl->GetSigmaZ2()};
430 double chi2 = track->GetPredictedChi2(p,cov);
431 if (chi2>AliITSUReconstructor::GetRecoParam()->GetMaxTr2ClChi2(lr)) {
433 printf("Loose good cl: Chi2=%e > Chi2Max=%e \n",chi2,AliITSUReconstructor::GetRecoParam()->GetMaxTr2ClChi2(lr));
437 return kClusterNotMatching;
440 track = NewSeedFromPool(track); // input track will be reused, use its clone for updates
441 if (!track->Update()) {
442 if (goodCl) {printf("Loose good cl: Failed update |"); cl->Print();}
443 return kClusterNotMatching;
445 track->SetChi2Cl(chi2);
446 track->SetLrClusterID(lr,clID);
447 cl->IncreaseClusterUsage();
449 AliInfo(Form("AddCl Cl%d lr:%d: dY:%+8.4f dZ:%+8.4f (MC: %5d %5d %5d) |Chi2=%f",clID,lr,dy,dz2,cl->GetLabel(0),cl->GetLabel(1),cl->GetLabel(2), chi2));
451 AddProlongationHypothesis(track,lr);
453 return kClusterMatching;
456 //_________________________________________________________________________
457 Bool_t AliITSUTrackerGlo::NeedToKill(AliITSUSeed *seed, Int_t flag)
459 // check if the seed should not be discarded
460 const UShort_t kMask = 0xffff;
461 if (flag==kMissingCluster) {
462 int lastChecked = seed->GetLayerID();
463 UShort_t patt = seed->GetHitsPattern();
464 if (lastChecked) patt |= ~(kMask<<lastChecked); // not all layers were checked, complete unchecked once by potential hits
465 Bool_t seedOK = fTrCond.CheckPattern(patt);
471 //______________________________________________________________________________
472 Bool_t AliITSUTrackerGlo::PropagateSeed(AliITSUSeed *seed, Double_t xToGo, Double_t mass, Double_t maxStep, Bool_t matCorr)
474 // propagate seed to given x applying material correction if requested
475 const Double_t kEpsilon = 1e-5;
476 Double_t xpos = seed->GetX();
477 Int_t dir = (xpos<xToGo) ? 1:-1;
478 Double_t xyz0[3],xyz1[3],param[7];
480 if (matCorr) seed->GetXYZ(xyz1); //starting global position
481 while ( (xToGo-xpos)*dir > kEpsilon){
482 Double_t step = dir*TMath::Min(TMath::Abs(xToGo-xpos), maxStep);
483 Double_t x = xpos+step;
484 Double_t bz=GetBz(); // getting the local Bz
485 if (!seed->PropagateToX(x,bz)) return kFALSE;
487 xyz0[0]=xyz1[0]; // global pos at the beginning of step
490 seed->GetXYZ(xyz1); // // global pos at the end of step
491 MeanMaterialBudget(xyz0,xyz1,param);
492 Double_t xrho=param[0]*param[4], xx0=param[1];
493 if (dir>0) xrho = -xrho; // outward should be negative
494 if (!seed->ApplyMaterialCorrection(xx0,xrho,mass,kFALSE)) return kFALSE;