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 ClassImp(AliITSUTrackerGlo)
44 //_________________________________________________________________________
45 AliITSUTrackerGlo::AliITSUTrackerGlo(AliITSUReconstructor* rec)
50 ,fSeedsPool("AliITSUSeed",0)
52 // Default constructor
56 //_________________________________________________________________________
57 AliITSUTrackerGlo::~AliITSUTrackerGlo()
66 //_________________________________________________________________________
67 void AliITSUTrackerGlo::Init(AliITSUReconstructor* rec)
69 // init with external reconstructor
71 fITS = new AliITSURecoDet(rec->GetGeom(),"ITSURecoInterface");
72 for (int ilr=fITS->GetNLayersActive();ilr--;) {
73 fITS->GetLayerActive(ilr)->SetClusters(rec->GetClusters(ilr));
76 fSeedsPool.ExpandCreateFast(1000); // RS TOCHECK
77 int n = fITS->GetNLayersActive()+1;
78 fSeedsLr = new TObjArray[n];
83 //_________________________________________________________________________
84 Int_t AliITSUTrackerGlo::Clusters2Tracks(AliESDEvent *esdEv)
88 fITS->ProcessClusters();
89 // select ESD tracks to propagate
90 int nTrESD = esdEv->GetNumberOfTracks();
91 for (int itr=0;itr<nTrESD;itr++) {
92 AliESDtrack *esdTr = esdEv->GetTrack(itr);
99 //_________________________________________________________________________
100 Int_t AliITSUTrackerGlo::PropagateBack(AliESDEvent * /*event*/)
106 Info("PropagateBack","To be implemented");
110 //_________________________________________________________________________
111 Int_t AliITSUTrackerGlo::RefitInward(AliESDEvent * /*event*/)
117 Info("RefitInward","To be implemented");
121 //_________________________________________________________________________
122 Int_t AliITSUTrackerGlo::LoadClusters(TTree * treeRP)
124 // read from tree (if pointer provided) or directly from the ITS reco interface
126 return fReconstructor->LoadClusters(treeRP);
129 //_________________________________________________________________________
130 void AliITSUTrackerGlo::UnloadClusters()
136 Info("UnloadClusters","To be implemented");
138 //_________________________________________________________________________
139 AliCluster * AliITSUTrackerGlo::GetCluster(Int_t /*index*/) const
145 Info("GetCluster","To be implemented");
149 //_________________________________________________________________________
150 Bool_t AliITSUTrackerGlo::NeedToProlong(AliESDtrack* esdTr)
152 // do we need to match this track to ITS?
154 static double bz = GetBz();
155 if (!esdTr->IsOn(AliESDtrack::kTPCin) ||
156 esdTr->IsOn(AliESDtrack::kTPCout) ||
157 esdTr->IsOn(AliESDtrack::kITSin) ||
158 esdTr->GetKinkIndex(0)>0) return kFALSE;
160 if (esdTr->Pt()<AliITSUReconstructor::GetRecoParam()->GetMinPtForProlongation()) return kFALSE;
163 esdTr->GetDZ(GetX(),GetY(),GetZ(),bz,dtz);
164 // if track is not V0 candidata but has large offset wrt IP, reject it. RS TOCHECK
165 if ( !(esdTr->GetV0Index(0)>0 && dtz[0]>AliITSUReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation())
166 && (Abs(dtz[0])>AliITSUReconstructor::GetRecoParam()->GetMaxDForProlongation() ||
167 Abs(dtz[1])>AliITSUReconstructor::GetRecoParam()->GetMaxDZForProlongation())) return kFALSE;
172 //_________________________________________________________________________
173 void AliITSUTrackerGlo::FindTrack(AliESDtrack* esdTr)
175 // find prolongaion candidates finding for single seed
177 if (!NeedToProlong(esdTr)) return; // are we interested in this track?
178 if (!InitSeed(esdTr)) return; // initialize prolongations hypotheses tree
180 AliITSURecoSens *hitSens[AliITSURecoSens::kNNeighbors];
181 AliITSUSeed seedUC; // copy of the seed from the upper layer
182 AliITSUSeed seedT; // transient seed between the seedUC and new prolongation hypothesis
184 TObjArray clArr; // container for transfer of clusters matching to seed
186 for (int ila=fITS->GetNLayersActive();ila--;) {
187 int ilaUp = ila+1; // prolong seeds from layer above
188 int nSeedsUp = GetNSeeds(ilaUp);
189 for (int isd=0;isd<nSeedsUp;isd++) {
190 AliITSUSeed* seedU = GetSeed(ilaUp,isd); // seed on prev.active layer to prolong
192 seedUC.SetParent(seedU);
193 // go till next active layer
194 if (!TransportToLayer(&seedUC, fITS->GetLrIDActive(ilaUp), fITS->GetLrIDActive(ila)) ) {
196 // Check if the seed satisfies to track definition
197 if (NeedToKill(&seedUC,kTransportFailed)) KillSeed(ilaUp,isd);
198 continue; // RS TODO: decide what to do with tracks stopped on higher layers w/o killing
200 AliITSURecoLayer* lrA = fITS->GetLayerActive(ila);
201 if (!GetRoadWidth(&seedUC, ila)) { // failed to find road width on the layer
202 if (NeedToKill(&seedUC,kRWCheckFailed)) KillSeed(ilaUp,isd);
205 int nsens = lrA->FindSensors(&fTrImpData[kTrPhi0], hitSens); // find detectors which may be hit by the track (max 4)
207 for (int isn=nsens;isn--;) {
209 AliITSURecoSens* sens = hitSens[isn];
211 if (!seedT.Propagate(sens->GetPhiTF(),sens->GetXTF(),GetBz())) continue; // propagation failed, seedT is intact
212 int clID0 = sens->GetFirstClusterId();
213 for (int icl=sens->GetNClusters();icl--;) {
214 int res = CheckCluster(&seedT,ila,clID0+icl);
216 if (res==kStopSearchOnSensor) break; // stop looking on this sensor
217 if (res==kClusterNotMatching) continue; // cluster does not match
218 // cluster is matching and it was added to the hypotheses tree
221 // cluster search is done. Do we need ta have a version of this seed skipping current layer
223 if (!NeedToKill(&seedT,kMissingCluster)) AddProlongationHypothesis(NewSeedFromPool(&seedT) ,ila);
230 //_________________________________________________________________________
231 Bool_t AliITSUTrackerGlo::InitSeed(AliESDtrack *esdTr)
233 // init prolongaion candidates finding for single seed
234 fCurrMass = esdTr->GetMass();
235 if (fCurrMass<kPionMass*0.9) fCurrMass = kPionMass; // don't trust to mu, e identification from TPCin
237 AliITSUSeed* seed = NewSeedFromPool();
238 seed->AliExternalTrackParam::operator=(*esdTr);
239 seed->SetParent(esdTr);
240 AddProlongationHypothesis(seed,fITS->GetNLayersActive());
245 //_________________________________________________________________________
246 void AliITSUTrackerGlo::ResetSeedTree()
248 // reset current hypotheses tree
249 for (int i=fITS->GetNLayersActive()+1;i--;) fSeedsLr[fITS->GetNLayersActive()].Clear();
252 //_________________________________________________________________________
253 Bool_t AliITSUTrackerGlo::TransportToLayer(AliITSUSeed* seed, Int_t lFrom, Int_t lTo)
255 // transport seed from layerFrom to the entrance of layerTo
257 const double kToler = 1e-6; // tolerance for layer on-surface check
259 int dir = lTo > lFrom ? 1:-1;
260 AliITSURecoLayer* lrFr = fITS->GetLayer(lFrom); // this can be 0 when extrapolation from TPC to ITS is requested
261 Bool_t checkFirst = kTRUE;
263 double curR2 = seed->GetX()*seed->GetX() + seed->GetY()*seed->GetY(); // current radius
265 Bool_t doLayer = kTRUE;
266 double xToGo = dir>0 ? lrFr->GetRMax() : lrFr->GetRMin();
267 if (checkFirst) { // do we need to track till the surface of the current layer ?
269 if (dir>0) { if (curR2-xToGo*xToGo>kToler) doLayer = kFALSE; } // on the surface or outside of the layer
270 else if (dir<0) { if (xToGo*xToGo-curR2>kToler) doLayer = kFALSE; } // on the surface or outside of the layer
273 if (!seed->GetXatLabR(xToGo,xToGo,GetBz(),dir)) return kFALSE;
274 // go via layer to its boundary, applying material correction.
275 if (!PropagateTrackTo(seed,xToGo,fCurrMass, lrFr->GetMaxStep(), kFALSE, -1, 0, kTRUE)) return kFALSE;
278 AliITSURecoLayer* lrTo = fITS->GetLayer( (lFrom+=dir) );
279 if (!lrTo) AliFatal(Form("Layer %d does not exist",lFrom));
281 // go the entrance of the layer, assuming no materials in between
282 double xToGo = dir>0 ? lrTo->GetRMin() : lrTo->GetRMax();
283 if (seed->GetXatLabR(xToGo,xToGo,GetBz(),dir)) return kFALSE;
284 if (!seed->PropagateTo(xToGo, GetBz())) return kFALSE; // RS: do we need BxByBz?
291 //_________________________________________________________________________
292 Bool_t AliITSUTrackerGlo::GetRoadWidth(AliITSUSeed* seed, int ilrA)
294 // calculate road width in terms of phi and z for the track which MUST be on the external radius of the layer
295 // as well as some aux info
297 AliITSURecoLayer* lrA = fITS->GetLayerActive(ilrA);
298 seed->GetXYZ(&fTrImpData[kTrXIn]); // lab position at the entrance from above
300 fTrImpData[kTrPhiIn] = ATan2(fTrImpData[kTrYIn],fTrImpData[kTrXIn]);
301 if (!seed->Rotate(fTrImpData[kTrPhiIn])) return kFALSE; // go to the frame of the entry point into the layer
302 double dr = lrA->GetDR(); // approximate X dist at the inner radius
303 if (!seed->GetXYZAt(seed->GetX()-dr, bz, fTrImpData + kTrXOut)) {
304 // special case: track does not reach inner radius, might be tangential
305 double r = seed->GetD(0,0,bz);
307 if (!seed->GetXatLabR(r,x,bz,-1)) {
308 AliError(Form("This should not happen: r=%f",r));
312 dr = Abs(seed->GetX() - x);
313 if (!seed->GetXYZAt(x, bz, fTrImpData + kTrXOut)) {
314 AliError(Form("This should not happen: x=%f",x));
320 fTrImpData[kTrPhiOut] = ATan2(fTrImpData[kTrYOut],fTrImpData[kTrXOut]);
321 double sgy = seed->GetSigmaY2() + dr*dr*seed->GetSigmaSnp2() + AliITSUReconstructor::GetRecoParam()->GetSigmaY2(ilrA);
322 double sgz = seed->GetSigmaZ2() + dr*dr*seed->GetSigmaTgl2() + AliITSUReconstructor::GetRecoParam()->GetSigmaZ2(ilrA);
323 sgy = Sqrt(sgy)*AliITSUReconstructor::GetRecoParam()->GetNSigmaRoadY();
324 sgz = Sqrt(sgz)*AliITSUReconstructor::GetRecoParam()->GetNSigmaRoadZ();
325 fTrImpData[kTrPhi0] = 0.5*(fTrImpData[kTrPhiOut]+fTrImpData[kTrPhiIn]);
326 fTrImpData[kTrZ0] = 0.5*(fTrImpData[kTrZOut]+fTrImpData[kTrPhiIn]);
327 fTrImpData[kTrDPhi] = 0.5*Abs(fTrImpData[kTrPhiOut]-fTrImpData[kTrPhiIn]) + sgy/lrA->GetR();
328 fTrImpData[kTrDZ] = 0.5*Abs(fTrImpData[kTrZOut]-fTrImpData[kTrPhiIn]) + sgz;
333 //_________________________________________________________________________
334 AliITSUSeed* AliITSUTrackerGlo::NewSeedFromPool(const AliITSUSeed* src)
336 // create new seed, optionally copying from the source
338 new(fSeedsPool[fSeedsPool.GetEntriesFast()]) AliITSUSeed(*src) :
339 new(fSeedsPool[fSeedsPool.GetEntriesFast()]) AliITSUSeed();
342 //_________________________________________________________________________
343 Int_t AliITSUTrackerGlo::CheckCluster(AliITSUSeed* track, Int_t lr, Int_t clID)
345 // Check if the cluster (in tracking frame!) is matching to track.
346 // The track must be already propagated to sensor tracking frame.
347 // Returns: kStopSearchOnSensor if the search on given sensor should be stopped,
348 // kClusterMatching if the cluster is matching
349 // kClusterMatching otherwise
351 // The seed is already propagated to cluster
352 const double kTolerX = 5e-4;
353 AliCluster *cl = fITS->GetLayerActive(lr)->GetCluster(clID);
355 if (TMath::Abs(cl->GetX())>kTolerX) { // if due to the misalingment X is large, propagate track only
356 if (!track->PropagateParamOnlyTo(track->GetX()+cl->GetX(),GetBz())) return kStopSearchOnSensor; // propagation failed, seedT is intact
358 double dy = cl->GetY() - track->GetY();
360 double tol2 = (track->GetSigmaY2() + AliITSUReconstructor::GetRecoParam()->GetSigmaY2(lr))*
361 AliITSUReconstructor::GetRecoParam()->GetNSigmaRoadY()*AliITSUReconstructor::GetRecoParam()->GetNSigmaRoadY(); // RS TOOPTIMIZE
362 if (dy2>tol2) { // the clusters are sorted in Z(col) then in Y(row).
363 if (dy>0) return kStopSearchOnSensor; // No chance that other cluster of this sensor will match (all Y's will be even larger)
364 else return kClusterNotMatching; // Other clusters may match
366 double dz2 = cl->GetZ()-track->GetZ();
368 tol2 = (track->GetSigmaZ2() + AliITSUReconstructor::GetRecoParam()->GetSigmaZ2(lr))*
369 AliITSUReconstructor::GetRecoParam()->GetNSigmaRoadZ()*AliITSUReconstructor::GetRecoParam()->GetNSigmaRoadZ(); // RS TOOPTIMIZE
370 if (dz2>tol2) return kClusterNotMatching; // Other clusters may match
373 Double_t p[2]={cl->GetY(), cl->GetZ()};
374 Double_t cov[3]={cl->GetSigmaY2(), cl->GetSigmaYZ(), cl->GetSigmaZ2()};
375 double chi2 = track->GetPredictedChi2(p,cov);
376 if (chi2>AliITSUReconstructor::GetRecoParam()->GetMaxTr2ClChi2(lr)) return kClusterNotMatching;
378 track = NewSeedFromPool(track); // input track will be reused, use its clone for updates
379 if (!track->Update(p,cov)) return kClusterNotMatching;
380 track->SetChi2Cl(chi2);
381 track->SetLrClusterID(lr,clID);
382 cl->IncreaseClusterUsage();
384 AddProlongationHypothesis(track,lr);
386 return kClusterMatching;