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 "AliITStrackerMI.h"
43 #include "AliITSReconstructor.h"
44 #include "AliTrackPointArray.h"
45 #include "AliAlignObj.h"
46 #include "AliITSClusterParam.h"
48 ClassImp(AliITStrackerMI)
50 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
52 AliITStrackerMI::AliITStrackerMI():AliTracker(),
62 fLastLayerToTrackTo(0),
65 fTrackingPhase("Default"),
71 fxTimesRhoPipeTrks(0),
72 fxOverX0ShieldTrks(0),
73 fxTimesRhoShieldTrks(0),
75 fxTimesRhoLayerTrks(0),
79 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
80 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
81 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
83 //------------------------------------------------------------------------
84 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
85 fI(AliITSgeomTGeo::GetNLayers()),
94 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
97 fTrackingPhase("Default"),
103 fxTimesRhoPipeTrks(0),
104 fxOverX0ShieldTrks(0),
105 fxTimesRhoShieldTrks(0),
106 fxOverX0LayerTrks(0),
107 fxTimesRhoLayerTrks(0),
109 //--------------------------------------------------------------------
110 //This is the AliITStrackerMI constructor
111 //--------------------------------------------------------------------
113 AliWarning("\"geom\" is actually a dummy argument !");
119 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
120 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
121 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
123 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
124 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
125 Double_t poff=TMath::ATan2(y,x);
127 Double_t r=TMath::Sqrt(x*x + y*y);
129 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
130 r += TMath::Sqrt(x*x + y*y);
131 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
132 r += TMath::Sqrt(x*x + y*y);
133 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
134 r += TMath::Sqrt(x*x + y*y);
137 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
139 for (Int_t j=1; j<nlad+1; j++) {
140 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
141 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
142 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
144 Double_t txyz[3]={0.}, xyz[3]={0.};
145 m.LocalToMaster(txyz,xyz);
146 Double_t r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
147 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
149 if (phi<0) phi+=TMath::TwoPi();
150 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
152 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
153 new(&det) AliITSdetector(r,phi);
159 fI=AliITSgeomTGeo::GetNLayers();
162 fConstraint[0]=1; fConstraint[1]=0;
164 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
165 AliITSReconstructor::GetRecoParam()->GetYVdef(),
166 AliITSReconstructor::GetRecoParam()->GetZVdef()};
167 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
168 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
169 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
170 SetVertex(xyzVtx,ersVtx);
172 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=AliITSRecoParam::GetLayersNotToSkip(i);
173 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
174 for (Int_t i=0;i<100000;i++){
175 fBestTrackIndex[i]=0;
178 // store positions of centre of SPD modules (in z)
180 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
181 fSPDdetzcentre[0] = tr[2];
182 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
183 fSPDdetzcentre[1] = tr[2];
184 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
185 fSPDdetzcentre[2] = tr[2];
186 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
187 fSPDdetzcentre[3] = tr[2];
189 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
191 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
192 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
194 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
197 //------------------------------------------------------------------------
198 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
200 fBestTrack(tracker.fBestTrack),
201 fTrackToFollow(tracker.fTrackToFollow),
202 fTrackHypothesys(tracker.fTrackHypothesys),
203 fBestHypothesys(tracker.fBestHypothesys),
204 fOriginal(tracker.fOriginal),
205 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
206 fPass(tracker.fPass),
207 fAfterV0(tracker.fAfterV0),
208 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
209 fCoefficients(tracker.fCoefficients),
211 fTrackingPhase(tracker.fTrackingPhase),
212 fUseTGeo(tracker.fUseTGeo),
213 fNtracks(tracker.fNtracks),
214 fxOverX0Pipe(tracker.fxOverX0Pipe),
215 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
217 fxTimesRhoPipeTrks(0),
218 fxOverX0ShieldTrks(0),
219 fxTimesRhoShieldTrks(0),
220 fxOverX0LayerTrks(0),
221 fxTimesRhoLayerTrks(0),
222 fDebugStreamer(tracker.fDebugStreamer){
226 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
229 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
230 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
233 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
234 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
237 //------------------------------------------------------------------------
238 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
239 //Assignment operator
240 this->~AliITStrackerMI();
241 new(this) AliITStrackerMI(tracker);
244 //------------------------------------------------------------------------
245 AliITStrackerMI::~AliITStrackerMI()
250 if (fCoefficients) delete [] fCoefficients;
251 DeleteTrksMaterialLUT();
252 if (fDebugStreamer) {
253 //fDebugStreamer->Close();
254 delete fDebugStreamer;
257 //------------------------------------------------------------------------
258 void AliITStrackerMI::SetLayersNotToSkip(Int_t *l) {
259 //--------------------------------------------------------------------
260 //This function set masks of the layers which must be not skipped
261 //--------------------------------------------------------------------
262 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=l[i];
264 //------------------------------------------------------------------------
265 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
266 //--------------------------------------------------------------------
267 //This function loads ITS clusters
268 //--------------------------------------------------------------------
269 TBranch *branch=cTree->GetBranch("ITSRecPoints");
271 Error("LoadClusters"," can't get the branch !\n");
275 TClonesArray dummy("AliITSRecPoint",10000), *clusters=&dummy;
276 branch->SetAddress(&clusters);
280 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
281 Int_t ndet=fgLayers[i].GetNdetectors();
282 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
283 for (; j<jmax; j++) {
284 if (!cTree->GetEvent(j)) continue;
285 Int_t ncl=clusters->GetEntriesFast();
286 SignDeltas(clusters,GetZ());
289 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
290 detector=c->GetDetectorIndex();
292 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
294 fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
297 // add dead zone "virtual" cluster in SPD, if there is a cluster within
298 // zwindow cm from the dead zone
299 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
300 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
301 Int_t lab[4] = {0,0,0,detector};
302 Int_t info[3] = {0,0,i};
304 Float_t hit[5] = {xdead,
306 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
307 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
309 Bool_t local = kTRUE;
310 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
311 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
312 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
313 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
314 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
315 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
316 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
317 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
318 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
319 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
320 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
321 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
322 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
323 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
324 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
325 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
326 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
327 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
328 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
334 fgLayers[i].ResetRoad(); //road defined by the cluster density
335 fgLayers[i].SortClusters();
340 //------------------------------------------------------------------------
341 void AliITStrackerMI::UnloadClusters() {
342 //--------------------------------------------------------------------
343 //This function unloads ITS clusters
344 //--------------------------------------------------------------------
345 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
347 //------------------------------------------------------------------------
348 static Int_t CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
349 //--------------------------------------------------------------------
350 // Correction for the material between the TPC and the ITS
351 //--------------------------------------------------------------------
352 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
353 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
354 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
355 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
356 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
357 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
358 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
359 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
361 Error("CorrectForTPCtoITSDeadZoneMaterial","Track is already in the dead zone !");
367 //------------------------------------------------------------------------
368 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
369 //--------------------------------------------------------------------
370 // This functions reconstructs ITS tracks
371 // The clusters must be already loaded !
372 //--------------------------------------------------------------------
373 fTrackingPhase="Clusters2Tracks";
375 TObjArray itsTracks(15000);
377 fEsd = event; // store pointer to the esd
379 // temporary (for cosmics)
380 if(event->GetVertex()) {
381 TString title = event->GetVertex()->GetTitle();
382 if(title.Contains("cosmics")) {
383 Double_t xyz[3]={GetX(),GetY(),GetZ()};
384 Double_t exyz[3]={0.1,0.1,0.1};
390 {/* Read ESD tracks */
391 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
392 Int_t nentr=event->GetNumberOfTracks();
393 Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
395 AliESDtrack *esd=event->GetTrack(nentr);
397 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
398 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
399 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
400 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
403 t=new AliITStrackMI(*esd);
404 } catch (const Char_t *msg) {
405 //Warning("Clusters2Tracks",msg);
409 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
410 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
411 // look at the ESD mass hypothesys !
412 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
414 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
416 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
417 //track - can be V0 according to TPC
419 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
423 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
427 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
431 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
436 t->SetReconstructed(kFALSE);
437 itsTracks.AddLast(t);
438 fOriginal.AddLast(t);
440 } /* End Read ESD tracks */
444 Int_t nentr=itsTracks.GetEntriesFast();
445 fTrackHypothesys.Expand(nentr);
446 fBestHypothesys.Expand(nentr);
447 MakeCoefficients(nentr);
448 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(nentr);
450 // THE TWO TRACKING PASSES
451 for (fPass=0; fPass<2; fPass++) {
452 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
453 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
454 //cerr<<fPass<<" "<<fCurrentEsdTrack<<'\n';
455 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
456 if (t==0) continue; //this track has been already tracked
457 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
458 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
459 if (fConstraint[fPass]) {
460 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
461 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
464 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
466 ResetTrackToFollow(*t);
468 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
470 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
472 AliITStrackMI * besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
473 if (!besttrack) continue;
474 besttrack->SetLabel(tpcLabel);
475 // besttrack->CookdEdx();
477 besttrack->SetFakeRatio(1.);
478 CookLabel(besttrack,0.); //For comparison only
479 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
481 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
483 t->SetReconstructed(kTRUE);
486 GetBestHypothesysMIP(itsTracks);
487 } // end loop on the two tracking passes
489 //GetBestHypothesysMIP(itsTracks);
490 if(event->GetNumberOfV0s()>0) UpdateTPCV0(event);
491 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) FindV02(event);
493 //GetBestHypothesysMIP(itsTracks);
497 Int_t entries = fTrackHypothesys.GetEntriesFast();
498 for (Int_t ientry=0; ientry<entries; ientry++) {
499 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
500 if (array) array->Delete();
501 delete fTrackHypothesys.RemoveAt(ientry);
504 fTrackHypothesys.Delete();
505 fBestHypothesys.Delete();
507 delete [] fCoefficients;
509 DeleteTrksMaterialLUT();
511 Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
513 fTrackingPhase="Default";
517 //------------------------------------------------------------------------
518 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
519 //--------------------------------------------------------------------
520 // This functions propagates reconstructed ITS tracks back
521 // The clusters must be loaded !
522 //--------------------------------------------------------------------
523 fTrackingPhase="PropagateBack";
524 Int_t nentr=event->GetNumberOfTracks();
525 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
528 for (Int_t i=0; i<nentr; i++) {
529 AliESDtrack *esd=event->GetTrack(i);
531 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
532 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
536 t=new AliITStrackMI(*esd);
537 } catch (const Char_t *msg) {
538 //Warning("PropagateBack",msg);
542 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
544 ResetTrackToFollow(*t);
546 // propagate to vertex [SR, GSI 17.02.2003]
547 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
548 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
549 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
550 fTrackToFollow.StartTimeIntegral();
551 // from vertex to outside pipe
552 CorrectForPipeMaterial(&fTrackToFollow,"outward");
555 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
556 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
557 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
561 fTrackToFollow.SetLabel(t->GetLabel());
562 //fTrackToFollow.CookdEdx();
563 CookLabel(&fTrackToFollow,0.); //For comparison only
564 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
565 //UseClusters(&fTrackToFollow);
571 Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
573 fTrackingPhase="Default";
577 //------------------------------------------------------------------------
578 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
579 //--------------------------------------------------------------------
580 // This functions refits ITS tracks using the
581 // "inward propagated" TPC tracks
582 // The clusters must be loaded !
583 //--------------------------------------------------------------------
584 fTrackingPhase="RefitInward";
585 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) RefitV02(event);
586 Int_t nentr=event->GetNumberOfTracks();
587 Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
590 for (Int_t i=0; i<nentr; i++) {
591 AliESDtrack *esd=event->GetTrack(i);
593 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
594 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
595 if (esd->GetStatus()&AliESDtrack::kTPCout)
596 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
600 t=new AliITStrackMI(*esd);
601 } catch (const Char_t *msg) {
602 //Warning("RefitInward",msg);
606 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
607 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
612 ResetTrackToFollow(*t);
613 fTrackToFollow.ResetClusters();
615 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
616 fTrackToFollow.ResetCovariance(10.);
619 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(), &fTrackToFollow, t,kTRUE)) {
620 fTrackToFollow.SetLabel(t->GetLabel());
621 // fTrackToFollow.CookdEdx();
622 CookdEdx(&fTrackToFollow);
624 CookLabel(&fTrackToFollow,0.0); //For comparison only
627 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
628 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
629 esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit);
630 Float_t r[3]={0.,0.,0.};
632 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
639 Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
641 fTrackingPhase="Default";
645 //------------------------------------------------------------------------
646 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
647 //--------------------------------------------------------------------
648 // Return pointer to a given cluster
649 //--------------------------------------------------------------------
650 Int_t l=(index & 0xf0000000) >> 28;
651 Int_t c=(index & 0x0fffffff) >> 00;
652 return fgLayers[l].GetCluster(c);
654 //------------------------------------------------------------------------
655 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
656 //--------------------------------------------------------------------
657 // Get track space point with index i
658 //--------------------------------------------------------------------
660 Int_t l=(index & 0xf0000000) >> 28;
661 Int_t c=(index & 0x0fffffff) >> 00;
662 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
663 Int_t idet = cl->GetDetectorIndex();
667 cl->GetGlobalXYZ(xyz);
668 cl->GetGlobalCov(cov);
671 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
674 iLayer = AliGeomManager::kSPD1;
677 iLayer = AliGeomManager::kSPD2;
680 iLayer = AliGeomManager::kSDD1;
683 iLayer = AliGeomManager::kSDD2;
686 iLayer = AliGeomManager::kSSD1;
689 iLayer = AliGeomManager::kSSD2;
692 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
695 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
696 p.SetVolumeID((UShort_t)volid);
699 //------------------------------------------------------------------------
700 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
701 AliTrackPoint& p, const AliESDtrack *t) {
702 //--------------------------------------------------------------------
703 // Get track space point with index i
704 // (assign error estimated during the tracking)
705 //--------------------------------------------------------------------
707 Int_t l=(index & 0xf0000000) >> 28;
708 Int_t c=(index & 0x0fffffff) >> 00;
709 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
710 Int_t idet = cl->GetDetectorIndex();
711 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
713 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
715 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
716 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
717 Double_t alpha = t->GetAlpha();
718 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
719 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,AliTracker::GetBz()));
720 phi += alpha-det.GetPhi();
721 Float_t tgphi = TMath::Tan(phi);
723 Float_t tgl = t->GetTgl(); // tgl about const along track
724 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
726 Float_t errlocalx,errlocalz;
727 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errlocalx,errlocalz);
731 cl->GetGlobalXYZ(xyz);
732 // cl->GetGlobalCov(cov);
733 Float_t pos[3] = {0.,0.,0.};
734 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errlocalx*errlocalx,errlocalz*errlocalz,0);
735 tmpcl.GetGlobalCov(cov);
739 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
742 iLayer = AliGeomManager::kSPD1;
745 iLayer = AliGeomManager::kSPD2;
748 iLayer = AliGeomManager::kSDD1;
751 iLayer = AliGeomManager::kSDD2;
754 iLayer = AliGeomManager::kSSD1;
757 iLayer = AliGeomManager::kSSD2;
760 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
763 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
764 p.SetVolumeID((UShort_t)volid);
767 //------------------------------------------------------------------------
768 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
770 //--------------------------------------------------------------------
771 // Follow prolongation tree
772 //--------------------------------------------------------------------
774 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
775 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
778 AliESDtrack * esd = otrack->GetESDtrack();
779 if (esd->GetV0Index(0)>0) {
780 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
781 // mapping of ESD track is different as ITS track in Containers
782 // Need something more stable
783 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
784 for (Int_t i=0;i<3;i++){
785 Int_t index = esd->GetV0Index(i);
787 AliESDv0 * vertex = fEsd->GetV0(index);
788 if (vertex->GetStatus()<0) continue; // rejected V0
790 if (esd->GetSign()>0) {
791 vertex->SetIndex(0,esdindex);
793 vertex->SetIndex(1,esdindex);
797 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
799 bestarray = new TObjArray(5);
800 fBestHypothesys.AddAt(bestarray,esdindex);
804 //setup tree of the prolongations
806 static AliITStrackMI tracks[7][100];
807 AliITStrackMI *currenttrack;
808 static AliITStrackMI currenttrack1;
809 static AliITStrackMI currenttrack2;
810 static AliITStrackMI backuptrack;
812 Int_t nindexes[7][100];
813 Float_t normalizedchi2[100];
814 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
815 otrack->SetNSkipped(0);
816 new (&(tracks[6][0])) AliITStrackMI(*otrack);
818 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
821 // follow prolongations
822 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
825 AliITSlayer &layer=fgLayers[ilayer];
826 Double_t r = layer.GetR();
832 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
834 if (ntracks[ilayer]>=100) break;
835 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
836 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
837 if (ntracks[ilayer]>15+ilayer){
838 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
839 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
842 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
844 // material between SSD and SDD, SDD and SPD
846 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
848 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
852 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
853 Int_t idet=layer.FindDetectorIndex(phi,z);
855 Double_t trackGlobXYZ1[3];
856 currenttrack1.GetXYZ(trackGlobXYZ1);
858 // Get the budget to the primary vertex for the current track being prolonged
859 Double_t budgetToPrimVertex = GetEffectiveThickness();
861 // check if we allow a prolongation without point
862 Int_t skip = SkipLayer(¤ttrack1,ilayer,idet);
864 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
865 // apply correction for material of the current layer
866 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
867 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
868 vtrack->SetClIndex(ilayer,0);
869 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
871 continue; //if (skip==1 || skip==2) continue;
874 // track outside layer acceptance in z
875 if (idet<0) continue;
877 //propagate to the intersection with the detector plane
878 const AliITSdetector &det=layer.GetDetector(idet);
879 new(¤ttrack2) AliITStrackMI(currenttrack1);
880 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
881 currenttrack2.Propagate(det.GetPhi(),det.GetR());
882 currenttrack1.SetDetectorIndex(idet);
883 currenttrack2.SetDetectorIndex(idet);
886 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
888 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
889 TMath::Sqrt(currenttrack1.GetSigmaZ2() +
890 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
891 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
892 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
893 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
894 TMath::Sqrt(currenttrack1.GetSigmaY2() +
895 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
896 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
897 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
899 // track at boundary between detectors, enlarge road
900 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
901 if ( (currenttrack1.GetY()-dy < det.GetYmin()+boundaryWidth) ||
902 (currenttrack1.GetY()+dy > det.GetYmax()-boundaryWidth) ||
903 (currenttrack1.GetZ()-dz < det.GetZmin()+boundaryWidth) ||
904 (currenttrack1.GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
905 Float_t tgl = TMath::Abs(currenttrack1.GetTgl());
906 if (tgl > 1.) tgl=1.;
907 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
908 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
909 Float_t snp = TMath::Abs(currenttrack1.GetSnp());
910 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) continue;
911 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
914 // road in global (rphi,z) [i.e. in tracking ref. system]
915 Double_t zmin = currenttrack1.GetZ() - dz;
916 Double_t zmax = currenttrack1.GetZ() + dz;
917 Double_t ymin = currenttrack1.GetY() + r*det.GetPhi() - dy;
918 Double_t ymax = currenttrack1.GetY() + r*det.GetPhi() + dy;
920 // select clusters in road
921 layer.SelectClusters(zmin,zmax,ymin,ymax);
922 //********************
924 // Define criteria for track-cluster association
925 Double_t msz = currenttrack1.GetSigmaZ2() +
926 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
927 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
928 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
929 Double_t msy = currenttrack1.GetSigmaY2() +
930 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
931 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
932 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
934 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
935 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
937 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
938 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
940 msz = 1./msz; // 1/RoadZ^2
941 msy = 1./msy; // 1/RoadY^2
944 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
946 const AliITSRecPoint *cl=0;
948 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
950 currenttrack = ¤ttrack1;
951 // loop over selected clusters
952 while ((cl=layer.GetNextCluster(clidx))!=0) {
953 if (ntracks[ilayer]>95) break; //space for skipped clusters
954 Bool_t changedet =kFALSE;
955 if (cl->GetQ()==0 && (deadzone==1)) continue;
956 Int_t idet=cl->GetDetectorIndex();
958 if (currenttrack->GetDetectorIndex()==idet) { // track already on the cluster's detector
959 // a first cut on track-cluster distance
960 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
961 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
962 continue; // cluster not associated to track
963 } else { // have to move track to cluster's detector
964 const AliITSdetector &det=layer.GetDetector(idet);
965 // a first cut on track-cluster distance
967 if (!currenttrack2.GetProlongationFast(det.GetPhi(),det.GetR(),y,z)) continue;
968 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
969 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
970 continue; // cluster not associated to track
972 new (&backuptrack) AliITStrackMI(currenttrack2);
974 currenttrack =¤ttrack2;
975 if (!currenttrack->Propagate(det.GetPhi(),det.GetR())) {
976 new (currenttrack) AliITStrackMI(backuptrack);
980 currenttrack->SetDetectorIndex(idet);
981 // Get again the budget to the primary vertex
982 // for the current track being prolonged, if had to change detector
983 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
986 // calculate track-clusters chi2
987 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
989 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
990 if (cl->GetQ()==0) deadzone=1; // take dead zone only once
991 if (ntracks[ilayer]>=100) continue;
992 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
993 updatetrack->SetClIndex(ilayer,0);
994 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
997 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) continue;
998 updatetrack->SetSampledEdx(cl->GetQ(),updatetrack->GetNumberOfClusters()-1); //b.b.
999 } else { // cluster in dead zone
1000 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1001 updatetrack->SetDeadZoneProbability(GetDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1003 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1005 // apply correction for material of the current layer
1006 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1008 if (constrain) { // apply vertex constrain
1009 updatetrack->SetConstrain(constrain);
1010 Bool_t isPrim = kTRUE;
1011 if (ilayer<4) { // check that it's close to the vertex
1012 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1013 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1014 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1015 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1016 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1018 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1019 } //apply vertex constrain
1021 } // create new hypothesis
1022 } // loop over possible prolongations
1024 // allow one prolongation without clusters
1025 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzone==0 && ntracks[ilayer]<100) {
1026 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1027 // apply correction for material of the current layer
1028 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1029 vtrack->SetClIndex(ilayer,0);
1030 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1031 vtrack->IncrementNSkipped();
1035 // allow one prolongation without clusters for tracks with |tgl|>1.1
1036 if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) { //big theta - for low flux
1037 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1038 // apply correction for material of the current layer
1039 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1040 vtrack->SetClIndex(ilayer,0);
1041 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1042 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1047 } // loop over tracks in layer ilayer+1
1049 //loop over track candidates for the current layer
1055 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1056 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1057 if (normalizedchi2[itrack] <
1058 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1062 if (constrain) { // constrain
1063 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1065 } else { // !constrain
1066 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1071 // sort tracks by increasing normalized chi2
1072 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1073 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1074 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1075 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1076 } // end loop over layers
1078 //printf("%d\t%d\t%d\t%d\t%d\t%d\n",ntracks[0],ntracks[1],ntracks[2],ntracks[3],ntracks[4],ntracks[5]);
1081 // Now select tracks to be kept
1083 Int_t max = constrain ? 20 : 5;
1085 // tracks that reach layer 0 (SPD inner)
1086 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1087 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1088 if (track.GetNumberOfClusters()<2) continue;
1089 if (!constrain && track.GetNormChi2(0) >
1090 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1091 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1094 // tracks that reach layer 1 (SPD outer)
1095 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1096 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1097 if (track.GetNumberOfClusters()<4) continue;
1098 if (!constrain && track.GetNormChi2(1) >
1099 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1100 if (constrain) track.IncrementNSkipped();
1102 track.SetD(0,track.GetD(GetX(),GetY()));
1103 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1104 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1105 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1108 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1111 // tracks that reack layer 2 (SDD inner), only during non-constrained pass
1113 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1114 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1115 if (track.GetNumberOfClusters()<3) continue;
1116 if (!constrain && track.GetNormChi2(2) >
1117 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1118 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1120 track.SetD(0,track.GetD(GetX(),GetY()));
1121 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1122 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1123 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1126 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1132 // register best track of each layer - important for V0 finder
1134 for (Int_t ilayer=0;ilayer<5;ilayer++){
1135 if (ntracks[ilayer]==0) continue;
1136 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1137 if (track.GetNumberOfClusters()<1) continue;
1138 CookLabel(&track,0);
1139 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1143 // update TPC V0 information
1145 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1146 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1147 for (Int_t i=0;i<3;i++){
1148 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1149 if (index==0) break;
1150 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1151 if (vertex->GetStatus()<0) continue; // rejected V0
1153 if (otrack->GetSign()>0) {
1154 vertex->SetIndex(0,esdindex);
1157 vertex->SetIndex(1,esdindex);
1159 //find nearest layer with track info
1160 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1161 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1162 Int_t nearest = nearestold;
1163 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1164 if (ntracks[nearest]==0){
1169 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1170 if (nearestold<5&&nearest<5){
1171 Bool_t accept = track.GetNormChi2(nearest)<10;
1173 if (track.GetSign()>0) {
1174 vertex->SetParamP(track);
1175 vertex->Update(fprimvertex);
1176 //vertex->SetIndex(0,track.fESDtrack->GetID());
1177 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1179 vertex->SetParamN(track);
1180 vertex->Update(fprimvertex);
1181 //vertex->SetIndex(1,track.fESDtrack->GetID());
1182 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1184 vertex->SetStatus(vertex->GetStatus()+1);
1186 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1193 //------------------------------------------------------------------------
1194 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1196 //--------------------------------------------------------------------
1199 return fgLayers[layer];
1201 //------------------------------------------------------------------------
1202 AliITStrackerMI::AliITSlayer::AliITSlayer():
1227 //--------------------------------------------------------------------
1228 //default AliITSlayer constructor
1229 //--------------------------------------------------------------------
1230 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1231 fClusterWeight[i]=0;
1232 fClusterTracks[0][i]=-1;
1233 fClusterTracks[1][i]=-1;
1234 fClusterTracks[2][i]=-1;
1235 fClusterTracks[3][i]=-1;
1238 //------------------------------------------------------------------------
1239 AliITStrackerMI::AliITSlayer::
1240 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1265 //--------------------------------------------------------------------
1266 //main AliITSlayer constructor
1267 //--------------------------------------------------------------------
1268 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1269 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1271 //------------------------------------------------------------------------
1272 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1274 fPhiOffset(layer.fPhiOffset),
1275 fNladders(layer.fNladders),
1276 fZOffset(layer.fZOffset),
1277 fNdetectors(layer.fNdetectors),
1278 fDetectors(layer.fDetectors),
1283 fClustersCs(layer.fClustersCs),
1284 fClusterIndexCs(layer.fClusterIndexCs),
1288 fCurrentSlice(layer.fCurrentSlice),
1295 fAccepted(layer.fAccepted),
1299 //------------------------------------------------------------------------
1300 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1301 //--------------------------------------------------------------------
1302 // AliITSlayer destructor
1303 //--------------------------------------------------------------------
1304 delete[] fDetectors;
1305 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1306 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1307 fClusterWeight[i]=0;
1308 fClusterTracks[0][i]=-1;
1309 fClusterTracks[1][i]=-1;
1310 fClusterTracks[2][i]=-1;
1311 fClusterTracks[3][i]=-1;
1314 //------------------------------------------------------------------------
1315 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1316 //--------------------------------------------------------------------
1317 // This function removes loaded clusters
1318 //--------------------------------------------------------------------
1319 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1320 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1321 fClusterWeight[i]=0;
1322 fClusterTracks[0][i]=-1;
1323 fClusterTracks[1][i]=-1;
1324 fClusterTracks[2][i]=-1;
1325 fClusterTracks[3][i]=-1;
1331 //------------------------------------------------------------------------
1332 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1333 //--------------------------------------------------------------------
1334 // This function reset weights of the clusters
1335 //--------------------------------------------------------------------
1336 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1337 fClusterWeight[i]=0;
1338 fClusterTracks[0][i]=-1;
1339 fClusterTracks[1][i]=-1;
1340 fClusterTracks[2][i]=-1;
1341 fClusterTracks[3][i]=-1;
1343 for (Int_t i=0; i<fN;i++) {
1344 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1345 if (cl&&cl->IsUsed()) cl->Use();
1349 //------------------------------------------------------------------------
1350 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1351 //--------------------------------------------------------------------
1352 // This function calculates the road defined by the cluster density
1353 //--------------------------------------------------------------------
1355 for (Int_t i=0; i<fN; i++) {
1356 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1358 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1360 //------------------------------------------------------------------------
1361 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1362 //--------------------------------------------------------------------
1363 //This function adds a cluster to this layer
1364 //--------------------------------------------------------------------
1365 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1366 ::Error("InsertCluster","Too many clusters !\n");
1372 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1373 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1374 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1375 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1376 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1380 //------------------------------------------------------------------------
1381 void AliITStrackerMI::AliITSlayer::SortClusters()
1386 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1387 Float_t *z = new Float_t[fN];
1388 Int_t * index = new Int_t[fN];
1390 for (Int_t i=0;i<fN;i++){
1391 z[i] = fClusters[i]->GetZ();
1393 TMath::Sort(fN,z,index,kFALSE);
1394 for (Int_t i=0;i<fN;i++){
1395 clusters[i] = fClusters[index[i]];
1398 for (Int_t i=0;i<fN;i++){
1399 fClusters[i] = clusters[i];
1400 fZ[i] = fClusters[i]->GetZ();
1401 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1402 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1403 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1413 for (Int_t i=0;i<fN;i++){
1414 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1415 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1416 fClusterIndex[i] = i;
1420 fDy5 = (fYB[1]-fYB[0])/5.;
1421 fDy10 = (fYB[1]-fYB[0])/10.;
1422 fDy20 = (fYB[1]-fYB[0])/20.;
1423 for (Int_t i=0;i<6;i++) fN5[i] =0;
1424 for (Int_t i=0;i<11;i++) fN10[i]=0;
1425 for (Int_t i=0;i<21;i++) fN20[i]=0;
1427 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;}
1428 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;}
1429 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;}
1432 for (Int_t i=0;i<fN;i++)
1433 for (Int_t irot=-1;irot<=1;irot++){
1434 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1436 for (Int_t slice=0; slice<6;slice++){
1437 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1438 fClusters5[slice][fN5[slice]] = fClusters[i];
1439 fY5[slice][fN5[slice]] = curY;
1440 fZ5[slice][fN5[slice]] = fZ[i];
1441 fClusterIndex5[slice][fN5[slice]]=i;
1446 for (Int_t slice=0; slice<11;slice++){
1447 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1448 fClusters10[slice][fN10[slice]] = fClusters[i];
1449 fY10[slice][fN10[slice]] = curY;
1450 fZ10[slice][fN10[slice]] = fZ[i];
1451 fClusterIndex10[slice][fN10[slice]]=i;
1456 for (Int_t slice=0; slice<21;slice++){
1457 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1458 fClusters20[slice][fN20[slice]] = fClusters[i];
1459 fY20[slice][fN20[slice]] = curY;
1460 fZ20[slice][fN20[slice]] = fZ[i];
1461 fClusterIndex20[slice][fN20[slice]]=i;
1468 // consistency check
1470 for (Int_t i=0;i<fN-1;i++){
1476 for (Int_t slice=0;slice<21;slice++)
1477 for (Int_t i=0;i<fN20[slice]-1;i++){
1478 if (fZ20[slice][i]>fZ20[slice][i+1]){
1485 //------------------------------------------------------------------------
1486 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1487 //--------------------------------------------------------------------
1488 // This function returns the index of the nearest cluster
1489 //--------------------------------------------------------------------
1492 if (fCurrentSlice<0) {
1501 if (ncl==0) return 0;
1502 Int_t b=0, e=ncl-1, m=(b+e)/2;
1503 for (; b<e; m=(b+e)/2) {
1504 // if (z > fClusters[m]->GetZ()) b=m+1;
1505 if (z > zcl[m]) b=m+1;
1510 //------------------------------------------------------------------------
1511 void AliITStrackerMI::AliITSlayer::
1512 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1513 //--------------------------------------------------------------------
1514 // This function sets the "window"
1515 //--------------------------------------------------------------------
1517 Double_t circle=2*TMath::Pi()*fR;
1518 fYmin = ymin; fYmax =ymax;
1519 Float_t ymiddle = (fYmin+fYmax)*0.5;
1520 if (ymiddle<fYB[0]) {fYmin+=circle; fYmax+=circle;ymiddle+=circle;}
1522 if (ymiddle>fYB[1]) {fYmin-=circle; fYmax-=circle;ymiddle-=circle;}
1527 fClustersCs = fClusters;
1528 fClusterIndexCs = fClusterIndex;
1534 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1535 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1536 if (slice<0) slice=0;
1537 if (slice>20) slice=20;
1538 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1540 fCurrentSlice=slice;
1541 fClustersCs = fClusters20[fCurrentSlice];
1542 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1543 fYcs = fY20[fCurrentSlice];
1544 fZcs = fZ20[fCurrentSlice];
1545 fNcs = fN20[fCurrentSlice];
1550 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1551 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1552 if (slice<0) slice=0;
1553 if (slice>10) slice=10;
1554 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1556 fCurrentSlice=slice;
1557 fClustersCs = fClusters10[fCurrentSlice];
1558 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1559 fYcs = fY10[fCurrentSlice];
1560 fZcs = fZ10[fCurrentSlice];
1561 fNcs = fN10[fCurrentSlice];
1566 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1567 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1568 if (slice<0) slice=0;
1569 if (slice>5) slice=5;
1570 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1572 fCurrentSlice=slice;
1573 fClustersCs = fClusters5[fCurrentSlice];
1574 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1575 fYcs = fY5[fCurrentSlice];
1576 fZcs = fZ5[fCurrentSlice];
1577 fNcs = fN5[fCurrentSlice];
1581 fI=FindClusterIndex(zmin); fZmax=zmax;
1582 fImax = TMath::Min(FindClusterIndex(zmax)+1,fNcs);
1586 //------------------------------------------------------------------------
1587 Int_t AliITStrackerMI::AliITSlayer::
1588 FindDetectorIndex(Double_t phi, Double_t z) const {
1589 //--------------------------------------------------------------------
1590 //This function finds the detector crossed by the track
1591 //--------------------------------------------------------------------
1593 if (fZOffset<0) // old geometry
1594 dphi = -(phi-fPhiOffset);
1595 else // new geometry
1596 dphi = phi-fPhiOffset;
1598 if (dphi < 0) dphi += 2*TMath::Pi();
1599 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1600 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1601 if (np>=fNladders) np-=fNladders;
1602 if (np<0) np+=fNladders;
1604 Double_t dz=fZOffset-z;
1605 Int_t nz=Int_t(dz*(fNdetectors-1)*0.5/fZOffset+0.5);
1606 if (nz>=fNdetectors) return -1;
1607 if (nz<0) return -1;
1609 return np*fNdetectors + nz;
1611 //------------------------------------------------------------------------
1612 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci){
1613 //--------------------------------------------------------------------
1614 // This function returns clusters within the "window"
1615 //--------------------------------------------------------------------
1617 if (fCurrentSlice<0){
1618 Double_t rpi2 = 2.*fR*TMath::Pi();
1619 for (Int_t i=fI; i<fImax; i++) {
1621 if (fYmax<y) y -= rpi2;
1622 if (fYmin>y) y += rpi2;
1623 if (y<fYmin) continue;
1624 if (y>fYmax) continue;
1625 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1628 return fClusters[i];
1632 for (Int_t i=fI; i<fImax; i++) {
1633 if (fYcs[i]<fYmin) continue;
1634 if (fYcs[i]>fYmax) continue;
1635 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1636 ci=fClusterIndexCs[i];
1638 return fClustersCs[i];
1643 //------------------------------------------------------------------------
1644 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1646 //--------------------------------------------------------------------
1647 // This function returns the layer thickness at this point (units X0)
1648 //--------------------------------------------------------------------
1650 x0=AliITSRecoParam::GetX0Air();
1651 if (43<fR&&fR<45) { //SSD2
1654 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1655 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1656 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1657 for (Int_t i=0; i<12; i++) {
1658 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1659 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1663 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1664 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1668 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1669 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1672 if (37<fR&&fR<41) { //SSD1
1675 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1676 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1677 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1678 for (Int_t i=0; i<11; i++) {
1679 if (TMath::Abs(z-3.9*i)<0.15) {
1680 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1684 if (TMath::Abs(z+3.9*i)<0.15) {
1685 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1689 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1690 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1693 if (13<fR&&fR<26) { //SDD
1696 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1698 if (TMath::Abs(y-1.80)<0.55) {
1700 for (Int_t j=0; j<20; j++) {
1701 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1702 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1705 if (TMath::Abs(y+1.80)<0.55) {
1707 for (Int_t j=0; j<20; j++) {
1708 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1709 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1713 for (Int_t i=0; i<4; i++) {
1714 if (TMath::Abs(z-7.3*i)<0.60) {
1716 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1719 if (TMath::Abs(z+7.3*i)<0.60) {
1721 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1726 if (6<fR&&fR<8) { //SPD2
1727 Double_t dd=0.0063; x0=21.5;
1729 if (TMath::Abs(y-3.08)>0.5) d+=dd;
1730 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
1732 if (3<fR&&fR<5) { //SPD1
1733 Double_t dd=0.0063; x0=21.5;
1735 if (TMath::Abs(y+0.21)>0.6) d+=dd;
1736 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
1741 //------------------------------------------------------------------------
1742 Double_t AliITStrackerMI::GetEffectiveThickness()
1744 //--------------------------------------------------------------------
1745 // Returns the thickness between the current layer and the vertex (units X0)
1746 //--------------------------------------------------------------------
1749 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
1750 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
1751 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
1755 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
1756 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
1760 Double_t xn=fgLayers[fI].GetR();
1761 for (Int_t i=0; i<fI; i++) {
1762 Double_t xi=fgLayers[i].GetR();
1763 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
1769 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
1770 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
1773 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
1774 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
1778 //------------------------------------------------------------------------
1779 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
1780 //--------------------------------------------------------------------
1781 // This function returns number of clusters within the "window"
1782 //--------------------------------------------------------------------
1784 for (Int_t i=fI; i<fN; i++) {
1785 const AliITSRecPoint *c=fClusters[i];
1786 if (c->GetZ() > fZmax) break;
1787 if (c->IsUsed()) continue;
1788 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
1789 Double_t y=fR*det.GetPhi() + c->GetY();
1791 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
1792 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
1794 if (y<fYmin) continue;
1795 if (y>fYmax) continue;
1800 //------------------------------------------------------------------------
1801 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *t,
1802 const AliITStrackMI *c, Bool_t extra) {
1803 //--------------------------------------------------------------------
1804 // This function refits the track "t" at the position "x" using
1805 // the clusters from "c"
1806 // If "extra"==kTRUE,
1807 // the clusters from overlapped modules get attached to "t"
1808 //--------------------------------------------------------------------
1809 Int_t index[AliITSgeomTGeo::kNLayers];
1811 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
1812 Int_t nc=c->GetNumberOfClusters();
1813 for (k=0; k<nc; k++) {
1814 Int_t idx=c->GetClusterIndex(k),nl=(idx&0xf0000000)>>28;
1818 // special for cosmics: check which the innermost layer crossed
1820 Int_t innermostlayer=5;
1821 Double_t d = TMath::Abs(t->GetD(0.,0.));
1822 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++)
1823 if(d<fgLayers[innermostlayer].GetR()) break;
1824 //printf(" d %f innermost %d\n",d,innermostlayer);
1826 Int_t from, to, step;
1827 if (xx > t->GetX()) {
1828 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
1831 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
1834 TString dir=(step>0 ? "outward" : "inward");
1836 // loop on the layers
1837 for (Int_t i=from; i != to; i += step) {
1838 AliITSlayer &layer=fgLayers[i];
1839 Double_t r=layer.GetR();
1841 // material between SSD and SDD, SDD and SPD
1842 Double_t hI=i-0.5*step;
1843 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
1844 if(!CorrectForShieldMaterial(t,"SDD",dir)) return kFALSE;
1845 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
1846 if(!CorrectForShieldMaterial(t,"SPD",dir)) return kFALSE;
1848 // remember old position [SR, GSI 18.02.2003]
1849 Double_t oldX=0., oldY=0., oldZ=0.;
1850 if (t->IsStartedTimeIntegral() && step==1) {
1851 t->GetGlobalXYZat(t->GetX(),oldX,oldY,oldZ);
1855 Double_t oldGlobXYZ[3];
1856 t->GetXYZ(oldGlobXYZ);
1859 if (!t->GetPhiZat(r,phi,z)) return kFALSE;
1861 Int_t idet=layer.FindDetectorIndex(phi,z);
1862 if (idet<0) return kFALSE;
1864 const AliITSdetector &det=layer.GetDetector(idet);
1866 if (!t->Propagate(phi,det.GetR())) return kFALSE;
1867 t->SetDetectorIndex(idet);
1869 const AliITSRecPoint *cl=0;
1870 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
1874 const AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(idx);
1876 if (idet != c->GetDetectorIndex()) {
1877 idet=c->GetDetectorIndex();
1878 const AliITSdetector &det=layer.GetDetector(idet);
1879 if (!t->Propagate(det.GetPhi(),det.GetR())) {
1882 t->SetDetectorIndex(idet);
1884 //Double_t chi2=t->GetPredictedChi2(c);
1885 Int_t layer = (idx & 0xf0000000) >> 28;;
1886 Double_t chi2=GetPredictedChi2MI(t,c,layer);
1897 if (!UpdateMI(t,cl,maxchi2,idx)) return kFALSE;
1898 t->SetSampledEdx(cl->GetQ(),t->GetNumberOfClusters()-1);
1901 if (extra) { //search for extra clusters
1902 AliITStrackV2 tmp(*t);
1903 Double_t dz=4*TMath::Sqrt(tmp.GetSigmaZ2()+AliITSReconstructor::GetRecoParam()->GetSigmaZ2(i));
1904 if (dz < 0.5*TMath::Abs(tmp.GetTgl())) dz=0.5*TMath::Abs(tmp.GetTgl());
1905 Double_t dy=4*TMath::Sqrt(t->GetSigmaY2()+AliITSReconstructor::GetRecoParam()->GetSigmaY2(i));
1906 if (dy < 0.5*TMath::Abs(tmp.GetSnp())) dy=0.5*TMath::Abs(tmp.GetSnp());
1907 Double_t zmin=t->GetZ() - dz;
1908 Double_t zmax=t->GetZ() + dz;
1909 Double_t ymin=t->GetY() + phi*r - dy;
1910 Double_t ymax=t->GetY() + phi*r + dy;
1911 layer.SelectClusters(zmin,zmax,ymin,ymax);
1913 const AliITSRecPoint *c=0; Int_t ci=-1,cci=-1;
1914 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2(), tolerance=0.1;
1915 while ((c=layer.GetNextCluster(ci))!=0) {
1916 if (idet == c->GetDetectorIndex()) continue;
1918 const AliITSdetector &det=layer.GetDetector(c->GetDetectorIndex());
1920 if (!tmp.Propagate(det.GetPhi(),det.GetR())) continue;
1922 if (TMath::Abs(tmp.GetZ() - c->GetZ()) > tolerance) continue;
1923 if (TMath::Abs(tmp.GetY() - c->GetY()) > tolerance) continue;
1925 Double_t chi2=tmp.GetPredictedChi2(c);
1926 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
1928 if (cci>=0) t->SetExtraCluster(i,(i<<28)+cci);
1931 // track time update [SR, GSI 17.02.2003]
1932 if (t->IsStartedTimeIntegral() && step==1) {
1933 Double_t newX, newY, newZ;
1934 t->GetGlobalXYZat(t->GetX(),newX,newY,newZ);
1935 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
1936 (oldZ-newZ)*(oldZ-newZ);
1937 t->AddTimeStep(TMath::Sqrt(dL2));
1941 // Correct for material of the current layer
1942 if(!CorrectForLayerMaterial(t,i,oldGlobXYZ,dir)) return kFALSE;
1944 } // end loop on the layers
1946 if (!t->PropagateTo(xx,0.,0.)) return kFALSE;
1949 //------------------------------------------------------------------------
1951 AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *t,const Int_t *clindex) {
1952 //--------------------------------------------------------------------
1953 // This function refits the track "t" at the position "x" using
1954 // the clusters from array
1955 //--------------------------------------------------------------------
1956 Int_t index[AliITSgeomTGeo::kNLayers];
1958 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
1960 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
1961 index[k]=clindex[k];
1964 // special for cosmics: check which the innermost layer crossed
1966 Int_t innermostlayer=5;
1967 Double_t d = TMath::Abs(t->GetD(0.,0.));
1968 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++)
1969 if(d<fgLayers[innermostlayer].GetR()) break;
1970 //printf(" d %f innermost %d\n",d,innermostlayer);
1972 Int_t from, to, step;
1973 if (xx > t->GetX()) {
1974 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
1977 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
1980 TString dir=(step>0 ? "outward" : "inward");
1982 for (Int_t i=from; i != to; i += step) {
1983 AliITSlayer &layer=fgLayers[i];
1984 Double_t r=layer.GetR();
1985 if (step<0 && xx>r) break;
1987 // material between SSD and SDD, SDD and SPD
1988 Double_t hI=i-0.5*step;
1989 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
1990 if(!CorrectForShieldMaterial(t,"SDD",dir)) return kFALSE;
1991 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
1992 if(!CorrectForShieldMaterial(t,"SPD",dir)) return kFALSE;
1994 // remember old position [SR, GSI 18.02.2003]
1995 Double_t oldX=0., oldY=0., oldZ=0.;
1996 if (t->IsStartedTimeIntegral() && step==1) {
1997 t->GetGlobalXYZat(t->GetX(),oldX,oldY,oldZ);
2000 Double_t oldGlobXYZ[3];
2001 t->GetXYZ(oldGlobXYZ);
2004 if (!t->GetPhiZat(r,phi,z)) return kFALSE;
2006 Int_t idet=layer.FindDetectorIndex(phi,z);
2007 if (idet<0) return kFALSE;
2008 const AliITSdetector &det=layer.GetDetector(idet);
2010 if (!t->Propagate(phi,det.GetR())) return kFALSE;
2011 t->SetDetectorIndex(idet);
2013 const AliITSRecPoint *cl=0;
2014 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2018 const AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(idx);
2020 if (idet != c->GetDetectorIndex()) {
2021 idet=c->GetDetectorIndex();
2022 const AliITSdetector &det=layer.GetDetector(idet);
2023 if (!t->Propagate(det.GetPhi(),det.GetR())) {
2026 t->SetDetectorIndex(idet);
2028 //Double_t chi2=t->GetPredictedChi2(c);
2029 Int_t layer = (idx & 0xf0000000) >> 28;;
2030 Double_t chi2=GetPredictedChi2MI(t,c,layer);
2041 if (!UpdateMI(t,cl,maxchi2,idx)) return kFALSE;
2042 t->SetSampledEdx(cl->GetQ(),t->GetNumberOfClusters()-1);
2045 // Correct for material of the current layer
2046 if(!CorrectForLayerMaterial(t,i,oldGlobXYZ,dir)) return kFALSE;
2048 // track time update [SR, GSI 17.02.2003]
2049 if (t->IsStartedTimeIntegral() && step==1) {
2050 Double_t newX, newY, newZ;
2051 t->GetGlobalXYZat(t->GetX(),newX,newY,newZ);
2052 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2053 (oldZ-newZ)*(oldZ-newZ);
2054 t->AddTimeStep(TMath::Sqrt(dL2));
2060 if (!t->PropagateTo(xx,0.,0.)) return kFALSE;
2063 //------------------------------------------------------------------------
2064 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2067 // calculate normalized chi2
2068 // return NormalizedChi2(track,0);
2071 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2072 // track->fdEdxMismatch=0;
2073 Float_t dedxmismatch =0;
2074 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2076 for (Int_t i = 0;i<6;i++){
2077 if (track->GetClIndex(i)>0){
2078 Float_t cerry, cerrz;
2079 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2081 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2084 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2085 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2086 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2088 cchi2+=(0.5-ratio)*10.;
2089 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2090 dedxmismatch+=(0.5-ratio)*10.;
2094 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2095 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2096 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2097 if (i<2) chi2+=2*cl->GetDeltaProbability();
2103 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2104 track->SetdEdxMismatch(dedxmismatch);
2108 for (Int_t i = 0;i<4;i++){
2109 if (track->GetClIndex(i)>0){
2110 Float_t cerry, cerrz;
2111 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2112 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2115 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2116 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2120 for (Int_t i = 4;i<6;i++){
2121 if (track->GetClIndex(i)>0){
2122 Float_t cerry, cerrz;
2123 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2124 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2127 Float_t cerryb, cerrzb;
2128 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2129 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2132 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2133 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2138 if (track->GetESDtrack()->GetTPCsignal()>85){
2139 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2141 chi2+=(0.5-ratio)*5.;
2144 chi2+=(ratio-2.0)*3;
2148 Double_t match = TMath::Sqrt(track->GetChi22());
2149 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2150 if (!track->GetConstrain()) {
2151 if (track->GetNumberOfClusters()>2) {
2152 match/=track->GetNumberOfClusters()-2.;
2157 if (match<0) match=0;
2158 Float_t deadzonefactor = (track->GetNDeadZone()>0) ? 3*(1.1-track->GetDeadZoneProbability()):0.;
2159 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2160 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2161 1./(1.+track->GetNSkipped()));
2165 //------------------------------------------------------------------------
2166 Double_t AliITStrackerMI::GetMatchingChi2(AliITStrackMI * track1, AliITStrackMI * track2)
2169 // return matching chi2 between two tracks
2170 AliITStrackMI track3(*track2);
2171 track3.Propagate(track1->GetAlpha(),track1->GetX());
2173 vec(0,0)=track1->GetY() - track3.GetY();
2174 vec(1,0)=track1->GetZ() - track3.GetZ();
2175 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2176 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2177 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2180 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2181 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2182 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2183 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2184 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2186 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2187 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2188 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2189 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2191 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2192 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2193 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2195 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2196 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2198 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2201 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2202 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2205 //------------------------------------------------------------------------
2206 Double_t AliITStrackerMI::GetDeadZoneProbability(Double_t zpos, Double_t zerr)
2209 // return probability that given point (characterized by z position and error)
2210 // is in SPD dead zone
2212 Double_t probability = 0.;
2213 Double_t absz = TMath::Abs(zpos);
2214 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2215 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2216 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2217 Double_t zmin, zmax;
2218 if (zpos<-6.) { // dead zone at z = -7
2219 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2220 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2221 } else if (zpos>6.) { // dead zone at z = +7
2222 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2223 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2224 } else if (absz<2.) { // dead zone at z = 0
2225 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2226 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2231 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2233 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2234 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2237 //------------------------------------------------------------------------
2238 Double_t AliITStrackerMI::GetTruncatedChi2(AliITStrackMI * track, Float_t fac)
2241 // calculate normalized chi2
2243 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2245 for (Int_t i = 0;i<6;i++){
2246 if (TMath::Abs(track->GetDy(i))>0){
2247 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2248 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2251 else{chi2[i]=10000;}
2254 TMath::Sort(6,chi2,index,kFALSE);
2255 Float_t max = float(ncl)*fac-1.;
2256 Float_t sumchi=0, sumweight=0;
2257 for (Int_t i=0;i<max+1;i++){
2258 Float_t weight = (i<max)?1.:(max+1.-i);
2259 sumchi+=weight*chi2[index[i]];
2262 Double_t normchi2 = sumchi/sumweight;
2265 //------------------------------------------------------------------------
2266 Double_t AliITStrackerMI::GetInterpolatedChi2(AliITStrackMI * forwardtrack, AliITStrackMI * backtrack)
2269 // calculate normalized chi2
2270 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2273 for (Int_t i=0;i<6;i++){
2274 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2275 Double_t sy1 = forwardtrack->GetSigmaY(i);
2276 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2277 Double_t sy2 = backtrack->GetSigmaY(i);
2278 Double_t sz2 = backtrack->GetSigmaZ(i);
2279 if (i<2){ sy2=1000.;sz2=1000;}
2281 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2282 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2284 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2285 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2287 res+= nz0*nz0+ny0*ny0;
2290 if (npoints>1) return
2291 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2292 //2*forwardtrack->fNUsed+
2293 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2294 1./(1.+forwardtrack->GetNSkipped()));
2297 //------------------------------------------------------------------------
2298 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2299 //--------------------------------------------------------------------
2300 // Return pointer to a given cluster
2301 //--------------------------------------------------------------------
2302 Int_t l=(index & 0xf0000000) >> 28;
2303 Int_t c=(index & 0x0fffffff) >> 00;
2304 return fgLayers[l].GetWeight(c);
2306 //------------------------------------------------------------------------
2307 void AliITStrackerMI::RegisterClusterTracks(AliITStrackMI* track,Int_t id)
2309 //---------------------------------------------
2310 // register track to the list
2312 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2315 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2316 Int_t index = track->GetClusterIndex(icluster);
2317 Int_t l=(index & 0xf0000000) >> 28;
2318 Int_t c=(index & 0x0fffffff) >> 00;
2319 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2320 for (Int_t itrack=0;itrack<4;itrack++){
2321 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2322 fgLayers[l].SetClusterTracks(itrack,c,id);
2328 //------------------------------------------------------------------------
2329 void AliITStrackerMI::UnRegisterClusterTracks(AliITStrackMI* track, Int_t id)
2331 //---------------------------------------------
2332 // unregister track from the list
2333 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2334 Int_t index = track->GetClusterIndex(icluster);
2335 Int_t l=(index & 0xf0000000) >> 28;
2336 Int_t c=(index & 0x0fffffff) >> 00;
2337 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2338 for (Int_t itrack=0;itrack<4;itrack++){
2339 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2340 fgLayers[l].SetClusterTracks(itrack,c,-1);
2345 //------------------------------------------------------------------------
2346 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2348 //-------------------------------------------------------------
2349 //get number of shared clusters
2350 //-------------------------------------------------------------
2352 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2353 // mean number of clusters
2354 Float_t *ny = GetNy(id), *nz = GetNz(id);
2357 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2358 Int_t index = track->GetClusterIndex(icluster);
2359 Int_t l=(index & 0xf0000000) >> 28;
2360 Int_t c=(index & 0x0fffffff) >> 00;
2361 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2363 printf("problem\n");
2365 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2369 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2370 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2371 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2373 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2376 deltan = (cl->GetNz()-nz[l]);
2378 if (deltan>2.0) continue; // extended - highly probable shared cluster
2379 weight = 2./TMath::Max(3.+deltan,2.);
2381 for (Int_t itrack=0;itrack<4;itrack++){
2382 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2384 clist[l] = (AliITSRecPoint*)GetCluster(index);
2390 track->SetNUsed(shared);
2393 //------------------------------------------------------------------------
2394 Int_t AliITStrackerMI::GetOverlapTrack(AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2397 // find first shared track
2399 // mean number of clusters
2400 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2402 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2403 Int_t sharedtrack=100000;
2404 Int_t tracks[24],trackindex=0;
2405 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2407 for (Int_t icluster=0;icluster<6;icluster++){
2408 if (clusterlist[icluster]<0) continue;
2409 Int_t index = clusterlist[icluster];
2410 Int_t l=(index & 0xf0000000) >> 28;
2411 Int_t c=(index & 0x0fffffff) >> 00;
2413 printf("problem\n");
2415 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2416 //if (l>3) continue;
2417 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2420 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2421 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2422 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2424 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2427 deltan = (cl->GetNz()-nz[l]);
2429 if (deltan>2.0) continue; // extended - highly probable shared cluster
2431 for (Int_t itrack=3;itrack>=0;itrack--){
2432 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2433 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2434 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2439 if (trackindex==0) return -1;
2441 sharedtrack = tracks[0];
2443 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2446 Int_t track[24], cluster[24];
2447 for (Int_t i=0;i<trackindex;i++){ track[i]=-1; cluster[i]=0;}
2450 for (Int_t i=0;i<trackindex;i++){
2451 if (tracks[i]<0) continue;
2452 track[index] = tracks[i];
2454 for (Int_t j=i+1;j<trackindex;j++){
2455 if (tracks[j]<0) continue;
2456 if (tracks[j]==tracks[i]){
2464 for (Int_t i=0;i<index;i++){
2465 if (cluster[index]>max) {
2466 sharedtrack=track[index];
2473 if (sharedtrack>=100000) return -1;
2475 // make list of overlaps
2477 for (Int_t icluster=0;icluster<6;icluster++){
2478 if (clusterlist[icluster]<0) continue;
2479 Int_t index = clusterlist[icluster];
2480 Int_t l=(index & 0xf0000000) >> 28;
2481 Int_t c=(index & 0x0fffffff) >> 00;
2482 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2483 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2485 if (cl->GetNy()>2) continue;
2486 if (cl->GetNz()>2) continue;
2489 if (cl->GetNy()>3) continue;
2490 if (cl->GetNz()>3) continue;
2493 for (Int_t itrack=3;itrack>=0;itrack--){
2494 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2495 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2503 //------------------------------------------------------------------------
2504 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2506 // try to find track hypothesys without conflicts
2507 // with minimal chi2;
2508 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2509 Int_t entries1 = arr1->GetEntriesFast();
2510 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2511 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2512 Int_t entries2 = arr2->GetEntriesFast();
2513 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2515 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2516 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2517 if (track10->Pt()>0.5+track20->Pt()) return track10;
2519 for (Int_t itrack=0;itrack<entries1;itrack++){
2520 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2521 UnRegisterClusterTracks(track,trackID1);
2524 for (Int_t itrack=0;itrack<entries2;itrack++){
2525 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2526 UnRegisterClusterTracks(track,trackID2);
2530 Float_t maxconflicts=6;
2531 Double_t maxchi2 =1000.;
2533 // get weight of hypothesys - using best hypothesy
2536 Int_t list1[6],list2[6];
2537 AliITSRecPoint *clist1[6], *clist2[6] ;
2538 RegisterClusterTracks(track10,trackID1);
2539 RegisterClusterTracks(track20,trackID2);
2540 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2541 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2542 UnRegisterClusterTracks(track10,trackID1);
2543 UnRegisterClusterTracks(track20,trackID2);
2546 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2547 Float_t nerry[6],nerrz[6];
2548 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2549 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2550 for (Int_t i=0;i<6;i++){
2551 if ( (erry1[i]>0) && (erry2[i]>0)) {
2552 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2553 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2555 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2556 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2558 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2559 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2560 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2563 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2564 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2565 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2573 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2574 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2575 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2576 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2578 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2579 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2580 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2582 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2583 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2584 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2587 Double_t sumw = w1+w2;
2591 w1 = (d2+0.5)/(d1+d2+1.);
2592 w2 = (d1+0.5)/(d1+d2+1.);
2594 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2595 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2597 // get pair of "best" hypothesys
2599 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2600 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2602 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2603 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2604 //if (track1->fFakeRatio>0) continue;
2605 RegisterClusterTracks(track1,trackID1);
2606 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2607 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2609 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2610 //if (track2->fFakeRatio>0) continue;
2612 RegisterClusterTracks(track2,trackID2);
2613 Int_t list1[6],list2[6];
2614 AliITSRecPoint *clist1[6], *clist2[6] ;
2615 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2616 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2617 UnRegisterClusterTracks(track2,trackID2);
2619 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2620 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2621 if (nskipped>0.5) continue;
2623 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2624 if (conflict1+1<cconflict1) continue;
2625 if (conflict2+1<cconflict2) continue;
2629 for (Int_t i=0;i<6;i++){
2631 Float_t c1 =0.; // conflict coeficients
2633 if (clist1[i]&&clist2[i]){
2636 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2639 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
2641 c1 = 2./TMath::Max(3.+deltan,2.);
2642 c2 = 2./TMath::Max(3.+deltan,2.);
2648 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
2651 deltan = (clist1[i]->GetNz()-nz1[i]);
2653 c1 = 2./TMath::Max(3.+deltan,2.);
2660 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
2663 deltan = (clist2[i]->GetNz()-nz2[i]);
2665 c2 = 2./TMath::Max(3.+deltan,2.);
2670 Double_t chi21=0,chi22=0;
2671 if (TMath::Abs(track1->GetDy(i))>0.) {
2672 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
2673 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
2674 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
2675 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
2677 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
2680 if (TMath::Abs(track2->GetDy(i))>0.) {
2681 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
2682 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
2683 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
2684 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
2687 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
2689 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
2690 if (chi21>0) sum+=w1;
2691 if (chi22>0) sum+=w2;
2694 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
2695 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
2696 Double_t normchi2 = 2*conflict+sumchi2/sum;
2697 if ( normchi2 <maxchi2 ){
2700 maxconflicts = conflict;
2704 UnRegisterClusterTracks(track1,trackID1);
2707 // if (maxconflicts<4 && maxchi2<th0){
2708 if (maxchi2<th0*2.){
2709 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
2710 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
2711 track1->SetChi2MIP(5,maxconflicts);
2712 track1->SetChi2MIP(6,maxchi2);
2713 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
2714 // track1->UpdateESDtrack(AliESDtrack::kITSin);
2715 track1->SetChi2MIP(8,index1);
2716 fBestTrackIndex[trackID1] =index1;
2717 UpdateESDtrack(track1, AliESDtrack::kITSin);
2719 else if (track10->GetChi2MIP(0)<th1){
2720 track10->SetChi2MIP(5,maxconflicts);
2721 track10->SetChi2MIP(6,maxchi2);
2722 // track10->UpdateESDtrack(AliESDtrack::kITSin);
2723 UpdateESDtrack(track10,AliESDtrack::kITSin);
2726 for (Int_t itrack=0;itrack<entries1;itrack++){
2727 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2728 UnRegisterClusterTracks(track,trackID1);
2731 for (Int_t itrack=0;itrack<entries2;itrack++){
2732 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2733 UnRegisterClusterTracks(track,trackID2);
2736 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2737 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2738 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2739 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2740 RegisterClusterTracks(track10,trackID1);
2742 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2743 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2744 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2745 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2746 RegisterClusterTracks(track20,trackID2);
2751 //------------------------------------------------------------------------
2752 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
2753 //--------------------------------------------------------------------
2754 // This function marks clusters assigned to the track
2755 //--------------------------------------------------------------------
2756 AliTracker::UseClusters(t,from);
2758 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
2759 //if (c->GetQ()>2) c->Use();
2760 if (c->GetSigmaZ2()>0.1) c->Use();
2761 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
2762 //if (c->GetQ()>2) c->Use();
2763 if (c->GetSigmaZ2()>0.1) c->Use();
2766 //------------------------------------------------------------------------
2767 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
2769 //------------------------------------------------------------------
2770 // add track to the list of hypothesys
2771 //------------------------------------------------------------------
2773 if (esdindex>=fTrackHypothesys.GetEntriesFast()) fTrackHypothesys.Expand(esdindex*2+10);
2775 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
2777 array = new TObjArray(10);
2778 fTrackHypothesys.AddAt(array,esdindex);
2780 array->AddLast(track);
2782 //------------------------------------------------------------------------
2783 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
2785 //-------------------------------------------------------------------
2786 // compress array of track hypothesys
2787 // keep only maxsize best hypothesys
2788 //-------------------------------------------------------------------
2789 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
2790 if (! (fTrackHypothesys.At(esdindex)) ) return;
2791 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
2792 Int_t entries = array->GetEntriesFast();
2794 //- find preliminary besttrack as a reference
2795 Float_t minchi2=10000;
2797 AliITStrackMI * besttrack=0;
2798 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
2799 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2800 if (!track) continue;
2801 Float_t chi2 = NormalizedChi2(track,0);
2803 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
2804 track->SetLabel(tpcLabel);
2806 track->SetFakeRatio(1.);
2807 CookLabel(track,0.); //For comparison only
2809 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
2810 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
2811 if (track->GetNumberOfClusters()<maxn) continue;
2812 maxn = track->GetNumberOfClusters();
2819 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2820 delete array->RemoveAt(itrack);
2824 if (!besttrack) return;
2827 //take errors of best track as a reference
2828 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
2829 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
2830 for (Int_t i=0;i<6;i++) {
2831 if (besttrack->GetClIndex(i)>0){
2832 erry[i] = besttrack->GetSigmaY(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2833 errz[i] = besttrack->GetSigmaZ(i); errz[i+6] = besttrack->GetSigmaZ(i+6);
2834 ny[i] = besttrack->GetNy(i);
2835 nz[i] = besttrack->GetNz(i);
2839 // calculate normalized chi2
2841 Float_t * chi2 = new Float_t[entries];
2842 Int_t * index = new Int_t[entries];
2843 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
2844 for (Int_t itrack=0;itrack<entries;itrack++){
2845 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2847 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
2848 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
2849 chi2[itrack] = track->GetChi2MIP(0);
2851 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2852 delete array->RemoveAt(itrack);
2858 TMath::Sort(entries,chi2,index,kFALSE);
2859 besttrack = (AliITStrackMI*)array->At(index[0]);
2860 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
2861 for (Int_t i=0;i<6;i++){
2862 if (besttrack->GetClIndex(i)>0){
2863 erry[i] = besttrack->GetSigmaY(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2864 errz[i] = besttrack->GetSigmaZ(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2865 ny[i] = besttrack->GetNy(i);
2866 nz[i] = besttrack->GetNz(i);
2871 // calculate one more time with updated normalized errors
2872 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
2873 for (Int_t itrack=0;itrack<entries;itrack++){
2874 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2876 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
2877 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
2878 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
2881 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2882 delete array->RemoveAt(itrack);
2887 entries = array->GetEntriesFast();
2891 TObjArray * newarray = new TObjArray();
2892 TMath::Sort(entries,chi2,index,kFALSE);
2893 besttrack = (AliITStrackMI*)array->At(index[0]);
2896 for (Int_t i=0;i<6;i++){
2897 if (besttrack->GetNz(i)>0&&besttrack->GetNy(i)>0){
2898 erry[i] = besttrack->GetSigmaY(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2899 errz[i] = besttrack->GetSigmaZ(i); errz[i+6] = besttrack->GetSigmaZ(i+6);
2900 ny[i] = besttrack->GetNy(i);
2901 nz[i] = besttrack->GetNz(i);
2904 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
2905 Float_t minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
2906 Float_t minn = besttrack->GetNumberOfClusters()-3;
2908 for (Int_t i=0;i<entries;i++){
2909 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
2910 if (!track) continue;
2911 if (accepted>maxcut) break;
2912 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
2913 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2914 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
2915 delete array->RemoveAt(index[i]);
2919 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
2920 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
2921 if (!shortbest) accepted++;
2923 newarray->AddLast(array->RemoveAt(index[i]));
2924 for (Int_t i=0;i<6;i++){
2926 erry[i] = track->GetSigmaY(i); erry[i+6] = track->GetSigmaY(i+6);
2927 errz[i] = track->GetSigmaZ(i); errz[i] = track->GetSigmaZ(i+6);
2928 ny[i] = track->GetNy(i);
2929 nz[i] = track->GetNz(i);
2934 delete array->RemoveAt(index[i]);
2938 delete fTrackHypothesys.RemoveAt(esdindex);
2939 fTrackHypothesys.AddAt(newarray,esdindex);
2943 delete fTrackHypothesys.RemoveAt(esdindex);
2949 //------------------------------------------------------------------------
2950 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
2952 //-------------------------------------------------------------
2953 // try to find best hypothesy
2954 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
2955 //-------------------------------------------------------------
2956 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
2957 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
2958 if (!array) return 0;
2959 Int_t entries = array->GetEntriesFast();
2960 if (!entries) return 0;
2961 Float_t minchi2 = 100000;
2962 AliITStrackMI * besttrack=0;
2964 AliITStrackMI * backtrack = new AliITStrackMI(*original);
2965 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
2966 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
2967 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
2969 for (Int_t i=0;i<entries;i++){
2970 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
2971 if (!track) continue;
2972 Float_t sigmarfi,sigmaz;
2973 GetDCASigma(track,sigmarfi,sigmaz);
2974 track->SetDnorm(0,sigmarfi);
2975 track->SetDnorm(1,sigmaz);
2977 track->SetChi2MIP(1,1000000);
2978 track->SetChi2MIP(2,1000000);
2979 track->SetChi2MIP(3,1000000);
2982 backtrack = new(backtrack) AliITStrackMI(*track);
2983 if (track->GetConstrain()) {
2984 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
2985 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
2986 backtrack->ResetCovariance(10.);
2988 backtrack->ResetCovariance(10.);
2990 backtrack->ResetClusters();
2992 Double_t x = original->GetX();
2993 if (!RefitAt(x,backtrack,track)) continue;
2995 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
2996 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
2997 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
2998 track->SetChi22(GetMatchingChi2(backtrack,original));
3000 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3001 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3002 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3005 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3007 //forward track - without constraint
3008 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3009 forwardtrack->ResetClusters();
3011 RefitAt(x,forwardtrack,track);
3012 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3013 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3014 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3016 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3017 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3018 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3019 forwardtrack->SetD(0,track->GetD(0));
3020 forwardtrack->SetD(1,track->GetD(1));
3023 AliITSRecPoint* clist[6];
3024 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3025 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3028 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3029 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3030 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3031 track->SetChi2MIP(3,1000);
3034 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3036 for (Int_t ichi=0;ichi<5;ichi++){
3037 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3039 if (chi2 < minchi2){
3040 //besttrack = new AliITStrackMI(*forwardtrack);
3042 besttrack->SetLabel(track->GetLabel());
3043 besttrack->SetFakeRatio(track->GetFakeRatio());
3045 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3046 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3047 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3051 delete forwardtrack;
3053 for (Int_t i=0;i<entries;i++){
3054 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3055 if (!track) continue;
3057 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3058 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3059 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3060 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3061 delete array->RemoveAt(i);
3071 SortTrackHypothesys(esdindex,checkmax,1);
3072 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3073 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3074 besttrack = (AliITStrackMI*)array->At(0);
3075 if (!besttrack) return 0;
3076 besttrack->SetChi2MIP(8,0);
3077 fBestTrackIndex[esdindex]=0;
3078 entries = array->GetEntriesFast();
3079 AliITStrackMI *longtrack =0;
3081 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3082 for (Int_t itrack=entries-1;itrack>0;itrack--){
3083 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3084 if (!track->GetConstrain()) continue;
3085 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3086 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3087 if (track->GetChi2MIP(0)>4.) continue;
3088 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3091 //if (longtrack) besttrack=longtrack;
3094 AliITSRecPoint * clist[6];
3095 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3096 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3097 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3098 RegisterClusterTracks(besttrack,esdindex);
3105 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3106 if (sharedtrack>=0){
3108 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3110 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3116 if (shared>2.5) return 0;
3117 if (shared>1.0) return besttrack;
3119 // Don't sign clusters if not gold track
3121 if (!besttrack->IsGoldPrimary()) return besttrack;
3122 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3124 if (fConstraint[fPass]){
3128 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3129 for (Int_t i=0;i<6;i++){
3130 Int_t index = besttrack->GetClIndex(i);
3131 if (index<=0) continue;
3132 Int_t ilayer = (index & 0xf0000000) >> 28;
3133 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3134 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3136 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3137 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3138 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3139 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3140 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3141 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3143 Bool_t cansign = kTRUE;
3144 for (Int_t itrack=0;itrack<entries; itrack++){
3145 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3146 if (!track) continue;
3147 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3148 if ( (track->GetClIndex(ilayer)>0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3154 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3155 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3156 if (!c->IsUsed()) c->Use();
3162 //------------------------------------------------------------------------
3163 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3166 // get "best" hypothesys
3169 Int_t nentries = itsTracks.GetEntriesFast();
3170 for (Int_t i=0;i<nentries;i++){
3171 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3172 if (!track) continue;
3173 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3174 if (!array) continue;
3175 if (array->GetEntriesFast()<=0) continue;
3177 AliITStrackMI* longtrack=0;
3179 Float_t maxchi2=1000;
3180 for (Int_t j=0;j<array->GetEntriesFast();j++){
3181 AliITStrackMI* track = (AliITStrackMI*)array->At(j);
3182 if (!track) continue;
3183 if (track->GetGoldV0()) {
3184 longtrack = track; //gold V0 track taken
3187 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3188 Float_t chi2 = track->GetChi2MIP(0);
3190 if (!track->GetGoldV0()&&track->GetConstrain()==kFALSE) chi2+=5;
3192 if (track->GetNumberOfClusters()+track->GetNDeadZone()>minn) maxchi2 = track->GetChi2MIP(0);
3194 if (chi2 > maxchi2) continue;
3195 minn= track->GetNumberOfClusters()+track->GetNDeadZone();
3202 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3203 if (!longtrack) {longtrack = besttrack;}
3204 else besttrack= longtrack;
3208 AliITSRecPoint * clist[6];
3209 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3211 track->SetNUsed(shared);
3212 track->SetNSkipped(besttrack->GetNSkipped());
3213 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3215 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3219 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3220 //if (sharedtrack==-1) sharedtrack=0;
3221 if (sharedtrack>=0) {
3222 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3225 if (besttrack&&fAfterV0) {
3226 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3228 if (besttrack&&fConstraint[fPass])
3229 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3230 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3231 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3232 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3238 //------------------------------------------------------------------------
3239 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3240 //--------------------------------------------------------------------
3241 //This function "cooks" a track label. If label<0, this track is fake.
3242 //--------------------------------------------------------------------
3245 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3247 track->SetChi2MIP(9,0);
3249 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3250 Int_t cindex = track->GetClusterIndex(i);
3251 Int_t l=(cindex & 0xf0000000) >> 28;
3252 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3254 for (Int_t ind=0;ind<3;ind++){
3256 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3258 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3261 Int_t nclusters = track->GetNumberOfClusters();
3262 if (nclusters > 0) //PH Some tracks don't have any cluster
3263 track->SetFakeRatio(double(nwrong)/double(nclusters));
3265 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3267 track->SetLabel(tpcLabel);
3271 //------------------------------------------------------------------------
3272 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3277 //AliITSRecPoint * clist[6];
3278 // Int_t shared = GetNumberOfSharedClusters(track,index,list,clist);
3281 track->SetChi2MIP(9,0);
3282 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3283 Int_t cindex = track->GetClusterIndex(i);
3284 Int_t l=(cindex & 0xf0000000) >> 28;
3285 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3286 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3288 for (Int_t ind=0;ind<3;ind++){
3289 if (cl->GetLabel(ind)==lab) isWrong=0;
3291 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3293 //if (l>3 && (cl->GetNy()>4) || (cl->GetNz()>4)) continue; //shared track
3294 //if (l>3&& !(cl->GetType()==1||cl->GetType()==10)) continue;
3295 //if (l<4&& !(cl->GetType()==1)) continue;
3296 dedx[accepted]= track->GetSampledEdx(i);
3297 //dedx[accepted]= track->fNormQ[l];
3305 TMath::Sort(accepted,dedx,indexes,kFALSE);
3308 Double_t nl=low*accepted, nu =up*accepted;
3310 Float_t sumweight =0;
3311 for (Int_t i=0; i<accepted; i++) {
3313 if (i<nl+0.1) weight = TMath::Max(1.-(nl-i),0.);
3314 if (i>nu-1) weight = TMath::Max(nu-i,0.);
3315 sumamp+= dedx[indexes[i]]*weight;
3318 track->SetdEdx(sumamp/sumweight);
3320 //------------------------------------------------------------------------
3321 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3324 if (fCoefficients) delete []fCoefficients;
3325 fCoefficients = new Float_t[ntracks*48];
3326 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3328 //------------------------------------------------------------------------
3329 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3335 Float_t theta = track->GetTgl();
3336 Float_t phi = track->GetSnp();
3337 phi = TMath::Sqrt(phi*phi/(1.-phi*phi));
3338 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz);
3339 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz);
3341 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3342 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3344 chi2+=0.5*TMath::Min(delta/2,2.);
3345 chi2+=2.*cluster->GetDeltaProbability();
3348 track->SetNy(layer,ny);
3349 track->SetNz(layer,nz);
3350 track->SetSigmaY(layer,erry);
3351 track->SetSigmaZ(layer, errz);
3352 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3353 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/(1.- track->GetSnp()*track->GetSnp())));
3357 //------------------------------------------------------------------------
3358 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3363 Int_t layer = (index & 0xf0000000) >> 28;
3364 track->SetClIndex(layer, index);
3365 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3366 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3367 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3368 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3372 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3374 //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]);
3377 // Take into account the mis-alignment
3378 Double_t x=track->GetX()+cl->GetX();
3379 if (!track->PropagateTo(x,0.,0.)) return 0;
3381 return track->UpdateMI(cl->GetY(),cl->GetZ(),track->GetSigmaY(layer),track->GetSigmaZ(layer),chi2,index);
3383 //------------------------------------------------------------------------
3384 void AliITStrackerMI::GetDCASigma(AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3387 //DCA sigmas parameterization
3388 //to be paramterized using external parameters in future
3391 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3392 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3394 //------------------------------------------------------------------------
3395 void AliITStrackerMI::SignDeltas( TObjArray *ClusterArray, Float_t vz)
3399 Int_t entries = ClusterArray->GetEntriesFast();
3400 if (entries<4) return;
3401 AliITSRecPoint* cluster = (AliITSRecPoint*)ClusterArray->At(0);
3402 Int_t layer = cluster->GetLayer();
3403 if (layer>1) return;
3405 Int_t ncandidates=0;
3406 Float_t r = (layer>0)? 7:4;
3408 for (Int_t i=0;i<entries;i++){
3409 AliITSRecPoint* cl0 = (AliITSRecPoint*)ClusterArray->At(i);
3410 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3411 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3412 index[ncandidates] = i; //candidate to belong to delta electron track
3414 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3415 cl0->SetDeltaProbability(1);
3421 for (Int_t i=0;i<ncandidates;i++){
3422 AliITSRecPoint* cl0 = (AliITSRecPoint*)ClusterArray->At(index[i]);
3423 if (cl0->GetDeltaProbability()>0.8) continue;
3426 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3427 sumy=sumz=sumy2=sumyz=sumw=0.0;
3428 for (Int_t j=0;j<ncandidates;j++){
3430 AliITSRecPoint* cl1 = (AliITSRecPoint*)ClusterArray->At(index[j]);
3432 Float_t dz = cl0->GetZ()-cl1->GetZ();
3433 Float_t dy = cl0->GetY()-cl1->GetY();
3434 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3435 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3436 y[ncl] = cl1->GetY();
3437 z[ncl] = cl1->GetZ();
3438 sumy+= y[ncl]*weight;
3439 sumz+= z[ncl]*weight;
3440 sumy2+=y[ncl]*y[ncl]*weight;
3441 sumyz+=y[ncl]*z[ncl]*weight;
3446 if (ncl<4) continue;
3447 Float_t det = sumw*sumy2 - sumy*sumy;
3449 if (TMath::Abs(det)>0.01){
3450 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3451 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3452 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3455 Float_t z0 = sumyz/sumy;
3456 delta = TMath::Abs(cl0->GetZ()-z0);
3459 cl0->SetDeltaProbability(1-20.*delta);
3463 //------------------------------------------------------------------------
3464 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3468 track->UpdateESDtrack(flags);
3469 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3470 if (oldtrack) delete oldtrack;
3471 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3472 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3473 printf("Problem\n");
3476 //------------------------------------------------------------------------
3477 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3479 //Get nearest upper layer close to the point xr.
3480 // rough approximation
3482 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3483 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3485 for (Int_t i=0;i<6;i++){
3486 if (radius<kRadiuses[i]){
3493 //------------------------------------------------------------------------
3494 void AliITStrackerMI::UpdateTPCV0(AliESDEvent *event){
3496 //try to update, or reject TPC V0s
3498 Int_t nv0s = event->GetNumberOfV0s();
3499 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3501 for (Int_t i=0;i<nv0s;i++){
3502 AliESDv0 * vertex = event->GetV0(i);
3503 Int_t ip = vertex->GetIndex(0);
3504 Int_t im = vertex->GetIndex(1);
3506 TObjArray * arrayp = (ip<nitstracks) ? (TObjArray*)fTrackHypothesys.At(ip):0;
3507 TObjArray * arraym = (im<nitstracks) ? (TObjArray*)fTrackHypothesys.At(im):0;
3508 AliITStrackMI * trackp = (arrayp!=0) ? (AliITStrackMI*)arrayp->At(0):0;
3509 AliITStrackMI * trackm = (arraym!=0) ? (AliITStrackMI*)arraym->At(0):0;
3513 if (trackp->GetNumberOfClusters()+trackp->GetNDeadZone()>5.5){
3514 if (trackp->GetConstrain()&&trackp->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3515 if (!trackp->GetConstrain()&&trackp->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3520 if (trackm->GetNumberOfClusters()+trackm->GetNDeadZone()>5.5){
3521 if (trackm->GetConstrain()&&trackm->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3522 if (!trackm->GetConstrain()&&trackm->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3525 if (vertex->GetStatus()==-100) continue;
3527 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
3528 Int_t clayer = GetNearestLayer(xrp); //I.B.
3529 vertex->SetNBefore(clayer); //
3530 vertex->SetChi2Before(9*clayer); //
3531 vertex->SetNAfter(6-clayer); //
3532 vertex->SetChi2After(0); //
3534 if (clayer >1 ){ // calculate chi2 before vertex
3535 Float_t chi2p = 0, chi2m=0;
3538 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3539 if (trackp->GetClIndex(ilayer)>0){
3540 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3541 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3552 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3553 if (trackm->GetClIndex(ilayer)>0){
3554 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3555 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3564 vertex->SetChi2Before(TMath::Min(chi2p,chi2m));
3565 if (TMath::Min(chi2p,chi2m)/Float_t(clayer)<4) vertex->SetStatus(-10); // track exist before vertex
3568 if (clayer < 5 ){ // calculate chi2 after vertex
3569 Float_t chi2p = 0, chi2m=0;
3571 if (trackp&&TMath::Abs(trackp->GetTgl())<1.){
3572 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3573 if (trackp->GetClIndex(ilayer)>0){
3574 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3575 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3585 if (trackm&&TMath::Abs(trackm->GetTgl())<1.){
3586 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3587 if (trackm->GetClIndex(ilayer)>0){
3588 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3589 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3598 vertex->SetChi2After(TMath::Max(chi2p,chi2m));
3599 if (TMath::Max(chi2m,chi2p)/Float_t(6-clayer)>9) vertex->SetStatus(-20); // track not found in ITS
3604 //------------------------------------------------------------------------
3605 void AliITStrackerMI::FindV02(AliESDEvent *event)
3610 // Cuts on DCA - R dependent
3611 // max distance DCA between 2 tracks cut
3612 // maxDist = TMath::Min(kMaxDist,kMaxDist0+pvertex->GetRr()*kMaxDist);
3614 const Float_t kMaxDist0 = 0.1;
3615 const Float_t kMaxDist1 = 0.1;
3616 const Float_t kMaxDist = 1;
3617 const Float_t kMinPointAngle = 0.85;
3618 const Float_t kMinPointAngle2 = 0.99;
3619 const Float_t kMinR = 0.5;
3620 const Float_t kMaxR = 220;
3621 //const Float_t kCausality0Cut = 0.19;
3622 //const Float_t kLikelihood01Cut = 0.25;
3623 //const Float_t kPointAngleCut = 0.9996;
3624 const Float_t kCausality0Cut = 0.19;
3625 const Float_t kLikelihood01Cut = 0.45;
3626 const Float_t kLikelihood1Cut = 0.5;
3627 const Float_t kCombinedCut = 0.55;
3631 TTreeSRedirector &cstream = *fDebugStreamer;
3632 Int_t ntracks = event->GetNumberOfTracks();
3633 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3634 fOriginal.Expand(ntracks);
3635 fTrackHypothesys.Expand(ntracks);
3636 fBestHypothesys.Expand(ntracks);
3638 AliHelix * helixes = new AliHelix[ntracks+2];
3639 TObjArray trackarray(ntracks+2); //array with tracks - with vertex constrain
3640 TObjArray trackarrayc(ntracks+2); //array of "best tracks" - without vertex constrain
3641 TObjArray trackarrayl(ntracks+2); //array of "longest tracks" - without vertex constrain
3642 Bool_t * forbidden = new Bool_t [ntracks+2];
3643 Int_t *itsmap = new Int_t [ntracks+2];
3644 Float_t *dist = new Float_t[ntracks+2];
3645 Float_t *normdist0 = new Float_t[ntracks+2];
3646 Float_t *normdist1 = new Float_t[ntracks+2];
3647 Float_t *normdist = new Float_t[ntracks+2];
3648 Float_t *norm = new Float_t[ntracks+2];
3649 Float_t *maxr = new Float_t[ntracks+2];
3650 Float_t *minr = new Float_t[ntracks+2];
3651 Float_t *minPointAngle= new Float_t[ntracks+2];
3653 AliV0 *pvertex = new AliV0;
3654 AliITStrackMI * dummy= new AliITStrackMI;
3656 AliITStrackMI trackat0; //temporary track for DCA calculation
3658 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
3660 // make ITS - ESD map
3662 for (Int_t itrack=0;itrack<ntracks+2;itrack++) {
3663 itsmap[itrack] = -1;
3664 forbidden[itrack] = kFALSE;
3665 maxr[itrack] = kMaxR;
3666 minr[itrack] = kMinR;
3667 minPointAngle[itrack] = kMinPointAngle;
3669 for (Int_t itrack=0;itrack<nitstracks;itrack++){
3670 AliITStrackMI * original = (AliITStrackMI*)(fOriginal.At(itrack));
3671 Int_t esdindex = original->GetESDtrack()->GetID();
3672 itsmap[esdindex] = itrack;
3675 // create ITS tracks from ESD tracks if not done before
3677 for (Int_t itrack=0;itrack<ntracks;itrack++){
3678 if (itsmap[itrack]>=0) continue;
3679 AliITStrackMI * tpctrack = new AliITStrackMI(*(event->GetTrack(itrack)));
3680 //tpctrack->fD[0] = tpctrack->GetD(GetX(),GetY());
3681 //tpctrack->fD[1] = tpctrack->GetZat(GetX())-GetZ();
3682 tpctrack->GetDZ(GetX(),GetY(),GetZ(),tpctrack->GetDP()); //I.B.
3683 if (tpctrack->GetD(0)<20 && tpctrack->GetD(1)<20){
3684 // tracks which can reach inner part of ITS
3685 // propagate track to outer its volume - with correction for material
3686 CorrectForTPCtoITSDeadZoneMaterial(tpctrack);
3688 itsmap[itrack] = nitstracks;
3689 fOriginal.AddAt(tpctrack,nitstracks);
3693 // fill temporary arrays
3695 for (Int_t itrack=0;itrack<ntracks;itrack++){
3696 AliESDtrack * esdtrack = event->GetTrack(itrack);
3697 Int_t itsindex = itsmap[itrack];
3698 AliITStrackMI *original = (AliITStrackMI*)fOriginal.At(itsmap[itrack]);
3699 if (!original) continue;
3700 AliITStrackMI *bestConst = 0;
3701 AliITStrackMI *bestLong = 0;
3702 AliITStrackMI *best = 0;
3705 TObjArray * array = (TObjArray*) fTrackHypothesys.At(itsindex);
3706 Int_t hentries = (array==0) ? 0 : array->GetEntriesFast();
3707 // Get best track with vertex constrain
3708 for (Int_t ih=0;ih<hentries;ih++){
3709 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
3710 if (!trackh->GetConstrain()) continue;
3711 if (!bestConst) bestConst = trackh;
3712 if (trackh->GetNumberOfClusters()>5.0){
3713 bestConst = trackh; // full track - with minimal chi2
3716 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()) continue;
3720 // Get best long track without vertex constrain and best track without vertex constrain
3721 for (Int_t ih=0;ih<hentries;ih++){
3722 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
3723 if (trackh->GetConstrain()) continue;
3724 if (!best) best = trackh;
3725 if (!bestLong) bestLong = trackh;
3726 if (trackh->GetNumberOfClusters()>5.0){
3727 bestLong = trackh; // full track - with minimal chi2
3730 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()) continue;
3735 bestLong = original;
3737 //I.B. trackat0 = *bestLong;
3738 new (&trackat0) AliITStrackMI(*bestLong);
3739 Double_t xx,yy,zz,alpha;
3740 bestLong->GetGlobalXYZat(bestLong->GetX(),xx,yy,zz);
3741 alpha = TMath::ATan2(yy,xx);
3742 trackat0.Propagate(alpha,0);
3743 // calculate normalized distances to the vertex
3745 Float_t ptfac = (1.+100.*TMath::Abs(trackat0.GetC()));
3746 if ( bestLong->GetNumberOfClusters()>3 ){
3747 dist[itsindex] = trackat0.GetY();
3748 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
3749 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
3750 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
3751 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3753 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<6) normdist[itsindex]*=2.;
3754 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<5) normdist[itsindex]*=2.;
3755 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<4) normdist[itsindex]*=2.;
3757 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<6) normdist[itsindex]*=1.5;
3758 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<5) normdist[itsindex]*=1.5;
3762 if (bestConst&&bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5){
3763 dist[itsindex] = bestConst->GetD(0);
3764 norm[itsindex] = bestConst->GetDnorm(0);
3765 normdist0[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
3766 normdist1[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
3767 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3769 dist[itsindex] = trackat0.GetY();
3770 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
3771 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
3772 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
3773 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3774 if (TMath::Abs(trackat0.GetTgl())>1.05){
3775 if (normdist[itsindex]<3) forbidden[itsindex]=kTRUE;
3776 if (normdist[itsindex]>3) {
3777 minr[itsindex] = TMath::Max(Float_t(40.),minr[itsindex]);
3783 //-----------------------------------------------------------
3784 //Forbid primary track candidates -
3786 //treetr->SetAlias("forbidden0","Tr0.fN<4&&Tr1.fN+Tr1.fNDeadZone>4.5");
3787 //treetr->SetAlias("forbidden1","ND<3&&Tr1.fN+Tr1.fNDeadZone>5.5");
3788 //treetr->SetAlias("forbidden2","ND<2&&Tr1.fClIndex[0]>0&&Tr1.fClIndex[0]>0");
3789 //treetr->SetAlias("forbidden3","ND<1&&Tr1.fClIndex[0]>0");
3790 //treetr->SetAlias("forbidden4","ND<4&&Tr1.fNormChi2[0]<2");
3791 //treetr->SetAlias("forbidden5","ND<5&&Tr1.fNormChi2[0]<1");
3792 //-----------------------------------------------------------
3794 if (bestLong->GetNumberOfClusters()<4 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5) forbidden[itsindex]=kTRUE;
3795 if (normdist[itsindex]<3 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>5.5) forbidden[itsindex]=kTRUE;
3796 if (normdist[itsindex]<2 && bestConst->GetClIndex(0)>0 && bestConst->GetClIndex(1)>0 ) forbidden[itsindex]=kTRUE;
3797 if (normdist[itsindex]<1 && bestConst->GetClIndex(0)>0) forbidden[itsindex]=kTRUE;
3798 if (normdist[itsindex]<4 && bestConst->GetNormChi2(0)<2) forbidden[itsindex]=kTRUE;
3799 if (normdist[itsindex]<5 && bestConst->GetNormChi2(0)<1) forbidden[itsindex]=kTRUE;
3800 if (bestConst->GetNormChi2(0)<2.5) {
3801 minPointAngle[itsindex]= 0.9999;
3802 maxr[itsindex] = 10;
3806 //forbid daughter kink candidates
3808 if (esdtrack->GetKinkIndex(0)>0) forbidden[itsindex] = kTRUE;
3809 Bool_t isElectron = kTRUE;
3810 Bool_t isProton = kTRUE;
3812 esdtrack->GetESDpid(pid);
3813 for (Int_t i=1;i<5;i++){
3814 if (pid[0]<pid[i]) isElectron= kFALSE;
3815 if (pid[4]<pid[i]) isProton= kFALSE;
3818 forbidden[itsindex]=kFALSE;
3819 normdist[itsindex]*=-1;
3822 if (normdist[itsindex]>2) forbidden[itsindex]=kFALSE;
3823 normdist[itsindex]*=-1;
3827 // Causality cuts in TPC volume
3829 if (esdtrack->GetTPCdensity(0,10) >0.6) maxr[itsindex] = TMath::Min(Float_t(110),maxr[itsindex]);
3830 if (esdtrack->GetTPCdensity(10,30)>0.6) maxr[itsindex] = TMath::Min(Float_t(120),maxr[itsindex]);
3831 if (esdtrack->GetTPCdensity(20,40)>0.6) maxr[itsindex] = TMath::Min(Float_t(130),maxr[itsindex]);
3832 if (esdtrack->GetTPCdensity(30,50)>0.6) maxr[itsindex] = TMath::Min(Float_t(140),maxr[itsindex]);
3834 if (esdtrack->GetTPCdensity(0,60)<0.4&&bestLong->GetNumberOfClusters()<3) minr[itsindex]=100;
3840 "Tr1.="<<((bestConst)? bestConst:dummy)<<
3842 "Tr3.="<<&trackat0<<
3844 "Dist="<<dist[itsindex]<<
3845 "ND0="<<normdist0[itsindex]<<
3846 "ND1="<<normdist1[itsindex]<<
3847 "ND="<<normdist[itsindex]<<
3848 "Pz="<<primvertex[2]<<
3849 "Forbid="<<forbidden[itsindex]<<
3853 trackarray.AddAt(best,itsindex);
3854 trackarrayc.AddAt(bestConst,itsindex);
3855 trackarrayl.AddAt(bestLong,itsindex);
3856 new (&helixes[itsindex]) AliHelix(*best);
3861 // first iterration of V0 finder
3863 for (Int_t iesd0=0;iesd0<ntracks;iesd0++){
3864 Int_t itrack0 = itsmap[iesd0];
3865 if (forbidden[itrack0]) continue;
3866 AliITStrackMI * btrack0 = (AliITStrackMI*)trackarray.At(itrack0);
3867 if (!btrack0) continue;
3868 if (btrack0->GetSign()>0) continue;
3869 AliITStrackMI *trackc0 = (AliITStrackMI*)trackarrayc.At(itrack0);
3871 for (Int_t iesd1=0;iesd1<ntracks;iesd1++){
3872 Int_t itrack1 = itsmap[iesd1];
3873 if (forbidden[itrack1]) continue;
3875 AliITStrackMI * btrack1 = (AliITStrackMI*)trackarray.At(itrack1);
3876 if (!btrack1) continue;
3877 if (btrack1->GetSign()<0) continue;
3878 Bool_t isGold = kFALSE;
3879 if (TMath::Abs(TMath::Abs(btrack0->GetLabel())-TMath::Abs(btrack1->GetLabel()))==1){
3882 AliITStrackMI *trackc1 = (AliITStrackMI*)trackarrayc.At(itrack1);
3883 AliHelix &h1 = helixes[itrack0];
3884 AliHelix &h2 = helixes[itrack1];
3886 // find linear distance
3891 Double_t phase[2][2],radius[2];
3892 Int_t points = h1.GetRPHIintersections(h2, phase, radius);
3893 if (points==0) continue;
3894 Double_t delta[2]={1000000,1000000};
3896 h1.ParabolicDCA(h2,phase[0][0],phase[0][1],radius[0],delta[0]);
3898 if (radius[1]<rmin) rmin = radius[1];
3899 h1.ParabolicDCA(h2,phase[1][0],phase[1][1],radius[1],delta[1]);
3901 rmin = TMath::Sqrt(rmin);
3902 Double_t distance = 0;
3903 Double_t radiusC = 0;
3905 if (points==1 || delta[0]<delta[1]){
3906 distance = TMath::Sqrt(delta[0]);
3907 radiusC = TMath::Sqrt(radius[0]);
3909 distance = TMath::Sqrt(delta[1]);
3910 radiusC = TMath::Sqrt(radius[1]);
3913 if (radiusC<TMath::Max(minr[itrack0],minr[itrack1])) continue;
3914 if (radiusC>TMath::Min(maxr[itrack0],maxr[itrack1])) continue;
3915 Float_t maxDist = TMath::Min(kMaxDist,Float_t(kMaxDist0+radiusC*kMaxDist1));
3916 if (distance>maxDist) continue;
3917 Float_t pointAngle = h1.GetPointAngle(h2,phase[iphase],primvertex);
3918 if (pointAngle<TMath::Max(minPointAngle[itrack0],minPointAngle[itrack1])) continue;
3921 // Double_t distance = TestV0(h1,h2,pvertex,rmin);
3923 // if (distance>maxDist) continue;
3924 // if (pvertex->GetRr()<kMinR) continue;
3925 // if (pvertex->GetRr()>kMaxR) continue;
3926 AliITStrackMI * track0=btrack0;
3927 AliITStrackMI * track1=btrack1;
3928 // if (pvertex->GetRr()<3.5){
3930 //use longest tracks inside the pipe
3931 track0 = (AliITStrackMI*)trackarrayl.At(itrack0);
3932 track1 = (AliITStrackMI*)trackarrayl.At(itrack1);
3936 pvertex->SetParamN(*track0);
3937 pvertex->SetParamP(*track1);
3938 pvertex->Update(primvertex);
3939 pvertex->SetClusters(track0->ClIndex(),track1->ClIndex()); // register clusters
3941 if (pvertex->GetRr()<kMinR) continue;
3942 if (pvertex->GetRr()>kMaxR) continue;
3943 if (pvertex->GetV0CosineOfPointingAngle()<kMinPointAngle) continue;
3944 //Bo: if (pvertex->GetDist2()>maxDist) continue;
3945 if (pvertex->GetDcaV0Daughters()>maxDist) continue;
3946 //Bo: pvertex->SetLab(0,track0->GetLabel());
3947 //Bo: pvertex->SetLab(1,track1->GetLabel());
3948 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
3949 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
3951 AliITStrackMI * htrackc0 = trackc0 ? trackc0:dummy;
3952 AliITStrackMI * htrackc1 = trackc1 ? trackc1:dummy;
3956 TObjArray * array0b = (TObjArray*)fBestHypothesys.At(itrack0);
3957 if (!array0b&&pvertex->GetRr()<40 && TMath::Abs(track0->GetTgl())<1.1)
3958 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack0),itrack0, kFALSE);
3959 TObjArray * array1b = (TObjArray*)fBestHypothesys.At(itrack1);
3960 if (!array1b&&pvertex->GetRr()<40 && TMath::Abs(track1->GetTgl())<1.1)
3961 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack1),itrack1, kFALSE);
3963 AliITStrackMI * track0b = (AliITStrackMI*)fOriginal.At(itrack0);
3964 AliITStrackMI * track1b = (AliITStrackMI*)fOriginal.At(itrack1);
3965 AliITStrackMI * track0l = (AliITStrackMI*)fOriginal.At(itrack0);
3966 AliITStrackMI * track1l = (AliITStrackMI*)fOriginal.At(itrack1);
3968 Float_t minchi2before0=16;
3969 Float_t minchi2before1=16;
3970 Float_t minchi2after0 =16;
3971 Float_t minchi2after1 =16;
3972 Double_t xrp[3]; pvertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
3973 Int_t maxLayer = GetNearestLayer(xrp); //I.B.
3975 if (array0b) for (Int_t i=0;i<5;i++){
3976 // best track after vertex
3977 AliITStrackMI * btrack = (AliITStrackMI*)array0b->At(i);
3978 if (!btrack) continue;
3979 if (btrack->GetNumberOfClusters()>track0l->GetNumberOfClusters()) track0l = btrack;
3980 // if (btrack->fX<pvertex->GetRr()-2.-0.5/(0.1+pvertex->GetAnglep()[2])) {
3981 if (btrack->GetX()<pvertex->GetRr()-2.) {
3982 if ( (maxLayer>i+2|| (i==0)) && btrack->GetNumberOfClusters()==(6-i)&&i<3){
3985 if (maxLayer<3){ // take prim vertex as additional measurement
3986 if (normdist[itrack0]>0 && htrackc0){
3987 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack0]*normdist[itrack0],16.);
3989 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack0]*normdist[itrack0]+3.),16.);
3993 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
3995 if (!btrack->GetClIndex(ilayer)){
3999 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4000 for (Int_t itrack=0;itrack<4;itrack++){
4001 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack0){
4002 sumchi2+=18.; //shared cluster
4006 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4007 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4011 if (sumchi2<minchi2before0) minchi2before0=sumchi2;
4013 continue; //safety space - Geo manager will give exact layer
4016 minchi2after0 = btrack->GetNormChi2(i);
4019 if (array1b) for (Int_t i=0;i<5;i++){
4020 // best track after vertex
4021 AliITStrackMI * btrack = (AliITStrackMI*)array1b->At(i);
4022 if (!btrack) continue;
4023 if (btrack->GetNumberOfClusters()>track1l->GetNumberOfClusters()) track1l = btrack;
4024 // if (btrack->fX<pvertex->GetRr()-2-0.5/(0.1+pvertex->GetAnglep()[2])){
4025 if (btrack->GetX()<pvertex->GetRr()-2){
4026 if ((maxLayer>i+2 || (i==0))&&btrack->GetNumberOfClusters()==(6-i)&&(i<3)){
4029 if (maxLayer<3){ // take prim vertex as additional measurement
4030 if (normdist[itrack1]>0 && htrackc1){
4031 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack1]*normdist[itrack1],16.);
4033 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack1]*normdist[itrack1]+3.),16.);
4037 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4039 if (!btrack->GetClIndex(ilayer)){
4043 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4044 for (Int_t itrack=0;itrack<4;itrack++){
4045 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack1){
4046 sumchi2+=18.; //shared cluster
4050 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4051 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4055 if (sumchi2<minchi2before1) minchi2before1=sumchi2;
4057 continue; //safety space - Geo manager will give exact layer
4060 minchi2after1 = btrack->GetNormChi2(i);
4064 // position resolution - used for DCA cut
4065 Float_t sigmad = track0b->GetSigmaY2()+track0b->GetSigmaZ2()+track1b->GetSigmaY2()+track1b->GetSigmaZ2()+
4066 (track0b->GetX()-pvertex->GetRr())*(track0b->GetX()-pvertex->GetRr())*(track0b->GetSigmaSnp2()+track0b->GetSigmaTgl2())+
4067 (track1b->GetX()-pvertex->GetRr())*(track1b->GetX()-pvertex->GetRr())*(track1b->GetSigmaSnp2()+track1b->GetSigmaTgl2());
4068 sigmad =TMath::Sqrt(sigmad)+0.04;
4069 if (pvertex->GetRr()>50){
4070 Double_t cov0[15],cov1[15];
4071 track0b->GetESDtrack()->GetInnerExternalCovariance(cov0);
4072 track1b->GetESDtrack()->GetInnerExternalCovariance(cov1);
4073 sigmad = cov0[0]+cov0[2]+cov1[0]+cov1[2]+
4074 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov0[5]+cov0[9])+
4075 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov1[5]+cov1[9]);
4076 sigmad =TMath::Sqrt(sigmad)+0.05;
4080 vertex2.SetParamN(*track0b);
4081 vertex2.SetParamP(*track1b);
4082 vertex2.Update(primvertex);
4083 //Bo: if (vertex2.GetDist2()<=pvertex->GetDist2()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4084 if (vertex2.GetDcaV0Daughters()<=pvertex->GetDcaV0Daughters()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4085 pvertex->SetParamN(*track0b);
4086 pvertex->SetParamP(*track1b);
4087 pvertex->Update(primvertex);
4088 pvertex->SetClusters(track0b->ClIndex(),track1b->ClIndex()); // register clusters
4089 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4090 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4092 pvertex->SetDistSigma(sigmad);
4093 //Bo: pvertex->SetDistNorm(pvertex->GetDist2()/sigmad);
4094 pvertex->SetNormDCAPrim(normdist[itrack0],normdist[itrack1]);
4096 // define likelihhod and causalities
4098 Float_t pa0=1, pa1=1, pb0=0.26, pb1=0.26;
4100 Float_t fnorm0 = normdist[itrack0];
4101 if (fnorm0<0) fnorm0*=-3;
4102 Float_t fnorm1 = normdist[itrack1];
4103 if (fnorm1<0) fnorm1*=-3;
4104 if (pvertex->GetAnglep()[2]>0.1 || (pvertex->GetRr()<10.5)&& pvertex->GetAnglep()[2]>0.05 || pvertex->GetRr()<3){
4105 pb0 = TMath::Exp(-TMath::Min(fnorm0,Float_t(16.))/12.);
4106 pb1 = TMath::Exp(-TMath::Min(fnorm1,Float_t(16.))/12.);
4108 pvertex->SetChi2Before(normdist[itrack0]);
4109 pvertex->SetChi2After(normdist[itrack1]);
4110 pvertex->SetNAfter(0);
4111 pvertex->SetNBefore(0);
4113 pvertex->SetChi2Before(minchi2before0);
4114 pvertex->SetChi2After(minchi2before1);
4115 if (pvertex->GetAnglep()[2]>0.1 || ( pvertex->GetRr()<10.5 && pvertex->GetAnglep()[2]>0.05) || pvertex->GetRr()<3){
4116 pb0 = TMath::Exp(-TMath::Min(minchi2before0,Float_t(16))/12.);
4117 pb1 = TMath::Exp(-TMath::Min(minchi2before1,Float_t(16))/12.);
4119 pvertex->SetNAfter(maxLayer);
4120 pvertex->SetNBefore(maxLayer);
4122 if (pvertex->GetRr()<90){
4123 pa0 *= TMath::Min(track0->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4124 pa1 *= TMath::Min(track1->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4126 if (pvertex->GetRr()<20){
4127 pa0 *= (0.2+TMath::Exp(-TMath::Min(minchi2after0,Float_t(16))/8.))/1.2;
4128 pa1 *= (0.2+TMath::Exp(-TMath::Min(minchi2after1,Float_t(16))/8.))/1.2;
4131 pvertex->SetCausality(pb0,pb1,pa0,pa1);
4133 // Likelihood calculations - apply cuts
4135 Bool_t v0OK = kTRUE;
4136 Float_t p12 = pvertex->GetParamP()->GetParameter()[4]*pvertex->GetParamP()->GetParameter()[4];
4137 p12 += pvertex->GetParamN()->GetParameter()[4]*pvertex->GetParamN()->GetParameter()[4];
4138 p12 = TMath::Sqrt(p12); // "mean" momenta
4139 Float_t sigmap0 = 0.0001+0.001/(0.1+pvertex->GetRr());
4140 Float_t sigmap = 0.5*sigmap0*(0.6+0.4*p12); // "resolution: of point angle - as a function of radius and momenta
4142 Float_t causalityA = (1.0-pvertex->GetCausalityP()[0])*(1.0-pvertex->GetCausalityP()[1]);
4143 Float_t causalityB = TMath::Sqrt(TMath::Min(pvertex->GetCausalityP()[2],Double_t(0.7))*
4144 TMath::Min(pvertex->GetCausalityP()[3],Double_t(0.7)));
4146 //Bo: Float_t likelihood0 = (TMath::Exp(-pvertex->GetDistNorm())+0.1) *(pvertex->GetDist2()<0.5)*(pvertex->GetDistNorm()<5);
4147 Float_t lDistNorm = pvertex->GetDcaV0Daughters()/pvertex->GetDistSigma();
4148 Float_t likelihood0 = (TMath::Exp(-lDistNorm)+0.1) *(pvertex->GetDcaV0Daughters()<0.5)*(lDistNorm<5);
4150 Float_t likelihood1 = TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/sigmap)+
4151 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(4.*sigmap))+
4152 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(8.*sigmap))+
4153 0.1*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/0.01);
4155 if (causalityA<kCausality0Cut) v0OK = kFALSE;
4156 if (TMath::Sqrt(likelihood0*likelihood1)<kLikelihood01Cut) v0OK = kFALSE;
4157 if (likelihood1<kLikelihood1Cut) v0OK = kFALSE;
4158 if (TMath::Power(likelihood0*likelihood1*causalityB,0.33)<kCombinedCut) v0OK = kFALSE;
4163 Bool_t gold = TMath::Abs(TMath::Abs(track0->GetLabel())-TMath::Abs(track1->GetLabel()))==1;
4165 "Tr0.="<<track0<< //best without constrain
4166 "Tr1.="<<track1<< //best without constrain
4167 "Tr0B.="<<track0b<< //best without constrain after vertex
4168 "Tr1B.="<<track1b<< //best without constrain after vertex
4169 "Tr0C.="<<htrackc0<< //best with constrain if exist
4170 "Tr1C.="<<htrackc1<< //best with constrain if exist
4171 "Tr0L.="<<track0l<< //longest best
4172 "Tr1L.="<<track1l<< //longest best
4173 "Esd0.="<<track0->GetESDtrack()<< // esd track0 params
4174 "Esd1.="<<track1->GetESDtrack()<< // esd track1 params
4175 "V0.="<<pvertex<< //vertex properties
4176 "V0b.="<<&vertex2<< //vertex properties at "best" track
4177 "ND0="<<normdist[itrack0]<< //normalize distance for track0
4178 "ND1="<<normdist[itrack1]<< //normalize distance for track1
4180 // "RejectBase="<<rejectBase<< //rejection in First itteration
4186 //if (rejectBase) continue;
4188 pvertex->SetStatus(0);
4189 // if (rejectBase) {
4190 // pvertex->SetStatus(-100);
4192 if (pvertex->GetV0CosineOfPointingAngle()>kMinPointAngle2) {
4193 //Bo: pvertex->SetESDindexes(track0->GetESDtrack()->GetID(),track1->GetESDtrack()->GetID());
4194 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());//Bo: consistency 0 for neg
4195 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());//Bo: consistency 1 for pos
4197 // AliV0vertex vertexjuri(*track0,*track1);
4198 // vertexjuri.SetESDindexes(track0->fESDtrack->GetID(),track1->fESDtrack->GetID());
4199 // event->AddV0(&vertexjuri);
4200 pvertex->SetStatus(100);
4202 pvertex->SetOnFlyStatus(kTRUE);
4203 pvertex->ChangeMassHypothesis(kK0Short);
4204 event->AddV0(pvertex);
4210 // delete temporary arrays
4213 delete[] minPointAngle;
4225 //------------------------------------------------------------------------
4226 void AliITStrackerMI::RefitV02(AliESDEvent *event)
4229 //try to refit V0s in the third path of the reconstruction
4231 TTreeSRedirector &cstream = *fDebugStreamer;
4233 Int_t nv0s = event->GetNumberOfV0s();
4234 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
4236 for (Int_t iv0 = 0; iv0<nv0s;iv0++){
4237 AliV0 * v0mi = (AliV0*)event->GetV0(iv0);
4238 if (!v0mi) continue;
4239 Int_t itrack0 = v0mi->GetIndex(0);
4240 Int_t itrack1 = v0mi->GetIndex(1);
4241 AliESDtrack *esd0 = event->GetTrack(itrack0);
4242 AliESDtrack *esd1 = event->GetTrack(itrack1);
4243 if (!esd0||!esd1) continue;
4244 AliITStrackMI tpc0(*esd0);
4245 AliITStrackMI tpc1(*esd1);
4246 Double_t x,y,z; v0mi->GetXYZ(x,y,z); //I.B.
4247 Double_t alpha =TMath::ATan2(y,x); //I.B.
4248 if (v0mi->GetRr()>85){
4249 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4250 v0temp.SetParamN(tpc0);
4251 v0temp.SetParamP(tpc1);
4252 v0temp.Update(primvertex);
4253 if (kFALSE) cstream<<"Refit"<<
4255 "V0refit.="<<&v0temp<<
4259 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4260 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4261 v0mi->SetParamN(tpc0);
4262 v0mi->SetParamP(tpc1);
4263 v0mi->Update(primvertex);
4268 if (v0mi->GetRr()>35){
4269 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4270 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4271 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4272 v0temp.SetParamN(tpc0);
4273 v0temp.SetParamP(tpc1);
4274 v0temp.Update(primvertex);
4275 if (kFALSE) cstream<<"Refit"<<
4277 "V0refit.="<<&v0temp<<
4281 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4282 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4283 v0mi->SetParamN(tpc0);
4284 v0mi->SetParamP(tpc1);
4285 v0mi->Update(primvertex);
4290 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4291 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4292 // if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4293 if (RefitAt(v0mi->GetRr(),&tpc0, v0mi->GetClusters(0)) && RefitAt(v0mi->GetRr(),&tpc1, v0mi->GetClusters(1))){
4294 v0temp.SetParamN(tpc0);
4295 v0temp.SetParamP(tpc1);
4296 v0temp.Update(primvertex);
4297 if (kFALSE) cstream<<"Refit"<<
4299 "V0refit.="<<&v0temp<<
4303 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4304 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4305 v0mi->SetParamN(tpc0);
4306 v0mi->SetParamP(tpc1);
4307 v0mi->Update(primvertex);
4312 //------------------------------------------------------------------------
4313 void AliITStrackerMI::BuildMaterialLUT(TString material) {
4314 //--------------------------------------------------------------------
4315 // Fill a look-up table with mean material
4316 //--------------------------------------------------------------------
4320 Double_t point1[3],point2[3];
4321 Double_t phi,cosphi,sinphi,z;
4322 // 0-5 layers, 6 pipe, 7-8 shields
4323 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 7.5,25.0};
4324 Double_t rmax[9]={ 5.5, 7.3,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
4326 Int_t ifirst=0,ilast=0;
4327 if(material.Contains("Pipe")) {
4329 } else if(material.Contains("Shields")) {
4331 } else if(material.Contains("Layers")) {
4334 Error("BuildMaterialLUT","Wrong layer name\n");
4337 for(Int_t imat=ifirst; imat<=ilast; imat++) {
4338 Double_t param[5]={0.,0.,0.,0.,0.};
4339 for (Int_t i=0; i<n; i++) {
4340 phi = 2.*TMath::Pi()*gRandom->Rndm();
4341 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
4342 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
4343 point1[0] = rmin[imat]*cosphi;
4344 point1[1] = rmin[imat]*sinphi;
4346 point2[0] = rmax[imat]*cosphi;
4347 point2[1] = rmax[imat]*sinphi;
4349 AliTracker::MeanMaterialBudget(point1,point2,mparam);
4350 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
4352 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
4354 fxOverX0Layer[imat] = param[1];
4355 fxTimesRhoLayer[imat] = param[0]*param[4];
4356 } else if(imat==6) {
4357 fxOverX0Pipe = param[1];
4358 fxTimesRhoPipe = param[0]*param[4];
4359 } else if(imat==7) {
4360 fxOverX0Shield[0] = param[1];
4361 fxTimesRhoShield[0] = param[0]*param[4];
4362 } else if(imat==8) {
4363 fxOverX0Shield[1] = param[1];
4364 fxTimesRhoShield[1] = param[0]*param[4];
4368 printf("%s\n",material.Data());
4369 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
4370 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
4371 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
4372 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
4373 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
4374 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
4375 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
4376 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
4377 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
4381 //------------------------------------------------------------------------
4382 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
4383 TString direction) {
4384 //-------------------------------------------------------------------
4385 // Propagate beyond beam pipe and correct for material
4386 // (material budget in different ways according to fUseTGeo value)
4387 //-------------------------------------------------------------------
4389 // Define budget mode:
4390 // 0: material from AliITSRecoParam (hard coded)
4391 // 1: material from TGeo (on the fly)
4392 // 2: material from lut
4393 // 3: material from TGeo (same for all hypotheses)
4406 if(fTrackingPhase.Contains("Clusters2Tracks"))
4407 { mode=3; } else { mode=1; }
4410 if(fTrackingPhase.Contains("Clusters2Tracks"))
4411 { mode=3; } else { mode=2; }
4417 if(fTrackingPhase.Contains("Default")) mode=0;
4419 Int_t index=fCurrentEsdTrack;
4421 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4422 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4423 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4425 Double_t xOverX0,x0,lengthTimesMeanDensity;
4426 Bool_t anglecorr=kTRUE;
4430 xOverX0 = AliITSRecoParam::GetdPipe();
4431 x0 = AliITSRecoParam::GetX0Be();
4432 lengthTimesMeanDensity = xOverX0*x0;
4435 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4439 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4440 xOverX0 = fxOverX0Pipe;
4441 lengthTimesMeanDensity = fxTimesRhoPipe;
4444 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4445 if(fxOverX0PipeTrks[index]<0) {
4446 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4447 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4448 (1.-t->GetSnp()*t->GetSnp()));
4449 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4450 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4453 xOverX0 = fxOverX0PipeTrks[index];
4454 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4458 lengthTimesMeanDensity *= dir;
4460 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4461 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4465 //------------------------------------------------------------------------
4466 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4468 TString direction) {
4469 //-------------------------------------------------------------------
4470 // Propagate beyond SPD or SDD shield and correct for material
4471 // (material budget in different ways according to fUseTGeo value)
4472 //-------------------------------------------------------------------
4474 // Define budget mode:
4475 // 0: material from AliITSRecoParam (hard coded)
4476 // 1: material from TGeo (on the fly)
4477 // 2: material from lut
4478 // 3: material from TGeo (same for all hypotheses)
4491 if(fTrackingPhase.Contains("Clusters2Tracks"))
4492 { mode=3; } else { mode=1; }
4495 if(fTrackingPhase.Contains("Clusters2Tracks"))
4496 { mode=3; } else { mode=2; }
4502 if(fTrackingPhase.Contains("Default")) mode=0;
4504 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4506 Int_t shieldindex=0;
4507 if (shield.Contains("SDD")) { // SDDouter
4508 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4510 } else if (shield.Contains("SPD")) { // SPDouter
4511 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4514 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4515 // printf("%s\n",shield.Data());
4518 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4520 Int_t index=2*fCurrentEsdTrack+shieldindex;
4522 Double_t xOverX0,x0,lengthTimesMeanDensity;
4523 Bool_t anglecorr=kTRUE;
4527 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4528 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4529 lengthTimesMeanDensity = xOverX0*x0;
4532 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4536 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4537 xOverX0 = fxOverX0Shield[shieldindex];
4538 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4541 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4542 if(fxOverX0ShieldTrks[index]<0) {
4543 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4544 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4545 (1.-t->GetSnp()*t->GetSnp()));
4546 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4547 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4550 xOverX0 = fxOverX0ShieldTrks[index];
4551 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4555 lengthTimesMeanDensity *= dir;
4557 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4558 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4562 //------------------------------------------------------------------------
4563 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4565 Double_t oldGlobXYZ[3],
4566 TString direction) {
4567 //-------------------------------------------------------------------
4568 // Propagate beyond layer and correct for material
4569 // (material budget in different ways according to fUseTGeo value)
4570 //-------------------------------------------------------------------
4572 // Define budget mode:
4573 // 0: material from AliITSRecoParam (hard coded)
4574 // 1: material from TGeo (on the fly)
4575 // 2: material from lut
4576 // 3: material from TGeo (same for all hypotheses)
4589 if(fTrackingPhase.Contains("Clusters2Tracks"))
4590 { mode=3; } else { mode=1; }
4593 if(fTrackingPhase.Contains("Clusters2Tracks"))
4594 { mode=3; } else { mode=2; }
4600 if(fTrackingPhase.Contains("Default")) mode=0;
4602 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4604 Double_t r=fgLayers[layerindex].GetR();
4605 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4607 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4608 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4610 Int_t index=6*fCurrentEsdTrack+layerindex;
4612 // Bring the track beyond the material
4613 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4614 Double_t globXYZ[3];
4617 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4619 Bool_t anglecorr=kTRUE;
4623 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4624 lengthTimesMeanDensity = xOverX0*x0;
4627 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4628 if(mparam[1]>900000) return 0;
4630 lengthTimesMeanDensity=mparam[0]*mparam[4];
4634 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4635 xOverX0 = fxOverX0Layer[layerindex];
4636 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4639 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4640 if(fxOverX0LayerTrks[index]<0) {
4641 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4642 if(mparam[1]>900000) return 0;
4643 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4644 (1.-t->GetSnp()*t->GetSnp()));
4645 xOverX0=mparam[1]/angle;
4646 lengthTimesMeanDensity=mparam[0]*mparam[4]/angle;
4647 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0);
4648 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity);
4650 xOverX0 = fxOverX0LayerTrks[index];
4651 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4655 lengthTimesMeanDensity *= dir;
4657 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4661 //------------------------------------------------------------------------
4662 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4663 //-----------------------------------------------------------------
4664 // Initialize LUT for storing material for each prolonged track
4665 //-----------------------------------------------------------------
4666 fxOverX0PipeTrks = new Float_t[ntracks];
4667 fxTimesRhoPipeTrks = new Float_t[ntracks];
4668 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4669 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4670 fxOverX0LayerTrks = new Float_t[ntracks*6];
4671 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4673 for(Int_t i=0; i<ntracks; i++) {
4674 fxOverX0PipeTrks[i] = -1.;
4675 fxTimesRhoPipeTrks[i] = -1.;
4677 for(Int_t j=0; j<ntracks*2; j++) {
4678 fxOverX0ShieldTrks[j] = -1.;
4679 fxTimesRhoShieldTrks[j] = -1.;
4681 for(Int_t k=0; k<ntracks*6; k++) {
4682 fxOverX0LayerTrks[k] = -1.;
4683 fxTimesRhoLayerTrks[k] = -1.;
4690 //------------------------------------------------------------------------
4691 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4692 //-----------------------------------------------------------------
4693 // Delete LUT for storing material for each prolonged track
4694 //-----------------------------------------------------------------
4695 if(fxOverX0PipeTrks) {
4696 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4698 if(fxOverX0ShieldTrks) {
4699 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4702 if(fxOverX0LayerTrks) {
4703 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4705 if(fxTimesRhoPipeTrks) {
4706 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4708 if(fxTimesRhoShieldTrks) {
4709 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4711 if(fxTimesRhoLayerTrks) {
4712 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4716 //------------------------------------------------------------------------
4717 Int_t AliITStrackerMI::SkipLayer(AliITStrackMI *track,
4718 Int_t ilayer,Int_t idet) const {
4719 //-----------------------------------------------------------------
4720 // This method is used to decide whether to allow a prolongation
4721 // without clusters, because we want to skip the layer.
4722 // In this case the return value is > 0:
4723 // return 1: the user requested to skip a layer
4724 // return 2: track outside z acceptance of SSD/SDD and will cross both SPD
4725 //-----------------------------------------------------------------
4727 if (AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) return 1;
4729 if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4730 // check if track will cross SPD outer layer
4731 Double_t phiAtSPD2,zAtSPD2;
4732 if(track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4733 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4739 //------------------------------------------------------------------------