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();
190 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
191 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
195 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
196 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
198 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
201 //------------------------------------------------------------------------
202 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
204 fBestTrack(tracker.fBestTrack),
205 fTrackToFollow(tracker.fTrackToFollow),
206 fTrackHypothesys(tracker.fTrackHypothesys),
207 fBestHypothesys(tracker.fBestHypothesys),
208 fOriginal(tracker.fOriginal),
209 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
210 fPass(tracker.fPass),
211 fAfterV0(tracker.fAfterV0),
212 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
213 fCoefficients(tracker.fCoefficients),
215 fTrackingPhase(tracker.fTrackingPhase),
216 fUseTGeo(tracker.fUseTGeo),
217 fNtracks(tracker.fNtracks),
218 fxOverX0Pipe(tracker.fxOverX0Pipe),
219 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
221 fxTimesRhoPipeTrks(0),
222 fxOverX0ShieldTrks(0),
223 fxTimesRhoShieldTrks(0),
224 fxOverX0LayerTrks(0),
225 fxTimesRhoLayerTrks(0),
226 fDebugStreamer(tracker.fDebugStreamer){
230 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
233 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
234 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
237 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
238 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
241 //------------------------------------------------------------------------
242 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
243 //Assignment operator
244 this->~AliITStrackerMI();
245 new(this) AliITStrackerMI(tracker);
248 //------------------------------------------------------------------------
249 AliITStrackerMI::~AliITStrackerMI()
254 if (fCoefficients) delete [] fCoefficients;
255 DeleteTrksMaterialLUT();
256 if (fDebugStreamer) {
257 //fDebugStreamer->Close();
258 delete fDebugStreamer;
261 //------------------------------------------------------------------------
262 void AliITStrackerMI::SetLayersNotToSkip(Int_t *l) {
263 //--------------------------------------------------------------------
264 //This function set masks of the layers which must be not skipped
265 //--------------------------------------------------------------------
266 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=l[i];
268 //------------------------------------------------------------------------
269 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
270 //--------------------------------------------------------------------
271 //This function loads ITS clusters
272 //--------------------------------------------------------------------
273 TBranch *branch=cTree->GetBranch("ITSRecPoints");
275 Error("LoadClusters"," can't get the branch !\n");
279 TClonesArray dummy("AliITSRecPoint",10000), *clusters=&dummy;
280 branch->SetAddress(&clusters);
284 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
285 Int_t ndet=fgLayers[i].GetNdetectors();
286 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
287 for (; j<jmax; j++) {
288 if (!cTree->GetEvent(j)) continue;
289 Int_t ncl=clusters->GetEntriesFast();
290 SignDeltas(clusters,GetZ());
293 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
294 detector=c->GetDetectorIndex();
296 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
298 fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
301 // add dead zone "virtual" cluster in SPD, if there is a cluster within
302 // zwindow cm from the dead zone
303 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
304 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
305 Int_t lab[4] = {0,0,0,detector};
306 Int_t info[3] = {0,0,i};
307 Float_t q = 0.; // this identifies virtual clusters
308 Float_t hit[5] = {xdead,
310 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
311 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
313 Bool_t local = kTRUE;
314 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
315 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
316 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
317 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
318 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
319 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
320 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
321 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
322 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
323 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
324 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
325 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
326 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
327 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
328 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
329 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
330 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
331 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
332 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
334 } // "virtual" clusters in SPD
338 fgLayers[i].ResetRoad(); //road defined by the cluster density
339 fgLayers[i].SortClusters();
344 //------------------------------------------------------------------------
345 void AliITStrackerMI::UnloadClusters() {
346 //--------------------------------------------------------------------
347 //This function unloads ITS clusters
348 //--------------------------------------------------------------------
349 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
351 //------------------------------------------------------------------------
352 static Int_t CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
353 //--------------------------------------------------------------------
354 // Correction for the material between the TPC and the ITS
355 //--------------------------------------------------------------------
356 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
357 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
358 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
359 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
360 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
361 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
362 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
363 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
365 Error("CorrectForTPCtoITSDeadZoneMaterial","Track is already in the dead zone !");
371 //------------------------------------------------------------------------
372 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
373 //--------------------------------------------------------------------
374 // This functions reconstructs ITS tracks
375 // The clusters must be already loaded !
376 //--------------------------------------------------------------------
377 fTrackingPhase="Clusters2Tracks";
379 TObjArray itsTracks(15000);
381 fEsd = event; // store pointer to the esd
383 // temporary (for cosmics)
384 if(event->GetVertex()) {
385 TString title = event->GetVertex()->GetTitle();
386 if(title.Contains("cosmics")) {
387 Double_t xyz[3]={GetX(),GetY(),GetZ()};
388 Double_t exyz[3]={0.1,0.1,0.1};
394 {/* Read ESD tracks */
395 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
396 Int_t nentr=event->GetNumberOfTracks();
397 Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
399 AliESDtrack *esd=event->GetTrack(nentr);
401 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
402 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
403 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
404 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
407 t=new AliITStrackMI(*esd);
408 } catch (const Char_t *msg) {
409 //Warning("Clusters2Tracks",msg);
413 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
414 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
417 // look at the ESD mass hypothesys !
418 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
420 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
422 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
423 //track - can be V0 according to TPC
425 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
429 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
433 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
437 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
442 t->SetReconstructed(kFALSE);
443 itsTracks.AddLast(t);
444 fOriginal.AddLast(t);
446 } /* End Read ESD tracks */
450 Int_t nentr=itsTracks.GetEntriesFast();
451 fTrackHypothesys.Expand(nentr);
452 fBestHypothesys.Expand(nentr);
453 MakeCoefficients(nentr);
454 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(nentr);
456 // THE TWO TRACKING PASSES
457 for (fPass=0; fPass<2; fPass++) {
458 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
459 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
460 //cerr<<fPass<<" "<<fCurrentEsdTrack<<'\n';
461 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
462 if (t==0) continue; //this track has been already tracked
463 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
464 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
465 if (fConstraint[fPass]) {
466 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
467 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
470 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
472 ResetTrackToFollow(*t);
475 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
477 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
479 AliITStrackMI * besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
480 if (!besttrack) continue;
481 besttrack->SetLabel(tpcLabel);
482 // besttrack->CookdEdx();
484 besttrack->SetFakeRatio(1.);
485 CookLabel(besttrack,0.); //For comparison only
486 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
488 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
490 t->SetReconstructed(kTRUE);
493 GetBestHypothesysMIP(itsTracks);
494 } // end loop on the two tracking passes
496 //GetBestHypothesysMIP(itsTracks);
497 if(event->GetNumberOfV0s()>0) UpdateTPCV0(event);
498 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) FindV02(event);
500 //GetBestHypothesysMIP(itsTracks);
504 Int_t entries = fTrackHypothesys.GetEntriesFast();
505 for (Int_t ientry=0; ientry<entries; ientry++) {
506 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
507 if (array) array->Delete();
508 delete fTrackHypothesys.RemoveAt(ientry);
511 fTrackHypothesys.Delete();
512 fBestHypothesys.Delete();
514 delete [] fCoefficients;
516 DeleteTrksMaterialLUT();
518 Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
520 fTrackingPhase="Default";
524 //------------------------------------------------------------------------
525 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
526 //--------------------------------------------------------------------
527 // This functions propagates reconstructed ITS tracks back
528 // The clusters must be loaded !
529 //--------------------------------------------------------------------
530 fTrackingPhase="PropagateBack";
531 Int_t nentr=event->GetNumberOfTracks();
532 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
535 for (Int_t i=0; i<nentr; i++) {
536 AliESDtrack *esd=event->GetTrack(i);
538 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
539 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
543 t=new AliITStrackMI(*esd);
544 } catch (const Char_t *msg) {
545 //Warning("PropagateBack",msg);
549 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
551 ResetTrackToFollow(*t);
553 // propagate to vertex [SR, GSI 17.02.2003]
554 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
555 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
556 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
557 fTrackToFollow.StartTimeIntegral();
558 // from vertex to outside pipe
559 CorrectForPipeMaterial(&fTrackToFollow,"outward");
562 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
563 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
564 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
568 fTrackToFollow.SetLabel(t->GetLabel());
569 //fTrackToFollow.CookdEdx();
570 CookLabel(&fTrackToFollow,0.); //For comparison only
571 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
572 //UseClusters(&fTrackToFollow);
578 Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
580 fTrackingPhase="Default";
584 //------------------------------------------------------------------------
585 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
586 //--------------------------------------------------------------------
587 // This functions refits ITS tracks using the
588 // "inward propagated" TPC tracks
589 // The clusters must be loaded !
590 //--------------------------------------------------------------------
591 fTrackingPhase="RefitInward";
592 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) RefitV02(event);
593 Int_t nentr=event->GetNumberOfTracks();
594 Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
597 for (Int_t i=0; i<nentr; i++) {
598 AliESDtrack *esd=event->GetTrack(i);
600 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
601 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
602 if (esd->GetStatus()&AliESDtrack::kTPCout)
603 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
607 t=new AliITStrackMI(*esd);
608 } catch (const Char_t *msg) {
609 //Warning("RefitInward",msg);
613 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
614 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
619 ResetTrackToFollow(*t);
620 fTrackToFollow.ResetClusters();
622 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
623 fTrackToFollow.ResetCovariance(10.);
626 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(), &fTrackToFollow, t,kTRUE)) {
627 fTrackToFollow.SetLabel(t->GetLabel());
628 // fTrackToFollow.CookdEdx();
629 CookdEdx(&fTrackToFollow);
631 CookLabel(&fTrackToFollow,0.0); //For comparison only
634 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
635 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
636 esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit);
637 Float_t r[3]={0.,0.,0.};
639 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
646 Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
648 fTrackingPhase="Default";
652 //------------------------------------------------------------------------
653 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
654 //--------------------------------------------------------------------
655 // Return pointer to a given cluster
656 //--------------------------------------------------------------------
657 Int_t l=(index & 0xf0000000) >> 28;
658 Int_t c=(index & 0x0fffffff) >> 00;
659 return fgLayers[l].GetCluster(c);
661 //------------------------------------------------------------------------
662 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
663 //--------------------------------------------------------------------
664 // Get track space point with index i
665 //--------------------------------------------------------------------
667 Int_t l=(index & 0xf0000000) >> 28;
668 Int_t c=(index & 0x0fffffff) >> 00;
669 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
670 Int_t idet = cl->GetDetectorIndex();
674 cl->GetGlobalXYZ(xyz);
675 cl->GetGlobalCov(cov);
678 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
681 iLayer = AliGeomManager::kSPD1;
684 iLayer = AliGeomManager::kSPD2;
687 iLayer = AliGeomManager::kSDD1;
690 iLayer = AliGeomManager::kSDD2;
693 iLayer = AliGeomManager::kSSD1;
696 iLayer = AliGeomManager::kSSD2;
699 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
702 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
703 p.SetVolumeID((UShort_t)volid);
706 //------------------------------------------------------------------------
707 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
708 AliTrackPoint& p, const AliESDtrack *t) {
709 //--------------------------------------------------------------------
710 // Get track space point with index i
711 // (assign error estimated during the tracking)
712 //--------------------------------------------------------------------
714 Int_t l=(index & 0xf0000000) >> 28;
715 Int_t c=(index & 0x0fffffff) >> 00;
716 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
717 Int_t idet = cl->GetDetectorIndex();
718 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
720 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
722 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
723 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
724 Double_t alpha = t->GetAlpha();
725 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
726 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,AliTracker::GetBz()));
727 phi += alpha-det.GetPhi();
728 Float_t tgphi = TMath::Tan(phi);
730 Float_t tgl = t->GetTgl(); // tgl about const along track
731 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
733 Float_t errlocalx,errlocalz;
734 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errlocalx,errlocalz);
738 cl->GetGlobalXYZ(xyz);
739 // cl->GetGlobalCov(cov);
740 Float_t pos[3] = {0.,0.,0.};
741 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errlocalx*errlocalx,errlocalz*errlocalz,0);
742 tmpcl.GetGlobalCov(cov);
746 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
749 iLayer = AliGeomManager::kSPD1;
752 iLayer = AliGeomManager::kSPD2;
755 iLayer = AliGeomManager::kSDD1;
758 iLayer = AliGeomManager::kSDD2;
761 iLayer = AliGeomManager::kSSD1;
764 iLayer = AliGeomManager::kSSD2;
767 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
770 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
771 p.SetVolumeID((UShort_t)volid);
774 //------------------------------------------------------------------------
775 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
777 //--------------------------------------------------------------------
778 // Follow prolongation tree
779 //--------------------------------------------------------------------
781 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
782 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
785 AliESDtrack * esd = otrack->GetESDtrack();
786 if (esd->GetV0Index(0)>0) {
787 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
788 // mapping of ESD track is different as ITS track in Containers
789 // Need something more stable
790 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
791 for (Int_t i=0;i<3;i++){
792 Int_t index = esd->GetV0Index(i);
794 AliESDv0 * vertex = fEsd->GetV0(index);
795 if (vertex->GetStatus()<0) continue; // rejected V0
797 if (esd->GetSign()>0) {
798 vertex->SetIndex(0,esdindex);
800 vertex->SetIndex(1,esdindex);
804 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
806 bestarray = new TObjArray(5);
807 fBestHypothesys.AddAt(bestarray,esdindex);
811 //setup tree of the prolongations
813 static AliITStrackMI tracks[7][100];
814 AliITStrackMI *currenttrack;
815 static AliITStrackMI currenttrack1;
816 static AliITStrackMI currenttrack2;
817 static AliITStrackMI backuptrack;
819 Int_t nindexes[7][100];
820 Float_t normalizedchi2[100];
821 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
822 otrack->SetNSkipped(0);
823 new (&(tracks[6][0])) AliITStrackMI(*otrack);
825 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
828 // follow prolongations
829 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
832 AliITSlayer &layer=fgLayers[ilayer];
833 Double_t r = layer.GetR();
839 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
841 if (ntracks[ilayer]>=100) break;
842 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
843 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
844 if (ntracks[ilayer]>15+ilayer){
845 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
846 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
849 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
851 // material between SSD and SDD, SDD and SPD
853 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
855 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
859 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
860 Int_t idet=layer.FindDetectorIndex(phi,z);
862 Double_t trackGlobXYZ1[3];
863 currenttrack1.GetXYZ(trackGlobXYZ1);
865 // Get the budget to the primary vertex for the current track being prolonged
866 Double_t budgetToPrimVertex = GetEffectiveThickness();
868 // check if we allow a prolongation without point
869 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
871 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
872 // propagate to the layer radius
873 Double_t xToGo; vtrack->GetLocalXat(r,xToGo);
874 vtrack->AliExternalTrackParam::PropagateTo(xToGo,GetBz());
875 // apply correction for material of the current layer
876 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
877 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
878 vtrack->SetClIndex(ilayer,0);
879 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
884 // track outside layer acceptance in z
885 if (idet<0) continue;
887 //propagate to the intersection with the detector plane
888 const AliITSdetector &det=layer.GetDetector(idet);
889 new(¤ttrack2) AliITStrackMI(currenttrack1);
890 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
891 currenttrack2.Propagate(det.GetPhi(),det.GetR());
892 currenttrack1.SetDetectorIndex(idet);
893 currenttrack2.SetDetectorIndex(idet);
896 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
898 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
899 TMath::Sqrt(currenttrack1.GetSigmaZ2() +
900 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
901 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
902 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
903 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
904 TMath::Sqrt(currenttrack1.GetSigmaY2() +
905 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
906 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
907 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
909 // track at boundary between detectors, enlarge road
910 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
911 if ( (currenttrack1.GetY()-dy < det.GetYmin()+boundaryWidth) ||
912 (currenttrack1.GetY()+dy > det.GetYmax()-boundaryWidth) ||
913 (currenttrack1.GetZ()-dz < det.GetZmin()+boundaryWidth) ||
914 (currenttrack1.GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
915 Float_t tgl = TMath::Abs(currenttrack1.GetTgl());
916 if (tgl > 1.) tgl=1.;
917 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
918 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
919 Float_t snp = TMath::Abs(currenttrack1.GetSnp());
920 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) continue;
921 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
924 // road in global (rphi,z) [i.e. in tracking ref. system]
925 Double_t zmin = currenttrack1.GetZ() - dz;
926 Double_t zmax = currenttrack1.GetZ() + dz;
927 Double_t ymin = currenttrack1.GetY() + r*det.GetPhi() - dy;
928 Double_t ymax = currenttrack1.GetY() + r*det.GetPhi() + dy;
930 // select clusters in road
931 layer.SelectClusters(zmin,zmax,ymin,ymax);
932 //********************
934 // Define criteria for track-cluster association
935 Double_t msz = currenttrack1.GetSigmaZ2() +
936 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
937 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
938 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
939 Double_t msy = currenttrack1.GetSigmaY2() +
940 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
941 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
942 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
944 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
945 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
947 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
948 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
950 msz = 1./msz; // 1/RoadZ^2
951 msy = 1./msy; // 1/RoadY^2
954 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
956 const AliITSRecPoint *cl=0;
958 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
959 Bool_t deadzoneSPD=kFALSE;
960 currenttrack = ¤ttrack1;
962 // check if the road contains a dead zone and create a prolongation
963 Int_t dead = CheckDeadZone(/*currenttrack,*/ilayer,/*idet,*/zmin,zmax/*,ymin,ymax*/);
965 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
966 updatetrack->SetClIndex(ilayer,0);
967 // apply correction for material of the current layer
968 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
969 if (constrain) { // apply vertex constrain
970 updatetrack->SetConstrain(constrain);
971 Bool_t isPrim = kTRUE;
972 if (ilayer<4) { // check that it's close to the vertex
973 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
974 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
975 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
976 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
977 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
979 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
981 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
982 if (dead==1) { // dead zone at z=0,+-7cm in SPD
983 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
989 // loop over clusters in the road
990 while ((cl=layer.GetNextCluster(clidx))!=0) {
991 if (ntracks[ilayer]>95) break; //space for skipped clusters
992 Bool_t changedet =kFALSE;
993 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
994 Int_t idet=cl->GetDetectorIndex();
996 if (currenttrack->GetDetectorIndex()==idet) { // track already on the cluster's detector
997 // a first cut on track-cluster distance
998 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
999 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1000 continue; // cluster not associated to track
1001 } else { // have to move track to cluster's detector
1002 const AliITSdetector &det=layer.GetDetector(idet);
1003 // a first cut on track-cluster distance
1005 if (!currenttrack2.GetProlongationFast(det.GetPhi(),det.GetR(),y,z)) continue;
1006 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1007 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1008 continue; // cluster not associated to track
1010 new (&backuptrack) AliITStrackMI(currenttrack2);
1012 currenttrack =¤ttrack2;
1013 if (!currenttrack->Propagate(det.GetPhi(),det.GetR())) {
1014 new (currenttrack) AliITStrackMI(backuptrack);
1018 currenttrack->SetDetectorIndex(idet);
1019 // Get again the budget to the primary vertex
1020 // for the current track being prolonged, if had to change detector
1021 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1024 // calculate track-clusters chi2
1025 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1027 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1028 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1029 if (ntracks[ilayer]>=100) continue;
1030 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1031 updatetrack->SetClIndex(ilayer,0);
1032 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1034 if (cl->GetQ()!=0) { // real cluster
1035 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) continue;
1036 updatetrack->SetSampledEdx(cl->GetQ(),updatetrack->GetNumberOfClusters()-1); //b.b.
1037 } else { // virtual cluster in dead zone
1038 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1039 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1041 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1043 // apply correction for material of the current layer
1044 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1046 if (constrain) { // apply vertex constrain
1047 updatetrack->SetConstrain(constrain);
1048 Bool_t isPrim = kTRUE;
1049 if (ilayer<4) { // check that it's close to the vertex
1050 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1051 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1052 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1053 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1054 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1056 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1057 } //apply vertex constrain
1059 } // create new hypothesis
1060 } // loop over possible prolongations
1062 // allow one prolongation without clusters
1063 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1064 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1065 // apply correction for material of the current layer
1066 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1067 vtrack->SetClIndex(ilayer,0);
1068 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1069 vtrack->IncrementNSkipped();
1073 // allow one prolongation without clusters for tracks with |tgl|>1.1
1074 if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) { //big theta - for low flux
1075 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1076 // apply correction for material of the current layer
1077 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1078 vtrack->SetClIndex(ilayer,0);
1079 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1080 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1085 } // loop over tracks in layer ilayer+1
1087 //loop over track candidates for the current layer
1093 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1094 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1095 if (normalizedchi2[itrack] <
1096 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1100 if (constrain) { // constrain
1101 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1103 } else { // !constrain
1104 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1109 // sort tracks by increasing normalized chi2
1110 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1111 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1112 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1113 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1114 } // end loop over layers
1118 // Now select tracks to be kept
1120 Int_t max = constrain ? 20 : 5;
1122 // tracks that reach layer 0 (SPD inner)
1123 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1124 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1125 if (track.GetNumberOfClusters()<2) continue;
1126 if (!constrain && track.GetNormChi2(0) >
1127 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1130 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1133 // tracks that reach layer 1 (SPD outer)
1134 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1135 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1136 if (track.GetNumberOfClusters()<4) continue;
1137 if (!constrain && track.GetNormChi2(1) >
1138 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1139 if (constrain) track.IncrementNSkipped();
1141 track.SetD(0,track.GetD(GetX(),GetY()));
1142 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1143 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1144 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1147 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1150 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1152 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1153 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1154 if (track.GetNumberOfClusters()<3) continue;
1155 if (!constrain && track.GetNormChi2(2) >
1156 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1157 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1159 track.SetD(0,track.GetD(GetX(),GetY()));
1160 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1161 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1162 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1165 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1171 // register best track of each layer - important for V0 finder
1173 for (Int_t ilayer=0;ilayer<5;ilayer++){
1174 if (ntracks[ilayer]==0) continue;
1175 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1176 if (track.GetNumberOfClusters()<1) continue;
1177 CookLabel(&track,0);
1178 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1182 // update TPC V0 information
1184 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1185 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1186 for (Int_t i=0;i<3;i++){
1187 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1188 if (index==0) break;
1189 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1190 if (vertex->GetStatus()<0) continue; // rejected V0
1192 if (otrack->GetSign()>0) {
1193 vertex->SetIndex(0,esdindex);
1196 vertex->SetIndex(1,esdindex);
1198 //find nearest layer with track info
1199 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1200 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1201 Int_t nearest = nearestold;
1202 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1203 if (ntracks[nearest]==0){
1208 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1209 if (nearestold<5&&nearest<5){
1210 Bool_t accept = track.GetNormChi2(nearest)<10;
1212 if (track.GetSign()>0) {
1213 vertex->SetParamP(track);
1214 vertex->Update(fprimvertex);
1215 //vertex->SetIndex(0,track.fESDtrack->GetID());
1216 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1218 vertex->SetParamN(track);
1219 vertex->Update(fprimvertex);
1220 //vertex->SetIndex(1,track.fESDtrack->GetID());
1221 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1223 vertex->SetStatus(vertex->GetStatus()+1);
1225 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1232 //------------------------------------------------------------------------
1233 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1235 //--------------------------------------------------------------------
1238 return fgLayers[layer];
1240 //------------------------------------------------------------------------
1241 AliITStrackerMI::AliITSlayer::AliITSlayer():
1266 //--------------------------------------------------------------------
1267 //default AliITSlayer constructor
1268 //--------------------------------------------------------------------
1269 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1270 fClusterWeight[i]=0;
1271 fClusterTracks[0][i]=-1;
1272 fClusterTracks[1][i]=-1;
1273 fClusterTracks[2][i]=-1;
1274 fClusterTracks[3][i]=-1;
1277 //------------------------------------------------------------------------
1278 AliITStrackerMI::AliITSlayer::
1279 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1304 //--------------------------------------------------------------------
1305 //main AliITSlayer constructor
1306 //--------------------------------------------------------------------
1307 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1308 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1310 //------------------------------------------------------------------------
1311 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1313 fPhiOffset(layer.fPhiOffset),
1314 fNladders(layer.fNladders),
1315 fZOffset(layer.fZOffset),
1316 fNdetectors(layer.fNdetectors),
1317 fDetectors(layer.fDetectors),
1322 fClustersCs(layer.fClustersCs),
1323 fClusterIndexCs(layer.fClusterIndexCs),
1327 fCurrentSlice(layer.fCurrentSlice),
1334 fAccepted(layer.fAccepted),
1338 //------------------------------------------------------------------------
1339 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1340 //--------------------------------------------------------------------
1341 // AliITSlayer destructor
1342 //--------------------------------------------------------------------
1343 delete[] fDetectors;
1344 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1345 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1346 fClusterWeight[i]=0;
1347 fClusterTracks[0][i]=-1;
1348 fClusterTracks[1][i]=-1;
1349 fClusterTracks[2][i]=-1;
1350 fClusterTracks[3][i]=-1;
1353 //------------------------------------------------------------------------
1354 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1355 //--------------------------------------------------------------------
1356 // This function removes loaded clusters
1357 //--------------------------------------------------------------------
1358 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1359 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1360 fClusterWeight[i]=0;
1361 fClusterTracks[0][i]=-1;
1362 fClusterTracks[1][i]=-1;
1363 fClusterTracks[2][i]=-1;
1364 fClusterTracks[3][i]=-1;
1370 //------------------------------------------------------------------------
1371 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1372 //--------------------------------------------------------------------
1373 // This function reset weights of the clusters
1374 //--------------------------------------------------------------------
1375 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1376 fClusterWeight[i]=0;
1377 fClusterTracks[0][i]=-1;
1378 fClusterTracks[1][i]=-1;
1379 fClusterTracks[2][i]=-1;
1380 fClusterTracks[3][i]=-1;
1382 for (Int_t i=0; i<fN;i++) {
1383 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1384 if (cl&&cl->IsUsed()) cl->Use();
1388 //------------------------------------------------------------------------
1389 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1390 //--------------------------------------------------------------------
1391 // This function calculates the road defined by the cluster density
1392 //--------------------------------------------------------------------
1394 for (Int_t i=0; i<fN; i++) {
1395 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1397 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1399 //------------------------------------------------------------------------
1400 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1401 //--------------------------------------------------------------------
1402 //This function adds a cluster to this layer
1403 //--------------------------------------------------------------------
1404 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1405 ::Error("InsertCluster","Too many clusters !\n");
1411 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1412 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1413 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1414 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1415 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1419 //------------------------------------------------------------------------
1420 void AliITStrackerMI::AliITSlayer::SortClusters()
1425 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1426 Float_t *z = new Float_t[fN];
1427 Int_t * index = new Int_t[fN];
1429 for (Int_t i=0;i<fN;i++){
1430 z[i] = fClusters[i]->GetZ();
1432 TMath::Sort(fN,z,index,kFALSE);
1433 for (Int_t i=0;i<fN;i++){
1434 clusters[i] = fClusters[index[i]];
1437 for (Int_t i=0;i<fN;i++){
1438 fClusters[i] = clusters[i];
1439 fZ[i] = fClusters[i]->GetZ();
1440 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1441 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1442 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1452 for (Int_t i=0;i<fN;i++){
1453 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1454 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1455 fClusterIndex[i] = i;
1459 fDy5 = (fYB[1]-fYB[0])/5.;
1460 fDy10 = (fYB[1]-fYB[0])/10.;
1461 fDy20 = (fYB[1]-fYB[0])/20.;
1462 for (Int_t i=0;i<6;i++) fN5[i] =0;
1463 for (Int_t i=0;i<11;i++) fN10[i]=0;
1464 for (Int_t i=0;i<21;i++) fN20[i]=0;
1466 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;}
1467 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;}
1468 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;}
1471 for (Int_t i=0;i<fN;i++)
1472 for (Int_t irot=-1;irot<=1;irot++){
1473 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1475 for (Int_t slice=0; slice<6;slice++){
1476 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1477 fClusters5[slice][fN5[slice]] = fClusters[i];
1478 fY5[slice][fN5[slice]] = curY;
1479 fZ5[slice][fN5[slice]] = fZ[i];
1480 fClusterIndex5[slice][fN5[slice]]=i;
1485 for (Int_t slice=0; slice<11;slice++){
1486 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1487 fClusters10[slice][fN10[slice]] = fClusters[i];
1488 fY10[slice][fN10[slice]] = curY;
1489 fZ10[slice][fN10[slice]] = fZ[i];
1490 fClusterIndex10[slice][fN10[slice]]=i;
1495 for (Int_t slice=0; slice<21;slice++){
1496 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1497 fClusters20[slice][fN20[slice]] = fClusters[i];
1498 fY20[slice][fN20[slice]] = curY;
1499 fZ20[slice][fN20[slice]] = fZ[i];
1500 fClusterIndex20[slice][fN20[slice]]=i;
1507 // consistency check
1509 for (Int_t i=0;i<fN-1;i++){
1515 for (Int_t slice=0;slice<21;slice++)
1516 for (Int_t i=0;i<fN20[slice]-1;i++){
1517 if (fZ20[slice][i]>fZ20[slice][i+1]){
1524 //------------------------------------------------------------------------
1525 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1526 //--------------------------------------------------------------------
1527 // This function returns the index of the nearest cluster
1528 //--------------------------------------------------------------------
1531 if (fCurrentSlice<0) {
1540 if (ncl==0) return 0;
1541 Int_t b=0, e=ncl-1, m=(b+e)/2;
1542 for (; b<e; m=(b+e)/2) {
1543 // if (z > fClusters[m]->GetZ()) b=m+1;
1544 if (z > zcl[m]) b=m+1;
1549 //------------------------------------------------------------------------
1550 void AliITStrackerMI::AliITSlayer::
1551 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1552 //--------------------------------------------------------------------
1553 // This function sets the "window"
1554 //--------------------------------------------------------------------
1556 Double_t circle=2*TMath::Pi()*fR;
1557 fYmin = ymin; fYmax =ymax;
1558 Float_t ymiddle = (fYmin+fYmax)*0.5;
1559 if (ymiddle<fYB[0]) {fYmin+=circle; fYmax+=circle;ymiddle+=circle;}
1561 if (ymiddle>fYB[1]) {fYmin-=circle; fYmax-=circle;ymiddle-=circle;}
1566 fClustersCs = fClusters;
1567 fClusterIndexCs = fClusterIndex;
1573 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1574 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1575 if (slice<0) slice=0;
1576 if (slice>20) slice=20;
1577 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1579 fCurrentSlice=slice;
1580 fClustersCs = fClusters20[fCurrentSlice];
1581 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1582 fYcs = fY20[fCurrentSlice];
1583 fZcs = fZ20[fCurrentSlice];
1584 fNcs = fN20[fCurrentSlice];
1589 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1590 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1591 if (slice<0) slice=0;
1592 if (slice>10) slice=10;
1593 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1595 fCurrentSlice=slice;
1596 fClustersCs = fClusters10[fCurrentSlice];
1597 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1598 fYcs = fY10[fCurrentSlice];
1599 fZcs = fZ10[fCurrentSlice];
1600 fNcs = fN10[fCurrentSlice];
1605 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1606 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1607 if (slice<0) slice=0;
1608 if (slice>5) slice=5;
1609 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1611 fCurrentSlice=slice;
1612 fClustersCs = fClusters5[fCurrentSlice];
1613 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1614 fYcs = fY5[fCurrentSlice];
1615 fZcs = fZ5[fCurrentSlice];
1616 fNcs = fN5[fCurrentSlice];
1620 fI=FindClusterIndex(zmin); fZmax=zmax;
1621 fImax = TMath::Min(FindClusterIndex(zmax)+1,fNcs);
1627 //------------------------------------------------------------------------
1628 Int_t AliITStrackerMI::AliITSlayer::
1629 FindDetectorIndex(Double_t phi, Double_t z) const {
1630 //--------------------------------------------------------------------
1631 //This function finds the detector crossed by the track
1632 //--------------------------------------------------------------------
1634 if (fZOffset<0) // old geometry
1635 dphi = -(phi-fPhiOffset);
1636 else // new geometry
1637 dphi = phi-fPhiOffset;
1640 if (dphi < 0) dphi += 2*TMath::Pi();
1641 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1642 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1643 if (np>=fNladders) np-=fNladders;
1644 if (np<0) np+=fNladders;
1647 Double_t dz=fZOffset-z;
1648 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1649 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1650 if (nz>=fNdetectors) return -1;
1651 if (nz<0) return -1;
1653 return np*fNdetectors + nz;
1655 //------------------------------------------------------------------------
1656 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci){
1657 //--------------------------------------------------------------------
1658 // This function returns clusters within the "window"
1659 //--------------------------------------------------------------------
1661 if (fCurrentSlice<0){
1662 Double_t rpi2 = 2.*fR*TMath::Pi();
1663 for (Int_t i=fI; i<fImax; i++) {
1665 if (fYmax<y) y -= rpi2;
1666 if (fYmin>y) y += rpi2;
1667 if (y<fYmin) continue;
1668 if (y>fYmax) continue;
1669 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1672 return fClusters[i];
1676 for (Int_t i=fI; i<fImax; i++) {
1677 if (fYcs[i]<fYmin) continue;
1678 if (fYcs[i]>fYmax) continue;
1679 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1680 ci=fClusterIndexCs[i];
1682 return fClustersCs[i];
1687 //------------------------------------------------------------------------
1688 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1690 //--------------------------------------------------------------------
1691 // This function returns the layer thickness at this point (units X0)
1692 //--------------------------------------------------------------------
1694 x0=AliITSRecoParam::GetX0Air();
1695 if (43<fR&&fR<45) { //SSD2
1698 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1699 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1700 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1701 for (Int_t i=0; i<12; i++) {
1702 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1703 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1707 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1708 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1712 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1713 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1716 if (37<fR&&fR<41) { //SSD1
1719 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1720 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1721 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1722 for (Int_t i=0; i<11; i++) {
1723 if (TMath::Abs(z-3.9*i)<0.15) {
1724 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1728 if (TMath::Abs(z+3.9*i)<0.15) {
1729 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1733 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1734 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1737 if (13<fR&&fR<26) { //SDD
1740 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1742 if (TMath::Abs(y-1.80)<0.55) {
1744 for (Int_t j=0; j<20; j++) {
1745 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1746 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1749 if (TMath::Abs(y+1.80)<0.55) {
1751 for (Int_t j=0; j<20; j++) {
1752 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1753 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1757 for (Int_t i=0; i<4; i++) {
1758 if (TMath::Abs(z-7.3*i)<0.60) {
1760 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1763 if (TMath::Abs(z+7.3*i)<0.60) {
1765 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1770 if (6<fR&&fR<8) { //SPD2
1771 Double_t dd=0.0063; x0=21.5;
1773 if (TMath::Abs(y-3.08)>0.5) d+=dd;
1774 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
1776 if (3<fR&&fR<5) { //SPD1
1777 Double_t dd=0.0063; x0=21.5;
1779 if (TMath::Abs(y+0.21)>0.6) d+=dd;
1780 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
1785 //------------------------------------------------------------------------
1786 Double_t AliITStrackerMI::GetEffectiveThickness()
1788 //--------------------------------------------------------------------
1789 // Returns the thickness between the current layer and the vertex (units X0)
1790 //--------------------------------------------------------------------
1793 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
1794 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
1795 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
1799 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
1800 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
1804 Double_t xn=fgLayers[fI].GetR();
1805 for (Int_t i=0; i<fI; i++) {
1806 Double_t xi=fgLayers[i].GetR();
1807 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
1813 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
1814 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
1817 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
1818 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
1822 //------------------------------------------------------------------------
1823 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
1824 //--------------------------------------------------------------------
1825 // This function returns number of clusters within the "window"
1826 //--------------------------------------------------------------------
1828 for (Int_t i=fI; i<fN; i++) {
1829 const AliITSRecPoint *c=fClusters[i];
1830 if (c->GetZ() > fZmax) break;
1831 if (c->IsUsed()) continue;
1832 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
1833 Double_t y=fR*det.GetPhi() + c->GetY();
1835 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
1836 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
1838 if (y<fYmin) continue;
1839 if (y>fYmax) continue;
1844 //------------------------------------------------------------------------
1845 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *t,
1846 const AliITStrackMI *c, Bool_t extra) {
1847 //--------------------------------------------------------------------
1848 // This function refits the track "t" at the position "x" using
1849 // the clusters from "c"
1850 // If "extra"==kTRUE,
1851 // the clusters from overlapped modules get attached to "t"
1852 //--------------------------------------------------------------------
1854 Int_t index[AliITSgeomTGeo::kNLayers];
1856 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
1857 Int_t nc=c->GetNumberOfClusters();
1858 for (k=0; k<nc; k++) {
1859 Int_t idx=c->GetClusterIndex(k),nl=(idx&0xf0000000)>>28;
1863 // special for cosmics: check which is the innermost layer crossed
1865 Int_t innermostlayer=5;
1866 Double_t d = TMath::Abs(t->GetD(0.,0.));
1867 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++)
1868 if(d<fgLayers[innermostlayer].GetR()) break;
1869 //printf(" d %f innermost %d\n",d,innermostlayer);
1871 Int_t from, to, step;
1872 if (xx > t->GetX()) {
1873 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
1876 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
1879 TString dir=(step>0 ? "outward" : "inward");
1881 // loop on the layers
1882 for (Int_t ilayer=from; ilayer != to; ilayer += step) {
1883 AliITSlayer &layer=fgLayers[ilayer];
1884 Double_t r=layer.GetR();
1886 // material between SSD and SDD, SDD and SPD
1887 Double_t hI=ilayer-0.5*step;
1888 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
1889 if(!CorrectForShieldMaterial(t,"SDD",dir)) return kFALSE;
1890 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
1891 if(!CorrectForShieldMaterial(t,"SPD",dir)) return kFALSE;
1893 // remember old position [SR, GSI 18.02.2003]
1894 Double_t oldX=0., oldY=0., oldZ=0.;
1895 if (t->IsStartedTimeIntegral() && step==1) {
1896 t->GetGlobalXYZat(t->GetX(),oldX,oldY,oldZ);
1900 Double_t oldGlobXYZ[3];
1901 t->GetXYZ(oldGlobXYZ);
1904 if (!t->GetPhiZat(r,phi,z)) return kFALSE;
1906 Int_t idet=layer.FindDetectorIndex(phi,z);
1908 // check if we allow a prolongation without point for large-eta tracks
1909 Int_t skip = CheckSkipLayer(t,ilayer,idet);
1911 // propagate to the layer radius
1912 Double_t xToGo; t->GetLocalXat(r,xToGo);
1913 t->AliExternalTrackParam::PropagateTo(xToGo,GetBz());
1914 // apply correction for material of the current layer
1915 CorrectForLayerMaterial(t,ilayer,oldGlobXYZ,dir);
1916 // track time update [SR, GSI 17.02.2003]
1917 if (t->IsStartedTimeIntegral() && step==1) {
1918 Double_t newX, newY, newZ;
1919 t->GetGlobalXYZat(t->GetX(),newX,newY,newZ);
1920 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
1921 (oldZ-newZ)*(oldZ-newZ);
1922 t->AddTimeStep(TMath::Sqrt(dL2));
1927 if (idet<0) return kFALSE;
1929 const AliITSdetector &det=layer.GetDetector(idet);
1931 if (!t->Propagate(phi,det.GetR())) return kFALSE;
1932 t->SetDetectorIndex(idet);
1934 const AliITSRecPoint *cl=0;
1935 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
1937 Int_t idx=index[ilayer];
1939 const AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(idx);
1941 if (idet != c->GetDetectorIndex()) {
1942 idet=c->GetDetectorIndex();
1943 const AliITSdetector &det=layer.GetDetector(idet);
1944 if (!t->Propagate(det.GetPhi(),det.GetR())) {
1947 t->SetDetectorIndex(idet);
1949 //Double_t chi2=t->GetPredictedChi2(c);
1950 Int_t layer = (idx & 0xf0000000) >> 28;;
1951 Double_t chi2=GetPredictedChi2MI(t,c,layer);
1962 if (!UpdateMI(t,cl,maxchi2,idx)) return kFALSE;
1963 t->SetSampledEdx(cl->GetQ(),t->GetNumberOfClusters()-1);
1966 if (extra) { //search for extra clusters
1967 AliITStrackV2 tmp(*t);
1968 Double_t dz=4*TMath::Sqrt(tmp.GetSigmaZ2()+AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1969 if (dz < 0.5*TMath::Abs(tmp.GetTgl())) dz=0.5*TMath::Abs(tmp.GetTgl());
1970 Double_t dy=4*TMath::Sqrt(t->GetSigmaY2()+AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1971 if (dy < 0.5*TMath::Abs(tmp.GetSnp())) dy=0.5*TMath::Abs(tmp.GetSnp());
1972 Double_t zmin=t->GetZ() - dz;
1973 Double_t zmax=t->GetZ() + dz;
1974 Double_t ymin=t->GetY() + phi*r - dy;
1975 Double_t ymax=t->GetY() + phi*r + dy;
1976 layer.SelectClusters(zmin,zmax,ymin,ymax);
1978 const AliITSRecPoint *c=0; Int_t ci=-1,cci=-1;
1979 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2(), tolerance=0.1;
1980 while ((c=layer.GetNextCluster(ci))!=0) {
1981 if (idet == c->GetDetectorIndex()) continue;
1983 const AliITSdetector &det=layer.GetDetector(c->GetDetectorIndex());
1985 if (!tmp.Propagate(det.GetPhi(),det.GetR())) continue;
1987 if (TMath::Abs(tmp.GetZ() - c->GetZ()) > tolerance) continue;
1988 if (TMath::Abs(tmp.GetY() - c->GetY()) > tolerance) continue;
1990 Double_t chi2=tmp.GetPredictedChi2(c);
1991 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
1993 if (cci>=0) t->SetExtraCluster(ilayer,(ilayer<<28)+cci);
1996 // track time update [SR, GSI 17.02.2003]
1997 if (t->IsStartedTimeIntegral() && step==1) {
1998 Double_t newX, newY, newZ;
1999 t->GetGlobalXYZat(t->GetX(),newX,newY,newZ);
2000 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2001 (oldZ-newZ)*(oldZ-newZ);
2002 t->AddTimeStep(TMath::Sqrt(dL2));
2006 // Correct for material of the current layer
2007 if(!CorrectForLayerMaterial(t,ilayer,oldGlobXYZ,dir)) return kFALSE;
2009 } // end loop on the layers
2011 if (!t->PropagateTo(xx,0.,0.)) return kFALSE;
2014 //------------------------------------------------------------------------
2016 AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *t,const Int_t *clindex) {
2017 //--------------------------------------------------------------------
2018 // This function refits the track "t" at the position "x" using
2019 // the clusters from array
2020 //--------------------------------------------------------------------
2021 Int_t index[AliITSgeomTGeo::kNLayers];
2023 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2025 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2026 index[k]=clindex[k];
2029 // special for cosmics: check which the innermost layer crossed
2031 Int_t innermostlayer=5;
2032 Double_t d = TMath::Abs(t->GetD(0.,0.));
2033 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++)
2034 if(d<fgLayers[innermostlayer].GetR()) break;
2035 //printf(" d %f innermost %d\n",d,innermostlayer);
2037 Int_t from, to, step;
2038 if (xx > t->GetX()) {
2039 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2042 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2045 TString dir=(step>0 ? "outward" : "inward");
2047 for (Int_t ilayer=from; ilayer != to; ilayer += step) {
2048 AliITSlayer &layer=fgLayers[ilayer];
2049 Double_t r=layer.GetR();
2050 if (step<0 && xx>r) break;
2052 // material between SSD and SDD, SDD and SPD
2053 Double_t hI=ilayer-0.5*step;
2054 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2055 if(!CorrectForShieldMaterial(t,"SDD",dir)) return kFALSE;
2056 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2057 if(!CorrectForShieldMaterial(t,"SPD",dir)) return kFALSE;
2059 // remember old position [SR, GSI 18.02.2003]
2060 Double_t oldX=0., oldY=0., oldZ=0.;
2061 if (t->IsStartedTimeIntegral() && step==1) {
2062 t->GetGlobalXYZat(t->GetX(),oldX,oldY,oldZ);
2065 Double_t oldGlobXYZ[3];
2066 t->GetXYZ(oldGlobXYZ);
2069 if (!t->GetPhiZat(r,phi,z)) return kFALSE;
2071 Int_t idet=layer.FindDetectorIndex(phi,z);
2073 // check if we allow a prolongation without point for large-eta tracks
2074 Int_t skip = CheckSkipLayer(t,ilayer,idet);
2076 // propagate to the layer radius
2077 Double_t xToGo; t->GetLocalXat(r,xToGo);
2078 t->AliExternalTrackParam::PropagateTo(xToGo,GetBz());
2079 // apply correction for material of the current layer
2080 CorrectForLayerMaterial(t,ilayer,oldGlobXYZ,dir);
2081 // track time update [SR, GSI 17.02.2003]
2082 if (t->IsStartedTimeIntegral() && step==1) {
2083 Double_t newX, newY, newZ;
2084 t->GetGlobalXYZat(t->GetX(),newX,newY,newZ);
2085 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2086 (oldZ-newZ)*(oldZ-newZ);
2087 t->AddTimeStep(TMath::Sqrt(dL2));
2092 if (idet<0) return kFALSE;
2093 const AliITSdetector &det=layer.GetDetector(idet);
2095 if (!t->Propagate(phi,det.GetR())) return kFALSE;
2096 t->SetDetectorIndex(idet);
2098 const AliITSRecPoint *cl=0;
2099 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2101 Int_t idx=index[ilayer];
2103 const AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(idx);
2105 if (idet != c->GetDetectorIndex()) {
2106 idet=c->GetDetectorIndex();
2107 const AliITSdetector &det=layer.GetDetector(idet);
2108 if (!t->Propagate(det.GetPhi(),det.GetR())) {
2111 t->SetDetectorIndex(idet);
2113 //Double_t chi2=t->GetPredictedChi2(c);
2114 Int_t layer = (idx & 0xf0000000) >> 28;;
2115 Double_t chi2=GetPredictedChi2MI(t,c,layer);
2126 if (!UpdateMI(t,cl,maxchi2,idx)) return kFALSE;
2127 t->SetSampledEdx(cl->GetQ(),t->GetNumberOfClusters()-1);
2130 // Correct for material of the current layer
2131 if(!CorrectForLayerMaterial(t,ilayer,oldGlobXYZ,dir)) return kFALSE;
2133 // track time update [SR, GSI 17.02.2003]
2134 if (t->IsStartedTimeIntegral() && step==1) {
2135 Double_t newX, newY, newZ;
2136 t->GetGlobalXYZat(t->GetX(),newX,newY,newZ);
2137 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2138 (oldZ-newZ)*(oldZ-newZ);
2139 t->AddTimeStep(TMath::Sqrt(dL2));
2145 if (!t->PropagateTo(xx,0.,0.)) return kFALSE;
2148 //------------------------------------------------------------------------
2149 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2152 // calculate normalized chi2
2153 // return NormalizedChi2(track,0);
2156 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2157 // track->fdEdxMismatch=0;
2158 Float_t dedxmismatch =0;
2159 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2161 for (Int_t i = 0;i<6;i++){
2162 if (track->GetClIndex(i)>0){
2163 Float_t cerry, cerrz;
2164 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2166 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2169 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2170 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2171 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2173 cchi2+=(0.5-ratio)*10.;
2174 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2175 dedxmismatch+=(0.5-ratio)*10.;
2179 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2180 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2181 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2182 if (i<2) chi2+=2*cl->GetDeltaProbability();
2188 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2189 track->SetdEdxMismatch(dedxmismatch);
2193 for (Int_t i = 0;i<4;i++){
2194 if (track->GetClIndex(i)>0){
2195 Float_t cerry, cerrz;
2196 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2197 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2200 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2201 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2205 for (Int_t i = 4;i<6;i++){
2206 if (track->GetClIndex(i)>0){
2207 Float_t cerry, cerrz;
2208 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2209 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2212 Float_t cerryb, cerrzb;
2213 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2214 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2217 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2218 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2223 if (track->GetESDtrack()->GetTPCsignal()>85){
2224 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2226 chi2+=(0.5-ratio)*5.;
2229 chi2+=(ratio-2.0)*3;
2233 Double_t match = TMath::Sqrt(track->GetChi22());
2234 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2235 if (!track->GetConstrain()) {
2236 if (track->GetNumberOfClusters()>2) {
2237 match/=track->GetNumberOfClusters()-2.;
2242 if (match<0) match=0;
2243 Float_t deadzonefactor = (track->GetNDeadZone()>0) ? 3*(1.1-track->GetDeadZoneProbability()):0.;
2244 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2245 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2246 1./(1.+track->GetNSkipped()));
2250 //------------------------------------------------------------------------
2251 Double_t AliITStrackerMI::GetMatchingChi2(AliITStrackMI * track1, AliITStrackMI * track2)
2254 // return matching chi2 between two tracks
2255 AliITStrackMI track3(*track2);
2256 track3.Propagate(track1->GetAlpha(),track1->GetX());
2258 vec(0,0)=track1->GetY() - track3.GetY();
2259 vec(1,0)=track1->GetZ() - track3.GetZ();
2260 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2261 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2262 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2265 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2266 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2267 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2268 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2269 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2271 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2272 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2273 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2274 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2276 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2277 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2278 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2280 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2281 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2283 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2286 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2287 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2290 //------------------------------------------------------------------------
2291 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr)
2294 // return probability that given point (characterized by z position and error)
2295 // is in SPD dead zone
2297 Double_t probability = 0.;
2298 Double_t absz = TMath::Abs(zpos);
2299 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2300 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2301 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2302 Double_t zmin, zmax;
2303 if (zpos<-6.) { // dead zone at z = -7
2304 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2305 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2306 } else if (zpos>6.) { // dead zone at z = +7
2307 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2308 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2309 } else if (absz<2.) { // dead zone at z = 0
2310 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2311 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2316 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2318 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2319 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2322 //------------------------------------------------------------------------
2323 Double_t AliITStrackerMI::GetTruncatedChi2(AliITStrackMI * track, Float_t fac)
2326 // calculate normalized chi2
2328 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2330 for (Int_t i = 0;i<6;i++){
2331 if (TMath::Abs(track->GetDy(i))>0){
2332 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2333 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2336 else{chi2[i]=10000;}
2339 TMath::Sort(6,chi2,index,kFALSE);
2340 Float_t max = float(ncl)*fac-1.;
2341 Float_t sumchi=0, sumweight=0;
2342 for (Int_t i=0;i<max+1;i++){
2343 Float_t weight = (i<max)?1.:(max+1.-i);
2344 sumchi+=weight*chi2[index[i]];
2347 Double_t normchi2 = sumchi/sumweight;
2350 //------------------------------------------------------------------------
2351 Double_t AliITStrackerMI::GetInterpolatedChi2(AliITStrackMI * forwardtrack, AliITStrackMI * backtrack)
2354 // calculate normalized chi2
2355 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2358 for (Int_t i=0;i<6;i++){
2359 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2360 Double_t sy1 = forwardtrack->GetSigmaY(i);
2361 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2362 Double_t sy2 = backtrack->GetSigmaY(i);
2363 Double_t sz2 = backtrack->GetSigmaZ(i);
2364 if (i<2){ sy2=1000.;sz2=1000;}
2366 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2367 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2369 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2370 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2372 res+= nz0*nz0+ny0*ny0;
2375 if (npoints>1) return
2376 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2377 //2*forwardtrack->fNUsed+
2378 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2379 1./(1.+forwardtrack->GetNSkipped()));
2382 //------------------------------------------------------------------------
2383 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2384 //--------------------------------------------------------------------
2385 // Return pointer to a given cluster
2386 //--------------------------------------------------------------------
2387 Int_t l=(index & 0xf0000000) >> 28;
2388 Int_t c=(index & 0x0fffffff) >> 00;
2389 return fgLayers[l].GetWeight(c);
2391 //------------------------------------------------------------------------
2392 void AliITStrackerMI::RegisterClusterTracks(AliITStrackMI* track,Int_t id)
2394 //---------------------------------------------
2395 // register track to the list
2397 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2400 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2401 Int_t index = track->GetClusterIndex(icluster);
2402 Int_t l=(index & 0xf0000000) >> 28;
2403 Int_t c=(index & 0x0fffffff) >> 00;
2404 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2405 for (Int_t itrack=0;itrack<4;itrack++){
2406 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2407 fgLayers[l].SetClusterTracks(itrack,c,id);
2413 //------------------------------------------------------------------------
2414 void AliITStrackerMI::UnRegisterClusterTracks(AliITStrackMI* track, Int_t id)
2416 //---------------------------------------------
2417 // unregister track from the list
2418 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2419 Int_t index = track->GetClusterIndex(icluster);
2420 Int_t l=(index & 0xf0000000) >> 28;
2421 Int_t c=(index & 0x0fffffff) >> 00;
2422 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2423 for (Int_t itrack=0;itrack<4;itrack++){
2424 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2425 fgLayers[l].SetClusterTracks(itrack,c,-1);
2430 //------------------------------------------------------------------------
2431 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2433 //-------------------------------------------------------------
2434 //get number of shared clusters
2435 //-------------------------------------------------------------
2437 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2438 // mean number of clusters
2439 Float_t *ny = GetNy(id), *nz = GetNz(id);
2442 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2443 Int_t index = track->GetClusterIndex(icluster);
2444 Int_t l=(index & 0xf0000000) >> 28;
2445 Int_t c=(index & 0x0fffffff) >> 00;
2446 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2448 printf("problem\n");
2450 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2454 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2455 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2456 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2458 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2461 deltan = (cl->GetNz()-nz[l]);
2463 if (deltan>2.0) continue; // extended - highly probable shared cluster
2464 weight = 2./TMath::Max(3.+deltan,2.);
2466 for (Int_t itrack=0;itrack<4;itrack++){
2467 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2469 clist[l] = (AliITSRecPoint*)GetCluster(index);
2475 track->SetNUsed(shared);
2478 //------------------------------------------------------------------------
2479 Int_t AliITStrackerMI::GetOverlapTrack(AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2482 // find first shared track
2484 // mean number of clusters
2485 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2487 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2488 Int_t sharedtrack=100000;
2489 Int_t tracks[24],trackindex=0;
2490 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2492 for (Int_t icluster=0;icluster<6;icluster++){
2493 if (clusterlist[icluster]<0) continue;
2494 Int_t index = clusterlist[icluster];
2495 Int_t l=(index & 0xf0000000) >> 28;
2496 Int_t c=(index & 0x0fffffff) >> 00;
2498 printf("problem\n");
2500 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2501 //if (l>3) continue;
2502 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2505 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2506 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2507 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2509 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2512 deltan = (cl->GetNz()-nz[l]);
2514 if (deltan>2.0) continue; // extended - highly probable shared cluster
2516 for (Int_t itrack=3;itrack>=0;itrack--){
2517 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2518 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2519 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2524 if (trackindex==0) return -1;
2526 sharedtrack = tracks[0];
2528 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2531 Int_t track[24], cluster[24];
2532 for (Int_t i=0;i<trackindex;i++){ track[i]=-1; cluster[i]=0;}
2535 for (Int_t i=0;i<trackindex;i++){
2536 if (tracks[i]<0) continue;
2537 track[index] = tracks[i];
2539 for (Int_t j=i+1;j<trackindex;j++){
2540 if (tracks[j]<0) continue;
2541 if (tracks[j]==tracks[i]){
2549 for (Int_t i=0;i<index;i++){
2550 if (cluster[index]>max) {
2551 sharedtrack=track[index];
2558 if (sharedtrack>=100000) return -1;
2560 // make list of overlaps
2562 for (Int_t icluster=0;icluster<6;icluster++){
2563 if (clusterlist[icluster]<0) continue;
2564 Int_t index = clusterlist[icluster];
2565 Int_t l=(index & 0xf0000000) >> 28;
2566 Int_t c=(index & 0x0fffffff) >> 00;
2567 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2568 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2570 if (cl->GetNy()>2) continue;
2571 if (cl->GetNz()>2) continue;
2574 if (cl->GetNy()>3) continue;
2575 if (cl->GetNz()>3) continue;
2578 for (Int_t itrack=3;itrack>=0;itrack--){
2579 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2580 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2588 //------------------------------------------------------------------------
2589 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2591 // try to find track hypothesys without conflicts
2592 // with minimal chi2;
2593 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2594 Int_t entries1 = arr1->GetEntriesFast();
2595 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2596 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2597 Int_t entries2 = arr2->GetEntriesFast();
2598 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2600 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2601 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2602 if (track10->Pt()>0.5+track20->Pt()) return track10;
2604 for (Int_t itrack=0;itrack<entries1;itrack++){
2605 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2606 UnRegisterClusterTracks(track,trackID1);
2609 for (Int_t itrack=0;itrack<entries2;itrack++){
2610 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2611 UnRegisterClusterTracks(track,trackID2);
2615 Float_t maxconflicts=6;
2616 Double_t maxchi2 =1000.;
2618 // get weight of hypothesys - using best hypothesy
2621 Int_t list1[6],list2[6];
2622 AliITSRecPoint *clist1[6], *clist2[6] ;
2623 RegisterClusterTracks(track10,trackID1);
2624 RegisterClusterTracks(track20,trackID2);
2625 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2626 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2627 UnRegisterClusterTracks(track10,trackID1);
2628 UnRegisterClusterTracks(track20,trackID2);
2631 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2632 Float_t nerry[6],nerrz[6];
2633 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2634 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2635 for (Int_t i=0;i<6;i++){
2636 if ( (erry1[i]>0) && (erry2[i]>0)) {
2637 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2638 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2640 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2641 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2643 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2644 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2645 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2648 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2649 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2650 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2658 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2659 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2660 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2661 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2663 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2664 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2665 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2667 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2668 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2669 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2672 Double_t sumw = w1+w2;
2676 w1 = (d2+0.5)/(d1+d2+1.);
2677 w2 = (d1+0.5)/(d1+d2+1.);
2679 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2680 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2682 // get pair of "best" hypothesys
2684 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2685 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2687 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2688 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2689 //if (track1->fFakeRatio>0) continue;
2690 RegisterClusterTracks(track1,trackID1);
2691 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2692 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2694 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2695 //if (track2->fFakeRatio>0) continue;
2697 RegisterClusterTracks(track2,trackID2);
2698 Int_t list1[6],list2[6];
2699 AliITSRecPoint *clist1[6], *clist2[6] ;
2700 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2701 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2702 UnRegisterClusterTracks(track2,trackID2);
2704 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2705 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2706 if (nskipped>0.5) continue;
2708 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2709 if (conflict1+1<cconflict1) continue;
2710 if (conflict2+1<cconflict2) continue;
2714 for (Int_t i=0;i<6;i++){
2716 Float_t c1 =0.; // conflict coeficients
2718 if (clist1[i]&&clist2[i]){
2721 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2724 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
2726 c1 = 2./TMath::Max(3.+deltan,2.);
2727 c2 = 2./TMath::Max(3.+deltan,2.);
2733 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
2736 deltan = (clist1[i]->GetNz()-nz1[i]);
2738 c1 = 2./TMath::Max(3.+deltan,2.);
2745 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
2748 deltan = (clist2[i]->GetNz()-nz2[i]);
2750 c2 = 2./TMath::Max(3.+deltan,2.);
2755 Double_t chi21=0,chi22=0;
2756 if (TMath::Abs(track1->GetDy(i))>0.) {
2757 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
2758 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
2759 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
2760 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
2762 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
2765 if (TMath::Abs(track2->GetDy(i))>0.) {
2766 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
2767 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
2768 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
2769 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
2772 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
2774 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
2775 if (chi21>0) sum+=w1;
2776 if (chi22>0) sum+=w2;
2779 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
2780 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
2781 Double_t normchi2 = 2*conflict+sumchi2/sum;
2782 if ( normchi2 <maxchi2 ){
2785 maxconflicts = conflict;
2789 UnRegisterClusterTracks(track1,trackID1);
2792 // if (maxconflicts<4 && maxchi2<th0){
2793 if (maxchi2<th0*2.){
2794 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
2795 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
2796 track1->SetChi2MIP(5,maxconflicts);
2797 track1->SetChi2MIP(6,maxchi2);
2798 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
2799 // track1->UpdateESDtrack(AliESDtrack::kITSin);
2800 track1->SetChi2MIP(8,index1);
2801 fBestTrackIndex[trackID1] =index1;
2802 UpdateESDtrack(track1, AliESDtrack::kITSin);
2804 else if (track10->GetChi2MIP(0)<th1){
2805 track10->SetChi2MIP(5,maxconflicts);
2806 track10->SetChi2MIP(6,maxchi2);
2807 // track10->UpdateESDtrack(AliESDtrack::kITSin);
2808 UpdateESDtrack(track10,AliESDtrack::kITSin);
2811 for (Int_t itrack=0;itrack<entries1;itrack++){
2812 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2813 UnRegisterClusterTracks(track,trackID1);
2816 for (Int_t itrack=0;itrack<entries2;itrack++){
2817 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2818 UnRegisterClusterTracks(track,trackID2);
2821 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2822 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2823 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2824 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2825 RegisterClusterTracks(track10,trackID1);
2827 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2828 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2829 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2830 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2831 RegisterClusterTracks(track20,trackID2);
2836 //------------------------------------------------------------------------
2837 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
2838 //--------------------------------------------------------------------
2839 // This function marks clusters assigned to the track
2840 //--------------------------------------------------------------------
2841 AliTracker::UseClusters(t,from);
2843 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
2844 //if (c->GetQ()>2) c->Use();
2845 if (c->GetSigmaZ2()>0.1) c->Use();
2846 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
2847 //if (c->GetQ()>2) c->Use();
2848 if (c->GetSigmaZ2()>0.1) c->Use();
2851 //------------------------------------------------------------------------
2852 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
2854 //------------------------------------------------------------------
2855 // add track to the list of hypothesys
2856 //------------------------------------------------------------------
2858 if (esdindex>=fTrackHypothesys.GetEntriesFast()) fTrackHypothesys.Expand(esdindex*2+10);
2860 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
2862 array = new TObjArray(10);
2863 fTrackHypothesys.AddAt(array,esdindex);
2865 array->AddLast(track);
2867 //------------------------------------------------------------------------
2868 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
2870 //-------------------------------------------------------------------
2871 // compress array of track hypothesys
2872 // keep only maxsize best hypothesys
2873 //-------------------------------------------------------------------
2874 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
2875 if (! (fTrackHypothesys.At(esdindex)) ) return;
2876 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
2877 Int_t entries = array->GetEntriesFast();
2879 //- find preliminary besttrack as a reference
2880 Float_t minchi2=10000;
2882 AliITStrackMI * besttrack=0;
2883 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
2884 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2885 if (!track) continue;
2886 Float_t chi2 = NormalizedChi2(track,0);
2888 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
2889 track->SetLabel(tpcLabel);
2891 track->SetFakeRatio(1.);
2892 CookLabel(track,0.); //For comparison only
2894 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
2895 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
2896 if (track->GetNumberOfClusters()<maxn) continue;
2897 maxn = track->GetNumberOfClusters();
2904 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2905 delete array->RemoveAt(itrack);
2909 if (!besttrack) return;
2912 //take errors of best track as a reference
2913 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
2914 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
2915 for (Int_t i=0;i<6;i++) {
2916 if (besttrack->GetClIndex(i)>0){
2917 erry[i] = besttrack->GetSigmaY(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2918 errz[i] = besttrack->GetSigmaZ(i); errz[i+6] = besttrack->GetSigmaZ(i+6);
2919 ny[i] = besttrack->GetNy(i);
2920 nz[i] = besttrack->GetNz(i);
2924 // calculate normalized chi2
2926 Float_t * chi2 = new Float_t[entries];
2927 Int_t * index = new Int_t[entries];
2928 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
2929 for (Int_t itrack=0;itrack<entries;itrack++){
2930 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2932 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
2933 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
2934 chi2[itrack] = track->GetChi2MIP(0);
2936 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2937 delete array->RemoveAt(itrack);
2943 TMath::Sort(entries,chi2,index,kFALSE);
2944 besttrack = (AliITStrackMI*)array->At(index[0]);
2945 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
2946 for (Int_t i=0;i<6;i++){
2947 if (besttrack->GetClIndex(i)>0){
2948 erry[i] = besttrack->GetSigmaY(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2949 errz[i] = besttrack->GetSigmaZ(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2950 ny[i] = besttrack->GetNy(i);
2951 nz[i] = besttrack->GetNz(i);
2956 // calculate one more time with updated normalized errors
2957 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
2958 for (Int_t itrack=0;itrack<entries;itrack++){
2959 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2961 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
2962 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
2963 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
2966 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2967 delete array->RemoveAt(itrack);
2972 entries = array->GetEntriesFast();
2976 TObjArray * newarray = new TObjArray();
2977 TMath::Sort(entries,chi2,index,kFALSE);
2978 besttrack = (AliITStrackMI*)array->At(index[0]);
2981 for (Int_t i=0;i<6;i++){
2982 if (besttrack->GetNz(i)>0&&besttrack->GetNy(i)>0){
2983 erry[i] = besttrack->GetSigmaY(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2984 errz[i] = besttrack->GetSigmaZ(i); errz[i+6] = besttrack->GetSigmaZ(i+6);
2985 ny[i] = besttrack->GetNy(i);
2986 nz[i] = besttrack->GetNz(i);
2989 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
2990 Float_t minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
2991 Float_t minn = besttrack->GetNumberOfClusters()-3;
2993 for (Int_t i=0;i<entries;i++){
2994 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
2995 if (!track) continue;
2996 if (accepted>maxcut) break;
2997 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
2998 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2999 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3000 delete array->RemoveAt(index[i]);
3004 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3005 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3006 if (!shortbest) accepted++;
3008 newarray->AddLast(array->RemoveAt(index[i]));
3009 for (Int_t i=0;i<6;i++){
3011 erry[i] = track->GetSigmaY(i); erry[i+6] = track->GetSigmaY(i+6);
3012 errz[i] = track->GetSigmaZ(i); errz[i] = track->GetSigmaZ(i+6);
3013 ny[i] = track->GetNy(i);
3014 nz[i] = track->GetNz(i);
3019 delete array->RemoveAt(index[i]);
3023 delete fTrackHypothesys.RemoveAt(esdindex);
3024 fTrackHypothesys.AddAt(newarray,esdindex);
3028 delete fTrackHypothesys.RemoveAt(esdindex);
3034 //------------------------------------------------------------------------
3035 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3037 //-------------------------------------------------------------
3038 // try to find best hypothesy
3039 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3040 //-------------------------------------------------------------
3041 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3042 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3043 if (!array) return 0;
3044 Int_t entries = array->GetEntriesFast();
3045 if (!entries) return 0;
3046 Float_t minchi2 = 100000;
3047 AliITStrackMI * besttrack=0;
3049 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3050 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3051 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3052 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3054 for (Int_t i=0;i<entries;i++){
3055 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3056 if (!track) continue;
3057 Float_t sigmarfi,sigmaz;
3058 GetDCASigma(track,sigmarfi,sigmaz);
3059 track->SetDnorm(0,sigmarfi);
3060 track->SetDnorm(1,sigmaz);
3062 track->SetChi2MIP(1,1000000);
3063 track->SetChi2MIP(2,1000000);
3064 track->SetChi2MIP(3,1000000);
3067 backtrack = new(backtrack) AliITStrackMI(*track);
3068 if (track->GetConstrain()) {
3069 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3070 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3071 backtrack->ResetCovariance(10.);
3073 backtrack->ResetCovariance(10.);
3075 backtrack->ResetClusters();
3077 Double_t x = original->GetX();
3078 if (!RefitAt(x,backtrack,track)) continue;
3080 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3081 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3082 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3083 track->SetChi22(GetMatchingChi2(backtrack,original));
3085 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3086 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3087 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3090 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3092 //forward track - without constraint
3093 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3094 forwardtrack->ResetClusters();
3096 RefitAt(x,forwardtrack,track);
3097 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3098 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3099 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3101 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3102 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3103 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3104 forwardtrack->SetD(0,track->GetD(0));
3105 forwardtrack->SetD(1,track->GetD(1));
3108 AliITSRecPoint* clist[6];
3109 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3110 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3113 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3114 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3115 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3116 track->SetChi2MIP(3,1000);
3119 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3121 for (Int_t ichi=0;ichi<5;ichi++){
3122 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3124 if (chi2 < minchi2){
3125 //besttrack = new AliITStrackMI(*forwardtrack);
3127 besttrack->SetLabel(track->GetLabel());
3128 besttrack->SetFakeRatio(track->GetFakeRatio());
3130 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3131 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3132 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3136 delete forwardtrack;
3138 for (Int_t i=0;i<entries;i++){
3139 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3140 if (!track) continue;
3142 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3143 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3144 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3145 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3146 delete array->RemoveAt(i);
3156 SortTrackHypothesys(esdindex,checkmax,1);
3157 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3158 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3159 besttrack = (AliITStrackMI*)array->At(0);
3160 if (!besttrack) return 0;
3161 besttrack->SetChi2MIP(8,0);
3162 fBestTrackIndex[esdindex]=0;
3163 entries = array->GetEntriesFast();
3164 AliITStrackMI *longtrack =0;
3166 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3167 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3168 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3169 if (!track->GetConstrain()) continue;
3170 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3171 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3172 if (track->GetChi2MIP(0)>4.) continue;
3173 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3176 //if (longtrack) besttrack=longtrack;
3179 AliITSRecPoint * clist[6];
3180 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3181 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3182 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3183 RegisterClusterTracks(besttrack,esdindex);
3190 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3191 if (sharedtrack>=0){
3193 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3195 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3201 if (shared>2.5) return 0;
3202 if (shared>1.0) return besttrack;
3204 // Don't sign clusters if not gold track
3206 if (!besttrack->IsGoldPrimary()) return besttrack;
3207 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3209 if (fConstraint[fPass]){
3213 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3214 for (Int_t i=0;i<6;i++){
3215 Int_t index = besttrack->GetClIndex(i);
3216 if (index<=0) continue;
3217 Int_t ilayer = (index & 0xf0000000) >> 28;
3218 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3219 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3221 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3222 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3223 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3224 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3225 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3226 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3228 Bool_t cansign = kTRUE;
3229 for (Int_t itrack=0;itrack<entries; itrack++){
3230 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3231 if (!track) continue;
3232 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3233 if ( (track->GetClIndex(ilayer)>0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3239 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3240 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3241 if (!c->IsUsed()) c->Use();
3247 //------------------------------------------------------------------------
3248 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3251 // get "best" hypothesys
3254 Int_t nentries = itsTracks.GetEntriesFast();
3255 for (Int_t i=0;i<nentries;i++){
3256 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3257 if (!track) continue;
3258 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3259 if (!array) continue;
3260 if (array->GetEntriesFast()<=0) continue;
3262 AliITStrackMI* longtrack=0;
3264 Float_t maxchi2=1000;
3265 for (Int_t j=0;j<array->GetEntriesFast();j++){
3266 AliITStrackMI* track = (AliITStrackMI*)array->At(j);
3267 if (!track) continue;
3268 if (track->GetGoldV0()) {
3269 longtrack = track; //gold V0 track taken
3272 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3273 Float_t chi2 = track->GetChi2MIP(0);
3275 if (!track->GetGoldV0()&&track->GetConstrain()==kFALSE) chi2+=5;
3277 if (track->GetNumberOfClusters()+track->GetNDeadZone()>minn) maxchi2 = track->GetChi2MIP(0);
3279 if (chi2 > maxchi2) continue;
3280 minn= track->GetNumberOfClusters()+track->GetNDeadZone();
3287 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3288 if (!longtrack) {longtrack = besttrack;}
3289 else besttrack= longtrack;
3293 AliITSRecPoint * clist[6];
3294 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3296 track->SetNUsed(shared);
3297 track->SetNSkipped(besttrack->GetNSkipped());
3298 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3300 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3304 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3305 //if (sharedtrack==-1) sharedtrack=0;
3306 if (sharedtrack>=0) {
3307 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3310 if (besttrack&&fAfterV0) {
3311 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3313 if (besttrack&&fConstraint[fPass])
3314 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3315 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3316 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3317 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3323 //------------------------------------------------------------------------
3324 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3325 //--------------------------------------------------------------------
3326 //This function "cooks" a track label. If label<0, this track is fake.
3327 //--------------------------------------------------------------------
3330 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3332 track->SetChi2MIP(9,0);
3334 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3335 Int_t cindex = track->GetClusterIndex(i);
3336 Int_t l=(cindex & 0xf0000000) >> 28;
3337 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3339 for (Int_t ind=0;ind<3;ind++){
3341 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3343 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3346 Int_t nclusters = track->GetNumberOfClusters();
3347 if (nclusters > 0) //PH Some tracks don't have any cluster
3348 track->SetFakeRatio(double(nwrong)/double(nclusters));
3350 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3352 track->SetLabel(tpcLabel);
3356 //------------------------------------------------------------------------
3357 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3362 //AliITSRecPoint * clist[6];
3363 // Int_t shared = GetNumberOfSharedClusters(track,index,list,clist);
3366 track->SetChi2MIP(9,0);
3367 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3368 Int_t cindex = track->GetClusterIndex(i);
3369 Int_t l=(cindex & 0xf0000000) >> 28;
3370 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3371 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3373 for (Int_t ind=0;ind<3;ind++){
3374 if (cl->GetLabel(ind)==lab) isWrong=0;
3376 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3378 //if (l>3 && (cl->GetNy()>4) || (cl->GetNz()>4)) continue; //shared track
3379 //if (l>3&& !(cl->GetType()==1||cl->GetType()==10)) continue;
3380 //if (l<4&& !(cl->GetType()==1)) continue;
3381 dedx[accepted]= track->GetSampledEdx(i);
3382 //dedx[accepted]= track->fNormQ[l];
3390 TMath::Sort(accepted,dedx,indexes,kFALSE);
3393 Double_t nl=low*accepted, nu =up*accepted;
3395 Float_t sumweight =0;
3396 for (Int_t i=0; i<accepted; i++) {
3398 if (i<nl+0.1) weight = TMath::Max(1.-(nl-i),0.);
3399 if (i>nu-1) weight = TMath::Max(nu-i,0.);
3400 sumamp+= dedx[indexes[i]]*weight;
3403 track->SetdEdx(sumamp/sumweight);
3405 //------------------------------------------------------------------------
3406 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3409 if (fCoefficients) delete []fCoefficients;
3410 fCoefficients = new Float_t[ntracks*48];
3411 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3413 //------------------------------------------------------------------------
3414 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3420 Float_t theta = track->GetTgl();
3421 Float_t phi = track->GetSnp();
3422 phi = TMath::Sqrt(phi*phi/(1.-phi*phi));
3423 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz);
3424 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz);
3426 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3427 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3429 chi2+=0.5*TMath::Min(delta/2,2.);
3430 chi2+=2.*cluster->GetDeltaProbability();
3433 track->SetNy(layer,ny);
3434 track->SetNz(layer,nz);
3435 track->SetSigmaY(layer,erry);
3436 track->SetSigmaZ(layer, errz);
3437 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3438 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/(1.- track->GetSnp()*track->GetSnp())));
3442 //------------------------------------------------------------------------
3443 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3448 Int_t layer = (index & 0xf0000000) >> 28;
3449 track->SetClIndex(layer, index);
3450 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3451 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3452 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3453 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3457 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3459 //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]);
3462 // Take into account the mis-alignment
3463 Double_t x=track->GetX()+cl->GetX();
3464 if (!track->PropagateTo(x,0.,0.)) return 0;
3466 return track->UpdateMI(cl->GetY(),cl->GetZ(),track->GetSigmaY(layer),track->GetSigmaZ(layer),chi2,index);
3468 //------------------------------------------------------------------------
3469 void AliITStrackerMI::GetDCASigma(AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3472 //DCA sigmas parameterization
3473 //to be paramterized using external parameters in future
3476 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3477 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3479 //------------------------------------------------------------------------
3480 void AliITStrackerMI::SignDeltas( TObjArray *ClusterArray, Float_t vz)
3484 Int_t entries = ClusterArray->GetEntriesFast();
3485 if (entries<4) return;
3486 AliITSRecPoint* cluster = (AliITSRecPoint*)ClusterArray->At(0);
3487 Int_t layer = cluster->GetLayer();
3488 if (layer>1) return;
3490 Int_t ncandidates=0;
3491 Float_t r = (layer>0)? 7:4;
3493 for (Int_t i=0;i<entries;i++){
3494 AliITSRecPoint* cl0 = (AliITSRecPoint*)ClusterArray->At(i);
3495 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3496 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3497 index[ncandidates] = i; //candidate to belong to delta electron track
3499 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3500 cl0->SetDeltaProbability(1);
3506 for (Int_t i=0;i<ncandidates;i++){
3507 AliITSRecPoint* cl0 = (AliITSRecPoint*)ClusterArray->At(index[i]);
3508 if (cl0->GetDeltaProbability()>0.8) continue;
3511 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3512 sumy=sumz=sumy2=sumyz=sumw=0.0;
3513 for (Int_t j=0;j<ncandidates;j++){
3515 AliITSRecPoint* cl1 = (AliITSRecPoint*)ClusterArray->At(index[j]);
3517 Float_t dz = cl0->GetZ()-cl1->GetZ();
3518 Float_t dy = cl0->GetY()-cl1->GetY();
3519 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3520 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3521 y[ncl] = cl1->GetY();
3522 z[ncl] = cl1->GetZ();
3523 sumy+= y[ncl]*weight;
3524 sumz+= z[ncl]*weight;
3525 sumy2+=y[ncl]*y[ncl]*weight;
3526 sumyz+=y[ncl]*z[ncl]*weight;
3531 if (ncl<4) continue;
3532 Float_t det = sumw*sumy2 - sumy*sumy;
3534 if (TMath::Abs(det)>0.01){
3535 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3536 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3537 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3540 Float_t z0 = sumyz/sumy;
3541 delta = TMath::Abs(cl0->GetZ()-z0);
3544 cl0->SetDeltaProbability(1-20.*delta);
3548 //------------------------------------------------------------------------
3549 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3553 track->UpdateESDtrack(flags);
3554 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3555 if (oldtrack) delete oldtrack;
3556 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3557 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3558 printf("Problem\n");
3561 //------------------------------------------------------------------------
3562 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3564 //Get nearest upper layer close to the point xr.
3565 // rough approximation
3567 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3568 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3570 for (Int_t i=0;i<6;i++){
3571 if (radius<kRadiuses[i]){
3578 //------------------------------------------------------------------------
3579 void AliITStrackerMI::UpdateTPCV0(AliESDEvent *event){
3581 //try to update, or reject TPC V0s
3583 Int_t nv0s = event->GetNumberOfV0s();
3584 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3586 for (Int_t i=0;i<nv0s;i++){
3587 AliESDv0 * vertex = event->GetV0(i);
3588 Int_t ip = vertex->GetIndex(0);
3589 Int_t im = vertex->GetIndex(1);
3591 TObjArray * arrayp = (ip<nitstracks) ? (TObjArray*)fTrackHypothesys.At(ip):0;
3592 TObjArray * arraym = (im<nitstracks) ? (TObjArray*)fTrackHypothesys.At(im):0;
3593 AliITStrackMI * trackp = (arrayp!=0) ? (AliITStrackMI*)arrayp->At(0):0;
3594 AliITStrackMI * trackm = (arraym!=0) ? (AliITStrackMI*)arraym->At(0):0;
3598 if (trackp->GetNumberOfClusters()+trackp->GetNDeadZone()>5.5){
3599 if (trackp->GetConstrain()&&trackp->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3600 if (!trackp->GetConstrain()&&trackp->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3605 if (trackm->GetNumberOfClusters()+trackm->GetNDeadZone()>5.5){
3606 if (trackm->GetConstrain()&&trackm->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3607 if (!trackm->GetConstrain()&&trackm->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3610 if (vertex->GetStatus()==-100) continue;
3612 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
3613 Int_t clayer = GetNearestLayer(xrp); //I.B.
3614 vertex->SetNBefore(clayer); //
3615 vertex->SetChi2Before(9*clayer); //
3616 vertex->SetNAfter(6-clayer); //
3617 vertex->SetChi2After(0); //
3619 if (clayer >1 ){ // calculate chi2 before vertex
3620 Float_t chi2p = 0, chi2m=0;
3623 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3624 if (trackp->GetClIndex(ilayer)>0){
3625 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3626 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3637 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3638 if (trackm->GetClIndex(ilayer)>0){
3639 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3640 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3649 vertex->SetChi2Before(TMath::Min(chi2p,chi2m));
3650 if (TMath::Min(chi2p,chi2m)/Float_t(clayer)<4) vertex->SetStatus(-10); // track exist before vertex
3653 if (clayer < 5 ){ // calculate chi2 after vertex
3654 Float_t chi2p = 0, chi2m=0;
3656 if (trackp&&TMath::Abs(trackp->GetTgl())<1.){
3657 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3658 if (trackp->GetClIndex(ilayer)>0){
3659 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3660 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3670 if (trackm&&TMath::Abs(trackm->GetTgl())<1.){
3671 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3672 if (trackm->GetClIndex(ilayer)>0){
3673 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3674 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3683 vertex->SetChi2After(TMath::Max(chi2p,chi2m));
3684 if (TMath::Max(chi2m,chi2p)/Float_t(6-clayer)>9) vertex->SetStatus(-20); // track not found in ITS
3689 //------------------------------------------------------------------------
3690 void AliITStrackerMI::FindV02(AliESDEvent *event)
3695 // Cuts on DCA - R dependent
3696 // max distance DCA between 2 tracks cut
3697 // maxDist = TMath::Min(kMaxDist,kMaxDist0+pvertex->GetRr()*kMaxDist);
3699 const Float_t kMaxDist0 = 0.1;
3700 const Float_t kMaxDist1 = 0.1;
3701 const Float_t kMaxDist = 1;
3702 const Float_t kMinPointAngle = 0.85;
3703 const Float_t kMinPointAngle2 = 0.99;
3704 const Float_t kMinR = 0.5;
3705 const Float_t kMaxR = 220;
3706 //const Float_t kCausality0Cut = 0.19;
3707 //const Float_t kLikelihood01Cut = 0.25;
3708 //const Float_t kPointAngleCut = 0.9996;
3709 const Float_t kCausality0Cut = 0.19;
3710 const Float_t kLikelihood01Cut = 0.45;
3711 const Float_t kLikelihood1Cut = 0.5;
3712 const Float_t kCombinedCut = 0.55;
3716 TTreeSRedirector &cstream = *fDebugStreamer;
3717 Int_t ntracks = event->GetNumberOfTracks();
3718 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3719 fOriginal.Expand(ntracks);
3720 fTrackHypothesys.Expand(ntracks);
3721 fBestHypothesys.Expand(ntracks);
3723 AliHelix * helixes = new AliHelix[ntracks+2];
3724 TObjArray trackarray(ntracks+2); //array with tracks - with vertex constrain
3725 TObjArray trackarrayc(ntracks+2); //array of "best tracks" - without vertex constrain
3726 TObjArray trackarrayl(ntracks+2); //array of "longest tracks" - without vertex constrain
3727 Bool_t * forbidden = new Bool_t [ntracks+2];
3728 Int_t *itsmap = new Int_t [ntracks+2];
3729 Float_t *dist = new Float_t[ntracks+2];
3730 Float_t *normdist0 = new Float_t[ntracks+2];
3731 Float_t *normdist1 = new Float_t[ntracks+2];
3732 Float_t *normdist = new Float_t[ntracks+2];
3733 Float_t *norm = new Float_t[ntracks+2];
3734 Float_t *maxr = new Float_t[ntracks+2];
3735 Float_t *minr = new Float_t[ntracks+2];
3736 Float_t *minPointAngle= new Float_t[ntracks+2];
3738 AliV0 *pvertex = new AliV0;
3739 AliITStrackMI * dummy= new AliITStrackMI;
3741 AliITStrackMI trackat0; //temporary track for DCA calculation
3743 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
3745 // make ITS - ESD map
3747 for (Int_t itrack=0;itrack<ntracks+2;itrack++) {
3748 itsmap[itrack] = -1;
3749 forbidden[itrack] = kFALSE;
3750 maxr[itrack] = kMaxR;
3751 minr[itrack] = kMinR;
3752 minPointAngle[itrack] = kMinPointAngle;
3754 for (Int_t itrack=0;itrack<nitstracks;itrack++){
3755 AliITStrackMI * original = (AliITStrackMI*)(fOriginal.At(itrack));
3756 Int_t esdindex = original->GetESDtrack()->GetID();
3757 itsmap[esdindex] = itrack;
3760 // create ITS tracks from ESD tracks if not done before
3762 for (Int_t itrack=0;itrack<ntracks;itrack++){
3763 if (itsmap[itrack]>=0) continue;
3764 AliITStrackMI * tpctrack = new AliITStrackMI(*(event->GetTrack(itrack)));
3765 //tpctrack->fD[0] = tpctrack->GetD(GetX(),GetY());
3766 //tpctrack->fD[1] = tpctrack->GetZat(GetX())-GetZ();
3767 tpctrack->GetDZ(GetX(),GetY(),GetZ(),tpctrack->GetDP()); //I.B.
3768 if (tpctrack->GetD(0)<20 && tpctrack->GetD(1)<20){
3769 // tracks which can reach inner part of ITS
3770 // propagate track to outer its volume - with correction for material
3771 CorrectForTPCtoITSDeadZoneMaterial(tpctrack);
3773 itsmap[itrack] = nitstracks;
3774 fOriginal.AddAt(tpctrack,nitstracks);
3778 // fill temporary arrays
3780 for (Int_t itrack=0;itrack<ntracks;itrack++){
3781 AliESDtrack * esdtrack = event->GetTrack(itrack);
3782 Int_t itsindex = itsmap[itrack];
3783 AliITStrackMI *original = (AliITStrackMI*)fOriginal.At(itsmap[itrack]);
3784 if (!original) continue;
3785 AliITStrackMI *bestConst = 0;
3786 AliITStrackMI *bestLong = 0;
3787 AliITStrackMI *best = 0;
3790 TObjArray * array = (TObjArray*) fTrackHypothesys.At(itsindex);
3791 Int_t hentries = (array==0) ? 0 : array->GetEntriesFast();
3792 // Get best track with vertex constrain
3793 for (Int_t ih=0;ih<hentries;ih++){
3794 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
3795 if (!trackh->GetConstrain()) continue;
3796 if (!bestConst) bestConst = trackh;
3797 if (trackh->GetNumberOfClusters()>5.0){
3798 bestConst = trackh; // full track - with minimal chi2
3801 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()) continue;
3805 // Get best long track without vertex constrain and best track without vertex constrain
3806 for (Int_t ih=0;ih<hentries;ih++){
3807 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
3808 if (trackh->GetConstrain()) continue;
3809 if (!best) best = trackh;
3810 if (!bestLong) bestLong = trackh;
3811 if (trackh->GetNumberOfClusters()>5.0){
3812 bestLong = trackh; // full track - with minimal chi2
3815 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()) continue;
3820 bestLong = original;
3822 //I.B. trackat0 = *bestLong;
3823 new (&trackat0) AliITStrackMI(*bestLong);
3824 Double_t xx,yy,zz,alpha;
3825 bestLong->GetGlobalXYZat(bestLong->GetX(),xx,yy,zz);
3826 alpha = TMath::ATan2(yy,xx);
3827 trackat0.Propagate(alpha,0);
3828 // calculate normalized distances to the vertex
3830 Float_t ptfac = (1.+100.*TMath::Abs(trackat0.GetC()));
3831 if ( bestLong->GetNumberOfClusters()>3 ){
3832 dist[itsindex] = trackat0.GetY();
3833 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
3834 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
3835 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
3836 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3838 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<6) normdist[itsindex]*=2.;
3839 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<5) normdist[itsindex]*=2.;
3840 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<4) normdist[itsindex]*=2.;
3842 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<6) normdist[itsindex]*=1.5;
3843 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<5) normdist[itsindex]*=1.5;
3847 if (bestConst&&bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5){
3848 dist[itsindex] = bestConst->GetD(0);
3849 norm[itsindex] = bestConst->GetDnorm(0);
3850 normdist0[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
3851 normdist1[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
3852 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3854 dist[itsindex] = trackat0.GetY();
3855 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
3856 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
3857 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
3858 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3859 if (TMath::Abs(trackat0.GetTgl())>1.05){
3860 if (normdist[itsindex]<3) forbidden[itsindex]=kTRUE;
3861 if (normdist[itsindex]>3) {
3862 minr[itsindex] = TMath::Max(Float_t(40.),minr[itsindex]);
3868 //-----------------------------------------------------------
3869 //Forbid primary track candidates -
3871 //treetr->SetAlias("forbidden0","Tr0.fN<4&&Tr1.fN+Tr1.fNDeadZone>4.5");
3872 //treetr->SetAlias("forbidden1","ND<3&&Tr1.fN+Tr1.fNDeadZone>5.5");
3873 //treetr->SetAlias("forbidden2","ND<2&&Tr1.fClIndex[0]>0&&Tr1.fClIndex[0]>0");
3874 //treetr->SetAlias("forbidden3","ND<1&&Tr1.fClIndex[0]>0");
3875 //treetr->SetAlias("forbidden4","ND<4&&Tr1.fNormChi2[0]<2");
3876 //treetr->SetAlias("forbidden5","ND<5&&Tr1.fNormChi2[0]<1");
3877 //-----------------------------------------------------------
3879 if (bestLong->GetNumberOfClusters()<4 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5) forbidden[itsindex]=kTRUE;
3880 if (normdist[itsindex]<3 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>5.5) forbidden[itsindex]=kTRUE;
3881 if (normdist[itsindex]<2 && bestConst->GetClIndex(0)>0 && bestConst->GetClIndex(1)>0 ) forbidden[itsindex]=kTRUE;
3882 if (normdist[itsindex]<1 && bestConst->GetClIndex(0)>0) forbidden[itsindex]=kTRUE;
3883 if (normdist[itsindex]<4 && bestConst->GetNormChi2(0)<2) forbidden[itsindex]=kTRUE;
3884 if (normdist[itsindex]<5 && bestConst->GetNormChi2(0)<1) forbidden[itsindex]=kTRUE;
3885 if (bestConst->GetNormChi2(0)<2.5) {
3886 minPointAngle[itsindex]= 0.9999;
3887 maxr[itsindex] = 10;
3891 //forbid daughter kink candidates
3893 if (esdtrack->GetKinkIndex(0)>0) forbidden[itsindex] = kTRUE;
3894 Bool_t isElectron = kTRUE;
3895 Bool_t isProton = kTRUE;
3897 esdtrack->GetESDpid(pid);
3898 for (Int_t i=1;i<5;i++){
3899 if (pid[0]<pid[i]) isElectron= kFALSE;
3900 if (pid[4]<pid[i]) isProton= kFALSE;
3903 forbidden[itsindex]=kFALSE;
3904 normdist[itsindex]*=-1;
3907 if (normdist[itsindex]>2) forbidden[itsindex]=kFALSE;
3908 normdist[itsindex]*=-1;
3912 // Causality cuts in TPC volume
3914 if (esdtrack->GetTPCdensity(0,10) >0.6) maxr[itsindex] = TMath::Min(Float_t(110),maxr[itsindex]);
3915 if (esdtrack->GetTPCdensity(10,30)>0.6) maxr[itsindex] = TMath::Min(Float_t(120),maxr[itsindex]);
3916 if (esdtrack->GetTPCdensity(20,40)>0.6) maxr[itsindex] = TMath::Min(Float_t(130),maxr[itsindex]);
3917 if (esdtrack->GetTPCdensity(30,50)>0.6) maxr[itsindex] = TMath::Min(Float_t(140),maxr[itsindex]);
3919 if (esdtrack->GetTPCdensity(0,60)<0.4&&bestLong->GetNumberOfClusters()<3) minr[itsindex]=100;
3925 "Tr1.="<<((bestConst)? bestConst:dummy)<<
3927 "Tr3.="<<&trackat0<<
3929 "Dist="<<dist[itsindex]<<
3930 "ND0="<<normdist0[itsindex]<<
3931 "ND1="<<normdist1[itsindex]<<
3932 "ND="<<normdist[itsindex]<<
3933 "Pz="<<primvertex[2]<<
3934 "Forbid="<<forbidden[itsindex]<<
3938 trackarray.AddAt(best,itsindex);
3939 trackarrayc.AddAt(bestConst,itsindex);
3940 trackarrayl.AddAt(bestLong,itsindex);
3941 new (&helixes[itsindex]) AliHelix(*best);
3946 // first iterration of V0 finder
3948 for (Int_t iesd0=0;iesd0<ntracks;iesd0++){
3949 Int_t itrack0 = itsmap[iesd0];
3950 if (forbidden[itrack0]) continue;
3951 AliITStrackMI * btrack0 = (AliITStrackMI*)trackarray.At(itrack0);
3952 if (!btrack0) continue;
3953 if (btrack0->GetSign()>0) continue;
3954 AliITStrackMI *trackc0 = (AliITStrackMI*)trackarrayc.At(itrack0);
3956 for (Int_t iesd1=0;iesd1<ntracks;iesd1++){
3957 Int_t itrack1 = itsmap[iesd1];
3958 if (forbidden[itrack1]) continue;
3960 AliITStrackMI * btrack1 = (AliITStrackMI*)trackarray.At(itrack1);
3961 if (!btrack1) continue;
3962 if (btrack1->GetSign()<0) continue;
3963 Bool_t isGold = kFALSE;
3964 if (TMath::Abs(TMath::Abs(btrack0->GetLabel())-TMath::Abs(btrack1->GetLabel()))==1){
3967 AliITStrackMI *trackc1 = (AliITStrackMI*)trackarrayc.At(itrack1);
3968 AliHelix &h1 = helixes[itrack0];
3969 AliHelix &h2 = helixes[itrack1];
3971 // find linear distance
3976 Double_t phase[2][2],radius[2];
3977 Int_t points = h1.GetRPHIintersections(h2, phase, radius);
3978 if (points==0) continue;
3979 Double_t delta[2]={1000000,1000000};
3981 h1.ParabolicDCA(h2,phase[0][0],phase[0][1],radius[0],delta[0]);
3983 if (radius[1]<rmin) rmin = radius[1];
3984 h1.ParabolicDCA(h2,phase[1][0],phase[1][1],radius[1],delta[1]);
3986 rmin = TMath::Sqrt(rmin);
3987 Double_t distance = 0;
3988 Double_t radiusC = 0;
3990 if (points==1 || delta[0]<delta[1]){
3991 distance = TMath::Sqrt(delta[0]);
3992 radiusC = TMath::Sqrt(radius[0]);
3994 distance = TMath::Sqrt(delta[1]);
3995 radiusC = TMath::Sqrt(radius[1]);
3998 if (radiusC<TMath::Max(minr[itrack0],minr[itrack1])) continue;
3999 if (radiusC>TMath::Min(maxr[itrack0],maxr[itrack1])) continue;
4000 Float_t maxDist = TMath::Min(kMaxDist,Float_t(kMaxDist0+radiusC*kMaxDist1));
4001 if (distance>maxDist) continue;
4002 Float_t pointAngle = h1.GetPointAngle(h2,phase[iphase],primvertex);
4003 if (pointAngle<TMath::Max(minPointAngle[itrack0],minPointAngle[itrack1])) continue;
4006 // Double_t distance = TestV0(h1,h2,pvertex,rmin);
4008 // if (distance>maxDist) continue;
4009 // if (pvertex->GetRr()<kMinR) continue;
4010 // if (pvertex->GetRr()>kMaxR) continue;
4011 AliITStrackMI * track0=btrack0;
4012 AliITStrackMI * track1=btrack1;
4013 // if (pvertex->GetRr()<3.5){
4015 //use longest tracks inside the pipe
4016 track0 = (AliITStrackMI*)trackarrayl.At(itrack0);
4017 track1 = (AliITStrackMI*)trackarrayl.At(itrack1);
4021 pvertex->SetParamN(*track0);
4022 pvertex->SetParamP(*track1);
4023 pvertex->Update(primvertex);
4024 pvertex->SetClusters(track0->ClIndex(),track1->ClIndex()); // register clusters
4026 if (pvertex->GetRr()<kMinR) continue;
4027 if (pvertex->GetRr()>kMaxR) continue;
4028 if (pvertex->GetV0CosineOfPointingAngle()<kMinPointAngle) continue;
4029 //Bo: if (pvertex->GetDist2()>maxDist) continue;
4030 if (pvertex->GetDcaV0Daughters()>maxDist) continue;
4031 //Bo: pvertex->SetLab(0,track0->GetLabel());
4032 //Bo: pvertex->SetLab(1,track1->GetLabel());
4033 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4034 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4036 AliITStrackMI * htrackc0 = trackc0 ? trackc0:dummy;
4037 AliITStrackMI * htrackc1 = trackc1 ? trackc1:dummy;
4041 TObjArray * array0b = (TObjArray*)fBestHypothesys.At(itrack0);
4042 if (!array0b&&pvertex->GetRr()<40 && TMath::Abs(track0->GetTgl())<1.1)
4043 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack0),itrack0, kFALSE);
4044 TObjArray * array1b = (TObjArray*)fBestHypothesys.At(itrack1);
4045 if (!array1b&&pvertex->GetRr()<40 && TMath::Abs(track1->GetTgl())<1.1)
4046 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack1),itrack1, kFALSE);
4048 AliITStrackMI * track0b = (AliITStrackMI*)fOriginal.At(itrack0);
4049 AliITStrackMI * track1b = (AliITStrackMI*)fOriginal.At(itrack1);
4050 AliITStrackMI * track0l = (AliITStrackMI*)fOriginal.At(itrack0);
4051 AliITStrackMI * track1l = (AliITStrackMI*)fOriginal.At(itrack1);
4053 Float_t minchi2before0=16;
4054 Float_t minchi2before1=16;
4055 Float_t minchi2after0 =16;
4056 Float_t minchi2after1 =16;
4057 Double_t xrp[3]; pvertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
4058 Int_t maxLayer = GetNearestLayer(xrp); //I.B.
4060 if (array0b) for (Int_t i=0;i<5;i++){
4061 // best track after vertex
4062 AliITStrackMI * btrack = (AliITStrackMI*)array0b->At(i);
4063 if (!btrack) continue;
4064 if (btrack->GetNumberOfClusters()>track0l->GetNumberOfClusters()) track0l = btrack;
4065 // if (btrack->fX<pvertex->GetRr()-2.-0.5/(0.1+pvertex->GetAnglep()[2])) {
4066 if (btrack->GetX()<pvertex->GetRr()-2.) {
4067 if ( (maxLayer>i+2|| (i==0)) && btrack->GetNumberOfClusters()==(6-i)&&i<3){
4070 if (maxLayer<3){ // take prim vertex as additional measurement
4071 if (normdist[itrack0]>0 && htrackc0){
4072 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack0]*normdist[itrack0],16.);
4074 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack0]*normdist[itrack0]+3.),16.);
4078 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4080 if (!btrack->GetClIndex(ilayer)){
4084 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4085 for (Int_t itrack=0;itrack<4;itrack++){
4086 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack0){
4087 sumchi2+=18.; //shared cluster
4091 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4092 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4096 if (sumchi2<minchi2before0) minchi2before0=sumchi2;
4098 continue; //safety space - Geo manager will give exact layer
4101 minchi2after0 = btrack->GetNormChi2(i);
4104 if (array1b) for (Int_t i=0;i<5;i++){
4105 // best track after vertex
4106 AliITStrackMI * btrack = (AliITStrackMI*)array1b->At(i);
4107 if (!btrack) continue;
4108 if (btrack->GetNumberOfClusters()>track1l->GetNumberOfClusters()) track1l = btrack;
4109 // if (btrack->fX<pvertex->GetRr()-2-0.5/(0.1+pvertex->GetAnglep()[2])){
4110 if (btrack->GetX()<pvertex->GetRr()-2){
4111 if ((maxLayer>i+2 || (i==0))&&btrack->GetNumberOfClusters()==(6-i)&&(i<3)){
4114 if (maxLayer<3){ // take prim vertex as additional measurement
4115 if (normdist[itrack1]>0 && htrackc1){
4116 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack1]*normdist[itrack1],16.);
4118 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack1]*normdist[itrack1]+3.),16.);
4122 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4124 if (!btrack->GetClIndex(ilayer)){
4128 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4129 for (Int_t itrack=0;itrack<4;itrack++){
4130 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack1){
4131 sumchi2+=18.; //shared cluster
4135 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4136 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4140 if (sumchi2<minchi2before1) minchi2before1=sumchi2;
4142 continue; //safety space - Geo manager will give exact layer
4145 minchi2after1 = btrack->GetNormChi2(i);
4149 // position resolution - used for DCA cut
4150 Float_t sigmad = track0b->GetSigmaY2()+track0b->GetSigmaZ2()+track1b->GetSigmaY2()+track1b->GetSigmaZ2()+
4151 (track0b->GetX()-pvertex->GetRr())*(track0b->GetX()-pvertex->GetRr())*(track0b->GetSigmaSnp2()+track0b->GetSigmaTgl2())+
4152 (track1b->GetX()-pvertex->GetRr())*(track1b->GetX()-pvertex->GetRr())*(track1b->GetSigmaSnp2()+track1b->GetSigmaTgl2());
4153 sigmad =TMath::Sqrt(sigmad)+0.04;
4154 if (pvertex->GetRr()>50){
4155 Double_t cov0[15],cov1[15];
4156 track0b->GetESDtrack()->GetInnerExternalCovariance(cov0);
4157 track1b->GetESDtrack()->GetInnerExternalCovariance(cov1);
4158 sigmad = cov0[0]+cov0[2]+cov1[0]+cov1[2]+
4159 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov0[5]+cov0[9])+
4160 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov1[5]+cov1[9]);
4161 sigmad =TMath::Sqrt(sigmad)+0.05;
4165 vertex2.SetParamN(*track0b);
4166 vertex2.SetParamP(*track1b);
4167 vertex2.Update(primvertex);
4168 //Bo: if (vertex2.GetDist2()<=pvertex->GetDist2()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4169 if (vertex2.GetDcaV0Daughters()<=pvertex->GetDcaV0Daughters()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4170 pvertex->SetParamN(*track0b);
4171 pvertex->SetParamP(*track1b);
4172 pvertex->Update(primvertex);
4173 pvertex->SetClusters(track0b->ClIndex(),track1b->ClIndex()); // register clusters
4174 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4175 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4177 pvertex->SetDistSigma(sigmad);
4178 //Bo: pvertex->SetDistNorm(pvertex->GetDist2()/sigmad);
4179 pvertex->SetNormDCAPrim(normdist[itrack0],normdist[itrack1]);
4181 // define likelihhod and causalities
4183 Float_t pa0=1, pa1=1, pb0=0.26, pb1=0.26;
4185 Float_t fnorm0 = normdist[itrack0];
4186 if (fnorm0<0) fnorm0*=-3;
4187 Float_t fnorm1 = normdist[itrack1];
4188 if (fnorm1<0) fnorm1*=-3;
4189 if (pvertex->GetAnglep()[2]>0.1 || (pvertex->GetRr()<10.5)&& pvertex->GetAnglep()[2]>0.05 || pvertex->GetRr()<3){
4190 pb0 = TMath::Exp(-TMath::Min(fnorm0,Float_t(16.))/12.);
4191 pb1 = TMath::Exp(-TMath::Min(fnorm1,Float_t(16.))/12.);
4193 pvertex->SetChi2Before(normdist[itrack0]);
4194 pvertex->SetChi2After(normdist[itrack1]);
4195 pvertex->SetNAfter(0);
4196 pvertex->SetNBefore(0);
4198 pvertex->SetChi2Before(minchi2before0);
4199 pvertex->SetChi2After(minchi2before1);
4200 if (pvertex->GetAnglep()[2]>0.1 || ( pvertex->GetRr()<10.5 && pvertex->GetAnglep()[2]>0.05) || pvertex->GetRr()<3){
4201 pb0 = TMath::Exp(-TMath::Min(minchi2before0,Float_t(16))/12.);
4202 pb1 = TMath::Exp(-TMath::Min(minchi2before1,Float_t(16))/12.);
4204 pvertex->SetNAfter(maxLayer);
4205 pvertex->SetNBefore(maxLayer);
4207 if (pvertex->GetRr()<90){
4208 pa0 *= TMath::Min(track0->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4209 pa1 *= TMath::Min(track1->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4211 if (pvertex->GetRr()<20){
4212 pa0 *= (0.2+TMath::Exp(-TMath::Min(minchi2after0,Float_t(16))/8.))/1.2;
4213 pa1 *= (0.2+TMath::Exp(-TMath::Min(minchi2after1,Float_t(16))/8.))/1.2;
4216 pvertex->SetCausality(pb0,pb1,pa0,pa1);
4218 // Likelihood calculations - apply cuts
4220 Bool_t v0OK = kTRUE;
4221 Float_t p12 = pvertex->GetParamP()->GetParameter()[4]*pvertex->GetParamP()->GetParameter()[4];
4222 p12 += pvertex->GetParamN()->GetParameter()[4]*pvertex->GetParamN()->GetParameter()[4];
4223 p12 = TMath::Sqrt(p12); // "mean" momenta
4224 Float_t sigmap0 = 0.0001+0.001/(0.1+pvertex->GetRr());
4225 Float_t sigmap = 0.5*sigmap0*(0.6+0.4*p12); // "resolution: of point angle - as a function of radius and momenta
4227 Float_t causalityA = (1.0-pvertex->GetCausalityP()[0])*(1.0-pvertex->GetCausalityP()[1]);
4228 Float_t causalityB = TMath::Sqrt(TMath::Min(pvertex->GetCausalityP()[2],Double_t(0.7))*
4229 TMath::Min(pvertex->GetCausalityP()[3],Double_t(0.7)));
4231 //Bo: Float_t likelihood0 = (TMath::Exp(-pvertex->GetDistNorm())+0.1) *(pvertex->GetDist2()<0.5)*(pvertex->GetDistNorm()<5);
4232 Float_t lDistNorm = pvertex->GetDcaV0Daughters()/pvertex->GetDistSigma();
4233 Float_t likelihood0 = (TMath::Exp(-lDistNorm)+0.1) *(pvertex->GetDcaV0Daughters()<0.5)*(lDistNorm<5);
4235 Float_t likelihood1 = TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/sigmap)+
4236 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(4.*sigmap))+
4237 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(8.*sigmap))+
4238 0.1*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/0.01);
4240 if (causalityA<kCausality0Cut) v0OK = kFALSE;
4241 if (TMath::Sqrt(likelihood0*likelihood1)<kLikelihood01Cut) v0OK = kFALSE;
4242 if (likelihood1<kLikelihood1Cut) v0OK = kFALSE;
4243 if (TMath::Power(likelihood0*likelihood1*causalityB,0.33)<kCombinedCut) v0OK = kFALSE;
4248 Bool_t gold = TMath::Abs(TMath::Abs(track0->GetLabel())-TMath::Abs(track1->GetLabel()))==1;
4250 "Tr0.="<<track0<< //best without constrain
4251 "Tr1.="<<track1<< //best without constrain
4252 "Tr0B.="<<track0b<< //best without constrain after vertex
4253 "Tr1B.="<<track1b<< //best without constrain after vertex
4254 "Tr0C.="<<htrackc0<< //best with constrain if exist
4255 "Tr1C.="<<htrackc1<< //best with constrain if exist
4256 "Tr0L.="<<track0l<< //longest best
4257 "Tr1L.="<<track1l<< //longest best
4258 "Esd0.="<<track0->GetESDtrack()<< // esd track0 params
4259 "Esd1.="<<track1->GetESDtrack()<< // esd track1 params
4260 "V0.="<<pvertex<< //vertex properties
4261 "V0b.="<<&vertex2<< //vertex properties at "best" track
4262 "ND0="<<normdist[itrack0]<< //normalize distance for track0
4263 "ND1="<<normdist[itrack1]<< //normalize distance for track1
4265 // "RejectBase="<<rejectBase<< //rejection in First itteration
4271 //if (rejectBase) continue;
4273 pvertex->SetStatus(0);
4274 // if (rejectBase) {
4275 // pvertex->SetStatus(-100);
4277 if (pvertex->GetV0CosineOfPointingAngle()>kMinPointAngle2) {
4278 //Bo: pvertex->SetESDindexes(track0->GetESDtrack()->GetID(),track1->GetESDtrack()->GetID());
4279 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());//Bo: consistency 0 for neg
4280 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());//Bo: consistency 1 for pos
4282 // AliV0vertex vertexjuri(*track0,*track1);
4283 // vertexjuri.SetESDindexes(track0->fESDtrack->GetID(),track1->fESDtrack->GetID());
4284 // event->AddV0(&vertexjuri);
4285 pvertex->SetStatus(100);
4287 pvertex->SetOnFlyStatus(kTRUE);
4288 pvertex->ChangeMassHypothesis(kK0Short);
4289 event->AddV0(pvertex);
4295 // delete temporary arrays
4298 delete[] minPointAngle;
4310 //------------------------------------------------------------------------
4311 void AliITStrackerMI::RefitV02(AliESDEvent *event)
4314 //try to refit V0s in the third path of the reconstruction
4316 TTreeSRedirector &cstream = *fDebugStreamer;
4318 Int_t nv0s = event->GetNumberOfV0s();
4319 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
4321 for (Int_t iv0 = 0; iv0<nv0s;iv0++){
4322 AliV0 * v0mi = (AliV0*)event->GetV0(iv0);
4323 if (!v0mi) continue;
4324 Int_t itrack0 = v0mi->GetIndex(0);
4325 Int_t itrack1 = v0mi->GetIndex(1);
4326 AliESDtrack *esd0 = event->GetTrack(itrack0);
4327 AliESDtrack *esd1 = event->GetTrack(itrack1);
4328 if (!esd0||!esd1) continue;
4329 AliITStrackMI tpc0(*esd0);
4330 AliITStrackMI tpc1(*esd1);
4331 Double_t x,y,z; v0mi->GetXYZ(x,y,z); //I.B.
4332 Double_t alpha =TMath::ATan2(y,x); //I.B.
4333 if (v0mi->GetRr()>85){
4334 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4335 v0temp.SetParamN(tpc0);
4336 v0temp.SetParamP(tpc1);
4337 v0temp.Update(primvertex);
4338 if (kFALSE) cstream<<"Refit"<<
4340 "V0refit.="<<&v0temp<<
4344 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4345 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4346 v0mi->SetParamN(tpc0);
4347 v0mi->SetParamP(tpc1);
4348 v0mi->Update(primvertex);
4353 if (v0mi->GetRr()>35){
4354 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4355 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4356 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4357 v0temp.SetParamN(tpc0);
4358 v0temp.SetParamP(tpc1);
4359 v0temp.Update(primvertex);
4360 if (kFALSE) cstream<<"Refit"<<
4362 "V0refit.="<<&v0temp<<
4366 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4367 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4368 v0mi->SetParamN(tpc0);
4369 v0mi->SetParamP(tpc1);
4370 v0mi->Update(primvertex);
4375 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4376 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4377 // if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4378 if (RefitAt(v0mi->GetRr(),&tpc0, v0mi->GetClusters(0)) && RefitAt(v0mi->GetRr(),&tpc1, v0mi->GetClusters(1))){
4379 v0temp.SetParamN(tpc0);
4380 v0temp.SetParamP(tpc1);
4381 v0temp.Update(primvertex);
4382 if (kFALSE) cstream<<"Refit"<<
4384 "V0refit.="<<&v0temp<<
4388 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4389 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4390 v0mi->SetParamN(tpc0);
4391 v0mi->SetParamP(tpc1);
4392 v0mi->Update(primvertex);
4397 //------------------------------------------------------------------------
4398 void AliITStrackerMI::BuildMaterialLUT(TString material) {
4399 //--------------------------------------------------------------------
4400 // Fill a look-up table with mean material
4401 //--------------------------------------------------------------------
4405 Double_t point1[3],point2[3];
4406 Double_t phi,cosphi,sinphi,z;
4407 // 0-5 layers, 6 pipe, 7-8 shields
4408 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 7.5,25.0};
4409 Double_t rmax[9]={ 5.5, 7.3,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
4411 Int_t ifirst=0,ilast=0;
4412 if(material.Contains("Pipe")) {
4414 } else if(material.Contains("Shields")) {
4416 } else if(material.Contains("Layers")) {
4419 Error("BuildMaterialLUT","Wrong layer name\n");
4422 for(Int_t imat=ifirst; imat<=ilast; imat++) {
4423 Double_t param[5]={0.,0.,0.,0.,0.};
4424 for (Int_t i=0; i<n; i++) {
4425 phi = 2.*TMath::Pi()*gRandom->Rndm();
4426 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
4427 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
4428 point1[0] = rmin[imat]*cosphi;
4429 point1[1] = rmin[imat]*sinphi;
4431 point2[0] = rmax[imat]*cosphi;
4432 point2[1] = rmax[imat]*sinphi;
4434 AliTracker::MeanMaterialBudget(point1,point2,mparam);
4435 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
4437 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
4439 fxOverX0Layer[imat] = param[1];
4440 fxTimesRhoLayer[imat] = param[0]*param[4];
4441 } else if(imat==6) {
4442 fxOverX0Pipe = param[1];
4443 fxTimesRhoPipe = param[0]*param[4];
4444 } else if(imat==7) {
4445 fxOverX0Shield[0] = param[1];
4446 fxTimesRhoShield[0] = param[0]*param[4];
4447 } else if(imat==8) {
4448 fxOverX0Shield[1] = param[1];
4449 fxTimesRhoShield[1] = param[0]*param[4];
4453 printf("%s\n",material.Data());
4454 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
4455 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
4456 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
4457 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
4458 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
4459 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
4460 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
4461 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
4462 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
4466 //------------------------------------------------------------------------
4467 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
4468 TString direction) {
4469 //-------------------------------------------------------------------
4470 // Propagate beyond beam pipe 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 Int_t index=fCurrentEsdTrack;
4506 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4507 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4508 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4510 Double_t xOverX0,x0,lengthTimesMeanDensity;
4511 Bool_t anglecorr=kTRUE;
4515 xOverX0 = AliITSRecoParam::GetdPipe();
4516 x0 = AliITSRecoParam::GetX0Be();
4517 lengthTimesMeanDensity = xOverX0*x0;
4520 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4524 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4525 xOverX0 = fxOverX0Pipe;
4526 lengthTimesMeanDensity = fxTimesRhoPipe;
4529 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4530 if(fxOverX0PipeTrks[index]<0) {
4531 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4532 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4533 (1.-t->GetSnp()*t->GetSnp()));
4534 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4535 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4538 xOverX0 = fxOverX0PipeTrks[index];
4539 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4543 lengthTimesMeanDensity *= dir;
4545 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4546 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4550 //------------------------------------------------------------------------
4551 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4553 TString direction) {
4554 //-------------------------------------------------------------------
4555 // Propagate beyond SPD or SDD shield and correct for material
4556 // (material budget in different ways according to fUseTGeo value)
4557 //-------------------------------------------------------------------
4559 // Define budget mode:
4560 // 0: material from AliITSRecoParam (hard coded)
4561 // 1: material from TGeo (on the fly)
4562 // 2: material from lut
4563 // 3: material from TGeo (same for all hypotheses)
4576 if(fTrackingPhase.Contains("Clusters2Tracks"))
4577 { mode=3; } else { mode=1; }
4580 if(fTrackingPhase.Contains("Clusters2Tracks"))
4581 { mode=3; } else { mode=2; }
4587 if(fTrackingPhase.Contains("Default")) mode=0;
4589 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4591 Int_t shieldindex=0;
4592 if (shield.Contains("SDD")) { // SDDouter
4593 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4595 } else if (shield.Contains("SPD")) { // SPDouter
4596 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4599 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4602 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4604 Int_t index=2*fCurrentEsdTrack+shieldindex;
4606 Double_t xOverX0,x0,lengthTimesMeanDensity;
4607 Bool_t anglecorr=kTRUE;
4611 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4612 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4613 lengthTimesMeanDensity = xOverX0*x0;
4616 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4620 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4621 xOverX0 = fxOverX0Shield[shieldindex];
4622 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4625 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4626 if(fxOverX0ShieldTrks[index]<0) {
4627 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4628 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4629 (1.-t->GetSnp()*t->GetSnp()));
4630 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4631 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4634 xOverX0 = fxOverX0ShieldTrks[index];
4635 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4639 lengthTimesMeanDensity *= dir;
4641 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4642 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4646 //------------------------------------------------------------------------
4647 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4649 Double_t oldGlobXYZ[3],
4650 TString direction) {
4651 //-------------------------------------------------------------------
4652 // Propagate beyond layer and correct for material
4653 // (material budget in different ways according to fUseTGeo value)
4654 //-------------------------------------------------------------------
4656 // Define budget mode:
4657 // 0: material from AliITSRecoParam (hard coded)
4658 // 1: material from TGeo (on the fly)
4659 // 2: material from lut
4660 // 3: material from TGeo (same for all hypotheses)
4673 if(fTrackingPhase.Contains("Clusters2Tracks"))
4674 { mode=3; } else { mode=1; }
4677 if(fTrackingPhase.Contains("Clusters2Tracks"))
4678 { mode=3; } else { mode=2; }
4684 if(fTrackingPhase.Contains("Default")) mode=0;
4686 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4688 Double_t r=fgLayers[layerindex].GetR();
4689 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4691 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4692 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4694 Int_t index=6*fCurrentEsdTrack+layerindex;
4696 // Bring the track beyond the material
4697 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4698 Double_t globXYZ[3];
4701 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4703 Bool_t anglecorr=kTRUE;
4707 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4708 lengthTimesMeanDensity = xOverX0*x0;
4711 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4712 if(mparam[1]>900000) return 0;
4714 lengthTimesMeanDensity=mparam[0]*mparam[4];
4718 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4719 xOverX0 = fxOverX0Layer[layerindex];
4720 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4723 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4724 if(fxOverX0LayerTrks[index]<0) {
4725 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4726 if(mparam[1]>900000) return 0;
4727 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4728 (1.-t->GetSnp()*t->GetSnp()));
4729 xOverX0=mparam[1]/angle;
4730 lengthTimesMeanDensity=mparam[0]*mparam[4]/angle;
4731 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0);
4732 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity);
4734 xOverX0 = fxOverX0LayerTrks[index];
4735 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4739 lengthTimesMeanDensity *= dir;
4741 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4745 //------------------------------------------------------------------------
4746 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4747 //-----------------------------------------------------------------
4748 // Initialize LUT for storing material for each prolonged track
4749 //-----------------------------------------------------------------
4750 fxOverX0PipeTrks = new Float_t[ntracks];
4751 fxTimesRhoPipeTrks = new Float_t[ntracks];
4752 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4753 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4754 fxOverX0LayerTrks = new Float_t[ntracks*6];
4755 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4757 for(Int_t i=0; i<ntracks; i++) {
4758 fxOverX0PipeTrks[i] = -1.;
4759 fxTimesRhoPipeTrks[i] = -1.;
4761 for(Int_t j=0; j<ntracks*2; j++) {
4762 fxOverX0ShieldTrks[j] = -1.;
4763 fxTimesRhoShieldTrks[j] = -1.;
4765 for(Int_t k=0; k<ntracks*6; k++) {
4766 fxOverX0LayerTrks[k] = -1.;
4767 fxTimesRhoLayerTrks[k] = -1.;
4774 //------------------------------------------------------------------------
4775 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4776 //-----------------------------------------------------------------
4777 // Delete LUT for storing material for each prolonged track
4778 //-----------------------------------------------------------------
4779 if(fxOverX0PipeTrks) {
4780 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4782 if(fxOverX0ShieldTrks) {
4783 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4786 if(fxOverX0LayerTrks) {
4787 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4789 if(fxTimesRhoPipeTrks) {
4790 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4792 if(fxTimesRhoShieldTrks) {
4793 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4795 if(fxTimesRhoLayerTrks) {
4796 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4800 //------------------------------------------------------------------------
4801 Int_t AliITStrackerMI::CheckSkipLayer(AliITStrackMI *track,
4802 Int_t ilayer,Int_t idet) const {
4803 //-----------------------------------------------------------------
4804 // This method is used to decide whether to allow a prolongation
4805 // without clusters, because we want to skip the layer.
4806 // In this case the return value is > 0:
4807 // return 1: the user requested to skip a layer
4808 // return 2: track outside z acceptance of SSD/SDD and will cross both SPD
4809 //-----------------------------------------------------------------
4811 if (AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) return 1;
4813 if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4814 // check if track will cross SPD outer layer
4815 Double_t phiAtSPD2,zAtSPD2;
4816 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4817 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4823 //------------------------------------------------------------------------
4824 Int_t AliITStrackerMI::CheckDeadZone(/*AliITStrackMI *track,*/
4825 Int_t ilayer,/*Int_t idet,*/
4826 Double_t zmin,Double_t zmax/*,Double_t ymin,Double_t ymax*/) const {
4827 //-----------------------------------------------------------------
4828 // This method is used to decide whether to allow a prolongation
4829 // without clusters, because there is dead zone in the road.
4830 // In this case the return value is > 0:
4831 // return 1: dead zone at z=0,+-7cm in SPD
4832 // return 2: dead area from the OCDB
4833 //-----------------------------------------------------------------
4835 // check dead zones at z=0,+-7cm in the SPD
4836 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4837 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4838 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4839 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4840 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4841 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4842 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4843 for (Int_t i=0; i<3; i++)
4844 if (zmin<zmaxdead[i] && zmax>zmindead[i]) return 1;
4848 if (AliITSReconstructor::GetRecoParam()->GetUseDeadZonesFromOCDB()) {
4849 // NOT YET IMPLEMENTED
4851 //if (deadfromOCDB) return 2;
4856 //------------------------------------------------------------------------