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 // dE/dx analysis by: Boris Batyunya, JINR, Boris.Batiounia@cern.ch
23 // Params moved to AliITSRecoParam by: Andrea Dainese, INFN
24 // Material budget from TGeo by: Ludovic Gaudichet & Andrea Dainese, INFN
25 //-------------------------------------------------------------------------
29 #include <TTreeStream.h>
30 #include <TDatabasePDG.h>
35 #include "AliESDEvent.h"
36 #include "AliESDtrack.h"
37 #include "AliESDVertex.h"
40 #include "AliITSRecPoint.h"
41 #include "AliITSgeomTGeo.h"
42 #include "AliITSReconstructor.h"
43 #include "AliTrackPointArray.h"
44 #include "AliAlignObj.h"
45 #include "AliITSClusterParam.h"
46 #include "AliCDBManager.h"
47 #include "AliCDBEntry.h"
48 #include "AliITSCalibrationSPD.h"
49 #include "AliITSCalibrationSDD.h"
50 #include "AliITSCalibrationSSD.h"
51 #include "AliITSPlaneEff.h"
52 #include "AliITSPlaneEffSPD.h"
53 #include "AliITSPlaneEffSDD.h"
54 #include "AliITSPlaneEffSSD.h"
55 #include "AliITStrackerMI.h"
57 ClassImp(AliITStrackerMI)
59 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
61 AliITStrackerMI::AliITStrackerMI():AliTracker(),
71 fLastLayerToTrackTo(0),
74 fTrackingPhase("Default"),
80 fxTimesRhoPipeTrks(0),
81 fxOverX0ShieldTrks(0),
82 fxTimesRhoShieldTrks(0),
84 fxTimesRhoLayerTrks(0),
89 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
90 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
91 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
93 //------------------------------------------------------------------------
94 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
95 fI(AliITSgeomTGeo::GetNLayers()),
104 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
107 fTrackingPhase("Default"),
113 fxTimesRhoPipeTrks(0),
114 fxOverX0ShieldTrks(0),
115 fxTimesRhoShieldTrks(0),
116 fxOverX0LayerTrks(0),
117 fxTimesRhoLayerTrks(0),
120 //--------------------------------------------------------------------
121 //This is the AliITStrackerMI constructor
122 //--------------------------------------------------------------------
124 AliWarning("\"geom\" is actually a dummy argument !");
130 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
131 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
132 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
134 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
135 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
136 Double_t poff=TMath::ATan2(y,x);
138 Double_t r=TMath::Sqrt(x*x + y*y);
140 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
141 r += TMath::Sqrt(x*x + y*y);
142 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
143 r += TMath::Sqrt(x*x + y*y);
144 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
145 r += TMath::Sqrt(x*x + y*y);
148 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
150 for (Int_t j=1; j<nlad+1; j++) {
151 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
152 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
153 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
155 Double_t txyz[3]={0.}, xyz[3]={0.};
156 m.LocalToMaster(txyz,xyz);
157 Double_t r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
158 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
160 if (phi<0) phi+=TMath::TwoPi();
161 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
163 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
164 new(&det) AliITSdetector(r,phi);
170 fI=AliITSgeomTGeo::GetNLayers();
173 fConstraint[0]=1; fConstraint[1]=0;
175 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
176 AliITSReconstructor::GetRecoParam()->GetYVdef(),
177 AliITSReconstructor::GetRecoParam()->GetZVdef()};
178 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
179 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
180 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
181 SetVertex(xyzVtx,ersVtx);
183 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=AliITSRecoParam::GetLayersNotToSkip(i);
184 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
185 for (Int_t i=0;i<100000;i++){
186 fBestTrackIndex[i]=0;
189 // store positions of centre of SPD modules (in z)
191 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
192 fSPDdetzcentre[0] = tr[2];
193 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
194 fSPDdetzcentre[1] = tr[2];
195 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
196 fSPDdetzcentre[2] = tr[2];
197 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
198 fSPDdetzcentre[3] = tr[2];
200 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
201 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
202 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
206 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
207 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
209 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
211 // only for plane efficiency evaluation
212 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff()) {
213 for(Int_t ilay=0;ilay<6;ilay++) {
214 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilay)) {
215 if (ilay<2) fPlaneEff = new AliITSPlaneEffSPD();
216 else if (ilay<4) fPlaneEff = new AliITSPlaneEffSDD();
217 else fPlaneEff = new AliITSPlaneEffSSD();
218 break; // only one layer type to skip at once
221 if(!fPlaneEff->ReadFromCDB())
222 {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
223 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
224 fPlaneEff->SetCreateHistos(kTRUE);
225 //fPlaneEff->ReadHistosFromFile();
229 //------------------------------------------------------------------------
230 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
232 fBestTrack(tracker.fBestTrack),
233 fTrackToFollow(tracker.fTrackToFollow),
234 fTrackHypothesys(tracker.fTrackHypothesys),
235 fBestHypothesys(tracker.fBestHypothesys),
236 fOriginal(tracker.fOriginal),
237 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
238 fPass(tracker.fPass),
239 fAfterV0(tracker.fAfterV0),
240 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
241 fCoefficients(tracker.fCoefficients),
243 fTrackingPhase(tracker.fTrackingPhase),
244 fUseTGeo(tracker.fUseTGeo),
245 fNtracks(tracker.fNtracks),
246 fxOverX0Pipe(tracker.fxOverX0Pipe),
247 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
249 fxTimesRhoPipeTrks(0),
250 fxOverX0ShieldTrks(0),
251 fxTimesRhoShieldTrks(0),
252 fxOverX0LayerTrks(0),
253 fxTimesRhoLayerTrks(0),
254 fDebugStreamer(tracker.fDebugStreamer),
255 fPlaneEff(tracker.fPlaneEff) {
259 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
262 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
263 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
266 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
267 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
270 //------------------------------------------------------------------------
271 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
272 //Assignment operator
273 this->~AliITStrackerMI();
274 new(this) AliITStrackerMI(tracker);
277 //------------------------------------------------------------------------
278 AliITStrackerMI::~AliITStrackerMI()
283 if (fCoefficients) delete [] fCoefficients;
284 DeleteTrksMaterialLUT();
285 if (fDebugStreamer) {
286 //fDebugStreamer->Close();
287 delete fDebugStreamer;
290 //------------------------------------------------------------------------
291 void AliITStrackerMI::SetLayersNotToSkip(Int_t *l) {
292 //--------------------------------------------------------------------
293 //This function set masks of the layers which must be not skipped
294 //--------------------------------------------------------------------
295 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=l[i];
297 //------------------------------------------------------------------------
298 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
299 //--------------------------------------------------------------------
300 //This function loads ITS clusters
301 //--------------------------------------------------------------------
302 TBranch *branch=cTree->GetBranch("ITSRecPoints");
304 Error("LoadClusters"," can't get the branch !\n");
308 TClonesArray dummy("AliITSRecPoint",10000), *clusters=&dummy;
309 branch->SetAddress(&clusters);
313 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
314 Int_t ndet=fgLayers[i].GetNdetectors();
315 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
316 for (; j<jmax; j++) {
317 if (!cTree->GetEvent(j)) continue;
318 Int_t ncl=clusters->GetEntriesFast();
319 SignDeltas(clusters,GetZ());
322 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
323 detector=c->GetDetectorIndex();
325 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
327 fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
330 // add dead zone "virtual" cluster in SPD, if there is a cluster within
331 // zwindow cm from the dead zone
332 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
333 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
334 Int_t lab[4] = {0,0,0,detector};
335 Int_t info[3] = {0,0,i};
336 Float_t q = 0.; // this identifies virtual clusters
337 Float_t hit[5] = {xdead,
339 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
340 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
342 Bool_t local = kTRUE;
343 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
344 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
345 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
346 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
347 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
348 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
349 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
350 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
351 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
352 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
353 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
354 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
355 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
356 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
357 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
358 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
359 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
360 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
361 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
363 } // "virtual" clusters in SPD
367 fgLayers[i].ResetRoad(); //road defined by the cluster density
368 fgLayers[i].SortClusters();
373 //------------------------------------------------------------------------
374 void AliITStrackerMI::UnloadClusters() {
375 //--------------------------------------------------------------------
376 //This function unloads ITS clusters
377 //--------------------------------------------------------------------
378 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
380 //------------------------------------------------------------------------
381 static Int_t CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
382 //--------------------------------------------------------------------
383 // Correction for the material between the TPC and the ITS
384 //--------------------------------------------------------------------
385 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
386 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
387 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
388 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
389 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
390 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
391 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
392 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
394 Error("CorrectForTPCtoITSDeadZoneMaterial","Track is already in the dead zone !");
400 //------------------------------------------------------------------------
401 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
402 //--------------------------------------------------------------------
403 // This functions reconstructs ITS tracks
404 // The clusters must be already loaded !
405 //--------------------------------------------------------------------
406 fTrackingPhase="Clusters2Tracks";
408 TObjArray itsTracks(15000);
410 fEsd = event; // store pointer to the esd
412 // temporary (for cosmics)
413 if(event->GetVertex()) {
414 TString title = event->GetVertex()->GetTitle();
415 if(title.Contains("cosmics")) {
416 Double_t xyz[3]={GetX(),GetY(),GetZ()};
417 Double_t exyz[3]={0.1,0.1,0.1};
423 {/* Read ESD tracks */
424 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
425 Int_t nentr=event->GetNumberOfTracks();
426 Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
428 AliESDtrack *esd=event->GetTrack(nentr);
430 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
431 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
432 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
433 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
436 t=new AliITStrackMI(*esd);
437 } catch (const Char_t *msg) {
438 //Warning("Clusters2Tracks",msg);
442 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
443 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
446 // look at the ESD mass hypothesys !
447 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
449 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
451 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
452 //track - can be V0 according to TPC
454 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
458 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
462 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
466 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
471 t->SetReconstructed(kFALSE);
472 itsTracks.AddLast(t);
473 fOriginal.AddLast(t);
475 } /* End Read ESD tracks */
479 Int_t nentr=itsTracks.GetEntriesFast();
480 fTrackHypothesys.Expand(nentr);
481 fBestHypothesys.Expand(nentr);
482 MakeCoefficients(nentr);
483 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
485 // THE TWO TRACKING PASSES
486 for (fPass=0; fPass<2; fPass++) {
487 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
488 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
489 //cerr<<fPass<<" "<<fCurrentEsdTrack<<'\n';
490 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
491 if (t==0) continue; //this track has been already tracked
492 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
493 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
494 if (fConstraint[fPass]) {
495 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
496 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
499 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
501 ResetTrackToFollow(*t);
504 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
506 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
508 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
509 if (!besttrack) continue;
510 besttrack->SetLabel(tpcLabel);
511 // besttrack->CookdEdx();
513 besttrack->SetFakeRatio(1.);
514 CookLabel(besttrack,0.); //For comparison only
515 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
517 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
519 t->SetReconstructed(kTRUE);
522 GetBestHypothesysMIP(itsTracks);
523 } // end loop on the two tracking passes
525 //GetBestHypothesysMIP(itsTracks);
526 if(event->GetNumberOfV0s()>0) UpdateTPCV0(event);
527 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) FindV02(event);
529 //GetBestHypothesysMIP(itsTracks);
533 Int_t entries = fTrackHypothesys.GetEntriesFast();
534 for (Int_t ientry=0; ientry<entries; ientry++) {
535 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
536 if (array) array->Delete();
537 delete fTrackHypothesys.RemoveAt(ientry);
540 fTrackHypothesys.Delete();
541 fBestHypothesys.Delete();
543 delete [] fCoefficients;
545 DeleteTrksMaterialLUT();
547 Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
549 fTrackingPhase="Default";
553 //------------------------------------------------------------------------
554 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
555 //--------------------------------------------------------------------
556 // This functions propagates reconstructed ITS tracks back
557 // The clusters must be loaded !
558 //--------------------------------------------------------------------
559 fTrackingPhase="PropagateBack";
560 Int_t nentr=event->GetNumberOfTracks();
561 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
564 for (Int_t i=0; i<nentr; i++) {
565 AliESDtrack *esd=event->GetTrack(i);
567 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
568 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
572 t=new AliITStrackMI(*esd);
573 } catch (const Char_t *msg) {
574 //Warning("PropagateBack",msg);
578 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
580 ResetTrackToFollow(*t);
582 // propagate to vertex [SR, GSI 17.02.2003]
583 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
584 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
585 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
586 fTrackToFollow.StartTimeIntegral();
587 // from vertex to outside pipe
588 CorrectForPipeMaterial(&fTrackToFollow,"outward");
591 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
592 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
593 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
597 fTrackToFollow.SetLabel(t->GetLabel());
598 //fTrackToFollow.CookdEdx();
599 CookLabel(&fTrackToFollow,0.); //For comparison only
600 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
601 //UseClusters(&fTrackToFollow);
607 Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
609 fTrackingPhase="Default";
613 //------------------------------------------------------------------------
614 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
615 //--------------------------------------------------------------------
616 // This functions refits ITS tracks using the
617 // "inward propagated" TPC tracks
618 // The clusters must be loaded !
619 //--------------------------------------------------------------------
620 fTrackingPhase="RefitInward";
621 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) RefitV02(event);
622 Int_t nentr=event->GetNumberOfTracks();
623 Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
626 for (Int_t i=0; i<nentr; i++) {
627 AliESDtrack *esd=event->GetTrack(i);
629 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
630 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
631 if (esd->GetStatus()&AliESDtrack::kTPCout)
632 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
636 t=new AliITStrackMI(*esd);
637 } catch (const Char_t *msg) {
638 //Warning("RefitInward",msg);
642 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
643 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
648 ResetTrackToFollow(*t);
649 fTrackToFollow.ResetClusters();
651 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
652 fTrackToFollow.ResetCovariance(10.);
655 Bool_t pe=AliITSReconstructor::GetRecoParam()->GetComputePlaneEff();
656 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
657 fTrackToFollow.SetLabel(t->GetLabel());
658 // fTrackToFollow.CookdEdx();
659 CookdEdx(&fTrackToFollow);
661 CookLabel(&fTrackToFollow,0.0); //For comparison only
664 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
665 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
666 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
667 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
668 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
669 Float_t r[3]={0.,0.,0.};
671 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
678 Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
680 fTrackingPhase="Default";
684 //------------------------------------------------------------------------
685 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
686 //--------------------------------------------------------------------
687 // Return pointer to a given cluster
688 //--------------------------------------------------------------------
689 Int_t l=(index & 0xf0000000) >> 28;
690 Int_t c=(index & 0x0fffffff) >> 00;
691 return fgLayers[l].GetCluster(c);
693 //------------------------------------------------------------------------
694 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
695 //--------------------------------------------------------------------
696 // Get track space point with index i
697 //--------------------------------------------------------------------
699 Int_t l=(index & 0xf0000000) >> 28;
700 Int_t c=(index & 0x0fffffff) >> 00;
701 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
702 Int_t idet = cl->GetDetectorIndex();
706 cl->GetGlobalXYZ(xyz);
707 cl->GetGlobalCov(cov);
710 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
713 iLayer = AliGeomManager::kSPD1;
716 iLayer = AliGeomManager::kSPD2;
719 iLayer = AliGeomManager::kSDD1;
722 iLayer = AliGeomManager::kSDD2;
725 iLayer = AliGeomManager::kSSD1;
728 iLayer = AliGeomManager::kSSD2;
731 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
734 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
735 p.SetVolumeID((UShort_t)volid);
738 //------------------------------------------------------------------------
739 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
740 AliTrackPoint& p, const AliESDtrack *t) {
741 //--------------------------------------------------------------------
742 // Get track space point with index i
743 // (assign error estimated during the tracking)
744 //--------------------------------------------------------------------
746 Int_t l=(index & 0xf0000000) >> 28;
747 Int_t c=(index & 0x0fffffff) >> 00;
748 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
749 Int_t idet = cl->GetDetectorIndex();
750 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
752 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
754 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
755 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
756 Double_t alpha = t->GetAlpha();
757 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
758 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,AliTracker::GetBz()));
759 phi += alpha-det.GetPhi();
760 Float_t tgphi = TMath::Tan(phi);
762 Float_t tgl = t->GetTgl(); // tgl about const along track
763 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
765 Float_t errlocalx,errlocalz;
766 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errlocalx,errlocalz);
770 cl->GetGlobalXYZ(xyz);
771 // cl->GetGlobalCov(cov);
772 Float_t pos[3] = {0.,0.,0.};
773 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errlocalx*errlocalx,errlocalz*errlocalz,0);
774 tmpcl.GetGlobalCov(cov);
778 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
781 iLayer = AliGeomManager::kSPD1;
784 iLayer = AliGeomManager::kSPD2;
787 iLayer = AliGeomManager::kSDD1;
790 iLayer = AliGeomManager::kSDD2;
793 iLayer = AliGeomManager::kSSD1;
796 iLayer = AliGeomManager::kSSD2;
799 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
802 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
803 p.SetVolumeID((UShort_t)volid);
806 //------------------------------------------------------------------------
807 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
809 //--------------------------------------------------------------------
810 // Follow prolongation tree
811 //--------------------------------------------------------------------
813 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
814 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
817 AliESDtrack * esd = otrack->GetESDtrack();
818 if (esd->GetV0Index(0)>0) {
819 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
820 // mapping of ESD track is different as ITS track in Containers
821 // Need something more stable
822 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
823 for (Int_t i=0;i<3;i++){
824 Int_t index = esd->GetV0Index(i);
826 AliESDv0 * vertex = fEsd->GetV0(index);
827 if (vertex->GetStatus()<0) continue; // rejected V0
829 if (esd->GetSign()>0) {
830 vertex->SetIndex(0,esdindex);
832 vertex->SetIndex(1,esdindex);
836 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
838 bestarray = new TObjArray(5);
839 fBestHypothesys.AddAt(bestarray,esdindex);
843 //setup tree of the prolongations
845 static AliITStrackMI tracks[7][100];
846 AliITStrackMI *currenttrack;
847 static AliITStrackMI currenttrack1;
848 static AliITStrackMI currenttrack2;
849 static AliITStrackMI backuptrack;
851 Int_t nindexes[7][100];
852 Float_t normalizedchi2[100];
853 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
854 otrack->SetNSkipped(0);
855 new (&(tracks[6][0])) AliITStrackMI(*otrack);
857 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
858 Int_t modstatus = 1; // found
862 // follow prolongations
863 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
866 AliITSlayer &layer=fgLayers[ilayer];
867 Double_t r = layer.GetR();
873 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
875 if (ntracks[ilayer]>=100) break;
876 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
877 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
878 if (ntracks[ilayer]>15+ilayer){
879 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
880 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
883 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
885 // material between SSD and SDD, SDD and SPD
887 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
889 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
893 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
894 Int_t idet=layer.FindDetectorIndex(phi,z);
896 Double_t trackGlobXYZ1[3];
897 currenttrack1.GetXYZ(trackGlobXYZ1);
899 // Get the budget to the primary vertex for the current track being prolonged
900 Double_t budgetToPrimVertex = GetEffectiveThickness();
902 // check if we allow a prolongation without point
903 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
905 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
906 // propagate to the layer radius
907 Double_t xToGo; vtrack->GetLocalXat(r,xToGo);
908 vtrack->AliExternalTrackParam::PropagateTo(xToGo,GetBz());
909 // apply correction for material of the current layer
910 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
911 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
912 vtrack->SetClIndex(ilayer,0);
913 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
914 LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc); // local module coords
915 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
916 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
921 // track outside layer acceptance in z
922 if (idet<0) continue;
924 //propagate to the intersection with the detector plane
925 const AliITSdetector &det=layer.GetDetector(idet);
926 new(¤ttrack2) AliITStrackMI(currenttrack1);
927 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
928 LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc); // local module coords
929 currenttrack2.Propagate(det.GetPhi(),det.GetR());
930 currenttrack1.SetDetectorIndex(idet);
931 currenttrack2.SetDetectorIndex(idet);
934 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
936 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
937 TMath::Sqrt(currenttrack1.GetSigmaZ2() +
938 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
939 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
940 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
941 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
942 TMath::Sqrt(currenttrack1.GetSigmaY2() +
943 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
944 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
945 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
947 // track at boundary between detectors, enlarge road
948 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
949 if ( (currenttrack1.GetY()-dy < det.GetYmin()+boundaryWidth) ||
950 (currenttrack1.GetY()+dy > det.GetYmax()-boundaryWidth) ||
951 (currenttrack1.GetZ()-dz < det.GetZmin()+boundaryWidth) ||
952 (currenttrack1.GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
953 Float_t tgl = TMath::Abs(currenttrack1.GetTgl());
954 if (tgl > 1.) tgl=1.;
955 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
956 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
957 Float_t snp = TMath::Abs(currenttrack1.GetSnp());
958 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) continue;
959 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
962 // road in global (rphi,z) [i.e. in tracking ref. system]
963 Double_t zmin = currenttrack1.GetZ() - dz;
964 Double_t zmax = currenttrack1.GetZ() + dz;
965 Double_t ymin = currenttrack1.GetY() + r*det.GetPhi() - dy;
966 Double_t ymax = currenttrack1.GetY() + r*det.GetPhi() + dy;
968 // select clusters in road
969 layer.SelectClusters(zmin,zmax,ymin,ymax);
970 //********************
972 // Define criteria for track-cluster association
973 Double_t msz = currenttrack1.GetSigmaZ2() +
974 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
975 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
976 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
977 Double_t msy = currenttrack1.GetSigmaY2() +
978 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
979 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
980 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
982 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
983 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
985 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
986 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
988 msz = 1./msz; // 1/RoadZ^2
989 msy = 1./msy; // 1/RoadY^2
992 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
994 const AliITSRecPoint *cl=0;
996 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
997 Bool_t deadzoneSPD=kFALSE;
998 currenttrack = ¤ttrack1;
1000 // check if the road contains a dead zone
1001 Int_t dead = CheckDeadZone(ilayer,idet,zmin,zmax);
1002 // create a prolongation without clusters (check also if there are no clusters in the road)
1004 ((layer.GetNextCluster(clidx,kTRUE))==0 &&
1005 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1006 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1007 updatetrack->SetClIndex(ilayer,0);
1009 modstatus = 5; // no cls in road
1010 } else if (dead==1) {
1011 modstatus = 7; // holes in z in SPD
1012 } else if (dead==2) {
1013 modstatus = 2; // dead from OCDB
1015 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1016 // apply correction for material of the current layer
1017 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1018 if (constrain) { // apply vertex constrain
1019 updatetrack->SetConstrain(constrain);
1020 Bool_t isPrim = kTRUE;
1021 if (ilayer<4) { // check that it's close to the vertex
1022 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1023 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1024 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1025 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1026 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1028 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1031 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1032 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1033 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1041 // loop over clusters in the road
1042 while ((cl=layer.GetNextCluster(clidx))!=0) {
1043 if (ntracks[ilayer]>95) break; //space for skipped clusters
1044 Bool_t changedet =kFALSE;
1045 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
1046 Int_t idet=cl->GetDetectorIndex();
1048 if (currenttrack->GetDetectorIndex()==idet) { // track already on the cluster's detector
1049 // a first cut on track-cluster distance
1050 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1051 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1052 continue; // cluster not associated to track
1053 } else { // have to move track to cluster's detector
1054 const AliITSdetector &det=layer.GetDetector(idet);
1055 // a first cut on track-cluster distance
1057 if (!currenttrack2.GetProlongationFast(det.GetPhi(),det.GetR(),y,z)) continue;
1058 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1059 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1060 continue; // cluster not associated to track
1062 new (&backuptrack) AliITStrackMI(currenttrack2);
1064 currenttrack =¤ttrack2;
1065 if (!currenttrack->Propagate(det.GetPhi(),det.GetR())) {
1066 new (currenttrack) AliITStrackMI(backuptrack);
1070 currenttrack->SetDetectorIndex(idet);
1071 // Get again the budget to the primary vertex
1072 // for the current track being prolonged, if had to change detector
1073 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1076 // calculate track-clusters chi2
1077 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1079 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1080 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1081 if (ntracks[ilayer]>=100) continue;
1082 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1083 updatetrack->SetClIndex(ilayer,0);
1084 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1086 if (cl->GetQ()!=0) { // real cluster
1087 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) continue;
1088 updatetrack->SetSampledEdx(cl->GetQ(),updatetrack->GetNumberOfClusters()-1); //b.b.
1089 modstatus = 1; // found
1090 } else { // virtual cluster in dead zone
1091 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1092 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1093 modstatus = 7; // holes in z in SPD
1097 Float_t xlocnewdet,zlocnewdet;
1098 LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet); // local module coords
1099 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1101 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1103 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1105 // apply correction for material of the current layer
1106 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1108 if (constrain) { // apply vertex constrain
1109 updatetrack->SetConstrain(constrain);
1110 Bool_t isPrim = kTRUE;
1111 if (ilayer<4) { // check that it's close to the vertex
1112 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1113 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1114 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1115 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1116 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1118 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1119 } //apply vertex constrain
1121 } // create new hypothesis
1122 } // loop over possible prolongations
1124 // allow one prolongation without clusters
1125 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1126 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1127 // apply correction for material of the current layer
1128 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1129 vtrack->SetClIndex(ilayer,0);
1130 modstatus = 3; // skipped
1131 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1132 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1133 vtrack->IncrementNSkipped();
1137 // allow one prolongation without clusters for tracks with |tgl|>1.1
1138 if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) { //big theta - for low flux
1139 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1140 // apply correction for material of the current layer
1141 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1142 vtrack->SetClIndex(ilayer,0);
1143 modstatus = 3; // skipped
1144 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1145 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1146 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1151 } // loop over tracks in layer ilayer+1
1153 //loop over track candidates for the current layer
1159 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1160 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1161 if (normalizedchi2[itrack] <
1162 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1166 if (constrain) { // constrain
1167 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1169 } else { // !constrain
1170 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1175 // sort tracks by increasing normalized chi2
1176 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1177 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1178 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1179 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1180 } // end loop over layers
1184 // Now select tracks to be kept
1186 Int_t max = constrain ? 20 : 5;
1188 // tracks that reach layer 0 (SPD inner)
1189 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1190 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1191 if (track.GetNumberOfClusters()<2) continue;
1192 if (!constrain && track.GetNormChi2(0) >
1193 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1196 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1199 // tracks that reach layer 1 (SPD outer)
1200 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1201 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1202 if (track.GetNumberOfClusters()<4) continue;
1203 if (!constrain && track.GetNormChi2(1) >
1204 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1205 if (constrain) track.IncrementNSkipped();
1207 track.SetD(0,track.GetD(GetX(),GetY()));
1208 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1209 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1210 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1213 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1216 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1218 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1219 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1220 if (track.GetNumberOfClusters()<3) continue;
1221 if (!constrain && track.GetNormChi2(2) >
1222 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1223 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1225 track.SetD(0,track.GetD(GetX(),GetY()));
1226 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1227 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1228 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1231 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1237 // register best track of each layer - important for V0 finder
1239 for (Int_t ilayer=0;ilayer<5;ilayer++){
1240 if (ntracks[ilayer]==0) continue;
1241 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1242 if (track.GetNumberOfClusters()<1) continue;
1243 CookLabel(&track,0);
1244 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1248 // update TPC V0 information
1250 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1251 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1252 for (Int_t i=0;i<3;i++){
1253 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1254 if (index==0) break;
1255 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1256 if (vertex->GetStatus()<0) continue; // rejected V0
1258 if (otrack->GetSign()>0) {
1259 vertex->SetIndex(0,esdindex);
1262 vertex->SetIndex(1,esdindex);
1264 //find nearest layer with track info
1265 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1266 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1267 Int_t nearest = nearestold;
1268 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1269 if (ntracks[nearest]==0){
1274 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1275 if (nearestold<5&&nearest<5){
1276 Bool_t accept = track.GetNormChi2(nearest)<10;
1278 if (track.GetSign()>0) {
1279 vertex->SetParamP(track);
1280 vertex->Update(fprimvertex);
1281 //vertex->SetIndex(0,track.fESDtrack->GetID());
1282 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1284 vertex->SetParamN(track);
1285 vertex->Update(fprimvertex);
1286 //vertex->SetIndex(1,track.fESDtrack->GetID());
1287 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1289 vertex->SetStatus(vertex->GetStatus()+1);
1291 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1298 //------------------------------------------------------------------------
1299 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1301 //--------------------------------------------------------------------
1304 return fgLayers[layer];
1306 //------------------------------------------------------------------------
1307 AliITStrackerMI::AliITSlayer::AliITSlayer():
1332 //--------------------------------------------------------------------
1333 //default AliITSlayer constructor
1334 //--------------------------------------------------------------------
1335 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1336 fClusterWeight[i]=0;
1337 fClusterTracks[0][i]=-1;
1338 fClusterTracks[1][i]=-1;
1339 fClusterTracks[2][i]=-1;
1340 fClusterTracks[3][i]=-1;
1343 //------------------------------------------------------------------------
1344 AliITStrackerMI::AliITSlayer::
1345 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1370 //--------------------------------------------------------------------
1371 //main AliITSlayer constructor
1372 //--------------------------------------------------------------------
1373 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1374 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1376 //------------------------------------------------------------------------
1377 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1379 fPhiOffset(layer.fPhiOffset),
1380 fNladders(layer.fNladders),
1381 fZOffset(layer.fZOffset),
1382 fNdetectors(layer.fNdetectors),
1383 fDetectors(layer.fDetectors),
1388 fClustersCs(layer.fClustersCs),
1389 fClusterIndexCs(layer.fClusterIndexCs),
1393 fCurrentSlice(layer.fCurrentSlice),
1400 fAccepted(layer.fAccepted),
1404 //------------------------------------------------------------------------
1405 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1406 //--------------------------------------------------------------------
1407 // AliITSlayer destructor
1408 //--------------------------------------------------------------------
1409 delete[] fDetectors;
1410 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1411 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1412 fClusterWeight[i]=0;
1413 fClusterTracks[0][i]=-1;
1414 fClusterTracks[1][i]=-1;
1415 fClusterTracks[2][i]=-1;
1416 fClusterTracks[3][i]=-1;
1419 //------------------------------------------------------------------------
1420 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1421 //--------------------------------------------------------------------
1422 // This function removes loaded clusters
1423 //--------------------------------------------------------------------
1424 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1425 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1426 fClusterWeight[i]=0;
1427 fClusterTracks[0][i]=-1;
1428 fClusterTracks[1][i]=-1;
1429 fClusterTracks[2][i]=-1;
1430 fClusterTracks[3][i]=-1;
1436 //------------------------------------------------------------------------
1437 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1438 //--------------------------------------------------------------------
1439 // This function reset weights of the clusters
1440 //--------------------------------------------------------------------
1441 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1442 fClusterWeight[i]=0;
1443 fClusterTracks[0][i]=-1;
1444 fClusterTracks[1][i]=-1;
1445 fClusterTracks[2][i]=-1;
1446 fClusterTracks[3][i]=-1;
1448 for (Int_t i=0; i<fN;i++) {
1449 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1450 if (cl&&cl->IsUsed()) cl->Use();
1454 //------------------------------------------------------------------------
1455 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1456 //--------------------------------------------------------------------
1457 // This function calculates the road defined by the cluster density
1458 //--------------------------------------------------------------------
1460 for (Int_t i=0; i<fN; i++) {
1461 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1463 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1465 //------------------------------------------------------------------------
1466 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1467 //--------------------------------------------------------------------
1468 //This function adds a cluster to this layer
1469 //--------------------------------------------------------------------
1470 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1471 ::Error("InsertCluster","Too many clusters !\n");
1477 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1478 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1479 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1480 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1481 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1485 //------------------------------------------------------------------------
1486 void AliITStrackerMI::AliITSlayer::SortClusters()
1491 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1492 Float_t *z = new Float_t[fN];
1493 Int_t * index = new Int_t[fN];
1495 for (Int_t i=0;i<fN;i++){
1496 z[i] = fClusters[i]->GetZ();
1498 TMath::Sort(fN,z,index,kFALSE);
1499 for (Int_t i=0;i<fN;i++){
1500 clusters[i] = fClusters[index[i]];
1503 for (Int_t i=0;i<fN;i++){
1504 fClusters[i] = clusters[i];
1505 fZ[i] = fClusters[i]->GetZ();
1506 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1507 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1508 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1518 for (Int_t i=0;i<fN;i++){
1519 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1520 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1521 fClusterIndex[i] = i;
1525 fDy5 = (fYB[1]-fYB[0])/5.;
1526 fDy10 = (fYB[1]-fYB[0])/10.;
1527 fDy20 = (fYB[1]-fYB[0])/20.;
1528 for (Int_t i=0;i<6;i++) fN5[i] =0;
1529 for (Int_t i=0;i<11;i++) fN10[i]=0;
1530 for (Int_t i=0;i<21;i++) fN20[i]=0;
1532 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;}
1533 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;}
1534 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;}
1537 for (Int_t i=0;i<fN;i++)
1538 for (Int_t irot=-1;irot<=1;irot++){
1539 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1541 for (Int_t slice=0; slice<6;slice++){
1542 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1543 fClusters5[slice][fN5[slice]] = fClusters[i];
1544 fY5[slice][fN5[slice]] = curY;
1545 fZ5[slice][fN5[slice]] = fZ[i];
1546 fClusterIndex5[slice][fN5[slice]]=i;
1551 for (Int_t slice=0; slice<11;slice++){
1552 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1553 fClusters10[slice][fN10[slice]] = fClusters[i];
1554 fY10[slice][fN10[slice]] = curY;
1555 fZ10[slice][fN10[slice]] = fZ[i];
1556 fClusterIndex10[slice][fN10[slice]]=i;
1561 for (Int_t slice=0; slice<21;slice++){
1562 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1563 fClusters20[slice][fN20[slice]] = fClusters[i];
1564 fY20[slice][fN20[slice]] = curY;
1565 fZ20[slice][fN20[slice]] = fZ[i];
1566 fClusterIndex20[slice][fN20[slice]]=i;
1573 // consistency check
1575 for (Int_t i=0;i<fN-1;i++){
1581 for (Int_t slice=0;slice<21;slice++)
1582 for (Int_t i=0;i<fN20[slice]-1;i++){
1583 if (fZ20[slice][i]>fZ20[slice][i+1]){
1590 //------------------------------------------------------------------------
1591 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1592 //--------------------------------------------------------------------
1593 // This function returns the index of the nearest cluster
1594 //--------------------------------------------------------------------
1597 if (fCurrentSlice<0) {
1606 if (ncl==0) return 0;
1607 Int_t b=0, e=ncl-1, m=(b+e)/2;
1608 for (; b<e; m=(b+e)/2) {
1609 // if (z > fClusters[m]->GetZ()) b=m+1;
1610 if (z > zcl[m]) b=m+1;
1615 //------------------------------------------------------------------------
1616 void AliITStrackerMI::AliITSlayer::
1617 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1618 //--------------------------------------------------------------------
1619 // This function sets the "window"
1620 //--------------------------------------------------------------------
1622 Double_t circle=2*TMath::Pi()*fR;
1623 fYmin = ymin; fYmax =ymax;
1624 Float_t ymiddle = (fYmin+fYmax)*0.5;
1625 if (ymiddle<fYB[0]) {
1626 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1627 } else if (ymiddle>fYB[1]) {
1628 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1634 fClustersCs = fClusters;
1635 fClusterIndexCs = fClusterIndex;
1641 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1642 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1643 if (slice<0) slice=0;
1644 if (slice>20) slice=20;
1645 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1647 fCurrentSlice=slice;
1648 fClustersCs = fClusters20[fCurrentSlice];
1649 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1650 fYcs = fY20[fCurrentSlice];
1651 fZcs = fZ20[fCurrentSlice];
1652 fNcs = fN20[fCurrentSlice];
1657 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1658 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1659 if (slice<0) slice=0;
1660 if (slice>10) slice=10;
1661 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1663 fCurrentSlice=slice;
1664 fClustersCs = fClusters10[fCurrentSlice];
1665 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1666 fYcs = fY10[fCurrentSlice];
1667 fZcs = fZ10[fCurrentSlice];
1668 fNcs = fN10[fCurrentSlice];
1673 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1674 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1675 if (slice<0) slice=0;
1676 if (slice>5) slice=5;
1677 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1679 fCurrentSlice=slice;
1680 fClustersCs = fClusters5[fCurrentSlice];
1681 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1682 fYcs = fY5[fCurrentSlice];
1683 fZcs = fZ5[fCurrentSlice];
1684 fNcs = fN5[fCurrentSlice];
1688 fI=FindClusterIndex(zmin); fZmax=zmax;
1689 fImax = TMath::Min(FindClusterIndex(zmax)+1,fNcs);
1695 //------------------------------------------------------------------------
1696 Int_t AliITStrackerMI::AliITSlayer::
1697 FindDetectorIndex(Double_t phi, Double_t z) const {
1698 //--------------------------------------------------------------------
1699 //This function finds the detector crossed by the track
1700 //--------------------------------------------------------------------
1702 if (fZOffset<0) // old geometry
1703 dphi = -(phi-fPhiOffset);
1704 else // new geometry
1705 dphi = phi-fPhiOffset;
1708 if (dphi < 0) dphi += 2*TMath::Pi();
1709 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1710 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1711 if (np>=fNladders) np-=fNladders;
1712 if (np<0) np+=fNladders;
1715 Double_t dz=fZOffset-z;
1716 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1717 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1718 if (nz>=fNdetectors) return -1;
1719 if (nz<0) return -1;
1721 return np*fNdetectors + nz;
1723 //------------------------------------------------------------------------
1724 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1726 //--------------------------------------------------------------------
1727 // This function returns clusters within the "window"
1728 //--------------------------------------------------------------------
1730 if (fCurrentSlice<0) {
1731 Double_t rpi2 = 2.*fR*TMath::Pi();
1732 for (Int_t i=fI; i<fImax; i++) {
1734 if (fYmax<y) y -= rpi2;
1735 if (fYmin>y) y += rpi2;
1736 if (y<fYmin) continue;
1737 if (y>fYmax) continue;
1738 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1741 return fClusters[i];
1744 for (Int_t i=fI; i<fImax; i++) {
1745 if (fYcs[i]<fYmin) continue;
1746 if (fYcs[i]>fYmax) continue;
1747 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1748 ci=fClusterIndexCs[i];
1750 return fClustersCs[i];
1755 //------------------------------------------------------------------------
1756 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1758 //--------------------------------------------------------------------
1759 // This function returns the layer thickness at this point (units X0)
1760 //--------------------------------------------------------------------
1762 x0=AliITSRecoParam::GetX0Air();
1763 if (43<fR&&fR<45) { //SSD2
1766 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1767 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1768 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1769 for (Int_t i=0; i<12; i++) {
1770 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1771 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1775 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1776 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1780 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1781 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1784 if (37<fR&&fR<41) { //SSD1
1787 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1788 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1789 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1790 for (Int_t i=0; i<11; i++) {
1791 if (TMath::Abs(z-3.9*i)<0.15) {
1792 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1796 if (TMath::Abs(z+3.9*i)<0.15) {
1797 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1801 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1802 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1805 if (13<fR&&fR<26) { //SDD
1808 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1810 if (TMath::Abs(y-1.80)<0.55) {
1812 for (Int_t j=0; j<20; j++) {
1813 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1814 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1817 if (TMath::Abs(y+1.80)<0.55) {
1819 for (Int_t j=0; j<20; j++) {
1820 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1821 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1825 for (Int_t i=0; i<4; i++) {
1826 if (TMath::Abs(z-7.3*i)<0.60) {
1828 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1831 if (TMath::Abs(z+7.3*i)<0.60) {
1833 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1838 if (6<fR&&fR<8) { //SPD2
1839 Double_t dd=0.0063; x0=21.5;
1841 if (TMath::Abs(y-3.08)>0.5) d+=dd;
1842 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
1844 if (3<fR&&fR<5) { //SPD1
1845 Double_t dd=0.0063; x0=21.5;
1847 if (TMath::Abs(y+0.21)>0.6) d+=dd;
1848 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
1853 //------------------------------------------------------------------------
1854 Double_t AliITStrackerMI::GetEffectiveThickness()
1856 //--------------------------------------------------------------------
1857 // Returns the thickness between the current layer and the vertex (units X0)
1858 //--------------------------------------------------------------------
1861 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
1862 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
1863 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
1867 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
1868 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
1872 Double_t xn=fgLayers[fI].GetR();
1873 for (Int_t i=0; i<fI; i++) {
1874 Double_t xi=fgLayers[i].GetR();
1875 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
1881 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
1882 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
1885 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
1886 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
1890 //------------------------------------------------------------------------
1891 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
1892 //-------------------------------------------------------------------
1893 // This function returns number of clusters within the "window"
1894 //--------------------------------------------------------------------
1896 for (Int_t i=fI; i<fN; i++) {
1897 const AliITSRecPoint *c=fClusters[i];
1898 if (c->GetZ() > fZmax) break;
1899 if (c->IsUsed()) continue;
1900 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
1901 Double_t y=fR*det.GetPhi() + c->GetY();
1903 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
1904 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
1906 if (y<fYmin) continue;
1907 if (y>fYmax) continue;
1912 //------------------------------------------------------------------------
1913 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
1914 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
1916 //--------------------------------------------------------------------
1917 // This function refits the track "track" at the position "x" using
1918 // the clusters from "clusters"
1919 // If "extra"==kTRUE,
1920 // the clusters from overlapped modules get attached to "track"
1921 // If "planeff"==kTRUE,
1922 // special approach for plane efficiency evaluation is applyed
1923 //--------------------------------------------------------------------
1925 Int_t index[AliITSgeomTGeo::kNLayers];
1927 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
1928 Int_t nc=clusters->GetNumberOfClusters();
1929 for (k=0; k<nc; k++) {
1930 Int_t idx=clusters->GetClusterIndex(k);
1931 Int_t ilayer=(idx&0xf0000000)>>28;
1935 return RefitAt(xx,track,index,extra,planeeff); // call the method below
1937 //------------------------------------------------------------------------
1938 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
1939 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
1941 //--------------------------------------------------------------------
1942 // This function refits the track "track" at the position "x" using
1943 // the clusters from array
1944 // If "extra"==kTRUE,
1945 // the clusters from overlapped modules get attached to "track"
1946 // If "planeff"==kTRUE,
1947 // special approach for plane efficiency evaluation is applyed
1948 //--------------------------------------------------------------------
1949 Int_t index[AliITSgeomTGeo::kNLayers];
1951 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
1953 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
1954 index[k]=clusters[k];
1957 // special for cosmics: check which the innermost layer crossed
1959 Int_t innermostlayer=5;
1960 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
1961 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
1962 if(drphi < fgLayers[innermostlayer].GetR()) break;
1964 //printf(" drphi %f innermost %d\n",drphi,innermostlayer);
1966 Int_t modstatus=1; // found
1968 Int_t from, to, step;
1969 if (xx > track->GetX()) {
1970 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
1973 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
1976 TString dir = (step>0 ? "outward" : "inward");
1978 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
1979 AliITSlayer &layer=fgLayers[ilayer];
1980 Double_t r=layer.GetR();
1981 if (step<0 && xx>r) break;
1983 // material between SSD and SDD, SDD and SPD
1984 Double_t hI=ilayer-0.5*step;
1985 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
1986 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
1987 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
1988 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
1990 // remember old position [SR, GSI 18.02.2003]
1991 Double_t oldX=0., oldY=0., oldZ=0.;
1992 if (track->IsStartedTimeIntegral() && step==1) {
1993 track->GetGlobalXYZat(track->GetX(),oldX,oldY,oldZ);
1997 Double_t oldGlobXYZ[3];
1998 track->GetXYZ(oldGlobXYZ);
2001 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2003 Int_t idet=layer.FindDetectorIndex(phi,z);
2005 // check if we allow a prolongation without point for large-eta tracks
2006 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2008 // propagate to the layer radius
2009 Double_t xToGo; track->GetLocalXat(r,xToGo);
2010 track->AliExternalTrackParam::PropagateTo(xToGo,GetBz());
2011 // apply correction for material of the current layer
2012 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2013 modstatus = 4; // out in z
2014 LocalModuleCoord(ilayer,idet,track,xloc,zloc); // local module coords
2015 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2016 // track time update [SR, GSI 17.02.2003]
2017 if (track->IsStartedTimeIntegral() && step==1) {
2018 Double_t newX, newY, newZ;
2019 track->GetGlobalXYZat(track->GetX(),newX,newY,newZ);
2020 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2021 (oldZ-newZ)*(oldZ-newZ);
2022 track->AddTimeStep(TMath::Sqrt(dL2));
2027 if (idet<0) return kFALSE;
2029 const AliITSdetector &det=layer.GetDetector(idet);
2031 if (!track->Propagate(phi,det.GetR())) return kFALSE;
2032 track->SetDetectorIndex(idet);
2033 LocalModuleCoord(ilayer,idet,track,xloc,zloc); // local module coords
2035 Double_t dz,zmin,zmax;
2037 const AliITSRecPoint *clAcc=0;
2038 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2040 Int_t idx=index[ilayer];
2041 if (idx>=0) { // cluster in this layer
2042 modstatus = 6; // no refit
2043 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2045 if (idet != cl->GetDetectorIndex()) {
2046 idet=cl->GetDetectorIndex();
2047 const AliITSdetector &det=layer.GetDetector(idet);
2048 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2049 track->SetDetectorIndex(idet);
2050 LocalModuleCoord(ilayer,idet,track,xloc,zloc); // local module coords
2052 //Double_t chi2=track->GetPredictedChi2(cl);
2053 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2054 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2058 modstatus = 1; // found
2063 } else { // no cluster in this layer
2065 modstatus = 3; // skipped
2066 // Plane Eff determination:
2067 if (planeeff && AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) {
2068 if (IsOKForPlaneEff(track,ilayer)) // only adequate track for plane eff. evaluation
2069 UseTrackForPlaneEff(track,ilayer);
2072 modstatus = 5; // no cls in road
2074 dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
2075 TMath::Sqrt(track->GetSigmaZ2() +
2076 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
2077 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
2078 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
2079 zmin=track->GetZ() - dz;
2080 zmax=track->GetZ() + dz;
2081 Int_t dead = CheckDeadZone(ilayer,idet,zmin,zmax);
2082 if (dead==1) modstatus = 7; // holes in z in SPD
2083 if (dead==2) modstatus = 2; // dead from OCDB
2088 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2089 track->SetSampledEdx(clAcc->GetQ(),track->GetNumberOfClusters()-1);
2091 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2094 if (extra) { // search for extra clusters in overlapped modules
2095 AliITStrackV2 tmp(*track);
2096 Double_t dy,ymin,ymax;
2097 dz=4*TMath::Sqrt(tmp.GetSigmaZ2()+AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
2098 if (dz < 0.5*TMath::Abs(tmp.GetTgl())) dz=0.5*TMath::Abs(tmp.GetTgl());
2099 dy=4*TMath::Sqrt(track->GetSigmaY2()+AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
2100 if (dy < 0.5*TMath::Abs(tmp.GetSnp())) dy=0.5*TMath::Abs(tmp.GetSnp());
2101 zmin=track->GetZ() - dz;
2102 zmax=track->GetZ() + dz;
2103 ymin=track->GetY() + phi*r - dy;
2104 ymax=track->GetY() + phi*r + dy;
2105 layer.SelectClusters(zmin,zmax,ymin,ymax);
2107 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2109 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2(), tolerance=0.1;
2110 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2111 // only clusters in another module! (overlaps)
2112 idetExtra = clExtra->GetDetectorIndex();
2113 if (idet == idetExtra) continue;
2115 const AliITSdetector &det=layer.GetDetector(idetExtra);
2117 if (!tmp.Propagate(det.GetPhi(),det.GetR())) continue;
2119 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2120 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2122 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2123 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2126 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2127 track->SetExtraModule(ilayer,idetExtra);
2129 } // end search for extra clusters in overlapped modules
2131 // Correct for material of the current layer
2132 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2134 // track time update [SR, GSI 17.02.2003]
2135 if (track->IsStartedTimeIntegral() && step==1) {
2136 Double_t newX, newY, newZ;
2137 track->GetGlobalXYZat(track->GetX(),newX,newY,newZ);
2138 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2139 (oldZ-newZ)*(oldZ-newZ);
2140 track->AddTimeStep(TMath::Sqrt(dL2));
2144 } // end loop on layers
2146 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2150 //------------------------------------------------------------------------
2151 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2154 // calculate normalized chi2
2155 // return NormalizedChi2(track,0);
2158 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2159 // track->fdEdxMismatch=0;
2160 Float_t dedxmismatch =0;
2161 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2163 for (Int_t i = 0;i<6;i++){
2164 if (track->GetClIndex(i)>0){
2165 Float_t cerry, cerrz;
2166 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2168 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2171 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2172 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2173 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2175 cchi2+=(0.5-ratio)*10.;
2176 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2177 dedxmismatch+=(0.5-ratio)*10.;
2181 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2182 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2183 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2184 if (i<2) chi2+=2*cl->GetDeltaProbability();
2190 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2191 track->SetdEdxMismatch(dedxmismatch);
2195 for (Int_t i = 0;i<4;i++){
2196 if (track->GetClIndex(i)>0){
2197 Float_t cerry, cerrz;
2198 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2199 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2202 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2203 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2207 for (Int_t i = 4;i<6;i++){
2208 if (track->GetClIndex(i)>0){
2209 Float_t cerry, cerrz;
2210 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2211 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2214 Float_t cerryb, cerrzb;
2215 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2216 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2219 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2220 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2225 if (track->GetESDtrack()->GetTPCsignal()>85){
2226 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2228 chi2+=(0.5-ratio)*5.;
2231 chi2+=(ratio-2.0)*3;
2235 Double_t match = TMath::Sqrt(track->GetChi22());
2236 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2237 if (!track->GetConstrain()) {
2238 if (track->GetNumberOfClusters()>2) {
2239 match/=track->GetNumberOfClusters()-2.;
2244 if (match<0) match=0;
2245 Float_t deadzonefactor = (track->GetNDeadZone()>0) ? 3*(1.1-track->GetDeadZoneProbability()):0.;
2246 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2247 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2248 1./(1.+track->GetNSkipped()));
2252 //------------------------------------------------------------------------
2253 Double_t AliITStrackerMI::GetMatchingChi2(AliITStrackMI * track1, AliITStrackMI * track2)
2256 // return matching chi2 between two tracks
2257 AliITStrackMI track3(*track2);
2258 track3.Propagate(track1->GetAlpha(),track1->GetX());
2260 vec(0,0)=track1->GetY() - track3.GetY();
2261 vec(1,0)=track1->GetZ() - track3.GetZ();
2262 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2263 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2264 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2267 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2268 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2269 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2270 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2271 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2273 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2274 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2275 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2276 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2278 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2279 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2280 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2282 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2283 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2285 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2288 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2289 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2292 //------------------------------------------------------------------------
2293 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr)
2296 // return probability that given point (characterized by z position and error)
2297 // is in SPD dead zone
2299 Double_t probability = 0.;
2300 Double_t absz = TMath::Abs(zpos);
2301 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2302 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2303 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2304 Double_t zmin, zmax;
2305 if (zpos<-6.) { // dead zone at z = -7
2306 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2307 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2308 } else if (zpos>6.) { // dead zone at z = +7
2309 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2310 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2311 } else if (absz<2.) { // dead zone at z = 0
2312 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2313 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2318 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2320 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2321 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2324 //------------------------------------------------------------------------
2325 Double_t AliITStrackerMI::GetTruncatedChi2(AliITStrackMI * track, Float_t fac)
2328 // calculate normalized chi2
2330 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2332 for (Int_t i = 0;i<6;i++){
2333 if (TMath::Abs(track->GetDy(i))>0){
2334 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2335 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2338 else{chi2[i]=10000;}
2341 TMath::Sort(6,chi2,index,kFALSE);
2342 Float_t max = float(ncl)*fac-1.;
2343 Float_t sumchi=0, sumweight=0;
2344 for (Int_t i=0;i<max+1;i++){
2345 Float_t weight = (i<max)?1.:(max+1.-i);
2346 sumchi+=weight*chi2[index[i]];
2349 Double_t normchi2 = sumchi/sumweight;
2352 //------------------------------------------------------------------------
2353 Double_t AliITStrackerMI::GetInterpolatedChi2(AliITStrackMI * forwardtrack, AliITStrackMI * backtrack)
2356 // calculate normalized chi2
2357 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2360 for (Int_t i=0;i<6;i++){
2361 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2362 Double_t sy1 = forwardtrack->GetSigmaY(i);
2363 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2364 Double_t sy2 = backtrack->GetSigmaY(i);
2365 Double_t sz2 = backtrack->GetSigmaZ(i);
2366 if (i<2){ sy2=1000.;sz2=1000;}
2368 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2369 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2371 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2372 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2374 res+= nz0*nz0+ny0*ny0;
2377 if (npoints>1) return
2378 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2379 //2*forwardtrack->fNUsed+
2380 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2381 1./(1.+forwardtrack->GetNSkipped()));
2384 //------------------------------------------------------------------------
2385 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2386 //--------------------------------------------------------------------
2387 // Return pointer to a given cluster
2388 //--------------------------------------------------------------------
2389 Int_t l=(index & 0xf0000000) >> 28;
2390 Int_t c=(index & 0x0fffffff) >> 00;
2391 return fgLayers[l].GetWeight(c);
2393 //------------------------------------------------------------------------
2394 void AliITStrackerMI::RegisterClusterTracks(AliITStrackMI* track,Int_t id)
2396 //---------------------------------------------
2397 // register track to the list
2399 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2402 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2403 Int_t index = track->GetClusterIndex(icluster);
2404 Int_t l=(index & 0xf0000000) >> 28;
2405 Int_t c=(index & 0x0fffffff) >> 00;
2406 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2407 for (Int_t itrack=0;itrack<4;itrack++){
2408 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2409 fgLayers[l].SetClusterTracks(itrack,c,id);
2415 //------------------------------------------------------------------------
2416 void AliITStrackerMI::UnRegisterClusterTracks(AliITStrackMI* track, Int_t id)
2418 //---------------------------------------------
2419 // unregister track from the list
2420 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2421 Int_t index = track->GetClusterIndex(icluster);
2422 Int_t l=(index & 0xf0000000) >> 28;
2423 Int_t c=(index & 0x0fffffff) >> 00;
2424 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2425 for (Int_t itrack=0;itrack<4;itrack++){
2426 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2427 fgLayers[l].SetClusterTracks(itrack,c,-1);
2432 //------------------------------------------------------------------------
2433 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2435 //-------------------------------------------------------------
2436 //get number of shared clusters
2437 //-------------------------------------------------------------
2439 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2440 // mean number of clusters
2441 Float_t *ny = GetNy(id), *nz = GetNz(id);
2444 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2445 Int_t index = track->GetClusterIndex(icluster);
2446 Int_t l=(index & 0xf0000000) >> 28;
2447 Int_t c=(index & 0x0fffffff) >> 00;
2448 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2450 printf("problem\n");
2452 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2456 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2457 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2458 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2460 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2463 deltan = (cl->GetNz()-nz[l]);
2465 if (deltan>2.0) continue; // extended - highly probable shared cluster
2466 weight = 2./TMath::Max(3.+deltan,2.);
2468 for (Int_t itrack=0;itrack<4;itrack++){
2469 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2471 clist[l] = (AliITSRecPoint*)GetCluster(index);
2477 track->SetNUsed(shared);
2480 //------------------------------------------------------------------------
2481 Int_t AliITStrackerMI::GetOverlapTrack(AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2484 // find first shared track
2486 // mean number of clusters
2487 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2489 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2490 Int_t sharedtrack=100000;
2491 Int_t tracks[24],trackindex=0;
2492 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2494 for (Int_t icluster=0;icluster<6;icluster++){
2495 if (clusterlist[icluster]<0) continue;
2496 Int_t index = clusterlist[icluster];
2497 Int_t l=(index & 0xf0000000) >> 28;
2498 Int_t c=(index & 0x0fffffff) >> 00;
2500 printf("problem\n");
2502 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2503 //if (l>3) continue;
2504 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2507 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2508 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2509 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2511 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2514 deltan = (cl->GetNz()-nz[l]);
2516 if (deltan>2.0) continue; // extended - highly probable shared cluster
2518 for (Int_t itrack=3;itrack>=0;itrack--){
2519 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2520 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2521 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2526 if (trackindex==0) return -1;
2528 sharedtrack = tracks[0];
2530 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2533 Int_t track[24], cluster[24];
2534 for (Int_t i=0;i<trackindex;i++){ track[i]=-1; cluster[i]=0;}
2537 for (Int_t i=0;i<trackindex;i++){
2538 if (tracks[i]<0) continue;
2539 track[index] = tracks[i];
2541 for (Int_t j=i+1;j<trackindex;j++){
2542 if (tracks[j]<0) continue;
2543 if (tracks[j]==tracks[i]){
2551 for (Int_t i=0;i<index;i++){
2552 if (cluster[index]>max) {
2553 sharedtrack=track[index];
2560 if (sharedtrack>=100000) return -1;
2562 // make list of overlaps
2564 for (Int_t icluster=0;icluster<6;icluster++){
2565 if (clusterlist[icluster]<0) continue;
2566 Int_t index = clusterlist[icluster];
2567 Int_t l=(index & 0xf0000000) >> 28;
2568 Int_t c=(index & 0x0fffffff) >> 00;
2569 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2570 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2572 if (cl->GetNy()>2) continue;
2573 if (cl->GetNz()>2) continue;
2576 if (cl->GetNy()>3) continue;
2577 if (cl->GetNz()>3) continue;
2580 for (Int_t itrack=3;itrack>=0;itrack--){
2581 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2582 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2590 //------------------------------------------------------------------------
2591 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2593 // try to find track hypothesys without conflicts
2594 // with minimal chi2;
2595 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2596 Int_t entries1 = arr1->GetEntriesFast();
2597 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2598 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2599 Int_t entries2 = arr2->GetEntriesFast();
2600 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2602 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2603 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2604 if (track10->Pt()>0.5+track20->Pt()) return track10;
2606 for (Int_t itrack=0;itrack<entries1;itrack++){
2607 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2608 UnRegisterClusterTracks(track,trackID1);
2611 for (Int_t itrack=0;itrack<entries2;itrack++){
2612 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2613 UnRegisterClusterTracks(track,trackID2);
2617 Float_t maxconflicts=6;
2618 Double_t maxchi2 =1000.;
2620 // get weight of hypothesys - using best hypothesy
2623 Int_t list1[6],list2[6];
2624 AliITSRecPoint *clist1[6], *clist2[6] ;
2625 RegisterClusterTracks(track10,trackID1);
2626 RegisterClusterTracks(track20,trackID2);
2627 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2628 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2629 UnRegisterClusterTracks(track10,trackID1);
2630 UnRegisterClusterTracks(track20,trackID2);
2633 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2634 Float_t nerry[6],nerrz[6];
2635 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2636 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2637 for (Int_t i=0;i<6;i++){
2638 if ( (erry1[i]>0) && (erry2[i]>0)) {
2639 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2640 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2642 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2643 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2645 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2646 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2647 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2650 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2651 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2652 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2660 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2661 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2662 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2663 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2665 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2666 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2667 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2669 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2670 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2671 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2674 Double_t sumw = w1+w2;
2678 w1 = (d2+0.5)/(d1+d2+1.);
2679 w2 = (d1+0.5)/(d1+d2+1.);
2681 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2682 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2684 // get pair of "best" hypothesys
2686 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2687 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2689 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2690 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2691 //if (track1->fFakeRatio>0) continue;
2692 RegisterClusterTracks(track1,trackID1);
2693 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2694 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2696 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2697 //if (track2->fFakeRatio>0) continue;
2699 RegisterClusterTracks(track2,trackID2);
2700 Int_t list1[6],list2[6];
2701 AliITSRecPoint *clist1[6], *clist2[6] ;
2702 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2703 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2704 UnRegisterClusterTracks(track2,trackID2);
2706 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2707 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2708 if (nskipped>0.5) continue;
2710 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2711 if (conflict1+1<cconflict1) continue;
2712 if (conflict2+1<cconflict2) continue;
2716 for (Int_t i=0;i<6;i++){
2718 Float_t c1 =0.; // conflict coeficients
2720 if (clist1[i]&&clist2[i]){
2723 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2726 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
2728 c1 = 2./TMath::Max(3.+deltan,2.);
2729 c2 = 2./TMath::Max(3.+deltan,2.);
2735 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
2738 deltan = (clist1[i]->GetNz()-nz1[i]);
2740 c1 = 2./TMath::Max(3.+deltan,2.);
2747 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
2750 deltan = (clist2[i]->GetNz()-nz2[i]);
2752 c2 = 2./TMath::Max(3.+deltan,2.);
2757 Double_t chi21=0,chi22=0;
2758 if (TMath::Abs(track1->GetDy(i))>0.) {
2759 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
2760 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
2761 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
2762 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
2764 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
2767 if (TMath::Abs(track2->GetDy(i))>0.) {
2768 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
2769 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
2770 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
2771 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
2774 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
2776 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
2777 if (chi21>0) sum+=w1;
2778 if (chi22>0) sum+=w2;
2781 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
2782 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
2783 Double_t normchi2 = 2*conflict+sumchi2/sum;
2784 if ( normchi2 <maxchi2 ){
2787 maxconflicts = conflict;
2791 UnRegisterClusterTracks(track1,trackID1);
2794 // if (maxconflicts<4 && maxchi2<th0){
2795 if (maxchi2<th0*2.){
2796 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
2797 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
2798 track1->SetChi2MIP(5,maxconflicts);
2799 track1->SetChi2MIP(6,maxchi2);
2800 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
2801 // track1->UpdateESDtrack(AliESDtrack::kITSin);
2802 track1->SetChi2MIP(8,index1);
2803 fBestTrackIndex[trackID1] =index1;
2804 UpdateESDtrack(track1, AliESDtrack::kITSin);
2806 else if (track10->GetChi2MIP(0)<th1){
2807 track10->SetChi2MIP(5,maxconflicts);
2808 track10->SetChi2MIP(6,maxchi2);
2809 // track10->UpdateESDtrack(AliESDtrack::kITSin);
2810 UpdateESDtrack(track10,AliESDtrack::kITSin);
2813 for (Int_t itrack=0;itrack<entries1;itrack++){
2814 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2815 UnRegisterClusterTracks(track,trackID1);
2818 for (Int_t itrack=0;itrack<entries2;itrack++){
2819 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2820 UnRegisterClusterTracks(track,trackID2);
2823 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2824 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2825 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2826 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2827 RegisterClusterTracks(track10,trackID1);
2829 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2830 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2831 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2832 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2833 RegisterClusterTracks(track20,trackID2);
2838 //------------------------------------------------------------------------
2839 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
2840 //--------------------------------------------------------------------
2841 // This function marks clusters assigned to the track
2842 //--------------------------------------------------------------------
2843 AliTracker::UseClusters(t,from);
2845 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
2846 //if (c->GetQ()>2) c->Use();
2847 if (c->GetSigmaZ2()>0.1) c->Use();
2848 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
2849 //if (c->GetQ()>2) c->Use();
2850 if (c->GetSigmaZ2()>0.1) c->Use();
2853 //------------------------------------------------------------------------
2854 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
2856 //------------------------------------------------------------------
2857 // add track to the list of hypothesys
2858 //------------------------------------------------------------------
2860 if (esdindex>=fTrackHypothesys.GetEntriesFast()) fTrackHypothesys.Expand(esdindex*2+10);
2862 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
2864 array = new TObjArray(10);
2865 fTrackHypothesys.AddAt(array,esdindex);
2867 array->AddLast(track);
2869 //------------------------------------------------------------------------
2870 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
2872 //-------------------------------------------------------------------
2873 // compress array of track hypothesys
2874 // keep only maxsize best hypothesys
2875 //-------------------------------------------------------------------
2876 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
2877 if (! (fTrackHypothesys.At(esdindex)) ) return;
2878 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
2879 Int_t entries = array->GetEntriesFast();
2881 //- find preliminary besttrack as a reference
2882 Float_t minchi2=10000;
2884 AliITStrackMI * besttrack=0;
2885 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
2886 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2887 if (!track) continue;
2888 Float_t chi2 = NormalizedChi2(track,0);
2890 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
2891 track->SetLabel(tpcLabel);
2893 track->SetFakeRatio(1.);
2894 CookLabel(track,0.); //For comparison only
2896 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
2897 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
2898 if (track->GetNumberOfClusters()<maxn) continue;
2899 maxn = track->GetNumberOfClusters();
2906 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2907 delete array->RemoveAt(itrack);
2911 if (!besttrack) return;
2914 //take errors of best track as a reference
2915 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
2916 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
2917 for (Int_t i=0;i<6;i++) {
2918 if (besttrack->GetClIndex(i)>0){
2919 erry[i] = besttrack->GetSigmaY(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2920 errz[i] = besttrack->GetSigmaZ(i); errz[i+6] = besttrack->GetSigmaZ(i+6);
2921 ny[i] = besttrack->GetNy(i);
2922 nz[i] = besttrack->GetNz(i);
2926 // calculate normalized chi2
2928 Float_t * chi2 = new Float_t[entries];
2929 Int_t * index = new Int_t[entries];
2930 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
2931 for (Int_t itrack=0;itrack<entries;itrack++){
2932 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2934 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
2935 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
2936 chi2[itrack] = track->GetChi2MIP(0);
2938 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2939 delete array->RemoveAt(itrack);
2945 TMath::Sort(entries,chi2,index,kFALSE);
2946 besttrack = (AliITStrackMI*)array->At(index[0]);
2947 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
2948 for (Int_t i=0;i<6;i++){
2949 if (besttrack->GetClIndex(i)>0){
2950 erry[i] = besttrack->GetSigmaY(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2951 errz[i] = besttrack->GetSigmaZ(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2952 ny[i] = besttrack->GetNy(i);
2953 nz[i] = besttrack->GetNz(i);
2958 // calculate one more time with updated normalized errors
2959 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
2960 for (Int_t itrack=0;itrack<entries;itrack++){
2961 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2963 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
2964 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
2965 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
2968 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2969 delete array->RemoveAt(itrack);
2974 entries = array->GetEntriesFast();
2978 TObjArray * newarray = new TObjArray();
2979 TMath::Sort(entries,chi2,index,kFALSE);
2980 besttrack = (AliITStrackMI*)array->At(index[0]);
2983 for (Int_t i=0;i<6;i++){
2984 if (besttrack->GetNz(i)>0&&besttrack->GetNy(i)>0){
2985 erry[i] = besttrack->GetSigmaY(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2986 errz[i] = besttrack->GetSigmaZ(i); errz[i+6] = besttrack->GetSigmaZ(i+6);
2987 ny[i] = besttrack->GetNy(i);
2988 nz[i] = besttrack->GetNz(i);
2991 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
2992 Float_t minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
2993 Float_t minn = besttrack->GetNumberOfClusters()-3;
2995 for (Int_t i=0;i<entries;i++){
2996 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
2997 if (!track) continue;
2998 if (accepted>maxcut) break;
2999 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3000 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3001 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3002 delete array->RemoveAt(index[i]);
3006 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3007 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3008 if (!shortbest) accepted++;
3010 newarray->AddLast(array->RemoveAt(index[i]));
3011 for (Int_t i=0;i<6;i++){
3013 erry[i] = track->GetSigmaY(i); erry[i+6] = track->GetSigmaY(i+6);
3014 errz[i] = track->GetSigmaZ(i); errz[i] = track->GetSigmaZ(i+6);
3015 ny[i] = track->GetNy(i);
3016 nz[i] = track->GetNz(i);
3021 delete array->RemoveAt(index[i]);
3025 delete fTrackHypothesys.RemoveAt(esdindex);
3026 fTrackHypothesys.AddAt(newarray,esdindex);
3030 delete fTrackHypothesys.RemoveAt(esdindex);
3036 //------------------------------------------------------------------------
3037 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3039 //-------------------------------------------------------------
3040 // try to find best hypothesy
3041 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3042 //-------------------------------------------------------------
3043 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3044 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3045 if (!array) return 0;
3046 Int_t entries = array->GetEntriesFast();
3047 if (!entries) return 0;
3048 Float_t minchi2 = 100000;
3049 AliITStrackMI * besttrack=0;
3051 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3052 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3053 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3054 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3056 for (Int_t i=0;i<entries;i++){
3057 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3058 if (!track) continue;
3059 Float_t sigmarfi,sigmaz;
3060 GetDCASigma(track,sigmarfi,sigmaz);
3061 track->SetDnorm(0,sigmarfi);
3062 track->SetDnorm(1,sigmaz);
3064 track->SetChi2MIP(1,1000000);
3065 track->SetChi2MIP(2,1000000);
3066 track->SetChi2MIP(3,1000000);
3069 backtrack = new(backtrack) AliITStrackMI(*track);
3070 if (track->GetConstrain()) {
3071 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3072 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3073 backtrack->ResetCovariance(10.);
3075 backtrack->ResetCovariance(10.);
3077 backtrack->ResetClusters();
3079 Double_t x = original->GetX();
3080 if (!RefitAt(x,backtrack,track)) continue;
3082 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3083 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3084 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3085 track->SetChi22(GetMatchingChi2(backtrack,original));
3087 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3088 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3089 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3092 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3094 //forward track - without constraint
3095 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3096 forwardtrack->ResetClusters();
3098 RefitAt(x,forwardtrack,track);
3099 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3100 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3101 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3103 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3104 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3105 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3106 forwardtrack->SetD(0,track->GetD(0));
3107 forwardtrack->SetD(1,track->GetD(1));
3110 AliITSRecPoint* clist[6];
3111 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3112 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3115 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3116 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3117 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3118 track->SetChi2MIP(3,1000);
3121 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3123 for (Int_t ichi=0;ichi<5;ichi++){
3124 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3126 if (chi2 < minchi2){
3127 //besttrack = new AliITStrackMI(*forwardtrack);
3129 besttrack->SetLabel(track->GetLabel());
3130 besttrack->SetFakeRatio(track->GetFakeRatio());
3132 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3133 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3134 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3138 delete forwardtrack;
3140 for (Int_t i=0;i<entries;i++){
3141 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3142 if (!track) continue;
3144 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3145 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3146 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3147 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3148 delete array->RemoveAt(i);
3158 SortTrackHypothesys(esdindex,checkmax,1);
3159 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3160 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3161 besttrack = (AliITStrackMI*)array->At(0);
3162 if (!besttrack) return 0;
3163 besttrack->SetChi2MIP(8,0);
3164 fBestTrackIndex[esdindex]=0;
3165 entries = array->GetEntriesFast();
3166 AliITStrackMI *longtrack =0;
3168 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3169 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3170 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3171 if (!track->GetConstrain()) continue;
3172 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3173 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3174 if (track->GetChi2MIP(0)>4.) continue;
3175 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3178 //if (longtrack) besttrack=longtrack;
3181 AliITSRecPoint * clist[6];
3182 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3183 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3184 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3185 RegisterClusterTracks(besttrack,esdindex);
3192 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3193 if (sharedtrack>=0){
3195 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3197 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3203 if (shared>2.5) return 0;
3204 if (shared>1.0) return besttrack;
3206 // Don't sign clusters if not gold track
3208 if (!besttrack->IsGoldPrimary()) return besttrack;
3209 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3211 if (fConstraint[fPass]){
3215 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3216 for (Int_t i=0;i<6;i++){
3217 Int_t index = besttrack->GetClIndex(i);
3218 if (index<=0) continue;
3219 Int_t ilayer = (index & 0xf0000000) >> 28;
3220 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3221 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3223 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3224 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3225 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3226 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3227 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3228 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3230 Bool_t cansign = kTRUE;
3231 for (Int_t itrack=0;itrack<entries; itrack++){
3232 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3233 if (!track) continue;
3234 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3235 if ( (track->GetClIndex(ilayer)>0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3241 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3242 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3243 if (!c->IsUsed()) c->Use();
3249 //------------------------------------------------------------------------
3250 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3253 // get "best" hypothesys
3256 Int_t nentries = itsTracks.GetEntriesFast();
3257 for (Int_t i=0;i<nentries;i++){
3258 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3259 if (!track) continue;
3260 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3261 if (!array) continue;
3262 if (array->GetEntriesFast()<=0) continue;
3264 AliITStrackMI* longtrack=0;
3266 Float_t maxchi2=1000;
3267 for (Int_t j=0;j<array->GetEntriesFast();j++){
3268 AliITStrackMI* track = (AliITStrackMI*)array->At(j);
3269 if (!track) continue;
3270 if (track->GetGoldV0()) {
3271 longtrack = track; //gold V0 track taken
3274 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3275 Float_t chi2 = track->GetChi2MIP(0);
3277 if (!track->GetGoldV0()&&track->GetConstrain()==kFALSE) chi2+=5;
3279 if (track->GetNumberOfClusters()+track->GetNDeadZone()>minn) maxchi2 = track->GetChi2MIP(0);
3281 if (chi2 > maxchi2) continue;
3282 minn= track->GetNumberOfClusters()+track->GetNDeadZone();
3289 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3290 if (!longtrack) {longtrack = besttrack;}
3291 else besttrack= longtrack;
3295 AliITSRecPoint * clist[6];
3296 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3298 track->SetNUsed(shared);
3299 track->SetNSkipped(besttrack->GetNSkipped());
3300 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3302 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3306 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3307 //if (sharedtrack==-1) sharedtrack=0;
3308 if (sharedtrack>=0) {
3309 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3312 if (besttrack&&fAfterV0) {
3313 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3315 if (besttrack&&fConstraint[fPass])
3316 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3317 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3318 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3319 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3325 //------------------------------------------------------------------------
3326 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3327 //--------------------------------------------------------------------
3328 //This function "cooks" a track label. If label<0, this track is fake.
3329 //--------------------------------------------------------------------
3332 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3334 track->SetChi2MIP(9,0);
3336 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3337 Int_t cindex = track->GetClusterIndex(i);
3338 Int_t l=(cindex & 0xf0000000) >> 28;
3339 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3341 for (Int_t ind=0;ind<3;ind++){
3343 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3345 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3348 Int_t nclusters = track->GetNumberOfClusters();
3349 if (nclusters > 0) //PH Some tracks don't have any cluster
3350 track->SetFakeRatio(double(nwrong)/double(nclusters));
3352 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3354 track->SetLabel(tpcLabel);
3358 //------------------------------------------------------------------------
3359 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3364 //AliITSRecPoint * clist[6];
3365 // Int_t shared = GetNumberOfSharedClusters(track,index,list,clist);
3368 track->SetChi2MIP(9,0);
3369 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3370 Int_t cindex = track->GetClusterIndex(i);
3371 Int_t l=(cindex & 0xf0000000) >> 28;
3372 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3373 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3375 for (Int_t ind=0;ind<3;ind++){
3376 if (cl->GetLabel(ind)==lab) isWrong=0;
3378 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3380 //if (l>3 && (cl->GetNy()>4) || (cl->GetNz()>4)) continue; //shared track
3381 //if (l>3&& !(cl->GetType()==1||cl->GetType()==10)) continue;
3382 //if (l<4&& !(cl->GetType()==1)) continue;
3383 dedx[accepted]= track->GetSampledEdx(i);
3384 //dedx[accepted]= track->fNormQ[l];
3392 TMath::Sort(accepted,dedx,indexes,kFALSE);
3395 Double_t nl=low*accepted, nu =up*accepted;
3397 Float_t sumweight =0;
3398 for (Int_t i=0; i<accepted; i++) {
3400 if (i<nl+0.1) weight = TMath::Max(1.-(nl-i),0.);
3401 if (i>nu-1) weight = TMath::Max(nu-i,0.);
3402 sumamp+= dedx[indexes[i]]*weight;
3405 track->SetdEdx(sumamp/sumweight);
3407 //------------------------------------------------------------------------
3408 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3411 if (fCoefficients) delete []fCoefficients;
3412 fCoefficients = new Float_t[ntracks*48];
3413 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3415 //------------------------------------------------------------------------
3416 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3422 Float_t theta = track->GetTgl();
3423 Float_t phi = track->GetSnp();
3424 phi = TMath::Sqrt(phi*phi/(1.-phi*phi));
3425 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz);
3426 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz);
3428 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3429 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3431 chi2+=0.5*TMath::Min(delta/2,2.);
3432 chi2+=2.*cluster->GetDeltaProbability();
3435 track->SetNy(layer,ny);
3436 track->SetNz(layer,nz);
3437 track->SetSigmaY(layer,erry);
3438 track->SetSigmaZ(layer, errz);
3439 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3440 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/(1.- track->GetSnp()*track->GetSnp())));
3444 //------------------------------------------------------------------------
3445 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3450 Int_t layer = (index & 0xf0000000) >> 28;
3451 track->SetClIndex(layer, index);
3452 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3453 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3454 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3455 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3459 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3461 //Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);printf("gtr %f %f %f\n",trxyz[0],trxyz[1],trxyz[2]);printf("gcl %f %f %f\n",clxyz[0],clxyz[1],clxyz[2]);
3464 // Take into account the mis-alignment
3465 Double_t x=track->GetX()+cl->GetX();
3466 if (!track->PropagateTo(x,0.,0.)) return 0;
3469 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3470 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3472 return track->UpdateMI(&c,chi2,index);
3475 //------------------------------------------------------------------------
3476 void AliITStrackerMI::GetDCASigma(AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3479 //DCA sigmas parameterization
3480 //to be paramterized using external parameters in future
3483 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3484 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3486 //------------------------------------------------------------------------
3487 void AliITStrackerMI::SignDeltas( TObjArray *ClusterArray, Float_t vz)
3491 Int_t entries = ClusterArray->GetEntriesFast();
3492 if (entries<4) return;
3493 AliITSRecPoint* cluster = (AliITSRecPoint*)ClusterArray->At(0);
3494 Int_t layer = cluster->GetLayer();
3495 if (layer>1) return;
3497 Int_t ncandidates=0;
3498 Float_t r = (layer>0)? 7:4;
3500 for (Int_t i=0;i<entries;i++){
3501 AliITSRecPoint* cl0 = (AliITSRecPoint*)ClusterArray->At(i);
3502 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3503 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3504 index[ncandidates] = i; //candidate to belong to delta electron track
3506 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3507 cl0->SetDeltaProbability(1);
3513 for (Int_t i=0;i<ncandidates;i++){
3514 AliITSRecPoint* cl0 = (AliITSRecPoint*)ClusterArray->At(index[i]);
3515 if (cl0->GetDeltaProbability()>0.8) continue;
3518 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3519 sumy=sumz=sumy2=sumyz=sumw=0.0;
3520 for (Int_t j=0;j<ncandidates;j++){
3522 AliITSRecPoint* cl1 = (AliITSRecPoint*)ClusterArray->At(index[j]);
3524 Float_t dz = cl0->GetZ()-cl1->GetZ();
3525 Float_t dy = cl0->GetY()-cl1->GetY();
3526 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3527 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3528 y[ncl] = cl1->GetY();
3529 z[ncl] = cl1->GetZ();
3530 sumy+= y[ncl]*weight;
3531 sumz+= z[ncl]*weight;
3532 sumy2+=y[ncl]*y[ncl]*weight;
3533 sumyz+=y[ncl]*z[ncl]*weight;
3538 if (ncl<4) continue;
3539 Float_t det = sumw*sumy2 - sumy*sumy;
3541 if (TMath::Abs(det)>0.01){
3542 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3543 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3544 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3547 Float_t z0 = sumyz/sumy;
3548 delta = TMath::Abs(cl0->GetZ()-z0);
3551 cl0->SetDeltaProbability(1-20.*delta);
3555 //------------------------------------------------------------------------
3556 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3560 track->UpdateESDtrack(flags);
3561 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3562 if (oldtrack) delete oldtrack;
3563 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3564 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3565 printf("Problem\n");
3568 //------------------------------------------------------------------------
3569 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3571 // Get nearest upper layer close to the point xr.
3572 // rough approximation
3574 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3575 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3577 for (Int_t i=0;i<6;i++){
3578 if (radius<kRadiuses[i]){
3585 //------------------------------------------------------------------------
3586 void AliITStrackerMI::UpdateTPCV0(AliESDEvent *event){
3588 //try to update, or reject TPC V0s
3590 Int_t nv0s = event->GetNumberOfV0s();
3591 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3593 for (Int_t i=0;i<nv0s;i++){
3594 AliESDv0 * vertex = event->GetV0(i);
3595 Int_t ip = vertex->GetIndex(0);
3596 Int_t im = vertex->GetIndex(1);
3598 TObjArray * arrayp = (ip<nitstracks) ? (TObjArray*)fTrackHypothesys.At(ip):0;
3599 TObjArray * arraym = (im<nitstracks) ? (TObjArray*)fTrackHypothesys.At(im):0;
3600 AliITStrackMI * trackp = (arrayp!=0) ? (AliITStrackMI*)arrayp->At(0):0;
3601 AliITStrackMI * trackm = (arraym!=0) ? (AliITStrackMI*)arraym->At(0):0;
3605 if (trackp->GetNumberOfClusters()+trackp->GetNDeadZone()>5.5){
3606 if (trackp->GetConstrain()&&trackp->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3607 if (!trackp->GetConstrain()&&trackp->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3612 if (trackm->GetNumberOfClusters()+trackm->GetNDeadZone()>5.5){
3613 if (trackm->GetConstrain()&&trackm->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3614 if (!trackm->GetConstrain()&&trackm->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3617 if (vertex->GetStatus()==-100) continue;
3619 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
3620 Int_t clayer = GetNearestLayer(xrp); //I.B.
3621 vertex->SetNBefore(clayer); //
3622 vertex->SetChi2Before(9*clayer); //
3623 vertex->SetNAfter(6-clayer); //
3624 vertex->SetChi2After(0); //
3626 if (clayer >1 ){ // calculate chi2 before vertex
3627 Float_t chi2p = 0, chi2m=0;
3630 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3631 if (trackp->GetClIndex(ilayer)>0){
3632 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3633 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3644 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3645 if (trackm->GetClIndex(ilayer)>0){
3646 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3647 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3656 vertex->SetChi2Before(TMath::Min(chi2p,chi2m));
3657 if (TMath::Min(chi2p,chi2m)/Float_t(clayer)<4) vertex->SetStatus(-10); // track exist before vertex
3660 if (clayer < 5 ){ // calculate chi2 after vertex
3661 Float_t chi2p = 0, chi2m=0;
3663 if (trackp&&TMath::Abs(trackp->GetTgl())<1.){
3664 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3665 if (trackp->GetClIndex(ilayer)>0){
3666 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3667 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3677 if (trackm&&TMath::Abs(trackm->GetTgl())<1.){
3678 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3679 if (trackm->GetClIndex(ilayer)>0){
3680 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3681 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3690 vertex->SetChi2After(TMath::Max(chi2p,chi2m));
3691 if (TMath::Max(chi2m,chi2p)/Float_t(6-clayer)>9) vertex->SetStatus(-20); // track not found in ITS
3696 //------------------------------------------------------------------------
3697 void AliITStrackerMI::FindV02(AliESDEvent *event)
3702 // Cuts on DCA - R dependent
3703 // max distance DCA between 2 tracks cut
3704 // maxDist = TMath::Min(kMaxDist,kMaxDist0+pvertex->GetRr()*kMaxDist);
3706 const Float_t kMaxDist0 = 0.1;
3707 const Float_t kMaxDist1 = 0.1;
3708 const Float_t kMaxDist = 1;
3709 const Float_t kMinPointAngle = 0.85;
3710 const Float_t kMinPointAngle2 = 0.99;
3711 const Float_t kMinR = 0.5;
3712 const Float_t kMaxR = 220;
3713 //const Float_t kCausality0Cut = 0.19;
3714 //const Float_t kLikelihood01Cut = 0.25;
3715 //const Float_t kPointAngleCut = 0.9996;
3716 const Float_t kCausality0Cut = 0.19;
3717 const Float_t kLikelihood01Cut = 0.45;
3718 const Float_t kLikelihood1Cut = 0.5;
3719 const Float_t kCombinedCut = 0.55;
3723 TTreeSRedirector &cstream = *fDebugStreamer;
3724 Int_t ntracks = event->GetNumberOfTracks();
3725 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3726 fOriginal.Expand(ntracks);
3727 fTrackHypothesys.Expand(ntracks);
3728 fBestHypothesys.Expand(ntracks);
3730 AliHelix * helixes = new AliHelix[ntracks+2];
3731 TObjArray trackarray(ntracks+2); //array with tracks - with vertex constrain
3732 TObjArray trackarrayc(ntracks+2); //array of "best tracks" - without vertex constrain
3733 TObjArray trackarrayl(ntracks+2); //array of "longest tracks" - without vertex constrain
3734 Bool_t * forbidden = new Bool_t [ntracks+2];
3735 Int_t *itsmap = new Int_t [ntracks+2];
3736 Float_t *dist = new Float_t[ntracks+2];
3737 Float_t *normdist0 = new Float_t[ntracks+2];
3738 Float_t *normdist1 = new Float_t[ntracks+2];
3739 Float_t *normdist = new Float_t[ntracks+2];
3740 Float_t *norm = new Float_t[ntracks+2];
3741 Float_t *maxr = new Float_t[ntracks+2];
3742 Float_t *minr = new Float_t[ntracks+2];
3743 Float_t *minPointAngle= new Float_t[ntracks+2];
3745 AliV0 *pvertex = new AliV0;
3746 AliITStrackMI * dummy= new AliITStrackMI;
3748 AliITStrackMI trackat0; //temporary track for DCA calculation
3750 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
3752 // make ITS - ESD map
3754 for (Int_t itrack=0;itrack<ntracks+2;itrack++) {
3755 itsmap[itrack] = -1;
3756 forbidden[itrack] = kFALSE;
3757 maxr[itrack] = kMaxR;
3758 minr[itrack] = kMinR;
3759 minPointAngle[itrack] = kMinPointAngle;
3761 for (Int_t itrack=0;itrack<nitstracks;itrack++){
3762 AliITStrackMI * original = (AliITStrackMI*)(fOriginal.At(itrack));
3763 Int_t esdindex = original->GetESDtrack()->GetID();
3764 itsmap[esdindex] = itrack;
3767 // create ITS tracks from ESD tracks if not done before
3769 for (Int_t itrack=0;itrack<ntracks;itrack++){
3770 if (itsmap[itrack]>=0) continue;
3771 AliITStrackMI * tpctrack = new AliITStrackMI(*(event->GetTrack(itrack)));
3772 //tpctrack->fD[0] = tpctrack->GetD(GetX(),GetY());
3773 //tpctrack->fD[1] = tpctrack->GetZat(GetX())-GetZ();
3774 tpctrack->GetDZ(GetX(),GetY(),GetZ(),tpctrack->GetDP()); //I.B.
3775 if (tpctrack->GetD(0)<20 && tpctrack->GetD(1)<20){
3776 // tracks which can reach inner part of ITS
3777 // propagate track to outer its volume - with correction for material
3778 CorrectForTPCtoITSDeadZoneMaterial(tpctrack);
3780 itsmap[itrack] = nitstracks;
3781 fOriginal.AddAt(tpctrack,nitstracks);
3785 // fill temporary arrays
3787 for (Int_t itrack=0;itrack<ntracks;itrack++){
3788 AliESDtrack * esdtrack = event->GetTrack(itrack);
3789 Int_t itsindex = itsmap[itrack];
3790 AliITStrackMI *original = (AliITStrackMI*)fOriginal.At(itsmap[itrack]);
3791 if (!original) continue;
3792 AliITStrackMI *bestConst = 0;
3793 AliITStrackMI *bestLong = 0;
3794 AliITStrackMI *best = 0;
3797 TObjArray * array = (TObjArray*) fTrackHypothesys.At(itsindex);
3798 Int_t hentries = (array==0) ? 0 : array->GetEntriesFast();
3799 // Get best track with vertex constrain
3800 for (Int_t ih=0;ih<hentries;ih++){
3801 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
3802 if (!trackh->GetConstrain()) continue;
3803 if (!bestConst) bestConst = trackh;
3804 if (trackh->GetNumberOfClusters()>5.0){
3805 bestConst = trackh; // full track - with minimal chi2
3808 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()) continue;
3812 // Get best long track without vertex constrain and best track without vertex constrain
3813 for (Int_t ih=0;ih<hentries;ih++){
3814 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
3815 if (trackh->GetConstrain()) continue;
3816 if (!best) best = trackh;
3817 if (!bestLong) bestLong = trackh;
3818 if (trackh->GetNumberOfClusters()>5.0){
3819 bestLong = trackh; // full track - with minimal chi2
3822 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()) continue;
3827 bestLong = original;
3829 //I.B. trackat0 = *bestLong;
3830 new (&trackat0) AliITStrackMI(*bestLong);
3831 Double_t xx,yy,zz,alpha;
3832 bestLong->GetGlobalXYZat(bestLong->GetX(),xx,yy,zz);
3833 alpha = TMath::ATan2(yy,xx);
3834 trackat0.Propagate(alpha,0);
3835 // calculate normalized distances to the vertex
3837 Float_t ptfac = (1.+100.*TMath::Abs(trackat0.GetC()));
3838 if ( bestLong->GetNumberOfClusters()>3 ){
3839 dist[itsindex] = trackat0.GetY();
3840 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
3841 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
3842 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
3843 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3845 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<6) normdist[itsindex]*=2.;
3846 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<5) normdist[itsindex]*=2.;
3847 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<4) normdist[itsindex]*=2.;
3849 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<6) normdist[itsindex]*=1.5;
3850 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<5) normdist[itsindex]*=1.5;
3854 if (bestConst&&bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5){
3855 dist[itsindex] = bestConst->GetD(0);
3856 norm[itsindex] = bestConst->GetDnorm(0);
3857 normdist0[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
3858 normdist1[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
3859 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3861 dist[itsindex] = trackat0.GetY();
3862 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
3863 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
3864 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
3865 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3866 if (TMath::Abs(trackat0.GetTgl())>1.05){
3867 if (normdist[itsindex]<3) forbidden[itsindex]=kTRUE;
3868 if (normdist[itsindex]>3) {
3869 minr[itsindex] = TMath::Max(Float_t(40.),minr[itsindex]);
3875 //-----------------------------------------------------------
3876 //Forbid primary track candidates -
3878 //treetr->SetAlias("forbidden0","Tr0.fN<4&&Tr1.fN+Tr1.fNDeadZone>4.5");
3879 //treetr->SetAlias("forbidden1","ND<3&&Tr1.fN+Tr1.fNDeadZone>5.5");
3880 //treetr->SetAlias("forbidden2","ND<2&&Tr1.fClIndex[0]>0&&Tr1.fClIndex[0]>0");
3881 //treetr->SetAlias("forbidden3","ND<1&&Tr1.fClIndex[0]>0");
3882 //treetr->SetAlias("forbidden4","ND<4&&Tr1.fNormChi2[0]<2");
3883 //treetr->SetAlias("forbidden5","ND<5&&Tr1.fNormChi2[0]<1");
3884 //-----------------------------------------------------------
3886 if (bestLong->GetNumberOfClusters()<4 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5) forbidden[itsindex]=kTRUE;
3887 if (normdist[itsindex]<3 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>5.5) forbidden[itsindex]=kTRUE;
3888 if (normdist[itsindex]<2 && bestConst->GetClIndex(0)>0 && bestConst->GetClIndex(1)>0 ) forbidden[itsindex]=kTRUE;
3889 if (normdist[itsindex]<1 && bestConst->GetClIndex(0)>0) forbidden[itsindex]=kTRUE;
3890 if (normdist[itsindex]<4 && bestConst->GetNormChi2(0)<2) forbidden[itsindex]=kTRUE;
3891 if (normdist[itsindex]<5 && bestConst->GetNormChi2(0)<1) forbidden[itsindex]=kTRUE;
3892 if (bestConst->GetNormChi2(0)<2.5) {
3893 minPointAngle[itsindex]= 0.9999;
3894 maxr[itsindex] = 10;
3898 //forbid daughter kink candidates
3900 if (esdtrack->GetKinkIndex(0)>0) forbidden[itsindex] = kTRUE;
3901 Bool_t isElectron = kTRUE;
3902 Bool_t isProton = kTRUE;
3904 esdtrack->GetESDpid(pid);
3905 for (Int_t i=1;i<5;i++){
3906 if (pid[0]<pid[i]) isElectron= kFALSE;
3907 if (pid[4]<pid[i]) isProton= kFALSE;
3910 forbidden[itsindex]=kFALSE;
3911 normdist[itsindex]*=-1;
3914 if (normdist[itsindex]>2) forbidden[itsindex]=kFALSE;
3915 normdist[itsindex]*=-1;
3919 // Causality cuts in TPC volume
3921 if (esdtrack->GetTPCdensity(0,10) >0.6) maxr[itsindex] = TMath::Min(Float_t(110),maxr[itsindex]);
3922 if (esdtrack->GetTPCdensity(10,30)>0.6) maxr[itsindex] = TMath::Min(Float_t(120),maxr[itsindex]);
3923 if (esdtrack->GetTPCdensity(20,40)>0.6) maxr[itsindex] = TMath::Min(Float_t(130),maxr[itsindex]);
3924 if (esdtrack->GetTPCdensity(30,50)>0.6) maxr[itsindex] = TMath::Min(Float_t(140),maxr[itsindex]);
3926 if (esdtrack->GetTPCdensity(0,60)<0.4&&bestLong->GetNumberOfClusters()<3) minr[itsindex]=100;
3932 "Tr1.="<<((bestConst)? bestConst:dummy)<<
3934 "Tr3.="<<&trackat0<<
3936 "Dist="<<dist[itsindex]<<
3937 "ND0="<<normdist0[itsindex]<<
3938 "ND1="<<normdist1[itsindex]<<
3939 "ND="<<normdist[itsindex]<<
3940 "Pz="<<primvertex[2]<<
3941 "Forbid="<<forbidden[itsindex]<<
3945 trackarray.AddAt(best,itsindex);
3946 trackarrayc.AddAt(bestConst,itsindex);
3947 trackarrayl.AddAt(bestLong,itsindex);
3948 new (&helixes[itsindex]) AliHelix(*best);
3953 // first iterration of V0 finder
3955 for (Int_t iesd0=0;iesd0<ntracks;iesd0++){
3956 Int_t itrack0 = itsmap[iesd0];
3957 if (forbidden[itrack0]) continue;
3958 AliITStrackMI * btrack0 = (AliITStrackMI*)trackarray.At(itrack0);
3959 if (!btrack0) continue;
3960 if (btrack0->GetSign()>0) continue;
3961 AliITStrackMI *trackc0 = (AliITStrackMI*)trackarrayc.At(itrack0);
3963 for (Int_t iesd1=0;iesd1<ntracks;iesd1++){
3964 Int_t itrack1 = itsmap[iesd1];
3965 if (forbidden[itrack1]) continue;
3967 AliITStrackMI * btrack1 = (AliITStrackMI*)trackarray.At(itrack1);
3968 if (!btrack1) continue;
3969 if (btrack1->GetSign()<0) continue;
3970 Bool_t isGold = kFALSE;
3971 if (TMath::Abs(TMath::Abs(btrack0->GetLabel())-TMath::Abs(btrack1->GetLabel()))==1){
3974 AliITStrackMI *trackc1 = (AliITStrackMI*)trackarrayc.At(itrack1);
3975 AliHelix &h1 = helixes[itrack0];
3976 AliHelix &h2 = helixes[itrack1];
3978 // find linear distance
3983 Double_t phase[2][2],radius[2];
3984 Int_t points = h1.GetRPHIintersections(h2, phase, radius);
3985 if (points==0) continue;
3986 Double_t delta[2]={1000000,1000000};
3988 h1.ParabolicDCA(h2,phase[0][0],phase[0][1],radius[0],delta[0]);
3990 if (radius[1]<rmin) rmin = radius[1];
3991 h1.ParabolicDCA(h2,phase[1][0],phase[1][1],radius[1],delta[1]);
3993 rmin = TMath::Sqrt(rmin);
3994 Double_t distance = 0;
3995 Double_t radiusC = 0;
3997 if (points==1 || delta[0]<delta[1]){
3998 distance = TMath::Sqrt(delta[0]);
3999 radiusC = TMath::Sqrt(radius[0]);
4001 distance = TMath::Sqrt(delta[1]);
4002 radiusC = TMath::Sqrt(radius[1]);
4005 if (radiusC<TMath::Max(minr[itrack0],minr[itrack1])) continue;
4006 if (radiusC>TMath::Min(maxr[itrack0],maxr[itrack1])) continue;
4007 Float_t maxDist = TMath::Min(kMaxDist,Float_t(kMaxDist0+radiusC*kMaxDist1));
4008 if (distance>maxDist) continue;
4009 Float_t pointAngle = h1.GetPointAngle(h2,phase[iphase],primvertex);
4010 if (pointAngle<TMath::Max(minPointAngle[itrack0],minPointAngle[itrack1])) continue;
4013 // Double_t distance = TestV0(h1,h2,pvertex,rmin);
4015 // if (distance>maxDist) continue;
4016 // if (pvertex->GetRr()<kMinR) continue;
4017 // if (pvertex->GetRr()>kMaxR) continue;
4018 AliITStrackMI * track0=btrack0;
4019 AliITStrackMI * track1=btrack1;
4020 // if (pvertex->GetRr()<3.5){
4022 //use longest tracks inside the pipe
4023 track0 = (AliITStrackMI*)trackarrayl.At(itrack0);
4024 track1 = (AliITStrackMI*)trackarrayl.At(itrack1);
4028 pvertex->SetParamN(*track0);
4029 pvertex->SetParamP(*track1);
4030 pvertex->Update(primvertex);
4031 pvertex->SetClusters(track0->ClIndex(),track1->ClIndex()); // register clusters
4033 if (pvertex->GetRr()<kMinR) continue;
4034 if (pvertex->GetRr()>kMaxR) continue;
4035 if (pvertex->GetV0CosineOfPointingAngle()<kMinPointAngle) continue;
4036 //Bo: if (pvertex->GetDist2()>maxDist) continue;
4037 if (pvertex->GetDcaV0Daughters()>maxDist) continue;
4038 //Bo: pvertex->SetLab(0,track0->GetLabel());
4039 //Bo: pvertex->SetLab(1,track1->GetLabel());
4040 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4041 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4043 AliITStrackMI * htrackc0 = trackc0 ? trackc0:dummy;
4044 AliITStrackMI * htrackc1 = trackc1 ? trackc1:dummy;
4048 TObjArray * array0b = (TObjArray*)fBestHypothesys.At(itrack0);
4049 if (!array0b&&pvertex->GetRr()<40 && TMath::Abs(track0->GetTgl())<1.1) {
4050 fCurrentEsdTrack = itrack0;
4051 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack0),itrack0, kFALSE);
4053 TObjArray * array1b = (TObjArray*)fBestHypothesys.At(itrack1);
4054 if (!array1b&&pvertex->GetRr()<40 && TMath::Abs(track1->GetTgl())<1.1) {
4055 fCurrentEsdTrack = itrack1;
4056 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack1),itrack1, kFALSE);
4059 AliITStrackMI * track0b = (AliITStrackMI*)fOriginal.At(itrack0);
4060 AliITStrackMI * track1b = (AliITStrackMI*)fOriginal.At(itrack1);
4061 AliITStrackMI * track0l = (AliITStrackMI*)fOriginal.At(itrack0);
4062 AliITStrackMI * track1l = (AliITStrackMI*)fOriginal.At(itrack1);
4064 Float_t minchi2before0=16;
4065 Float_t minchi2before1=16;
4066 Float_t minchi2after0 =16;
4067 Float_t minchi2after1 =16;
4068 Double_t xrp[3]; pvertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
4069 Int_t maxLayer = GetNearestLayer(xrp); //I.B.
4071 if (array0b) for (Int_t i=0;i<5;i++){
4072 // best track after vertex
4073 AliITStrackMI * btrack = (AliITStrackMI*)array0b->At(i);
4074 if (!btrack) continue;
4075 if (btrack->GetNumberOfClusters()>track0l->GetNumberOfClusters()) track0l = btrack;
4076 // if (btrack->fX<pvertex->GetRr()-2.-0.5/(0.1+pvertex->GetAnglep()[2])) {
4077 if (btrack->GetX()<pvertex->GetRr()-2.) {
4078 if ( (maxLayer>i+2|| (i==0)) && btrack->GetNumberOfClusters()==(6-i)&&i<3){
4081 if (maxLayer<3){ // take prim vertex as additional measurement
4082 if (normdist[itrack0]>0 && htrackc0){
4083 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack0]*normdist[itrack0],16.);
4085 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack0]*normdist[itrack0]+3.),16.);
4089 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4091 if (!btrack->GetClIndex(ilayer)){
4095 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4096 for (Int_t itrack=0;itrack<4;itrack++){
4097 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack0){
4098 sumchi2+=18.; //shared cluster
4102 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4103 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4107 if (sumchi2<minchi2before0) minchi2before0=sumchi2;
4109 continue; //safety space - Geo manager will give exact layer
4112 minchi2after0 = btrack->GetNormChi2(i);
4115 if (array1b) for (Int_t i=0;i<5;i++){
4116 // best track after vertex
4117 AliITStrackMI * btrack = (AliITStrackMI*)array1b->At(i);
4118 if (!btrack) continue;
4119 if (btrack->GetNumberOfClusters()>track1l->GetNumberOfClusters()) track1l = btrack;
4120 // if (btrack->fX<pvertex->GetRr()-2-0.5/(0.1+pvertex->GetAnglep()[2])){
4121 if (btrack->GetX()<pvertex->GetRr()-2){
4122 if ((maxLayer>i+2 || (i==0))&&btrack->GetNumberOfClusters()==(6-i)&&(i<3)){
4125 if (maxLayer<3){ // take prim vertex as additional measurement
4126 if (normdist[itrack1]>0 && htrackc1){
4127 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack1]*normdist[itrack1],16.);
4129 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack1]*normdist[itrack1]+3.),16.);
4133 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4135 if (!btrack->GetClIndex(ilayer)){
4139 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4140 for (Int_t itrack=0;itrack<4;itrack++){
4141 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack1){
4142 sumchi2+=18.; //shared cluster
4146 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4147 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4151 if (sumchi2<minchi2before1) minchi2before1=sumchi2;
4153 continue; //safety space - Geo manager will give exact layer
4156 minchi2after1 = btrack->GetNormChi2(i);
4160 // position resolution - used for DCA cut
4161 Float_t sigmad = track0b->GetSigmaY2()+track0b->GetSigmaZ2()+track1b->GetSigmaY2()+track1b->GetSigmaZ2()+
4162 (track0b->GetX()-pvertex->GetRr())*(track0b->GetX()-pvertex->GetRr())*(track0b->GetSigmaSnp2()+track0b->GetSigmaTgl2())+
4163 (track1b->GetX()-pvertex->GetRr())*(track1b->GetX()-pvertex->GetRr())*(track1b->GetSigmaSnp2()+track1b->GetSigmaTgl2());
4164 sigmad =TMath::Sqrt(sigmad)+0.04;
4165 if (pvertex->GetRr()>50){
4166 Double_t cov0[15],cov1[15];
4167 track0b->GetESDtrack()->GetInnerExternalCovariance(cov0);
4168 track1b->GetESDtrack()->GetInnerExternalCovariance(cov1);
4169 sigmad = cov0[0]+cov0[2]+cov1[0]+cov1[2]+
4170 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov0[5]+cov0[9])+
4171 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov1[5]+cov1[9]);
4172 sigmad =TMath::Sqrt(sigmad)+0.05;
4176 vertex2.SetParamN(*track0b);
4177 vertex2.SetParamP(*track1b);
4178 vertex2.Update(primvertex);
4179 //Bo: if (vertex2.GetDist2()<=pvertex->GetDist2()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4180 if (vertex2.GetDcaV0Daughters()<=pvertex->GetDcaV0Daughters()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4181 pvertex->SetParamN(*track0b);
4182 pvertex->SetParamP(*track1b);
4183 pvertex->Update(primvertex);
4184 pvertex->SetClusters(track0b->ClIndex(),track1b->ClIndex()); // register clusters
4185 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4186 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4188 pvertex->SetDistSigma(sigmad);
4189 //Bo: pvertex->SetDistNorm(pvertex->GetDist2()/sigmad);
4190 pvertex->SetNormDCAPrim(normdist[itrack0],normdist[itrack1]);
4192 // define likelihhod and causalities
4194 Float_t pa0=1, pa1=1, pb0=0.26, pb1=0.26;
4196 Float_t fnorm0 = normdist[itrack0];
4197 if (fnorm0<0) fnorm0*=-3;
4198 Float_t fnorm1 = normdist[itrack1];
4199 if (fnorm1<0) fnorm1*=-3;
4200 if (pvertex->GetAnglep()[2]>0.1 || (pvertex->GetRr()<10.5)&& pvertex->GetAnglep()[2]>0.05 || pvertex->GetRr()<3){
4201 pb0 = TMath::Exp(-TMath::Min(fnorm0,Float_t(16.))/12.);
4202 pb1 = TMath::Exp(-TMath::Min(fnorm1,Float_t(16.))/12.);
4204 pvertex->SetChi2Before(normdist[itrack0]);
4205 pvertex->SetChi2After(normdist[itrack1]);
4206 pvertex->SetNAfter(0);
4207 pvertex->SetNBefore(0);
4209 pvertex->SetChi2Before(minchi2before0);
4210 pvertex->SetChi2After(minchi2before1);
4211 if (pvertex->GetAnglep()[2]>0.1 || ( pvertex->GetRr()<10.5 && pvertex->GetAnglep()[2]>0.05) || pvertex->GetRr()<3){
4212 pb0 = TMath::Exp(-TMath::Min(minchi2before0,Float_t(16))/12.);
4213 pb1 = TMath::Exp(-TMath::Min(minchi2before1,Float_t(16))/12.);
4215 pvertex->SetNAfter(maxLayer);
4216 pvertex->SetNBefore(maxLayer);
4218 if (pvertex->GetRr()<90){
4219 pa0 *= TMath::Min(track0->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4220 pa1 *= TMath::Min(track1->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4222 if (pvertex->GetRr()<20){
4223 pa0 *= (0.2+TMath::Exp(-TMath::Min(minchi2after0,Float_t(16))/8.))/1.2;
4224 pa1 *= (0.2+TMath::Exp(-TMath::Min(minchi2after1,Float_t(16))/8.))/1.2;
4227 pvertex->SetCausality(pb0,pb1,pa0,pa1);
4229 // Likelihood calculations - apply cuts
4231 Bool_t v0OK = kTRUE;
4232 Float_t p12 = pvertex->GetParamP()->GetParameter()[4]*pvertex->GetParamP()->GetParameter()[4];
4233 p12 += pvertex->GetParamN()->GetParameter()[4]*pvertex->GetParamN()->GetParameter()[4];
4234 p12 = TMath::Sqrt(p12); // "mean" momenta
4235 Float_t sigmap0 = 0.0001+0.001/(0.1+pvertex->GetRr());
4236 Float_t sigmap = 0.5*sigmap0*(0.6+0.4*p12); // "resolution: of point angle - as a function of radius and momenta
4238 Float_t causalityA = (1.0-pvertex->GetCausalityP()[0])*(1.0-pvertex->GetCausalityP()[1]);
4239 Float_t causalityB = TMath::Sqrt(TMath::Min(pvertex->GetCausalityP()[2],Double_t(0.7))*
4240 TMath::Min(pvertex->GetCausalityP()[3],Double_t(0.7)));
4242 //Bo: Float_t likelihood0 = (TMath::Exp(-pvertex->GetDistNorm())+0.1) *(pvertex->GetDist2()<0.5)*(pvertex->GetDistNorm()<5);
4243 Float_t lDistNorm = pvertex->GetDcaV0Daughters()/pvertex->GetDistSigma();
4244 Float_t likelihood0 = (TMath::Exp(-lDistNorm)+0.1) *(pvertex->GetDcaV0Daughters()<0.5)*(lDistNorm<5);
4246 Float_t likelihood1 = TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/sigmap)+
4247 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(4.*sigmap))+
4248 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(8.*sigmap))+
4249 0.1*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/0.01);
4251 if (causalityA<kCausality0Cut) v0OK = kFALSE;
4252 if (TMath::Sqrt(likelihood0*likelihood1)<kLikelihood01Cut) v0OK = kFALSE;
4253 if (likelihood1<kLikelihood1Cut) v0OK = kFALSE;
4254 if (TMath::Power(likelihood0*likelihood1*causalityB,0.33)<kCombinedCut) v0OK = kFALSE;
4259 Bool_t gold = TMath::Abs(TMath::Abs(track0->GetLabel())-TMath::Abs(track1->GetLabel()))==1;
4261 "Tr0.="<<track0<< //best without constrain
4262 "Tr1.="<<track1<< //best without constrain
4263 "Tr0B.="<<track0b<< //best without constrain after vertex
4264 "Tr1B.="<<track1b<< //best without constrain after vertex
4265 "Tr0C.="<<htrackc0<< //best with constrain if exist
4266 "Tr1C.="<<htrackc1<< //best with constrain if exist
4267 "Tr0L.="<<track0l<< //longest best
4268 "Tr1L.="<<track1l<< //longest best
4269 "Esd0.="<<track0->GetESDtrack()<< // esd track0 params
4270 "Esd1.="<<track1->GetESDtrack()<< // esd track1 params
4271 "V0.="<<pvertex<< //vertex properties
4272 "V0b.="<<&vertex2<< //vertex properties at "best" track
4273 "ND0="<<normdist[itrack0]<< //normalize distance for track0
4274 "ND1="<<normdist[itrack1]<< //normalize distance for track1
4276 // "RejectBase="<<rejectBase<< //rejection in First itteration
4282 //if (rejectBase) continue;
4284 pvertex->SetStatus(0);
4285 // if (rejectBase) {
4286 // pvertex->SetStatus(-100);
4288 if (pvertex->GetV0CosineOfPointingAngle()>kMinPointAngle2) {
4289 //Bo: pvertex->SetESDindexes(track0->GetESDtrack()->GetID(),track1->GetESDtrack()->GetID());
4290 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());//Bo: consistency 0 for neg
4291 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());//Bo: consistency 1 for pos
4293 // AliV0vertex vertexjuri(*track0,*track1);
4294 // vertexjuri.SetESDindexes(track0->fESDtrack->GetID(),track1->fESDtrack->GetID());
4295 // event->AddV0(&vertexjuri);
4296 pvertex->SetStatus(100);
4298 pvertex->SetOnFlyStatus(kTRUE);
4299 pvertex->ChangeMassHypothesis(kK0Short);
4300 event->AddV0(pvertex);
4306 // delete temporary arrays
4309 delete[] minPointAngle;
4321 //------------------------------------------------------------------------
4322 void AliITStrackerMI::RefitV02(AliESDEvent *event)
4325 //try to refit V0s in the third path of the reconstruction
4327 TTreeSRedirector &cstream = *fDebugStreamer;
4329 Int_t nv0s = event->GetNumberOfV0s();
4330 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
4332 for (Int_t iv0 = 0; iv0<nv0s;iv0++){
4333 AliV0 * v0mi = (AliV0*)event->GetV0(iv0);
4334 if (!v0mi) continue;
4335 Int_t itrack0 = v0mi->GetIndex(0);
4336 Int_t itrack1 = v0mi->GetIndex(1);
4337 AliESDtrack *esd0 = event->GetTrack(itrack0);
4338 AliESDtrack *esd1 = event->GetTrack(itrack1);
4339 if (!esd0||!esd1) continue;
4340 AliITStrackMI tpc0(*esd0);
4341 AliITStrackMI tpc1(*esd1);
4342 Double_t x,y,z; v0mi->GetXYZ(x,y,z); //I.B.
4343 Double_t alpha =TMath::ATan2(y,x); //I.B.
4344 if (v0mi->GetRr()>85){
4345 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4346 v0temp.SetParamN(tpc0);
4347 v0temp.SetParamP(tpc1);
4348 v0temp.Update(primvertex);
4349 if (kFALSE) cstream<<"Refit"<<
4351 "V0refit.="<<&v0temp<<
4355 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4356 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4357 v0mi->SetParamN(tpc0);
4358 v0mi->SetParamP(tpc1);
4359 v0mi->Update(primvertex);
4364 if (v0mi->GetRr()>35){
4365 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4366 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4367 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4368 v0temp.SetParamN(tpc0);
4369 v0temp.SetParamP(tpc1);
4370 v0temp.Update(primvertex);
4371 if (kFALSE) cstream<<"Refit"<<
4373 "V0refit.="<<&v0temp<<
4377 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4378 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4379 v0mi->SetParamN(tpc0);
4380 v0mi->SetParamP(tpc1);
4381 v0mi->Update(primvertex);
4386 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4387 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4388 // if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4389 if (RefitAt(v0mi->GetRr(),&tpc0, v0mi->GetClusters(0)) && RefitAt(v0mi->GetRr(),&tpc1, v0mi->GetClusters(1))){
4390 v0temp.SetParamN(tpc0);
4391 v0temp.SetParamP(tpc1);
4392 v0temp.Update(primvertex);
4393 if (kFALSE) cstream<<"Refit"<<
4395 "V0refit.="<<&v0temp<<
4399 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4400 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4401 v0mi->SetParamN(tpc0);
4402 v0mi->SetParamP(tpc1);
4403 v0mi->Update(primvertex);
4408 //------------------------------------------------------------------------
4409 void AliITStrackerMI::BuildMaterialLUT(TString material) {
4410 //--------------------------------------------------------------------
4411 // Fill a look-up table with mean material
4412 //--------------------------------------------------------------------
4416 Double_t point1[3],point2[3];
4417 Double_t phi,cosphi,sinphi,z;
4418 // 0-5 layers, 6 pipe, 7-8 shields
4419 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 7.5,25.0};
4420 Double_t rmax[9]={ 5.5, 7.3,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
4422 Int_t ifirst=0,ilast=0;
4423 if(material.Contains("Pipe")) {
4425 } else if(material.Contains("Shields")) {
4427 } else if(material.Contains("Layers")) {
4430 Error("BuildMaterialLUT","Wrong layer name\n");
4433 for(Int_t imat=ifirst; imat<=ilast; imat++) {
4434 Double_t param[5]={0.,0.,0.,0.,0.};
4435 for (Int_t i=0; i<n; i++) {
4436 phi = 2.*TMath::Pi()*gRandom->Rndm();
4437 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
4438 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
4439 point1[0] = rmin[imat]*cosphi;
4440 point1[1] = rmin[imat]*sinphi;
4442 point2[0] = rmax[imat]*cosphi;
4443 point2[1] = rmax[imat]*sinphi;
4445 AliTracker::MeanMaterialBudget(point1,point2,mparam);
4446 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
4448 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
4450 fxOverX0Layer[imat] = param[1];
4451 fxTimesRhoLayer[imat] = param[0]*param[4];
4452 } else if(imat==6) {
4453 fxOverX0Pipe = param[1];
4454 fxTimesRhoPipe = param[0]*param[4];
4455 } else if(imat==7) {
4456 fxOverX0Shield[0] = param[1];
4457 fxTimesRhoShield[0] = param[0]*param[4];
4458 } else if(imat==8) {
4459 fxOverX0Shield[1] = param[1];
4460 fxTimesRhoShield[1] = param[0]*param[4];
4464 printf("%s\n",material.Data());
4465 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
4466 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
4467 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
4468 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
4469 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
4470 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
4471 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
4472 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
4473 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
4477 //------------------------------------------------------------------------
4478 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
4479 TString direction) {
4480 //-------------------------------------------------------------------
4481 // Propagate beyond beam pipe and correct for material
4482 // (material budget in different ways according to fUseTGeo value)
4483 //-------------------------------------------------------------------
4485 // Define budget mode:
4486 // 0: material from AliITSRecoParam (hard coded)
4487 // 1: material from TGeo (on the fly)
4488 // 2: material from lut
4489 // 3: material from TGeo (same for all hypotheses)
4502 if(fTrackingPhase.Contains("Clusters2Tracks"))
4503 { mode=3; } else { mode=1; }
4506 if(fTrackingPhase.Contains("Clusters2Tracks"))
4507 { mode=3; } else { mode=2; }
4513 if(fTrackingPhase.Contains("Default")) mode=0;
4515 Int_t index=fCurrentEsdTrack;
4517 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4518 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4519 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4521 Double_t xOverX0,x0,lengthTimesMeanDensity;
4522 Bool_t anglecorr=kTRUE;
4526 xOverX0 = AliITSRecoParam::GetdPipe();
4527 x0 = AliITSRecoParam::GetX0Be();
4528 lengthTimesMeanDensity = xOverX0*x0;
4531 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4535 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4536 xOverX0 = fxOverX0Pipe;
4537 lengthTimesMeanDensity = fxTimesRhoPipe;
4540 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4541 if(fxOverX0PipeTrks[index]<0) {
4542 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4543 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4544 (1.-t->GetSnp()*t->GetSnp()));
4545 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4546 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4549 xOverX0 = fxOverX0PipeTrks[index];
4550 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4554 lengthTimesMeanDensity *= dir;
4556 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4557 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4561 //------------------------------------------------------------------------
4562 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4564 TString direction) {
4565 //-------------------------------------------------------------------
4566 // Propagate beyond SPD or SDD shield and correct for material
4567 // (material budget in different ways according to fUseTGeo value)
4568 //-------------------------------------------------------------------
4570 // Define budget mode:
4571 // 0: material from AliITSRecoParam (hard coded)
4572 // 1: material from TGeo (on the fly)
4573 // 2: material from lut
4574 // 3: material from TGeo (same for all hypotheses)
4587 if(fTrackingPhase.Contains("Clusters2Tracks"))
4588 { mode=3; } else { mode=1; }
4591 if(fTrackingPhase.Contains("Clusters2Tracks"))
4592 { mode=3; } else { mode=2; }
4598 if(fTrackingPhase.Contains("Default")) mode=0;
4600 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4602 Int_t shieldindex=0;
4603 if (shield.Contains("SDD")) { // SDDouter
4604 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4606 } else if (shield.Contains("SPD")) { // SPDouter
4607 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4610 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4613 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4615 Int_t index=2*fCurrentEsdTrack+shieldindex;
4617 Double_t xOverX0,x0,lengthTimesMeanDensity;
4618 Bool_t anglecorr=kTRUE;
4622 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4623 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4624 lengthTimesMeanDensity = xOverX0*x0;
4627 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4631 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4632 xOverX0 = fxOverX0Shield[shieldindex];
4633 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4636 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4637 if(fxOverX0ShieldTrks[index]<0) {
4638 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4639 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4640 (1.-t->GetSnp()*t->GetSnp()));
4641 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4642 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4645 xOverX0 = fxOverX0ShieldTrks[index];
4646 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4650 lengthTimesMeanDensity *= dir;
4652 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4653 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4657 //------------------------------------------------------------------------
4658 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4660 Double_t oldGlobXYZ[3],
4661 TString direction) {
4662 //-------------------------------------------------------------------
4663 // Propagate beyond layer and correct for material
4664 // (material budget in different ways according to fUseTGeo value)
4665 //-------------------------------------------------------------------
4667 // Define budget mode:
4668 // 0: material from AliITSRecoParam (hard coded)
4669 // 1: material from TGeo (on the fly)
4670 // 2: material from lut
4671 // 3: material from TGeo (same for all hypotheses)
4684 if(fTrackingPhase.Contains("Clusters2Tracks"))
4685 { mode=3; } else { mode=1; }
4688 if(fTrackingPhase.Contains("Clusters2Tracks"))
4689 { mode=3; } else { mode=2; }
4695 if(fTrackingPhase.Contains("Default")) mode=0;
4697 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4699 Double_t r=fgLayers[layerindex].GetR();
4700 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4702 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4703 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4705 Int_t index=6*fCurrentEsdTrack+layerindex;
4707 // Bring the track beyond the material
4708 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4709 Double_t globXYZ[3];
4712 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4714 Bool_t anglecorr=kTRUE;
4718 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4719 lengthTimesMeanDensity = xOverX0*x0;
4722 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4723 if(mparam[1]>900000) return 0;
4725 lengthTimesMeanDensity=mparam[0]*mparam[4];
4729 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4730 xOverX0 = fxOverX0Layer[layerindex];
4731 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4734 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4735 if(fxOverX0LayerTrks[index]<0) {
4736 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4737 if(mparam[1]>900000) return 0;
4738 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4739 (1.-t->GetSnp()*t->GetSnp()));
4740 xOverX0=mparam[1]/angle;
4741 lengthTimesMeanDensity=mparam[0]*mparam[4]/angle;
4742 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0);
4743 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity);
4745 xOverX0 = fxOverX0LayerTrks[index];
4746 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4750 lengthTimesMeanDensity *= dir;
4752 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4756 //------------------------------------------------------------------------
4757 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4758 //-----------------------------------------------------------------
4759 // Initialize LUT for storing material for each prolonged track
4760 //-----------------------------------------------------------------
4761 fxOverX0PipeTrks = new Float_t[ntracks];
4762 fxTimesRhoPipeTrks = new Float_t[ntracks];
4763 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4764 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4765 fxOverX0LayerTrks = new Float_t[ntracks*6];
4766 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4768 for(Int_t i=0; i<ntracks; i++) {
4769 fxOverX0PipeTrks[i] = -1.;
4770 fxTimesRhoPipeTrks[i] = -1.;
4772 for(Int_t j=0; j<ntracks*2; j++) {
4773 fxOverX0ShieldTrks[j] = -1.;
4774 fxTimesRhoShieldTrks[j] = -1.;
4776 for(Int_t k=0; k<ntracks*6; k++) {
4777 fxOverX0LayerTrks[k] = -1.;
4778 fxTimesRhoLayerTrks[k] = -1.;
4785 //------------------------------------------------------------------------
4786 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4787 //-----------------------------------------------------------------
4788 // Delete LUT for storing material for each prolonged track
4789 //-----------------------------------------------------------------
4790 if(fxOverX0PipeTrks) {
4791 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4793 if(fxOverX0ShieldTrks) {
4794 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4797 if(fxOverX0LayerTrks) {
4798 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4800 if(fxTimesRhoPipeTrks) {
4801 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4803 if(fxTimesRhoShieldTrks) {
4804 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4806 if(fxTimesRhoLayerTrks) {
4807 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4811 //------------------------------------------------------------------------
4812 Int_t AliITStrackerMI::CheckSkipLayer(AliITStrackMI *track,
4813 Int_t ilayer,Int_t idet) const {
4814 //-----------------------------------------------------------------
4815 // This method is used to decide whether to allow a prolongation
4816 // without clusters, because we want to skip the layer.
4817 // In this case the return value is > 0:
4818 // return 1: the user requested to skip a layer
4819 // return 2: track outside z acceptance of SSD/SDD and will cross both SPD
4820 //-----------------------------------------------------------------
4822 if (AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) return 1;
4824 if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4825 // check if track will cross SPD outer layer
4826 Double_t phiAtSPD2,zAtSPD2;
4827 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4828 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4834 //------------------------------------------------------------------------
4835 Int_t AliITStrackerMI::CheckDeadZone(/*AliITStrackMI *track,*/
4836 Int_t ilayer,Int_t idet,
4837 Double_t zmin,Double_t zmax/*,Double_t ymin,Double_t ymax*/) const {
4838 //-----------------------------------------------------------------
4839 // This method is used to decide whether to allow a prolongation
4840 // without clusters, because there is a dead zone in the road.
4841 // In this case the return value is > 0:
4842 // return 1: dead zone at z=0,+-7cm in SPD
4843 // return 2: dead area from the OCDB // NOT YET IMPLEMENTED
4844 //-----------------------------------------------------------------
4846 // check dead zones at z=0,+-7cm in the SPD
4847 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4848 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4849 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4850 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4851 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4852 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4853 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4854 for (Int_t i=0; i<3; i++)
4855 if (zmin<zmaxdead[i] && zmax>zmindead[i]) return 1;
4858 // check dead zones from OCDB
4859 if (!AliITSReconstructor::GetRecoParam()->GetUseDeadZonesFromOCDB()) return 0;
4861 if(idet<0) return 0;
4863 // look in OCDB (only entire dead modules for the moment)
4864 if (ilayer==0 || ilayer==1) { // SPD
4865 AliCDBEntry* cdbEntry = AliCDBManager::Instance()->Get("ITS/Calib/SPDDead");
4867 Error("CheckDeadZone","Cannot get CDB entry for SPD\n");
4870 TObjArray* spdEntry = (TObjArray*)cdbEntry->GetObject();
4872 Error("CheckDeadZone","Cannot get CDB entry for SPD\n");
4875 if(ilayer==1) idet += AliITSgeomTGeo::GetNLadders(1)*AliITSgeomTGeo::GetNDetectors(1);
4876 //printf("SPD det: %d\n",idet);
4877 AliITSCalibrationSPD *calibSPD = (AliITSCalibrationSPD*)spdEntry->At(idet);
4878 if (calibSPD->IsBad()) return 2;
4879 } else if (ilayer==2 || ilayer==3) { // SDD
4880 AliCDBEntry* cdbEntry = AliCDBManager::Instance()->Get("ITS/Calib/CalibSDD");
4882 Error("CheckDeadZone","Cannot get CDB entry for SDD\n");
4885 TObjArray* sddEntry = (TObjArray*)cdbEntry->GetObject();
4887 Error("CheckDeadZone","Cannot get CDB entry for SDD\n");
4890 if(ilayer==3) idet += AliITSgeomTGeo::GetNLadders(3)*AliITSgeomTGeo::GetNDetectors(3);
4891 //printf("SDD det: %d\n",idet);
4892 AliITSCalibrationSDD *calibSDD = (AliITSCalibrationSDD*)sddEntry->At(idet);
4893 if (calibSDD->IsDead()) return 2;
4894 } else if (ilayer==4 || ilayer==5) { // SSD
4896 Error("CheckDeadZone","Wrong layer number\n");
4897 if(ilayer==5) idet += AliITSgeomTGeo::GetNLadders(5)*AliITSgeomTGeo::GetNDetectors(5);
4903 //------------------------------------------------------------------------
4904 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4905 AliITStrackMI *track,
4906 Float_t &xloc,Float_t &zloc) const {
4907 //-----------------------------------------------------------------
4908 // Gives position of track in local module ref. frame
4909 //-----------------------------------------------------------------
4914 if(idet<0) return kFALSE;
4916 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4918 Int_t lad = Int_t(idet/ndet) + 1;
4920 Int_t det = idet - (lad-1)*ndet + 1;
4922 Double_t xyzGlob[3],xyzLoc[3];
4924 track->GetXYZ(xyzGlob);
4926 AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc);
4928 xloc = (Float_t)xyzLoc[0];
4929 zloc = (Float_t)xyzLoc[2];
4933 //------------------------------------------------------------------------
4934 Bool_t AliITStrackerMI::IsOKForPlaneEff(AliITStrackMI* track, Int_t ilayer) const {
4935 // Method still to be implemented:
4937 // it will apply a pre-selection to obtain good quality tracks.
4938 // Here also you will have the possibility to put a control on the
4939 // impact point of the track on the basic block, in order to exclude border regions
4940 // this will be done by calling a proper method of the AliITSPlaneEff class.
4942 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4943 // output: Bool_t -> kTRUE 2f usable track, kFALSE if not usable.
4945 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4946 AliITSlayer &layer=fgLayers[ilayer];
4947 Double_t r=layer.GetR();
4948 //AliITStrackV2 tmp(*track);
4949 AliITStrackMI tmp(*track);
4953 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4954 Int_t idet=layer.FindDetectorIndex(phi,z);
4955 if(idet<0) { AliInfo(Form("cannot find detector"));
4958 // here check if it has good Chi Square.
4960 //propagate to the intersection with the detector plane
4961 const AliITSdetector &det=layer.GetDetector(idet);
4962 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4966 LocalModuleCoord(ilayer,idet,&tmp,locx,locz);
4967 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4968 if(key>fPlaneEff->Nblock()) return kFALSE;
4969 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4970 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4971 // transform Local boundaries of the basic block into
4972 // Global (i.e. ALICE, not tracking reference) coordinate
4974 Double_t a1[3]={blockXmn,0.,blockZmn};
4975 Double_t a2[3]={blockXmx,0.,blockZmn};
4976 Double_t a3[3]={blockXmn,0.,blockZmx};
4977 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4978 Int_t lad = Int_t(idet/ndet) + 1;
4979 Int_t hdet = idet - (lad-1)*ndet + 1;
4980 Double_t xyzGlob[3];
4981 AliITSgeomTGeo::LocalToGlobal(ilayer+1,lad,hdet,a1,a1);
4982 AliITSgeomTGeo::LocalToGlobal(ilayer+1,lad,hdet,a2,a2);
4983 AliITSgeomTGeo::LocalToGlobal(ilayer+1,lad,hdet,a3,a3);
4984 Double_t gBlockYmn,gBlockYmx,gBlockZmn,gBlockZmx;
4985 if(a1[1]>a2[1]) {gBlockYmn=a2[1]; gBlockYmx=a1[1];}
4986 else {gBlockYmn=a1[1]; gBlockYmx=a2[1];}
4987 if(a2[2]>a3[2]) {gBlockZmn=a3[2]; gBlockZmx=a2[2];}
4988 else {gBlockZmn=a2[2]; gBlockZmx=a3[2];}
4989 AliDebug(2,Form("Boundaries in Global system Ymin=%f, Ymax=%f, Zmin=%f, Zmax=%f",
4990 gBlockYmn,gBlockYmx,gBlockZmn,gBlockZmx));
4993 // DEFINITION OF SEARCH ROAD FOR accepting a track
4995 //For the time being they are hard-wired, later on from AliITSRecoParam
4996 Double_t dz=4.*TMath::Sqrt(tmp.GetSigmaZ2()); // those are precisions in the tracking reference system
4997 Double_t dy=4.*TMath::Sqrt(tmp.GetSigmaY2()); // dy needs to be reduced (it is max now) if you do
4998 // comparison in Global Reference system
5000 Float_t gdy=dy*TMath::Abs(TMath::Cos(tmp.GetAlpha()));
5002 // exclude tracks at boundary between detectors
5003 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
5004 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
5005 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
5006 tmp.GetXYZ(xyzGlob);
5007 AliDebug(2,Form("Global: track impact x=%f, y=%f, z=%f",xyzGlob[0],xyzGlob[1],xyzGlob[2]));
5008 //AliInfo(Form("TEST GLOBAL track y = %f, z=%f",tmp.GetY(),tmp.GetZ()));
5009 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dy,dz));
5010 AliDebug(2,Form("Search Road. Global: Gdy=%f , Gdz=%f",gdy,gdz));
5011 if ( (xyzGlob[1]-gdy < gBlockYmn+boundaryWidth) ||
5012 (xyzGlob[1]+gdy > gBlockYmx-boundaryWidth) ||
5013 (xyzGlob[2]-gdz < gBlockZmn+boundaryWidth) ||
5014 (xyzGlob[2]+gdz > gBlockZmx-boundaryWidth) ) return kFALSE;
5018 //------------------------------------------------------------------------
5019 void AliITStrackerMI::UseTrackForPlaneEff(AliITStrackMI* track, Int_t ilayer) {
5021 // This Method has to be optimized! For the time-being it uses the same criteria
5022 // as those used in the search of extra clusters for overlapping modules.
5024 // Method Purpose: estabilish whether a track has produced a recpoint or not
5025 // in the layer under study (For Plane efficiency)
5027 // inputs: AliITStrackMI* track (pointer to a usable track)
5029 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
5030 // traversed by this very track. In details:
5031 // - if a cluster can be associated to the track then call
5032 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
5033 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
5036 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
5037 AliITSlayer &layer=fgLayers[ilayer];
5038 Double_t r=layer.GetR();
5039 //AliITStrackV2 tmp(*track);
5040 AliITStrackMI tmp(*track);
5044 if (!tmp.GetPhiZat(r,phi,z)) return;
5045 Int_t idet=layer.FindDetectorIndex(phi,z);
5047 if(idet<0) { AliInfo(Form("cannot find detector"));
5050 //Double_t trackGlobXYZ1[3];
5051 //tmp.GetXYZ(trackGlobXYZ1);
5053 //propagate to the intersection with the detector plane
5054 const AliITSdetector &det=layer.GetDetector(idet);
5055 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
5057 //Float_t xloc,zloc;
5060 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
5062 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
5063 TMath::Sqrt(tmp.GetSigmaZ2() +
5064 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5065 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5066 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
5067 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
5068 TMath::Sqrt(tmp.GetSigmaY2() +
5069 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5070 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5071 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
5073 // road in global (rphi,z) [i.e. in tracking ref. system]
5074 Double_t zmin = tmp.GetZ() - dz;
5075 Double_t zmax = tmp.GetZ() + dz;
5076 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
5077 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
5079 // select clusters in road
5080 layer.SelectClusters(zmin,zmax,ymin,ymax);
5082 // Define criteria for track-cluster association
5083 Double_t msz = tmp.GetSigmaZ2() +
5084 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5085 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5086 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
5087 Double_t msy = tmp.GetSigmaY2() +
5088 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5089 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5090 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
5091 if (tmp.GetConstrain()) {
5092 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
5093 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
5095 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
5096 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
5098 msz = 1./msz; // 1/RoadZ^2
5099 msy = 1./msy; // 1/RoadY^2
5102 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
5104 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
5105 //Double_t tolerance=0.2;
5106 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
5107 idetc = cl->GetDetectorIndex();
5108 if(idet!=idetc) continue;
5109 //Int_t ilay = cl->GetLayer();
5111 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
5112 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
5114 Double_t chi2=tmp.GetPredictedChi2(cl);
5115 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
5119 LocalModuleCoord(ilayer,idet,&tmp,locx,locz);
5121 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
5122 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5123 if(key>fPlaneEff->Nblock()) return;
5124 Bool_t found=kFALSE;
5127 while ((cl=layer.GetNextCluster(clidx))!=0) {
5128 idetc = cl->GetDetectorIndex();
5129 if(idet!=idetc) continue;
5130 // here real control to see whether the cluster can be associated to the track.
5131 // cluster not associated to track
5132 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
5133 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
5134 // calculate track-clusters chi2
5135 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
5136 // in particular, the error associated to the cluster
5137 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
5139 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
5141 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
5142 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
5143 // track->SetExtraModule(ilayer,idetExtra);
5145 if(!fPlaneEff->UpDatePlaneEff(found,key))
5146 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
5147 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
5148 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
5149 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
5150 Int_t cltype[2]={-999,-999};
5151 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
5152 Int_t lad = Int_t(idet/ndet) + 1;
5153 Int_t hdet = idet - (lad-1)*ndet + 1;
5154 Double_t xyzGlob[3],xyzLoc[3],cv[21],exyzLoc[3],exyzGlob[3];
5155 if(tmp.GetXYZ(xyzGlob)) {
5156 if (AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,hdet,xyzGlob,xyzLoc)) {
5161 if(tmp.GetCovarianceXYZPxPyPz(cv)) {
5162 exyzGlob[0]=TMath::Sqrt(cv[0]);
5163 exyzGlob[1]=TMath::Sqrt(cv[2]);
5164 exyzGlob[2]=TMath::Sqrt(cv[5]);
5165 if (AliITSgeomTGeo::GlobalToLocalVect(AliITSgeomTGeo::GetModuleIndex(ilayer+1,lad,hdet),exyzGlob,exyzLoc)) {
5166 tr[2]=TMath::Abs(exyzLoc[0]);
5167 tr[3]=TMath::Abs(exyzLoc[2]);
5171 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
5172 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
5173 cltype[0]=layer.GetCluster(ci)->GetNy();
5174 cltype[1]=layer.GetCluster(ci)->GetNz();
5176 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
5177 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
5178 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
5179 // It is computed properly by calling the method
5180 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
5182 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
5183 //if (tmp.PropagateTo(x,0.,0.)) {
5184 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
5185 AliCluster c(*layer.GetCluster(ci));
5186 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
5187 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
5189 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
5190 if (c.GetGlobalCov(cov))
5192 exyzGlob[0]=TMath::Sqrt(cov[0]);
5193 exyzGlob[1]=TMath::Sqrt(cov[3]);
5194 exyzGlob[2]=TMath::Sqrt(cov[5]);
5195 if (AliITSgeomTGeo::GlobalToLocalVect(AliITSgeomTGeo::GetModuleIndex(ilayer+1,lad,hdet),exyzGlob,exyzLoc)) {
5196 clu[2]=TMath::Abs(exyzLoc[0]);
5197 clu[3]=TMath::Abs(exyzLoc[2]);
5202 fPlaneEff->FillHistos(key,found,tr,clu,cltype);