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