Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 2007-2009, 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 : /* $Id$ */
16 :
17 : //-------------------------------------------------------------------------
18 : // Implementation of the ITS tracker class
19 : // It reads AliITSRecPoint clusters and creates AliITStrackMI tracks
20 : // and fills with them the ESD
21 : // Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch
22 : // Current support and development:
23 : // Andrea Dainese, andrea.dainese@lnl.infn.it
24 : // dE/dx analysis by: Boris Batyunya, JINR, Boris.Batiounia@cern.ch
25 : // Params moved to AliITSRecoParam by: Andrea Dainese, INFN
26 : // Material budget from TGeo by: Ludovic Gaudichet & Andrea Dainese, INFN
27 : //-------------------------------------------------------------------------
28 :
29 : #include <TMatrixD.h>
30 : #include <TTree.h>
31 : #include <TDatabasePDG.h>
32 : #include <TString.h>
33 : #include <TRandom.h>
34 : #include <TTreeStream.h>
35 : #include <TVector3.h>
36 : #include <TBits.h>
37 :
38 : #include "AliLog.h"
39 : #include "AliGeomManager.h"
40 : #include "AliITSPlaneEff.h"
41 : #include "AliTrackPointArray.h"
42 : #include "AliESDEvent.h"
43 : #include "AliESDV0Params.h"
44 : #include "AliESDtrack.h"
45 : #include "AliV0.h"
46 : #include "AliITSChannelStatus.h"
47 : #include "AliITSDetTypeRec.h"
48 : #include "AliITSRecPoint.h"
49 : #include "AliITSRecPointContainer.h"
50 : #include "AliITSgeomTGeo.h"
51 : #include "AliITSReconstructor.h"
52 : #include "AliITSClusterParam.h"
53 : #include "AliITSsegmentation.h"
54 : #include "AliITSCalibration.h"
55 : #include "AliITSPlaneEffSPD.h"
56 : #include "AliITSPlaneEffSDD.h"
57 : #include "AliITSPlaneEffSSD.h"
58 : #include "AliITSV0Finder.h"
59 : #include "AliITStrackerMI.h"
60 : #include "AliMathBase.h"
61 : #include "AliPID.h"
62 :
63 :
64 118 : ClassImp(AliITStrackerMI)
65 :
66 1062 : AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
67 :
68 0 : AliITStrackerMI::AliITStrackerMI():AliTracker(),
69 0 : fI(0),
70 0 : fBestTrack(),
71 0 : fTrackToFollow(),
72 0 : fTrackHypothesys(),
73 0 : fBestHypothesys(),
74 0 : fOriginal(),
75 0 : fCurrentEsdTrack(),
76 0 : fPass(0),
77 0 : fAfterV0(kFALSE),
78 0 : fLastLayerToTrackTo(0),
79 0 : fCoefficients(0),
80 0 : fEsd(0),
81 0 : fTrackingPhase("Default"),
82 0 : fUseTGeo(3),
83 0 : fNtracks(0),
84 0 : fFlagFakes(kFALSE),
85 0 : fSelectBestMIP03(kFALSE),
86 0 : fUseImproveKalman(kFALSE),
87 0 : fxOverX0Pipe(-1.),
88 0 : fxTimesRhoPipe(-1.),
89 0 : fxOverX0PipeTrks(0),
90 0 : fxTimesRhoPipeTrks(0),
91 0 : fxOverX0ShieldTrks(0),
92 0 : fxTimesRhoShieldTrks(0),
93 0 : fxOverX0LayerTrks(0),
94 0 : fxTimesRhoLayerTrks(0),
95 0 : fDebugStreamer(0),
96 0 : fITSChannelStatus(0),
97 0 : fkDetTypeRec(0),
98 0 : fPlaneEff(0),
99 0 : fSPDChipIntPlaneEff(0),
100 0 : fITSPid(0)
101 :
102 0 : {
103 : //Default constructor
104 : Int_t i;
105 0 : for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
106 0 : for(i=0;i<2;i++) {
107 0 : fxOverX0Shield[i]=-1.;
108 0 : fxTimesRhoShield[i]=-1.;
109 0 : fConstraint[i]=0;
110 : }
111 0 : for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
112 0 : fOriginal.SetOwner();
113 0 : for(i=0;i<AliITSgeomTGeo::kNLayers;i++)fForceSkippingOfLayer[i]=0;
114 0 : for(i=0;i<100000;i++)fBestTrackIndex[i]=0;
115 0 : fITSPid=new AliITSPIDResponse();
116 :
117 0 : }
118 : //------------------------------------------------------------------------
119 28 : AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
120 2 : fI(AliITSgeomTGeo::GetNLayers()),
121 2 : fBestTrack(),
122 2 : fTrackToFollow(),
123 2 : fTrackHypothesys(),
124 2 : fBestHypothesys(),
125 2 : fOriginal(),
126 2 : fCurrentEsdTrack(),
127 2 : fPass(0),
128 2 : fAfterV0(kFALSE),
129 2 : fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
130 2 : fCoefficients(0),
131 2 : fEsd(0),
132 2 : fTrackingPhase("Default"),
133 2 : fUseTGeo(3),
134 2 : fNtracks(0),
135 2 : fFlagFakes(kFALSE),
136 2 : fSelectBestMIP03(kFALSE),
137 2 : fUseImproveKalman(kFALSE),
138 2 : fxOverX0Pipe(-1.),
139 2 : fxTimesRhoPipe(-1.),
140 2 : fxOverX0PipeTrks(0),
141 2 : fxTimesRhoPipeTrks(0),
142 2 : fxOverX0ShieldTrks(0),
143 2 : fxTimesRhoShieldTrks(0),
144 2 : fxOverX0LayerTrks(0),
145 2 : fxTimesRhoLayerTrks(0),
146 2 : fDebugStreamer(0),
147 2 : fITSChannelStatus(0),
148 2 : fkDetTypeRec(0),
149 2 : fPlaneEff(0),
150 2 : fSPDChipIntPlaneEff(0),
151 8 : fITSPid(0) {
152 : //--------------------------------------------------------------------
153 : //This is the AliITStrackerMI constructor
154 : //--------------------------------------------------------------------
155 2 : if (geom) {
156 0 : AliWarning("\"geom\" is actually a dummy argument !");
157 : }
158 :
159 2 : fOriginal.SetOwner();
160 2 : fCoefficients = 0;
161 2 : fAfterV0 = kFALSE;
162 :
163 28 : for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
164 12 : Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
165 12 : Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
166 :
167 12 : Double_t xyz[3]={0}, &x=xyz[0], &y=xyz[1], &z=xyz[2];
168 12 : AliITSgeomTGeo::GetTranslation(i,1,1,xyz);
169 12 : Double_t poff=TMath::ATan2(y,x);
170 12 : Double_t zoff=z;
171 :
172 12 : AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
173 12 : Double_t r=TMath::Sqrt(x*x + y*y);
174 :
175 12 : AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
176 12 : r += TMath::Sqrt(x*x + y*y);
177 12 : AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
178 12 : r += TMath::Sqrt(x*x + y*y);
179 12 : AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
180 12 : r += TMath::Sqrt(x*x + y*y);
181 12 : r*=0.25;
182 :
183 12 : new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
184 :
185 696 : for (Int_t j=1; j<nlad+1; j++) {
186 9464 : for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
187 8792 : TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
188 4396 : const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
189 4396 : m.Multiply(tm);
190 4396 : Double_t txyz[3]={0.};
191 4396 : xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
192 4396 : m.LocalToMaster(txyz,xyz);
193 4396 : r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
194 4396 : Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
195 :
196 8792 : if (phi<0) phi+=TMath::TwoPi();
197 4396 : else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
198 :
199 4396 : AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
200 4396 : new(&det) AliITSdetector(r,phi);
201 : // compute the real radius (with misalignment)
202 8792 : TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
203 4396 : mmisal.Multiply(tm);
204 4396 : xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
205 4396 : mmisal.LocalToMaster(txyz,xyz);
206 4396 : Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
207 4396 : det.SetRmisal(rmisal);
208 :
209 4396 : } // end loop on detectors
210 : } // end loop on ladders
211 12 : fForceSkippingOfLayer[i-1] = 0;
212 12 : } // end loop on layers
213 :
214 :
215 2 : fI=AliITSgeomTGeo::GetNLayers();
216 :
217 2 : fPass=0;
218 2 : fConstraint[0]=1; fConstraint[1]=0;
219 :
220 8 : Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
221 4 : AliITSReconstructor::GetRecoParam()->GetYVdef(),
222 4 : AliITSReconstructor::GetRecoParam()->GetZVdef()};
223 8 : Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
224 4 : AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
225 4 : AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
226 2 : SetVertex(xyzVtx,ersVtx);
227 :
228 2 : fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
229 400004 : for (Int_t i=0;i<100000;i++){
230 200000 : fBestTrackIndex[i]=0;
231 : }
232 :
233 : // store positions of centre of SPD modules (in z)
234 : // The convetion is that fSPDdetzcentre is ordered from -z to +z
235 2 : Double_t tr[3]={0};
236 2 : AliITSgeomTGeo::GetTranslation(1,1,1,tr);
237 2 : if (tr[2]<0) { // old geom (up to v5asymmPPR)
238 0 : AliITSgeomTGeo::GetTranslation(1,1,1,tr);
239 0 : fSPDdetzcentre[0] = tr[2];
240 0 : AliITSgeomTGeo::GetTranslation(1,1,2,tr);
241 0 : fSPDdetzcentre[1] = tr[2];
242 0 : AliITSgeomTGeo::GetTranslation(1,1,3,tr);
243 0 : fSPDdetzcentre[2] = tr[2];
244 0 : AliITSgeomTGeo::GetTranslation(1,1,4,tr);
245 0 : fSPDdetzcentre[3] = tr[2];
246 0 : } else { // new geom (from v11Hybrid)
247 2 : AliITSgeomTGeo::GetTranslation(1,1,4,tr);
248 2 : fSPDdetzcentre[0] = tr[2];
249 2 : AliITSgeomTGeo::GetTranslation(1,1,3,tr);
250 2 : fSPDdetzcentre[1] = tr[2];
251 2 : AliITSgeomTGeo::GetTranslation(1,1,2,tr);
252 2 : fSPDdetzcentre[2] = tr[2];
253 2 : AliITSgeomTGeo::GetTranslation(1,1,1,tr);
254 2 : fSPDdetzcentre[3] = tr[2];
255 : }
256 :
257 4 : fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
258 8 : if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
259 0 : AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
260 0 : fUseTGeo = 3;
261 0 : }
262 :
263 12 : for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
264 28 : for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
265 :
266 4 : if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0)
267 0 : fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
268 :
269 : // only for plane efficiency evaluation
270 4 : if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
271 0 : AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
272 0 : Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
273 0 : if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)!=1)
274 0 : AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
275 0 : if (iplane<2) {
276 0 : fPlaneEff = new AliITSPlaneEffSPD();
277 0 : fSPDChipIntPlaneEff = new Bool_t[AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip];
278 0 : for (UInt_t i=0; i<AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip; i++) fSPDChipIntPlaneEff[i]=kFALSE;
279 0 : }
280 0 : else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
281 0 : else fPlaneEff = new AliITSPlaneEffSSD();
282 0 : if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
283 0 : if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
284 0 : if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
285 0 : }
286 : //
287 : // RS
288 2 : fSelectBestMIP03 = kFALSE;//AliITSReconstructor::GetRecoParam()->GetSelectBestMIP03();
289 4 : fFlagFakes = AliITSReconstructor::GetRecoParam()->GetFlagFakes();
290 4 : fUseImproveKalman = AliITSReconstructor::GetRecoParam()->GetUseImproveKalman();
291 : //
292 6 : fITSPid=new AliITSPIDResponse();
293 2 : }
294 : /*
295 : //------------------------------------------------------------------------
296 : AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
297 : fI(tracker.fI),
298 : fBestTrack(tracker.fBestTrack),
299 : fTrackToFollow(tracker.fTrackToFollow),
300 : fTrackHypothesys(tracker.fTrackHypothesys),
301 : fBestHypothesys(tracker.fBestHypothesys),
302 : fOriginal(tracker.fOriginal),
303 : fCurrentEsdTrack(tracker.fCurrentEsdTrack),
304 : fPass(tracker.fPass),
305 : fAfterV0(tracker.fAfterV0),
306 : fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
307 : fCoefficients(tracker.fCoefficients),
308 : fEsd(tracker.fEsd),
309 : fTrackingPhase(tracker.fTrackingPhase),
310 : fUseTGeo(tracker.fUseTGeo),
311 : fNtracks(tracker.fNtracks),
312 : fFlagFakes(tracker.fFlagFakes),
313 : fSelectBestMIP03(tracker.fSelectBestMIP03),
314 : fxOverX0Pipe(tracker.fxOverX0Pipe),
315 : fxTimesRhoPipe(tracker.fxTimesRhoPipe),
316 : fxOverX0PipeTrks(0),
317 : fxTimesRhoPipeTrks(0),
318 : fxOverX0ShieldTrks(0),
319 : fxTimesRhoShieldTrks(0),
320 : fxOverX0LayerTrks(0),
321 : fxTimesRhoLayerTrks(0),
322 : fDebugStreamer(tracker.fDebugStreamer),
323 : fITSChannelStatus(tracker.fITSChannelStatus),
324 : fkDetTypeRec(tracker.fkDetTypeRec),
325 : fPlaneEff(tracker.fPlaneEff) {
326 : //Copy constructor
327 : fOriginal.SetOwner();
328 : Int_t i;
329 : for(i=0;i<4;i++) {
330 : fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
331 : }
332 : for(i=0;i<6;i++) {
333 : fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
334 : fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
335 : }
336 : for(i=0;i<2;i++) {
337 : fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
338 : fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
339 : }
340 : }
341 :
342 : //------------------------------------------------------------------------
343 : AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
344 : //Assignment operator
345 : this->~AliITStrackerMI();
346 : new(this) AliITStrackerMI(tracker);
347 : return *this;
348 : }
349 : */
350 : //------------------------------------------------------------------------
351 : AliITStrackerMI::~AliITStrackerMI()
352 4 : {
353 : //
354 : //destructor
355 : //
356 2 : if (fCoefficients) delete [] fCoefficients;
357 2 : DeleteTrksMaterialLUT();
358 2 : if (fDebugStreamer) {
359 : //fDebugStreamer->Close();
360 0 : delete fDebugStreamer;
361 : }
362 6 : if(fITSChannelStatus) delete fITSChannelStatus;
363 2 : if(fPlaneEff) delete fPlaneEff;
364 6 : if(fITSPid) delete fITSPid;
365 2 : if (fSPDChipIntPlaneEff) delete [] fSPDChipIntPlaneEff;
366 :
367 16 : }
368 : //------------------------------------------------------------------------
369 : void AliITStrackerMI::ReadBadFromDetTypeRec() {
370 : //--------------------------------------------------------------------
371 : //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
372 : //i.e. from OCDB
373 : //--------------------------------------------------------------------
374 :
375 4 : if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
376 :
377 2 : Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
378 :
379 2 : if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
380 :
381 : // ITS channels map
382 2 : if(fITSChannelStatus) delete fITSChannelStatus;
383 4 : fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
384 :
385 : // ITS detectors and chips
386 : Int_t i=0,j=0,k=0,ndet=0;
387 28 : for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
388 : Int_t nBadDetsPerLayer=0;
389 12 : ndet=AliITSgeomTGeo::GetNDetectors(i);
390 696 : for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
391 9464 : for (k=1; k<ndet+1; k++) {
392 4396 : AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
393 4396 : det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fkDetTypeRec);
394 4576 : if(det.IsBad()) {nBadDetsPerLayer++;}
395 : } // end loop on detectors
396 : } // end loop on ladders
397 12 : AliInfo(Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
398 : } // end loop on layers
399 :
400 : return;
401 2 : }
402 : //------------------------------------------------------------------------
403 : Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
404 : //--------------------------------------------------------------------
405 : //This function loads ITS clusters
406 : //--------------------------------------------------------------------
407 :
408 : TClonesArray *clusters = NULL;
409 16 : AliITSRecPointContainer* rpcont=AliITSRecPointContainer::Instance();
410 8 : clusters=rpcont->FetchClusters(0,cTree);
411 8 : if(!clusters) return 1;
412 :
413 8 : if(!(rpcont->IsSPDActive() || rpcont->IsSDDActive() || rpcont->IsSSDActive())){
414 0 : AliError("ITS is not in a known running configuration: SPD, SDD and SSD are not active");
415 0 : return 1;
416 : }
417 : Int_t i=0,j=0,ndet=0;
418 : Int_t detector=0;
419 112 : for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
420 48 : ndet=fgLayers[i].GetNdetectors();
421 48 : Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
422 35264 : for (; j<jmax; j++) {
423 : // if (!cTree->GetEvent(j)) continue;
424 17584 : clusters = rpcont->UncheckedGetClusters(j);
425 17584 : if(!clusters)continue;
426 17584 : Int_t ncl=clusters->GetEntriesFast();
427 17584 : SignDeltas(clusters,GetZ());
428 :
429 35834 : while (ncl--) {
430 666 : AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
431 666 : detector=c->GetDetectorIndex();
432 :
433 666 : if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
434 :
435 1332 : Int_t retval = fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
436 666 : if(retval) {
437 0 : AliWarning(Form("Too many clusters on layer %d!",i));
438 0 : break;
439 : }
440 666 : }
441 :
442 : // add dead zone "virtual" cluster in SPD, if there is a cluster within
443 : // zwindow cm from the dead zone
444 : // This method assumes that fSPDdetzcentre is ordered from -z to +z
445 19504 : if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
446 0 : for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
447 0 : Int_t lab[4] = {0,0,0,detector};
448 0 : Int_t info[3] = {0,0,i};
449 : Float_t q = 0.; // this identifies virtual clusters
450 0 : Float_t hit[6] = {xdead,
451 : 0.,
452 0 : static_cast<Float_t>(AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2()),
453 0 : static_cast<Float_t>(AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2()),
454 : q,
455 : 0.};
456 : Bool_t local = kTRUE;
457 0 : Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
458 0 : hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
459 0 : if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
460 0 : fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
461 0 : hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
462 0 : if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
463 0 : fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
464 0 : hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
465 0 : if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
466 0 : fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
467 0 : hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
468 0 : if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
469 0 : fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
470 0 : hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
471 0 : if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
472 0 : fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
473 0 : hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
474 0 : if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
475 0 : fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
476 0 : }
477 0 : } // "virtual" clusters in SPD
478 :
479 17584 : }
480 : //
481 48 : fgLayers[i].ResetRoad(); //road defined by the cluster density
482 48 : fgLayers[i].SortClusters();
483 : }
484 :
485 : // check whether we have to skip some layers
486 8 : SetForceSkippingOfLayer();
487 :
488 : return 0;
489 8 : }
490 : //------------------------------------------------------------------------
491 : void AliITStrackerMI::UnloadClusters() {
492 : //--------------------------------------------------------------------
493 : //This function unloads ITS clusters
494 : //--------------------------------------------------------------------
495 120 : for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
496 8 : }
497 : //------------------------------------------------------------------------
498 : void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
499 : //--------------------------------------------------------------------
500 : // Publishes all pointers to clusters known to the tracker into the
501 : // passed object array.
502 : // The ownership is not transfered - the caller is not expected to delete
503 : // the clusters.
504 : //--------------------------------------------------------------------
505 :
506 0 : for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
507 0 : for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
508 0 : AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
509 0 : array->AddLast(cl);
510 : }
511 : }
512 :
513 0 : return;
514 : }
515 : //------------------------------------------------------------------------
516 : Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
517 : //--------------------------------------------------------------------
518 : // Correction for the material between the TPC and the ITS
519 : //--------------------------------------------------------------------
520 684 : if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
521 246 : if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
522 242 : if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
523 242 : if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
524 98 : } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
525 98 : if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
526 98 : if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
527 98 : if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
528 : } else {
529 0 : printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
530 0 : return 0;
531 : }
532 :
533 340 : return 1;
534 342 : }
535 : //------------------------------------------------------------------------
536 : Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
537 : //--------------------------------------------------------------------
538 : // This functions reconstructs ITS tracks
539 : // The clusters must be already loaded !
540 : //--------------------------------------------------------------------
541 :
542 32 : AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
543 :
544 8 : fTrackingPhase="Clusters2Tracks";
545 : //
546 : // RS
547 8 : fSelectBestMIP03 = kFALSE;//AliITSReconstructor::GetRecoParam()->GetSelectBestMIP03();
548 8 : fFlagFakes = AliITSReconstructor::GetRecoParam()->GetFlagFakes();
549 8 : fUseImproveKalman = AliITSReconstructor::GetRecoParam()->GetUseImproveKalman();
550 : //
551 8 : double minPtCut = AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation();
552 : // the pt cutoff is tuned for nominal 5kG field, scale it with real field
553 : const double kNomField = 5.00668e+00;
554 8 : minPtCut *= TMath::Abs(GetBz()/kNomField);
555 : //
556 8 : TObjArray itsTracks(15000);
557 8 : fOriginal.Clear();
558 8 : fEsd = event; // store pointer to the esd
559 8 : Bool_t checkInv = AliITSReconstructor::GetCheckInvariant(); // off in the special reco mode w/o invariant check
560 : // temporary (for cosmics)
561 16 : if(event->GetVertex()) {
562 24 : TString title = event->GetVertex()->GetTitle();
563 16 : if(title.Contains("cosmics")) {
564 0 : Double_t xyz[3]={GetX(),GetY(),GetZ()};
565 0 : Double_t exyz[3]={0.1,0.1,0.1};
566 0 : SetVertex(xyz,exyz);
567 0 : }
568 8 : }
569 : // temporary
570 : Int_t noesd = 0;
571 : {/* Read ESD tracks */
572 8 : Int_t nentr=event->GetNumberOfTracks();
573 : noesd=nentr;
574 : // Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
575 152 : while (nentr--) {
576 136 : AliESDtrack *esd=event->GetTrack(nentr);
577 : // ---- for debugging:
578 : //if(TMath::Abs(esd->GetX()-83.65)<0.1) { FILE *f=fopen("tpc.dat","a"); fprintf(f,"%f %f %f %f %f %f\n",(Float_t)event->GetEventNumberInFile(),(Float_t)TMath::Abs(esd->GetLabel()),(Float_t)esd->GetX(),(Float_t)esd->GetY(),(Float_t)esd->GetZ(),(Float_t)esd->Pt()); fclose(f); }
579 :
580 272 : if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
581 272 : if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
582 272 : if (esd->GetStatus()&AliESDtrack::kITSin) continue;
583 276 : if (esd->GetKinkIndex(0)>0) continue; //kink daughter
584 264 : AliITStrackMI *t = new AliITStrackMI(*esd);
585 132 : t->SetCheckInvariant(checkInv);
586 132 : t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
587 132 : Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
588 :
589 : // write expected q
590 264 : t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
591 :
592 132 : if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
593 : //track - can be V0 according to TPC
594 : } else {
595 264 : if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
596 12 : delete t;
597 6 : continue;
598 : }
599 252 : if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
600 8 : delete t;
601 4 : continue;
602 : }
603 244 : if (t->Pt()<minPtCut) {
604 24 : delete t;
605 12 : continue;
606 : }
607 220 : if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
608 0 : delete t;
609 0 : continue;
610 : }
611 : }
612 110 : t->SetReconstructed(kFALSE);
613 110 : itsTracks.AddLast(t);
614 110 : fOriginal.AddLast(t);
615 110 : }
616 : } /* End Read ESD tracks */
617 :
618 8 : itsTracks.Sort();
619 8 : fOriginal.Sort();
620 8 : Int_t nentr=itsTracks.GetEntriesFast();
621 8 : fTrackHypothesys.Expand(nentr);
622 8 : fBestHypothesys.Expand(nentr);
623 8 : MakeCoefficients(nentr);
624 24 : if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
625 : Int_t ntrk=0;
626 : // THE TWO TRACKING PASSES
627 48 : for (fPass=0; fPass<2; fPass++) {
628 16 : Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
629 472 : for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
630 220 : AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
631 220 : if (t==0) continue; //this track has been already tracked
632 : //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
633 220 : if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
634 220 : Float_t dz[2]={0}; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
635 220 : if (fConstraint[fPass]) {
636 316 : if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
637 206 : TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
638 : }
639 :
640 206 : Int_t tpcLabel=t->GetLabel(); //save the TPC track label
641 1030 : AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
642 206 : fI = 6;
643 206 : ResetTrackToFollow(*t);
644 206 : ResetBestTrack();
645 :
646 206 : FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
647 :
648 :
649 206 : SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
650 : //
651 206 : AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
652 254 : if (!besttrack) continue;
653 158 : besttrack->SetLabel(tpcLabel);
654 : // besttrack->CookdEdx();
655 158 : CookdEdx(besttrack);
656 158 : besttrack->SetFakeRatio(1.);
657 158 : CookLabel(besttrack,0.); //For comparison only
658 158 : UpdateESDtrack(besttrack,AliESDtrack::kITSin);
659 158 : t->SetWinner(besttrack);
660 :
661 386 : if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
662 :
663 82 : t->SetReconstructed(kTRUE);
664 82 : ntrk++;
665 410 : AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
666 302 : }
667 16 : GetBestHypothesysMIP(itsTracks);
668 16 : } // end loop on the two tracking passes
669 : //
670 8 : if (fFlagFakes) FlagFakes(itsTracks);
671 : //
672 16 : if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
673 24 : if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
674 8 : fAfterV0 = kTRUE;
675 : //
676 8 : itsTracks.Clear();
677 : //
678 8 : Int_t entries = fTrackHypothesys.GetEntriesFast();
679 228 : for (Int_t ientry=0; ientry<entries; ientry++) {
680 212 : TObjArray * array =(TObjArray*)fTrackHypothesys.At(ientry);
681 188 : if (array) array->Delete();
682 294 : delete fTrackHypothesys.RemoveAt(ientry);
683 : }
684 :
685 8 : fTrackHypothesys.Delete();
686 8 : entries = fBestHypothesys.GetEntriesFast();
687 236 : for (Int_t ientry=0; ientry<entries; ientry++) {
688 220 : TObjArray * array =(TObjArray*)fBestHypothesys.At(ientry);
689 220 : if (array) array->Delete();
690 330 : delete fBestHypothesys.RemoveAt(ientry);
691 : }
692 8 : fBestHypothesys.Delete();
693 8 : fOriginal.Clear();
694 16 : delete [] fCoefficients;
695 8 : fCoefficients=0;
696 8 : DeleteTrksMaterialLUT();
697 :
698 24 : AliInfo(Form("Number of prolonged tracks: %d out of %d ESD tracks",ntrk,noesd));
699 :
700 8 : fTrackingPhase="Default";
701 :
702 : return 0;
703 8 : }
704 : //------------------------------------------------------------------------
705 : Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
706 : //--------------------------------------------------------------------
707 : // This functions propagates reconstructed ITS tracks back
708 : // The clusters must be loaded !
709 : //--------------------------------------------------------------------
710 16 : fTrackingPhase="PropagateBack";
711 8 : Int_t nentr=event->GetNumberOfTracks();
712 : // Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
713 8 : double bz0 = GetBz();
714 : const double kWatchStep=10.; // for larger steps watch arc vs segment difference
715 : //
716 8 : Bool_t checkInv = AliITSReconstructor::GetCheckInvariant(); // off in the special reco mode w/o invariant check
717 : Int_t ntrk=0;
718 320 : for (Int_t i=0; i<nentr; i++) {
719 152 : AliESDtrack *esd=event->GetTrack(i);
720 :
721 : // Start time integral and add distance from current position to vertex
722 152 : if (esd->GetStatus()&AliESDtrack::kITSout) continue;
723 152 : AliITStrackMI t(*esd);
724 152 : t.SetCheckInvariant(checkInv);
725 152 : Double_t xyzTrk[3]={0},xyzVtx[3]={GetX(),GetY(),GetZ()};
726 152 : t.GetXYZ(xyzTrk);
727 : Double_t dst2 = 0.;
728 : {
729 152 : double dxs = xyzTrk[0] - xyzVtx[0];
730 152 : double dys = xyzTrk[1] - xyzVtx[1];
731 152 : double dzs = xyzTrk[2] - xyzVtx[2];
732 : // RS: for large segment steps d use approximation of cicrular arc s by
733 : // s = 2R*asin(d/2R) = d/p asin(p) \approx d/p (p + 1/6 p^3) = d (1+1/6 p^2)
734 : // where R is the track radius, p = d/2R = 2C*d (C is the abs curvature)
735 : // Hence s^2/d^2 = (1+1/6 p^2)^2
736 152 : dst2 = dxs*dxs + dys*dys;
737 152 : if (dst2 > kWatchStep*kWatchStep) { // correct circular part for arc/segment factor
738 120 : double crv = TMath::Abs(esd->GetC(bz0));
739 60 : double fcarc = 1.+crv*crv*dst2/6.;
740 60 : dst2 *= fcarc*fcarc;
741 60 : }
742 152 : dst2 += dzs*dzs;
743 : }
744 152 : t.StartTimeIntegral();
745 152 : t.AddTimeStep(TMath::Sqrt(dst2));
746 : //
747 : // transfer the time integral to ESD track
748 152 : esd->SetStatus(AliESDtrack::kTIME);
749 152 : Double_t times[AliPID::kSPECIESC]={0};
750 152 : t.GetIntegratedTimes(times,AliPID::kSPECIESC);
751 152 : esd->SetIntegratedTimes(times);
752 304 : esd->SetIntegratedLength(t.GetIntegratedLength());
753 : //
754 358 : if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
755 :
756 196 : t.SetExpQ(TMath::Max(0.8*t.GetESDtrack()->GetTPCsignal(),30.));
757 98 : ResetTrackToFollow(t);
758 : //
759 98 : fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
760 196 : if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,&t)) {
761 196 : if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) continue;
762 : // fTrackToFollow.SetLabel(t.GetLabel()); // why do we neet this
763 : //fTrackToFollow.CookdEdx();
764 98 : CookLabel(&fTrackToFollow,0.); //For comparison only // why do we need this?
765 98 : fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
766 : //UseClusters(&fTrackToFollow);
767 98 : ntrk++;
768 98 : }
769 250 : }
770 :
771 8 : AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
772 :
773 8 : fTrackingPhase="Default";
774 :
775 8 : return 0;
776 0 : }
777 : //------------------------------------------------------------------------
778 : Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
779 : //--------------------------------------------------------------------
780 : // This functions refits ITS tracks using the
781 : // "inward propagated" TPC tracks
782 : // The clusters must be loaded !
783 : //--------------------------------------------------------------------
784 16 : fTrackingPhase="RefitInward";
785 :
786 16 : if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
787 :
788 8 : Bool_t doExtra=AliITSReconstructor::GetRecoParam()->GetSearchForExtraClusters();
789 8 : if(!doExtra) AliDebug(2,"Do not search for extra clusters");
790 :
791 8 : Int_t nentr=event->GetNumberOfTracks();
792 : // Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
793 :
794 : // only for PlaneEff and in case of SPD (for FO studies)
795 8 : if( AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
796 0 : AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0 &&
797 0 : AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()<2) {
798 0 : for (UInt_t i=0; i<AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip; i++) fSPDChipIntPlaneEff[i]=kFALSE;
799 0 : }
800 :
801 8 : Bool_t checkInv = AliITSReconstructor::GetCheckInvariant(); // off in the special reco mode w/o invariant check
802 :
803 : Int_t ntrk=0;
804 320 : for (Int_t i=0; i<nentr; i++) {
805 152 : AliESDtrack *esd=event->GetTrack(i);
806 :
807 206 : if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
808 98 : if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
809 98 : if (esd->GetStatus()&AliESDtrack::kTPCout)
810 82 : if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
811 :
812 98 : AliITStrackMI *t = new AliITStrackMI(*esd);
813 98 : t->SetCheckInvariant(checkInv);
814 :
815 98 : t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
816 98 : if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
817 0 : delete t;
818 0 : continue;
819 : }
820 :
821 98 : ResetTrackToFollow(*t);
822 98 : fTrackToFollow.ResetClusters();
823 :
824 : // ITS standalone tracks
825 98 : if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) {
826 16 : fTrackToFollow.ResetCovariance(10.);
827 : // protection for loopers that can have parameters screwed up
828 32 : if(TMath::Abs(fTrackToFollow.GetY())>1000. ||
829 16 : TMath::Abs(fTrackToFollow.GetZ())>1000.) {
830 0 : delete t;
831 0 : continue;
832 : }
833 : }
834 :
835 : //Refitting...
836 196 : Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
837 0 : AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
838 :
839 294 : AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
840 98 : if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,doExtra,pe)) {
841 288 : AliDebug(2," refit OK");
842 96 : fTrackToFollow.SetLabel(t->GetLabel());
843 : // fTrackToFollow.CookdEdx();
844 96 : CookdEdx(&fTrackToFollow);
845 :
846 96 : CookLabel(&fTrackToFollow,0.0); //For comparison only // RS why do we need this?
847 :
848 : //The beam pipe
849 192 : if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
850 92 : fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
851 92 : AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
852 : //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
853 : //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
854 92 : Double_t r[3]={0.,0.,0.};
855 : Double_t maxD=3.;
856 92 : esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
857 92 : ntrk++;
858 92 : }
859 : }
860 196 : delete t;
861 98 : }
862 :
863 8 : AliInfo(Form("Number of refitted tracks: %d out of %d ESD tracks",ntrk,nentr));
864 :
865 8 : fTrackingPhase="Default";
866 :
867 8 : return 0;
868 0 : }
869 : //------------------------------------------------------------------------
870 : AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
871 : //--------------------------------------------------------------------
872 : // Return pointer to a given cluster
873 : //--------------------------------------------------------------------
874 106276 : Int_t l=(index & 0xf0000000) >> 28;
875 53138 : Int_t c=(index & 0x0fffffff) >> 00;
876 53138 : return fgLayers[l].GetCluster(c);
877 : }
878 : //------------------------------------------------------------------------
879 : Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
880 : //--------------------------------------------------------------------
881 : // Get track space point with index i
882 : //--------------------------------------------------------------------
883 :
884 534 : Int_t l=(index & 0xf0000000) >> 28;
885 267 : Int_t c=(index & 0x0fffffff) >> 00;
886 267 : AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
887 267 : Int_t idet = cl->GetDetectorIndex();
888 :
889 267 : Float_t xyz[3]={0};
890 267 : Float_t cov[6]={0};
891 267 : cl->GetGlobalXYZ(xyz);
892 267 : cl->GetGlobalCov(cov);
893 267 : p.SetXYZ(xyz, cov);
894 267 : p.SetCharge(cl->GetQ());
895 267 : p.SetDriftTime(cl->GetDriftTime());
896 267 : p.SetChargeRatio(cl->GetChargeRatio());
897 267 : p.SetClusterType(cl->GetClusterType());
898 : AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
899 267 : switch (l) {
900 : case 0:
901 : iLayer = AliGeomManager::kSPD1;
902 38 : break;
903 : case 1:
904 : iLayer = AliGeomManager::kSPD2;
905 29 : break;
906 : case 2:
907 : iLayer = AliGeomManager::kSDD1;
908 47 : break;
909 : case 3:
910 : iLayer = AliGeomManager::kSDD2;
911 52 : break;
912 : case 4:
913 : iLayer = AliGeomManager::kSSD1;
914 51 : break;
915 : case 5:
916 : iLayer = AliGeomManager::kSSD2;
917 50 : break;
918 : default:
919 0 : AliWarning(Form("Wrong layer index in ITS (%d) !",l));
920 0 : break;
921 : };
922 267 : UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
923 267 : p.SetVolumeID((UShort_t)volid);
924 267 : return kTRUE;
925 267 : }
926 : //------------------------------------------------------------------------
927 : Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
928 : AliTrackPoint& p, const AliESDtrack *t) {
929 : //--------------------------------------------------------------------
930 : // Get track space point with index i
931 : // (assign error estimated during the tracking)
932 : //--------------------------------------------------------------------
933 :
934 0 : Int_t l=(index & 0xf0000000) >> 28;
935 0 : Int_t c=(index & 0x0fffffff) >> 00;
936 0 : const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
937 0 : Int_t idet = cl->GetDetectorIndex();
938 :
939 0 : const AliITSdetector &det=fgLayers[l].GetDetector(idet);
940 :
941 : // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
942 : Float_t detxy[2]={0};
943 0 : detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
944 0 : detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
945 0 : Double_t alpha = t->GetAlpha();
946 0 : Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
947 0 : Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe+cl->GetX(),GetBz()));
948 0 : phi += alpha-det.GetPhi();
949 0 : Float_t tgphi = TMath::Tan(phi);
950 :
951 0 : Float_t tgl = t->GetTgl(); // tgl about const along track
952 0 : Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
953 :
954 0 : Float_t errtrky,errtrkz,covyz;
955 : Bool_t addMisalErr=kFALSE;
956 0 : AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
957 :
958 0 : Float_t xyz[3]={0};
959 0 : Float_t cov[6]={0};
960 0 : cl->GetGlobalXYZ(xyz);
961 : // cl->GetGlobalCov(cov);
962 : Float_t pos[3] = {0.,0.,0.};
963 0 : AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
964 0 : tmpcl.GetGlobalCov(cov);
965 :
966 0 : p.SetXYZ(xyz, cov);
967 0 : p.SetCharge(cl->GetQ());
968 0 : p.SetDriftTime(cl->GetDriftTime());
969 0 : p.SetChargeRatio(cl->GetChargeRatio());
970 0 : p.SetClusterType(cl->GetClusterType());
971 :
972 : AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
973 0 : switch (l) {
974 : case 0:
975 : iLayer = AliGeomManager::kSPD1;
976 0 : break;
977 : case 1:
978 : iLayer = AliGeomManager::kSPD2;
979 0 : break;
980 : case 2:
981 : iLayer = AliGeomManager::kSDD1;
982 0 : break;
983 : case 3:
984 : iLayer = AliGeomManager::kSDD2;
985 0 : break;
986 : case 4:
987 : iLayer = AliGeomManager::kSSD1;
988 0 : break;
989 : case 5:
990 : iLayer = AliGeomManager::kSSD2;
991 0 : break;
992 : default:
993 0 : AliWarning(Form("Wrong layer index in ITS (%d) !",l));
994 : break;
995 : };
996 0 : UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
997 :
998 0 : p.SetVolumeID((UShort_t)volid);
999 : return kTRUE;
1000 0 : }
1001 : //------------------------------------------------------------------------
1002 : void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
1003 : {
1004 : //--------------------------------------------------------------------
1005 : // Follow prolongation tree
1006 : //--------------------------------------------------------------------
1007 : //
1008 206 : Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
1009 206 : Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
1010 :
1011 :
1012 206 : AliESDtrack * esd = otrack->GetESDtrack();
1013 206 : if (esd->GetV0Index(0)>0) {
1014 : // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
1015 : // mapping of ESD track is different as ITS track in Containers
1016 : // Need something more stable
1017 : // Indexes are set back again to the ESD track indexes in UpdateTPCV0
1018 0 : for (Int_t i=0;i<3;i++){
1019 0 : Int_t index = esd->GetV0Index(i);
1020 0 : if (index==0) break;
1021 0 : AliESDv0 * vertex = fEsd->GetV0(index);
1022 0 : if (vertex->GetStatus()<0) continue; // rejected V0
1023 : //
1024 0 : if (esd->GetSign()>0) {
1025 0 : vertex->SetIndex(0,esdindex);
1026 0 : } else {
1027 0 : vertex->SetIndex(1,esdindex);
1028 : }
1029 0 : }
1030 0 : }
1031 206 : TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
1032 206 : if (!bestarray){
1033 110 : bestarray = new TObjArray(5);
1034 110 : bestarray->SetOwner();
1035 110 : fBestHypothesys.AddAt(bestarray,esdindex);
1036 110 : }
1037 :
1038 : //
1039 : //setup tree of the prolongations
1040 : //
1041 : const int kMaxTr = 100; //RS
1042 3010 : static AliITStrackMI tracks[7][kMaxTr];
1043 : AliITStrackMI *currenttrack;
1044 212 : static AliITStrackMI currenttrack1;
1045 212 : static AliITStrackMI currenttrack2;
1046 212 : static AliITStrackMI backuptrack;
1047 206 : Int_t ntracks[7]={0};
1048 206 : Int_t nindexes[7][kMaxTr];
1049 206 : Float_t normalizedchi2[kMaxTr]={0};
1050 2884 : for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
1051 206 : otrack->SetNSkipped(0);
1052 206 : new (&(tracks[6][0])) AliITStrackMI(*otrack);
1053 206 : ntracks[6]=1;
1054 3296 : for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
1055 : Int_t modstatus = 1; // found
1056 206 : Float_t xloc,zloc;
1057 : //
1058 : //
1059 : // follow prolongations
1060 2884 : for (Int_t ilayer=5; ilayer>=0; ilayer--) {
1061 3708 : AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
1062 1236 : fI = ilayer;
1063 : //
1064 1236 : AliITSlayer &layer=fgLayers[ilayer];
1065 1236 : Double_t r = layer.GetR();
1066 1236 : ntracks[ilayer]=0;
1067 : //
1068 : //
1069 : Int_t nskipped=0;
1070 : Float_t nused =0;
1071 9184 : for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
1072 : // printf("LR %d Tr:%d NSeeds: %d\n",ilayer,itrack,ntracks[ilayer+1]);
1073 : //set current track
1074 2738 : if (ntracks[ilayer]>=kMaxTr) break;
1075 4068 : if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
1076 2738 : if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
1077 2738 : if (ntracks[ilayer]>15+ilayer){
1078 0 : if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
1079 0 : if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
1080 : }
1081 :
1082 2738 : new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
1083 :
1084 : // material between SSD and SDD, SDD and SPD
1085 2738 : if (ilayer==3)
1086 1314 : if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
1087 2738 : if (ilayer==1)
1088 1764 : if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
1089 :
1090 : // detector number
1091 2732 : Double_t phi,z;
1092 2734 : if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
1093 2730 : Int_t idet=layer.FindDetectorIndex(phi,z);
1094 :
1095 2730 : Double_t trackGlobXYZ1[3]={0};
1096 2730 : if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1097 :
1098 : // Get the budget to the primary vertex for the current track being prolonged
1099 : Double_t budgetToPrimVertex = 0;
1100 2730 : double xMSLrs[9]={0},x2X0MSLrs[9]={0}; // needed for ImproveKalman
1101 : int nMSLrs = 0;
1102 : //
1103 2730 : if (fUseImproveKalman) nMSLrs = GetEffectiveThicknessLbyL(xMSLrs,x2X0MSLrs);
1104 2730 : else budgetToPrimVertex = GetEffectiveThickness();
1105 : //
1106 : // check if we allow a prolongation without point
1107 2730 : Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1108 2730 : if (skip) {
1109 4 : AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1110 : // propagate to the layer radius
1111 4 : Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1112 4 : if(!vtrack->Propagate(xToGo)) continue;
1113 : // apply correction for material of the current layer
1114 8 : CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1115 4 : vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1116 4 : vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1117 4 : vtrack->SetClIndex(ilayer,-1);
1118 4 : modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1119 4 : if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1120 4 : vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1121 4 : }
1122 4 : if(constrain && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
1123 0 : fUseImproveKalman ?
1124 0 : vtrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) :
1125 0 : vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1126 : }
1127 4 : ntracks[ilayer]++;
1128 4 : continue;
1129 4 : }
1130 :
1131 : // track outside layer acceptance in z
1132 2726 : if (idet<0) continue;
1133 :
1134 : //propagate to the intersection with the detector plane
1135 2726 : const AliITSdetector &det=layer.GetDetector(idet);
1136 2726 : new(¤ttrack2) AliITStrackMI(currenttrack1);
1137 2726 : if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1138 2726 : if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1139 2726 : currenttrack1.SetDetectorIndex(idet);
1140 2726 : currenttrack2.SetDetectorIndex(idet);
1141 2726 : if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1142 :
1143 : //***************
1144 : // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1145 : //
1146 : // road in global (rphi,z) [i.e. in tracking ref. system]
1147 2726 : Double_t zmin,zmax,ymin,ymax;
1148 2726 : if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1149 :
1150 : // select clusters in road
1151 2726 : layer.SelectClusters(zmin,zmax,ymin,ymax);
1152 : //********************
1153 :
1154 : // Define criteria for track-cluster association
1155 5452 : Double_t msz = currenttrack1.GetSigmaZ2() +
1156 5452 : AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1157 5452 : AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1158 2726 : AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1159 5452 : Double_t msy = currenttrack1.GetSigmaY2() +
1160 5452 : AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1161 5452 : AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1162 2726 : AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1163 5452 : if (constrain) {
1164 4726 : msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1165 2000 : msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1166 2000 : } else {
1167 726 : msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1168 726 : msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1169 : }
1170 2726 : msz = 1./msz; // 1/RoadZ^2
1171 2726 : msy = 1./msy; // 1/RoadY^2
1172 :
1173 : //
1174 : //
1175 : // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1176 : //
1177 : const AliITSRecPoint *cl=0;
1178 2726 : Int_t clidx=-1;
1179 2726 : Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1180 : Bool_t deadzoneSPD=kFALSE;
1181 : currenttrack = ¤ttrack1;
1182 :
1183 : // check if the road contains a dead zone
1184 : Bool_t noClusters = kFALSE;
1185 2880 : if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1186 3188 : if (noClusters) AliDebug(2,"no clusters in road");
1187 2726 : Double_t dz=0.5*(zmax-zmin);
1188 2726 : Double_t dy=0.5*(ymax-ymin);
1189 2726 : Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1190 3860 : if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1191 : // create a prolongation without clusters (check also if there are no clusters in the road)
1192 2784 : if (dead ||
1193 2348 : (noClusters &&
1194 58 : AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1195 436 : AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1196 436 : updatetrack->SetClIndex(ilayer,-1);
1197 436 : if (dead==0) {
1198 : modstatus = 5; // no cls in road
1199 436 : } else if (dead==1) {
1200 : modstatus = 7; // holes in z in SPD
1201 378 : } else if (dead==2 || dead==3 || dead==4) {
1202 : modstatus = 2; // dead from OCDB
1203 96 : }
1204 436 : updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1205 : // apply correction for material of the current layer
1206 872 : CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1207 436 : if (constrain) { // apply vertex constrain
1208 326 : updatetrack->SetConstrain(constrain);
1209 : Bool_t isPrim = kTRUE;
1210 326 : if (ilayer<4) { // check that it's close to the vertex
1211 306 : updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1212 914 : if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1213 612 : AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1214 604 : TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1215 306 : AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1216 : }
1217 648 : if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
1218 0 : fUseImproveKalman ?
1219 0 : updatetrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) :
1220 0 : updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1221 : }
1222 326 : }
1223 436 : updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1224 436 : if (dead) {
1225 378 : if (dead==1) { // dead zone at z=0,+-7cm in SPD
1226 282 : updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1227 : deadzoneSPD=kTRUE;
1228 378 : } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1229 64 : updatetrack->SetDeadZoneProbability(ilayer,1.);
1230 96 : } else if (dead==4) { // at least a single dead channel from OCDB
1231 32 : updatetrack->SetDeadZoneProbability(ilayer,0.);
1232 32 : }
1233 : }
1234 436 : ntracks[ilayer]++;
1235 436 : }
1236 :
1237 2726 : clidx=-1;
1238 : // loop over clusters in the road
1239 8654 : while ((cl=layer.GetNextCluster(clidx))!=0) {
1240 3202 : if (ntracks[ilayer]>int(0.95*kMaxTr)) break; //space for skipped clusters
1241 : Bool_t changedet =kFALSE;
1242 3202 : if (TMath::Abs(cl->GetQ())<1.e-13 && deadzoneSPD==kTRUE) continue;
1243 3202 : Int_t idetc=cl->GetDetectorIndex();
1244 :
1245 3202 : if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1246 : // take into account misalignment (bring track to real detector plane)
1247 2466 : Double_t xTrOrig = currenttrack->GetX();
1248 2466 : if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1249 : // a first cut on track-cluster distance
1250 7398 : if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1251 4932 : (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1252 : { // cluster not associated to track
1253 1224 : AliDebug(2,"not associated");
1254 : // MvL: added here as well
1255 : // bring track back to ideal detector plane
1256 408 : currenttrack->Propagate(xTrOrig);
1257 408 : continue;
1258 : }
1259 : // bring track back to ideal detector plane
1260 2058 : if (!currenttrack->Propagate(xTrOrig)) continue;
1261 2058 : } else { // have to move track to cluster's detector
1262 736 : const AliITSdetector &detc=layer.GetDetector(idetc);
1263 : // a first cut on track-cluster distance
1264 736 : Double_t y;
1265 736 : if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1266 2208 : if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1267 1472 : (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1268 316 : continue; // cluster not associated to track
1269 : //
1270 420 : new (&backuptrack) AliITStrackMI(currenttrack2);
1271 : changedet = kTRUE;
1272 : currenttrack =¤ttrack2;
1273 420 : if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1274 0 : new (currenttrack) AliITStrackMI(backuptrack);
1275 : changedet = kFALSE;
1276 0 : continue;
1277 : }
1278 420 : currenttrack->SetDetectorIndex(idetc);
1279 : // Get again the budget to the primary vertex
1280 : // for the current track being prolonged, if had to change detector
1281 : //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1282 1156 : }
1283 :
1284 : // calculate track-clusters chi2
1285 2478 : chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1286 : // chi2 cut
1287 7434 : AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1288 2478 : if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1289 2378 : if (TMath::Abs(cl->GetQ())<1.e-13) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1290 2378 : if (ntracks[ilayer]>=kMaxTr) continue;
1291 2378 : AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1292 2378 : updatetrack->SetClIndex(ilayer,-1);
1293 2772 : if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1294 :
1295 2378 : if (TMath::Abs(cl->GetQ())>1.e-13) { // real cluster
1296 2378 : if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1297 0 : AliDebug(2,"update failed");
1298 0 : continue;
1299 : }
1300 2378 : updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1301 : modstatus = 1; // found
1302 2378 : } else { // virtual cluster in dead zone
1303 0 : updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1304 0 : updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1305 : modstatus = 7; // holes in z in SPD
1306 : }
1307 :
1308 2378 : if (changedet) {
1309 394 : Float_t xlocnewdet,zlocnewdet;
1310 394 : if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1311 394 : updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1312 394 : }
1313 394 : } else {
1314 1984 : updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1315 : }
1316 2378 : if (cl->IsUsed()) updatetrack->IncrementNUsed();
1317 :
1318 : // apply correction for material of the current layer
1319 4756 : CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1320 :
1321 2378 : if (constrain) { // apply vertex constrain
1322 1726 : updatetrack->SetConstrain(constrain);
1323 : Bool_t isPrim = kTRUE;
1324 1726 : if (ilayer<4) { // check that it's close to the vertex
1325 1370 : updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1326 4110 : if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1327 2740 : AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1328 2740 : TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1329 1370 : AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1330 : }
1331 3452 : if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
1332 0 : fUseImproveKalman ?
1333 0 : updatetrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) :
1334 0 : updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1335 : }
1336 1726 : } //apply vertex constrain
1337 2378 : ntracks[ilayer]++;
1338 2378 : } // create new hypothesis
1339 : else {
1340 300 : AliDebug(2,"chi2 too large");
1341 : }
1342 :
1343 2478 : } // loop over possible prolongations
1344 :
1345 : // allow one prolongation without clusters
1346 4814 : if (constrain && itrack<=1 && TMath::Abs(currenttrack1.GetNSkipped())<1.e-13 && deadzoneSPD==kFALSE && ntracks[ilayer]<kMaxTr) {
1347 554 : AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1348 : // apply correction for material of the current layer
1349 1108 : CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1350 554 : vtrack->SetClIndex(ilayer,-1);
1351 : modstatus = 3; // skipped
1352 554 : vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1353 554 : if(AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
1354 0 : fUseImproveKalman ?
1355 0 : vtrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) :
1356 0 : vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1357 : }
1358 554 : vtrack->IncrementNSkipped();
1359 554 : ntracks[ilayer]++;
1360 554 : }
1361 :
1362 :
1363 13644 : } // loop over tracks in layer ilayer+1
1364 :
1365 : //loop over track candidates for the current layer
1366 : //
1367 : //
1368 : Int_t accepted=0;
1369 :
1370 : Int_t golden=0;
1371 9216 : for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1372 3372 : normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1373 6744 : if (normalizedchi2[itrack] <
1374 5125 : AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1375 3372 : if (ilayer>4) {
1376 378 : accepted++;
1377 378 : } else {
1378 5988 : if (constrain) { // constrain
1379 5374 : if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1380 2312 : accepted++;
1381 : } else { // !constrain
1382 614 : if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1383 580 : accepted++;
1384 : }
1385 : }
1386 : }
1387 : // sort tracks by increasing normalized chi2
1388 1236 : TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1389 1236 : ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1390 2302 : if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1391 : // if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1392 1236 : if (ntracks[ilayer]>int(kMaxTr*0.9)) ntracks[ilayer]=int(kMaxTr*0.9);
1393 : } // end loop over layers
1394 :
1395 :
1396 : //
1397 : // Now select tracks to be kept
1398 : //
1399 206 : Int_t max = constrain ? 20 : 5;
1400 :
1401 : // tracks that reach layer 0 (SPD inner)
1402 1648 : for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1403 618 : AliITStrackMI & track= tracks[0][nindexes[0][i]];
1404 624 : if (track.GetNumberOfClusters()<2) continue;
1405 816 : if (!constrain && track.GetNormChi2(0) >
1406 102 : AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1407 0 : continue;
1408 : }
1409 1224 : AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1410 612 : }
1411 :
1412 : // tracks that reach layer 1 (SPD outer)
1413 920 : for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1414 254 : AliITStrackMI & track= tracks[1][nindexes[1][i]];
1415 276 : if (track.GetNumberOfClusters()<4) continue;
1416 424 : if (!constrain && track.GetNormChi2(1) >
1417 96 : AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1418 368 : if (constrain) track.IncrementNSkipped();
1419 232 : if (!constrain) {
1420 96 : track.SetD(0,track.GetD(GetX(),GetY()));
1421 96 : track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1422 96 : if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1423 0 : track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1424 0 : }
1425 : }
1426 464 : AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1427 232 : }
1428 :
1429 : // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1430 206 : if (!constrain){
1431 444 : for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1432 112 : AliITStrackMI & track= tracks[2][nindexes[2][i]];
1433 118 : if (track.GetNumberOfClusters()<3) continue;
1434 212 : if (track.GetNormChi2(2) >
1435 106 : AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1436 106 : track.SetD(0,track.GetD(GetX(),GetY()));
1437 106 : track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1438 106 : if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1439 0 : track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1440 0 : }
1441 212 : AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1442 106 : }
1443 110 : }
1444 :
1445 206 : if (!constrain) {
1446 : //
1447 : // register best track of each layer - important for V0 finder
1448 : //
1449 1320 : for (Int_t ilayer=0;ilayer<5;ilayer++){
1450 550 : if (ntracks[ilayer]==0) continue;
1451 420 : AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1452 426 : if (track.GetNumberOfClusters()<1) continue;
1453 414 : CookLabel(&track,0);
1454 828 : bestarray->AddAt(new AliITStrackMI(track),ilayer);
1455 414 : }
1456 110 : }
1457 : //
1458 : // update TPC V0 information
1459 : //
1460 206 : if (otrack->GetESDtrack()->GetV0Index(0)>0){
1461 0 : Float_t fprimvertex[3]={static_cast<Float_t>(GetX()),static_cast<Float_t>(GetY()),static_cast<Float_t>(GetZ())};
1462 0 : for (Int_t i=0;i<3;i++){
1463 0 : Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1464 0 : if (index==0) break;
1465 0 : AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1466 0 : if (vertex->GetStatus()<0) continue; // rejected V0
1467 : //
1468 0 : if (otrack->GetSign()>0) {
1469 0 : vertex->SetIndex(0,esdindex);
1470 0 : }
1471 : else{
1472 0 : vertex->SetIndex(1,esdindex);
1473 : }
1474 : //find nearest layer with track info
1475 0 : Double_t xrp[3]={0}; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1476 0 : Int_t nearestold = GetNearestLayer(xrp); //I.B.
1477 : Int_t nearest = nearestold;
1478 0 : for (Int_t ilayer =nearest;ilayer<7;ilayer++){
1479 0 : if (ntracks[nearest]==0){
1480 : nearest = ilayer;
1481 0 : }
1482 : }
1483 : //
1484 0 : AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1485 0 : if (nearestold<5&&nearest<5){
1486 0 : Bool_t accept = track.GetNormChi2(nearest)<10;
1487 0 : if (accept){
1488 0 : if (track.GetSign()>0) {
1489 0 : vertex->SetParamP(track);
1490 0 : vertex->Update(fprimvertex);
1491 : //vertex->SetIndex(0,track.fESDtrack->GetID());
1492 0 : if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1493 : }else{
1494 0 : vertex->SetParamN(track);
1495 0 : vertex->Update(fprimvertex);
1496 : //vertex->SetIndex(1,track.fESDtrack->GetID());
1497 0 : if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1498 : }
1499 0 : vertex->SetStatus(vertex->GetStatus()+1);
1500 0 : }else{
1501 : //vertex->SetStatus(-2); // reject V0 - not enough clusters
1502 : }
1503 0 : }
1504 0 : }
1505 0 : }
1506 :
1507 1612 : }
1508 : //------------------------------------------------------------------------
1509 : AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1510 : {
1511 : //--------------------------------------------------------------------
1512 : //
1513 : //
1514 100 : return fgLayers[layer];
1515 : }
1516 : //------------------------------------------------------------------------
1517 : AliITStrackerMI::AliITSlayer::AliITSlayer():
1518 708 : fR(0),
1519 354 : fPhiOffset(0),
1520 354 : fNladders(0),
1521 354 : fZOffset(0),
1522 354 : fNdetectors(0),
1523 354 : fDetectors(0),
1524 354 : fN(0),
1525 354 : fDy5(0),
1526 354 : fDy10(0),
1527 354 : fDy20(0),
1528 354 : fClustersCs(0),
1529 354 : fClusterIndexCs(0),
1530 354 : fYcs(0),
1531 354 : fZcs(0),
1532 354 : fNcs(0),
1533 354 : fCurrentSlice(-1),
1534 354 : fZmin(0),
1535 354 : fZmax(0),
1536 354 : fYmin(0),
1537 354 : fYmax(0),
1538 354 : fI(0),
1539 354 : fImax(0),
1540 354 : fSkip(0),
1541 354 : fAccepted(0),
1542 354 : fRoad(0),
1543 354 : fMaxSigmaClY(0),
1544 354 : fMaxSigmaClZ(0),
1545 354 : fNMaxSigmaCl(3)
1546 708 : {
1547 : //--------------------------------------------------------------------
1548 : //default AliITSlayer constructor
1549 : //--------------------------------------------------------------------
1550 : //
1551 : // RS speedup reseting
1552 : // memset(fClusterWeight,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
1553 354 : memset(fClusterTracks,0,sizeof(UShort_t)*AliITSRecoParam::kMaxClusterPerLayer*4);
1554 354 : memset(fY,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
1555 354 : memset(fZ,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
1556 : /*
1557 : for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1558 : fClusterWeight[i]=0;
1559 : fClusterTracks[0][i]=-1;
1560 : fClusterTracks[1][i]=-1;
1561 : fClusterTracks[2][i]=-1;
1562 : fClusterTracks[3][i]=-1;
1563 : fY[i]=0;
1564 : fZ[i]=0;
1565 : }
1566 : */
1567 354 : fYB[0]=0;
1568 354 : fYB[1]=0;
1569 :
1570 9063108 : for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer5; j++) {
1571 63436800 : for (Int_t j1=0; j1<6; j1++) {
1572 27187200 : fClusters5[j1][j]=0;
1573 27187200 : fClusterIndex5[j1][j]=0;//RS -1;
1574 27187200 : fY5[j1][j]=0;
1575 27187200 : fZ5[j1][j]=0;
1576 27187200 : fN5[j1]=0;
1577 27187200 : fBy5[j1][0]=0;
1578 27187200 : fBy5[j1][1]=0;
1579 : }
1580 : }
1581 :
1582 4531908 : for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer10; j++) {
1583 54374400 : for (Int_t j1=0; j1<11; j1++) {
1584 24921600 : fClusters10[j1][j]=0;
1585 24921600 : fClusterIndex10[j1][j]=0;//RS-1;
1586 24921600 : fY10[j1][j]=0;
1587 24921600 : fZ10[j1][j]=0;
1588 24921600 : fN10[j1]=0;
1589 24921600 : fBy10[j1][0]=0;
1590 24921600 : fBy10[j1][1]=0;
1591 : }
1592 : }
1593 :
1594 2266308 : for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer20; j++) {
1595 49843200 : for (Int_t j1=0; j1<21; j1++) {
1596 23788800 : fClusters20[j1][j]=0;
1597 23788800 : fClusterIndex20[j1][j]=0;//RS-1;
1598 23788800 : fY20[j1][j]=0;
1599 23788800 : fZ20[j1][j]=0;
1600 23788800 : fN20[j1]=0;
1601 23788800 : fBy20[j1][0]=0;
1602 23788800 : fBy20[j1][1]=0;
1603 : }
1604 : }
1605 22656708 : for(Int_t i=0;i<AliITSRecoParam::kMaxClusterPerLayer;i++){
1606 11328000 : fClusters[i]=NULL;
1607 11328000 : fClusterIndex[i]=0;
1608 : }
1609 708 : }
1610 : //------------------------------------------------------------------------
1611 : AliITStrackerMI::AliITSlayer::
1612 : AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1613 24 : fR(r),
1614 12 : fPhiOffset(p),
1615 12 : fNladders(nl),
1616 12 : fZOffset(z),
1617 12 : fNdetectors(nd),
1618 12 : fDetectors(0),
1619 12 : fN(0),
1620 12 : fDy5(0),
1621 12 : fDy10(0),
1622 12 : fDy20(0),
1623 12 : fClustersCs(0),
1624 12 : fClusterIndexCs(0),
1625 12 : fYcs(0),
1626 12 : fZcs(0),
1627 12 : fNcs(0),
1628 12 : fCurrentSlice(-1),
1629 12 : fZmin(0),
1630 12 : fZmax(0),
1631 12 : fYmin(0),
1632 12 : fYmax(0),
1633 12 : fI(0),
1634 12 : fImax(0),
1635 12 : fSkip(0),
1636 12 : fAccepted(0),
1637 12 : fRoad(0),
1638 12 : fMaxSigmaClY(0),
1639 12 : fMaxSigmaClZ(0),
1640 36 : fNMaxSigmaCl(3) {
1641 : //--------------------------------------------------------------------
1642 : //main AliITSlayer constructor
1643 : //--------------------------------------------------------------------
1644 8828 : fDetectors=new AliITSdetector[fNladders*fNdetectors];
1645 12 : fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1646 : //
1647 : // RS speedup reseting
1648 : // memset(fClusterWeight,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
1649 12 : memset(fClusterTracks,0,sizeof(UShort_t)*AliITSRecoParam::kMaxClusterPerLayer*4);
1650 12 : memset(fY,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
1651 12 : memset(fZ,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
1652 : /*
1653 : for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1654 : fClusterWeight[i]=0;
1655 : fClusterTracks[0][i]=-1;
1656 : fClusterTracks[1][i]=-1;
1657 : fClusterTracks[2][i]=-1;
1658 : fClusterTracks[3][i]=-1;
1659 : fY[i]=0;
1660 : fZ[i]=0;
1661 : }
1662 : */
1663 12 : fYB[0]=0;
1664 12 : fYB[1]=0;
1665 :
1666 307224 : for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer5; j++) {
1667 2150400 : for (Int_t j1=0; j1<6; j1++) {
1668 921600 : fClusters5[j1][j]=0;
1669 921600 : fClusterIndex5[j1][j]=0;//RS-1;
1670 921600 : fY5[j1][j]=0;
1671 921600 : fZ5[j1][j]=0;
1672 921600 : fN5[j1]=0;
1673 921600 : fBy5[j1][0]=0;
1674 921600 : fBy5[j1][1]=0;
1675 : }
1676 : }
1677 :
1678 153624 : for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer10; j++) {
1679 1843200 : for (Int_t j1=0; j1<11; j1++) {
1680 844800 : fClusters10[j1][j]=0;
1681 844800 : fClusterIndex10[j1][j]=0;//RS-1;
1682 844800 : fY10[j1][j]=0;
1683 844800 : fZ10[j1][j]=0;
1684 844800 : fN10[j1]=0;
1685 844800 : fBy10[j1][0]=0;
1686 844800 : fBy10[j1][1]=0;
1687 : }
1688 : }
1689 :
1690 76824 : for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer20; j++) {
1691 1689600 : for (Int_t j1=0; j1<21; j1++) {
1692 806400 : fClusters20[j1][j]=0;
1693 806400 : fClusterIndex20[j1][j]=0;//RS-1;
1694 806400 : fY20[j1][j]=0;
1695 806400 : fZ20[j1][j]=0;
1696 806400 : fN20[j1]=0;
1697 806400 : fBy20[j1][0]=0;
1698 806400 : fBy20[j1][1]=0;
1699 : }
1700 : }
1701 768024 : for(Int_t i=0;i<AliITSRecoParam::kMaxClusterPerLayer;i++){
1702 384000 : fClusters[i]=NULL;
1703 384000 : fClusterIndex[i]=0;
1704 : }
1705 24 : }
1706 : /*
1707 : //------------------------------------------------------------------------
1708 : AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1709 : fR(layer.fR),
1710 : fPhiOffset(layer.fPhiOffset),
1711 : fNladders(layer.fNladders),
1712 : fZOffset(layer.fZOffset),
1713 : fNdetectors(layer.fNdetectors),
1714 : fDetectors(layer.fDetectors),
1715 : fN(layer.fN),
1716 : fDy5(layer.fDy5),
1717 : fDy10(layer.fDy10),
1718 : fDy20(layer.fDy20),
1719 : fClustersCs(layer.fClustersCs),
1720 : fClusterIndexCs(layer.fClusterIndexCs),
1721 : fYcs(layer.fYcs),
1722 : fZcs(layer.fZcs),
1723 : fNcs(layer.fNcs),
1724 : fCurrentSlice(layer.fCurrentSlice),
1725 : fZmin(layer.fZmin),
1726 : fZmax(layer.fZmax),
1727 : fYmin(layer.fYmin),
1728 : fYmax(layer.fYmax),
1729 : fI(layer.fI),
1730 : fImax(layer.fImax),
1731 : fSkip(layer.fSkip),
1732 : fAccepted(layer.fAccepted),
1733 : fRoad(layer.fRoad),
1734 : fMaxSigmaClY(layer.fMaxSigmaClY),
1735 : fMaxSigmaClZ(layer.fMaxSigmaClZ),
1736 : fNMaxSigmaCl(layer.fNMaxSigmaCl)
1737 : {
1738 : //Copy constructor
1739 : }
1740 : */
1741 : //------------------------------------------------------------------------
1742 708 : AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1743 : //--------------------------------------------------------------------
1744 : // AliITSlayer destructor
1745 : //--------------------------------------------------------------------
1746 5128 : delete [] fDetectors;
1747 708 : for (Int_t i=0; i<fN; i++) delete fClusters[i];
1748 : /* RS: Why?
1749 : for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1750 : fClusterWeight[i]=0;
1751 : fClusterTracks[0][i]=-1;
1752 : fClusterTracks[1][i]=-1;
1753 : fClusterTracks[2][i]=-1;
1754 : fClusterTracks[3][i]=-1;
1755 : }
1756 : */
1757 708 : }
1758 : //------------------------------------------------------------------------
1759 : void AliITStrackerMI::AliITSlayer::ResetClusters() {
1760 : //--------------------------------------------------------------------
1761 : // This function removes loaded clusters
1762 : //--------------------------------------------------------------------
1763 2142 : for (Int_t i=fN; i--;) delete fClusters[i];
1764 : // RS speedup reseting
1765 : // memset(fClusterWeight,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
1766 48 : memset(fClusterTracks,0,sizeof(UShort_t)*AliITSRecoParam::kMaxClusterPerLayer*4);
1767 : /*
1768 : for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1769 : fClusterWeight[i]=0;
1770 : fClusterTracks[0][i]=-1;
1771 : fClusterTracks[1][i]=-1;
1772 : fClusterTracks[2][i]=-1;
1773 : fClusterTracks[3][i]=-1;
1774 : }
1775 : */
1776 48 : fN=0;
1777 48 : fI=0;
1778 48 : }
1779 : //------------------------------------------------------------------------
1780 : void AliITStrackerMI::AliITSlayer::ResetWeights() {
1781 : //--------------------------------------------------------------------
1782 : // This function reset weights of the clusters
1783 : //--------------------------------------------------------------------
1784 : // RS speedup reseting
1785 : // memset(fClusterWeight,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
1786 0 : memset(fClusterTracks,0,sizeof(UShort_t)*AliITSRecoParam::kMaxClusterPerLayer*4);
1787 : /*
1788 : for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1789 : fClusterWeight[i]=0;
1790 : fClusterTracks[0][i]=-1;
1791 : fClusterTracks[1][i]=-1;
1792 : fClusterTracks[2][i]=-1;
1793 : fClusterTracks[3][i]=-1;
1794 : }
1795 : */
1796 0 : for (Int_t i=fN;i--;) {
1797 0 : AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1798 0 : if (cl&&cl->IsUsed()) cl->Use();
1799 : }
1800 :
1801 0 : }
1802 : //------------------------------------------------------------------------
1803 : void AliITStrackerMI::AliITSlayer::ResetRoad() {
1804 : //--------------------------------------------------------------------
1805 : // This function calculates the road defined by the cluster density
1806 : //--------------------------------------------------------------------
1807 : Int_t n=0;
1808 810 : for (Int_t i=fN; i--;) {
1809 1312 : if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1810 : }
1811 96 : if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1812 48 : }
1813 : //------------------------------------------------------------------------
1814 : Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1815 : //--------------------------------------------------------------------
1816 : //This function adds a cluster to this layer
1817 : //--------------------------------------------------------------------
1818 1332 : if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1819 0 : AliWarningGeneralF("AliITStrackerMI::AliITSlayer","Number of clusters for layer R=%.2f exceeds limit of %d",fR,fN);
1820 0 : return 1;
1821 : }
1822 666 : fCurrentSlice=-1;
1823 666 : fClusters[fN]=cl;
1824 666 : fN++;
1825 666 : AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1826 : //AD
1827 666 : Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
1828 666 : Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2());
1829 1012 : if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
1830 1032 : if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
1831 1040 : if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
1832 1021 : if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
1833 : //AD
1834 : /*
1835 : if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1836 : if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1837 : if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1838 : if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1839 : */
1840 : return 0;
1841 666 : }
1842 : //------------------------------------------------------------------------
1843 : void AliITStrackerMI::AliITSlayer::SortClusters()
1844 : {
1845 : //
1846 : //sort clusters
1847 : //
1848 : //
1849 96 : fMaxSigmaClY=0.; //AD
1850 48 : fMaxSigmaClZ=0.; //AD
1851 48 : AliITSRecPoint *clusters[fN];
1852 48 : Float_t z[fN];
1853 48 : Int_t index[fN];
1854 :
1855 1428 : for (Int_t i=0;i<fN;i++){
1856 666 : z[i] = fClusters[i]->GetZ();
1857 : // save largest errors in y and z for this layer
1858 666 : fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
1859 666 : fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
1860 : }
1861 48 : TMath::Sort(fN,z,index,kFALSE);
1862 1428 : for (Int_t i=fN;i--;) {
1863 666 : clusters[i] = fClusters[index[i]];
1864 : }
1865 : //
1866 1428 : for (Int_t i=fN;i--;){
1867 666 : fClusters[i] = clusters[i];
1868 666 : fZ[i] = fClusters[i]->GetZ();
1869 666 : AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1870 666 : Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1871 674 : if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1872 666 : fY[i] = y;
1873 : }
1874 : // delete[] index; // RS Moved to stack
1875 : // delete[] z;
1876 : // delete[] clusters;
1877 : //
1878 :
1879 48 : fYB[0]=10000000;
1880 48 : fYB[1]=-10000000;
1881 1428 : for (Int_t i=0;i<fN;i++){
1882 770 : if (fY[i]<fYB[0]) fYB[0]=fY[i];
1883 826 : if (fY[i]>fYB[1]) fYB[1]=fY[i];
1884 666 : fClusterIndex[i] = i;
1885 : }
1886 : //
1887 : // fill slices
1888 48 : fDy5 = (fYB[1]-fYB[0])/5.;
1889 48 : fDy10 = (fYB[1]-fYB[0])/10.;
1890 48 : fDy20 = (fYB[1]-fYB[0])/20.;
1891 672 : for (Int_t i=6;i--;) fN5[i] =0;
1892 1152 : for (Int_t i=11;i--;) fN10[i]=0;
1893 2112 : for (Int_t i=21;i--;) fN20[i]=0;
1894 : //
1895 672 : for (Int_t i=6;i--;) {fBy5[i][0] = fYB[0]+(i-0.75)*fDy5; fBy5[i][1] = fYB[0]+(i+0.75)*fDy5;}
1896 1152 : for (Int_t i=11;i--;) {fBy10[i][0] = fYB[0]+(i-0.75)*fDy10; fBy10[i][1] = fYB[0]+(i+0.75)*fDy10;}
1897 2112 : for (Int_t i=21;i--;) {fBy20[i][0] = fYB[0]+(i-0.75)*fDy20; fBy20[i][1] = fYB[0]+(i+0.75)*fDy20;}
1898 : //
1899 : //
1900 1428 : for (Int_t i=0;i<fN;i++)
1901 5328 : for (Int_t irot=-1;irot<=1;irot++){
1902 1998 : Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1903 : // slice 5
1904 27972 : for (Int_t slice=0; slice<6;slice++){
1905 19112 : if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1906 1232 : fClusters5[slice][fN5[slice]] = fClusters[i];
1907 1232 : fY5[slice][fN5[slice]] = curY;
1908 1232 : fZ5[slice][fN5[slice]] = fZ[i];
1909 1232 : fClusterIndex5[slice][fN5[slice]]=i;
1910 1232 : fN5[slice]++;
1911 1232 : }
1912 : }
1913 : // slice 10
1914 47952 : for (Int_t slice=0; slice<11;slice++){
1915 33154 : if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1916 1000 : fClusters10[slice][fN10[slice]] = fClusters[i];
1917 1000 : fY10[slice][fN10[slice]] = curY;
1918 1000 : fZ10[slice][fN10[slice]] = fZ[i];
1919 1000 : fClusterIndex10[slice][fN10[slice]]=i;
1920 1000 : fN10[slice]++;
1921 1000 : }
1922 : }
1923 : // slice 20
1924 87912 : for (Int_t slice=0; slice<21;slice++){
1925 61652 : if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1926 858 : fClusters20[slice][fN20[slice]] = fClusters[i];
1927 858 : fY20[slice][fN20[slice]] = curY;
1928 858 : fZ20[slice][fN20[slice]] = fZ[i];
1929 858 : fClusterIndex20[slice][fN20[slice]]=i;
1930 858 : fN20[slice]++;
1931 858 : }
1932 : }
1933 : }
1934 :
1935 : //
1936 : // consistency check
1937 : //
1938 1332 : for (Int_t i=0;i<fN-1;i++){
1939 618 : if (fZ[i]>fZ[i+1]){
1940 0 : printf("Bug\n");
1941 0 : }
1942 : }
1943 : //
1944 2112 : for (Int_t slice=0;slice<21;slice++)
1945 2912 : for (Int_t i=0;i<fN20[slice]-1;i++){
1946 448 : if (fZ20[slice][i]>fZ20[slice][i+1]){
1947 0 : printf("Bug\n");
1948 0 : }
1949 : }
1950 :
1951 :
1952 48 : }
1953 : //------------------------------------------------------------------------
1954 : Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1955 : //--------------------------------------------------------------------
1956 : // This function returns the index of the nearest cluster
1957 : //--------------------------------------------------------------------
1958 : Int_t ncl=0;
1959 : const Float_t *zcl;
1960 12960 : if (fCurrentSlice<0) {
1961 144 : ncl = fN;
1962 144 : zcl = fZ;
1963 144 : }
1964 : else{
1965 6336 : ncl = fNcs;
1966 6336 : zcl = fZcs;;
1967 : }
1968 :
1969 6532 : if (ncl==0) return 0;
1970 6428 : Int_t b=0, e=ncl-1, m=(b+e)/2;
1971 29200 : for (; b<e; m=(b+e)/2) {
1972 : // if (z > fClusters[m]->GetZ()) b=m+1;
1973 12976 : if (z > zcl[m]) b=m+1;
1974 : else e=m;
1975 : }
1976 : return m;
1977 6480 : }
1978 : //------------------------------------------------------------------------
1979 : Bool_t AliITStrackerMI::ComputeRoad(AliITStrackMI* track,Int_t ilayer,Int_t idet,Double_t &zmin,Double_t &zmax,Double_t &ymin,Double_t &ymax) const {
1980 : //--------------------------------------------------------------------
1981 : // This function computes the rectangular road for this track
1982 : //--------------------------------------------------------------------
1983 :
1984 :
1985 9700 : AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1986 : // take into account the misalignment: propagate track to misaligned detector plane
1987 4850 : if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1988 :
1989 9700 : Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1990 9700 : TMath::Sqrt(track->GetSigmaZ2() +
1991 9700 : AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1992 9700 : AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1993 4850 : AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1994 9700 : Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1995 9700 : TMath::Sqrt(track->GetSigmaY2() +
1996 9700 : AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1997 9700 : AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1998 4850 : AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1999 :
2000 : // track at boundary between detectors, enlarge road
2001 4850 : Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
2002 4850 : if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
2003 256 : (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
2004 48 : (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
2005 0 : (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
2006 4850 : Float_t tgl = TMath::Abs(track->GetTgl());
2007 4850 : if (tgl > 1.) tgl=1.;
2008 4850 : Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
2009 4850 : dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
2010 4850 : Float_t snp = TMath::Abs(track->GetSnp());
2011 4850 : if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
2012 4850 : dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
2013 4850 : } // boundary
2014 :
2015 : // add to the road a term (up to 2-3 mm) to deal with misalignments
2016 4850 : dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
2017 4850 : dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
2018 :
2019 4850 : Double_t r = fgLayers[ilayer].GetR();
2020 4850 : zmin = track->GetZ() - dz;
2021 4850 : zmax = track->GetZ() + dz;
2022 4850 : ymin = track->GetY() + r*det.GetPhi() - dy;
2023 4850 : ymax = track->GetY() + r*det.GetPhi() + dy;
2024 :
2025 : // bring track back to idead detector plane
2026 4850 : if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2027 :
2028 4850 : return kTRUE;
2029 4850 : }
2030 : //------------------------------------------------------------------------
2031 : void AliITStrackerMI::AliITSlayer::
2032 : SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
2033 : //--------------------------------------------------------------------
2034 : // This function sets the "window"
2035 : //--------------------------------------------------------------------
2036 :
2037 6480 : Double_t circle=2*TMath::Pi()*fR;
2038 3240 : fYmin = ymin;
2039 3240 : fYmax = ymax;
2040 3240 : fZmin = zmin;
2041 3240 : fZmax = zmax;
2042 : // AD
2043 : // enlarge road in y by maximum cluster error on this layer (3 sigma)
2044 3240 : fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
2045 3240 : fYmax += fNMaxSigmaCl*fMaxSigmaClY;
2046 3240 : fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
2047 3240 : fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
2048 :
2049 3240 : Float_t ymiddle = (fYmin+fYmax)*0.5;
2050 3240 : if (ymiddle<fYB[0]) {
2051 202 : fYmin+=circle; fYmax+=circle; ymiddle+=circle;
2052 3240 : } else if (ymiddle>fYB[1]) {
2053 344 : fYmin-=circle; fYmax-=circle; ymiddle-=circle;
2054 344 : }
2055 :
2056 : //
2057 3240 : fCurrentSlice =-1;
2058 : // defualt take all
2059 3240 : fClustersCs = fClusters;
2060 3240 : fClusterIndexCs = fClusterIndex;
2061 3240 : fYcs = fY;
2062 3240 : fZcs = fZ;
2063 3240 : fNcs = fN;
2064 : //
2065 : //is in 20 slice?
2066 6480 : if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
2067 3232 : Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
2068 3232 : if (slice<0) slice=0;
2069 3232 : if (slice>20) slice=20;
2070 9520 : Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
2071 3232 : if (isOK) {
2072 2852 : fCurrentSlice=slice;
2073 2852 : fClustersCs = fClusters20[fCurrentSlice];
2074 2852 : fClusterIndexCs = fClusterIndex20[fCurrentSlice];
2075 2852 : fYcs = fY20[fCurrentSlice];
2076 2852 : fZcs = fZ20[fCurrentSlice];
2077 2852 : fNcs = fN20[fCurrentSlice];
2078 2852 : }
2079 3232 : }
2080 : //
2081 : //is in 10 slice?
2082 3628 : if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
2083 385 : Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
2084 385 : if (slice<0) slice=0;
2085 385 : if (slice>10) slice=10;
2086 979 : Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
2087 385 : if (isOK) {
2088 6 : fCurrentSlice=slice;
2089 6 : fClustersCs = fClusters10[fCurrentSlice];
2090 6 : fClusterIndexCs = fClusterIndex10[fCurrentSlice];
2091 6 : fYcs = fY10[fCurrentSlice];
2092 6 : fZcs = fZ10[fCurrentSlice];
2093 6 : fNcs = fN10[fCurrentSlice];
2094 6 : }
2095 385 : }
2096 : //
2097 : //is in 5 slice?
2098 3622 : if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
2099 382 : Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
2100 382 : if (slice<0) slice=0;
2101 382 : if (slice>5) slice=5;
2102 1074 : Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
2103 382 : if (isOK) {
2104 310 : fCurrentSlice=slice;
2105 310 : fClustersCs = fClusters5[fCurrentSlice];
2106 310 : fClusterIndexCs = fClusterIndex5[fCurrentSlice];
2107 310 : fYcs = fY5[fCurrentSlice];
2108 310 : fZcs = fZ5[fCurrentSlice];
2109 310 : fNcs = fN5[fCurrentSlice];
2110 310 : }
2111 382 : }
2112 : //
2113 3240 : fI = FindClusterIndex(fZmin);
2114 3240 : fImax = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
2115 3240 : fSkip = 0;
2116 3240 : fAccepted = 0;
2117 :
2118 : return;
2119 3240 : }
2120 : //------------------------------------------------------------------------
2121 : Int_t AliITStrackerMI::AliITSlayer::
2122 : FindDetectorIndex(Double_t phi, Double_t z) const {
2123 : //--------------------------------------------------------------------
2124 : //This function finds the detector crossed by the track
2125 : //--------------------------------------------------------------------
2126 : Double_t dphi;
2127 41490 : if (fZOffset<0) // old geometry
2128 13830 : dphi = -(phi-fPhiOffset);
2129 : else // new geometry
2130 : dphi = phi-fPhiOffset;
2131 :
2132 :
2133 14924 : if (dphi < 0) dphi += 2*TMath::Pi();
2134 12736 : else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
2135 13830 : Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
2136 14924 : if (np>=fNladders) np-=fNladders;
2137 13830 : if (np<0) np+=fNladders;
2138 :
2139 :
2140 13830 : Double_t dz=fZOffset-z;
2141 13830 : Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
2142 13830 : Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
2143 13830 : if (nz>=fNdetectors || nz<0) {
2144 : //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
2145 4 : return -1;
2146 : }
2147 :
2148 : // ad hoc correction for 3rd ladder of SDD inner layer,
2149 : // which is reversed (rotated by pi around local y)
2150 : // this correction is OK only from AliITSv11Hybrid onwards
2151 32694 : if (GetR()>12. && GetR()<20.) { // SDD inner
2152 9434 : if(np==2) { // 3rd ladder
2153 0 : Double_t posMod252[3]={0};
2154 0 : AliITSgeomTGeo::GetTranslation(252,posMod252);
2155 : // check the Z coordinate of Mod 252: if negative
2156 : // (old SDD geometry in AliITSv11Hybrid)
2157 : // the swap of numeration whould be applied
2158 0 : if(posMod252[2]<0.){
2159 0 : nz = (fNdetectors-1) - nz;
2160 0 : }
2161 0 : }
2162 : }
2163 : //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
2164 :
2165 :
2166 13826 : return np*fNdetectors + nz;
2167 13830 : }
2168 : //------------------------------------------------------------------------
2169 : const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
2170 : {
2171 : //--------------------------------------------------------------------
2172 : // This function returns clusters within the "window"
2173 : //--------------------------------------------------------------------
2174 :
2175 9770 : if (fCurrentSlice<0) {
2176 176 : Double_t rpi2 = 2.*fR*TMath::Pi();
2177 884 : for (Int_t i=fI; i<fImax; i++) {
2178 286 : Double_t y = fY[i];
2179 286 : Double_t z = fZ[i];
2180 572 : if (fYmax<y) y -= rpi2;
2181 500 : if (fYmin>y) y += rpi2;
2182 286 : if (y<fYmin) continue;
2183 500 : if (y>fYmax) continue;
2184 : // AD
2185 : // skip clusters that are in "extended" road but they
2186 : // 3sigma error does not touch the original road
2187 72 : if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
2188 72 : if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
2189 : //
2190 72 : if (TMath::Abs(fClusters[i]->GetQ())<1.e-13 && fSkip==2) continue;
2191 72 : ci=i;
2192 112 : if (!test) fI=i+1;
2193 72 : return fClusters[i];
2194 : }
2195 104 : } else {
2196 26242 : for (Int_t i=fI; i<fImax; i++) {
2197 8186 : if (fYcs[i]<fYmin) continue;
2198 7126 : if (fYcs[i]>fYmax) continue;
2199 6304 : if (TMath::Abs(fClustersCs[i]->GetQ())<1.e-13 && fSkip==2) continue;
2200 6304 : ci=fClusterIndexCs[i];
2201 10068 : if (!test) fI=i+1;
2202 6304 : return fClustersCs[i];
2203 : }
2204 : }
2205 3394 : return 0;
2206 9770 : }
2207 : //------------------------------------------------------------------------
2208 : Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
2209 : const {
2210 : //--------------------------------------------------------------------
2211 : // This function returns the layer thickness at this point (units X0)
2212 : //--------------------------------------------------------------------
2213 : Double_t d=0.0085;
2214 424 : x0=AliITSRecoParam::GetX0Air();
2215 248 : if (43<fR&&fR<45) { //SSD2
2216 : Double_t dd=0.0034;
2217 : d=dd;
2218 40 : if (TMath::Abs(y-0.00)>3.40) d+=dd;
2219 36 : if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2220 36 : if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2221 334 : for (Int_t i=0; i<12; i++) {
2222 152 : if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
2223 0 : if (TMath::Abs(y-0.00)>3.40) d+=dd;
2224 0 : d+=0.0034;
2225 0 : break;
2226 : }
2227 152 : if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
2228 0 : if (TMath::Abs(y-0.00)>3.40) d+=dd;
2229 0 : d+=0.0034;
2230 0 : break;
2231 : }
2232 152 : if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2233 178 : if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2234 : }
2235 36 : } else
2236 212 : if (37<fR&&fR<41) { //SSD1
2237 : Double_t dd=0.0034;
2238 : d=dd;
2239 36 : if (TMath::Abs(y-0.00)>3.40) d+=dd;
2240 44 : if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2241 38 : if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2242 410 : for (Int_t i=0; i<11; i++) {
2243 184 : if (TMath::Abs(z-3.9*i)<0.15) {
2244 20 : if (TMath::Abs(y-0.00)>3.40) d+=dd;
2245 20 : d+=dd;
2246 20 : break;
2247 : }
2248 164 : if (TMath::Abs(z+3.9*i)<0.15) {
2249 0 : if (TMath::Abs(y-0.00)>3.40) d+=dd;
2250 0 : d+=dd;
2251 0 : break;
2252 : }
2253 166 : if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2254 162 : if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2255 : }
2256 36 : } else
2257 212 : if (13<fR&&fR<26) { //SDD
2258 : Double_t dd=0.0033;
2259 : d=dd;
2260 74 : if (TMath::Abs(y-0.00)>3.30) d+=dd;
2261 :
2262 72 : if (TMath::Abs(y-1.80)<0.55) {
2263 8 : d+=0.016;
2264 266 : for (Int_t j=0; j<20; j++) {
2265 126 : if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2266 122 : if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2267 : }
2268 8 : }
2269 72 : if (TMath::Abs(y+1.80)<0.55) {
2270 8 : d+=0.016;
2271 344 : for (Int_t j=0; j<20; j++) {
2272 160 : if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2273 160 : if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2274 : }
2275 8 : }
2276 :
2277 418 : for (Int_t i=0; i<4; i++) {
2278 164 : if (TMath::Abs(z-7.3*i)<0.60) {
2279 42 : d+=dd;
2280 42 : if (TMath::Abs(y-0.00)>3.30) d+=dd;
2281 42 : break;
2282 : }
2283 122 : if (TMath::Abs(z+7.3*i)<0.60) {
2284 0 : d+=dd;
2285 0 : if (TMath::Abs(y-0.00)>3.30) d+=dd;
2286 0 : break;
2287 : }
2288 : }
2289 72 : } else
2290 102 : if (6<fR&&fR<8) { //SPD2
2291 34 : Double_t dd=0.0063; x0=21.5;
2292 : d=dd;
2293 52 : if (TMath::Abs(y-3.08)>0.5) d+=dd;
2294 34 : if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2295 34 : } else
2296 68 : if (3<fR&&fR<5) { //SPD1
2297 34 : Double_t dd=0.0063; x0=21.5;
2298 : d=dd;
2299 56 : if (TMath::Abs(y+0.21)>0.6) d+=dd;
2300 40 : if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2301 34 : }
2302 :
2303 212 : return d;
2304 : }
2305 : //------------------------------------------------------------------------
2306 : AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2307 0 : fR(det.fR),
2308 0 : fRmisal(det.fRmisal),
2309 0 : fPhi(det.fPhi),
2310 0 : fSinPhi(det.fSinPhi),
2311 0 : fCosPhi(det.fCosPhi),
2312 0 : fYmin(det.fYmin),
2313 0 : fYmax(det.fYmax),
2314 0 : fZmin(det.fZmin),
2315 0 : fZmax(det.fZmax),
2316 0 : fIsBad(det.fIsBad),
2317 0 : fNChips(det.fNChips),
2318 0 : fChipIsBad(det.fChipIsBad)
2319 0 : {
2320 : //Copy constructor
2321 0 : }
2322 : //------------------------------------------------------------------------
2323 : void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2324 : const AliITSDetTypeRec *detTypeRec)
2325 : {
2326 : //--------------------------------------------------------------------
2327 : // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2328 : //--------------------------------------------------------------------
2329 :
2330 : // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2331 : // while in the tracker they start from 0 for each layer
2332 47580 : for(Int_t il=0; il<ilayer; il++)
2333 17196 : idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2334 :
2335 : Int_t detType;
2336 4396 : if (ilayer==0 || ilayer==1) { // ---------- SPD
2337 : detType = 0;
2338 4396 : } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2339 : detType = 1;
2340 3916 : } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2341 : detType = 2;
2342 : } else {
2343 0 : printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2344 0 : return;
2345 : }
2346 :
2347 : // Get calibration from AliITSDetTypeRec
2348 4396 : AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2349 4396 : calib->SetModuleIndex(idet);
2350 : AliITSCalibration *calibSPDdead = 0;
2351 4876 : if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2352 4876 : if (calib->IsBad() ||
2353 4744 : (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2354 : {
2355 180 : SetBad();
2356 : // printf("lay %d bad %d\n",ilayer,idet);
2357 180 : }
2358 :
2359 : // Get segmentation from AliITSDetTypeRec
2360 4396 : AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2361 :
2362 : // Read info about bad chips
2363 4396 : fNChips = segm->GetMaximumChipIndex()+1;
2364 : //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2365 4396 : if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2366 4396 : fChipIsBad = new Bool_t[fNChips];
2367 103416 : for (Int_t iCh=0;iCh<fNChips;iCh++) {
2368 47312 : fChipIsBad[iCh] = calib->IsChipBad(iCh);
2369 49952 : if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2370 : //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2371 : }
2372 :
2373 : return;
2374 4396 : }
2375 : //------------------------------------------------------------------------
2376 : Double_t AliITStrackerMI::GetEffectiveThickness()
2377 : {
2378 : //--------------------------------------------------------------------
2379 : // Returns the thickness between the current layer and the vertex (units X0)
2380 : //--------------------------------------------------------------------
2381 :
2382 5460 : if(fUseTGeo!=0) {
2383 2734 : if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2384 2734 : if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2385 2734 : if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2386 : }
2387 :
2388 : // beam pipe
2389 8190 : Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2390 2730 : Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2391 :
2392 : // layers
2393 2730 : Double_t x0=0;
2394 2730 : Double_t xn=fgLayers[fI].GetR();
2395 16384 : for (Int_t i=0; i<fI; i++) {
2396 5462 : Double_t xi=fgLayers[i].GetR();
2397 16386 : Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2398 5462 : d+=dLayer*xi*xi;
2399 : }
2400 :
2401 : // shields
2402 2730 : if (fI>1) {
2403 4602 : Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2404 1534 : d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2405 1534 : }
2406 2730 : if (fI>3) {
2407 1752 : Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2408 584 : d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2409 584 : }
2410 5460 : return d/(xn*xn);
2411 2730 : }
2412 :
2413 : //------------------------------------------------------------------------
2414 : Int_t AliITStrackerMI::GetEffectiveThicknessLbyL(Double_t* xMS, Double_t* x2x0MS)
2415 : {
2416 : //--------------------------------------------------------------------
2417 : // Returns the array of layers between the current layer and the vertex
2418 : //--------------------------------------------------------------------
2419 : //
2420 0 : if(fUseTGeo!=0) {
2421 0 : if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2422 0 : if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2423 0 : if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2424 : }
2425 :
2426 : int nl = 0;
2427 0 : double x0 = 0;
2428 0 : for (int il=fI;il--;) {
2429 : //
2430 0 : if (il==3) {
2431 0 : x2x0MS[nl] = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2432 0 : xMS[nl++] = AliITSRecoParam::GetrInsideShield(1);
2433 0 : }
2434 0 : else if (il==1) {
2435 0 : x2x0MS[nl] = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2436 0 : xMS[nl++] = AliITSRecoParam::GetrInsideShield(0);
2437 0 : }
2438 : //
2439 0 : x2x0MS[nl] = (fUseTGeo==0 ? fgLayers[il].GetThickness(0,0,x0) : fxOverX0Layer[il]);
2440 0 : xMS[nl++] = fgLayers[il].GetR();
2441 : //
2442 : }
2443 : //
2444 : // beam pipe
2445 0 : x2x0MS[nl] = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2446 0 : xMS[nl++] = AliITSRecoParam::GetrPipe();
2447 : //
2448 0 : return nl;
2449 0 : }
2450 :
2451 :
2452 : //------------------------------------------------------------------------
2453 : Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2454 : //-------------------------------------------------------------------
2455 : // This function returns number of clusters within the "window"
2456 : //--------------------------------------------------------------------
2457 : Int_t ncl=0;
2458 0 : for (Int_t i=fI; i<fN; i++) {
2459 0 : const AliITSRecPoint *c=fClusters[i];
2460 0 : if (c->GetZ() > fZmax) break;
2461 0 : if (c->IsUsed()) continue;
2462 0 : const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2463 0 : Double_t y=fR*det.GetPhi() + c->GetY();
2464 :
2465 0 : if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2466 0 : if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2467 :
2468 0 : if (y<fYmin) continue;
2469 0 : if (y>fYmax) continue;
2470 0 : ncl++;
2471 0 : }
2472 0 : return ncl;
2473 : }
2474 : //------------------------------------------------------------------------
2475 : Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2476 : const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2477 : {
2478 : //--------------------------------------------------------------------
2479 : // This function refits the track "track" at the position "x" using
2480 : // the clusters from "clusters"
2481 : // If "extra"==kTRUE,
2482 : // the clusters from overlapped modules get attached to "track"
2483 : // If "planeff"==kTRUE,
2484 : // special approach for plane efficiency evaluation is applyed
2485 : //--------------------------------------------------------------------
2486 :
2487 1970 : Int_t index[AliITSgeomTGeo::kNLayers]={0};
2488 : Int_t k;
2489 27580 : for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2490 1970 : Int_t nc=clusters->GetNumberOfClusters();
2491 22872 : for (k=0; k<nc; k++) {
2492 9466 : Int_t idx=clusters->GetClusterIndex(k);
2493 9466 : Int_t ilayer=(idx&0xf0000000)>>28;
2494 9466 : index[ilayer]=idx;
2495 : }
2496 :
2497 3940 : return RefitAt(xx,track,index,extra,planeeff); // call the method below
2498 1970 : }
2499 : //------------------------------------------------------------------------
2500 : Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2501 : const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2502 : {
2503 : //--------------------------------------------------------------------
2504 : // This function refits the track "track" at the position "x" using
2505 : // the clusters from array
2506 : // If "extra"==kTRUE,
2507 : // the clusters from overlapped modules get attached to "track"
2508 : // If "planeff"==kTRUE,
2509 : // special approach for plane efficiency evaluation is applyed
2510 : //--------------------------------------------------------------------
2511 1978 : Int_t index[AliITSgeomTGeo::kNLayers]={0};
2512 : Int_t k;
2513 27692 : for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2514 : //
2515 27692 : for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2516 11868 : index[k]=clusters[k];
2517 : }
2518 :
2519 : // special for cosmics and TPC prolonged tracks:
2520 : // propagate to the innermost of:
2521 : // - innermost layer crossed by the track
2522 : // - innermost layer where a cluster was associated to the track
2523 : static AliITSRecoParam *repa = NULL;
2524 1978 : if(!repa){
2525 2 : repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
2526 2 : if(!repa){
2527 0 : repa = AliITSRecoParam::GetHighFluxParam();
2528 0 : AliWarning("Using default AliITSRecoParam class");
2529 0 : }
2530 : }
2531 1978 : Int_t evsp=repa->GetEventSpecie();
2532 : ULong_t trStatus=0;
2533 3920 : if(track->GetESDtrack()) trStatus=track->GetStatus();
2534 : Int_t innermostlayer=0;
2535 3956 : if((evsp&AliRecoParam::kCosmic) || (trStatus&AliESDtrack::kTPCin)) {
2536 : innermostlayer=5;
2537 1910 : Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2538 3896 : for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2539 1986 : if( (drphi < (fgLayers[innermostlayer].GetR()+1.)) ||
2540 38 : index[innermostlayer] >= 0 ) break;
2541 : }
2542 :
2543 5730 : AliDebug(2,Form(" drphi %f innermost %d",drphi,innermostlayer));
2544 1910 : }
2545 :
2546 : Int_t modstatus=1; // found
2547 1978 : Float_t xloc,zloc;
2548 : Int_t from, to, step;
2549 1978 : if (xx > track->GetX()) {
2550 986 : from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2551 : step=+1;
2552 986 : } else {
2553 992 : from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2554 : step=-1;
2555 : }
2556 1978 : TString dir = (step>0 ? "outward" : "inward");
2557 :
2558 28437 : for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2559 11718 : AliITSlayer &layer=fgLayers[ilayer];
2560 11718 : Double_t r=layer.GetR();
2561 :
2562 17846 : if (step<0 && xx>r) break;
2563 :
2564 : // material between SSD and SDD, SDD and SPD
2565 11408 : Double_t hI=ilayer-0.5*step;
2566 11408 : if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2567 7896 : if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2568 11408 : if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2569 7448 : if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2570 :
2571 :
2572 11408 : Double_t oldGlobXYZ[3]={0};
2573 22816 : if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2574 :
2575 : // continue if we are already beyond this layer
2576 11408 : Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2577 17616 : if(step>0 && oldGlobR > r) continue; // going outward
2578 16608 : if(step<0 && oldGlobR < r) continue; // going inward
2579 :
2580 11100 : Double_t phi,z;
2581 22200 : if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2582 :
2583 11100 : Int_t idet=layer.FindDetectorIndex(phi,z);
2584 :
2585 : // check if we allow a prolongation without point for large-eta tracks
2586 11100 : Int_t skip = CheckSkipLayer(track,ilayer,idet);
2587 11100 : if (skip==2) {
2588 : modstatus = 4; // out in z
2589 0 : if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2590 0 : track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2591 : }
2592 : // cross layer
2593 : // apply correction for material of the current layer
2594 : // add time if going outward
2595 0 : CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2596 0 : continue;
2597 : }
2598 :
2599 11100 : if (idet<0) return kFALSE;
2600 :
2601 :
2602 11100 : const AliITSdetector &det=layer.GetDetector(idet);
2603 : // only for ITS-SA tracks refit
2604 : Bool_t saveCheckInv = kTRUE;
2605 27740 : if (ilayer>1 && fTrackingPhase.Contains("RefitInward") && !(track->GetStatus()&AliESDtrack::kTPCin)) {
2606 64 : saveCheckInv = track->GetCheckInvariant();
2607 64 : track->SetCheckInvariant(kFALSE);
2608 64 : }
2609 : //
2610 22200 : if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2611 :
2612 11100 : track->SetDetectorIndex(idet);
2613 22200 : if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2614 :
2615 11100 : Double_t dz,zmin,zmax,dy,ymin,ymax;
2616 :
2617 : const AliITSRecPoint *clAcc=0;
2618 22200 : Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2619 :
2620 11100 : Int_t idx=index[ilayer];
2621 11100 : if (idx>=0) { // cluster in this layer
2622 : modstatus = 6; // no refit
2623 18980 : const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2624 9490 : if (cl) {
2625 9490 : if (idet != cl->GetDetectorIndex()) {
2626 1430 : idet=cl->GetDetectorIndex();
2627 1430 : const AliITSdetector &detc=layer.GetDetector(idet);
2628 2860 : if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2629 1430 : track->SetDetectorIndex(idet);
2630 2860 : if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2631 1430 : }
2632 9490 : Int_t cllayer = (idx & 0xf0000000) >> 28;;
2633 9490 : Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2634 9490 : if (chi2<maxchi2) {
2635 : clAcc=cl;
2636 : maxchi2=chi2;
2637 : modstatus = 1; // found
2638 : } else {
2639 0 : return kFALSE; //
2640 : }
2641 9490 : }
2642 9490 : } else { // no cluster in this layer
2643 1610 : if (skip==1) {
2644 : modstatus = 3; // skipped
2645 : // Plane Eff determination:
2646 0 : if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2647 0 : if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2648 0 : UseTrackForPlaneEff(track,ilayer);
2649 : }
2650 : } else {
2651 : modstatus = 5; // no cls in road
2652 : // check dead
2653 3220 : if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2654 1610 : dz = 0.5*(zmax-zmin);
2655 1610 : dy = 0.5*(ymax-ymin);
2656 1610 : Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2657 2362 : if (dead==1) modstatus = 7; // holes in z in SPD
2658 1962 : if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2659 : }
2660 : }
2661 :
2662 11100 : if (clAcc) {
2663 18980 : if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2664 9490 : track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2665 : }
2666 11100 : track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2667 :
2668 :
2669 11100 : if (extra && clAcc) { // search for extra clusters in overlapped modules
2670 514 : AliITStrackV2 tmp(*track);
2671 1028 : if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2672 514 : layer.SelectClusters(zmin,zmax,ymin,ymax);
2673 :
2674 514 : const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2675 : Int_t idetExtra=-1;
2676 1028 : maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2677 : Double_t tolerance=0.1;
2678 2746 : while ((clExtra=layer.GetNextCluster(ci))!=0) {
2679 : // only clusters in another module! (overlaps)
2680 602 : idetExtra = clExtra->GetDetectorIndex();
2681 602 : if (idet == idetExtra) continue;
2682 :
2683 68 : const AliITSdetector &detx=layer.GetDetector(idetExtra);
2684 :
2685 136 : if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2686 184 : if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2687 40 : if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2688 40 : if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2689 :
2690 20 : Double_t chi2=tmp.GetPredictedChi2(clExtra);
2691 40 : if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2692 20 : }
2693 514 : if (cci>=0) {
2694 20 : track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2695 20 : track->SetExtraModule(ilayer,idetExtra);
2696 20 : }
2697 1028 : } // end search for extra clusters in overlapped modules
2698 :
2699 : // Correct for material of the current layer
2700 : // cross material
2701 : // add time if going outward
2702 33301 : if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2703 11099 : track->SetCheckInvariant(saveCheckInv);
2704 44707 : } // end loop on layers
2705 :
2706 3955 : if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2707 :
2708 1976 : return kTRUE;
2709 1978 : }
2710 : //------------------------------------------------------------------------
2711 : Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2712 : {
2713 : //
2714 : // calculate normalized chi2
2715 : // return NormalizedChi2(track,0);
2716 : Float_t chi2 = 0;
2717 : Float_t sum=0;
2718 10636 : Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2719 : // track->fdEdxMismatch=0;
2720 : Float_t dedxmismatch =0;
2721 5318 : Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2722 5318 : if (mode<100){
2723 74452 : for (Int_t i = 0;i<6;i++){
2724 31908 : if (track->GetClIndex(i)>=0){
2725 : Float_t cerry, cerrz;
2726 50706 : if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2727 : else
2728 74 : { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2729 25390 : cerry*=cerry;
2730 25390 : cerrz*=cerrz;
2731 25390 : Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2732 45498 : if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2733 20108 : Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2734 20108 : if (ratio<0.5) {
2735 0 : cchi2+=(0.5-ratio)*10.;
2736 : //track->fdEdxMismatch+=(0.5-ratio)*10.;
2737 0 : dedxmismatch+=(0.5-ratio)*10.;
2738 0 : }
2739 20108 : }
2740 25390 : if (i<2 ||i>3){
2741 15190 : AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2742 15190 : Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2743 15680 : if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2744 20472 : if (i<2) chi2+=2*cl->GetDeltaProbability();
2745 15190 : }
2746 25390 : chi2+=cchi2;
2747 25390 : sum++;
2748 25390 : }
2749 : }
2750 5318 : if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2751 0 : track->SetdEdxMismatch(dedxmismatch);
2752 0 : }
2753 : }
2754 : else{
2755 0 : for (Int_t i = 0;i<4;i++){
2756 0 : if (track->GetClIndex(i)>=0){
2757 : Float_t cerry, cerrz;
2758 0 : if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2759 0 : else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2760 0 : cerry*=cerry;
2761 0 : cerrz*=cerrz;
2762 0 : chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2763 0 : chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2764 0 : sum++;
2765 0 : }
2766 : }
2767 0 : for (Int_t i = 4;i<6;i++){
2768 0 : if (track->GetClIndex(i)>=0){
2769 : Float_t cerry, cerrz;
2770 0 : if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2771 0 : else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2772 0 : cerry*=cerry;
2773 0 : cerrz*=cerrz;
2774 : Float_t cerryb, cerrzb;
2775 0 : if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2776 0 : else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2777 0 : cerryb*=cerryb;
2778 0 : cerrzb*=cerrzb;
2779 0 : chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2780 0 : chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2781 0 : sum++;
2782 0 : }
2783 : }
2784 : }
2785 5318 : if (track->GetESDtrack()->GetTPCsignal()>85){
2786 0 : Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2787 0 : if (ratio<0.5) {
2788 0 : chi2+=(0.5-ratio)*5.;
2789 0 : }
2790 0 : if (ratio>2){
2791 0 : chi2+=(ratio-2.0)*3;
2792 0 : }
2793 0 : }
2794 : //
2795 5318 : Double_t match = TMath::Sqrt(track->GetChi22());
2796 8724 : if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2797 5318 : if (!track->GetConstrain()) {
2798 1912 : if (track->GetNumberOfClusters()>2) {
2799 1912 : match/=track->GetNumberOfClusters()-2.;
2800 1912 : } else {
2801 : match=0;
2802 : }
2803 : }
2804 5318 : if (match<0) match=0;
2805 :
2806 : // penalty factor for missing points (NDeadZone>0), but no penalty
2807 : // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2808 : // or there is a dead from OCDB)
2809 : Float_t deadzonefactor = 0.;
2810 5318 : if (track->GetNDeadZone()>0.) {
2811 : Int_t sumDeadZoneProbability=0;
2812 35420 : for(Int_t ilay=0;ilay<6;ilay++) {
2813 17508 : if(track->GetDeadZoneProbability(ilay)>0.) sumDeadZoneProbability++;
2814 : }
2815 2530 : Int_t nDeadZoneWithProbNot1=(Int_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2816 2530 : if(nDeadZoneWithProbNot1>0) {
2817 272 : Float_t deadZoneProbability = track->GetNDeadZone()-(Float_t)sumDeadZoneProbability;
2818 816 : AliDebug(2,Form("nDeadZone %f sumDZProbability %d nDZWithProbNot1 %d deadZoneProb %f\n",track->GetNDeadZone(),sumDeadZoneProbability,nDeadZoneWithProbNot1,deadZoneProbability));
2819 272 : deadZoneProbability /= (Float_t)nDeadZoneWithProbNot1;
2820 : Float_t one = 1.;
2821 272 : deadZoneProbability = TMath::Min(deadZoneProbability,one);
2822 272 : deadzonefactor = 3.*(1.1-deadZoneProbability);
2823 272 : }
2824 2530 : }
2825 :
2826 10636 : Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2827 10636 : (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2828 5318 : 1./(1.+track->GetNSkipped()));
2829 15954 : AliDebug(2,Form("match %f deadzonefactor %f chi2 %f sum %f skipped %f\n",match,deadzonefactor,chi2,sum,track->GetNSkipped()));
2830 15954 : AliDebug(2,Form("NormChi2 %f cls %d\n",normchi2,track->GetNumberOfClusters()));
2831 5318 : return normchi2;
2832 : }
2833 : //------------------------------------------------------------------------
2834 : Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2835 : {
2836 : //
2837 : // return matching chi2 between two tracks
2838 : Double_t largeChi2=1000.;
2839 :
2840 1740 : AliITStrackMI track3(*track2);
2841 3480 : if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2842 870 : TMatrixD vec(5,1);
2843 3480 : vec(0,0)=track1->GetY() - track3.GetY();
2844 3480 : vec(1,0)=track1->GetZ() - track3.GetZ();
2845 3480 : vec(2,0)=track1->GetSnp() - track3.GetSnp();
2846 3480 : vec(3,0)=track1->GetTgl() - track3.GetTgl();
2847 3480 : vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2848 : //
2849 870 : TMatrixD cov(5,5);
2850 1740 : cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2851 1740 : cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2852 3480 : cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2853 1740 : cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2854 1740 : cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2855 :
2856 2610 : cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2857 2610 : cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2858 2610 : cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2859 2610 : cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2860 : //
2861 2610 : cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2862 2610 : cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2863 2610 : cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2864 : //
2865 2610 : cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2866 2610 : cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2867 : //
2868 2610 : cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2869 :
2870 870 : cov.Invert();
2871 870 : TMatrixD vec2(cov,TMatrixD::kMult,vec);
2872 870 : TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2873 1740 : return chi2(0,0);
2874 1740 : }
2875 : //------------------------------------------------------------------------
2876 : Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2877 : {
2878 : //
2879 : // return probability that given point (characterized by z position and error)
2880 : // is in SPD dead zone
2881 : // This method assumes that fSPDdetzcentre is ordered from -z to +z
2882 : //
2883 : Double_t probability = 0.;
2884 : Double_t nearestz = 0.,distz=0.;
2885 : Int_t nearestzone = -1;
2886 : Double_t mindistz = 1000.;
2887 :
2888 : // find closest dead zone
2889 15570 : for (Int_t i=0; i<3; i++) {
2890 5190 : distz=TMath::Abs(zpos-0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]));
2891 5190 : if (distz<mindistz) {
2892 : nearestzone=i;
2893 3460 : nearestz=0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]);
2894 : mindistz=distz;
2895 3460 : }
2896 : }
2897 :
2898 : // too far from dead zone
2899 1852 : if (TMath::Abs(zpos-nearestz)>0.25+3.*zerr) return probability;
2900 :
2901 :
2902 : Double_t zmin, zmax;
2903 1608 : if (nearestzone==0) { // dead zone at z = -7
2904 0 : zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2905 0 : zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2906 1608 : } else if (nearestzone==1) { // dead zone at z = 0
2907 1608 : zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2908 1608 : zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2909 1608 : } else if (nearestzone==2) { // dead zone at z = +7
2910 0 : zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2911 0 : zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2912 0 : } else {
2913 : zmin = 0.;
2914 : zmax = 0.;
2915 : }
2916 : // probability that the true z is in the range [zmin,zmax] (i.e. inside
2917 : // dead zone)
2918 3216 : probability = 0.5*( AliMathBase::ErfFast((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2919 1608 : AliMathBase::ErfFast((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2920 4824 : AliDebug(2,Form("zpos %f +- %f nearestzone %d zmin zmax %f %f prob %f\n",zpos,zerr,nearestzone,zmin,zmax,probability));
2921 : return probability;
2922 1730 : }
2923 : //------------------------------------------------------------------------
2924 : Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2925 : {
2926 : //
2927 : // calculate normalized chi2
2928 0 : Float_t chi2[6]={0};
2929 0 : Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2930 : Float_t ncl = 0;
2931 0 : for (Int_t i = 0;i<6;i++){
2932 0 : if (TMath::Abs(track->GetDy(i))>0){
2933 0 : chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2934 0 : chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2935 0 : ncl++;
2936 0 : }
2937 0 : else{chi2[i]=10000;}
2938 : }
2939 0 : Int_t index[6]={0};
2940 0 : TMath::Sort(6,chi2,index,kFALSE);
2941 0 : Float_t max = float(ncl)*fac-1.;
2942 : Float_t sumchi=0, sumweight=0;
2943 0 : for (Int_t i=0;i<max+1;i++){
2944 0 : Float_t weight = (i<max)?1.:(max+1.-i);
2945 0 : sumchi+=weight*chi2[index[i]];
2946 0 : sumweight+=weight;
2947 : }
2948 0 : Double_t normchi2 = sumchi/sumweight;
2949 0 : return normchi2;
2950 0 : }
2951 : //------------------------------------------------------------------------
2952 : Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2953 : {
2954 : //
2955 : // calculate normalized chi2
2956 : // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2957 : Int_t npoints = 0;
2958 : Double_t res =0;
2959 13020 : for (Int_t i=0;i<6;i++){
2960 9538 : if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2961 4116 : Double_t sy1 = forwardtrack->GetSigmaY(i);
2962 4116 : Double_t sz1 = forwardtrack->GetSigmaZ(i);
2963 4116 : Double_t sy2 = backtrack->GetSigmaY(i);
2964 4116 : Double_t sz2 = backtrack->GetSigmaZ(i);
2965 4942 : if (i<2){ sy2=1000.;sz2=1000;}
2966 : //
2967 4116 : Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2968 4116 : Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2969 : //
2970 4116 : Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2971 4116 : Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2972 : //
2973 4116 : res+= nz0*nz0+ny0*ny0;
2974 4116 : npoints++;
2975 4116 : }
2976 1736 : if (npoints>1) return
2977 1736 : TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2978 : //2*forwardtrack->fNUsed+
2979 1736 : res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2980 868 : 1./(1.+forwardtrack->GetNSkipped()));
2981 0 : return 1000;
2982 868 : }
2983 : /*
2984 : RS: Not used
2985 : //------------------------------------------------------------------------
2986 : Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2987 : //--------------------------------------------------------------------
2988 : // Return pointer to a given cluster
2989 : //--------------------------------------------------------------------
2990 : Int_t l=(index & 0xf0000000) >> 28;
2991 : Int_t c=(index & 0x0fffffff) >> 00;
2992 : return fgLayers[l].GetWeight(c);
2993 : }
2994 : */
2995 :
2996 : //------------------------------------------------------------------------
2997 : void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2998 : {
2999 : //---------------------------------------------
3000 : // register track to the list
3001 : //
3002 512 : if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
3003 : //
3004 : //
3005 2960 : for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
3006 1224 : Int_t index = track->GetClusterIndex(icluster);
3007 1224 : Int_t l=(index & 0xf0000000) >> 28;
3008 1224 : Int_t c=(index & 0x0fffffff) >> 00;
3009 1224 : if (c>fgLayers[l].GetNumberOfClusters()) continue;
3010 3304 : for (Int_t itrack=0;itrack<4;itrack++){
3011 1652 : if (fgLayers[l].GetClusterTracks(itrack,c)<0){
3012 1224 : fgLayers[l].SetClusterTracks(itrack,c,id);
3013 1224 : break;
3014 : }
3015 : }
3016 1224 : }
3017 256 : }
3018 : //------------------------------------------------------------------------
3019 : void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
3020 : {
3021 : //---------------------------------------------
3022 : // unregister track from the list
3023 2218 : for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
3024 812 : Int_t index = track->GetClusterIndex(icluster);
3025 812 : Int_t l=(index & 0xf0000000) >> 28;
3026 812 : Int_t c=(index & 0x0fffffff) >> 00;
3027 812 : if (c>fgLayers[l].GetNumberOfClusters()) continue;
3028 8120 : for (Int_t itrack=0;itrack<4;itrack++){
3029 3248 : if (fgLayers[l].GetClusterTracks(itrack,c)==id){
3030 464 : fgLayers[l].SetClusterTracks(itrack,c,-1);
3031 464 : }
3032 : }
3033 812 : }
3034 198 : }
3035 : //------------------------------------------------------------------------
3036 : Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
3037 : {
3038 : //-------------------------------------------------------------
3039 : //get number of shared clusters
3040 : //-------------------------------------------------------------
3041 : Float_t shared=0;
3042 19620 : for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
3043 : // mean number of clusters
3044 1308 : Float_t *ny = GetNy(id), *nz = GetNz(id);
3045 :
3046 :
3047 15180 : for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
3048 6282 : Int_t index = track->GetClusterIndex(icluster);
3049 6282 : Int_t l=(index & 0xf0000000) >> 28;
3050 6282 : Int_t c=(index & 0x0fffffff) >> 00;
3051 6282 : if (c>fgLayers[l].GetNumberOfClusters()) continue;
3052 : // if (ny[l]<1.e-13){
3053 : // printf("problem\n");
3054 : // }
3055 6282 : AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
3056 : Float_t weight=1;
3057 : //
3058 : Float_t deltan = 0;
3059 8818 : if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
3060 9954 : if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
3061 5353 : if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
3062 4601 : if (l<2 || l>3){
3063 2638 : deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
3064 2638 : }
3065 : else{
3066 1963 : deltan = (cl->GetNz()-nz[l]);
3067 : }
3068 4633 : if (deltan>2.0) continue; // extended - highly probable shared cluster
3069 4569 : weight = 2./TMath::Max(3.+deltan,2.);
3070 : //
3071 49339 : for (Int_t itrack=0;itrack<4;itrack++){
3072 21018 : if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
3073 112 : list[l]=index;
3074 112 : clist[l] = (AliITSRecPoint*)GetCluster(index);
3075 112 : track->SetSharedWeight(l,weight);
3076 112 : shared+=weight;
3077 112 : break;
3078 : }
3079 : }
3080 4569 : }
3081 1308 : track->SetNUsed(shared);
3082 1308 : return shared;
3083 : }
3084 : //------------------------------------------------------------------------
3085 : Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
3086 : {
3087 : //
3088 : // find first shared track
3089 : //
3090 : // mean number of clusters
3091 20 : Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
3092 : //
3093 140 : for (Int_t i=0;i<6;i++) overlist[i]=-1;
3094 : Int_t sharedtrack=100000;
3095 10 : Int_t tracks[24]={0},trackindex=0;
3096 500 : for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
3097 : //
3098 140 : for (Int_t icluster=0;icluster<6;icluster++){
3099 60 : if (clusterlist[icluster]<0) continue;
3100 : Int_t index = clusterlist[icluster];
3101 10 : Int_t l=(index & 0xf0000000) >> 28;
3102 10 : Int_t c=(index & 0x0fffffff) >> 00;
3103 : // if (ny[l]<1.e-13){
3104 : // printf("problem\n");
3105 : // }
3106 10 : if (c>fgLayers[l].GetNumberOfClusters()) continue;
3107 : //if (l>3) continue;
3108 10 : AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
3109 : //
3110 : Float_t deltan = 0;
3111 10 : if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
3112 14 : if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
3113 4 : if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
3114 10 : if (l<2 || l>3){
3115 0 : deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
3116 0 : }
3117 : else{
3118 10 : deltan = (cl->GetNz()-nz[l]);
3119 : }
3120 10 : if (deltan>2.0) continue; // extended - highly probable shared cluster
3121 : //
3122 100 : for (Int_t itrack=3;itrack>=0;itrack--){
3123 40 : if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
3124 12 : if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
3125 12 : tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
3126 12 : trackindex++;
3127 12 : }
3128 : }
3129 10 : }
3130 10 : if (trackindex==0) return -1;
3131 10 : if (trackindex==1){
3132 8 : sharedtrack = tracks[0];
3133 8 : }else{
3134 4 : if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
3135 : else{
3136 : //
3137 0 : Int_t tracks2[24]={0}, cluster[24]={0};
3138 0 : for (Int_t i=0;i<24;i++){ tracks2[i]=-1; cluster[i]=0;}
3139 : Int_t index =0;
3140 : //
3141 0 : for (Int_t i=0;i<trackindex;i++){
3142 0 : if (tracks[i]<0) continue;
3143 0 : tracks2[index] = tracks[i];
3144 0 : cluster[index]++;
3145 0 : for (Int_t j=i+1;j<trackindex;j++){
3146 0 : if (tracks[j]<0) continue;
3147 0 : if (tracks[j]==tracks[i]){
3148 0 : cluster[index]++;
3149 0 : tracks[j]=-1;
3150 0 : }
3151 : }
3152 0 : index++;
3153 0 : }
3154 : Int_t max=0;
3155 0 : for (Int_t i=0;i<index;i++){
3156 0 : if (cluster[index]>max) {
3157 0 : sharedtrack=tracks2[index];
3158 : max=cluster[index];
3159 0 : }
3160 : }
3161 0 : }
3162 : }
3163 :
3164 10 : if (sharedtrack>=100000) return -1;
3165 : //
3166 : // make list of overlaps
3167 10 : shared =0;
3168 140 : for (Int_t icluster=0;icluster<6;icluster++){
3169 60 : if (clusterlist[icluster]<0) continue;
3170 : Int_t index = clusterlist[icluster];
3171 10 : Int_t l=(index & 0xf0000000) >> 28;
3172 10 : Int_t c=(index & 0x0fffffff) >> 00;
3173 10 : if (c>fgLayers[l].GetNumberOfClusters()) continue;
3174 10 : AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
3175 10 : if (l==0 || l==1){
3176 0 : if (cl->GetNy()>2) continue;
3177 0 : if (cl->GetNz()>2) continue;
3178 : }
3179 10 : if (l==4 || l==5){
3180 0 : if (cl->GetNy()>3) continue;
3181 0 : if (cl->GetNz()>3) continue;
3182 : }
3183 : //
3184 100 : for (Int_t itrack=3;itrack>=0;itrack--){
3185 40 : if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
3186 12 : if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
3187 12 : overlist[l]=index;
3188 12 : shared++;
3189 12 : }
3190 : }
3191 10 : }
3192 10 : return sharedtrack;
3193 10 : }
3194 : //------------------------------------------------------------------------
3195 : AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1,AliITStrackMI* original){
3196 : //
3197 : // try to find track hypothesys without conflicts
3198 : // with minimal chi2;
3199 20 : TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
3200 10 : Int_t entries1 = arr1->GetEntriesFast();
3201 10 : TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
3202 10 : if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
3203 10 : Int_t entries2 = arr2->GetEntriesFast();
3204 10 : if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
3205 : //
3206 10 : AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
3207 10 : AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
3208 10 : if (track10->Pt()>0.5+track20->Pt()) return track10;
3209 : //
3210 84 : for (Int_t itrack=0;itrack<entries1;itrack++){
3211 32 : AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3212 32 : UnRegisterClusterTracks(track,trackID1);
3213 : }
3214 : //
3215 52 : for (Int_t itrack=0;itrack<entries2;itrack++){
3216 16 : AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3217 16 : UnRegisterClusterTracks(track,trackID2);
3218 : }
3219 : Int_t index1=0;
3220 : Int_t index2=0;
3221 : Float_t maxconflicts=6;
3222 : Double_t maxchi2 =1000.;
3223 : //
3224 : // get weight of hypothesys - using best hypothesy
3225 : Double_t w1,w2;
3226 :
3227 10 : Int_t list1[6]={0},list2[6]={0};
3228 10 : AliITSRecPoint *clist1[6]={0}, *clist2[6]={0} ;
3229 10 : RegisterClusterTracks(track10,trackID1);
3230 10 : RegisterClusterTracks(track20,trackID2);
3231 10 : Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
3232 10 : Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
3233 10 : UnRegisterClusterTracks(track10,trackID1);
3234 10 : UnRegisterClusterTracks(track20,trackID2);
3235 : //
3236 : // normalized chi2
3237 : Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
3238 10 : Float_t nerry[6]={0},nerrz[6]={0};
3239 10 : Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
3240 10 : Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
3241 140 : for (Int_t i=0;i<6;i++){
3242 102 : if ( (erry1[i]>0) && (erry2[i]>0)) {
3243 42 : nerry[i] = TMath::Min(erry1[i],erry2[i]);
3244 42 : nerrz[i] = TMath::Min(errz1[i],errz2[i]);
3245 42 : }else{
3246 18 : nerry[i] = TMath::Max(erry1[i],erry2[i]);
3247 18 : nerrz[i] = TMath::Max(errz1[i],errz2[i]);
3248 : }
3249 60 : if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
3250 42 : chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
3251 42 : chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
3252 42 : ncl1++;
3253 42 : }
3254 60 : if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
3255 40 : chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
3256 40 : chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
3257 40 : ncl2++;
3258 40 : }
3259 : }
3260 10 : chi21/=ncl1;
3261 10 : chi22/=ncl2;
3262 : //
3263 : //
3264 10 : Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
3265 10 : Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
3266 10 : Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
3267 10 : Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
3268 : //
3269 20 : w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
3270 10 : +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
3271 10 : +1.*track10->Pt()/(track10->Pt()+track20->Pt())
3272 : );
3273 20 : w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
3274 10 : s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
3275 10 : +1.*track20->Pt()/(track10->Pt()+track20->Pt())
3276 : );
3277 :
3278 10 : Double_t sumw = w1+w2;
3279 10 : w1/=sumw;
3280 10 : w2/=sumw;
3281 10 : if (w1<w2*0.5) {
3282 4 : w1 = (d2+0.5)/(d1+d2+1.);
3283 4 : w2 = (d1+0.5)/(d1+d2+1.);
3284 4 : }
3285 : // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
3286 : //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
3287 : //
3288 : // get pair of "best" hypothesys
3289 : //
3290 10 : Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
3291 10 : Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
3292 :
3293 84 : for (Int_t itrack1=0;itrack1<entries1;itrack1++){
3294 32 : AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
3295 : //if (track1->fFakeRatio>0) continue;
3296 32 : RegisterClusterTracks(track1,trackID1);
3297 164 : for (Int_t itrack2=0;itrack2<entries2;itrack2++){
3298 50 : AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
3299 :
3300 : // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
3301 : //if (track2->fFakeRatio>0) continue;
3302 : Float_t nskipped=0;
3303 50 : RegisterClusterTracks(track2,trackID2);
3304 50 : Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
3305 50 : Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
3306 50 : UnRegisterClusterTracks(track2,trackID2);
3307 : //
3308 66 : if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
3309 82 : if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
3310 66 : if (nskipped>0.5) continue;
3311 : //
3312 : //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
3313 34 : if (conflict1+1<cconflict1) continue;
3314 34 : if (conflict2+1<cconflict2) continue;
3315 : Float_t conflict=0;
3316 : Float_t sumchi2=0;
3317 : Float_t sum=0;
3318 476 : for (Int_t i=0;i<6;i++){
3319 : //
3320 : Float_t c1 =0.; // conflict coeficients
3321 : Float_t c2 =0.;
3322 234 : if (clist1[i]&&clist2[i]){
3323 : Float_t deltan = 0;
3324 30 : if (i<2 || i>3){
3325 0 : deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
3326 0 : }
3327 : else{
3328 30 : deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
3329 : }
3330 30 : c1 = 2./TMath::Max(3.+deltan,2.);
3331 30 : c2 = 2./TMath::Max(3.+deltan,2.);
3332 30 : }
3333 : else{
3334 174 : if (clist1[i]){
3335 : Float_t deltan = 0;
3336 0 : if (i<2 || i>3){
3337 0 : deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
3338 0 : }
3339 : else{
3340 0 : deltan = (clist1[i]->GetNz()-nz1[i]);
3341 : }
3342 0 : c1 = 2./TMath::Max(3.+deltan,2.);
3343 : c2 = 0;
3344 0 : }
3345 :
3346 174 : if (clist2[i]){
3347 : Float_t deltan = 0;
3348 0 : if (i<2 || i>3){
3349 0 : deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
3350 0 : }
3351 : else{
3352 0 : deltan = (clist2[i]->GetNz()-nz2[i]);
3353 : }
3354 0 : c2 = 2./TMath::Max(3.+deltan,2.);
3355 : c1 = 0;
3356 0 : }
3357 : }
3358 : //
3359 : chi21=0;chi22=0;
3360 204 : if (TMath::Abs(track1->GetDy(i))>0.) {
3361 296 : chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
3362 148 : (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
3363 : //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
3364 : // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
3365 148 : }else{
3366 56 : if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
3367 : }
3368 : //
3369 204 : if (TMath::Abs(track2->GetDy(i))>0.) {
3370 272 : chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
3371 136 : (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
3372 : //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
3373 : // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3374 136 : }
3375 : else{
3376 86 : if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3377 : }
3378 204 : sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3379 352 : if (chi21>0) sum+=w1;
3380 340 : if (chi22>0) sum+=w2;
3381 204 : conflict+=(c1+c2);
3382 : }
3383 34 : Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3384 34 : if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3385 34 : Double_t normchi2 = 2*conflict+sumchi2/sum;
3386 34 : if ( normchi2 <maxchi2 ){
3387 : index1 = itrack1;
3388 : index2 = itrack2;
3389 : maxconflicts = conflict;
3390 : maxchi2 = normchi2;
3391 20 : }
3392 34 : }
3393 32 : UnRegisterClusterTracks(track1,trackID1);
3394 : }
3395 : //
3396 : // if (maxconflicts<4 && maxchi2<th0){
3397 10 : if (maxchi2<th0*2.){
3398 10 : Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3399 10 : AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3400 10 : track1->SetChi2MIP(5,maxconflicts);
3401 10 : track1->SetChi2MIP(6,maxchi2);
3402 10 : track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3403 : // track1->UpdateESDtrack(AliESDtrack::kITSin);
3404 10 : track1->SetChi2MIP(8,index1);
3405 10 : fBestTrackIndex[trackID1] =index1;
3406 10 : UpdateESDtrack(track1, AliESDtrack::kITSin);
3407 10 : original->SetWinner(track1);
3408 10 : }
3409 0 : else if (track10->GetChi2MIP(0)<th1){
3410 0 : track10->SetChi2MIP(5,maxconflicts);
3411 0 : track10->SetChi2MIP(6,maxchi2);
3412 : // track10->UpdateESDtrack(AliESDtrack::kITSin);
3413 0 : UpdateESDtrack(track10,AliESDtrack::kITSin);
3414 0 : original->SetWinner(track10);
3415 0 : }
3416 :
3417 84 : for (Int_t itrack=0;itrack<entries1;itrack++){
3418 32 : AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3419 32 : UnRegisterClusterTracks(track,trackID1);
3420 : }
3421 : //
3422 52 : for (Int_t itrack=0;itrack<entries2;itrack++){
3423 16 : AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3424 16 : UnRegisterClusterTracks(track,trackID2);
3425 : }
3426 :
3427 28 : if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3428 18 : &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3429 : // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3430 : // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3431 0 : RegisterClusterTracks(track10,trackID1);
3432 0 : }
3433 40 : if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3434 30 : &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3435 : //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3436 : // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3437 10 : RegisterClusterTracks(track20,trackID2);
3438 10 : }
3439 : return track10;
3440 :
3441 20 : }
3442 : //------------------------------------------------------------------------
3443 : void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3444 : //--------------------------------------------------------------------
3445 : // This function marks clusters assigned to the track
3446 : //--------------------------------------------------------------------
3447 0 : AliTracker::UseClusters(t,from);
3448 :
3449 0 : AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3450 : //if (c->GetQ()>2) c->Use();
3451 0 : if (c->GetSigmaZ2()>0.1) c->Use();
3452 0 : c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3453 : //if (c->GetQ()>2) c->Use();
3454 0 : if (c->GetSigmaZ2()>0.1) c->Use();
3455 :
3456 0 : }
3457 : //------------------------------------------------------------------------
3458 : void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3459 : {
3460 : //------------------------------------------------------------------
3461 : // add track to the list of hypothesys
3462 : //------------------------------------------------------------------
3463 :
3464 : //
3465 1900 : TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3466 950 : if (!array) {
3467 82 : array = new TObjArray(10);
3468 82 : fTrackHypothesys.AddAtAndExpand(array,esdindex);
3469 82 : }
3470 950 : array->AddLast(track);
3471 950 : }
3472 : //------------------------------------------------------------------------
3473 : void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3474 : {
3475 : //-------------------------------------------------------------------
3476 : // compress array of track hypothesys
3477 : // keep only maxsize best hypothesys
3478 : //-------------------------------------------------------------------
3479 728 : if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3480 362 : if (! (fTrackHypothesys.At(esdindex)) ) return;
3481 316 : TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3482 316 : Int_t entries = array->GetEntriesFast();
3483 : //
3484 : //- find preliminary besttrack as a reference
3485 : Float_t minchi2=10000;
3486 : Int_t maxn=0;
3487 : AliITStrackMI * besttrack=0;
3488 : //
3489 4164 : for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3490 1766 : AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3491 1766 : if (!track) continue;
3492 1766 : Float_t chi2 = NormalizedChi2(track,0);
3493 : //
3494 1766 : Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3495 1766 : track->SetLabel(tpcLabel);
3496 1766 : CookdEdx(track);
3497 1766 : track->SetFakeRatio(1.);
3498 1766 : CookLabel(track,0.); //For comparison only
3499 : //
3500 : //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3501 1766 : if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3502 2824 : if (track->GetNumberOfClusters()<maxn) continue;
3503 704 : maxn = track->GetNumberOfClusters();
3504 : // if (fSelectBestMIP03 && track->GetChi2MIP(3)>0) chi2 *= track->GetChi2MIP(3); // RS
3505 704 : if (chi2<minchi2){
3506 : minchi2=chi2;
3507 : besttrack=track;
3508 392 : }
3509 : }
3510 : else{
3511 2 : if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3512 4 : delete array->RemoveAt(itrack);
3513 : }
3514 : }
3515 706 : }
3516 316 : if (!besttrack) return;
3517 : //
3518 : //
3519 : //take errors of best track as a reference
3520 316 : Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3521 316 : Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3522 4424 : for (Int_t j=0;j<6;j++) {
3523 1896 : if (besttrack->GetClIndex(j)>=0){
3524 1660 : erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3525 1660 : errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3526 1660 : ny[j] = besttrack->GetNy(j);
3527 1660 : nz[j] = besttrack->GetNz(j);
3528 1660 : }
3529 : }
3530 : //
3531 : // calculate normalized chi2
3532 : //
3533 316 : Float_t * chi2 = new Float_t[entries];
3534 316 : Int_t * index = new Int_t[entries];
3535 4164 : for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3536 4164 : for (Int_t itrack=0;itrack<entries;itrack++){
3537 1766 : AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3538 1766 : if (track){
3539 5292 : AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3540 1764 : double chi2t = GetNormalizedChi2(track, mode);
3541 1764 : track->SetChi2MIP(0,chi2t);
3542 1764 : if (chi2t<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)) {
3543 1616 : if (fSelectBestMIP03 && track->GetChi2MIP(3)>0) chi2t *= track->GetChi2MIP(3); // RS
3544 1616 : chi2[itrack] = chi2t;
3545 1616 : }
3546 : else{
3547 154 : if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3548 284 : delete array->RemoveAt(itrack);
3549 : }
3550 : }
3551 1764 : }
3552 : }
3553 : //
3554 316 : TMath::Sort(entries,chi2,index,kFALSE);
3555 316 : besttrack = (AliITStrackMI*)array->At(index[0]);
3556 1264 : if(besttrack) AliDebug(2,Form("ncls best track %d\n",besttrack->GetNumberOfClusters()));
3557 632 : if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3558 4424 : for (Int_t j=0;j<6;j++){
3559 1896 : if (besttrack->GetClIndex(j)>=0){
3560 1664 : erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3561 1664 : errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3562 1664 : ny[j] = besttrack->GetNy(j);
3563 1664 : nz[j] = besttrack->GetNz(j);
3564 1664 : }
3565 : }
3566 316 : }
3567 : //
3568 : // calculate one more time with updated normalized errors
3569 4164 : for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3570 4164 : for (Int_t itrack=0;itrack<entries;itrack++){
3571 1766 : AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3572 1766 : if (track){
3573 1622 : double chi2t = GetNormalizedChi2(track, mode);
3574 1622 : track->SetChi2MIP(0,chi2t);
3575 4866 : AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3576 1622 : if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)) {
3577 1610 : if (fSelectBestMIP03 && track->GetChi2MIP(3)>0) chi2t *= track->GetChi2MIP(3); // RS
3578 1610 : chi2[itrack] = chi2t; //-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3579 1610 : }
3580 : else {
3581 18 : if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3582 12 : delete array->RemoveAt(itrack);
3583 : }
3584 : }
3585 1622 : }
3586 : }
3587 316 : entries = array->GetEntriesFast();
3588 : //
3589 : //
3590 316 : if (entries>0){
3591 316 : TObjArray * newarray = new TObjArray();
3592 316 : TMath::Sort(entries,chi2,index,kFALSE);
3593 316 : besttrack = (AliITStrackMI*)array->At(index[0]);
3594 316 : if (besttrack){
3595 948 : AliDebug(2,Form("ncls best track %d %f %f\n",besttrack->GetNumberOfClusters(),besttrack->GetChi2MIP(0),chi2[index[0]]));
3596 : //
3597 4424 : for (Int_t j=0;j<6;j++){
3598 3562 : if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3599 1666 : erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3600 1666 : errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3601 1666 : ny[j] = besttrack->GetNy(j);
3602 1666 : nz[j] = besttrack->GetNz(j);
3603 1666 : }
3604 : }
3605 316 : besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3606 316 : minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3607 316 : Float_t minn = besttrack->GetNumberOfClusters()-3;
3608 : Int_t accepted=0;
3609 4444 : for (Int_t i=0;i<entries;i++){
3610 1748 : AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3611 1880 : if (!track) continue;
3612 1616 : if (accepted>maxcut) break;
3613 1616 : track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3614 2224 : if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3615 1928 : if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3616 220 : delete array->RemoveAt(index[i]);
3617 110 : continue;
3618 : }
3619 : }
3620 3620 : Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3621 3012 : if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3622 2492 : if (!shortbest) accepted++;
3623 : //
3624 1506 : newarray->AddLast(array->RemoveAt(index[i]));
3625 21084 : for (Int_t j=0;j<6;j++){
3626 9036 : if (nz[j]==0){
3627 0 : erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3628 0 : errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3629 0 : ny[j] = track->GetNy(j);
3630 0 : nz[j] = track->GetNz(j);
3631 0 : }
3632 : }
3633 1506 : }
3634 : else{
3635 0 : delete array->RemoveAt(index[i]);
3636 : }
3637 1506 : }
3638 316 : array->Delete();
3639 632 : delete fTrackHypothesys.RemoveAt(esdindex);
3640 316 : fTrackHypothesys.AddAt(newarray,esdindex);
3641 316 : }
3642 : else{
3643 0 : array->Delete();
3644 0 : delete fTrackHypothesys.RemoveAt(esdindex);
3645 : }
3646 316 : }
3647 632 : delete [] chi2;
3648 632 : delete [] index;
3649 680 : }
3650 : //------------------------------------------------------------------------
3651 : AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3652 : {
3653 : //-------------------------------------------------------------
3654 : // try to find best hypothesy
3655 : // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3656 : // RS: optionally changing this to product of Chi2MIP(0)*Chi2MIP(3) == (chi2*chi2_interpolated)
3657 : //-------------------------------------------------------------
3658 442 : if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3659 176 : TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3660 194 : if (!array) return 0;
3661 158 : Int_t entries = array->GetEntriesFast();
3662 158 : if (!entries) return 0;
3663 : Float_t minchi2 = 100000;
3664 : AliITStrackMI * besttrack=0;
3665 : //
3666 158 : AliITStrackMI * backtrack = new AliITStrackMI(*original);
3667 158 : AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3668 158 : Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3669 158 : Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3670 : //
3671 2056 : for (Int_t i=0;i<entries;i++){
3672 870 : AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3673 870 : if (!track) continue;
3674 870 : Float_t sigmarfi,sigmaz;
3675 870 : GetDCASigma(track,sigmarfi,sigmaz);
3676 870 : track->SetDnorm(0,sigmarfi);
3677 870 : track->SetDnorm(1,sigmaz);
3678 : //
3679 870 : track->SetChi2MIP(1,1000000);
3680 870 : track->SetChi2MIP(2,1000000);
3681 870 : track->SetChi2MIP(3,1000000);
3682 : //
3683 : // backtrack
3684 870 : backtrack = new(backtrack) AliITStrackMI(*track);
3685 870 : if (track->GetConstrain()) {
3686 1132 : if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3687 566 : if (AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
3688 0 : if (fUseImproveKalman) {if (!backtrack->ImproveKalman(xyzVtx,ersVtx,0,0,0)) continue;}
3689 0 : else {if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;}
3690 : }
3691 566 : backtrack->ResetCovariance(10.);
3692 566 : }else{
3693 304 : backtrack->ResetCovariance(10.);
3694 : }
3695 870 : backtrack->ResetClusters();
3696 :
3697 870 : Double_t x = original->GetX();
3698 870 : if (!RefitAt(x,backtrack,track)) continue;
3699 : //
3700 870 : track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3701 : //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3702 870 : if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3703 870 : track->SetChi22(GetMatchingChi2(backtrack,original));
3704 :
3705 1436 : if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3706 1176 : if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3707 868 : if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3708 :
3709 :
3710 1170 : if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3711 : //
3712 : //forward track - without constraint
3713 868 : forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3714 868 : forwardtrack->ResetClusters();
3715 868 : x = track->GetX();
3716 868 : if (!RefitAt(x,forwardtrack,track) && fSelectBestMIP03) continue; // w/o fwd track MIP03 is meaningless
3717 868 : track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3718 868 : if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3719 1170 : if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3720 :
3721 : //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3722 : //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3723 868 : forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3724 868 : forwardtrack->SetD(0,track->GetD(0));
3725 868 : forwardtrack->SetD(1,track->GetD(1));
3726 : {
3727 868 : Int_t list[6]={0};
3728 868 : AliITSRecPoint* clist[6]={0};
3729 868 : track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3730 1170 : if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3731 1736 : }
3732 :
3733 868 : track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3734 868 : if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3735 1170 : if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3736 0 : track->SetChi2MIP(3,1000);
3737 0 : continue;
3738 : }
3739 868 : Double_t chi2 = track->GetChi2MIP(0); // +track->GetNUsed(); //RS
3740 868 : if (fSelectBestMIP03) chi2 *= track->GetChi2MIP(3);
3741 868 : else chi2 += track->GetNUsed();
3742 : //
3743 10416 : for (Int_t ichi=0;ichi<5;ichi++){
3744 4340 : forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3745 : }
3746 868 : if (chi2 < minchi2){
3747 : //besttrack = new AliITStrackMI(*forwardtrack);
3748 : besttrack = track;
3749 158 : besttrack->SetLabel(track->GetLabel());
3750 158 : besttrack->SetFakeRatio(track->GetFakeRatio());
3751 158 : minchi2 = chi2;
3752 : //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3753 : //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3754 158 : forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3755 158 : }
3756 1738 : }
3757 316 : delete backtrack;
3758 316 : delete forwardtrack;
3759 :
3760 158 : if (!besttrack) return 0;
3761 :
3762 : Int_t accepted=0;
3763 2056 : for (Int_t i=0;i<entries;i++){
3764 870 : AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3765 :
3766 870 : if (!track) continue;
3767 :
3768 2560 : if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3769 868 : (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)
3770 : // RS: don't apply this cut when fSelectBestMIP03 is on
3771 2508 : || (!fSelectBestMIP03 && (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.))
3772 : ){
3773 530 : if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3774 468 : delete array->RemoveAt(i);
3775 234 : continue;
3776 : }
3777 : }
3778 : else{
3779 488 : accepted++;
3780 : }
3781 636 : }
3782 : //
3783 158 : array->Compress();
3784 158 : SortTrackHypothesys(esdindex,checkmax,1);
3785 :
3786 158 : array = (TObjArray*) fTrackHypothesys.At(esdindex);
3787 158 : if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3788 158 : besttrack = (AliITStrackMI*)array->At(0);
3789 158 : if (!besttrack) return 0;
3790 158 : besttrack->SetChi2MIP(8,0);
3791 158 : fBestTrackIndex[esdindex]=0;
3792 158 : entries = array->GetEntriesFast();
3793 : AliITStrackMI *longtrack =0;
3794 : minchi2 =1000;
3795 158 : Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3796 1272 : for (Int_t itrack=entries-1;itrack>0;itrack--) {
3797 478 : AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3798 776 : if (!track->GetConstrain()) continue;
3799 304 : if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3800 112 : if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3801 0 : if (track->GetChi2MIP(0)>4.) continue;
3802 0 : minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3803 : longtrack =track;
3804 0 : }
3805 : //if (longtrack) besttrack=longtrack;
3806 : //
3807 : // RS do shared cluster analysis here only if the new sharing analysis is not requested
3808 : //RRR if (fFlagFakes) return besttrack;
3809 :
3810 158 : Int_t list[6]={0};
3811 158 : AliITSRecPoint * clist[6]={0};
3812 158 : Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3813 614 : if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3814 456 : &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3815 144 : RegisterClusterTracks(besttrack,esdindex);
3816 144 : }
3817 : //
3818 : //
3819 158 : if (shared>0.0){
3820 4 : Int_t nshared;
3821 4 : Int_t overlist[6]={0};
3822 4 : Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3823 4 : if (sharedtrack>=0){
3824 : //
3825 4 : besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5,original);
3826 4 : if (besttrack){
3827 4 : shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3828 : }
3829 0 : else return 0;
3830 4 : }
3831 8 : }
3832 :
3833 158 : if (shared>2.5) return 0;
3834 158 : if (shared>1.0) return besttrack;
3835 : //
3836 : // Don't sign clusters if not gold track
3837 : //
3838 316 : if (!besttrack->IsGoldPrimary()) return besttrack;
3839 0 : if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3840 : //
3841 0 : if (fConstraint[fPass]){
3842 : //
3843 : // sign clusters
3844 : //
3845 0 : Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3846 0 : for (Int_t i=0;i<6;i++){
3847 0 : Int_t index = besttrack->GetClIndex(i);
3848 0 : if (index<0) continue;
3849 0 : Int_t ilayer = (index & 0xf0000000) >> 28;
3850 0 : if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3851 0 : AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3852 0 : if (!c) continue;
3853 0 : if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3854 0 : if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3855 0 : if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3856 0 : if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3857 0 : if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3858 : //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3859 :
3860 : Bool_t cansign = kTRUE;
3861 0 : for (Int_t itrack=0;itrack<entries; itrack++){
3862 0 : AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3863 0 : if (!track) continue;
3864 0 : if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3865 0 : if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3866 : cansign = kFALSE;
3867 0 : break;
3868 : }
3869 0 : }
3870 0 : if (cansign){
3871 0 : if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3872 0 : if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3873 0 : if (!c->IsUsed()) c->Use();
3874 : }
3875 0 : }
3876 0 : }
3877 0 : return besttrack;
3878 522 : }
3879 : //------------------------------------------------------------------------
3880 : void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3881 : {
3882 : //
3883 : // get "best" hypothesys
3884 : //
3885 :
3886 32 : Int_t nentries = itsTracks.GetEntriesFast();
3887 472 : for (Int_t i=0;i<nentries;i++){
3888 220 : AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3889 220 : if (!track) continue;
3890 220 : TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3891 282 : if (!array) continue;
3892 158 : if (array->GetEntriesFast()<=0) continue;
3893 : //
3894 : AliITStrackMI* longtrack=0;
3895 : Float_t minn=0;
3896 : Float_t maxchi2=1000;
3897 1746 : for (Int_t j=0;j<array->GetEntriesFast();j++){
3898 636 : AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3899 636 : if (!trackHyp) continue;
3900 636 : if (trackHyp->GetGoldV0()) {
3901 : longtrack = trackHyp; //gold V0 track taken
3902 0 : break;
3903 : }
3904 954 : if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3905 318 : Float_t chi2 = trackHyp->GetChi2MIP(0);
3906 318 : if (fSelectBestMIP03) chi2 *= trackHyp->GetChi2MIP(3);
3907 478 : if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = chi2; //trackHyp->GetChi2MIP(0);
3908 : //
3909 318 : if (fAfterV0){ // ??? RS
3910 578 : if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3911 : }
3912 484 : if (chi2 > maxchi2) continue;
3913 152 : minn = trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3914 152 : if (fSelectBestMIP03) minn++; // allow next to longest to win
3915 : maxchi2 = chi2;
3916 : longtrack=trackHyp;
3917 152 : }
3918 : //
3919 : //
3920 : //
3921 158 : AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3922 164 : if (!longtrack) {longtrack = besttrack;}
3923 : else besttrack= longtrack;
3924 : //
3925 158 : if (besttrack) {
3926 158 : Int_t list[6]={0};
3927 158 : AliITSRecPoint * clist[6]={0};
3928 158 : Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3929 : //
3930 158 : track->SetNUsed(shared);
3931 158 : track->SetNSkipped(besttrack->GetNSkipped());
3932 158 : track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3933 158 : if (shared>0) {
3934 6 : if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3935 6 : Int_t nshared;
3936 6 : Int_t overlist[6]={0};
3937 : //
3938 6 : Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3939 : //if (sharedtrack==-1) sharedtrack=0;
3940 6 : if (sharedtrack>=0) {
3941 6 : besttrack = GetBest2Tracks(i,sharedtrack,10,5.5,track);
3942 6 : }
3943 6 : }
3944 316 : if (besttrack&&fAfterV0) {
3945 122 : UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3946 122 : track->SetWinner(besttrack);
3947 122 : }
3948 158 : if (besttrack) {
3949 158 : if (fConstraint[fPass]) {
3950 76 : UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3951 76 : track->SetWinner(besttrack);
3952 76 : }
3953 280 : if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3954 116 : if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3955 58 : TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3956 : }
3957 : }
3958 316 : }
3959 158 : }
3960 16 : }
3961 :
3962 : //------------------------------------------------------------------------
3963 : void AliITStrackerMI::FlagFakes(const TObjArray &itsTracks)
3964 : {
3965 : //
3966 : // RS: flag those tracks which are suxpected to have fake clusters
3967 : //
3968 : const double kThreshPt = 0.5;
3969 0 : AliRefArray *refArr[6]={0};
3970 : //
3971 0 : for (int i=0;i<6;i++) {
3972 0 : int ncl = fgLayers[i].GetNumberOfClusters();
3973 0 : refArr[i] = new AliRefArray(ncl,TMath::Min(ncl,1000));
3974 : }
3975 0 : Int_t nentries = itsTracks.GetEntriesFast();
3976 : //
3977 : // fill cluster->track associations
3978 0 : for (Int_t itr=0;itr<nentries;itr++){
3979 0 : AliITStrackMI* track = (AliITStrackMI*)itsTracks.UncheckedAt(itr);
3980 0 : if (!track) continue;
3981 0 : AliITStrackMI* trackITS = track->GetWinner();
3982 0 : if (!trackITS) continue;
3983 0 : for (int il=trackITS->GetNumberOfClusters();il--;) {
3984 0 : int idx = trackITS->GetClusterIndex(il);
3985 0 : Int_t l=(idx & 0xf0000000) >> 28, c=(idx & 0x0fffffff) >> 00;
3986 : // if (c>fgLayers[l].GetNumberOfClusters()) continue;
3987 0 : refArr[l]->AddReference(c, itr);
3988 : }
3989 0 : }
3990 : //
3991 : const UInt_t kMaxRef = 100;
3992 0 : UInt_t crefs[kMaxRef]={0};
3993 : Int_t ncrefs=0;
3994 : // process tracks with shared clusters
3995 0 : for (int itr=0;itr<nentries;itr++){
3996 0 : AliITStrackMI* track0 = (AliITStrackMI*)itsTracks.UncheckedAt(itr);
3997 0 : AliITStrackMI* trackH0 = track0->GetWinner();
3998 0 : if (!trackH0) continue;
3999 0 : AliESDtrack* esd0 = track0->GetESDtrack();
4000 : //
4001 0 : for (int il=0;il<trackH0->GetNumberOfClusters();il++) {
4002 0 : int idx = trackH0->GetClusterIndex(il);
4003 0 : Int_t l=(idx & 0xf0000000) >> 28, c=(idx & 0x0fffffff) >> 00;
4004 0 : ncrefs = refArr[l]->GetReferences(c,crefs,kMaxRef);
4005 0 : if (ncrefs<2) continue; // there will be always self-reference, for sharing needs at least 2
4006 0 : esd0->SetITSSharedFlag(l);
4007 0 : for (int ir=ncrefs;ir--;) {
4008 0 : if (int(crefs[ir]) <= itr) continue; // ==:selfreference, <: the same pair will be checked with >
4009 0 : AliITStrackMI* track1 = (AliITStrackMI*)itsTracks.UncheckedAt(crefs[ir]);
4010 0 : AliITStrackMI* trackH1 = track1->GetWinner();
4011 0 : AliESDtrack* esd1 = track1->GetESDtrack();
4012 0 : esd1->SetITSSharedFlag(l);
4013 : //
4014 0 : double pt0 = trackH0->Pt(), pt1 = trackH1->Pt(), res = 0.;
4015 0 : if (pt0>kThreshPt && pt0-pt1>0.2+0.2*(pt0-kThreshPt) ) res = -100;
4016 0 : else if (pt1>kThreshPt && pt1-pt0>0.2+0.2*(pt1-kThreshPt) ) res = 100;
4017 :
4018 : // select the one with smallest chi2's product
4019 0 : res += trackH0->GetChi2MIP(0)*trackH0->GetChi2MIP(3);
4020 0 : res -= trackH1->GetChi2MIP(0)*trackH1->GetChi2MIP(3);
4021 : //
4022 0 : if (res<0) esd1->SetITSFakeFlag(); // esd0 is winner
4023 0 : else esd0->SetITSFakeFlag(); // esd1 is winner
4024 : }
4025 : //
4026 0 : }
4027 : //
4028 0 : }
4029 : //
4030 0 : for (int i=6;i--;) delete refArr[i];
4031 0 : }
4032 :
4033 :
4034 :
4035 : //------------------------------------------------------------------------
4036 : void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
4037 : //--------------------------------------------------------------------
4038 : //This function "cooks" a track label. If label<0, this track is fake.
4039 : //--------------------------------------------------------------------
4040 : const int kMaxLbPerCl = 3;
4041 5064 : int lbID[36]={0},lbStat[36]={0};
4042 2532 : Int_t nLab=0, nCl = track->GetNumberOfClusters();
4043 : //
4044 : // track->SetLabel(-1);
4045 : // track->SetFakeRatio(0);
4046 : //
4047 28420 : for (Int_t i=0;i<nCl;i++) { // fill all labels
4048 11678 : Int_t cindex = track->GetClusterIndex(i);
4049 : // Int_t l=(cindex & 0xf0000000) >> 28;
4050 11678 : AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
4051 : //
4052 40014 : for (int imc=0;imc<kMaxLbPerCl;imc++) { // labels within single cluster
4053 19968 : int trLb = cl->GetLabel(imc);
4054 31620 : if (trLb<0) break;
4055 : // search this mc track in already accounted ones
4056 : int iLab;
4057 23201 : for (iLab=0;iLab<nLab;iLab++) if (lbID[iLab]==trLb) break;
4058 13985 : if (iLab<nLab) lbStat[iLab]++;
4059 : else {
4060 2647 : lbID[nLab] = trLb;
4061 2647 : lbStat[nLab++] = 1;
4062 : }
4063 8316 : } // loop over given cluster's labels
4064 : } // loop over clusters
4065 : //
4066 2579 : if (nLab<1) return; // no labels at all
4067 : //
4068 : Int_t tpcLabel=-1;
4069 4970 : if (track->GetESDtrack() && track->GetESDtrack()->IsOn(AliESDtrack::kTPCin)){
4070 2453 : tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
4071 2453 : }
4072 : //
4073 : // find majority label
4074 2485 : if (nCl && nLab) {
4075 : int maxLab=0,tpcLabID=-1;
4076 10264 : for (int ilb=nLab;ilb--;) {
4077 2647 : int st = lbStat[ilb];
4078 2651 : if (lbStat[maxLab]<st) maxLab = ilb;
4079 3884 : if (lbID[ilb] == tpcLabel) tpcLabID = ilb;
4080 : }
4081 : // if there is an equal choice, prefer ITS label consistent with TPC label
4082 3722 : if (tpcLabID>=0 && (tpcLabID!=maxLab) && lbStat[maxLab]==lbStat[tpcLabID]) maxLab=tpcLabID;
4083 :
4084 2485 : track->SetFakeRatio(1.-float(lbStat[maxLab])/nCl);
4085 2485 : track->SetLabel( lbStat[maxLab]>=nCl-wrong ? lbID[maxLab] : -lbID[maxLab]);
4086 2485 : }
4087 : //
4088 5017 : }
4089 :
4090 : /*
4091 : //------------------------------------------------------------------------
4092 : void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
4093 : //--------------------------------------------------------------------
4094 : //This function "cooks" a track label. If label<0, this track is fake.
4095 : //--------------------------------------------------------------------
4096 : Int_t tpcLabel=-1;
4097 :
4098 : if (track->GetESDtrack()){
4099 : tpcLabel = track->GetESDtrack()->GetTPCLabel();
4100 : ULong_t trStatus=track->GetESDtrack()->GetStatus();
4101 : if(!(trStatus&AliESDtrack::kTPCin)) tpcLabel=track->GetLabel(); // for ITSsa tracks
4102 : }
4103 : track->SetChi2MIP(9,0);
4104 : Int_t nwrong=0;
4105 : for (Int_t i=0;i<track->GetNumberOfClusters();i++){
4106 : Int_t cindex = track->GetClusterIndex(i);
4107 : Int_t l=(cindex & 0xf0000000) >> 28;
4108 : AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
4109 : Int_t isWrong=1;
4110 : for (Int_t ind=0;ind<3;ind++){
4111 : if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
4112 : //AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
4113 : }
4114 : track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
4115 : nwrong+=isWrong;
4116 : }
4117 : Int_t nclusters = track->GetNumberOfClusters();
4118 : if (nclusters > 0) //PH Some tracks don't have any cluster
4119 : track->SetFakeRatio(double(nwrong)/double(nclusters));
4120 : if (tpcLabel>0 && track->GetFakeRatio()>wrong) {
4121 : track->SetLabel(-tpcLabel);
4122 : } else {
4123 : track->SetLabel(tpcLabel);
4124 : }
4125 : AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
4126 : }
4127 : */
4128 :
4129 : //------------------------------------------------------------------------
4130 : void AliITStrackerMI::CookdEdx(AliITStrackMI* track){
4131 : //
4132 : // Fill the dE/dx in this track
4133 : //
4134 4040 : track->SetChi2MIP(9,0);
4135 23388 : for (Int_t i=0;i<track->GetNumberOfClusters();i++){
4136 9674 : Int_t cindex = track->GetClusterIndex(i);
4137 9674 : Int_t l=(cindex & 0xf0000000) >> 28;
4138 9674 : AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
4139 9674 : Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
4140 : Int_t isWrong=1;
4141 77392 : for (Int_t ind=0;ind<3;ind++){
4142 33780 : if (cl->GetLabel(ind)==lab) isWrong=0;
4143 : }
4144 9674 : track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
4145 : }
4146 : Double_t low=0.;
4147 : Double_t up=0.51;
4148 2020 : track->CookdEdx(low,up);
4149 2020 : }
4150 : //------------------------------------------------------------------------
4151 : void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
4152 : //
4153 : // Create some arrays
4154 : //
4155 16 : if (fCoefficients) delete []fCoefficients;
4156 8 : fCoefficients = new Float_t[ntracks*48];
4157 10576 : for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
4158 8 : }
4159 : //------------------------------------------------------------------------
4160 : Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4161 : {
4162 : //
4163 : // Compute predicted chi2
4164 : //
4165 : // Take into account the mis-alignment (bring track to cluster plane)
4166 23936 : Double_t xTrOrig=track->GetX();
4167 11968 : if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
4168 11968 : Float_t erry,errz,covyz;
4169 11968 : Float_t theta = track->GetTgl();
4170 11968 : Float_t phi = track->GetSnp();
4171 11968 : phi *= TMath::Sqrt(1./((1.-phi)*(1.+phi)));
4172 11968 : AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
4173 35904 : AliDebug(2,Form(" chi2: tr-cl %f %f tr X %f cl X %f",track->GetY()-cluster->GetY(),track->GetZ()-cluster->GetZ(),track->GetX(),cluster->GetX()));
4174 35904 : AliDebug(2,Form(" chi2: tr-cl %f %f tr X %f cl X %f",track->GetY()-cluster->GetY(),track->GetZ()-cluster->GetZ(),track->GetX(),cluster->GetX()));
4175 11968 : Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
4176 : // Bring the track back to detector plane in ideal geometry
4177 : // [mis-alignment will be accounted for in UpdateMI()]
4178 11968 : if (!track->Propagate(xTrOrig)) return 1000.;
4179 11968 : Float_t ny,nz;
4180 11968 : AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
4181 11968 : Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
4182 11968 : if (delta>1){
4183 202 : chi2+=0.5*TMath::Min(delta/2,2.);
4184 202 : chi2+=2.*cluster->GetDeltaProbability();
4185 202 : }
4186 : //
4187 11968 : track->SetNy(layer,ny);
4188 11968 : track->SetNz(layer,nz);
4189 11968 : track->SetSigmaY(layer,erry);
4190 11968 : track->SetSigmaZ(layer, errz);
4191 11968 : track->SetSigmaYZ(layer,covyz);
4192 : //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
4193 11968 : track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
4194 : return chi2;
4195 :
4196 35904 : }
4197 : //------------------------------------------------------------------------
4198 : Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
4199 : {
4200 : //
4201 : // Update ITS track
4202 : //
4203 23736 : Int_t layer = (index & 0xf0000000) >> 28;
4204 11868 : track->SetClIndex(layer, index);
4205 20902 : if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
4206 9034 : if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
4207 0 : chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
4208 0 : track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
4209 0 : }
4210 : }
4211 :
4212 11868 : if (TMath::Abs(cl->GetQ())<1.e-13) return 0; // ingore the "virtual" clusters
4213 :
4214 :
4215 : // Take into account the mis-alignment (bring track to cluster plane)
4216 11868 : Double_t xTrOrig=track->GetX();
4217 11868 : Float_t clxyz[3]={0}; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]={0}; track->GetXYZ(trxyz);
4218 35604 : AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
4219 35604 : AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
4220 35604 : AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
4221 :
4222 11868 : if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
4223 :
4224 11868 : AliCluster c(*cl);
4225 11868 : c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
4226 11868 : c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
4227 11868 : c.SetSigmaYZ(track->GetSigmaYZ(layer));
4228 :
4229 :
4230 23736 : Int_t updated = track->UpdateMI(&c,chi2,index);
4231 : // Bring the track back to detector plane in ideal geometry
4232 23736 : if (!track->Propagate(xTrOrig)) return 0;
4233 :
4234 11868 : if(!updated) AliDebug(2,"update failed");
4235 11868 : return updated;
4236 35604 : }
4237 :
4238 : //------------------------------------------------------------------------
4239 : void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
4240 : {
4241 : //
4242 : //DCA sigmas parameterization
4243 : //to be paramterized using external parameters in future
4244 : //
4245 : //
4246 1740 : Double_t curv=track->GetC();
4247 870 : sigmarfi = 0.0040+1.4 *TMath::Abs(curv)+332.*curv*curv;
4248 870 : sigmaz = 0.0110+4.37*TMath::Abs(curv);
4249 870 : }
4250 : //------------------------------------------------------------------------
4251 : void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
4252 : {
4253 : //
4254 : // Clusters from delta electrons?
4255 : //
4256 35168 : Int_t entries = clusterArray->GetEntriesFast();
4257 35158 : if (entries<4) return;
4258 10 : AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
4259 10 : Int_t layer = cluster->GetLayer();
4260 20 : if (layer>1) return;
4261 0 : Int_t index[10000]={0};
4262 : Int_t ncandidates=0;
4263 0 : Float_t r = (layer>0)? 7:4;
4264 : //
4265 0 : for (Int_t i=0;i<entries;i++){
4266 0 : AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
4267 0 : Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
4268 0 : if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
4269 0 : index[ncandidates] = i; //candidate to belong to delta electron track
4270 0 : ncandidates++;
4271 0 : if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
4272 0 : cl0->SetDeltaProbability(1);
4273 0 : }
4274 0 : }
4275 : //
4276 : //
4277 : //
4278 0 : for (Int_t i=0;i<ncandidates;i++){
4279 0 : AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
4280 0 : if (cl0->GetDeltaProbability()>0.8) continue;
4281 : //
4282 : Int_t ncl = 0;
4283 0 : Float_t y[100]={0},z[100]={0},sumy,sumz,sumy2, sumyz, sumw;
4284 : sumy=sumz=sumy2=sumyz=sumw=0.0;
4285 0 : for (Int_t j=0;j<ncandidates;j++){
4286 0 : if (i==j) continue;
4287 0 : AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
4288 : //
4289 0 : Float_t dz = cl0->GetZ()-cl1->GetZ();
4290 0 : Float_t dy = cl0->GetY()-cl1->GetY();
4291 0 : if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
4292 0 : Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
4293 0 : y[ncl] = cl1->GetY();
4294 0 : z[ncl] = cl1->GetZ();
4295 0 : sumy+= y[ncl]*weight;
4296 0 : sumz+= z[ncl]*weight;
4297 0 : sumy2+=y[ncl]*y[ncl]*weight;
4298 0 : sumyz+=y[ncl]*z[ncl]*weight;
4299 0 : sumw+=weight;
4300 0 : ncl++;
4301 0 : }
4302 0 : }
4303 0 : if (ncl<4) continue;
4304 0 : Float_t det = sumw*sumy2 - sumy*sumy;
4305 : Float_t delta=1000;
4306 0 : if (TMath::Abs(det)>0.01){
4307 0 : Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
4308 0 : Float_t k = (sumyz*sumw - sumy*sumz)/det;
4309 0 : delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
4310 0 : }
4311 : else{
4312 0 : Float_t z0 = sumyz/sumy;
4313 0 : delta = TMath::Abs(cl0->GetZ()-z0);
4314 : }
4315 0 : if ( delta<0.05) {
4316 0 : cl0->SetDeltaProbability(1-20.*delta);
4317 0 : }
4318 0 : }
4319 17584 : }
4320 : //------------------------------------------------------------------------
4321 : void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
4322 : {
4323 : //
4324 : // Update ESD track
4325 : //
4326 732 : track->UpdateESDtrack(flags);
4327 366 : AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
4328 934 : if (oldtrack) delete oldtrack;
4329 732 : track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
4330 : // if (TMath::Abs(track->GetDnorm(1))<0.000000001){
4331 : // printf("Problem\n");
4332 : // }
4333 366 : }
4334 : //------------------------------------------------------------------------
4335 : Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
4336 : //
4337 : // Get nearest upper layer close to the point xr.
4338 : // rough approximation
4339 : //
4340 : const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
4341 28 : Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
4342 : Int_t res =6;
4343 172 : for (Int_t i=0;i<6;i++){
4344 74 : if (radius<kRadiuses[i]){
4345 : res =i;
4346 6 : break;
4347 : }
4348 : }
4349 14 : return res;
4350 : }
4351 : //------------------------------------------------------------------------
4352 : void AliITStrackerMI::BuildMaterialLUT(TString material) {
4353 : //--------------------------------------------------------------------
4354 : // Fill a look-up table with mean material
4355 : //--------------------------------------------------------------------
4356 :
4357 : Int_t n=1000;
4358 12 : Double_t mparam[7]={0};
4359 6 : Double_t point1[3]={0},point2[3]={0};
4360 : Double_t phi,cosphi,sinphi,z;
4361 : // 0-5 layers, 6 pipe, 7-8 shields
4362 6 : Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
4363 6 : Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
4364 :
4365 : Int_t ifirst=0,ilast=0;
4366 6 : if(material.Contains("Pipe")) {
4367 : ifirst=6; ilast=6;
4368 6 : } else if(material.Contains("Shields")) {
4369 : ifirst=7; ilast=8;
4370 4 : } else if(material.Contains("Layers")) {
4371 : ifirst=0; ilast=5;
4372 2 : } else {
4373 0 : Error("BuildMaterialLUT","Wrong layer name\n");
4374 : }
4375 : const double kAngEps = 1e-4; // tiny slope to avoid tracks strictly normal to Z axis
4376 48 : for(Int_t imat=ifirst; imat<=ilast; imat++) {
4377 18 : Double_t param[5]={0.,0.,0.,0.,0.};
4378 36036 : for (Int_t i=0; i<n; i++) {
4379 18000 : phi = 2.*TMath::Pi()*gRandom->Rndm();
4380 18000 : cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
4381 18000 : z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
4382 18000 : point1[0] = rmin[imat]*cosphi;
4383 18000 : point1[1] = rmin[imat]*sinphi;
4384 18000 : point1[2] = z;
4385 18000 : point2[0] = rmax[imat]*cosphi;
4386 18000 : point2[1] = rmax[imat]*sinphi;
4387 18000 : point2[2] = z+(rmax[imat]-rmin[imat])*kAngEps;
4388 18000 : AliTracker::MeanMaterialBudget(point1,point2,mparam);
4389 18000 : if (mparam[1]>999) {n--; continue;} // skip anomalous values in failed propagation
4390 216000 : for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
4391 18000 : }
4392 216 : for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
4393 18 : if(imat<=5) {
4394 12 : fxOverX0Layer[imat] = param[1];
4395 12 : fxTimesRhoLayer[imat] = param[0]*param[4];
4396 18 : } else if(imat==6) {
4397 2 : fxOverX0Pipe = param[1];
4398 2 : fxTimesRhoPipe = param[0]*param[4];
4399 6 : } else if(imat==7) {
4400 2 : fxOverX0Shield[0] = param[1];
4401 2 : fxTimesRhoShield[0] = param[0]*param[4];
4402 4 : } else if(imat==8) {
4403 2 : fxOverX0Shield[1] = param[1];
4404 2 : fxTimesRhoShield[1] = param[0]*param[4];
4405 2 : }
4406 18 : }
4407 : /*
4408 : printf("%s\n",material.Data());
4409 : printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
4410 : printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
4411 : printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
4412 : printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
4413 : printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
4414 : printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
4415 : printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
4416 : printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
4417 : printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
4418 : */
4419 : return;
4420 6 : }
4421 : //------------------------------------------------------------------------
4422 : Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
4423 : TString direction) {
4424 : //-------------------------------------------------------------------
4425 : // Propagate beyond beam pipe and correct for material
4426 : // (material budget in different ways according to fUseTGeo value)
4427 : // Add time if going outward (PropagateTo or PropagateToTGeo)
4428 : //-------------------------------------------------------------------
4429 :
4430 : // Define budget mode:
4431 : // 0: material from AliITSRecoParam (hard coded)
4432 : // 1: material from TGeo in one step (on the fly)
4433 : // 2: material from lut
4434 : // 3: material from TGeo in one step (same for all hypotheses)
4435 : Int_t mode;
4436 1324 : switch(fUseTGeo) {
4437 : case 0:
4438 : mode=0;
4439 0 : break;
4440 : case 1:
4441 : mode=1;
4442 0 : break;
4443 : case 2:
4444 : mode=2;
4445 0 : break;
4446 : case 3:
4447 662 : if(fTrackingPhase.Contains("Clusters2Tracks"))
4448 566 : { mode=3; } else { mode=1; }
4449 : break;
4450 : case 4:
4451 0 : if(fTrackingPhase.Contains("Clusters2Tracks"))
4452 0 : { mode=3; } else { mode=2; }
4453 : break;
4454 : default:
4455 : mode=0;
4456 0 : break;
4457 : }
4458 662 : if(fTrackingPhase.Contains("Default")) mode=0;
4459 :
4460 662 : Int_t index=fCurrentEsdTrack;
4461 :
4462 662 : Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4463 1986 : Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4464 662 : Double_t xToGo;
4465 666 : if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4466 :
4467 1240 : Double_t xOverX0,x0,lengthTimesMeanDensity;
4468 :
4469 1240 : switch(mode) {
4470 : case 0:
4471 0 : xOverX0 = AliITSRecoParam::GetdPipe();
4472 0 : x0 = AliITSRecoParam::GetX0Be();
4473 0 : lengthTimesMeanDensity = xOverX0*x0;
4474 0 : lengthTimesMeanDensity *= dir;
4475 0 : if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4476 : break;
4477 : case 1:
4478 92 : if (!t->PropagateToTGeo(xToGo,1)) return 0;
4479 : break;
4480 : case 2:
4481 0 : if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4482 0 : xOverX0 = fxOverX0Pipe;
4483 0 : lengthTimesMeanDensity = fxTimesRhoPipe;
4484 0 : lengthTimesMeanDensity *= dir;
4485 0 : if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4486 : break;
4487 : case 3:
4488 1132 : if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4489 566 : if(fxOverX0PipeTrks[index]<0) {
4490 76 : if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4491 152 : Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4492 76 : ((1.-t->GetSnp())*(1.+t->GetSnp())));
4493 76 : fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4494 76 : fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4495 : return 1;
4496 : }
4497 490 : xOverX0 = fxOverX0PipeTrks[index];
4498 490 : lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4499 490 : lengthTimesMeanDensity *= dir;
4500 490 : if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4501 : break;
4502 : }
4503 :
4504 582 : return 1;
4505 1320 : }
4506 : //------------------------------------------------------------------------
4507 : Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4508 : TString shield,
4509 : TString direction) {
4510 : //-------------------------------------------------------------------
4511 : // Propagate beyond SPD or SDD shield and correct for material
4512 : // (material budget in different ways according to fUseTGeo value)
4513 : // Add time if going outward (PropagateTo or PropagateToTGeo)
4514 : //-------------------------------------------------------------------
4515 :
4516 : // Define budget mode:
4517 : // 0: material from AliITSRecoParam (hard coded)
4518 : // 1: material from TGeo in steps of X cm (on the fly)
4519 : // X = AliITSRecoParam::GetStepSizeTGeo()
4520 : // 2: material from lut
4521 : // 3: material from TGeo in one step (same for all hypotheses)
4522 : Int_t mode;
4523 9724 : switch(fUseTGeo) {
4524 : case 0:
4525 : mode=0;
4526 0 : break;
4527 : case 1:
4528 : mode=1;
4529 0 : break;
4530 : case 2:
4531 : mode=2;
4532 0 : break;
4533 : case 3:
4534 4862 : if(fTrackingPhase.Contains("Clusters2Tracks"))
4535 4398 : { mode=3; } else { mode=1; }
4536 : break;
4537 : case 4:
4538 0 : if(fTrackingPhase.Contains("Clusters2Tracks"))
4539 0 : { mode=3; } else { mode=2; }
4540 : break;
4541 : default:
4542 : mode=0;
4543 0 : break;
4544 : }
4545 4934 : if(fTrackingPhase.Contains("Default")) mode=0;
4546 :
4547 4862 : Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4548 : Double_t rToGo;
4549 : Int_t shieldindex=0;
4550 4862 : if (shield.Contains("SDD")) { // SDDouter
4551 7236 : rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4552 : shieldindex=1;
4553 4862 : } else if (shield.Contains("SPD")) { // SPDouter
4554 7350 : rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4555 : shieldindex=0;
4556 : } else {
4557 0 : Error("CorrectForShieldMaterial"," Wrong shield name\n");
4558 0 : return 0;
4559 : }
4560 :
4561 : // do nothing if we are already beyond the shield
4562 4862 : Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4563 6948 : if(dir<0 && rTrack > rToGo) return 1; // going outward
4564 7638 : if(dir>0 && rTrack < rToGo) return 1; // going inward
4565 :
4566 :
4567 4748 : Double_t xToGo;
4568 4754 : if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4569 :
4570 9296 : Int_t index=2*fCurrentEsdTrack+shieldindex;
4571 :
4572 9296 : Double_t xOverX0,x0,lengthTimesMeanDensity;
4573 : Int_t nsteps=1;
4574 :
4575 9296 : switch(mode) {
4576 : case 0:
4577 70 : xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4578 70 : x0 = AliITSRecoParam::GetX0shield(shieldindex);
4579 70 : lengthTimesMeanDensity = xOverX0*x0;
4580 70 : lengthTimesMeanDensity *= dir;
4581 70 : if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4582 : break;
4583 : case 1:
4584 386 : nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4585 386 : if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4586 : break;
4587 : case 2:
4588 0 : if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4589 0 : xOverX0 = fxOverX0Shield[shieldindex];
4590 0 : lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4591 0 : lengthTimesMeanDensity *= dir;
4592 0 : if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4593 : break;
4594 : case 3:
4595 8572 : if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4596 4286 : if(fxOverX0ShieldTrks[index]<0) {
4597 188 : if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4598 376 : Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4599 188 : ((1.-t->GetSnp())*(1.+t->GetSnp())));
4600 188 : fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4601 188 : fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4602 : return 1;
4603 : }
4604 4098 : xOverX0 = fxOverX0ShieldTrks[index];
4605 4098 : lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4606 4098 : lengthTimesMeanDensity *= dir;
4607 4098 : if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4608 : break;
4609 : }
4610 :
4611 4554 : return 1;
4612 14352 : }
4613 : //------------------------------------------------------------------------
4614 : Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4615 : Int_t layerindex,
4616 : Double_t oldGlobXYZ[3],
4617 : TString direction) {
4618 : //-------------------------------------------------------------------
4619 : // Propagate beyond layer and correct for material
4620 : // (material budget in different ways according to fUseTGeo value)
4621 : // Add time if going outward (PropagateTo or PropagateToTGeo)
4622 : //-------------------------------------------------------------------
4623 :
4624 : // Define budget mode:
4625 : // 0: material from AliITSRecoParam (hard coded)
4626 : // 1: material from TGeo in stepsof X cm (on the fly)
4627 : // X = AliITSRecoParam::GetStepSizeTGeo()
4628 : // 2: material from lut
4629 : // 3: material from TGeo in one step (same for all hypotheses)
4630 : Int_t mode;
4631 28944 : switch(fUseTGeo) {
4632 : case 0:
4633 : mode=0;
4634 0 : break;
4635 : case 1:
4636 : mode=1;
4637 0 : break;
4638 : case 2:
4639 : mode=2;
4640 0 : break;
4641 : case 3:
4642 14472 : if(fTrackingPhase.Contains("Clusters2Tracks"))
4643 13082 : { mode=3; } else { mode=1; }
4644 : break;
4645 : case 4:
4646 0 : if(fTrackingPhase.Contains("Clusters2Tracks"))
4647 0 : { mode=3; } else { mode=2; }
4648 : break;
4649 : default:
4650 : mode=0;
4651 0 : break;
4652 : }
4653 14684 : if(fTrackingPhase.Contains("Default")) mode=0;
4654 :
4655 14472 : Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4656 :
4657 14472 : Double_t r=fgLayers[layerindex].GetR();
4658 14472 : Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4659 :
4660 14472 : Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4661 14472 : Double_t xToGo;
4662 14473 : if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4663 :
4664 14471 : Int_t index=6*fCurrentEsdTrack+layerindex;
4665 :
4666 :
4667 14471 : Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4668 : Int_t nsteps=1;
4669 :
4670 : // back before material (no correction)
4671 14471 : Double_t rOld,xOld;
4672 14471 : rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4673 14471 : if (!t->GetLocalXat(rOld,xOld)) return 0;
4674 14471 : if (!t->Propagate(xOld)) return 0;
4675 :
4676 28374 : switch(mode) {
4677 : case 0:
4678 212 : xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4679 212 : lengthTimesMeanDensity = xOverX0*x0;
4680 212 : lengthTimesMeanDensity *= dir;
4681 : // Bring the track beyond the material
4682 212 : if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4683 : break;
4684 : case 1:
4685 1177 : nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4686 1177 : if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4687 : break;
4688 : case 2:
4689 0 : if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4690 0 : xOverX0 = fxOverX0Layer[layerindex];
4691 0 : lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4692 0 : lengthTimesMeanDensity *= dir;
4693 : // Bring the track beyond the material
4694 0 : if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4695 : break;
4696 : case 3:
4697 26164 : if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4698 13082 : if(fxOverX0LayerTrks[index]<0) {
4699 568 : nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4700 568 : if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4701 1136 : Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4702 568 : ((1.-t->GetSnp())*(1.+t->GetSnp())));
4703 568 : fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4704 568 : fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4705 : return 1;
4706 : }
4707 12514 : xOverX0 = fxOverX0LayerTrks[index];
4708 12514 : lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4709 12514 : lengthTimesMeanDensity *= dir;
4710 12514 : if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4711 : break;
4712 : }
4713 :
4714 :
4715 13903 : return 1;
4716 28943 : }
4717 : //------------------------------------------------------------------------
4718 : void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4719 : //-----------------------------------------------------------------
4720 : // Initialize LUT for storing material for each prolonged track
4721 : //-----------------------------------------------------------------
4722 16 : fxOverX0PipeTrks = new Float_t[ntracks];
4723 8 : fxTimesRhoPipeTrks = new Float_t[ntracks];
4724 8 : fxOverX0ShieldTrks = new Float_t[ntracks*2];
4725 8 : fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4726 8 : fxOverX0LayerTrks = new Float_t[ntracks*6];
4727 8 : fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4728 :
4729 288 : for(Int_t i=0; i<ntracks; i++) {
4730 136 : fxOverX0PipeTrks[i] = -1.;
4731 136 : fxTimesRhoPipeTrks[i] = -1.;
4732 : }
4733 560 : for(Int_t j=0; j<ntracks*2; j++) {
4734 272 : fxOverX0ShieldTrks[j] = -1.;
4735 272 : fxTimesRhoShieldTrks[j] = -1.;
4736 : }
4737 1648 : for(Int_t k=0; k<ntracks*6; k++) {
4738 816 : fxOverX0LayerTrks[k] = -1.;
4739 816 : fxTimesRhoLayerTrks[k] = -1.;
4740 : }
4741 :
4742 8 : fNtracks = ntracks;
4743 :
4744 8 : return;
4745 : }
4746 : //------------------------------------------------------------------------
4747 : void AliITStrackerMI::DeleteTrksMaterialLUT() {
4748 : //-----------------------------------------------------------------
4749 : // Delete LUT for storing material for each prolonged track
4750 : //-----------------------------------------------------------------
4751 20 : if(fxOverX0PipeTrks) {
4752 24 : delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4753 8 : }
4754 10 : if(fxOverX0ShieldTrks) {
4755 24 : delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4756 8 : }
4757 :
4758 10 : if(fxOverX0LayerTrks) {
4759 24 : delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4760 8 : }
4761 10 : if(fxTimesRhoPipeTrks) {
4762 24 : delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4763 8 : }
4764 10 : if(fxTimesRhoShieldTrks) {
4765 24 : delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4766 8 : }
4767 10 : if(fxTimesRhoLayerTrks) {
4768 24 : delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4769 8 : }
4770 10 : return;
4771 : }
4772 : //------------------------------------------------------------------------
4773 : void AliITStrackerMI::SetForceSkippingOfLayer() {
4774 : //-----------------------------------------------------------------
4775 : // Check if we are forced to skip layers
4776 : // either we set to skip them in RecoParam
4777 : // or they were off during data-taking
4778 : //-----------------------------------------------------------------
4779 :
4780 16 : const AliEventInfo *eventInfo = GetEventInfo();
4781 :
4782 112 : for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
4783 48 : fForceSkippingOfLayer[l] = 0;
4784 : // check reco param
4785 48 : if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
4786 : // check run info
4787 :
4788 96 : if(eventInfo &&
4789 48 : AliITSReconstructor::GetRecoParam()->GetSkipSubdetsNotInTriggerCluster()) {
4790 144 : AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
4791 48 : if(l==0 || l==1) {
4792 16 : if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
4793 64 : } else if(l==2 || l==3) {
4794 48 : if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1;
4795 : } else {
4796 16 : if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
4797 : }
4798 : }
4799 : }
4800 : return;
4801 8 : }
4802 : //------------------------------------------------------------------------
4803 : Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4804 : Int_t ilayer,Int_t idet) const {
4805 : //-----------------------------------------------------------------
4806 : // This method is used to decide whether to allow a prolongation
4807 : // without clusters, because we want to skip the layer.
4808 : // In this case the return value is > 0:
4809 : // return 1: the user requested to skip a layer
4810 : // return 2: track outside z acceptance
4811 : //-----------------------------------------------------------------
4812 :
4813 27660 : if (ForceSkippingOfLayer(ilayer)) return 1;
4814 :
4815 : Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
4816 :
4817 13834 : if (idet<0 && // out in z
4818 4 : ilayer>innerLayCanSkip &&
4819 4 : AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4820 : // check if track will cross SPD outer layer
4821 4 : Double_t phiAtSPD2,zAtSPD2;
4822 4 : if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4823 0 : if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4824 : }
4825 4 : return 2; // always allow skipping, changed on 05.11.2009
4826 4 : }
4827 :
4828 13826 : return 0;
4829 13830 : }
4830 : //------------------------------------------------------------------------
4831 : Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4832 : Int_t ilayer,Int_t idet,
4833 : Double_t dz,Double_t dy,
4834 : Bool_t noClusters) const {
4835 : //-----------------------------------------------------------------
4836 : // This method is used to decide whether to allow a prolongation
4837 : // without clusters, because there is a dead zone in the road.
4838 : // In this case the return value is > 0:
4839 : // return 1: dead zone at z=0,+-7cm in SPD
4840 : // This method assumes that fSPDdetzcentre is ordered from -z to +z
4841 : // return 2: all road is "bad" (dead or noisy) from the OCDB
4842 : // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4843 : // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4844 : //-----------------------------------------------------------------
4845 :
4846 : // check dead zones at z=0,+-7cm in the SPD
4847 6744 : if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4848 7224 : Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4849 2408 : fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4850 2408 : fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4851 7224 : Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4852 2408 : fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4853 2408 : fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4854 16502 : for (Int_t i=0; i<3; i++)
4855 9690 : if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4856 4344 : AliDebug(2,Form("crack SPD %d track z %f %f %f %f\n",ilayer,track->GetZ(),dz,zmaxdead[i],zmindead[i]));
4857 2482 : if (GetSPDDeadZoneProbability(track->GetZ(),TMath::Sqrt(track->GetSigmaZ2()))>0.1) return 1;
4858 : }
4859 3782 : }
4860 :
4861 : // check bad zones from OCDB
4862 3302 : if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4863 :
4864 3302 : if (idet<0) return 0;
4865 :
4866 3302 : AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4867 :
4868 : Int_t detType=-1;
4869 : Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4870 3302 : if (ilayer==0 || ilayer==1) { // ---------- SPD
4871 : detType = 0;
4872 3302 : } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4873 : detType = 1;
4874 : detSizeFactorX *= 2.;
4875 1928 : } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4876 : detType = 2;
4877 836 : }
4878 3302 : AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4879 4138 : if (detType==2) segm->SetLayer(ilayer+1);
4880 3302 : Float_t detSizeX = detSizeFactorX*segm->Dx();
4881 3302 : Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4882 :
4883 : // check if the road overlaps with bad chips
4884 3302 : Float_t xloc,zloc;
4885 3302 : if(!(LocalModuleCoord(ilayer,idet,track,xloc,zloc)))return 0;
4886 3302 : Float_t zlocmin = zloc-dz;
4887 3302 : Float_t zlocmax = zloc+dz;
4888 3302 : Float_t xlocmin = xloc-dy;
4889 3302 : Float_t xlocmax = xloc+dy;
4890 3302 : Int_t chipsInRoad[100]={0};
4891 :
4892 : // check if road goes out of detector
4893 : Bool_t touchNeighbourDet=kFALSE;
4894 3567 : if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4895 3545 : if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4896 4072 : if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4897 4234 : if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4898 9906 : AliDebug(2,Form("layer %d det %d zmim zmax %f %f xmin xmax %f %f %f %f",ilayer,idet,zlocmin,zlocmax,xlocmin,xlocmax,detSizeZ,detSizeX));
4899 :
4900 : // check if this detector is bad
4901 3302 : if (det.IsBad()) {
4902 684 : AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4903 228 : if(!touchNeighbourDet) {
4904 162 : return 2; // all detectors in road are bad
4905 : } else {
4906 66 : return 3; // at least one is bad
4907 : }
4908 : }
4909 :
4910 3074 : if(zlocmin>zlocmax)return 0;
4911 3074 : Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4912 9222 : AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4913 3076 : if (!nChipsInRoad) return 0;
4914 :
4915 : Bool_t anyBad=kFALSE,anyGood=kFALSE;
4916 17200 : for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4917 11056 : if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4918 16584 : AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4919 5528 : if (det.IsChipBad(chipsInRoad[iCh])) {
4920 : anyBad=kTRUE;
4921 19 : } else {
4922 : anyGood=kTRUE;
4923 : }
4924 : }
4925 :
4926 3072 : if (!anyGood) {
4927 0 : if(!touchNeighbourDet) {
4928 0 : AliDebug(2,"all bad in road");
4929 0 : return 2; // all chips in road are bad
4930 : } else {
4931 0 : return 3; // at least a bad chip in road
4932 : }
4933 : }
4934 :
4935 3072 : if (anyBad) {
4936 30 : AliDebug(2,"at least a bad in road");
4937 10 : return 3; // at least a bad chip in road
4938 : }
4939 :
4940 :
4941 6124 : if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4942 8414 : || !noClusters) return 0;
4943 :
4944 : // There are no clusters in road: check if there is at least
4945 : // a bad SPD pixel or SDD anode or SSD strips on both sides
4946 :
4947 : Int_t idetInITS=idet;
4948 5132 : for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4949 :
4950 772 : if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4951 630 : AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4952 210 : return 4;
4953 : }
4954 : //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4955 :
4956 562 : return 0;
4957 10940 : }
4958 : //------------------------------------------------------------------------
4959 : Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4960 : const AliITStrackMI *track,
4961 : Float_t &xloc,Float_t &zloc) const {
4962 : //-----------------------------------------------------------------
4963 : // Gives position of track in local module ref. frame
4964 : //-----------------------------------------------------------------
4965 :
4966 37912 : xloc=0.;
4967 18956 : zloc=0.;
4968 :
4969 18960 : if(idet<0) return kTRUE; // track out of z acceptance of layer
4970 :
4971 18952 : Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4972 :
4973 18952 : Int_t lad = Int_t(idet/ndet) + 1;
4974 :
4975 18952 : Int_t det = idet - (lad-1)*ndet + 1;
4976 :
4977 18952 : Double_t xyzGlob[3]={0},xyzLoc[3]={0};
4978 :
4979 18952 : AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4980 : // take into account the misalignment: xyz at real detector plane
4981 18952 : if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4982 :
4983 18952 : if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4984 :
4985 18952 : xloc = (Float_t)xyzLoc[0];
4986 18952 : zloc = (Float_t)xyzLoc[2];
4987 :
4988 18952 : return kTRUE;
4989 37908 : }
4990 : //------------------------------------------------------------------------
4991 : //------------------------------------------------------------------------
4992 : Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer){
4993 : //
4994 : // Method to be optimized further:
4995 : // Aim: decide whether a track can be used for PlaneEff evaluation
4996 : // the decision is taken based on the track quality at the layer under study
4997 : // no information on the clusters on this layer has to be used
4998 : // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4999 : // the cut is done on number of sigmas from the boundaries
5000 : //
5001 : // Input: Actual track, layer [0,5] under study
5002 : // Output: none
5003 : // Return: kTRUE if this is a good track
5004 : //
5005 : // it will apply a pre-selection to obtain good quality tracks.
5006 : // Here also you will have the possibility to put a control on the
5007 : // impact point of the track on the basic block, in order to exclude border regions
5008 : // this will be done by calling a proper method of the AliITSPlaneEff class.
5009 : //
5010 : // input: AliITStrackMI* track, ilayer= layer number [0,5]
5011 : // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
5012 : //
5013 0 : Int_t index[AliITSgeomTGeo::kNLayers]={0};
5014 : Int_t k;
5015 0 : for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
5016 : //
5017 0 : for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
5018 0 : index[k]=clusters[k];
5019 : }
5020 :
5021 0 : if(!fPlaneEff)
5022 0 : {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
5023 0 : AliITSlayer &layer=fgLayers[ilayer];
5024 0 : Double_t r=layer.GetR();
5025 0 : AliITStrackMI tmp(*track);
5026 :
5027 : // require a minimal number of cluster in other layers and eventually clusters in closest layers
5028 : Int_t nclout=0; Int_t nclin=0;
5029 0 : for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) { // count n. of cluster in outermost layers
5030 0 : AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
5031 : tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
5032 : // if (tmp.GetClIndex(lay)>=0) nclout++;
5033 0 : if(index[lay]>=0)nclout++;
5034 : }
5035 0 : for(Int_t lay=ilayer-1; lay>=0;lay--) { // count n. of cluster in innermost layers
5036 0 : AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
5037 : tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
5038 0 : if (index[lay]>=0) nclin++;
5039 : }
5040 0 : Int_t ncl=nclout+nclin;
5041 : Bool_t nextout = kFALSE;
5042 0 : if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
5043 0 : else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
5044 : Bool_t nextin = kFALSE;
5045 0 : if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
5046 0 : else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
5047 : // maximum number of missing clusters allowed in outermost layers
5048 0 : if(nclout<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersOutPlaneEff())
5049 0 : return kFALSE;
5050 : // maximum number of missing clusters allowed (both in innermost and in outermost layers)
5051 0 : if(ncl<AliITSgeomTGeo::kNLayers-1-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
5052 0 : return kFALSE;
5053 0 : if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
5054 0 : if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
5055 0 : if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
5056 : // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
5057 :
5058 : // detector number
5059 0 : Double_t phi,z;
5060 0 : if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
5061 0 : Int_t idet=layer.FindDetectorIndex(phi,z);
5062 0 : if(idet<0) { AliInfo(Form("cannot find detector"));
5063 0 : return kFALSE;}
5064 :
5065 : // here check if it has good Chi Square.
5066 :
5067 : //propagate to the intersection with the detector plane
5068 0 : const AliITSdetector &det=layer.GetDetector(idet);
5069 0 : if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
5070 :
5071 0 : Float_t locx; //
5072 0 : Float_t locz; //
5073 0 : if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
5074 0 : UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5075 0 : if(key>fPlaneEff->Nblock()) return kFALSE;
5076 0 : Float_t blockXmn,blockXmx,blockZmn,blockZmx;
5077 0 : if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
5078 : //***************
5079 : // DEFINITION OF SEARCH ROAD FOR accepting a track
5080 : //
5081 0 : Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXFromBoundaryPlaneEff();
5082 0 : Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZFromBoundaryPlaneEff();
5083 0 : Double_t distx=AliITSReconstructor::GetRecoParam()->GetDistXFromBoundaryPlaneEff();
5084 0 : Double_t distz=AliITSReconstructor::GetRecoParam()->GetDistZFromBoundaryPlaneEff();
5085 0 : Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()) + distx;
5086 : // those are precisions in the tracking reference system
5087 0 : Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()) + distz;
5088 : // Use it also for the module reference system, as it is done for RecPoints
5089 :
5090 0 : if(AliITSReconstructor::GetRecoParam()->GetSwitchOnMaxDistNSigFrmBndPlaneEff()){
5091 0 : if(nsigx*TMath::Sqrt(tmp.GetSigmaY2())<=distx) dx -= nsigx*TMath::Sqrt(tmp.GetSigmaY2());
5092 0 : else dx -= distx;
5093 :
5094 0 : if(nsigz*TMath::Sqrt(tmp.GetSigmaZ2())<=distz) dz -= nsigz*TMath::Sqrt(tmp.GetSigmaZ2());
5095 0 : else dz -= distz;
5096 : }
5097 :
5098 : // exclude tracks at boundary between detectors
5099 : //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
5100 : Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
5101 0 : AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
5102 0 : AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
5103 0 : AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
5104 0 : if ( (locx-dx < blockXmn+boundaryWidth) ||
5105 0 : (locx+dx > blockXmx-boundaryWidth) ||
5106 0 : (locz-dz < blockZmn+boundaryWidth) ||
5107 0 : (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
5108 :
5109 0 : if(ilayer==0){
5110 0 : const AliESDEvent *myesd = ((AliESDtrack*)tmp.GetESDtrack())->GetESDEvent();
5111 : //The beam pipe
5112 0 : if (CorrectForPipeMaterial(&tmp,"inward")) {
5113 0 : const AliESDVertex* vtx = myesd->GetVertex();
5114 0 : if(!vtx) return kFALSE;
5115 0 : Double_t ddz[2]={0},cov[3]={0};
5116 : Double_t maxD=3.;
5117 0 : if(!tmp.PropagateToDCA(vtx,AliTracker::GetBz(),maxD,ddz,cov)) return kFALSE;
5118 0 : if(TMath::Abs(ddz[0])>=AliITSReconstructor::GetRecoParam()->GetDCACutPlaneEff()) return kFALSE;
5119 :
5120 0 : Double_t covar[6]; vtx->GetCovMatrix(covar);
5121 0 : Double_t p[2]={tmp.GetParameter()[0]-ddz[0],tmp.GetParameter()[1]-ddz[1]};
5122 0 : Double_t c[3]={covar[2],0.,covar[5]};
5123 0 : Double_t chi2= ((AliESDtrack*)tmp.GetESDtrack())->GetPredictedChi2(p,c);
5124 0 : if (chi2>AliITSReconstructor::GetRecoParam()->GetVertexChi2CutPlaneEff()) return kFALSE; // Use this to cut on chi^2
5125 :
5126 0 : } else return kFALSE;
5127 0 : }
5128 :
5129 :
5130 0 : return kTRUE;
5131 0 : }
5132 : //------------------------------------------------------------------------
5133 : void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
5134 : //
5135 : // This Method has to be optimized! For the time-being it uses the same criteria
5136 : // as those used in the search of extra clusters for overlapping modules.
5137 : //
5138 : // Method Purpose: estabilish whether a track has produced a recpoint or not
5139 : // in the layer under study (For Plane efficiency)
5140 : //
5141 : // inputs: AliITStrackMI* track (pointer to a usable track)
5142 : // outputs: none
5143 : // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
5144 : // traversed by this very track. In details:
5145 : // - if a cluster can be associated to the track then call
5146 : // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
5147 : // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
5148 : //
5149 0 : if(!fPlaneEff)
5150 0 : {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
5151 0 : AliITSlayer &layer=fgLayers[ilayer];
5152 0 : Double_t r=layer.GetR();
5153 0 : AliITStrackMI tmp(*track);
5154 :
5155 : // detector number
5156 0 : Double_t phi,z;
5157 0 : if (!tmp.GetPhiZat(r,phi,z)) return;
5158 0 : Int_t idet=layer.FindDetectorIndex(phi,z);
5159 :
5160 0 : if(idet<0) { AliInfo(Form("cannot find detector"));
5161 0 : return;}
5162 :
5163 :
5164 : //propagate to the intersection with the detector plane
5165 0 : const AliITSdetector &det=layer.GetDetector(idet);
5166 0 : if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
5167 :
5168 :
5169 : //***************
5170 : // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
5171 : //
5172 0 : Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
5173 0 : TMath::Sqrt(tmp.GetSigmaZ2() +
5174 0 : AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5175 0 : AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5176 0 : AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
5177 0 : Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
5178 0 : TMath::Sqrt(tmp.GetSigmaY2() +
5179 0 : AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5180 0 : AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5181 0 : AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
5182 :
5183 : // road in global (rphi,z) [i.e. in tracking ref. system]
5184 0 : Double_t zmin = tmp.GetZ() - dz;
5185 0 : Double_t zmax = tmp.GetZ() + dz;
5186 0 : Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
5187 0 : Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
5188 :
5189 : // select clusters in road
5190 0 : layer.SelectClusters(zmin,zmax,ymin,ymax);
5191 :
5192 : // Define criteria for track-cluster association
5193 0 : Double_t msz = tmp.GetSigmaZ2() +
5194 0 : AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5195 0 : AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5196 0 : AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
5197 0 : Double_t msy = tmp.GetSigmaY2() +
5198 0 : AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5199 0 : AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5200 0 : AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
5201 0 : if (tmp.GetConstrain()) {
5202 0 : msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
5203 0 : msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
5204 0 : } else {
5205 0 : msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
5206 0 : msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
5207 : }
5208 :
5209 0 : if(AliITSReconstructor::GetRecoParam()->GetSwitchOffStdSearchClusPlaneEff()){
5210 0 : Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXSearchClusterPlaneEff();
5211 0 : Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZSearchClusterPlaneEff();
5212 0 : Double_t distx=AliITSReconstructor::GetRecoParam()->GetDistXSearchClusterPlaneEff();
5213 0 : Double_t distz=AliITSReconstructor::GetRecoParam()->GetDistZSearchClusterPlaneEff();
5214 0 : msy = nsigx*TMath::Sqrt(tmp.GetSigmaY2()) + distx;
5215 0 : msz = nsigz*TMath::Sqrt(tmp.GetSigmaZ2()) + distz;
5216 :
5217 0 : if(AliITSReconstructor::GetRecoParam()->GetSwitchOnMaxDistNSigSrhClusPlaneEff()){
5218 0 : if(nsigx*TMath::Sqrt(tmp.GetSigmaY2())<=distx) msy -= nsigx*TMath::Sqrt(tmp.GetSigmaY2());
5219 0 : else msy -= distx;
5220 :
5221 0 : if(nsigz*TMath::Sqrt(tmp.GetSigmaZ2())<=distz) msz -= nsigz*TMath::Sqrt(tmp.GetSigmaZ2());
5222 0 : else msz -= distz;
5223 : }
5224 :
5225 0 : msy *= msy;
5226 0 : msz *= msz;
5227 :
5228 0 : }
5229 :
5230 0 : if(msz==0 || msy==0){AliWarning("UseTrackForPlaneEff: null search frame"); return;}
5231 :
5232 0 : msz = 1./msz; // 1/RoadZ^2
5233 0 : msy = 1./msy; // 1/RoadY^2
5234 :
5235 0 : const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
5236 : Int_t idetc=-1;
5237 0 : Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
5238 : //Double_t tolerance=0.2;
5239 : /*while ((cl=layer.GetNextCluster(clidx))!=0) {
5240 : idetc = cl->GetDetectorIndex();
5241 : if(idet!=idetc) continue;
5242 : //Int_t ilay = cl->GetLayer();
5243 :
5244 : if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
5245 : if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
5246 :
5247 : Double_t chi2=tmp.GetPredictedChi2(cl);
5248 : if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
5249 : }*/
5250 0 : Float_t locx; //
5251 0 : Float_t locz; //
5252 0 : if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
5253 : //
5254 0 : AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
5255 0 : UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5256 0 : if(key>fPlaneEff->Nblock()) return;
5257 : Bool_t found=kFALSE;
5258 : //if (ci>=0) {
5259 : Double_t chi2;
5260 0 : while ((cl=layer.GetNextCluster(clidx))!=0) {
5261 0 : idetc = cl->GetDetectorIndex();
5262 0 : if(idet!=idetc) continue;
5263 : // here real control to see whether the cluster can be associated to the track.
5264 : // cluster not associated to track
5265 0 : if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
5266 0 : (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
5267 : // calculate track-clusters chi2
5268 0 : chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
5269 : // in particular, the error associated to the cluster
5270 : //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
5271 : // chi2 cut
5272 0 : if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
5273 : found=kTRUE;
5274 0 : if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
5275 : // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
5276 : // track->SetExtraModule(ilayer,idetExtra);
5277 : }
5278 0 : if(!fPlaneEff->UpDatePlaneEff(found,key))
5279 0 : AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
5280 :
5281 : // this for FO efficiency studies (only for SPD) //
5282 : UInt_t keyFO=999999;
5283 : Bool_t foundFO=kFALSE;
5284 0 : if(ilayer<2){ //ONLY SPD layers for FastOr studies
5285 0 : TBits mapFO = fkDetTypeRec->GetFastOrFiredMap();
5286 0 : Int_t phase = (fEsd->GetBunchCrossNumber())%4;
5287 0 : if(!fSPDChipIntPlaneEff[key]){
5288 0 : AliITSPlaneEffSPD spd;
5289 0 : keyFO = spd.SwitchChipKeyNumbering(key);
5290 0 : if(mapFO.TestBitNumber(keyFO))foundFO=kTRUE;
5291 0 : keyFO = key + (AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip)*(phase+1);
5292 0 : if(keyFO<AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip) {
5293 0 : AliWarning(Form("UseTrackForPlaneEff: too small keyF0 (= %d), setting it to 999999",keyFO));
5294 : keyFO=999999;
5295 0 : }
5296 0 : if(!fPlaneEff->UpDatePlaneEff(foundFO,keyFO))
5297 0 : AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for FastOR for key=%d",keyFO));
5298 0 : }
5299 0 : }
5300 :
5301 :
5302 :
5303 0 : if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
5304 0 : Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
5305 0 : Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
5306 0 : Int_t cltype[2]={-999,-999};
5307 : // and the module
5308 :
5309 0 : Float_t angleModTrack[3]={99999.,99999.,99999.}; // angles (phi, z and "absolute angle") between the track and the mormal to the module (see below)
5310 :
5311 0 : tr[0]=locx;
5312 0 : tr[1]=locz;
5313 0 : tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
5314 0 : tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
5315 :
5316 0 : if (found){
5317 0 : clu[0]=layer.GetCluster(ci)->GetDetLocalX();
5318 0 : clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
5319 0 : cltype[0]=layer.GetCluster(ci)->GetNy();
5320 0 : cltype[1]=layer.GetCluster(ci)->GetNz();
5321 :
5322 : // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
5323 : // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
5324 : // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
5325 : // It is computed properly by calling the method
5326 : // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
5327 : // T
5328 : //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
5329 : //if (tmp.PropagateTo(x,0.,0.)) {
5330 0 : chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
5331 0 : AliCluster c(*layer.GetCluster(ci));
5332 0 : c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
5333 0 : c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
5334 : //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
5335 0 : clu[2]=TMath::Sqrt(c.GetSigmaY2());
5336 0 : clu[3]=TMath::Sqrt(c.GetSigmaZ2());
5337 : //}
5338 0 : }
5339 : // Compute the angles between the track and the module
5340 : // compute the angle "in phi direction", i.e. the angle in the transverse plane
5341 : // between the normal to the module and the projection (in the transverse plane) of the
5342 : // track trajectory
5343 : // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
5344 0 : Float_t tgl = tmp.GetTgl();
5345 0 : Float_t phitr = tmp.GetSnp();
5346 0 : phitr = TMath::ASin(phitr);
5347 0 : Int_t volId = AliGeomManager::LayerToVolUIDSafe(ilayer+1 ,idet );
5348 :
5349 0 : Double_t tra[3]={0}; AliGeomManager::GetOrigTranslation(volId,tra);
5350 0 : Double_t rot[9]={0}; AliGeomManager::GetOrigRotation(volId,rot);
5351 : Double_t alpha =0.;
5352 0 : alpha = tmp.GetAlpha();
5353 0 : Double_t phiglob = alpha+phitr;
5354 : Double_t p[3]={0};
5355 0 : p[0] = TMath::Cos(phiglob);
5356 0 : p[1] = TMath::Sin(phiglob);
5357 0 : p[2] = tgl;
5358 0 : TVector3 pvec(p[0],p[1],p[2]);
5359 0 : TVector3 normvec(rot[1],rot[4],rot[7]);
5360 0 : Double_t angle = pvec.Angle(normvec);
5361 :
5362 0 : if(angle>0.5*TMath::Pi()) angle = (TMath::Pi()-angle);
5363 0 : angle *= 180./TMath::Pi();
5364 :
5365 : //Trasverse Plane
5366 0 : TVector3 pt(p[0],p[1],0);
5367 0 : TVector3 normt(rot[1],rot[4],0);
5368 0 : Double_t anglet = pt.Angle(normt);
5369 :
5370 0 : Double_t phiPt = TMath::ATan2(p[1],p[0]);
5371 0 : if(phiPt<0)phiPt+=2.*TMath::Pi();
5372 0 : Double_t phiNorm = TMath::ATan2(rot[4],rot[1]);
5373 0 : if(phiNorm<0) phiNorm+=2.*TMath::Pi();
5374 0 : if(anglet>0.5*TMath::Pi()) anglet = (TMath::Pi()-anglet);
5375 0 : if(phiNorm>phiPt) anglet*=-1.;// pt-->normt clockwise: anglet>0
5376 0 : if((phiNorm-phiPt)>TMath::Pi()) anglet*=-1.;
5377 0 : anglet *= 180./TMath::Pi();
5378 :
5379 0 : angleModTrack[2]=(Float_t) angle;
5380 0 : angleModTrack[0]=(Float_t) anglet;
5381 : // now the "angle in z" (much easier, i.e. the angle between the z axis and the track momentum + 90)
5382 0 : angleModTrack[1]=TMath::ACos(tgl/TMath::Sqrt(tgl*tgl+1.));
5383 0 : angleModTrack[1]-=TMath::Pi()/2.; // range of angle is -pi/2 , pi/2
5384 0 : angleModTrack[1]*=180./TMath::Pi(); // in degree
5385 :
5386 0 : fPlaneEff->FillHistos(key,found,tr,clu,cltype,angleModTrack);
5387 :
5388 : // For FO efficiency studies of SPD
5389 0 : if(ilayer<2 && !fSPDChipIntPlaneEff[key]) fPlaneEff->FillHistos(keyFO,foundFO,tr,clu,cltype,angleModTrack);
5390 0 : }
5391 0 : if(ilayer<2) fSPDChipIntPlaneEff[key]=kTRUE;
5392 : return;
5393 0 : }
5394 :
5395 : Int_t AliITStrackerMI::FindClusterOfTrack(int label, int lr, int* store) const //RS
5396 : {
5397 : // find the MC cluster for the label
5398 0 : return fgLayers[lr].FindClusterForLabel(label,store);
5399 : }
5400 :
5401 : /*
5402 : Int_t AliITStrackerMI::GetPattern(const AliITStrackMI* track, char* patt)
5403 : {
5404 : // creates pattarn of hits marking fake/corrects by f/c. Used for debugging (RS)
5405 : strncpy(patt,"......",6);
5406 : int tpcLabel = 0;
5407 : if (track->GetESDtrack()) tpcLabel = track->GetESDtrack()->GetTPCLabel();
5408 : //
5409 : int nwrong = 0;
5410 : for (Int_t i=0;i<track->GetNumberOfClusters();i++){
5411 : Int_t cindex = track->GetClusterIndex(i);
5412 : Int_t l=(cindex & 0xf0000000) >> 28;
5413 : AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
5414 : Int_t isWrong=1;
5415 : for (Int_t ind=0;ind<3;ind++) if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
5416 : patt[l] = isWrong ? 'f':'c';
5417 : nwrong+=isWrong;
5418 : }
5419 : return nwrong;
5420 : }
5421 : */
5422 : //------------------------------------------------------------------------
5423 : Int_t AliITStrackerMI::AliITSlayer::FindClusterForLabel(Int_t label, Int_t *store) const
5424 : { //RS
5425 : //--------------------------------------------------------------------
5426 :
5427 : int nfound = 0;
5428 0 : for (int ic=0;ic<fN;ic++) {
5429 0 : const AliITSRecPoint *cl = GetCluster(ic);
5430 0 : for (int i=0;i<3;i++) if (cl->GetLabel(i)==label) {
5431 0 : if (nfound<50) {
5432 0 : if (store) store[nfound] = ic;
5433 0 : nfound++;
5434 0 : }
5435 0 : break;
5436 : }
5437 : }
5438 0 : return nfound;
5439 : }
5440 :
|