1 /**************************************************************************
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 //-------------------------------------------------------------------------
18 // Implementation of the ITS tracker class
19 // It reads AliITSRecPoint clusters and creates AliITStrackMI tracks
20 // and fills with them the ESD
21 // Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch
22 // Current support and development:
23 // Andrea Dainese, andrea.dainese@lnl.infn.it
24 // dE/dx analysis by: Boris Batyunya, JINR, Boris.Batiounia@cern.ch
25 // Params moved to AliITSRecoParam by: Andrea Dainese, INFN
26 // Material budget from TGeo by: Ludovic Gaudichet & Andrea Dainese, INFN
27 //-------------------------------------------------------------------------
31 #include <TDatabasePDG.h>
34 #include <TTreeStream.h>
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"
47 #include "AliESDEvent.h"
48 #include "AliESDtrack.h"
51 #include "AliITSChannelStatus.h"
52 #include "AliITSDetTypeRec.h"
53 #include "AliITSRecPoint.h"
54 #include "AliITSgeomTGeo.h"
55 #include "AliITSReconstructor.h"
56 #include "AliITSClusterParam.h"
57 #include "AliITSsegmentation.h"
58 #include "AliITSCalibration.h"
59 #include "AliITSPlaneEffSPD.h"
60 #include "AliITSPlaneEffSDD.h"
61 #include "AliITSPlaneEffSSD.h"
62 #include "AliITStrackerMI.h"
64 ClassImp(AliITStrackerMI)
66 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
68 AliITStrackerMI::AliITStrackerMI():AliTracker(),
78 fLastLayerToTrackTo(0),
81 fTrackingPhase("Default"),
87 fxTimesRhoPipeTrks(0),
88 fxOverX0ShieldTrks(0),
89 fxTimesRhoShieldTrks(0),
91 fxTimesRhoLayerTrks(0),
98 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
99 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
100 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
102 //------------------------------------------------------------------------
103 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
104 fI(AliITSgeomTGeo::GetNLayers()),
113 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
116 fTrackingPhase("Default"),
122 fxTimesRhoPipeTrks(0),
123 fxOverX0ShieldTrks(0),
124 fxTimesRhoShieldTrks(0),
125 fxOverX0LayerTrks(0),
126 fxTimesRhoLayerTrks(0),
128 fITSChannelStatus(0),
131 //--------------------------------------------------------------------
132 //This is the AliITStrackerMI constructor
133 //--------------------------------------------------------------------
135 AliWarning("\"geom\" is actually a dummy argument !");
141 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
142 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
143 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
145 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
146 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
147 Double_t poff=TMath::ATan2(y,x);
149 Double_t r=TMath::Sqrt(x*x + y*y);
151 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
152 r += TMath::Sqrt(x*x + y*y);
153 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
154 r += TMath::Sqrt(x*x + y*y);
155 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
156 r += TMath::Sqrt(x*x + y*y);
159 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
161 for (Int_t j=1; j<nlad+1; j++) {
162 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
163 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
164 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
166 Double_t txyz[3]={0.};
167 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
168 m.LocalToMaster(txyz,xyz);
169 r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
170 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
172 if (phi<0) phi+=TMath::TwoPi();
173 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
175 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
176 new(&det) AliITSdetector(r,phi);
177 // compute the real radius (with misalignment)
178 TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
180 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
181 mmisal.LocalToMaster(txyz,xyz);
182 Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
183 det.SetRmisal(rmisal);
185 } // end loop on detectors
186 } // end loop on ladders
187 } // end loop on layers
190 fI=AliITSgeomTGeo::GetNLayers();
193 fConstraint[0]=1; fConstraint[1]=0;
195 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
196 AliITSReconstructor::GetRecoParam()->GetYVdef(),
197 AliITSReconstructor::GetRecoParam()->GetZVdef()};
198 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
199 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
200 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
201 SetVertex(xyzVtx,ersVtx);
203 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=AliITSRecoParam::GetLayersNotToSkip(i);
204 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
205 for (Int_t i=0;i<100000;i++){
206 fBestTrackIndex[i]=0;
209 // store positions of centre of SPD modules (in z)
211 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
212 fSPDdetzcentre[0] = tr[2];
213 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
214 fSPDdetzcentre[1] = tr[2];
215 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
216 fSPDdetzcentre[2] = tr[2];
217 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
218 fSPDdetzcentre[3] = tr[2];
220 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
221 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
222 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
226 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
227 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
229 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
231 // only for plane efficiency evaluation
232 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff()) {
233 Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
234 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane))
235 AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
236 if (iplane<2) fPlaneEff = new AliITSPlaneEffSPD();
237 else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
238 else fPlaneEff = new AliITSPlaneEffSSD();
239 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
240 if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
241 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
244 //------------------------------------------------------------------------
245 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
247 fBestTrack(tracker.fBestTrack),
248 fTrackToFollow(tracker.fTrackToFollow),
249 fTrackHypothesys(tracker.fTrackHypothesys),
250 fBestHypothesys(tracker.fBestHypothesys),
251 fOriginal(tracker.fOriginal),
252 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
253 fPass(tracker.fPass),
254 fAfterV0(tracker.fAfterV0),
255 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
256 fCoefficients(tracker.fCoefficients),
258 fTrackingPhase(tracker.fTrackingPhase),
259 fUseTGeo(tracker.fUseTGeo),
260 fNtracks(tracker.fNtracks),
261 fxOverX0Pipe(tracker.fxOverX0Pipe),
262 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
264 fxTimesRhoPipeTrks(0),
265 fxOverX0ShieldTrks(0),
266 fxTimesRhoShieldTrks(0),
267 fxOverX0LayerTrks(0),
268 fxTimesRhoLayerTrks(0),
269 fDebugStreamer(tracker.fDebugStreamer),
270 fITSChannelStatus(tracker.fITSChannelStatus),
271 fkDetTypeRec(tracker.fkDetTypeRec),
272 fPlaneEff(tracker.fPlaneEff) {
276 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
279 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
280 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
283 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
284 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
287 //------------------------------------------------------------------------
288 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
289 //Assignment operator
290 this->~AliITStrackerMI();
291 new(this) AliITStrackerMI(tracker);
294 //------------------------------------------------------------------------
295 AliITStrackerMI::~AliITStrackerMI()
300 if (fCoefficients) delete [] fCoefficients;
301 DeleteTrksMaterialLUT();
302 if (fDebugStreamer) {
303 //fDebugStreamer->Close();
304 delete fDebugStreamer;
306 if(fITSChannelStatus) delete fITSChannelStatus;
307 if(fPlaneEff) delete fPlaneEff;
309 //------------------------------------------------------------------------
310 void AliITStrackerMI::SetLayersNotToSkip(const Int_t *l) {
311 //--------------------------------------------------------------------
312 //This function set masks of the layers which must be not skipped
313 //--------------------------------------------------------------------
314 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=l[i];
316 //------------------------------------------------------------------------
317 void AliITStrackerMI::ReadBadFromDetTypeRec() {
318 //--------------------------------------------------------------------
319 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
321 //--------------------------------------------------------------------
323 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
325 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
327 if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
330 if(fITSChannelStatus) delete fITSChannelStatus;
331 fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
333 // ITS detectors and chips
334 Int_t i=0,j=0,k=0,ndet=0;
335 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
336 Int_t nBadDetsPerLayer=0;
337 ndet=AliITSgeomTGeo::GetNDetectors(i);
338 for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
339 for (k=1; k<ndet+1; k++) {
340 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
341 det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fkDetTypeRec);
342 if(det.IsBad()) {nBadDetsPerLayer++;}
343 } // end loop on detectors
344 } // end loop on ladders
345 Info("ReadBadFromDetTypeRec",Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
346 } // end loop on layers
350 //------------------------------------------------------------------------
351 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
352 //--------------------------------------------------------------------
353 //This function loads ITS clusters
354 //--------------------------------------------------------------------
355 TBranch *branch=cTree->GetBranch("ITSRecPoints");
357 Error("LoadClusters"," can't get the branch !\n");
361 static TClonesArray dummy("AliITSRecPoint",10000), *clusters=&dummy;
362 branch->SetAddress(&clusters);
364 Int_t i=0,j=0,ndet=0;
366 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
367 ndet=fgLayers[i].GetNdetectors();
368 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
369 for (; j<jmax; j++) {
370 if (!cTree->GetEvent(j)) continue;
371 Int_t ncl=clusters->GetEntriesFast();
372 SignDeltas(clusters,GetZ());
375 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
376 detector=c->GetDetectorIndex();
378 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
380 fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
383 // add dead zone "virtual" cluster in SPD, if there is a cluster within
384 // zwindow cm from the dead zone
385 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
386 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
387 Int_t lab[4] = {0,0,0,detector};
388 Int_t info[3] = {0,0,i};
389 Float_t q = 0.; // this identifies virtual clusters
390 Float_t hit[5] = {xdead,
392 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
393 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
395 Bool_t local = kTRUE;
396 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
397 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
398 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
399 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
400 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
401 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
402 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
403 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
404 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
405 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
406 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
407 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
408 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
409 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
410 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
411 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
412 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
413 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
414 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
416 } // "virtual" clusters in SPD
420 fgLayers[i].ResetRoad(); //road defined by the cluster density
421 fgLayers[i].SortClusters();
428 //------------------------------------------------------------------------
429 void AliITStrackerMI::UnloadClusters() {
430 //--------------------------------------------------------------------
431 //This function unloads ITS clusters
432 //--------------------------------------------------------------------
433 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
435 //------------------------------------------------------------------------
436 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
437 //--------------------------------------------------------------------
438 // Publishes all pointers to clusters known to the tracker into the
439 // passed object array.
440 // The ownership is not transfered - the caller is not expected to delete
442 //--------------------------------------------------------------------
444 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
445 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
446 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
453 //------------------------------------------------------------------------
454 static Int_t CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
455 //--------------------------------------------------------------------
456 // Correction for the material between the TPC and the ITS
457 //--------------------------------------------------------------------
458 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
459 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
460 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
461 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
462 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
463 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
464 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
465 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
467 Error("CorrectForTPCtoITSDeadZoneMaterial","Track is already in the dead zone !");
473 //------------------------------------------------------------------------
474 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
475 //--------------------------------------------------------------------
476 // This functions reconstructs ITS tracks
477 // The clusters must be already loaded !
478 //--------------------------------------------------------------------
481 fTrackingPhase="Clusters2Tracks";
483 TObjArray itsTracks(15000);
485 fEsd = event; // store pointer to the esd
487 // temporary (for cosmics)
488 if(event->GetVertex()) {
489 TString title = event->GetVertex()->GetTitle();
490 if(title.Contains("cosmics")) {
491 Double_t xyz[3]={GetX(),GetY(),GetZ()};
492 Double_t exyz[3]={0.1,0.1,0.1};
498 {/* Read ESD tracks */
499 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
500 Int_t nentr=event->GetNumberOfTracks();
501 Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
503 AliESDtrack *esd=event->GetTrack(nentr);
504 // ---- for debugging:
505 //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); }
507 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
508 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
509 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
510 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
513 t=new AliITStrackMI(*esd);
514 } catch (const Char_t *msg) {
515 //Warning("Clusters2Tracks",msg);
519 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
520 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
523 // look at the ESD mass hypothesys !
524 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
526 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
528 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
529 //track - can be V0 according to TPC
531 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
535 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
539 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
543 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
548 t->SetReconstructed(kFALSE);
549 itsTracks.AddLast(t);
550 fOriginal.AddLast(t);
552 } /* End Read ESD tracks */
556 Int_t nentr=itsTracks.GetEntriesFast();
557 fTrackHypothesys.Expand(nentr);
558 fBestHypothesys.Expand(nentr);
559 MakeCoefficients(nentr);
560 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
562 // THE TWO TRACKING PASSES
563 for (fPass=0; fPass<2; fPass++) {
564 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
565 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
566 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
567 if (t==0) continue; //this track has been already tracked
568 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
569 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
570 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
571 if (fConstraint[fPass]) {
572 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
573 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
576 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
577 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
579 ResetTrackToFollow(*t);
582 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
585 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
587 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
588 if (!besttrack) continue;
589 besttrack->SetLabel(tpcLabel);
590 // besttrack->CookdEdx();
592 besttrack->SetFakeRatio(1.);
593 CookLabel(besttrack,0.); //For comparison only
594 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
596 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
598 t->SetReconstructed(kTRUE);
600 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
602 GetBestHypothesysMIP(itsTracks);
603 } // end loop on the two tracking passes
605 if(event->GetNumberOfV0s()>0) UpdateTPCV0(event);
606 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) FindV02(event);
611 Int_t entries = fTrackHypothesys.GetEntriesFast();
612 for (Int_t ientry=0; ientry<entries; ientry++) {
613 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
614 if (array) array->Delete();
615 delete fTrackHypothesys.RemoveAt(ientry);
618 fTrackHypothesys.Delete();
619 fBestHypothesys.Delete();
621 delete [] fCoefficients;
623 DeleteTrksMaterialLUT();
625 Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
627 fTrackingPhase="Default";
631 //------------------------------------------------------------------------
632 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
633 //--------------------------------------------------------------------
634 // This functions propagates reconstructed ITS tracks back
635 // The clusters must be loaded !
636 //--------------------------------------------------------------------
637 fTrackingPhase="PropagateBack";
638 Int_t nentr=event->GetNumberOfTracks();
639 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
642 for (Int_t i=0; i<nentr; i++) {
643 AliESDtrack *esd=event->GetTrack(i);
645 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
646 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
650 t=new AliITStrackMI(*esd);
651 } catch (const Char_t *msg) {
652 //Warning("PropagateBack",msg);
656 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
658 ResetTrackToFollow(*t);
660 // propagate to vertex [SR, GSI 17.02.2003]
661 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
662 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
663 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
664 fTrackToFollow.StartTimeIntegral();
665 // from vertex to outside pipe
666 CorrectForPipeMaterial(&fTrackToFollow,"outward");
669 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
670 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
671 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
675 fTrackToFollow.SetLabel(t->GetLabel());
676 //fTrackToFollow.CookdEdx();
677 CookLabel(&fTrackToFollow,0.); //For comparison only
678 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
679 //UseClusters(&fTrackToFollow);
685 Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
687 fTrackingPhase="Default";
691 //------------------------------------------------------------------------
692 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
693 //--------------------------------------------------------------------
694 // This functions refits ITS tracks using the
695 // "inward propagated" TPC tracks
696 // The clusters must be loaded !
697 //--------------------------------------------------------------------
698 fTrackingPhase="RefitInward";
699 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) RefitV02(event);
700 Int_t nentr=event->GetNumberOfTracks();
701 Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
704 for (Int_t i=0; i<nentr; i++) {
705 AliESDtrack *esd=event->GetTrack(i);
707 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
708 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
709 if (esd->GetStatus()&AliESDtrack::kTPCout)
710 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
714 t=new AliITStrackMI(*esd);
715 } catch (const Char_t *msg) {
716 //Warning("RefitInward",msg);
720 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
721 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
726 ResetTrackToFollow(*t);
727 fTrackToFollow.ResetClusters();
729 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
730 fTrackToFollow.ResetCovariance(10.);
733 Bool_t pe=AliITSReconstructor::GetRecoParam()->GetComputePlaneEff();
734 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
735 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
736 AliDebug(2," refit OK");
737 fTrackToFollow.SetLabel(t->GetLabel());
738 // fTrackToFollow.CookdEdx();
739 CookdEdx(&fTrackToFollow);
741 CookLabel(&fTrackToFollow,0.0); //For comparison only
744 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
745 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
746 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
747 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
748 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
749 Double_t r[3]={0.,0.,0.};
751 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
758 Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
760 fTrackingPhase="Default";
764 //------------------------------------------------------------------------
765 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
766 //--------------------------------------------------------------------
767 // Return pointer to a given cluster
768 //--------------------------------------------------------------------
769 Int_t l=(index & 0xf0000000) >> 28;
770 Int_t c=(index & 0x0fffffff) >> 00;
771 return fgLayers[l].GetCluster(c);
773 //------------------------------------------------------------------------
774 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
775 //--------------------------------------------------------------------
776 // Get track space point with index i
777 //--------------------------------------------------------------------
779 Int_t l=(index & 0xf0000000) >> 28;
780 Int_t c=(index & 0x0fffffff) >> 00;
781 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
782 Int_t idet = cl->GetDetectorIndex();
786 cl->GetGlobalXYZ(xyz);
787 cl->GetGlobalCov(cov);
789 p.SetCharge(cl->GetQ());
790 p.SetDriftTime(cl->GetDriftTime());
791 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
794 iLayer = AliGeomManager::kSPD1;
797 iLayer = AliGeomManager::kSPD2;
800 iLayer = AliGeomManager::kSDD1;
803 iLayer = AliGeomManager::kSDD2;
806 iLayer = AliGeomManager::kSSD1;
809 iLayer = AliGeomManager::kSSD2;
812 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
815 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
816 p.SetVolumeID((UShort_t)volid);
819 //------------------------------------------------------------------------
820 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
821 AliTrackPoint& p, const AliESDtrack *t) {
822 //--------------------------------------------------------------------
823 // Get track space point with index i
824 // (assign error estimated during the tracking)
825 //--------------------------------------------------------------------
827 Int_t l=(index & 0xf0000000) >> 28;
828 Int_t c=(index & 0x0fffffff) >> 00;
829 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
830 Int_t idet = cl->GetDetectorIndex();
832 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
834 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
836 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
837 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
838 Double_t alpha = t->GetAlpha();
839 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
840 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,GetBz()));
841 phi += alpha-det.GetPhi();
842 Float_t tgphi = TMath::Tan(phi);
844 Float_t tgl = t->GetTgl(); // tgl about const along track
845 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
847 Float_t errlocalx,errlocalz;
848 Bool_t addMisalErr=kFALSE;
849 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errlocalx,errlocalz,addMisalErr);
853 cl->GetGlobalXYZ(xyz);
854 // cl->GetGlobalCov(cov);
855 Float_t pos[3] = {0.,0.,0.};
856 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errlocalx*errlocalx,errlocalz*errlocalz,0);
857 tmpcl.GetGlobalCov(cov);
860 p.SetCharge(cl->GetQ());
861 p.SetDriftTime(cl->GetDriftTime());
863 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
866 iLayer = AliGeomManager::kSPD1;
869 iLayer = AliGeomManager::kSPD2;
872 iLayer = AliGeomManager::kSDD1;
875 iLayer = AliGeomManager::kSDD2;
878 iLayer = AliGeomManager::kSSD1;
881 iLayer = AliGeomManager::kSSD2;
884 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
887 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
889 p.SetVolumeID((UShort_t)volid);
892 //------------------------------------------------------------------------
893 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
895 //--------------------------------------------------------------------
896 // Follow prolongation tree
897 //--------------------------------------------------------------------
899 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
900 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
903 AliESDtrack * esd = otrack->GetESDtrack();
904 if (esd->GetV0Index(0)>0) {
905 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
906 // mapping of ESD track is different as ITS track in Containers
907 // Need something more stable
908 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
909 for (Int_t i=0;i<3;i++){
910 Int_t index = esd->GetV0Index(i);
912 AliESDv0 * vertex = fEsd->GetV0(index);
913 if (vertex->GetStatus()<0) continue; // rejected V0
915 if (esd->GetSign()>0) {
916 vertex->SetIndex(0,esdindex);
918 vertex->SetIndex(1,esdindex);
922 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
924 bestarray = new TObjArray(5);
925 fBestHypothesys.AddAt(bestarray,esdindex);
929 //setup tree of the prolongations
931 static AliITStrackMI tracks[7][100];
932 AliITStrackMI *currenttrack;
933 static AliITStrackMI currenttrack1;
934 static AliITStrackMI currenttrack2;
935 static AliITStrackMI backuptrack;
937 Int_t nindexes[7][100];
938 Float_t normalizedchi2[100];
939 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
940 otrack->SetNSkipped(0);
941 new (&(tracks[6][0])) AliITStrackMI(*otrack);
943 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
944 Int_t modstatus = 1; // found
948 // follow prolongations
949 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
950 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
953 AliITSlayer &layer=fgLayers[ilayer];
954 Double_t r = layer.GetR();
960 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
962 if (ntracks[ilayer]>=100) break;
963 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
964 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
965 if (ntracks[ilayer]>15+ilayer){
966 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
967 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
970 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
972 // material between SSD and SDD, SDD and SPD
974 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
976 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
980 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
981 Int_t idet=layer.FindDetectorIndex(phi,z);
983 Double_t trackGlobXYZ1[3];
984 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
986 // Get the budget to the primary vertex for the current track being prolonged
987 Double_t budgetToPrimVertex = GetEffectiveThickness();
989 // check if we allow a prolongation without point
990 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
992 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
993 // propagate to the layer radius
994 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
995 if(!vtrack->Propagate(xToGo)) continue;
996 // apply correction for material of the current layer
997 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
998 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
999 vtrack->SetClIndex(ilayer,0);
1000 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1001 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1002 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1004 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1009 // track outside layer acceptance in z
1010 if (idet<0) continue;
1012 //propagate to the intersection with the detector plane
1013 const AliITSdetector &det=layer.GetDetector(idet);
1014 new(¤ttrack2) AliITStrackMI(currenttrack1);
1015 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1016 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1017 currenttrack1.SetDetectorIndex(idet);
1018 currenttrack2.SetDetectorIndex(idet);
1019 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1022 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1024 // road in global (rphi,z) [i.e. in tracking ref. system]
1025 Double_t zmin,zmax,ymin,ymax;
1026 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1028 // select clusters in road
1029 layer.SelectClusters(zmin,zmax,ymin,ymax);
1030 //********************
1032 // Define criteria for track-cluster association
1033 Double_t msz = currenttrack1.GetSigmaZ2() +
1034 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1035 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1036 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1037 Double_t msy = currenttrack1.GetSigmaY2() +
1038 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1039 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1040 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1042 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1043 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1045 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1046 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1048 msz = 1./msz; // 1/RoadZ^2
1049 msy = 1./msy; // 1/RoadY^2
1053 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1055 const AliITSRecPoint *cl=0;
1057 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1058 Bool_t deadzoneSPD=kFALSE;
1059 currenttrack = ¤ttrack1;
1061 // check if the road contains a dead zone
1062 Bool_t noClusters = kFALSE;
1063 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1064 if (noClusters) AliDebug(2,"no clusters in road");
1065 Double_t dz=0.5*(zmax-zmin);
1066 Double_t dy=0.5*(ymax-ymin);
1067 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1068 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1069 // create a prolongation without clusters (check also if there are no clusters in the road)
1072 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1073 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1074 updatetrack->SetClIndex(ilayer,0);
1076 modstatus = 5; // no cls in road
1077 } else if (dead==1) {
1078 modstatus = 7; // holes in z in SPD
1079 } else if (dead==2 || dead==3) {
1080 modstatus = 2; // dead from OCDB
1082 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1083 // apply correction for material of the current layer
1084 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1085 if (constrain) { // apply vertex constrain
1086 updatetrack->SetConstrain(constrain);
1087 Bool_t isPrim = kTRUE;
1088 if (ilayer<4) { // check that it's close to the vertex
1089 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1090 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1091 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1092 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1093 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1095 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1098 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1099 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1100 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1108 // loop over clusters in the road
1109 while ((cl=layer.GetNextCluster(clidx))!=0) {
1110 if (ntracks[ilayer]>95) break; //space for skipped clusters
1111 Bool_t changedet =kFALSE;
1112 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
1113 Int_t idetc=cl->GetDetectorIndex();
1115 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1116 // take into account misalignment (bring track to real detector plane)
1117 Double_t xTrOrig = currenttrack->GetX();
1118 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1119 // a first cut on track-cluster distance
1120 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1121 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1122 { // cluster not associated to track
1123 AliDebug(2,"not associated");
1126 // bring track back to ideal detector plane
1127 if (!currenttrack->Propagate(xTrOrig)) continue;
1128 } else { // have to move track to cluster's detector
1129 const AliITSdetector &detc=layer.GetDetector(idetc);
1130 // a first cut on track-cluster distance
1132 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1133 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1134 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1135 continue; // cluster not associated to track
1137 new (&backuptrack) AliITStrackMI(currenttrack2);
1139 currenttrack =¤ttrack2;
1140 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1141 new (currenttrack) AliITStrackMI(backuptrack);
1145 currenttrack->SetDetectorIndex(idetc);
1146 // Get again the budget to the primary vertex
1147 // for the current track being prolonged, if had to change detector
1148 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1151 // calculate track-clusters chi2
1152 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1154 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1155 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1156 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1157 if (ntracks[ilayer]>=100) continue;
1158 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1159 updatetrack->SetClIndex(ilayer,0);
1160 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1162 if (cl->GetQ()!=0) { // real cluster
1163 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1164 AliDebug(2,"update failed");
1167 updatetrack->SetSampledEdx(cl->GetQ(),updatetrack->GetNumberOfClusters()-1); //b.b.
1168 modstatus = 1; // found
1169 } else { // virtual cluster in dead zone
1170 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1171 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1172 modstatus = 7; // holes in z in SPD
1176 Float_t xlocnewdet,zlocnewdet;
1177 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1178 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1181 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1183 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1185 // apply correction for material of the current layer
1186 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1188 if (constrain) { // apply vertex constrain
1189 updatetrack->SetConstrain(constrain);
1190 Bool_t isPrim = kTRUE;
1191 if (ilayer<4) { // check that it's close to the vertex
1192 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1193 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1194 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1195 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1196 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1198 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1199 } //apply vertex constrain
1201 } // create new hypothesis
1203 AliDebug(2,"chi2 too large");
1206 } // loop over possible prolongations
1208 // allow one prolongation without clusters
1209 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1210 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1211 // apply correction for material of the current layer
1212 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1213 vtrack->SetClIndex(ilayer,0);
1214 modstatus = 3; // skipped
1215 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1216 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1217 vtrack->IncrementNSkipped();
1221 // allow one prolongation without clusters for tracks with |tgl|>1.1
1222 if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) { //big theta - for low flux
1223 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1224 // apply correction for material of the current layer
1225 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1226 vtrack->SetClIndex(ilayer,0);
1227 modstatus = 3; // skipped
1228 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1229 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1230 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1235 } // loop over tracks in layer ilayer+1
1237 //loop over track candidates for the current layer
1243 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1244 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1245 if (normalizedchi2[itrack] <
1246 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1250 if (constrain) { // constrain
1251 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1253 } else { // !constrain
1254 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1259 // sort tracks by increasing normalized chi2
1260 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1261 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1262 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1263 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1264 } // end loop over layers
1268 // Now select tracks to be kept
1270 Int_t max = constrain ? 20 : 5;
1272 // tracks that reach layer 0 (SPD inner)
1273 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1274 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1275 if (track.GetNumberOfClusters()<2) continue;
1276 if (!constrain && track.GetNormChi2(0) >
1277 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1280 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1283 // tracks that reach layer 1 (SPD outer)
1284 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1285 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1286 if (track.GetNumberOfClusters()<4) continue;
1287 if (!constrain && track.GetNormChi2(1) >
1288 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1289 if (constrain) track.IncrementNSkipped();
1291 track.SetD(0,track.GetD(GetX(),GetY()));
1292 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1293 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1294 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1297 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1300 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1302 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1303 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1304 if (track.GetNumberOfClusters()<3) continue;
1305 if (!constrain && track.GetNormChi2(2) >
1306 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1307 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1309 track.SetD(0,track.GetD(GetX(),GetY()));
1310 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1311 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1312 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1315 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1321 // register best track of each layer - important for V0 finder
1323 for (Int_t ilayer=0;ilayer<5;ilayer++){
1324 if (ntracks[ilayer]==0) continue;
1325 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1326 if (track.GetNumberOfClusters()<1) continue;
1327 CookLabel(&track,0);
1328 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1332 // update TPC V0 information
1334 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1335 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1336 for (Int_t i=0;i<3;i++){
1337 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1338 if (index==0) break;
1339 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1340 if (vertex->GetStatus()<0) continue; // rejected V0
1342 if (otrack->GetSign()>0) {
1343 vertex->SetIndex(0,esdindex);
1346 vertex->SetIndex(1,esdindex);
1348 //find nearest layer with track info
1349 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1350 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1351 Int_t nearest = nearestold;
1352 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1353 if (ntracks[nearest]==0){
1358 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1359 if (nearestold<5&&nearest<5){
1360 Bool_t accept = track.GetNormChi2(nearest)<10;
1362 if (track.GetSign()>0) {
1363 vertex->SetParamP(track);
1364 vertex->Update(fprimvertex);
1365 //vertex->SetIndex(0,track.fESDtrack->GetID());
1366 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1368 vertex->SetParamN(track);
1369 vertex->Update(fprimvertex);
1370 //vertex->SetIndex(1,track.fESDtrack->GetID());
1371 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1373 vertex->SetStatus(vertex->GetStatus()+1);
1375 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1382 //------------------------------------------------------------------------
1383 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1385 //--------------------------------------------------------------------
1388 return fgLayers[layer];
1390 //------------------------------------------------------------------------
1391 AliITStrackerMI::AliITSlayer::AliITSlayer():
1416 //--------------------------------------------------------------------
1417 //default AliITSlayer constructor
1418 //--------------------------------------------------------------------
1419 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1420 fClusterWeight[i]=0;
1421 fClusterTracks[0][i]=-1;
1422 fClusterTracks[1][i]=-1;
1423 fClusterTracks[2][i]=-1;
1424 fClusterTracks[3][i]=-1;
1427 //------------------------------------------------------------------------
1428 AliITStrackerMI::AliITSlayer::
1429 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1454 //--------------------------------------------------------------------
1455 //main AliITSlayer constructor
1456 //--------------------------------------------------------------------
1457 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1458 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1460 //------------------------------------------------------------------------
1461 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1463 fPhiOffset(layer.fPhiOffset),
1464 fNladders(layer.fNladders),
1465 fZOffset(layer.fZOffset),
1466 fNdetectors(layer.fNdetectors),
1467 fDetectors(layer.fDetectors),
1472 fClustersCs(layer.fClustersCs),
1473 fClusterIndexCs(layer.fClusterIndexCs),
1477 fCurrentSlice(layer.fCurrentSlice),
1484 fAccepted(layer.fAccepted),
1488 //------------------------------------------------------------------------
1489 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1490 //--------------------------------------------------------------------
1491 // AliITSlayer destructor
1492 //--------------------------------------------------------------------
1493 delete [] fDetectors;
1494 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1495 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1496 fClusterWeight[i]=0;
1497 fClusterTracks[0][i]=-1;
1498 fClusterTracks[1][i]=-1;
1499 fClusterTracks[2][i]=-1;
1500 fClusterTracks[3][i]=-1;
1503 //------------------------------------------------------------------------
1504 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1505 //--------------------------------------------------------------------
1506 // This function removes loaded clusters
1507 //--------------------------------------------------------------------
1508 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1509 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1510 fClusterWeight[i]=0;
1511 fClusterTracks[0][i]=-1;
1512 fClusterTracks[1][i]=-1;
1513 fClusterTracks[2][i]=-1;
1514 fClusterTracks[3][i]=-1;
1520 //------------------------------------------------------------------------
1521 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1522 //--------------------------------------------------------------------
1523 // This function reset weights of the clusters
1524 //--------------------------------------------------------------------
1525 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1526 fClusterWeight[i]=0;
1527 fClusterTracks[0][i]=-1;
1528 fClusterTracks[1][i]=-1;
1529 fClusterTracks[2][i]=-1;
1530 fClusterTracks[3][i]=-1;
1532 for (Int_t i=0; i<fN;i++) {
1533 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1534 if (cl&&cl->IsUsed()) cl->Use();
1538 //------------------------------------------------------------------------
1539 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1540 //--------------------------------------------------------------------
1541 // This function calculates the road defined by the cluster density
1542 //--------------------------------------------------------------------
1544 for (Int_t i=0; i<fN; i++) {
1545 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1547 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1549 //------------------------------------------------------------------------
1550 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1551 //--------------------------------------------------------------------
1552 //This function adds a cluster to this layer
1553 //--------------------------------------------------------------------
1554 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1555 ::Error("InsertCluster","Too many clusters !\n");
1561 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1562 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1563 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1564 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1565 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1569 //------------------------------------------------------------------------
1570 void AliITStrackerMI::AliITSlayer::SortClusters()
1575 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1576 Float_t *z = new Float_t[fN];
1577 Int_t * index = new Int_t[fN];
1579 for (Int_t i=0;i<fN;i++){
1580 z[i] = fClusters[i]->GetZ();
1582 TMath::Sort(fN,z,index,kFALSE);
1583 for (Int_t i=0;i<fN;i++){
1584 clusters[i] = fClusters[index[i]];
1587 for (Int_t i=0;i<fN;i++){
1588 fClusters[i] = clusters[i];
1589 fZ[i] = fClusters[i]->GetZ();
1590 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1591 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1592 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1602 for (Int_t i=0;i<fN;i++){
1603 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1604 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1605 fClusterIndex[i] = i;
1609 fDy5 = (fYB[1]-fYB[0])/5.;
1610 fDy10 = (fYB[1]-fYB[0])/10.;
1611 fDy20 = (fYB[1]-fYB[0])/20.;
1612 for (Int_t i=0;i<6;i++) fN5[i] =0;
1613 for (Int_t i=0;i<11;i++) fN10[i]=0;
1614 for (Int_t i=0;i<21;i++) fN20[i]=0;
1616 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;}
1617 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;}
1618 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;}
1621 for (Int_t i=0;i<fN;i++)
1622 for (Int_t irot=-1;irot<=1;irot++){
1623 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1625 for (Int_t slice=0; slice<6;slice++){
1626 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1627 fClusters5[slice][fN5[slice]] = fClusters[i];
1628 fY5[slice][fN5[slice]] = curY;
1629 fZ5[slice][fN5[slice]] = fZ[i];
1630 fClusterIndex5[slice][fN5[slice]]=i;
1635 for (Int_t slice=0; slice<11;slice++){
1636 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1637 fClusters10[slice][fN10[slice]] = fClusters[i];
1638 fY10[slice][fN10[slice]] = curY;
1639 fZ10[slice][fN10[slice]] = fZ[i];
1640 fClusterIndex10[slice][fN10[slice]]=i;
1645 for (Int_t slice=0; slice<21;slice++){
1646 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1647 fClusters20[slice][fN20[slice]] = fClusters[i];
1648 fY20[slice][fN20[slice]] = curY;
1649 fZ20[slice][fN20[slice]] = fZ[i];
1650 fClusterIndex20[slice][fN20[slice]]=i;
1657 // consistency check
1659 for (Int_t i=0;i<fN-1;i++){
1665 for (Int_t slice=0;slice<21;slice++)
1666 for (Int_t i=0;i<fN20[slice]-1;i++){
1667 if (fZ20[slice][i]>fZ20[slice][i+1]){
1674 //------------------------------------------------------------------------
1675 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1676 //--------------------------------------------------------------------
1677 // This function returns the index of the nearest cluster
1678 //--------------------------------------------------------------------
1681 if (fCurrentSlice<0) {
1690 if (ncl==0) return 0;
1691 Int_t b=0, e=ncl-1, m=(b+e)/2;
1692 for (; b<e; m=(b+e)/2) {
1693 // if (z > fClusters[m]->GetZ()) b=m+1;
1694 if (z > zcl[m]) b=m+1;
1699 //------------------------------------------------------------------------
1700 Bool_t AliITStrackerMI::ComputeRoad(AliITStrackMI* track,Int_t ilayer,Int_t idet,Double_t &zmin,Double_t &zmax,Double_t &ymin,Double_t &ymax) const {
1701 //--------------------------------------------------------------------
1702 // This function computes the rectangular road for this track
1703 //--------------------------------------------------------------------
1706 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1707 // take into account the misalignment: propagate track to misaligned detector plane
1708 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1710 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1711 TMath::Sqrt(track->GetSigmaZ2() +
1712 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1713 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1714 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1715 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1716 TMath::Sqrt(track->GetSigmaY2() +
1717 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1718 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1719 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1721 // track at boundary between detectors, enlarge road
1722 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1723 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1724 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1725 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1726 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1727 Float_t tgl = TMath::Abs(track->GetTgl());
1728 if (tgl > 1.) tgl=1.;
1729 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1730 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1731 Float_t snp = TMath::Abs(track->GetSnp());
1732 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1733 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1736 // add to the road a term (up to 2-3 mm) to deal with misalignments
1737 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1738 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1740 Double_t r = fgLayers[ilayer].GetR();
1741 zmin = track->GetZ() - dz;
1742 zmax = track->GetZ() + dz;
1743 ymin = track->GetY() + r*det.GetPhi() - dy;
1744 ymax = track->GetY() + r*det.GetPhi() + dy;
1746 // bring track back to idead detector plane
1747 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1751 //------------------------------------------------------------------------
1752 void AliITStrackerMI::AliITSlayer::
1753 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1754 //--------------------------------------------------------------------
1755 // This function sets the "window"
1756 //--------------------------------------------------------------------
1758 Double_t circle=2*TMath::Pi()*fR;
1759 fYmin = ymin; fYmax =ymax;
1760 Float_t ymiddle = (fYmin+fYmax)*0.5;
1761 if (ymiddle<fYB[0]) {
1762 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1763 } else if (ymiddle>fYB[1]) {
1764 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1770 fClustersCs = fClusters;
1771 fClusterIndexCs = fClusterIndex;
1777 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1778 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1779 if (slice<0) slice=0;
1780 if (slice>20) slice=20;
1781 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1783 fCurrentSlice=slice;
1784 fClustersCs = fClusters20[fCurrentSlice];
1785 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1786 fYcs = fY20[fCurrentSlice];
1787 fZcs = fZ20[fCurrentSlice];
1788 fNcs = fN20[fCurrentSlice];
1793 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1794 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1795 if (slice<0) slice=0;
1796 if (slice>10) slice=10;
1797 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1799 fCurrentSlice=slice;
1800 fClustersCs = fClusters10[fCurrentSlice];
1801 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1802 fYcs = fY10[fCurrentSlice];
1803 fZcs = fZ10[fCurrentSlice];
1804 fNcs = fN10[fCurrentSlice];
1809 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1810 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1811 if (slice<0) slice=0;
1812 if (slice>5) slice=5;
1813 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1815 fCurrentSlice=slice;
1816 fClustersCs = fClusters5[fCurrentSlice];
1817 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1818 fYcs = fY5[fCurrentSlice];
1819 fZcs = fZ5[fCurrentSlice];
1820 fNcs = fN5[fCurrentSlice];
1824 fI=FindClusterIndex(zmin); fZmax=zmax;
1825 fImax = TMath::Min(FindClusterIndex(zmax)+1,fNcs);
1831 //------------------------------------------------------------------------
1832 Int_t AliITStrackerMI::AliITSlayer::
1833 FindDetectorIndex(Double_t phi, Double_t z) const {
1834 //--------------------------------------------------------------------
1835 //This function finds the detector crossed by the track
1836 //--------------------------------------------------------------------
1838 if (fZOffset<0) // old geometry
1839 dphi = -(phi-fPhiOffset);
1840 else // new geometry
1841 dphi = phi-fPhiOffset;
1844 if (dphi < 0) dphi += 2*TMath::Pi();
1845 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1846 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1847 if (np>=fNladders) np-=fNladders;
1848 if (np<0) np+=fNladders;
1851 Double_t dz=fZOffset-z;
1852 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1853 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1854 if (nz>=fNdetectors) return -1;
1855 if (nz<0) return -1;
1857 // ad hoc correction for 3rd ladder of SDD inner layer,
1858 // which is reversed (rotated by pi around local y)
1859 // this correction is OK only from AliITSv11Hybrid onwards
1860 if (GetR()>12. && GetR()<20.) { // SDD inner
1861 if(np==2) { // 3rd ladder
1862 nz = (fNdetectors-1) - nz;
1865 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1868 return np*fNdetectors + nz;
1870 //------------------------------------------------------------------------
1871 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1873 //--------------------------------------------------------------------
1874 // This function returns clusters within the "window"
1875 //--------------------------------------------------------------------
1877 if (fCurrentSlice<0) {
1878 Double_t rpi2 = 2.*fR*TMath::Pi();
1879 for (Int_t i=fI; i<fImax; i++) {
1881 if (fYmax<y) y -= rpi2;
1882 if (fYmin>y) y += rpi2;
1883 if (y<fYmin) continue;
1884 if (y>fYmax) continue;
1885 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1888 return fClusters[i];
1891 for (Int_t i=fI; i<fImax; i++) {
1892 if (fYcs[i]<fYmin) continue;
1893 if (fYcs[i]>fYmax) continue;
1894 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1895 ci=fClusterIndexCs[i];
1897 return fClustersCs[i];
1902 //------------------------------------------------------------------------
1903 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1905 //--------------------------------------------------------------------
1906 // This function returns the layer thickness at this point (units X0)
1907 //--------------------------------------------------------------------
1909 x0=AliITSRecoParam::GetX0Air();
1910 if (43<fR&&fR<45) { //SSD2
1913 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1914 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1915 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1916 for (Int_t i=0; i<12; i++) {
1917 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1918 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1922 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1923 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1927 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1928 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1931 if (37<fR&&fR<41) { //SSD1
1934 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1935 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1936 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1937 for (Int_t i=0; i<11; i++) {
1938 if (TMath::Abs(z-3.9*i)<0.15) {
1939 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1943 if (TMath::Abs(z+3.9*i)<0.15) {
1944 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1948 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1949 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1952 if (13<fR&&fR<26) { //SDD
1955 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1957 if (TMath::Abs(y-1.80)<0.55) {
1959 for (Int_t j=0; j<20; j++) {
1960 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1961 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1964 if (TMath::Abs(y+1.80)<0.55) {
1966 for (Int_t j=0; j<20; j++) {
1967 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1968 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1972 for (Int_t i=0; i<4; i++) {
1973 if (TMath::Abs(z-7.3*i)<0.60) {
1975 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1978 if (TMath::Abs(z+7.3*i)<0.60) {
1980 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1985 if (6<fR&&fR<8) { //SPD2
1986 Double_t dd=0.0063; x0=21.5;
1988 if (TMath::Abs(y-3.08)>0.5) d+=dd;
1989 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
1991 if (3<fR&&fR<5) { //SPD1
1992 Double_t dd=0.0063; x0=21.5;
1994 if (TMath::Abs(y+0.21)>0.6) d+=dd;
1995 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2000 //------------------------------------------------------------------------
2001 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2003 fRmisal(det.fRmisal),
2005 fSinPhi(det.fSinPhi),
2006 fCosPhi(det.fCosPhi),
2012 fNChips(det.fNChips),
2013 fChipIsBad(det.fChipIsBad)
2017 //------------------------------------------------------------------------
2018 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2019 const AliITSDetTypeRec *detTypeRec)
2021 //--------------------------------------------------------------------
2022 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2023 //--------------------------------------------------------------------
2025 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2026 // while in the tracker they start from 0 for each layer
2027 for(Int_t il=0; il<ilayer; il++)
2028 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2031 if (ilayer==0 || ilayer==1) { // ---------- SPD
2033 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2035 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2038 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2042 // Get calibration from AliITSDetTypeRec
2043 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2044 calib->SetModuleIndex(idet);
2045 AliITSCalibration *calibSPDdead = 0;
2046 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2047 if (calib->IsBad() ||
2048 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2051 // printf("lay %d bad %d\n",ilayer,idet);
2054 // Get segmentation from AliITSDetTypeRec
2055 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2057 // Read info about bad chips
2058 fNChips = segm->GetMaximumChipIndex()+1;
2059 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2060 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2061 fChipIsBad = new Bool_t[fNChips];
2062 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2063 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2064 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2065 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2070 //------------------------------------------------------------------------
2071 Double_t AliITStrackerMI::GetEffectiveThickness()
2073 //--------------------------------------------------------------------
2074 // Returns the thickness between the current layer and the vertex (units X0)
2075 //--------------------------------------------------------------------
2078 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2079 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2080 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2084 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2085 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2089 Double_t xn=fgLayers[fI].GetR();
2090 for (Int_t i=0; i<fI; i++) {
2091 Double_t xi=fgLayers[i].GetR();
2092 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2098 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2099 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2102 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2103 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2107 //------------------------------------------------------------------------
2108 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2109 //-------------------------------------------------------------------
2110 // This function returns number of clusters within the "window"
2111 //--------------------------------------------------------------------
2113 for (Int_t i=fI; i<fN; i++) {
2114 const AliITSRecPoint *c=fClusters[i];
2115 if (c->GetZ() > fZmax) break;
2116 if (c->IsUsed()) continue;
2117 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2118 Double_t y=fR*det.GetPhi() + c->GetY();
2120 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2121 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2123 if (y<fYmin) continue;
2124 if (y>fYmax) continue;
2129 //------------------------------------------------------------------------
2130 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2131 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2133 //--------------------------------------------------------------------
2134 // This function refits the track "track" at the position "x" using
2135 // the clusters from "clusters"
2136 // If "extra"==kTRUE,
2137 // the clusters from overlapped modules get attached to "track"
2138 // If "planeff"==kTRUE,
2139 // special approach for plane efficiency evaluation is applyed
2140 //--------------------------------------------------------------------
2142 Int_t index[AliITSgeomTGeo::kNLayers];
2144 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2145 Int_t nc=clusters->GetNumberOfClusters();
2146 for (k=0; k<nc; k++) {
2147 Int_t idx=clusters->GetClusterIndex(k);
2148 Int_t ilayer=(idx&0xf0000000)>>28;
2152 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2154 //------------------------------------------------------------------------
2155 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2156 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2158 //--------------------------------------------------------------------
2159 // This function refits the track "track" at the position "x" using
2160 // the clusters from array
2161 // If "extra"==kTRUE,
2162 // the clusters from overlapped modules get attached to "track"
2163 // If "planeff"==kTRUE,
2164 // special approach for plane efficiency evaluation is applyed
2165 //--------------------------------------------------------------------
2166 Int_t index[AliITSgeomTGeo::kNLayers];
2168 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2170 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2171 index[k]=clusters[k];
2174 // special for cosmics: check which the innermost layer crossed
2176 Int_t innermostlayer=5;
2177 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2178 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2179 if(drphi < fgLayers[innermostlayer].GetR()) break;
2181 //printf(" drphi %f innermost %d\n",drphi,innermostlayer);
2183 Int_t modstatus=1; // found
2185 Int_t from, to, step;
2186 if (xx > track->GetX()) {
2187 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2190 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2193 TString dir = (step>0 ? "outward" : "inward");
2195 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2196 AliITSlayer &layer=fgLayers[ilayer];
2197 Double_t r=layer.GetR();
2198 if (step<0 && xx>r) break;
2200 // material between SSD and SDD, SDD and SPD
2201 Double_t hI=ilayer-0.5*step;
2202 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2203 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2204 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2205 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2207 // remember old position [SR, GSI 18.02.2003]
2208 Double_t oldX=0., oldY=0., oldZ=0.;
2209 if (track->IsStartedTimeIntegral() && step==1) {
2210 if (!track->GetGlobalXYZat(track->GetX(),oldX,oldY,oldZ)) return kFALSE;
2214 Double_t oldGlobXYZ[3];
2215 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2216 //TMath::Sqrt(track->GetSigmaY2());
2219 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2221 Int_t idet=layer.FindDetectorIndex(phi,z);
2223 // check if we allow a prolongation without point for large-eta tracks
2224 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2226 // propagate to the layer radius
2227 Double_t xToGo; if (!track->GetLocalXat(r,xToGo)) return kFALSE;
2228 if (!track->Propagate(xToGo)) return kFALSE;
2229 // apply correction for material of the current layer
2230 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2231 modstatus = 4; // out in z
2232 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2233 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2235 // track time update [SR, GSI 17.02.2003]
2236 if (track->IsStartedTimeIntegral() && step==1) {
2237 Double_t newX, newY, newZ;
2238 if (!track->GetGlobalXYZat(track->GetX(),newX,newY,newZ)) return kFALSE;
2239 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2240 (oldZ-newZ)*(oldZ-newZ);
2241 track->AddTimeStep(TMath::Sqrt(dL2));
2246 if (idet<0) return kFALSE;
2248 const AliITSdetector &det=layer.GetDetector(idet);
2249 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2251 track->SetDetectorIndex(idet);
2252 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2254 Double_t dz,zmin,zmax,dy,ymin,ymax;
2256 const AliITSRecPoint *clAcc=0;
2257 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2259 Int_t idx=index[ilayer];
2260 if (idx>=0) { // cluster in this layer
2261 modstatus = 6; // no refit
2262 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2264 if (idet != cl->GetDetectorIndex()) {
2265 idet=cl->GetDetectorIndex();
2266 const AliITSdetector &detc=layer.GetDetector(idet);
2267 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2268 track->SetDetectorIndex(idet);
2269 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2271 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2272 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2276 modstatus = 1; // found
2281 } else { // no cluster in this layer
2283 modstatus = 3; // skipped
2284 // Plane Eff determination:
2285 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2286 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2287 UseTrackForPlaneEff(track,ilayer);
2290 modstatus = 5; // no cls in road
2292 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2293 dz = 0.5*(zmax-zmin);
2294 dy = 0.5*(ymax-ymin);
2295 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2296 if (dead==1) modstatus = 7; // holes in z in SPD
2297 if (dead==2 || dead==3) modstatus = 2; // dead from OCDB
2302 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2303 track->SetSampledEdx(clAcc->GetQ(),track->GetNumberOfClusters()-1);
2305 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2308 if (extra) { // search for extra clusters in overlapped modules
2309 AliITStrackV2 tmp(*track);
2310 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2311 layer.SelectClusters(zmin,zmax,ymin,ymax);
2313 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2315 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2316 Double_t tolerance=0.1;
2317 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2318 // only clusters in another module! (overlaps)
2319 idetExtra = clExtra->GetDetectorIndex();
2320 if (idet == idetExtra) continue;
2322 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2324 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2325 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2326 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2327 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2329 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2330 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2333 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2334 track->SetExtraModule(ilayer,idetExtra);
2336 } // end search for extra clusters in overlapped modules
2338 // Correct for material of the current layer
2339 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2341 // track time update [SR, GSI 17.02.2003]
2342 if (track->IsStartedTimeIntegral() && step==1) {
2343 Double_t newX, newY, newZ;
2344 if (!track->GetGlobalXYZat(track->GetX(),newX,newY,newZ)) return kFALSE;
2345 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2346 (oldZ-newZ)*(oldZ-newZ);
2347 track->AddTimeStep(TMath::Sqrt(dL2));
2351 } // end loop on layers
2353 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2357 //------------------------------------------------------------------------
2358 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2361 // calculate normalized chi2
2362 // return NormalizedChi2(track,0);
2365 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2366 // track->fdEdxMismatch=0;
2367 Float_t dedxmismatch =0;
2368 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2370 for (Int_t i = 0;i<6;i++){
2371 if (track->GetClIndex(i)>0){
2372 Float_t cerry, cerrz;
2373 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2375 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2378 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2379 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2380 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2382 cchi2+=(0.5-ratio)*10.;
2383 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2384 dedxmismatch+=(0.5-ratio)*10.;
2388 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2389 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2390 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2391 if (i<2) chi2+=2*cl->GetDeltaProbability();
2397 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2398 track->SetdEdxMismatch(dedxmismatch);
2402 for (Int_t i = 0;i<4;i++){
2403 if (track->GetClIndex(i)>0){
2404 Float_t cerry, cerrz;
2405 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2406 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2409 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2410 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2414 for (Int_t i = 4;i<6;i++){
2415 if (track->GetClIndex(i)>0){
2416 Float_t cerry, cerrz;
2417 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2418 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2421 Float_t cerryb, cerrzb;
2422 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2423 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2426 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2427 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2432 if (track->GetESDtrack()->GetTPCsignal()>85){
2433 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2435 chi2+=(0.5-ratio)*5.;
2438 chi2+=(ratio-2.0)*3;
2442 Double_t match = TMath::Sqrt(track->GetChi22());
2443 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2444 if (!track->GetConstrain()) {
2445 if (track->GetNumberOfClusters()>2) {
2446 match/=track->GetNumberOfClusters()-2.;
2451 if (match<0) match=0;
2452 Float_t deadzonefactor = (track->GetNDeadZone()>0) ? 3*(1.1-track->GetDeadZoneProbability()):0.;
2453 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2454 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2455 1./(1.+track->GetNSkipped()));
2459 //------------------------------------------------------------------------
2460 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2463 // return matching chi2 between two tracks
2464 Double_t largeChi2=1000.;
2466 AliITStrackMI track3(*track2);
2467 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2469 vec(0,0)=track1->GetY() - track3.GetY();
2470 vec(1,0)=track1->GetZ() - track3.GetZ();
2471 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2472 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2473 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2476 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2477 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2478 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2479 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2480 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2482 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2483 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2484 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2485 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2487 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2488 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2489 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2491 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2492 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2494 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2497 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2498 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2501 //------------------------------------------------------------------------
2502 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2505 // return probability that given point (characterized by z position and error)
2506 // is in SPD dead zone
2508 Double_t probability = 0.;
2509 Double_t absz = TMath::Abs(zpos);
2510 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2511 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2512 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2513 Double_t zmin, zmax;
2514 if (zpos<-6.) { // dead zone at z = -7
2515 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2516 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2517 } else if (zpos>6.) { // dead zone at z = +7
2518 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2519 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2520 } else if (absz<2.) { // dead zone at z = 0
2521 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2522 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2527 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2529 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2530 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2533 //------------------------------------------------------------------------
2534 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2537 // calculate normalized chi2
2539 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2541 for (Int_t i = 0;i<6;i++){
2542 if (TMath::Abs(track->GetDy(i))>0){
2543 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2544 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2547 else{chi2[i]=10000;}
2550 TMath::Sort(6,chi2,index,kFALSE);
2551 Float_t max = float(ncl)*fac-1.;
2552 Float_t sumchi=0, sumweight=0;
2553 for (Int_t i=0;i<max+1;i++){
2554 Float_t weight = (i<max)?1.:(max+1.-i);
2555 sumchi+=weight*chi2[index[i]];
2558 Double_t normchi2 = sumchi/sumweight;
2561 //------------------------------------------------------------------------
2562 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2565 // calculate normalized chi2
2566 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2569 for (Int_t i=0;i<6;i++){
2570 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2571 Double_t sy1 = forwardtrack->GetSigmaY(i);
2572 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2573 Double_t sy2 = backtrack->GetSigmaY(i);
2574 Double_t sz2 = backtrack->GetSigmaZ(i);
2575 if (i<2){ sy2=1000.;sz2=1000;}
2577 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2578 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2580 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2581 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2583 res+= nz0*nz0+ny0*ny0;
2586 if (npoints>1) return
2587 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2588 //2*forwardtrack->fNUsed+
2589 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2590 1./(1.+forwardtrack->GetNSkipped()));
2593 //------------------------------------------------------------------------
2594 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2595 //--------------------------------------------------------------------
2596 // Return pointer to a given cluster
2597 //--------------------------------------------------------------------
2598 Int_t l=(index & 0xf0000000) >> 28;
2599 Int_t c=(index & 0x0fffffff) >> 00;
2600 return fgLayers[l].GetWeight(c);
2602 //------------------------------------------------------------------------
2603 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2605 //---------------------------------------------
2606 // register track to the list
2608 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2611 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2612 Int_t index = track->GetClusterIndex(icluster);
2613 Int_t l=(index & 0xf0000000) >> 28;
2614 Int_t c=(index & 0x0fffffff) >> 00;
2615 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2616 for (Int_t itrack=0;itrack<4;itrack++){
2617 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2618 fgLayers[l].SetClusterTracks(itrack,c,id);
2624 //------------------------------------------------------------------------
2625 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2627 //---------------------------------------------
2628 // unregister track from the list
2629 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2630 Int_t index = track->GetClusterIndex(icluster);
2631 Int_t l=(index & 0xf0000000) >> 28;
2632 Int_t c=(index & 0x0fffffff) >> 00;
2633 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2634 for (Int_t itrack=0;itrack<4;itrack++){
2635 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2636 fgLayers[l].SetClusterTracks(itrack,c,-1);
2641 //------------------------------------------------------------------------
2642 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2644 //-------------------------------------------------------------
2645 //get number of shared clusters
2646 //-------------------------------------------------------------
2648 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2649 // mean number of clusters
2650 Float_t *ny = GetNy(id), *nz = GetNz(id);
2653 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2654 Int_t index = track->GetClusterIndex(icluster);
2655 Int_t l=(index & 0xf0000000) >> 28;
2656 Int_t c=(index & 0x0fffffff) >> 00;
2657 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2659 printf("problem\n");
2661 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2665 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2666 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2667 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2669 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2672 deltan = (cl->GetNz()-nz[l]);
2674 if (deltan>2.0) continue; // extended - highly probable shared cluster
2675 weight = 2./TMath::Max(3.+deltan,2.);
2677 for (Int_t itrack=0;itrack<4;itrack++){
2678 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2680 clist[l] = (AliITSRecPoint*)GetCluster(index);
2686 track->SetNUsed(shared);
2689 //------------------------------------------------------------------------
2690 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2693 // find first shared track
2695 // mean number of clusters
2696 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2698 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2699 Int_t sharedtrack=100000;
2700 Int_t tracks[24],trackindex=0;
2701 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2703 for (Int_t icluster=0;icluster<6;icluster++){
2704 if (clusterlist[icluster]<0) continue;
2705 Int_t index = clusterlist[icluster];
2706 Int_t l=(index & 0xf0000000) >> 28;
2707 Int_t c=(index & 0x0fffffff) >> 00;
2709 printf("problem\n");
2711 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2712 //if (l>3) continue;
2713 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2716 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2717 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2718 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2720 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2723 deltan = (cl->GetNz()-nz[l]);
2725 if (deltan>2.0) continue; // extended - highly probable shared cluster
2727 for (Int_t itrack=3;itrack>=0;itrack--){
2728 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2729 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2730 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2735 if (trackindex==0) return -1;
2737 sharedtrack = tracks[0];
2739 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2742 Int_t tracks2[24], cluster[24];
2743 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2746 for (Int_t i=0;i<trackindex;i++){
2747 if (tracks[i]<0) continue;
2748 tracks2[index] = tracks[i];
2750 for (Int_t j=i+1;j<trackindex;j++){
2751 if (tracks[j]<0) continue;
2752 if (tracks[j]==tracks[i]){
2760 for (Int_t i=0;i<index;i++){
2761 if (cluster[index]>max) {
2762 sharedtrack=tracks2[index];
2769 if (sharedtrack>=100000) return -1;
2771 // make list of overlaps
2773 for (Int_t icluster=0;icluster<6;icluster++){
2774 if (clusterlist[icluster]<0) continue;
2775 Int_t index = clusterlist[icluster];
2776 Int_t l=(index & 0xf0000000) >> 28;
2777 Int_t c=(index & 0x0fffffff) >> 00;
2778 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2779 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2781 if (cl->GetNy()>2) continue;
2782 if (cl->GetNz()>2) continue;
2785 if (cl->GetNy()>3) continue;
2786 if (cl->GetNz()>3) continue;
2789 for (Int_t itrack=3;itrack>=0;itrack--){
2790 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2791 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2799 //------------------------------------------------------------------------
2800 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2802 // try to find track hypothesys without conflicts
2803 // with minimal chi2;
2804 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2805 Int_t entries1 = arr1->GetEntriesFast();
2806 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2807 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2808 Int_t entries2 = arr2->GetEntriesFast();
2809 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2811 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2812 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2813 if (track10->Pt()>0.5+track20->Pt()) return track10;
2815 for (Int_t itrack=0;itrack<entries1;itrack++){
2816 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2817 UnRegisterClusterTracks(track,trackID1);
2820 for (Int_t itrack=0;itrack<entries2;itrack++){
2821 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2822 UnRegisterClusterTracks(track,trackID2);
2826 Float_t maxconflicts=6;
2827 Double_t maxchi2 =1000.;
2829 // get weight of hypothesys - using best hypothesy
2832 Int_t list1[6],list2[6];
2833 AliITSRecPoint *clist1[6], *clist2[6] ;
2834 RegisterClusterTracks(track10,trackID1);
2835 RegisterClusterTracks(track20,trackID2);
2836 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2837 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2838 UnRegisterClusterTracks(track10,trackID1);
2839 UnRegisterClusterTracks(track20,trackID2);
2842 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2843 Float_t nerry[6],nerrz[6];
2844 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2845 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2846 for (Int_t i=0;i<6;i++){
2847 if ( (erry1[i]>0) && (erry2[i]>0)) {
2848 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2849 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2851 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2852 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2854 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2855 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2856 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2859 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2860 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2861 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2869 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2870 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2871 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2872 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2874 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2875 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2876 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2878 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2879 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2880 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2883 Double_t sumw = w1+w2;
2887 w1 = (d2+0.5)/(d1+d2+1.);
2888 w2 = (d1+0.5)/(d1+d2+1.);
2890 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2891 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2893 // get pair of "best" hypothesys
2895 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2896 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2898 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2899 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2900 //if (track1->fFakeRatio>0) continue;
2901 RegisterClusterTracks(track1,trackID1);
2902 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2903 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2905 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2906 //if (track2->fFakeRatio>0) continue;
2908 RegisterClusterTracks(track2,trackID2);
2909 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2910 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2911 UnRegisterClusterTracks(track2,trackID2);
2913 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2914 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2915 if (nskipped>0.5) continue;
2917 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2918 if (conflict1+1<cconflict1) continue;
2919 if (conflict2+1<cconflict2) continue;
2923 for (Int_t i=0;i<6;i++){
2925 Float_t c1 =0.; // conflict coeficients
2927 if (clist1[i]&&clist2[i]){
2930 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2933 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
2935 c1 = 2./TMath::Max(3.+deltan,2.);
2936 c2 = 2./TMath::Max(3.+deltan,2.);
2942 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
2945 deltan = (clist1[i]->GetNz()-nz1[i]);
2947 c1 = 2./TMath::Max(3.+deltan,2.);
2954 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
2957 deltan = (clist2[i]->GetNz()-nz2[i]);
2959 c2 = 2./TMath::Max(3.+deltan,2.);
2965 if (TMath::Abs(track1->GetDy(i))>0.) {
2966 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
2967 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
2968 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
2969 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
2971 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
2974 if (TMath::Abs(track2->GetDy(i))>0.) {
2975 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
2976 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
2977 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
2978 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
2981 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
2983 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
2984 if (chi21>0) sum+=w1;
2985 if (chi22>0) sum+=w2;
2988 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
2989 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
2990 Double_t normchi2 = 2*conflict+sumchi2/sum;
2991 if ( normchi2 <maxchi2 ){
2994 maxconflicts = conflict;
2998 UnRegisterClusterTracks(track1,trackID1);
3001 // if (maxconflicts<4 && maxchi2<th0){
3002 if (maxchi2<th0*2.){
3003 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3004 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3005 track1->SetChi2MIP(5,maxconflicts);
3006 track1->SetChi2MIP(6,maxchi2);
3007 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3008 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3009 track1->SetChi2MIP(8,index1);
3010 fBestTrackIndex[trackID1] =index1;
3011 UpdateESDtrack(track1, AliESDtrack::kITSin);
3013 else if (track10->GetChi2MIP(0)<th1){
3014 track10->SetChi2MIP(5,maxconflicts);
3015 track10->SetChi2MIP(6,maxchi2);
3016 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3017 UpdateESDtrack(track10,AliESDtrack::kITSin);
3020 for (Int_t itrack=0;itrack<entries1;itrack++){
3021 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3022 UnRegisterClusterTracks(track,trackID1);
3025 for (Int_t itrack=0;itrack<entries2;itrack++){
3026 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3027 UnRegisterClusterTracks(track,trackID2);
3030 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3031 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3032 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3033 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3034 RegisterClusterTracks(track10,trackID1);
3036 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3037 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3038 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3039 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3040 RegisterClusterTracks(track20,trackID2);
3045 //------------------------------------------------------------------------
3046 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3047 //--------------------------------------------------------------------
3048 // This function marks clusters assigned to the track
3049 //--------------------------------------------------------------------
3050 AliTracker::UseClusters(t,from);
3052 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3053 //if (c->GetQ()>2) c->Use();
3054 if (c->GetSigmaZ2()>0.1) c->Use();
3055 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3056 //if (c->GetQ()>2) c->Use();
3057 if (c->GetSigmaZ2()>0.1) c->Use();
3060 //------------------------------------------------------------------------
3061 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3063 //------------------------------------------------------------------
3064 // add track to the list of hypothesys
3065 //------------------------------------------------------------------
3067 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3068 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3070 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3072 array = new TObjArray(10);
3073 fTrackHypothesys.AddAt(array,esdindex);
3075 array->AddLast(track);
3077 //------------------------------------------------------------------------
3078 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3080 //-------------------------------------------------------------------
3081 // compress array of track hypothesys
3082 // keep only maxsize best hypothesys
3083 //-------------------------------------------------------------------
3084 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3085 if (! (fTrackHypothesys.At(esdindex)) ) return;
3086 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3087 Int_t entries = array->GetEntriesFast();
3089 //- find preliminary besttrack as a reference
3090 Float_t minchi2=10000;
3092 AliITStrackMI * besttrack=0;
3093 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3094 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3095 if (!track) continue;
3096 Float_t chi2 = NormalizedChi2(track,0);
3098 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3099 track->SetLabel(tpcLabel);
3101 track->SetFakeRatio(1.);
3102 CookLabel(track,0.); //For comparison only
3104 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3105 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3106 if (track->GetNumberOfClusters()<maxn) continue;
3107 maxn = track->GetNumberOfClusters();
3114 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3115 delete array->RemoveAt(itrack);
3119 if (!besttrack) return;
3122 //take errors of best track as a reference
3123 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3124 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3125 for (Int_t j=0;j<6;j++) {
3126 if (besttrack->GetClIndex(j)>0){
3127 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3128 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3129 ny[j] = besttrack->GetNy(j);
3130 nz[j] = besttrack->GetNz(j);
3134 // calculate normalized chi2
3136 Float_t * chi2 = new Float_t[entries];
3137 Int_t * index = new Int_t[entries];
3138 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3139 for (Int_t itrack=0;itrack<entries;itrack++){
3140 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3142 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3143 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3144 chi2[itrack] = track->GetChi2MIP(0);
3146 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3147 delete array->RemoveAt(itrack);
3153 TMath::Sort(entries,chi2,index,kFALSE);
3154 besttrack = (AliITStrackMI*)array->At(index[0]);
3155 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3156 for (Int_t j=0;j<6;j++){
3157 if (besttrack->GetClIndex(j)>0){
3158 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3159 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3160 ny[j] = besttrack->GetNy(j);
3161 nz[j] = besttrack->GetNz(j);
3166 // calculate one more time with updated normalized errors
3167 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3168 for (Int_t itrack=0;itrack<entries;itrack++){
3169 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3171 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3172 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3173 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3176 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3177 delete array->RemoveAt(itrack);
3182 entries = array->GetEntriesFast();
3186 TObjArray * newarray = new TObjArray();
3187 TMath::Sort(entries,chi2,index,kFALSE);
3188 besttrack = (AliITStrackMI*)array->At(index[0]);
3191 for (Int_t j=0;j<6;j++){
3192 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3193 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3194 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3195 ny[j] = besttrack->GetNy(j);
3196 nz[j] = besttrack->GetNz(j);
3199 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3200 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3201 Float_t minn = besttrack->GetNumberOfClusters()-3;
3203 for (Int_t i=0;i<entries;i++){
3204 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3205 if (!track) continue;
3206 if (accepted>maxcut) break;
3207 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3208 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3209 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3210 delete array->RemoveAt(index[i]);
3214 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3215 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3216 if (!shortbest) accepted++;
3218 newarray->AddLast(array->RemoveAt(index[i]));
3219 for (Int_t j=0;j<6;j++){
3221 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3222 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3223 ny[j] = track->GetNy(j);
3224 nz[j] = track->GetNz(j);
3229 delete array->RemoveAt(index[i]);
3233 delete fTrackHypothesys.RemoveAt(esdindex);
3234 fTrackHypothesys.AddAt(newarray,esdindex);
3238 delete fTrackHypothesys.RemoveAt(esdindex);
3244 //------------------------------------------------------------------------
3245 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3247 //-------------------------------------------------------------
3248 // try to find best hypothesy
3249 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3250 //-------------------------------------------------------------
3251 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3252 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3253 if (!array) return 0;
3254 Int_t entries = array->GetEntriesFast();
3255 if (!entries) return 0;
3256 Float_t minchi2 = 100000;
3257 AliITStrackMI * besttrack=0;
3259 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3260 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3261 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3262 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3264 for (Int_t i=0;i<entries;i++){
3265 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3266 if (!track) continue;
3267 Float_t sigmarfi,sigmaz;
3268 GetDCASigma(track,sigmarfi,sigmaz);
3269 track->SetDnorm(0,sigmarfi);
3270 track->SetDnorm(1,sigmaz);
3272 track->SetChi2MIP(1,1000000);
3273 track->SetChi2MIP(2,1000000);
3274 track->SetChi2MIP(3,1000000);
3277 backtrack = new(backtrack) AliITStrackMI(*track);
3278 if (track->GetConstrain()) {
3279 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3280 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3281 backtrack->ResetCovariance(10.);
3283 backtrack->ResetCovariance(10.);
3285 backtrack->ResetClusters();
3287 Double_t x = original->GetX();
3288 if (!RefitAt(x,backtrack,track)) continue;
3290 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3291 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3292 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3293 track->SetChi22(GetMatchingChi2(backtrack,original));
3295 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3296 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3297 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3300 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3302 //forward track - without constraint
3303 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3304 forwardtrack->ResetClusters();
3306 RefitAt(x,forwardtrack,track);
3307 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3308 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3309 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3311 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3312 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3313 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3314 forwardtrack->SetD(0,track->GetD(0));
3315 forwardtrack->SetD(1,track->GetD(1));
3318 AliITSRecPoint* clist[6];
3319 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3320 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3323 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3324 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3325 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3326 track->SetChi2MIP(3,1000);
3329 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3331 for (Int_t ichi=0;ichi<5;ichi++){
3332 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3334 if (chi2 < minchi2){
3335 //besttrack = new AliITStrackMI(*forwardtrack);
3337 besttrack->SetLabel(track->GetLabel());
3338 besttrack->SetFakeRatio(track->GetFakeRatio());
3340 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3341 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3342 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3346 delete forwardtrack;
3348 for (Int_t i=0;i<entries;i++){
3349 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3351 if (!track) continue;
3353 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3354 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3355 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3356 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3357 delete array->RemoveAt(i);
3367 SortTrackHypothesys(esdindex,checkmax,1);
3369 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3370 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3371 besttrack = (AliITStrackMI*)array->At(0);
3372 if (!besttrack) return 0;
3373 besttrack->SetChi2MIP(8,0);
3374 fBestTrackIndex[esdindex]=0;
3375 entries = array->GetEntriesFast();
3376 AliITStrackMI *longtrack =0;
3378 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3379 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3380 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3381 if (!track->GetConstrain()) continue;
3382 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3383 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3384 if (track->GetChi2MIP(0)>4.) continue;
3385 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3388 //if (longtrack) besttrack=longtrack;
3391 AliITSRecPoint * clist[6];
3392 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3393 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3394 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3395 RegisterClusterTracks(besttrack,esdindex);
3402 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3403 if (sharedtrack>=0){
3405 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3407 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3413 if (shared>2.5) return 0;
3414 if (shared>1.0) return besttrack;
3416 // Don't sign clusters if not gold track
3418 if (!besttrack->IsGoldPrimary()) return besttrack;
3419 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3421 if (fConstraint[fPass]){
3425 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3426 for (Int_t i=0;i<6;i++){
3427 Int_t index = besttrack->GetClIndex(i);
3428 if (index<=0) continue;
3429 Int_t ilayer = (index & 0xf0000000) >> 28;
3430 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3431 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3433 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3434 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3435 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3436 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3437 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3438 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3440 Bool_t cansign = kTRUE;
3441 for (Int_t itrack=0;itrack<entries; itrack++){
3442 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3443 if (!track) continue;
3444 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3445 if ( (track->GetClIndex(ilayer)>0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3451 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3452 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3453 if (!c->IsUsed()) c->Use();
3459 //------------------------------------------------------------------------
3460 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3463 // get "best" hypothesys
3466 Int_t nentries = itsTracks.GetEntriesFast();
3467 for (Int_t i=0;i<nentries;i++){
3468 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3469 if (!track) continue;
3470 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3471 if (!array) continue;
3472 if (array->GetEntriesFast()<=0) continue;
3474 AliITStrackMI* longtrack=0;
3476 Float_t maxchi2=1000;
3477 for (Int_t j=0;j<array->GetEntriesFast();j++){
3478 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3479 if (!trackHyp) continue;
3480 if (trackHyp->GetGoldV0()) {
3481 longtrack = trackHyp; //gold V0 track taken
3484 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3485 Float_t chi2 = trackHyp->GetChi2MIP(0);
3487 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3489 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3491 if (chi2 > maxchi2) continue;
3492 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3499 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3500 if (!longtrack) {longtrack = besttrack;}
3501 else besttrack= longtrack;
3505 AliITSRecPoint * clist[6];
3506 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3508 track->SetNUsed(shared);
3509 track->SetNSkipped(besttrack->GetNSkipped());
3510 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3512 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3516 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3517 //if (sharedtrack==-1) sharedtrack=0;
3518 if (sharedtrack>=0) {
3519 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3522 if (besttrack&&fAfterV0) {
3523 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3525 if (besttrack&&fConstraint[fPass])
3526 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3527 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3528 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3529 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3535 //------------------------------------------------------------------------
3536 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3537 //--------------------------------------------------------------------
3538 //This function "cooks" a track label. If label<0, this track is fake.
3539 //--------------------------------------------------------------------
3542 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3544 track->SetChi2MIP(9,0);
3546 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3547 Int_t cindex = track->GetClusterIndex(i);
3548 Int_t l=(cindex & 0xf0000000) >> 28;
3549 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3551 for (Int_t ind=0;ind<3;ind++){
3553 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3554 AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3556 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3559 Int_t nclusters = track->GetNumberOfClusters();
3560 if (nclusters > 0) //PH Some tracks don't have any cluster
3561 track->SetFakeRatio(double(nwrong)/double(nclusters));
3563 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3565 track->SetLabel(tpcLabel);
3567 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3570 //------------------------------------------------------------------------
3571 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3576 //AliITSRecPoint * clist[6];
3577 // Int_t shared = GetNumberOfSharedClusters(track,index,list,clist);
3580 track->SetChi2MIP(9,0);
3581 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3582 Int_t cindex = track->GetClusterIndex(i);
3583 Int_t l=(cindex & 0xf0000000) >> 28;
3584 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3585 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3587 for (Int_t ind=0;ind<3;ind++){
3588 if (cl->GetLabel(ind)==lab) isWrong=0;
3590 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3592 //if (l>3 && (cl->GetNy()>4) || (cl->GetNz()>4)) continue; //shared track
3593 //if (l>3&& !(cl->GetType()==1||cl->GetType()==10)) continue;
3594 //if (l<4&& !(cl->GetType()==1)) continue;
3595 dedx[accepted]= track->GetSampledEdx(i);
3596 //dedx[accepted]= track->fNormQ[l];
3604 TMath::Sort(accepted,dedx,indexes,kFALSE);
3607 Double_t nl=low*accepted, nu =up*accepted;
3609 Float_t sumweight =0;
3610 for (Int_t i=0; i<accepted; i++) {
3612 if (i<nl+0.1) weight = TMath::Max(1.-(nl-i),0.);
3613 if (i>nu-1) weight = TMath::Max(nu-i,0.);
3614 sumamp+= dedx[indexes[i]]*weight;
3617 track->SetdEdx(sumamp/sumweight);
3619 //------------------------------------------------------------------------
3620 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3622 // Create some arrays
3624 if (fCoefficients) delete []fCoefficients;
3625 fCoefficients = new Float_t[ntracks*48];
3626 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3628 //------------------------------------------------------------------------
3629 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3632 // Compute predicted chi2
3635 Float_t theta = track->GetTgl();
3636 Float_t phi = track->GetSnp();
3637 phi = TMath::Abs(phi)*TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3638 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz);
3639 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()));
3640 // Take into account the mis-alignment (bring track to cluster plane)
3641 Double_t xTrOrig=track->GetX();
3642 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3643 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()));
3644 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz);
3645 // Bring the track back to detector plane in ideal geometry
3646 // [mis-alignment will be accounted for in UpdateMI()]
3647 if (!track->Propagate(xTrOrig)) return 1000.;
3649 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3650 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3652 chi2+=0.5*TMath::Min(delta/2,2.);
3653 chi2+=2.*cluster->GetDeltaProbability();
3656 track->SetNy(layer,ny);
3657 track->SetNz(layer,nz);
3658 track->SetSigmaY(layer,erry);
3659 track->SetSigmaZ(layer, errz);
3660 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3661 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3665 //------------------------------------------------------------------------
3666 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3671 Int_t layer = (index & 0xf0000000) >> 28;
3672 track->SetClIndex(layer, index);
3673 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3674 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3675 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3676 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3680 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3683 // Take into account the mis-alignment (bring track to cluster plane)
3684 Double_t xTrOrig=track->GetX();
3685 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3686 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3687 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3688 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3690 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3694 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3695 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3698 Int_t updated = track->UpdateMI(&c,chi2,index);
3700 // Bring the track back to detector plane in ideal geometry
3701 if (!track->Propagate(xTrOrig)) return 0;
3703 if(!updated) AliDebug(2,"update failed");
3707 //------------------------------------------------------------------------
3708 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3711 //DCA sigmas parameterization
3712 //to be paramterized using external parameters in future
3715 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3716 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3718 //------------------------------------------------------------------------
3719 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3722 // Clusters from delta electrons?
3724 Int_t entries = clusterArray->GetEntriesFast();
3725 if (entries<4) return;
3726 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3727 Int_t layer = cluster->GetLayer();
3728 if (layer>1) return;
3730 Int_t ncandidates=0;
3731 Float_t r = (layer>0)? 7:4;
3733 for (Int_t i=0;i<entries;i++){
3734 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3735 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3736 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3737 index[ncandidates] = i; //candidate to belong to delta electron track
3739 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3740 cl0->SetDeltaProbability(1);
3746 for (Int_t i=0;i<ncandidates;i++){
3747 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3748 if (cl0->GetDeltaProbability()>0.8) continue;
3751 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3752 sumy=sumz=sumy2=sumyz=sumw=0.0;
3753 for (Int_t j=0;j<ncandidates;j++){
3755 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3757 Float_t dz = cl0->GetZ()-cl1->GetZ();
3758 Float_t dy = cl0->GetY()-cl1->GetY();
3759 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3760 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3761 y[ncl] = cl1->GetY();
3762 z[ncl] = cl1->GetZ();
3763 sumy+= y[ncl]*weight;
3764 sumz+= z[ncl]*weight;
3765 sumy2+=y[ncl]*y[ncl]*weight;
3766 sumyz+=y[ncl]*z[ncl]*weight;
3771 if (ncl<4) continue;
3772 Float_t det = sumw*sumy2 - sumy*sumy;
3774 if (TMath::Abs(det)>0.01){
3775 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3776 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3777 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3780 Float_t z0 = sumyz/sumy;
3781 delta = TMath::Abs(cl0->GetZ()-z0);
3784 cl0->SetDeltaProbability(1-20.*delta);
3788 //------------------------------------------------------------------------
3789 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3794 track->UpdateESDtrack(flags);
3795 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3796 if (oldtrack) delete oldtrack;
3797 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3798 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3799 printf("Problem\n");
3802 //------------------------------------------------------------------------
3803 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3805 // Get nearest upper layer close to the point xr.
3806 // rough approximation
3808 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3809 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3811 for (Int_t i=0;i<6;i++){
3812 if (radius<kRadiuses[i]){
3819 //------------------------------------------------------------------------
3820 void AliITStrackerMI::UpdateTPCV0(const AliESDEvent *event){
3822 //try to update, or reject TPC V0s
3824 Int_t nv0s = event->GetNumberOfV0s();
3825 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3827 for (Int_t i=0;i<nv0s;i++){
3828 AliESDv0 * vertex = event->GetV0(i);
3829 Int_t ip = vertex->GetIndex(0);
3830 Int_t im = vertex->GetIndex(1);
3832 TObjArray * arrayp = (ip<nitstracks) ? (TObjArray*)fTrackHypothesys.At(ip):0;
3833 TObjArray * arraym = (im<nitstracks) ? (TObjArray*)fTrackHypothesys.At(im):0;
3834 AliITStrackMI * trackp = (arrayp!=0) ? (AliITStrackMI*)arrayp->At(0):0;
3835 AliITStrackMI * trackm = (arraym!=0) ? (AliITStrackMI*)arraym->At(0):0;
3839 if (trackp->GetNumberOfClusters()+trackp->GetNDeadZone()>5.5){
3840 if (trackp->GetConstrain()&&trackp->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3841 if (!trackp->GetConstrain()&&trackp->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3846 if (trackm->GetNumberOfClusters()+trackm->GetNDeadZone()>5.5){
3847 if (trackm->GetConstrain()&&trackm->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3848 if (!trackm->GetConstrain()&&trackm->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3851 if (vertex->GetStatus()==-100) continue;
3853 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
3854 Int_t clayer = GetNearestLayer(xrp); //I.B.
3855 vertex->SetNBefore(clayer); //
3856 vertex->SetChi2Before(9*clayer); //
3857 vertex->SetNAfter(6-clayer); //
3858 vertex->SetChi2After(0); //
3860 if (clayer >1 ){ // calculate chi2 before vertex
3861 Float_t chi2p = 0, chi2m=0;
3864 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3865 if (trackp->GetClIndex(ilayer)>0){
3866 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3867 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3878 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3879 if (trackm->GetClIndex(ilayer)>0){
3880 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3881 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3890 vertex->SetChi2Before(TMath::Min(chi2p,chi2m));
3891 if (TMath::Min(chi2p,chi2m)/Float_t(clayer)<4) vertex->SetStatus(-10); // track exist before vertex
3894 if (clayer < 5 ){ // calculate chi2 after vertex
3895 Float_t chi2p = 0, chi2m=0;
3897 if (trackp&&TMath::Abs(trackp->GetTgl())<1.){
3898 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3899 if (trackp->GetClIndex(ilayer)>0){
3900 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3901 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3911 if (trackm&&TMath::Abs(trackm->GetTgl())<1.){
3912 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3913 if (trackm->GetClIndex(ilayer)>0){
3914 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3915 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3924 vertex->SetChi2After(TMath::Max(chi2p,chi2m));
3925 if (TMath::Max(chi2m,chi2p)/Float_t(6-clayer)>9) vertex->SetStatus(-20); // track not found in ITS
3930 //------------------------------------------------------------------------
3931 void AliITStrackerMI::FindV02(AliESDEvent *event)
3936 // Cuts on DCA - R dependent
3937 // max distance DCA between 2 tracks cut
3938 // maxDist = TMath::Min(kMaxDist,kMaxDist0+pvertex->GetRr()*kMaxDist);
3940 const Float_t kMaxDist0 = 0.1;
3941 const Float_t kMaxDist1 = 0.1;
3942 const Float_t kMaxDist = 1;
3943 const Float_t kMinPointAngle = 0.85;
3944 const Float_t kMinPointAngle2 = 0.99;
3945 const Float_t kMinR = 0.5;
3946 const Float_t kMaxR = 220;
3947 //const Float_t kCausality0Cut = 0.19;
3948 //const Float_t kLikelihood01Cut = 0.25;
3949 //const Float_t kPointAngleCut = 0.9996;
3950 const Float_t kCausality0Cut = 0.19;
3951 const Float_t kLikelihood01Cut = 0.45;
3952 const Float_t kLikelihood1Cut = 0.5;
3953 const Float_t kCombinedCut = 0.55;
3957 TTreeSRedirector &cstream = *fDebugStreamer;
3958 Int_t ntracks = event->GetNumberOfTracks();
3959 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3960 fOriginal.Expand(ntracks);
3961 fTrackHypothesys.Expand(ntracks);
3962 fBestHypothesys.Expand(ntracks);
3964 AliHelix * helixes = new AliHelix[ntracks+2];
3965 TObjArray trackarray(ntracks+2); //array with tracks - with vertex constrain
3966 TObjArray trackarrayc(ntracks+2); //array of "best tracks" - without vertex constrain
3967 TObjArray trackarrayl(ntracks+2); //array of "longest tracks" - without vertex constrain
3968 Bool_t * forbidden = new Bool_t [ntracks+2];
3969 Int_t *itsmap = new Int_t [ntracks+2];
3970 Float_t *dist = new Float_t[ntracks+2];
3971 Float_t *normdist0 = new Float_t[ntracks+2];
3972 Float_t *normdist1 = new Float_t[ntracks+2];
3973 Float_t *normdist = new Float_t[ntracks+2];
3974 Float_t *norm = new Float_t[ntracks+2];
3975 Float_t *maxr = new Float_t[ntracks+2];
3976 Float_t *minr = new Float_t[ntracks+2];
3977 Float_t *minPointAngle= new Float_t[ntracks+2];
3979 AliV0 *pvertex = new AliV0;
3980 AliITStrackMI * dummy= new AliITStrackMI;
3982 AliITStrackMI trackat0; //temporary track for DCA calculation
3984 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
3986 // make ITS - ESD map
3988 for (Int_t itrack=0;itrack<ntracks+2;itrack++) {
3989 itsmap[itrack] = -1;
3990 forbidden[itrack] = kFALSE;
3991 maxr[itrack] = kMaxR;
3992 minr[itrack] = kMinR;
3993 minPointAngle[itrack] = kMinPointAngle;
3995 for (Int_t itrack=0;itrack<nitstracks;itrack++){
3996 AliITStrackMI * original = (AliITStrackMI*)(fOriginal.At(itrack));
3997 Int_t esdindex = original->GetESDtrack()->GetID();
3998 itsmap[esdindex] = itrack;
4001 // create ITS tracks from ESD tracks if not done before
4003 for (Int_t itrack=0;itrack<ntracks;itrack++){
4004 if (itsmap[itrack]>=0) continue;
4005 AliITStrackMI * tpctrack = new AliITStrackMI(*(event->GetTrack(itrack)));
4006 //tpctrack->fD[0] = tpctrack->GetD(GetX(),GetY());
4007 //tpctrack->fD[1] = tpctrack->GetZat(GetX())-GetZ();
4008 tpctrack->GetDZ(GetX(),GetY(),GetZ(),tpctrack->GetDP()); //I.B.
4009 if (tpctrack->GetD(0)<20 && tpctrack->GetD(1)<20){
4010 // tracks which can reach inner part of ITS
4011 // propagate track to outer its volume - with correction for material
4012 CorrectForTPCtoITSDeadZoneMaterial(tpctrack);
4014 itsmap[itrack] = nitstracks;
4015 fOriginal.AddAt(tpctrack,nitstracks);
4019 // fill temporary arrays
4021 for (Int_t itrack=0;itrack<ntracks;itrack++){
4022 AliESDtrack * esdtrack = event->GetTrack(itrack);
4023 Int_t itsindex = itsmap[itrack];
4024 AliITStrackMI *original = (AliITStrackMI*)fOriginal.At(itsmap[itrack]);
4025 if (!original) continue;
4026 AliITStrackMI *bestConst = 0;
4027 AliITStrackMI *bestLong = 0;
4028 AliITStrackMI *best = 0;
4031 TObjArray * array = (TObjArray*) fTrackHypothesys.At(itsindex);
4032 Int_t hentries = (array==0) ? 0 : array->GetEntriesFast();
4033 // Get best track with vertex constrain
4034 for (Int_t ih=0;ih<hentries;ih++){
4035 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
4036 if (!trackh->GetConstrain()) continue;
4037 if (!bestConst) bestConst = trackh;
4038 if (trackh->GetNumberOfClusters()>5.0){
4039 bestConst = trackh; // full track - with minimal chi2
4042 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()) continue;
4046 // Get best long track without vertex constrain and best track without vertex constrain
4047 for (Int_t ih=0;ih<hentries;ih++){
4048 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
4049 if (trackh->GetConstrain()) continue;
4050 if (!best) best = trackh;
4051 if (!bestLong) bestLong = trackh;
4052 if (trackh->GetNumberOfClusters()>5.0){
4053 bestLong = trackh; // full track - with minimal chi2
4056 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()) continue;
4061 bestLong = original;
4063 //I.B. trackat0 = *bestLong;
4064 new (&trackat0) AliITStrackMI(*bestLong);
4065 Double_t xx,yy,zz,alpha;
4066 if (!bestLong->GetGlobalXYZat(bestLong->GetX(),xx,yy,zz)) continue;
4067 alpha = TMath::ATan2(yy,xx);
4068 if (!trackat0.Propagate(alpha,0)) continue;
4069 // calculate normalized distances to the vertex
4071 Float_t ptfac = (1.+100.*TMath::Abs(trackat0.GetC()));
4072 if ( bestLong->GetNumberOfClusters()>3 ){
4073 dist[itsindex] = trackat0.GetY();
4074 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
4075 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
4076 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
4077 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
4079 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<6) normdist[itsindex]*=2.;
4080 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<5) normdist[itsindex]*=2.;
4081 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<4) normdist[itsindex]*=2.;
4083 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<6) normdist[itsindex]*=1.5;
4084 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<5) normdist[itsindex]*=1.5;
4088 if (bestConst&&bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5){
4089 dist[itsindex] = bestConst->GetD(0);
4090 norm[itsindex] = bestConst->GetDnorm(0);
4091 normdist0[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
4092 normdist1[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
4093 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
4095 dist[itsindex] = trackat0.GetY();
4096 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
4097 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
4098 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
4099 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
4100 if (TMath::Abs(trackat0.GetTgl())>1.05){
4101 if (normdist[itsindex]<3) forbidden[itsindex]=kTRUE;
4102 if (normdist[itsindex]>3) {
4103 minr[itsindex] = TMath::Max(Float_t(40.),minr[itsindex]);
4109 //-----------------------------------------------------------
4110 //Forbid primary track candidates -
4112 //treetr->SetAlias("forbidden0","Tr0.fN<4&&Tr1.fN+Tr1.fNDeadZone>4.5");
4113 //treetr->SetAlias("forbidden1","ND<3&&Tr1.fN+Tr1.fNDeadZone>5.5");
4114 //treetr->SetAlias("forbidden2","ND<2&&Tr1.fClIndex[0]>0&&Tr1.fClIndex[0]>0");
4115 //treetr->SetAlias("forbidden3","ND<1&&Tr1.fClIndex[0]>0");
4116 //treetr->SetAlias("forbidden4","ND<4&&Tr1.fNormChi2[0]<2");
4117 //treetr->SetAlias("forbidden5","ND<5&&Tr1.fNormChi2[0]<1");
4118 //-----------------------------------------------------------
4120 if (bestLong->GetNumberOfClusters()<4 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5) forbidden[itsindex]=kTRUE;
4121 if (normdist[itsindex]<3 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>5.5) forbidden[itsindex]=kTRUE;
4122 if (normdist[itsindex]<2 && bestConst->GetClIndex(0)>0 && bestConst->GetClIndex(1)>0 ) forbidden[itsindex]=kTRUE;
4123 if (normdist[itsindex]<1 && bestConst->GetClIndex(0)>0) forbidden[itsindex]=kTRUE;
4124 if (normdist[itsindex]<4 && bestConst->GetNormChi2(0)<2) forbidden[itsindex]=kTRUE;
4125 if (normdist[itsindex]<5 && bestConst->GetNormChi2(0)<1) forbidden[itsindex]=kTRUE;
4126 if (bestConst->GetNormChi2(0)<2.5) {
4127 minPointAngle[itsindex]= 0.9999;
4128 maxr[itsindex] = 10;
4132 //forbid daughter kink candidates
4134 if (esdtrack->GetKinkIndex(0)>0) forbidden[itsindex] = kTRUE;
4135 Bool_t isElectron = kTRUE;
4136 Bool_t isProton = kTRUE;
4138 esdtrack->GetESDpid(pid);
4139 for (Int_t i=1;i<5;i++){
4140 if (pid[0]<pid[i]) isElectron= kFALSE;
4141 if (pid[4]<pid[i]) isProton= kFALSE;
4144 forbidden[itsindex]=kFALSE;
4145 normdist[itsindex]*=-1;
4148 if (normdist[itsindex]>2) forbidden[itsindex]=kFALSE;
4149 normdist[itsindex]*=-1;
4153 // Causality cuts in TPC volume
4155 if (esdtrack->GetTPCdensity(0,10) >0.6) maxr[itsindex] = TMath::Min(Float_t(110),maxr[itsindex]);
4156 if (esdtrack->GetTPCdensity(10,30)>0.6) maxr[itsindex] = TMath::Min(Float_t(120),maxr[itsindex]);
4157 if (esdtrack->GetTPCdensity(20,40)>0.6) maxr[itsindex] = TMath::Min(Float_t(130),maxr[itsindex]);
4158 if (esdtrack->GetTPCdensity(30,50)>0.6) maxr[itsindex] = TMath::Min(Float_t(140),maxr[itsindex]);
4160 if (esdtrack->GetTPCdensity(0,60)<0.4&&bestLong->GetNumberOfClusters()<3) minr[itsindex]=100;
4166 "Tr1.="<<((bestConst)? bestConst:dummy)<<
4168 "Tr3.="<<&trackat0<<
4170 "Dist="<<dist[itsindex]<<
4171 "ND0="<<normdist0[itsindex]<<
4172 "ND1="<<normdist1[itsindex]<<
4173 "ND="<<normdist[itsindex]<<
4174 "Pz="<<primvertex[2]<<
4175 "Forbid="<<forbidden[itsindex]<<
4179 trackarray.AddAt(best,itsindex);
4180 trackarrayc.AddAt(bestConst,itsindex);
4181 trackarrayl.AddAt(bestLong,itsindex);
4182 new (&helixes[itsindex]) AliHelix(*best);
4187 // first iterration of V0 finder
4189 for (Int_t iesd0=0;iesd0<ntracks;iesd0++){
4190 Int_t itrack0 = itsmap[iesd0];
4191 if (forbidden[itrack0]) continue;
4192 AliITStrackMI * btrack0 = (AliITStrackMI*)trackarray.At(itrack0);
4193 if (!btrack0) continue;
4194 if (btrack0->GetSign()>0) continue;
4195 AliITStrackMI *trackc0 = (AliITStrackMI*)trackarrayc.At(itrack0);
4197 for (Int_t iesd1=0;iesd1<ntracks;iesd1++){
4198 Int_t itrack1 = itsmap[iesd1];
4199 if (forbidden[itrack1]) continue;
4201 AliITStrackMI * btrack1 = (AliITStrackMI*)trackarray.At(itrack1);
4202 if (!btrack1) continue;
4203 if (btrack1->GetSign()<0) continue;
4204 Bool_t isGold = kFALSE;
4205 if (TMath::Abs(TMath::Abs(btrack0->GetLabel())-TMath::Abs(btrack1->GetLabel()))==1){
4208 AliITStrackMI *trackc1 = (AliITStrackMI*)trackarrayc.At(itrack1);
4209 AliHelix &h1 = helixes[itrack0];
4210 AliHelix &h2 = helixes[itrack1];
4212 // find linear distance
4217 Double_t phase[2][2],radius[2];
4218 Int_t points = h1.GetRPHIintersections(h2, phase, radius);
4219 if (points==0) continue;
4220 Double_t delta[2]={1000000,1000000};
4222 h1.ParabolicDCA(h2,phase[0][0],phase[0][1],radius[0],delta[0]);
4224 if (radius[1]<rmin) rmin = radius[1];
4225 h1.ParabolicDCA(h2,phase[1][0],phase[1][1],radius[1],delta[1]);
4227 rmin = TMath::Sqrt(rmin);
4228 Double_t distance = 0;
4229 Double_t radiusC = 0;
4231 if (points==1 || delta[0]<delta[1]){
4232 distance = TMath::Sqrt(delta[0]);
4233 radiusC = TMath::Sqrt(radius[0]);
4235 distance = TMath::Sqrt(delta[1]);
4236 radiusC = TMath::Sqrt(radius[1]);
4239 if (radiusC<TMath::Max(minr[itrack0],minr[itrack1])) continue;
4240 if (radiusC>TMath::Min(maxr[itrack0],maxr[itrack1])) continue;
4241 Float_t maxDist = TMath::Min(kMaxDist,Float_t(kMaxDist0+radiusC*kMaxDist1));
4242 if (distance>maxDist) continue;
4243 Float_t pointAngle = h1.GetPointAngle(h2,phase[iphase],primvertex);
4244 if (pointAngle<TMath::Max(minPointAngle[itrack0],minPointAngle[itrack1])) continue;
4247 // Double_t distance = TestV0(h1,h2,pvertex,rmin);
4249 // if (distance>maxDist) continue;
4250 // if (pvertex->GetRr()<kMinR) continue;
4251 // if (pvertex->GetRr()>kMaxR) continue;
4252 AliITStrackMI * track0=btrack0;
4253 AliITStrackMI * track1=btrack1;
4254 // if (pvertex->GetRr()<3.5){
4256 //use longest tracks inside the pipe
4257 track0 = (AliITStrackMI*)trackarrayl.At(itrack0);
4258 track1 = (AliITStrackMI*)trackarrayl.At(itrack1);
4262 pvertex->SetParamN(*track0);
4263 pvertex->SetParamP(*track1);
4264 pvertex->Update(primvertex);
4265 pvertex->SetClusters(track0->ClIndex(),track1->ClIndex()); // register clusters
4267 if (pvertex->GetRr()<kMinR) continue;
4268 if (pvertex->GetRr()>kMaxR) continue;
4269 if (pvertex->GetV0CosineOfPointingAngle()<kMinPointAngle) continue;
4270 //Bo: if (pvertex->GetDist2()>maxDist) continue;
4271 if (pvertex->GetDcaV0Daughters()>maxDist) continue;
4272 //Bo: pvertex->SetLab(0,track0->GetLabel());
4273 //Bo: pvertex->SetLab(1,track1->GetLabel());
4274 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4275 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4277 AliITStrackMI * htrackc0 = trackc0 ? trackc0:dummy;
4278 AliITStrackMI * htrackc1 = trackc1 ? trackc1:dummy;
4282 TObjArray * array0b = (TObjArray*)fBestHypothesys.At(itrack0);
4283 if (!array0b&&pvertex->GetRr()<40 && TMath::Abs(track0->GetTgl())<1.1) {
4284 fCurrentEsdTrack = itrack0;
4285 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack0),itrack0, kFALSE);
4287 TObjArray * array1b = (TObjArray*)fBestHypothesys.At(itrack1);
4288 if (!array1b&&pvertex->GetRr()<40 && TMath::Abs(track1->GetTgl())<1.1) {
4289 fCurrentEsdTrack = itrack1;
4290 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack1),itrack1, kFALSE);
4293 AliITStrackMI * track0b = (AliITStrackMI*)fOriginal.At(itrack0);
4294 AliITStrackMI * track1b = (AliITStrackMI*)fOriginal.At(itrack1);
4295 AliITStrackMI * track0l = (AliITStrackMI*)fOriginal.At(itrack0);
4296 AliITStrackMI * track1l = (AliITStrackMI*)fOriginal.At(itrack1);
4298 Float_t minchi2before0=16;
4299 Float_t minchi2before1=16;
4300 Float_t minchi2after0 =16;
4301 Float_t minchi2after1 =16;
4302 Double_t xrp[3]; pvertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
4303 Int_t maxLayer = GetNearestLayer(xrp); //I.B.
4305 if (array0b) for (Int_t i=0;i<5;i++){
4306 // best track after vertex
4307 AliITStrackMI * btrack = (AliITStrackMI*)array0b->At(i);
4308 if (!btrack) continue;
4309 if (btrack->GetNumberOfClusters()>track0l->GetNumberOfClusters()) track0l = btrack;
4310 // if (btrack->fX<pvertex->GetRr()-2.-0.5/(0.1+pvertex->GetAnglep()[2])) {
4311 if (btrack->GetX()<pvertex->GetRr()-2.) {
4312 if ( (maxLayer>i+2|| (i==0)) && btrack->GetNumberOfClusters()==(6-i)&&i<3){
4315 if (maxLayer<3){ // take prim vertex as additional measurement
4316 if (normdist[itrack0]>0 && htrackc0){
4317 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack0]*normdist[itrack0],16.);
4319 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack0]*normdist[itrack0]+3.),16.);
4323 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4325 if (!btrack->GetClIndex(ilayer)){
4329 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4330 for (Int_t itrack=0;itrack<4;itrack++){
4331 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack0){
4332 sumchi2+=18.; //shared cluster
4336 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4337 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4341 if (sumchi2<minchi2before0) minchi2before0=sumchi2;
4343 continue; //safety space - Geo manager will give exact layer
4346 minchi2after0 = btrack->GetNormChi2(i);
4349 if (array1b) for (Int_t i=0;i<5;i++){
4350 // best track after vertex
4351 AliITStrackMI * btrack = (AliITStrackMI*)array1b->At(i);
4352 if (!btrack) continue;
4353 if (btrack->GetNumberOfClusters()>track1l->GetNumberOfClusters()) track1l = btrack;
4354 // if (btrack->fX<pvertex->GetRr()-2-0.5/(0.1+pvertex->GetAnglep()[2])){
4355 if (btrack->GetX()<pvertex->GetRr()-2){
4356 if ((maxLayer>i+2 || (i==0))&&btrack->GetNumberOfClusters()==(6-i)&&(i<3)){
4359 if (maxLayer<3){ // take prim vertex as additional measurement
4360 if (normdist[itrack1]>0 && htrackc1){
4361 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack1]*normdist[itrack1],16.);
4363 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack1]*normdist[itrack1]+3.),16.);
4367 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4369 if (!btrack->GetClIndex(ilayer)){
4373 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4374 for (Int_t itrack=0;itrack<4;itrack++){
4375 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack1){
4376 sumchi2+=18.; //shared cluster
4380 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4381 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4385 if (sumchi2<minchi2before1) minchi2before1=sumchi2;
4387 continue; //safety space - Geo manager will give exact layer
4390 minchi2after1 = btrack->GetNormChi2(i);
4394 // position resolution - used for DCA cut
4395 Float_t sigmad = track0b->GetSigmaY2()+track0b->GetSigmaZ2()+track1b->GetSigmaY2()+track1b->GetSigmaZ2()+
4396 (track0b->GetX()-pvertex->GetRr())*(track0b->GetX()-pvertex->GetRr())*(track0b->GetSigmaSnp2()+track0b->GetSigmaTgl2())+
4397 (track1b->GetX()-pvertex->GetRr())*(track1b->GetX()-pvertex->GetRr())*(track1b->GetSigmaSnp2()+track1b->GetSigmaTgl2());
4398 sigmad =TMath::Sqrt(sigmad)+0.04;
4399 if (pvertex->GetRr()>50){
4400 Double_t cov0[15],cov1[15];
4401 track0b->GetESDtrack()->GetInnerExternalCovariance(cov0);
4402 track1b->GetESDtrack()->GetInnerExternalCovariance(cov1);
4403 sigmad = cov0[0]+cov0[2]+cov1[0]+cov1[2]+
4404 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov0[5]+cov0[9])+
4405 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov1[5]+cov1[9]);
4406 sigmad =TMath::Sqrt(sigmad)+0.05;
4410 vertex2.SetParamN(*track0b);
4411 vertex2.SetParamP(*track1b);
4412 vertex2.Update(primvertex);
4413 //Bo: if (vertex2.GetDist2()<=pvertex->GetDist2()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4414 if (vertex2.GetDcaV0Daughters()<=pvertex->GetDcaV0Daughters()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4415 pvertex->SetParamN(*track0b);
4416 pvertex->SetParamP(*track1b);
4417 pvertex->Update(primvertex);
4418 pvertex->SetClusters(track0b->ClIndex(),track1b->ClIndex()); // register clusters
4419 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4420 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4422 pvertex->SetDistSigma(sigmad);
4423 //Bo: pvertex->SetDistNorm(pvertex->GetDist2()/sigmad);
4424 pvertex->SetNormDCAPrim(normdist[itrack0],normdist[itrack1]);
4426 // define likelihhod and causalities
4428 Float_t pa0=1, pa1=1, pb0=0.26, pb1=0.26;
4430 Float_t fnorm0 = normdist[itrack0];
4431 if (fnorm0<0) fnorm0*=-3;
4432 Float_t fnorm1 = normdist[itrack1];
4433 if (fnorm1<0) fnorm1*=-3;
4434 if ((pvertex->GetAnglep()[2]>0.1) || ( (pvertex->GetRr()<10.5)&& pvertex->GetAnglep()[2]>0.05 ) || (pvertex->GetRr()<3)){
4435 pb0 = TMath::Exp(-TMath::Min(fnorm0,Float_t(16.))/12.);
4436 pb1 = TMath::Exp(-TMath::Min(fnorm1,Float_t(16.))/12.);
4438 pvertex->SetChi2Before(normdist[itrack0]);
4439 pvertex->SetChi2After(normdist[itrack1]);
4440 pvertex->SetNAfter(0);
4441 pvertex->SetNBefore(0);
4443 pvertex->SetChi2Before(minchi2before0);
4444 pvertex->SetChi2After(minchi2before1);
4445 if (pvertex->GetAnglep()[2]>0.1 || ( pvertex->GetRr()<10.5 && pvertex->GetAnglep()[2]>0.05) || pvertex->GetRr()<3){
4446 pb0 = TMath::Exp(-TMath::Min(minchi2before0,Float_t(16))/12.);
4447 pb1 = TMath::Exp(-TMath::Min(minchi2before1,Float_t(16))/12.);
4449 pvertex->SetNAfter(maxLayer);
4450 pvertex->SetNBefore(maxLayer);
4452 if (pvertex->GetRr()<90){
4453 pa0 *= TMath::Min(track0->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4454 pa1 *= TMath::Min(track1->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4456 if (pvertex->GetRr()<20){
4457 pa0 *= (0.2+TMath::Exp(-TMath::Min(minchi2after0,Float_t(16))/8.))/1.2;
4458 pa1 *= (0.2+TMath::Exp(-TMath::Min(minchi2after1,Float_t(16))/8.))/1.2;
4461 pvertex->SetCausality(pb0,pb1,pa0,pa1);
4463 // Likelihood calculations - apply cuts
4465 Bool_t v0OK = kTRUE;
4466 Float_t p12 = pvertex->GetParamP()->GetParameter()[4]*pvertex->GetParamP()->GetParameter()[4];
4467 p12 += pvertex->GetParamN()->GetParameter()[4]*pvertex->GetParamN()->GetParameter()[4];
4468 p12 = TMath::Sqrt(p12); // "mean" momenta
4469 Float_t sigmap0 = 0.0001+0.001/(0.1+pvertex->GetRr());
4470 Float_t sigmap = 0.5*sigmap0*(0.6+0.4*p12); // "resolution: of point angle - as a function of radius and momenta
4472 Float_t causalityA = (1.0-pvertex->GetCausalityP()[0])*(1.0-pvertex->GetCausalityP()[1]);
4473 Float_t causalityB = TMath::Sqrt(TMath::Min(pvertex->GetCausalityP()[2],Double_t(0.7))*
4474 TMath::Min(pvertex->GetCausalityP()[3],Double_t(0.7)));
4476 //Bo: Float_t likelihood0 = (TMath::Exp(-pvertex->GetDistNorm())+0.1) *(pvertex->GetDist2()<0.5)*(pvertex->GetDistNorm()<5);
4477 Float_t lDistNorm = pvertex->GetDcaV0Daughters()/pvertex->GetDistSigma();
4478 Float_t likelihood0 = (TMath::Exp(-lDistNorm)+0.1) *(pvertex->GetDcaV0Daughters()<0.5)*(lDistNorm<5);
4480 Float_t likelihood1 = TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/sigmap)+
4481 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(4.*sigmap))+
4482 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(8.*sigmap))+
4483 0.1*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/0.01);
4485 if (causalityA<kCausality0Cut) v0OK = kFALSE;
4486 if (TMath::Sqrt(likelihood0*likelihood1)<kLikelihood01Cut) v0OK = kFALSE;
4487 if (likelihood1<kLikelihood1Cut) v0OK = kFALSE;
4488 if (TMath::Power(likelihood0*likelihood1*causalityB,0.33)<kCombinedCut) v0OK = kFALSE;
4493 Bool_t gold = TMath::Abs(TMath::Abs(track0->GetLabel())-TMath::Abs(track1->GetLabel()))==1;
4495 "Tr0.="<<track0<< //best without constrain
4496 "Tr1.="<<track1<< //best without constrain
4497 "Tr0B.="<<track0b<< //best without constrain after vertex
4498 "Tr1B.="<<track1b<< //best without constrain after vertex
4499 "Tr0C.="<<htrackc0<< //best with constrain if exist
4500 "Tr1C.="<<htrackc1<< //best with constrain if exist
4501 "Tr0L.="<<track0l<< //longest best
4502 "Tr1L.="<<track1l<< //longest best
4503 "Esd0.="<<track0->GetESDtrack()<< // esd track0 params
4504 "Esd1.="<<track1->GetESDtrack()<< // esd track1 params
4505 "V0.="<<pvertex<< //vertex properties
4506 "V0b.="<<&vertex2<< //vertex properties at "best" track
4507 "ND0="<<normdist[itrack0]<< //normalize distance for track0
4508 "ND1="<<normdist[itrack1]<< //normalize distance for track1
4510 // "RejectBase="<<rejectBase<< //rejection in First itteration
4516 //if (rejectBase) continue;
4518 pvertex->SetStatus(0);
4519 // if (rejectBase) {
4520 // pvertex->SetStatus(-100);
4522 if (pvertex->GetV0CosineOfPointingAngle()>kMinPointAngle2) {
4523 //Bo: pvertex->SetESDindexes(track0->GetESDtrack()->GetID(),track1->GetESDtrack()->GetID());
4524 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());//Bo: consistency 0 for neg
4525 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());//Bo: consistency 1 for pos
4527 // AliV0vertex vertexjuri(*track0,*track1);
4528 // vertexjuri.SetESDindexes(track0->fESDtrack->GetID(),track1->fESDtrack->GetID());
4529 // event->AddV0(&vertexjuri);
4530 pvertex->SetStatus(100);
4532 pvertex->SetOnFlyStatus(kTRUE);
4533 pvertex->ChangeMassHypothesis(kK0Short);
4534 event->AddV0(pvertex);
4540 // delete temporary arrays
4543 delete[] minPointAngle;
4555 //------------------------------------------------------------------------
4556 void AliITStrackerMI::RefitV02(const AliESDEvent *event)
4559 //try to refit V0s in the third path of the reconstruction
4561 TTreeSRedirector &cstream = *fDebugStreamer;
4563 Int_t nv0s = event->GetNumberOfV0s();
4564 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
4566 for (Int_t iv0 = 0; iv0<nv0s;iv0++){
4567 AliV0 * v0mi = (AliV0*)event->GetV0(iv0);
4568 if (!v0mi) continue;
4569 Int_t itrack0 = v0mi->GetIndex(0);
4570 Int_t itrack1 = v0mi->GetIndex(1);
4571 AliESDtrack *esd0 = event->GetTrack(itrack0);
4572 AliESDtrack *esd1 = event->GetTrack(itrack1);
4573 if (!esd0||!esd1) continue;
4574 AliITStrackMI tpc0(*esd0);
4575 AliITStrackMI tpc1(*esd1);
4576 Double_t x,y,z; v0mi->GetXYZ(x,y,z); //I.B.
4577 Double_t alpha =TMath::ATan2(y,x); //I.B.
4578 if (v0mi->GetRr()>85){
4579 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4580 v0temp.SetParamN(tpc0);
4581 v0temp.SetParamP(tpc1);
4582 v0temp.Update(primvertex);
4583 if (kFALSE) cstream<<"Refit"<<
4585 "V0refit.="<<&v0temp<<
4589 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4590 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4591 v0mi->SetParamN(tpc0);
4592 v0mi->SetParamP(tpc1);
4593 v0mi->Update(primvertex);
4598 if (v0mi->GetRr()>35){
4599 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4600 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4601 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4602 v0temp.SetParamN(tpc0);
4603 v0temp.SetParamP(tpc1);
4604 v0temp.Update(primvertex);
4605 if (kFALSE) cstream<<"Refit"<<
4607 "V0refit.="<<&v0temp<<
4611 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4612 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4613 v0mi->SetParamN(tpc0);
4614 v0mi->SetParamP(tpc1);
4615 v0mi->Update(primvertex);
4620 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4621 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4622 // if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4623 if (RefitAt(v0mi->GetRr(),&tpc0, v0mi->GetClusters(0)) && RefitAt(v0mi->GetRr(),&tpc1, v0mi->GetClusters(1))){
4624 v0temp.SetParamN(tpc0);
4625 v0temp.SetParamP(tpc1);
4626 v0temp.Update(primvertex);
4627 if (kFALSE) cstream<<"Refit"<<
4629 "V0refit.="<<&v0temp<<
4633 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4634 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4635 v0mi->SetParamN(tpc0);
4636 v0mi->SetParamP(tpc1);
4637 v0mi->Update(primvertex);
4642 //------------------------------------------------------------------------
4643 void AliITStrackerMI::BuildMaterialLUT(TString material) {
4644 //--------------------------------------------------------------------
4645 // Fill a look-up table with mean material
4646 //--------------------------------------------------------------------
4650 Double_t point1[3],point2[3];
4651 Double_t phi,cosphi,sinphi,z;
4652 // 0-5 layers, 6 pipe, 7-8 shields
4653 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
4654 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
4656 Int_t ifirst=0,ilast=0;
4657 if(material.Contains("Pipe")) {
4659 } else if(material.Contains("Shields")) {
4661 } else if(material.Contains("Layers")) {
4664 Error("BuildMaterialLUT","Wrong layer name\n");
4667 for(Int_t imat=ifirst; imat<=ilast; imat++) {
4668 Double_t param[5]={0.,0.,0.,0.,0.};
4669 for (Int_t i=0; i<n; i++) {
4670 phi = 2.*TMath::Pi()*gRandom->Rndm();
4671 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
4672 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
4673 point1[0] = rmin[imat]*cosphi;
4674 point1[1] = rmin[imat]*sinphi;
4676 point2[0] = rmax[imat]*cosphi;
4677 point2[1] = rmax[imat]*sinphi;
4679 AliTracker::MeanMaterialBudget(point1,point2,mparam);
4680 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
4682 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
4684 fxOverX0Layer[imat] = param[1];
4685 fxTimesRhoLayer[imat] = param[0]*param[4];
4686 } else if(imat==6) {
4687 fxOverX0Pipe = param[1];
4688 fxTimesRhoPipe = param[0]*param[4];
4689 } else if(imat==7) {
4690 fxOverX0Shield[0] = param[1];
4691 fxTimesRhoShield[0] = param[0]*param[4];
4692 } else if(imat==8) {
4693 fxOverX0Shield[1] = param[1];
4694 fxTimesRhoShield[1] = param[0]*param[4];
4698 printf("%s\n",material.Data());
4699 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
4700 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
4701 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
4702 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
4703 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
4704 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
4705 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
4706 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
4707 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
4711 //------------------------------------------------------------------------
4712 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
4713 TString direction) {
4714 //-------------------------------------------------------------------
4715 // Propagate beyond beam pipe and correct for material
4716 // (material budget in different ways according to fUseTGeo value)
4717 //-------------------------------------------------------------------
4719 // Define budget mode:
4720 // 0: material from AliITSRecoParam (hard coded)
4721 // 1: material from TGeo in one step (on the fly)
4722 // 2: material from lut
4723 // 3: material from TGeo in one step (same for all hypotheses)
4736 if(fTrackingPhase.Contains("Clusters2Tracks"))
4737 { mode=3; } else { mode=1; }
4740 if(fTrackingPhase.Contains("Clusters2Tracks"))
4741 { mode=3; } else { mode=2; }
4747 if(fTrackingPhase.Contains("Default")) mode=0;
4749 Int_t index=fCurrentEsdTrack;
4751 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4752 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4754 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4756 Double_t xOverX0,x0,lengthTimesMeanDensity;
4757 Bool_t anglecorr=kTRUE;
4761 xOverX0 = AliITSRecoParam::GetdPipe();
4762 x0 = AliITSRecoParam::GetX0Be();
4763 lengthTimesMeanDensity = xOverX0*x0;
4764 lengthTimesMeanDensity *= dir;
4765 if (!t->Propagate(xToGo)) return 0;
4766 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4769 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4772 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4773 xOverX0 = fxOverX0Pipe;
4774 lengthTimesMeanDensity = fxTimesRhoPipe;
4775 lengthTimesMeanDensity *= dir;
4776 if (!t->Propagate(xToGo)) return 0;
4777 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4780 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4781 if(fxOverX0PipeTrks[index]<0) {
4782 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4783 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4784 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4785 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4786 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4789 xOverX0 = fxOverX0PipeTrks[index];
4790 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4791 lengthTimesMeanDensity *= dir;
4792 if (!t->Propagate(xToGo)) return 0;
4793 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4799 //------------------------------------------------------------------------
4800 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4802 TString direction) {
4803 //-------------------------------------------------------------------
4804 // Propagate beyond SPD or SDD shield and correct for material
4805 // (material budget in different ways according to fUseTGeo value)
4806 //-------------------------------------------------------------------
4808 // Define budget mode:
4809 // 0: material from AliITSRecoParam (hard coded)
4810 // 1: material from TGeo in steps of X cm (on the fly)
4811 // X = AliITSRecoParam::GetStepSizeTGeo()
4812 // 2: material from lut
4813 // 3: material from TGeo in one step (same for all hypotheses)
4826 if(fTrackingPhase.Contains("Clusters2Tracks"))
4827 { mode=3; } else { mode=1; }
4830 if(fTrackingPhase.Contains("Clusters2Tracks"))
4831 { mode=3; } else { mode=2; }
4837 if(fTrackingPhase.Contains("Default")) mode=0;
4839 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4841 Int_t shieldindex=0;
4842 if (shield.Contains("SDD")) { // SDDouter
4843 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4845 } else if (shield.Contains("SPD")) { // SPDouter
4846 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4849 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4853 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4855 Int_t index=2*fCurrentEsdTrack+shieldindex;
4857 Double_t xOverX0,x0,lengthTimesMeanDensity;
4858 Bool_t anglecorr=kTRUE;
4863 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4864 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4865 lengthTimesMeanDensity = xOverX0*x0;
4866 lengthTimesMeanDensity *= dir;
4867 if (!t->Propagate(xToGo)) return 0;
4868 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4871 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4872 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4875 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4876 xOverX0 = fxOverX0Shield[shieldindex];
4877 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4878 lengthTimesMeanDensity *= dir;
4879 if (!t->Propagate(xToGo)) return 0;
4880 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4883 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4884 if(fxOverX0ShieldTrks[index]<0) {
4885 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4886 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4887 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4888 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4889 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4892 xOverX0 = fxOverX0ShieldTrks[index];
4893 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4894 lengthTimesMeanDensity *= dir;
4895 if (!t->Propagate(xToGo)) return 0;
4896 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4902 //------------------------------------------------------------------------
4903 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4905 Double_t oldGlobXYZ[3],
4906 TString direction) {
4907 //-------------------------------------------------------------------
4908 // Propagate beyond layer and correct for material
4909 // (material budget in different ways according to fUseTGeo value)
4910 //-------------------------------------------------------------------
4912 // Define budget mode:
4913 // 0: material from AliITSRecoParam (hard coded)
4914 // 1: material from TGeo in stepsof X cm (on the fly)
4915 // X = AliITSRecoParam::GetStepSizeTGeo()
4916 // 2: material from lut
4917 // 3: material from TGeo in one step (same for all hypotheses)
4930 if(fTrackingPhase.Contains("Clusters2Tracks"))
4931 { mode=3; } else { mode=1; }
4934 if(fTrackingPhase.Contains("Clusters2Tracks"))
4935 { mode=3; } else { mode=2; }
4941 if(fTrackingPhase.Contains("Default")) mode=0;
4943 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4945 Double_t r=fgLayers[layerindex].GetR();
4946 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4948 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4950 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4952 Int_t index=6*fCurrentEsdTrack+layerindex;
4955 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4957 Bool_t anglecorr=kTRUE;
4961 Bool_t addTime = kFALSE;
4964 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4965 lengthTimesMeanDensity = xOverX0*x0;
4966 // Bring the track beyond the material
4967 if (!t->Propagate(xToGo)) return 0;
4968 lengthTimesMeanDensity *= dir;
4969 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4972 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4973 if (!t->GetLocalXat(rOld,xOld)) return 0;
4974 if (!t->Propagate(xOld)) return 0; // back before material (no correction)
4975 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4976 if (!t->PropagateToTGeo(xToGo,nsteps,addTime)) return 0; // cross the material and apply correction
4979 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4980 xOverX0 = fxOverX0Layer[layerindex];
4981 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4982 // Bring the track beyond the material
4983 if (!t->Propagate(xToGo)) return 0;
4984 lengthTimesMeanDensity *= dir;
4985 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4988 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4989 // Bring the track beyond the material
4990 if (!t->Propagate(xToGo)) return 0;
4991 Double_t globXYZ[3];
4992 if (!t->GetXYZ(globXYZ)) return 0;
4993 if (fxOverX0LayerTrks[index]<0) {
4994 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4995 if(mparam[1]>900000) return 0;
4996 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4997 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4998 xOverX0=mparam[1]/angle;
4999 lengthTimesMeanDensity=mparam[0]*mparam[4]/angle;
5000 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0);
5001 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity);
5003 xOverX0 = fxOverX0LayerTrks[index];
5004 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
5005 lengthTimesMeanDensity *= dir;
5006 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
5012 //------------------------------------------------------------------------
5013 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
5014 //-----------------------------------------------------------------
5015 // Initialize LUT for storing material for each prolonged track
5016 //-----------------------------------------------------------------
5017 fxOverX0PipeTrks = new Float_t[ntracks];
5018 fxTimesRhoPipeTrks = new Float_t[ntracks];
5019 fxOverX0ShieldTrks = new Float_t[ntracks*2];
5020 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
5021 fxOverX0LayerTrks = new Float_t[ntracks*6];
5022 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
5024 for(Int_t i=0; i<ntracks; i++) {
5025 fxOverX0PipeTrks[i] = -1.;
5026 fxTimesRhoPipeTrks[i] = -1.;
5028 for(Int_t j=0; j<ntracks*2; j++) {
5029 fxOverX0ShieldTrks[j] = -1.;
5030 fxTimesRhoShieldTrks[j] = -1.;
5032 for(Int_t k=0; k<ntracks*6; k++) {
5033 fxOverX0LayerTrks[k] = -1.;
5034 fxTimesRhoLayerTrks[k] = -1.;
5041 //------------------------------------------------------------------------
5042 void AliITStrackerMI::DeleteTrksMaterialLUT() {
5043 //-----------------------------------------------------------------
5044 // Delete LUT for storing material for each prolonged track
5045 //-----------------------------------------------------------------
5046 if(fxOverX0PipeTrks) {
5047 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
5049 if(fxOverX0ShieldTrks) {
5050 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
5053 if(fxOverX0LayerTrks) {
5054 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
5056 if(fxTimesRhoPipeTrks) {
5057 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
5059 if(fxTimesRhoShieldTrks) {
5060 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
5062 if(fxTimesRhoLayerTrks) {
5063 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
5067 //------------------------------------------------------------------------
5068 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
5069 Int_t ilayer,Int_t idet) const {
5070 //-----------------------------------------------------------------
5071 // This method is used to decide whether to allow a prolongation
5072 // without clusters, because we want to skip the layer.
5073 // In this case the return value is > 0:
5074 // return 1: the user requested to skip a layer
5075 // return 2: track outside z acceptance of SSD/SDD and will cross both SPD
5076 //-----------------------------------------------------------------
5078 if (AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) return 1;
5080 if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
5081 // check if track will cross SPD outer layer
5082 Double_t phiAtSPD2,zAtSPD2;
5083 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
5084 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
5090 //------------------------------------------------------------------------
5091 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
5092 Int_t ilayer,Int_t idet,
5093 Double_t dz,Double_t dy,
5094 Bool_t noClusters) const {
5095 //-----------------------------------------------------------------
5096 // This method is used to decide whether to allow a prolongation
5097 // without clusters, because there is a dead zone in the road.
5098 // In this case the return value is > 0:
5099 // return 1: dead zone at z=0,+-7cm in SPD
5100 // return 2: all road is "bad" (dead or noisy) from the OCDB
5101 // return 3: something "bad" (dead or noisy) from the OCDB
5102 //-----------------------------------------------------------------
5104 // check dead zones at z=0,+-7cm in the SPD
5105 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
5106 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
5107 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
5108 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
5109 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
5110 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
5111 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
5112 for (Int_t i=0; i<3; i++)
5113 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
5114 AliDebug(2,Form("crack SPD %d",ilayer));
5119 // check bad zones from OCDB
5120 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
5122 if (idet<0) return 0;
5124 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
5127 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
5128 if (ilayer==0 || ilayer==1) { // ---------- SPD
5130 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
5132 detSizeFactorX *= 2.;
5133 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
5136 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
5137 if (detType==2) segm->SetLayer(ilayer+1);
5138 Float_t detSizeX = detSizeFactorX*segm->Dx();
5139 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
5141 // check if the road overlaps with bad chips
5143 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
5144 Float_t zlocmin = zloc-dz;
5145 Float_t zlocmax = zloc+dz;
5146 Float_t xlocmin = xloc-dy;
5147 Float_t xlocmax = xloc+dy;
5148 Int_t chipsInRoad[100];
5150 // check if road goes out of detector
5151 Bool_t touchNeighbourDet=kFALSE;
5152 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.5*detSizeX; touchNeighbourDet=kTRUE;}
5153 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.5*detSizeX; touchNeighbourDet=kTRUE;}
5154 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.5*detSizeZ; touchNeighbourDet=kTRUE;}
5155 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.5*detSizeZ; touchNeighbourDet=kTRUE;}
5156 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));
5158 // check if this detector is bad
5160 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
5161 if(!touchNeighbourDet) {
5162 return 2; // all detectors in road are bad
5164 return 3; // at least one is bad
5168 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
5169 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
5170 if (!nChipsInRoad) return 0;
5172 Bool_t anyBad=kFALSE,anyGood=kFALSE;
5173 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
5174 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
5175 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
5176 if (det.IsChipBad(chipsInRoad[iCh])) {
5184 if(!touchNeighbourDet) {
5185 AliDebug(2,"all bad in road");
5186 return 2; // all chips in road are bad
5188 return 3; // at least a bad chip in road
5193 AliDebug(2,"at least a bad in road");
5194 return 3; // at least a bad chip in road
5198 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
5199 || ilayer==4 || ilayer==5 // SSD
5200 || !noClusters) return 0;
5202 // There are no clusters in road: check if there is at least
5203 // a bad SPD pixel or SDD anode
5205 Int_t idetInITS=idet;
5206 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
5208 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
5209 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
5212 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
5216 //------------------------------------------------------------------------
5217 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
5218 const AliITStrackMI *track,
5219 Float_t &xloc,Float_t &zloc) const {
5220 //-----------------------------------------------------------------
5221 // Gives position of track in local module ref. frame
5222 //-----------------------------------------------------------------
5227 if(idet<0) return kFALSE;
5229 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
5231 Int_t lad = Int_t(idet/ndet) + 1;
5233 Int_t det = idet - (lad-1)*ndet + 1;
5235 Double_t xyzGlob[3],xyzLoc[3];
5237 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
5238 // take into account the misalignment: xyz at real detector plane
5239 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
5241 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
5243 xloc = (Float_t)xyzLoc[0];
5244 zloc = (Float_t)xyzLoc[2];
5248 //------------------------------------------------------------------------
5249 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
5251 // Method to be optimized further:
5252 // Aim: decide whether a track can be used for PlaneEff evaluation
5253 // the decision is taken based on the track quality at the layer under study
5254 // no information on the clusters on this layer has to be used
5255 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
5256 // the cut is done on number of sigmas from the boundaries
5258 // Input: Actual track, layer [0,5] under study
5260 // Return: kTRUE if this is a good track
5262 // it will apply a pre-selection to obtain good quality tracks.
5263 // Here also you will have the possibility to put a control on the
5264 // impact point of the track on the basic block, in order to exclude border regions
5265 // this will be done by calling a proper method of the AliITSPlaneEff class.
5267 // input: AliITStrackMI* track, ilayer= layer number [0,5]
5268 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
5270 Int_t index[AliITSgeomTGeo::kNLayers];
5272 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
5274 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
5275 index[k]=clusters[k];
5279 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
5280 AliITSlayer &layer=fgLayers[ilayer];
5281 Double_t r=layer.GetR();
5282 AliITStrackMI tmp(*track);
5284 // require a minimal number of cluster in other layers and eventually clusters in closest layers
5286 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) {
5287 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
5288 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
5289 if (tmp.GetClIndex(lay)>0) ncl++;
5291 Bool_t nextout = kFALSE;
5292 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
5293 else nextout = ((tmp.GetClIndex(ilayer+1)>0)? kTRUE : kFALSE );
5294 Bool_t nextin = kFALSE;
5295 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
5296 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
5297 if(ncl<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
5299 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
5300 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
5301 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
5302 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
5306 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
5307 Int_t idet=layer.FindDetectorIndex(phi,z);
5308 if(idet<0) { AliInfo(Form("cannot find detector"));
5311 // here check if it has good Chi Square.
5313 //propagate to the intersection with the detector plane
5314 const AliITSdetector &det=layer.GetDetector(idet);
5315 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
5319 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
5320 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5321 if(key>fPlaneEff->Nblock()) return kFALSE;
5322 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
5323 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
5325 // DEFINITION OF SEARCH ROAD FOR accepting a track
5327 //For the time being they are hard-wired, later on from AliITSRecoParam
5328 // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
5329 // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
5332 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
5333 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
5334 // done for RecPoints
5336 // exclude tracks at boundary between detectors
5337 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
5338 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
5339 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
5340 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
5341 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
5343 if ( (locx-dx < blockXmn+boundaryWidth) ||
5344 (locx+dx > blockXmx-boundaryWidth) ||
5345 (locz-dz < blockZmn+boundaryWidth) ||
5346 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
5349 //------------------------------------------------------------------------
5350 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
5352 // This Method has to be optimized! For the time-being it uses the same criteria
5353 // as those used in the search of extra clusters for overlapping modules.
5355 // Method Purpose: estabilish whether a track has produced a recpoint or not
5356 // in the layer under study (For Plane efficiency)
5358 // inputs: AliITStrackMI* track (pointer to a usable track)
5360 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
5361 // traversed by this very track. In details:
5362 // - if a cluster can be associated to the track then call
5363 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
5364 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
5367 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
5368 AliITSlayer &layer=fgLayers[ilayer];
5369 Double_t r=layer.GetR();
5370 AliITStrackMI tmp(*track);
5374 if (!tmp.GetPhiZat(r,phi,z)) return;
5375 Int_t idet=layer.FindDetectorIndex(phi,z);
5377 if(idet<0) { AliInfo(Form("cannot find detector"));
5381 //propagate to the intersection with the detector plane
5382 const AliITSdetector &det=layer.GetDetector(idet);
5383 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
5387 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
5389 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
5390 TMath::Sqrt(tmp.GetSigmaZ2() +
5391 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5392 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5393 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
5394 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
5395 TMath::Sqrt(tmp.GetSigmaY2() +
5396 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5397 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5398 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
5400 // road in global (rphi,z) [i.e. in tracking ref. system]
5401 Double_t zmin = tmp.GetZ() - dz;
5402 Double_t zmax = tmp.GetZ() + dz;
5403 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
5404 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
5406 // select clusters in road
5407 layer.SelectClusters(zmin,zmax,ymin,ymax);
5409 // Define criteria for track-cluster association
5410 Double_t msz = tmp.GetSigmaZ2() +
5411 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5412 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5413 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
5414 Double_t msy = tmp.GetSigmaY2() +
5415 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5416 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5417 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
5418 if (tmp.GetConstrain()) {
5419 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
5420 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
5422 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
5423 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
5425 msz = 1./msz; // 1/RoadZ^2
5426 msy = 1./msy; // 1/RoadY^2
5429 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
5431 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
5432 //Double_t tolerance=0.2;
5433 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
5434 idetc = cl->GetDetectorIndex();
5435 if(idet!=idetc) continue;
5436 //Int_t ilay = cl->GetLayer();
5438 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
5439 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
5441 Double_t chi2=tmp.GetPredictedChi2(cl);
5442 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
5446 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
5448 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
5449 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5450 if(key>fPlaneEff->Nblock()) return;
5451 Bool_t found=kFALSE;
5454 while ((cl=layer.GetNextCluster(clidx))!=0) {
5455 idetc = cl->GetDetectorIndex();
5456 if(idet!=idetc) continue;
5457 // here real control to see whether the cluster can be associated to the track.
5458 // cluster not associated to track
5459 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
5460 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
5461 // calculate track-clusters chi2
5462 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
5463 // in particular, the error associated to the cluster
5464 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
5466 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
5468 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
5469 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
5470 // track->SetExtraModule(ilayer,idetExtra);
5472 if(!fPlaneEff->UpDatePlaneEff(found,key))
5473 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
5474 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
5475 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
5476 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
5477 Int_t cltype[2]={-999,-999};
5481 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
5482 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
5485 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
5486 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
5487 cltype[0]=layer.GetCluster(ci)->GetNy();
5488 cltype[1]=layer.GetCluster(ci)->GetNz();
5490 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
5491 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
5492 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
5493 // It is computed properly by calling the method
5494 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
5496 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
5497 //if (tmp.PropagateTo(x,0.,0.)) {
5498 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
5499 AliCluster c(*layer.GetCluster(ci));
5500 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
5501 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
5502 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
5503 clu[2]=TMath::Sqrt(c.GetSigmaY2());
5504 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
5507 fPlaneEff->FillHistos(key,found,tr,clu,cltype);