1 /**************************************************************************
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 //-------------------------------------------------------------------------
18 // Implementation of the ITS tracker class
19 // It reads AliITSRecPoint clusters and creates AliITStrackMI tracks
20 // and fills with them the ESD
21 // Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch
22 // dE/dx analysis by: Boris Batyunya, JINR, Boris.Batiounia@cern.ch
23 // Params moved to AliITSRecoParam by: Andrea Dainese, INFN
24 // Material budget from TGeo by: Ludovic Gaudichet & Andrea Dainese, INFN
25 //-------------------------------------------------------------------------
29 #include <TTreeStream.h>
30 #include <TDatabasePDG.h>
35 #include "AliESDEvent.h"
36 #include "AliESDtrack.h"
37 #include "AliESDVertex.h"
40 #include "AliITSRecPoint.h"
41 #include "AliITSgeomTGeo.h"
42 #include "AliITSReconstructor.h"
43 #include "AliTrackPointArray.h"
44 #include "AliAlignObj.h"
45 #include "AliITSClusterParam.h"
46 #include "AliCDBManager.h"
47 #include "AliCDBEntry.h"
48 #include "AliITSCalibrationSPD.h"
49 #include "AliITSCalibrationSDD.h"
50 #include "AliITSCalibrationSSD.h"
51 #include "AliITSPlaneEff.h"
52 #include "AliITSPlaneEffSPD.h"
53 #include "AliITSPlaneEffSDD.h"
54 #include "AliITSPlaneEffSSD.h"
55 #include "AliITStrackerMI.h"
57 ClassImp(AliITStrackerMI)
59 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
61 AliITStrackerMI::AliITStrackerMI():AliTracker(),
71 fLastLayerToTrackTo(0),
74 fTrackingPhase("Default"),
80 fxTimesRhoPipeTrks(0),
81 fxOverX0ShieldTrks(0),
82 fxTimesRhoShieldTrks(0),
84 fxTimesRhoLayerTrks(0),
89 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
90 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
91 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
93 //------------------------------------------------------------------------
94 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
95 fI(AliITSgeomTGeo::GetNLayers()),
104 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
107 fTrackingPhase("Default"),
113 fxTimesRhoPipeTrks(0),
114 fxOverX0ShieldTrks(0),
115 fxTimesRhoShieldTrks(0),
116 fxOverX0LayerTrks(0),
117 fxTimesRhoLayerTrks(0),
120 //--------------------------------------------------------------------
121 //This is the AliITStrackerMI constructor
122 //--------------------------------------------------------------------
124 AliWarning("\"geom\" is actually a dummy argument !");
130 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
131 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
132 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
134 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
135 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
136 Double_t poff=TMath::ATan2(y,x);
138 Double_t r=TMath::Sqrt(x*x + y*y);
140 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
141 r += TMath::Sqrt(x*x + y*y);
142 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
143 r += TMath::Sqrt(x*x + y*y);
144 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
145 r += TMath::Sqrt(x*x + y*y);
148 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
150 for (Int_t j=1; j<nlad+1; j++) {
151 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
152 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
153 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
155 Double_t txyz[3]={0.}, xyz[3]={0.};
156 m.LocalToMaster(txyz,xyz);
157 Double_t r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
158 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
160 if (phi<0) phi+=TMath::TwoPi();
161 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
163 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
164 new(&det) AliITSdetector(r,phi);
170 fI=AliITSgeomTGeo::GetNLayers();
173 fConstraint[0]=1; fConstraint[1]=0;
175 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
176 AliITSReconstructor::GetRecoParam()->GetYVdef(),
177 AliITSReconstructor::GetRecoParam()->GetZVdef()};
178 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
179 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
180 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
181 SetVertex(xyzVtx,ersVtx);
183 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=AliITSRecoParam::GetLayersNotToSkip(i);
184 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
185 for (Int_t i=0;i<100000;i++){
186 fBestTrackIndex[i]=0;
189 // store positions of centre of SPD modules (in z)
191 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
192 fSPDdetzcentre[0] = tr[2];
193 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
194 fSPDdetzcentre[1] = tr[2];
195 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
196 fSPDdetzcentre[2] = tr[2];
197 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
198 fSPDdetzcentre[3] = tr[2];
200 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
201 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
202 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
206 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
207 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
209 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
211 // only for plane efficiency evaluation
212 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff()) {
213 for(Int_t ilay=0;ilay<6;ilay++) {
214 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilay)) {
215 if (ilay<2) fPlaneEff = new AliITSPlaneEffSPD();
216 else if (ilay<4) fPlaneEff = new AliITSPlaneEffSDD();
217 else fPlaneEff = new AliITSPlaneEffSSD();
218 break; // only one layer type to skip at once
221 if(!fPlaneEff->ReadFromCDB())
222 {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
225 //------------------------------------------------------------------------
226 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
228 fBestTrack(tracker.fBestTrack),
229 fTrackToFollow(tracker.fTrackToFollow),
230 fTrackHypothesys(tracker.fTrackHypothesys),
231 fBestHypothesys(tracker.fBestHypothesys),
232 fOriginal(tracker.fOriginal),
233 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
234 fPass(tracker.fPass),
235 fAfterV0(tracker.fAfterV0),
236 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
237 fCoefficients(tracker.fCoefficients),
239 fTrackingPhase(tracker.fTrackingPhase),
240 fUseTGeo(tracker.fUseTGeo),
241 fNtracks(tracker.fNtracks),
242 fxOverX0Pipe(tracker.fxOverX0Pipe),
243 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
245 fxTimesRhoPipeTrks(0),
246 fxOverX0ShieldTrks(0),
247 fxTimesRhoShieldTrks(0),
248 fxOverX0LayerTrks(0),
249 fxTimesRhoLayerTrks(0),
250 fDebugStreamer(tracker.fDebugStreamer),
251 fPlaneEff(tracker.fPlaneEff) {
255 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
258 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
259 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
262 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
263 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
266 //------------------------------------------------------------------------
267 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
268 //Assignment operator
269 this->~AliITStrackerMI();
270 new(this) AliITStrackerMI(tracker);
273 //------------------------------------------------------------------------
274 AliITStrackerMI::~AliITStrackerMI()
279 if (fCoefficients) delete [] fCoefficients;
280 DeleteTrksMaterialLUT();
281 if (fDebugStreamer) {
282 //fDebugStreamer->Close();
283 delete fDebugStreamer;
286 //------------------------------------------------------------------------
287 void AliITStrackerMI::SetLayersNotToSkip(Int_t *l) {
288 //--------------------------------------------------------------------
289 //This function set masks of the layers which must be not skipped
290 //--------------------------------------------------------------------
291 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=l[i];
293 //------------------------------------------------------------------------
294 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
295 //--------------------------------------------------------------------
296 //This function loads ITS clusters
297 //--------------------------------------------------------------------
298 TBranch *branch=cTree->GetBranch("ITSRecPoints");
300 Error("LoadClusters"," can't get the branch !\n");
304 TClonesArray dummy("AliITSRecPoint",10000), *clusters=&dummy;
305 branch->SetAddress(&clusters);
309 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
310 Int_t ndet=fgLayers[i].GetNdetectors();
311 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
312 for (; j<jmax; j++) {
313 if (!cTree->GetEvent(j)) continue;
314 Int_t ncl=clusters->GetEntriesFast();
315 SignDeltas(clusters,GetZ());
318 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
319 detector=c->GetDetectorIndex();
321 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
323 fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
326 // add dead zone "virtual" cluster in SPD, if there is a cluster within
327 // zwindow cm from the dead zone
328 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
329 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
330 Int_t lab[4] = {0,0,0,detector};
331 Int_t info[3] = {0,0,i};
332 Float_t q = 0.; // this identifies virtual clusters
333 Float_t hit[5] = {xdead,
335 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
336 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
338 Bool_t local = kTRUE;
339 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
340 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
341 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
342 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
343 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
344 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
345 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
346 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
347 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
348 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
349 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
350 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
351 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
352 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
353 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
354 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
355 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
356 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
357 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
359 } // "virtual" clusters in SPD
363 fgLayers[i].ResetRoad(); //road defined by the cluster density
364 fgLayers[i].SortClusters();
369 //------------------------------------------------------------------------
370 void AliITStrackerMI::UnloadClusters() {
371 //--------------------------------------------------------------------
372 //This function unloads ITS clusters
373 //--------------------------------------------------------------------
374 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
376 //------------------------------------------------------------------------
377 static Int_t CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
378 //--------------------------------------------------------------------
379 // Correction for the material between the TPC and the ITS
380 //--------------------------------------------------------------------
381 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
382 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
383 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
384 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
385 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
386 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
387 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
388 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
390 Error("CorrectForTPCtoITSDeadZoneMaterial","Track is already in the dead zone !");
396 //------------------------------------------------------------------------
397 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
398 //--------------------------------------------------------------------
399 // This functions reconstructs ITS tracks
400 // The clusters must be already loaded !
401 //--------------------------------------------------------------------
402 fTrackingPhase="Clusters2Tracks";
404 TObjArray itsTracks(15000);
406 fEsd = event; // store pointer to the esd
408 // temporary (for cosmics)
409 if(event->GetVertex()) {
410 TString title = event->GetVertex()->GetTitle();
411 if(title.Contains("cosmics")) {
412 Double_t xyz[3]={GetX(),GetY(),GetZ()};
413 Double_t exyz[3]={0.1,0.1,0.1};
419 {/* Read ESD tracks */
420 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
421 Int_t nentr=event->GetNumberOfTracks();
422 Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
424 AliESDtrack *esd=event->GetTrack(nentr);
426 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
427 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
428 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
429 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
432 t=new AliITStrackMI(*esd);
433 } catch (const Char_t *msg) {
434 //Warning("Clusters2Tracks",msg);
438 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
439 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
442 // look at the ESD mass hypothesys !
443 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
445 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
447 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
448 //track - can be V0 according to TPC
450 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
454 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
458 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
462 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
467 t->SetReconstructed(kFALSE);
468 itsTracks.AddLast(t);
469 fOriginal.AddLast(t);
471 } /* End Read ESD tracks */
475 Int_t nentr=itsTracks.GetEntriesFast();
476 fTrackHypothesys.Expand(nentr);
477 fBestHypothesys.Expand(nentr);
478 MakeCoefficients(nentr);
479 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
481 // THE TWO TRACKING PASSES
482 for (fPass=0; fPass<2; fPass++) {
483 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
484 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
485 //cerr<<fPass<<" "<<fCurrentEsdTrack<<'\n';
486 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
487 if (t==0) continue; //this track has been already tracked
488 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
489 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
490 if (fConstraint[fPass]) {
491 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
492 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
495 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
497 ResetTrackToFollow(*t);
500 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
502 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
504 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
505 if (!besttrack) continue;
506 besttrack->SetLabel(tpcLabel);
507 // besttrack->CookdEdx();
509 besttrack->SetFakeRatio(1.);
510 CookLabel(besttrack,0.); //For comparison only
511 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
513 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
515 t->SetReconstructed(kTRUE);
518 GetBestHypothesysMIP(itsTracks);
519 } // end loop on the two tracking passes
521 //GetBestHypothesysMIP(itsTracks);
522 if(event->GetNumberOfV0s()>0) UpdateTPCV0(event);
523 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) FindV02(event);
525 //GetBestHypothesysMIP(itsTracks);
529 Int_t entries = fTrackHypothesys.GetEntriesFast();
530 for (Int_t ientry=0; ientry<entries; ientry++) {
531 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
532 if (array) array->Delete();
533 delete fTrackHypothesys.RemoveAt(ientry);
536 fTrackHypothesys.Delete();
537 fBestHypothesys.Delete();
539 delete [] fCoefficients;
541 DeleteTrksMaterialLUT();
543 Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
545 fTrackingPhase="Default";
549 //------------------------------------------------------------------------
550 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
551 //--------------------------------------------------------------------
552 // This functions propagates reconstructed ITS tracks back
553 // The clusters must be loaded !
554 //--------------------------------------------------------------------
555 fTrackingPhase="PropagateBack";
556 Int_t nentr=event->GetNumberOfTracks();
557 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
560 for (Int_t i=0; i<nentr; i++) {
561 AliESDtrack *esd=event->GetTrack(i);
563 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
564 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
568 t=new AliITStrackMI(*esd);
569 } catch (const Char_t *msg) {
570 //Warning("PropagateBack",msg);
574 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
576 ResetTrackToFollow(*t);
578 // propagate to vertex [SR, GSI 17.02.2003]
579 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
580 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
581 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
582 fTrackToFollow.StartTimeIntegral();
583 // from vertex to outside pipe
584 CorrectForPipeMaterial(&fTrackToFollow,"outward");
587 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
588 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
589 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
593 fTrackToFollow.SetLabel(t->GetLabel());
594 //fTrackToFollow.CookdEdx();
595 CookLabel(&fTrackToFollow,0.); //For comparison only
596 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
597 //UseClusters(&fTrackToFollow);
603 Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
605 fTrackingPhase="Default";
609 //------------------------------------------------------------------------
610 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
611 //--------------------------------------------------------------------
612 // This functions refits ITS tracks using the
613 // "inward propagated" TPC tracks
614 // The clusters must be loaded !
615 //--------------------------------------------------------------------
616 fTrackingPhase="RefitInward";
617 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) RefitV02(event);
618 Int_t nentr=event->GetNumberOfTracks();
619 Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
622 for (Int_t i=0; i<nentr; i++) {
623 AliESDtrack *esd=event->GetTrack(i);
625 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
626 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
627 if (esd->GetStatus()&AliESDtrack::kTPCout)
628 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
632 t=new AliITStrackMI(*esd);
633 } catch (const Char_t *msg) {
634 //Warning("RefitInward",msg);
638 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
639 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
644 ResetTrackToFollow(*t);
645 fTrackToFollow.ResetClusters();
647 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
648 fTrackToFollow.ResetCovariance(10.);
651 Bool_t pe=AliITSReconstructor::GetRecoParam()->GetComputePlaneEff();
652 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
653 fTrackToFollow.SetLabel(t->GetLabel());
654 // fTrackToFollow.CookdEdx();
655 CookdEdx(&fTrackToFollow);
657 CookLabel(&fTrackToFollow,0.0); //For comparison only
660 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
661 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
662 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
663 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
664 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
665 Float_t r[3]={0.,0.,0.};
667 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
674 Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
676 fTrackingPhase="Default";
680 //------------------------------------------------------------------------
681 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
682 //--------------------------------------------------------------------
683 // Return pointer to a given cluster
684 //--------------------------------------------------------------------
685 Int_t l=(index & 0xf0000000) >> 28;
686 Int_t c=(index & 0x0fffffff) >> 00;
687 return fgLayers[l].GetCluster(c);
689 //------------------------------------------------------------------------
690 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
691 //--------------------------------------------------------------------
692 // Get track space point with index i
693 //--------------------------------------------------------------------
695 Int_t l=(index & 0xf0000000) >> 28;
696 Int_t c=(index & 0x0fffffff) >> 00;
697 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
698 Int_t idet = cl->GetDetectorIndex();
702 cl->GetGlobalXYZ(xyz);
703 cl->GetGlobalCov(cov);
706 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
709 iLayer = AliGeomManager::kSPD1;
712 iLayer = AliGeomManager::kSPD2;
715 iLayer = AliGeomManager::kSDD1;
718 iLayer = AliGeomManager::kSDD2;
721 iLayer = AliGeomManager::kSSD1;
724 iLayer = AliGeomManager::kSSD2;
727 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
730 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
731 p.SetVolumeID((UShort_t)volid);
734 //------------------------------------------------------------------------
735 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
736 AliTrackPoint& p, const AliESDtrack *t) {
737 //--------------------------------------------------------------------
738 // Get track space point with index i
739 // (assign error estimated during the tracking)
740 //--------------------------------------------------------------------
742 Int_t l=(index & 0xf0000000) >> 28;
743 Int_t c=(index & 0x0fffffff) >> 00;
744 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
745 Int_t idet = cl->GetDetectorIndex();
746 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
748 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
750 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
751 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
752 Double_t alpha = t->GetAlpha();
753 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
754 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,AliTracker::GetBz()));
755 phi += alpha-det.GetPhi();
756 Float_t tgphi = TMath::Tan(phi);
758 Float_t tgl = t->GetTgl(); // tgl about const along track
759 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
761 Float_t errlocalx,errlocalz;
762 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errlocalx,errlocalz);
766 cl->GetGlobalXYZ(xyz);
767 // cl->GetGlobalCov(cov);
768 Float_t pos[3] = {0.,0.,0.};
769 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errlocalx*errlocalx,errlocalz*errlocalz,0);
770 tmpcl.GetGlobalCov(cov);
774 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
777 iLayer = AliGeomManager::kSPD1;
780 iLayer = AliGeomManager::kSPD2;
783 iLayer = AliGeomManager::kSDD1;
786 iLayer = AliGeomManager::kSDD2;
789 iLayer = AliGeomManager::kSSD1;
792 iLayer = AliGeomManager::kSSD2;
795 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
798 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
799 p.SetVolumeID((UShort_t)volid);
802 //------------------------------------------------------------------------
803 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
805 //--------------------------------------------------------------------
806 // Follow prolongation tree
807 //--------------------------------------------------------------------
809 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
810 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
813 AliESDtrack * esd = otrack->GetESDtrack();
814 if (esd->GetV0Index(0)>0) {
815 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
816 // mapping of ESD track is different as ITS track in Containers
817 // Need something more stable
818 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
819 for (Int_t i=0;i<3;i++){
820 Int_t index = esd->GetV0Index(i);
822 AliESDv0 * vertex = fEsd->GetV0(index);
823 if (vertex->GetStatus()<0) continue; // rejected V0
825 if (esd->GetSign()>0) {
826 vertex->SetIndex(0,esdindex);
828 vertex->SetIndex(1,esdindex);
832 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
834 bestarray = new TObjArray(5);
835 fBestHypothesys.AddAt(bestarray,esdindex);
839 //setup tree of the prolongations
841 static AliITStrackMI tracks[7][100];
842 AliITStrackMI *currenttrack;
843 static AliITStrackMI currenttrack1;
844 static AliITStrackMI currenttrack2;
845 static AliITStrackMI backuptrack;
847 Int_t nindexes[7][100];
848 Float_t normalizedchi2[100];
849 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
850 otrack->SetNSkipped(0);
851 new (&(tracks[6][0])) AliITStrackMI(*otrack);
853 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
854 Int_t modstatus = 1; // found
858 // follow prolongations
859 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
862 AliITSlayer &layer=fgLayers[ilayer];
863 Double_t r = layer.GetR();
869 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
871 if (ntracks[ilayer]>=100) break;
872 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
873 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
874 if (ntracks[ilayer]>15+ilayer){
875 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
876 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
879 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
881 // material between SSD and SDD, SDD and SPD
883 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
885 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
889 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
890 Int_t idet=layer.FindDetectorIndex(phi,z);
892 Double_t trackGlobXYZ1[3];
893 currenttrack1.GetXYZ(trackGlobXYZ1);
895 // Get the budget to the primary vertex for the current track being prolonged
896 Double_t budgetToPrimVertex = GetEffectiveThickness();
898 // check if we allow a prolongation without point
899 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
901 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
902 // propagate to the layer radius
903 Double_t xToGo; vtrack->GetLocalXat(r,xToGo);
904 vtrack->AliExternalTrackParam::PropagateTo(xToGo,GetBz());
905 // apply correction for material of the current layer
906 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
907 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
908 vtrack->SetClIndex(ilayer,0);
909 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
910 LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc); // local module coords
911 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
912 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
917 // track outside layer acceptance in z
918 if (idet<0) continue;
920 //propagate to the intersection with the detector plane
921 const AliITSdetector &det=layer.GetDetector(idet);
922 new(¤ttrack2) AliITStrackMI(currenttrack1);
923 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
924 LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc); // local module coords
925 currenttrack2.Propagate(det.GetPhi(),det.GetR());
926 currenttrack1.SetDetectorIndex(idet);
927 currenttrack2.SetDetectorIndex(idet);
930 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
932 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
933 TMath::Sqrt(currenttrack1.GetSigmaZ2() +
934 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
935 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
936 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
937 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
938 TMath::Sqrt(currenttrack1.GetSigmaY2() +
939 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
940 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
941 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
943 // track at boundary between detectors, enlarge road
944 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
945 if ( (currenttrack1.GetY()-dy < det.GetYmin()+boundaryWidth) ||
946 (currenttrack1.GetY()+dy > det.GetYmax()-boundaryWidth) ||
947 (currenttrack1.GetZ()-dz < det.GetZmin()+boundaryWidth) ||
948 (currenttrack1.GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
949 Float_t tgl = TMath::Abs(currenttrack1.GetTgl());
950 if (tgl > 1.) tgl=1.;
951 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
952 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
953 Float_t snp = TMath::Abs(currenttrack1.GetSnp());
954 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) continue;
955 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
958 // road in global (rphi,z) [i.e. in tracking ref. system]
959 Double_t zmin = currenttrack1.GetZ() - dz;
960 Double_t zmax = currenttrack1.GetZ() + dz;
961 Double_t ymin = currenttrack1.GetY() + r*det.GetPhi() - dy;
962 Double_t ymax = currenttrack1.GetY() + r*det.GetPhi() + dy;
964 // select clusters in road
965 layer.SelectClusters(zmin,zmax,ymin,ymax);
966 //********************
968 // Define criteria for track-cluster association
969 Double_t msz = currenttrack1.GetSigmaZ2() +
970 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
971 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
972 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
973 Double_t msy = currenttrack1.GetSigmaY2() +
974 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
975 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
976 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
978 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
979 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
981 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
982 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
984 msz = 1./msz; // 1/RoadZ^2
985 msy = 1./msy; // 1/RoadY^2
988 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
990 const AliITSRecPoint *cl=0;
992 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
993 Bool_t deadzoneSPD=kFALSE;
994 currenttrack = ¤ttrack1;
996 // check if the road contains a dead zone
997 Int_t dead = CheckDeadZone(ilayer,idet,zmin,zmax);
998 // create a prolongation without clusters (check also if there are no clusters in the road)
1000 ((layer.GetNextCluster(clidx,kTRUE))==0 &&
1001 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1002 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1003 updatetrack->SetClIndex(ilayer,0);
1005 modstatus = 5; // no cls in road
1006 } else if (dead==1) {
1007 modstatus = 7; // holes in z in SPD
1008 } else if (dead==2) {
1009 modstatus = 2; // dead from OCDB
1011 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1012 // apply correction for material of the current layer
1013 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1014 if (constrain) { // apply vertex constrain
1015 updatetrack->SetConstrain(constrain);
1016 Bool_t isPrim = kTRUE;
1017 if (ilayer<4) { // check that it's close to the vertex
1018 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1019 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1020 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1021 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1022 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1024 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1027 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1028 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1029 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1037 // loop over clusters in the road
1038 while ((cl=layer.GetNextCluster(clidx))!=0) {
1039 if (ntracks[ilayer]>95) break; //space for skipped clusters
1040 Bool_t changedet =kFALSE;
1041 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
1042 Int_t idet=cl->GetDetectorIndex();
1044 if (currenttrack->GetDetectorIndex()==idet) { // track already on the cluster's detector
1045 // a first cut on track-cluster distance
1046 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1047 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1048 continue; // cluster not associated to track
1049 } else { // have to move track to cluster's detector
1050 const AliITSdetector &det=layer.GetDetector(idet);
1051 // a first cut on track-cluster distance
1053 if (!currenttrack2.GetProlongationFast(det.GetPhi(),det.GetR(),y,z)) continue;
1054 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1055 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1056 continue; // cluster not associated to track
1058 new (&backuptrack) AliITStrackMI(currenttrack2);
1060 currenttrack =¤ttrack2;
1061 if (!currenttrack->Propagate(det.GetPhi(),det.GetR())) {
1062 new (currenttrack) AliITStrackMI(backuptrack);
1066 currenttrack->SetDetectorIndex(idet);
1067 // Get again the budget to the primary vertex
1068 // for the current track being prolonged, if had to change detector
1069 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1072 // calculate track-clusters chi2
1073 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1075 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1076 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1077 if (ntracks[ilayer]>=100) continue;
1078 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1079 updatetrack->SetClIndex(ilayer,0);
1080 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1082 if (cl->GetQ()!=0) { // real cluster
1083 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) continue;
1084 updatetrack->SetSampledEdx(cl->GetQ(),updatetrack->GetNumberOfClusters()-1); //b.b.
1085 modstatus = 1; // found
1086 } else { // virtual cluster in dead zone
1087 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1088 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1089 modstatus = 7; // holes in z in SPD
1093 Float_t xlocnewdet,zlocnewdet;
1094 LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet); // local module coords
1095 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1097 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1099 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1101 // apply correction for material of the current layer
1102 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1104 if (constrain) { // apply vertex constrain
1105 updatetrack->SetConstrain(constrain);
1106 Bool_t isPrim = kTRUE;
1107 if (ilayer<4) { // check that it's close to the vertex
1108 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1109 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1110 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1111 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1112 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1114 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1115 } //apply vertex constrain
1117 } // create new hypothesis
1118 } // loop over possible prolongations
1120 // allow one prolongation without clusters
1121 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1122 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1123 // apply correction for material of the current layer
1124 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1125 vtrack->SetClIndex(ilayer,0);
1126 modstatus = 3; // skipped
1127 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1128 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1129 vtrack->IncrementNSkipped();
1133 // allow one prolongation without clusters for tracks with |tgl|>1.1
1134 if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) { //big theta - for low flux
1135 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1136 // apply correction for material of the current layer
1137 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1138 vtrack->SetClIndex(ilayer,0);
1139 modstatus = 3; // skipped
1140 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1141 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1142 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1147 } // loop over tracks in layer ilayer+1
1149 //loop over track candidates for the current layer
1155 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1156 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1157 if (normalizedchi2[itrack] <
1158 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1162 if (constrain) { // constrain
1163 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1165 } else { // !constrain
1166 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1171 // sort tracks by increasing normalized chi2
1172 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1173 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1174 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1175 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1176 } // end loop over layers
1180 // Now select tracks to be kept
1182 Int_t max = constrain ? 20 : 5;
1184 // tracks that reach layer 0 (SPD inner)
1185 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1186 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1187 if (track.GetNumberOfClusters()<2) continue;
1188 if (!constrain && track.GetNormChi2(0) >
1189 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1192 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1195 // tracks that reach layer 1 (SPD outer)
1196 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1197 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1198 if (track.GetNumberOfClusters()<4) continue;
1199 if (!constrain && track.GetNormChi2(1) >
1200 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1201 if (constrain) track.IncrementNSkipped();
1203 track.SetD(0,track.GetD(GetX(),GetY()));
1204 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1205 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1206 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1209 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1212 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1214 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1215 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1216 if (track.GetNumberOfClusters()<3) continue;
1217 if (!constrain && track.GetNormChi2(2) >
1218 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1219 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1221 track.SetD(0,track.GetD(GetX(),GetY()));
1222 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1223 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1224 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1227 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1233 // register best track of each layer - important for V0 finder
1235 for (Int_t ilayer=0;ilayer<5;ilayer++){
1236 if (ntracks[ilayer]==0) continue;
1237 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1238 if (track.GetNumberOfClusters()<1) continue;
1239 CookLabel(&track,0);
1240 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1244 // update TPC V0 information
1246 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1247 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1248 for (Int_t i=0;i<3;i++){
1249 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1250 if (index==0) break;
1251 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1252 if (vertex->GetStatus()<0) continue; // rejected V0
1254 if (otrack->GetSign()>0) {
1255 vertex->SetIndex(0,esdindex);
1258 vertex->SetIndex(1,esdindex);
1260 //find nearest layer with track info
1261 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1262 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1263 Int_t nearest = nearestold;
1264 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1265 if (ntracks[nearest]==0){
1270 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1271 if (nearestold<5&&nearest<5){
1272 Bool_t accept = track.GetNormChi2(nearest)<10;
1274 if (track.GetSign()>0) {
1275 vertex->SetParamP(track);
1276 vertex->Update(fprimvertex);
1277 //vertex->SetIndex(0,track.fESDtrack->GetID());
1278 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1280 vertex->SetParamN(track);
1281 vertex->Update(fprimvertex);
1282 //vertex->SetIndex(1,track.fESDtrack->GetID());
1283 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1285 vertex->SetStatus(vertex->GetStatus()+1);
1287 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1294 //------------------------------------------------------------------------
1295 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1297 //--------------------------------------------------------------------
1300 return fgLayers[layer];
1302 //------------------------------------------------------------------------
1303 AliITStrackerMI::AliITSlayer::AliITSlayer():
1328 //--------------------------------------------------------------------
1329 //default AliITSlayer constructor
1330 //--------------------------------------------------------------------
1331 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1332 fClusterWeight[i]=0;
1333 fClusterTracks[0][i]=-1;
1334 fClusterTracks[1][i]=-1;
1335 fClusterTracks[2][i]=-1;
1336 fClusterTracks[3][i]=-1;
1339 //------------------------------------------------------------------------
1340 AliITStrackerMI::AliITSlayer::
1341 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1366 //--------------------------------------------------------------------
1367 //main AliITSlayer constructor
1368 //--------------------------------------------------------------------
1369 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1370 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1372 //------------------------------------------------------------------------
1373 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1375 fPhiOffset(layer.fPhiOffset),
1376 fNladders(layer.fNladders),
1377 fZOffset(layer.fZOffset),
1378 fNdetectors(layer.fNdetectors),
1379 fDetectors(layer.fDetectors),
1384 fClustersCs(layer.fClustersCs),
1385 fClusterIndexCs(layer.fClusterIndexCs),
1389 fCurrentSlice(layer.fCurrentSlice),
1396 fAccepted(layer.fAccepted),
1400 //------------------------------------------------------------------------
1401 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1402 //--------------------------------------------------------------------
1403 // AliITSlayer destructor
1404 //--------------------------------------------------------------------
1405 delete[] fDetectors;
1406 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1407 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1408 fClusterWeight[i]=0;
1409 fClusterTracks[0][i]=-1;
1410 fClusterTracks[1][i]=-1;
1411 fClusterTracks[2][i]=-1;
1412 fClusterTracks[3][i]=-1;
1415 //------------------------------------------------------------------------
1416 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1417 //--------------------------------------------------------------------
1418 // This function removes loaded clusters
1419 //--------------------------------------------------------------------
1420 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1421 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1422 fClusterWeight[i]=0;
1423 fClusterTracks[0][i]=-1;
1424 fClusterTracks[1][i]=-1;
1425 fClusterTracks[2][i]=-1;
1426 fClusterTracks[3][i]=-1;
1432 //------------------------------------------------------------------------
1433 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1434 //--------------------------------------------------------------------
1435 // This function reset weights of the clusters
1436 //--------------------------------------------------------------------
1437 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1438 fClusterWeight[i]=0;
1439 fClusterTracks[0][i]=-1;
1440 fClusterTracks[1][i]=-1;
1441 fClusterTracks[2][i]=-1;
1442 fClusterTracks[3][i]=-1;
1444 for (Int_t i=0; i<fN;i++) {
1445 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1446 if (cl&&cl->IsUsed()) cl->Use();
1450 //------------------------------------------------------------------------
1451 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1452 //--------------------------------------------------------------------
1453 // This function calculates the road defined by the cluster density
1454 //--------------------------------------------------------------------
1456 for (Int_t i=0; i<fN; i++) {
1457 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1459 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1461 //------------------------------------------------------------------------
1462 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1463 //--------------------------------------------------------------------
1464 //This function adds a cluster to this layer
1465 //--------------------------------------------------------------------
1466 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1467 ::Error("InsertCluster","Too many clusters !\n");
1473 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1474 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1475 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1476 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1477 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1481 //------------------------------------------------------------------------
1482 void AliITStrackerMI::AliITSlayer::SortClusters()
1487 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1488 Float_t *z = new Float_t[fN];
1489 Int_t * index = new Int_t[fN];
1491 for (Int_t i=0;i<fN;i++){
1492 z[i] = fClusters[i]->GetZ();
1494 TMath::Sort(fN,z,index,kFALSE);
1495 for (Int_t i=0;i<fN;i++){
1496 clusters[i] = fClusters[index[i]];
1499 for (Int_t i=0;i<fN;i++){
1500 fClusters[i] = clusters[i];
1501 fZ[i] = fClusters[i]->GetZ();
1502 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1503 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1504 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1514 for (Int_t i=0;i<fN;i++){
1515 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1516 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1517 fClusterIndex[i] = i;
1521 fDy5 = (fYB[1]-fYB[0])/5.;
1522 fDy10 = (fYB[1]-fYB[0])/10.;
1523 fDy20 = (fYB[1]-fYB[0])/20.;
1524 for (Int_t i=0;i<6;i++) fN5[i] =0;
1525 for (Int_t i=0;i<11;i++) fN10[i]=0;
1526 for (Int_t i=0;i<21;i++) fN20[i]=0;
1528 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;}
1529 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;}
1530 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;}
1533 for (Int_t i=0;i<fN;i++)
1534 for (Int_t irot=-1;irot<=1;irot++){
1535 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1537 for (Int_t slice=0; slice<6;slice++){
1538 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1539 fClusters5[slice][fN5[slice]] = fClusters[i];
1540 fY5[slice][fN5[slice]] = curY;
1541 fZ5[slice][fN5[slice]] = fZ[i];
1542 fClusterIndex5[slice][fN5[slice]]=i;
1547 for (Int_t slice=0; slice<11;slice++){
1548 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1549 fClusters10[slice][fN10[slice]] = fClusters[i];
1550 fY10[slice][fN10[slice]] = curY;
1551 fZ10[slice][fN10[slice]] = fZ[i];
1552 fClusterIndex10[slice][fN10[slice]]=i;
1557 for (Int_t slice=0; slice<21;slice++){
1558 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1559 fClusters20[slice][fN20[slice]] = fClusters[i];
1560 fY20[slice][fN20[slice]] = curY;
1561 fZ20[slice][fN20[slice]] = fZ[i];
1562 fClusterIndex20[slice][fN20[slice]]=i;
1569 // consistency check
1571 for (Int_t i=0;i<fN-1;i++){
1577 for (Int_t slice=0;slice<21;slice++)
1578 for (Int_t i=0;i<fN20[slice]-1;i++){
1579 if (fZ20[slice][i]>fZ20[slice][i+1]){
1586 //------------------------------------------------------------------------
1587 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1588 //--------------------------------------------------------------------
1589 // This function returns the index of the nearest cluster
1590 //--------------------------------------------------------------------
1593 if (fCurrentSlice<0) {
1602 if (ncl==0) return 0;
1603 Int_t b=0, e=ncl-1, m=(b+e)/2;
1604 for (; b<e; m=(b+e)/2) {
1605 // if (z > fClusters[m]->GetZ()) b=m+1;
1606 if (z > zcl[m]) b=m+1;
1611 //------------------------------------------------------------------------
1612 void AliITStrackerMI::AliITSlayer::
1613 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1614 //--------------------------------------------------------------------
1615 // This function sets the "window"
1616 //--------------------------------------------------------------------
1618 Double_t circle=2*TMath::Pi()*fR;
1619 fYmin = ymin; fYmax =ymax;
1620 Float_t ymiddle = (fYmin+fYmax)*0.5;
1621 if (ymiddle<fYB[0]) {
1622 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1623 } else if (ymiddle>fYB[1]) {
1624 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1630 fClustersCs = fClusters;
1631 fClusterIndexCs = fClusterIndex;
1637 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1638 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1639 if (slice<0) slice=0;
1640 if (slice>20) slice=20;
1641 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1643 fCurrentSlice=slice;
1644 fClustersCs = fClusters20[fCurrentSlice];
1645 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1646 fYcs = fY20[fCurrentSlice];
1647 fZcs = fZ20[fCurrentSlice];
1648 fNcs = fN20[fCurrentSlice];
1653 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1654 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1655 if (slice<0) slice=0;
1656 if (slice>10) slice=10;
1657 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1659 fCurrentSlice=slice;
1660 fClustersCs = fClusters10[fCurrentSlice];
1661 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1662 fYcs = fY10[fCurrentSlice];
1663 fZcs = fZ10[fCurrentSlice];
1664 fNcs = fN10[fCurrentSlice];
1669 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1670 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1671 if (slice<0) slice=0;
1672 if (slice>5) slice=5;
1673 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1675 fCurrentSlice=slice;
1676 fClustersCs = fClusters5[fCurrentSlice];
1677 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1678 fYcs = fY5[fCurrentSlice];
1679 fZcs = fZ5[fCurrentSlice];
1680 fNcs = fN5[fCurrentSlice];
1684 fI=FindClusterIndex(zmin); fZmax=zmax;
1685 fImax = TMath::Min(FindClusterIndex(zmax)+1,fNcs);
1691 //------------------------------------------------------------------------
1692 Int_t AliITStrackerMI::AliITSlayer::
1693 FindDetectorIndex(Double_t phi, Double_t z) const {
1694 //--------------------------------------------------------------------
1695 //This function finds the detector crossed by the track
1696 //--------------------------------------------------------------------
1698 if (fZOffset<0) // old geometry
1699 dphi = -(phi-fPhiOffset);
1700 else // new geometry
1701 dphi = phi-fPhiOffset;
1704 if (dphi < 0) dphi += 2*TMath::Pi();
1705 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1706 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1707 if (np>=fNladders) np-=fNladders;
1708 if (np<0) np+=fNladders;
1711 Double_t dz=fZOffset-z;
1712 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1713 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1714 if (nz>=fNdetectors) return -1;
1715 if (nz<0) return -1;
1717 return np*fNdetectors + nz;
1719 //------------------------------------------------------------------------
1720 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1722 //--------------------------------------------------------------------
1723 // This function returns clusters within the "window"
1724 //--------------------------------------------------------------------
1726 if (fCurrentSlice<0) {
1727 Double_t rpi2 = 2.*fR*TMath::Pi();
1728 for (Int_t i=fI; i<fImax; i++) {
1730 if (fYmax<y) y -= rpi2;
1731 if (fYmin>y) y += rpi2;
1732 if (y<fYmin) continue;
1733 if (y>fYmax) continue;
1734 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1737 return fClusters[i];
1740 for (Int_t i=fI; i<fImax; i++) {
1741 if (fYcs[i]<fYmin) continue;
1742 if (fYcs[i]>fYmax) continue;
1743 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1744 ci=fClusterIndexCs[i];
1746 return fClustersCs[i];
1751 //------------------------------------------------------------------------
1752 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1754 //--------------------------------------------------------------------
1755 // This function returns the layer thickness at this point (units X0)
1756 //--------------------------------------------------------------------
1758 x0=AliITSRecoParam::GetX0Air();
1759 if (43<fR&&fR<45) { //SSD2
1762 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1763 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1764 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1765 for (Int_t i=0; i<12; i++) {
1766 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1767 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1771 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1772 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1776 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1777 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1780 if (37<fR&&fR<41) { //SSD1
1783 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1784 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1785 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1786 for (Int_t i=0; i<11; i++) {
1787 if (TMath::Abs(z-3.9*i)<0.15) {
1788 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1792 if (TMath::Abs(z+3.9*i)<0.15) {
1793 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1797 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1798 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1801 if (13<fR&&fR<26) { //SDD
1804 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1806 if (TMath::Abs(y-1.80)<0.55) {
1808 for (Int_t j=0; j<20; j++) {
1809 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1810 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1813 if (TMath::Abs(y+1.80)<0.55) {
1815 for (Int_t j=0; j<20; j++) {
1816 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1817 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1821 for (Int_t i=0; i<4; i++) {
1822 if (TMath::Abs(z-7.3*i)<0.60) {
1824 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1827 if (TMath::Abs(z+7.3*i)<0.60) {
1829 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1834 if (6<fR&&fR<8) { //SPD2
1835 Double_t dd=0.0063; x0=21.5;
1837 if (TMath::Abs(y-3.08)>0.5) d+=dd;
1838 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
1840 if (3<fR&&fR<5) { //SPD1
1841 Double_t dd=0.0063; x0=21.5;
1843 if (TMath::Abs(y+0.21)>0.6) d+=dd;
1844 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
1849 //------------------------------------------------------------------------
1850 Double_t AliITStrackerMI::GetEffectiveThickness()
1852 //--------------------------------------------------------------------
1853 // Returns the thickness between the current layer and the vertex (units X0)
1854 //--------------------------------------------------------------------
1857 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
1858 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
1859 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
1863 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
1864 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
1868 Double_t xn=fgLayers[fI].GetR();
1869 for (Int_t i=0; i<fI; i++) {
1870 Double_t xi=fgLayers[i].GetR();
1871 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
1877 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
1878 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
1881 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
1882 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
1886 //------------------------------------------------------------------------
1887 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
1888 //-------------------------------------------------------------------
1889 // This function returns number of clusters within the "window"
1890 //--------------------------------------------------------------------
1892 for (Int_t i=fI; i<fN; i++) {
1893 const AliITSRecPoint *c=fClusters[i];
1894 if (c->GetZ() > fZmax) break;
1895 if (c->IsUsed()) continue;
1896 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
1897 Double_t y=fR*det.GetPhi() + c->GetY();
1899 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
1900 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
1902 if (y<fYmin) continue;
1903 if (y>fYmax) continue;
1908 //------------------------------------------------------------------------
1909 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
1910 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
1912 //--------------------------------------------------------------------
1913 // This function refits the track "track" at the position "x" using
1914 // the clusters from "clusters"
1915 // If "extra"==kTRUE,
1916 // the clusters from overlapped modules get attached to "track"
1917 // If "planeff"==kTRUE,
1918 // special approach for plane efficiency evaluation is applyed
1919 //--------------------------------------------------------------------
1921 Int_t index[AliITSgeomTGeo::kNLayers];
1923 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
1924 Int_t nc=clusters->GetNumberOfClusters();
1925 for (k=0; k<nc; k++) {
1926 Int_t idx=clusters->GetClusterIndex(k);
1927 Int_t ilayer=(idx&0xf0000000)>>28;
1931 return RefitAt(xx,track,index,extra,planeeff); // call the method below
1933 //------------------------------------------------------------------------
1934 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
1935 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
1937 //--------------------------------------------------------------------
1938 // This function refits the track "track" at the position "x" using
1939 // the clusters from array
1940 // If "extra"==kTRUE,
1941 // the clusters from overlapped modules get attached to "track"
1942 // If "planeff"==kTRUE,
1943 // special approach for plane efficiency evaluation is applyed
1944 //--------------------------------------------------------------------
1945 Int_t index[AliITSgeomTGeo::kNLayers];
1947 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
1949 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
1950 index[k]=clusters[k];
1953 // special for cosmics: check which the innermost layer crossed
1955 Int_t innermostlayer=5;
1956 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
1957 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
1958 if(drphi < fgLayers[innermostlayer].GetR()) break;
1960 //printf(" drphi %f innermost %d\n",drphi,innermostlayer);
1962 Int_t modstatus=1; // found
1964 Int_t from, to, step;
1965 if (xx > track->GetX()) {
1966 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
1969 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
1972 TString dir = (step>0 ? "outward" : "inward");
1974 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
1975 AliITSlayer &layer=fgLayers[ilayer];
1976 Double_t r=layer.GetR();
1977 if (step<0 && xx>r) break;
1979 // material between SSD and SDD, SDD and SPD
1980 Double_t hI=ilayer-0.5*step;
1981 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
1982 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
1983 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
1984 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
1986 // remember old position [SR, GSI 18.02.2003]
1987 Double_t oldX=0., oldY=0., oldZ=0.;
1988 if (track->IsStartedTimeIntegral() && step==1) {
1989 track->GetGlobalXYZat(track->GetX(),oldX,oldY,oldZ);
1993 Double_t oldGlobXYZ[3];
1994 track->GetXYZ(oldGlobXYZ);
1997 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
1999 Int_t idet=layer.FindDetectorIndex(phi,z);
2001 // check if we allow a prolongation without point for large-eta tracks
2002 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2004 // propagate to the layer radius
2005 Double_t xToGo; track->GetLocalXat(r,xToGo);
2006 track->AliExternalTrackParam::PropagateTo(xToGo,GetBz());
2007 // apply correction for material of the current layer
2008 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2009 modstatus = 4; // out in z
2010 LocalModuleCoord(ilayer,idet,track,xloc,zloc); // local module coords
2011 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2012 // track time update [SR, GSI 17.02.2003]
2013 if (track->IsStartedTimeIntegral() && step==1) {
2014 Double_t newX, newY, newZ;
2015 track->GetGlobalXYZat(track->GetX(),newX,newY,newZ);
2016 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2017 (oldZ-newZ)*(oldZ-newZ);
2018 track->AddTimeStep(TMath::Sqrt(dL2));
2023 if (idet<0) return kFALSE;
2025 const AliITSdetector &det=layer.GetDetector(idet);
2027 if (!track->Propagate(phi,det.GetR())) return kFALSE;
2028 track->SetDetectorIndex(idet);
2029 LocalModuleCoord(ilayer,idet,track,xloc,zloc); // local module coords
2031 Double_t dz,zmin,zmax;
2033 const AliITSRecPoint *clAcc=0;
2034 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2036 Int_t idx=index[ilayer];
2037 if (idx>=0) { // cluster in this layer
2038 modstatus = 6; // no refit
2039 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2041 if (idet != cl->GetDetectorIndex()) {
2042 idet=cl->GetDetectorIndex();
2043 const AliITSdetector &det=layer.GetDetector(idet);
2044 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2045 track->SetDetectorIndex(idet);
2046 LocalModuleCoord(ilayer,idet,track,xloc,zloc); // local module coords
2048 //Double_t chi2=track->GetPredictedChi2(cl);
2049 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2050 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2054 modstatus = 1; // found
2059 } else { // no cluster in this layer
2061 modstatus = 3; // skipped
2062 // Plane Eff determination:
2063 if (planeeff && AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) {
2064 if (IsOKForPlaneEff(track,ilayer)) // only adequate track for plane eff. evaluation
2065 UseTrackForPlaneEff(track,ilayer);
2068 modstatus = 5; // no cls in road
2070 dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
2071 TMath::Sqrt(track->GetSigmaZ2() +
2072 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
2073 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
2074 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
2075 zmin=track->GetZ() - dz;
2076 zmax=track->GetZ() + dz;
2077 Int_t dead = CheckDeadZone(ilayer,idet,zmin,zmax);
2078 if (dead==1) modstatus = 7; // holes in z in SPD
2079 if (dead==2) modstatus = 2; // dead from OCDB
2084 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2085 track->SetSampledEdx(clAcc->GetQ(),track->GetNumberOfClusters()-1);
2087 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2090 if (extra) { // search for extra clusters in overlapped modules
2091 AliITStrackV2 tmp(*track);
2092 Double_t dy,ymin,ymax;
2093 dz=4*TMath::Sqrt(tmp.GetSigmaZ2()+AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
2094 if (dz < 0.5*TMath::Abs(tmp.GetTgl())) dz=0.5*TMath::Abs(tmp.GetTgl());
2095 dy=4*TMath::Sqrt(track->GetSigmaY2()+AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
2096 if (dy < 0.5*TMath::Abs(tmp.GetSnp())) dy=0.5*TMath::Abs(tmp.GetSnp());
2097 zmin=track->GetZ() - dz;
2098 zmax=track->GetZ() + dz;
2099 ymin=track->GetY() + phi*r - dy;
2100 ymax=track->GetY() + phi*r + dy;
2101 layer.SelectClusters(zmin,zmax,ymin,ymax);
2103 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2105 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2(), tolerance=0.1;
2106 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2107 // only clusters in another module! (overlaps)
2108 idetExtra = clExtra->GetDetectorIndex();
2109 if (idet == idetExtra) continue;
2111 const AliITSdetector &det=layer.GetDetector(idetExtra);
2113 if (!tmp.Propagate(det.GetPhi(),det.GetR())) continue;
2115 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2116 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2118 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2119 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2122 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2123 track->SetExtraModule(ilayer,idetExtra);
2125 } // end search for extra clusters in overlapped modules
2127 // Correct for material of the current layer
2128 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2130 // track time update [SR, GSI 17.02.2003]
2131 if (track->IsStartedTimeIntegral() && step==1) {
2132 Double_t newX, newY, newZ;
2133 track->GetGlobalXYZat(track->GetX(),newX,newY,newZ);
2134 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2135 (oldZ-newZ)*(oldZ-newZ);
2136 track->AddTimeStep(TMath::Sqrt(dL2));
2140 } // end loop on layers
2142 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2146 //------------------------------------------------------------------------
2147 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2150 // calculate normalized chi2
2151 // return NormalizedChi2(track,0);
2154 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2155 // track->fdEdxMismatch=0;
2156 Float_t dedxmismatch =0;
2157 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2159 for (Int_t i = 0;i<6;i++){
2160 if (track->GetClIndex(i)>0){
2161 Float_t cerry, cerrz;
2162 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2164 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2167 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2168 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2169 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2171 cchi2+=(0.5-ratio)*10.;
2172 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2173 dedxmismatch+=(0.5-ratio)*10.;
2177 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2178 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2179 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2180 if (i<2) chi2+=2*cl->GetDeltaProbability();
2186 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2187 track->SetdEdxMismatch(dedxmismatch);
2191 for (Int_t i = 0;i<4;i++){
2192 if (track->GetClIndex(i)>0){
2193 Float_t cerry, cerrz;
2194 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2195 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2198 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2199 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2203 for (Int_t i = 4;i<6;i++){
2204 if (track->GetClIndex(i)>0){
2205 Float_t cerry, cerrz;
2206 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2207 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2210 Float_t cerryb, cerrzb;
2211 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2212 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2215 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2216 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2221 if (track->GetESDtrack()->GetTPCsignal()>85){
2222 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2224 chi2+=(0.5-ratio)*5.;
2227 chi2+=(ratio-2.0)*3;
2231 Double_t match = TMath::Sqrt(track->GetChi22());
2232 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2233 if (!track->GetConstrain()) {
2234 if (track->GetNumberOfClusters()>2) {
2235 match/=track->GetNumberOfClusters()-2.;
2240 if (match<0) match=0;
2241 Float_t deadzonefactor = (track->GetNDeadZone()>0) ? 3*(1.1-track->GetDeadZoneProbability()):0.;
2242 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2243 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2244 1./(1.+track->GetNSkipped()));
2248 //------------------------------------------------------------------------
2249 Double_t AliITStrackerMI::GetMatchingChi2(AliITStrackMI * track1, AliITStrackMI * track2)
2252 // return matching chi2 between two tracks
2253 AliITStrackMI track3(*track2);
2254 track3.Propagate(track1->GetAlpha(),track1->GetX());
2256 vec(0,0)=track1->GetY() - track3.GetY();
2257 vec(1,0)=track1->GetZ() - track3.GetZ();
2258 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2259 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2260 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2263 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2264 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2265 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2266 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2267 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2269 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2270 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2271 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2272 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2274 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2275 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2276 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2278 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2279 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2281 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2284 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2285 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2288 //------------------------------------------------------------------------
2289 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr)
2292 // return probability that given point (characterized by z position and error)
2293 // is in SPD dead zone
2295 Double_t probability = 0.;
2296 Double_t absz = TMath::Abs(zpos);
2297 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2298 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2299 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2300 Double_t zmin, zmax;
2301 if (zpos<-6.) { // dead zone at z = -7
2302 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2303 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2304 } else if (zpos>6.) { // dead zone at z = +7
2305 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2306 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2307 } else if (absz<2.) { // dead zone at z = 0
2308 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2309 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2314 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2316 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2317 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2320 //------------------------------------------------------------------------
2321 Double_t AliITStrackerMI::GetTruncatedChi2(AliITStrackMI * track, Float_t fac)
2324 // calculate normalized chi2
2326 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2328 for (Int_t i = 0;i<6;i++){
2329 if (TMath::Abs(track->GetDy(i))>0){
2330 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2331 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2334 else{chi2[i]=10000;}
2337 TMath::Sort(6,chi2,index,kFALSE);
2338 Float_t max = float(ncl)*fac-1.;
2339 Float_t sumchi=0, sumweight=0;
2340 for (Int_t i=0;i<max+1;i++){
2341 Float_t weight = (i<max)?1.:(max+1.-i);
2342 sumchi+=weight*chi2[index[i]];
2345 Double_t normchi2 = sumchi/sumweight;
2348 //------------------------------------------------------------------------
2349 Double_t AliITStrackerMI::GetInterpolatedChi2(AliITStrackMI * forwardtrack, AliITStrackMI * backtrack)
2352 // calculate normalized chi2
2353 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2356 for (Int_t i=0;i<6;i++){
2357 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2358 Double_t sy1 = forwardtrack->GetSigmaY(i);
2359 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2360 Double_t sy2 = backtrack->GetSigmaY(i);
2361 Double_t sz2 = backtrack->GetSigmaZ(i);
2362 if (i<2){ sy2=1000.;sz2=1000;}
2364 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2365 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2367 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2368 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2370 res+= nz0*nz0+ny0*ny0;
2373 if (npoints>1) return
2374 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2375 //2*forwardtrack->fNUsed+
2376 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2377 1./(1.+forwardtrack->GetNSkipped()));
2380 //------------------------------------------------------------------------
2381 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2382 //--------------------------------------------------------------------
2383 // Return pointer to a given cluster
2384 //--------------------------------------------------------------------
2385 Int_t l=(index & 0xf0000000) >> 28;
2386 Int_t c=(index & 0x0fffffff) >> 00;
2387 return fgLayers[l].GetWeight(c);
2389 //------------------------------------------------------------------------
2390 void AliITStrackerMI::RegisterClusterTracks(AliITStrackMI* track,Int_t id)
2392 //---------------------------------------------
2393 // register track to the list
2395 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2398 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2399 Int_t index = track->GetClusterIndex(icluster);
2400 Int_t l=(index & 0xf0000000) >> 28;
2401 Int_t c=(index & 0x0fffffff) >> 00;
2402 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2403 for (Int_t itrack=0;itrack<4;itrack++){
2404 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2405 fgLayers[l].SetClusterTracks(itrack,c,id);
2411 //------------------------------------------------------------------------
2412 void AliITStrackerMI::UnRegisterClusterTracks(AliITStrackMI* track, Int_t id)
2414 //---------------------------------------------
2415 // unregister track from the list
2416 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2417 Int_t index = track->GetClusterIndex(icluster);
2418 Int_t l=(index & 0xf0000000) >> 28;
2419 Int_t c=(index & 0x0fffffff) >> 00;
2420 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2421 for (Int_t itrack=0;itrack<4;itrack++){
2422 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2423 fgLayers[l].SetClusterTracks(itrack,c,-1);
2428 //------------------------------------------------------------------------
2429 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2431 //-------------------------------------------------------------
2432 //get number of shared clusters
2433 //-------------------------------------------------------------
2435 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2436 // mean number of clusters
2437 Float_t *ny = GetNy(id), *nz = GetNz(id);
2440 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2441 Int_t index = track->GetClusterIndex(icluster);
2442 Int_t l=(index & 0xf0000000) >> 28;
2443 Int_t c=(index & 0x0fffffff) >> 00;
2444 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2446 printf("problem\n");
2448 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2452 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2453 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2454 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2456 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2459 deltan = (cl->GetNz()-nz[l]);
2461 if (deltan>2.0) continue; // extended - highly probable shared cluster
2462 weight = 2./TMath::Max(3.+deltan,2.);
2464 for (Int_t itrack=0;itrack<4;itrack++){
2465 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2467 clist[l] = (AliITSRecPoint*)GetCluster(index);
2473 track->SetNUsed(shared);
2476 //------------------------------------------------------------------------
2477 Int_t AliITStrackerMI::GetOverlapTrack(AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2480 // find first shared track
2482 // mean number of clusters
2483 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2485 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2486 Int_t sharedtrack=100000;
2487 Int_t tracks[24],trackindex=0;
2488 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2490 for (Int_t icluster=0;icluster<6;icluster++){
2491 if (clusterlist[icluster]<0) continue;
2492 Int_t index = clusterlist[icluster];
2493 Int_t l=(index & 0xf0000000) >> 28;
2494 Int_t c=(index & 0x0fffffff) >> 00;
2496 printf("problem\n");
2498 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2499 //if (l>3) continue;
2500 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2503 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2504 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2505 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2507 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2510 deltan = (cl->GetNz()-nz[l]);
2512 if (deltan>2.0) continue; // extended - highly probable shared cluster
2514 for (Int_t itrack=3;itrack>=0;itrack--){
2515 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2516 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2517 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2522 if (trackindex==0) return -1;
2524 sharedtrack = tracks[0];
2526 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2529 Int_t track[24], cluster[24];
2530 for (Int_t i=0;i<trackindex;i++){ track[i]=-1; cluster[i]=0;}
2533 for (Int_t i=0;i<trackindex;i++){
2534 if (tracks[i]<0) continue;
2535 track[index] = tracks[i];
2537 for (Int_t j=i+1;j<trackindex;j++){
2538 if (tracks[j]<0) continue;
2539 if (tracks[j]==tracks[i]){
2547 for (Int_t i=0;i<index;i++){
2548 if (cluster[index]>max) {
2549 sharedtrack=track[index];
2556 if (sharedtrack>=100000) return -1;
2558 // make list of overlaps
2560 for (Int_t icluster=0;icluster<6;icluster++){
2561 if (clusterlist[icluster]<0) continue;
2562 Int_t index = clusterlist[icluster];
2563 Int_t l=(index & 0xf0000000) >> 28;
2564 Int_t c=(index & 0x0fffffff) >> 00;
2565 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2566 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2568 if (cl->GetNy()>2) continue;
2569 if (cl->GetNz()>2) continue;
2572 if (cl->GetNy()>3) continue;
2573 if (cl->GetNz()>3) continue;
2576 for (Int_t itrack=3;itrack>=0;itrack--){
2577 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2578 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2586 //------------------------------------------------------------------------
2587 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2589 // try to find track hypothesys without conflicts
2590 // with minimal chi2;
2591 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2592 Int_t entries1 = arr1->GetEntriesFast();
2593 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2594 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2595 Int_t entries2 = arr2->GetEntriesFast();
2596 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2598 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2599 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2600 if (track10->Pt()>0.5+track20->Pt()) return track10;
2602 for (Int_t itrack=0;itrack<entries1;itrack++){
2603 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2604 UnRegisterClusterTracks(track,trackID1);
2607 for (Int_t itrack=0;itrack<entries2;itrack++){
2608 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2609 UnRegisterClusterTracks(track,trackID2);
2613 Float_t maxconflicts=6;
2614 Double_t maxchi2 =1000.;
2616 // get weight of hypothesys - using best hypothesy
2619 Int_t list1[6],list2[6];
2620 AliITSRecPoint *clist1[6], *clist2[6] ;
2621 RegisterClusterTracks(track10,trackID1);
2622 RegisterClusterTracks(track20,trackID2);
2623 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2624 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2625 UnRegisterClusterTracks(track10,trackID1);
2626 UnRegisterClusterTracks(track20,trackID2);
2629 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2630 Float_t nerry[6],nerrz[6];
2631 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2632 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2633 for (Int_t i=0;i<6;i++){
2634 if ( (erry1[i]>0) && (erry2[i]>0)) {
2635 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2636 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2638 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2639 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2641 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2642 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2643 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2646 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2647 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2648 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2656 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2657 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2658 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2659 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2661 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2662 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2663 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2665 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2666 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2667 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2670 Double_t sumw = w1+w2;
2674 w1 = (d2+0.5)/(d1+d2+1.);
2675 w2 = (d1+0.5)/(d1+d2+1.);
2677 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2678 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2680 // get pair of "best" hypothesys
2682 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2683 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2685 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2686 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2687 //if (track1->fFakeRatio>0) continue;
2688 RegisterClusterTracks(track1,trackID1);
2689 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2690 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2692 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2693 //if (track2->fFakeRatio>0) continue;
2695 RegisterClusterTracks(track2,trackID2);
2696 Int_t list1[6],list2[6];
2697 AliITSRecPoint *clist1[6], *clist2[6] ;
2698 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2699 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2700 UnRegisterClusterTracks(track2,trackID2);
2702 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2703 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2704 if (nskipped>0.5) continue;
2706 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2707 if (conflict1+1<cconflict1) continue;
2708 if (conflict2+1<cconflict2) continue;
2712 for (Int_t i=0;i<6;i++){
2714 Float_t c1 =0.; // conflict coeficients
2716 if (clist1[i]&&clist2[i]){
2719 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2722 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
2724 c1 = 2./TMath::Max(3.+deltan,2.);
2725 c2 = 2./TMath::Max(3.+deltan,2.);
2731 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
2734 deltan = (clist1[i]->GetNz()-nz1[i]);
2736 c1 = 2./TMath::Max(3.+deltan,2.);
2743 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
2746 deltan = (clist2[i]->GetNz()-nz2[i]);
2748 c2 = 2./TMath::Max(3.+deltan,2.);
2753 Double_t chi21=0,chi22=0;
2754 if (TMath::Abs(track1->GetDy(i))>0.) {
2755 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
2756 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
2757 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
2758 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
2760 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
2763 if (TMath::Abs(track2->GetDy(i))>0.) {
2764 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
2765 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
2766 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
2767 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
2770 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
2772 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
2773 if (chi21>0) sum+=w1;
2774 if (chi22>0) sum+=w2;
2777 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
2778 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
2779 Double_t normchi2 = 2*conflict+sumchi2/sum;
2780 if ( normchi2 <maxchi2 ){
2783 maxconflicts = conflict;
2787 UnRegisterClusterTracks(track1,trackID1);
2790 // if (maxconflicts<4 && maxchi2<th0){
2791 if (maxchi2<th0*2.){
2792 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
2793 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
2794 track1->SetChi2MIP(5,maxconflicts);
2795 track1->SetChi2MIP(6,maxchi2);
2796 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
2797 // track1->UpdateESDtrack(AliESDtrack::kITSin);
2798 track1->SetChi2MIP(8,index1);
2799 fBestTrackIndex[trackID1] =index1;
2800 UpdateESDtrack(track1, AliESDtrack::kITSin);
2802 else if (track10->GetChi2MIP(0)<th1){
2803 track10->SetChi2MIP(5,maxconflicts);
2804 track10->SetChi2MIP(6,maxchi2);
2805 // track10->UpdateESDtrack(AliESDtrack::kITSin);
2806 UpdateESDtrack(track10,AliESDtrack::kITSin);
2809 for (Int_t itrack=0;itrack<entries1;itrack++){
2810 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2811 UnRegisterClusterTracks(track,trackID1);
2814 for (Int_t itrack=0;itrack<entries2;itrack++){
2815 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2816 UnRegisterClusterTracks(track,trackID2);
2819 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2820 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2821 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2822 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2823 RegisterClusterTracks(track10,trackID1);
2825 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2826 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2827 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
2828 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
2829 RegisterClusterTracks(track20,trackID2);
2834 //------------------------------------------------------------------------
2835 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
2836 //--------------------------------------------------------------------
2837 // This function marks clusters assigned to the track
2838 //--------------------------------------------------------------------
2839 AliTracker::UseClusters(t,from);
2841 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
2842 //if (c->GetQ()>2) c->Use();
2843 if (c->GetSigmaZ2()>0.1) c->Use();
2844 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
2845 //if (c->GetQ()>2) c->Use();
2846 if (c->GetSigmaZ2()>0.1) c->Use();
2849 //------------------------------------------------------------------------
2850 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
2852 //------------------------------------------------------------------
2853 // add track to the list of hypothesys
2854 //------------------------------------------------------------------
2856 if (esdindex>=fTrackHypothesys.GetEntriesFast()) fTrackHypothesys.Expand(esdindex*2+10);
2858 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
2860 array = new TObjArray(10);
2861 fTrackHypothesys.AddAt(array,esdindex);
2863 array->AddLast(track);
2865 //------------------------------------------------------------------------
2866 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
2868 //-------------------------------------------------------------------
2869 // compress array of track hypothesys
2870 // keep only maxsize best hypothesys
2871 //-------------------------------------------------------------------
2872 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
2873 if (! (fTrackHypothesys.At(esdindex)) ) return;
2874 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
2875 Int_t entries = array->GetEntriesFast();
2877 //- find preliminary besttrack as a reference
2878 Float_t minchi2=10000;
2880 AliITStrackMI * besttrack=0;
2881 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
2882 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2883 if (!track) continue;
2884 Float_t chi2 = NormalizedChi2(track,0);
2886 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
2887 track->SetLabel(tpcLabel);
2889 track->SetFakeRatio(1.);
2890 CookLabel(track,0.); //For comparison only
2892 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
2893 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
2894 if (track->GetNumberOfClusters()<maxn) continue;
2895 maxn = track->GetNumberOfClusters();
2902 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2903 delete array->RemoveAt(itrack);
2907 if (!besttrack) return;
2910 //take errors of best track as a reference
2911 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
2912 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
2913 for (Int_t i=0;i<6;i++) {
2914 if (besttrack->GetClIndex(i)>0){
2915 erry[i] = besttrack->GetSigmaY(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2916 errz[i] = besttrack->GetSigmaZ(i); errz[i+6] = besttrack->GetSigmaZ(i+6);
2917 ny[i] = besttrack->GetNy(i);
2918 nz[i] = besttrack->GetNz(i);
2922 // calculate normalized chi2
2924 Float_t * chi2 = new Float_t[entries];
2925 Int_t * index = new Int_t[entries];
2926 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
2927 for (Int_t itrack=0;itrack<entries;itrack++){
2928 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2930 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
2931 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
2932 chi2[itrack] = track->GetChi2MIP(0);
2934 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2935 delete array->RemoveAt(itrack);
2941 TMath::Sort(entries,chi2,index,kFALSE);
2942 besttrack = (AliITStrackMI*)array->At(index[0]);
2943 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
2944 for (Int_t i=0;i<6;i++){
2945 if (besttrack->GetClIndex(i)>0){
2946 erry[i] = besttrack->GetSigmaY(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2947 errz[i] = besttrack->GetSigmaZ(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2948 ny[i] = besttrack->GetNy(i);
2949 nz[i] = besttrack->GetNz(i);
2954 // calculate one more time with updated normalized errors
2955 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
2956 for (Int_t itrack=0;itrack<entries;itrack++){
2957 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2959 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
2960 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
2961 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
2964 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2965 delete array->RemoveAt(itrack);
2970 entries = array->GetEntriesFast();
2974 TObjArray * newarray = new TObjArray();
2975 TMath::Sort(entries,chi2,index,kFALSE);
2976 besttrack = (AliITStrackMI*)array->At(index[0]);
2979 for (Int_t i=0;i<6;i++){
2980 if (besttrack->GetNz(i)>0&&besttrack->GetNy(i)>0){
2981 erry[i] = besttrack->GetSigmaY(i); erry[i+6] = besttrack->GetSigmaY(i+6);
2982 errz[i] = besttrack->GetSigmaZ(i); errz[i+6] = besttrack->GetSigmaZ(i+6);
2983 ny[i] = besttrack->GetNy(i);
2984 nz[i] = besttrack->GetNz(i);
2987 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
2988 Float_t minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
2989 Float_t minn = besttrack->GetNumberOfClusters()-3;
2991 for (Int_t i=0;i<entries;i++){
2992 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
2993 if (!track) continue;
2994 if (accepted>maxcut) break;
2995 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
2996 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
2997 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
2998 delete array->RemoveAt(index[i]);
3002 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3003 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3004 if (!shortbest) accepted++;
3006 newarray->AddLast(array->RemoveAt(index[i]));
3007 for (Int_t i=0;i<6;i++){
3009 erry[i] = track->GetSigmaY(i); erry[i+6] = track->GetSigmaY(i+6);
3010 errz[i] = track->GetSigmaZ(i); errz[i] = track->GetSigmaZ(i+6);
3011 ny[i] = track->GetNy(i);
3012 nz[i] = track->GetNz(i);
3017 delete array->RemoveAt(index[i]);
3021 delete fTrackHypothesys.RemoveAt(esdindex);
3022 fTrackHypothesys.AddAt(newarray,esdindex);
3026 delete fTrackHypothesys.RemoveAt(esdindex);
3032 //------------------------------------------------------------------------
3033 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3035 //-------------------------------------------------------------
3036 // try to find best hypothesy
3037 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3038 //-------------------------------------------------------------
3039 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3040 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3041 if (!array) return 0;
3042 Int_t entries = array->GetEntriesFast();
3043 if (!entries) return 0;
3044 Float_t minchi2 = 100000;
3045 AliITStrackMI * besttrack=0;
3047 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3048 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3049 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3050 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3052 for (Int_t i=0;i<entries;i++){
3053 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3054 if (!track) continue;
3055 Float_t sigmarfi,sigmaz;
3056 GetDCASigma(track,sigmarfi,sigmaz);
3057 track->SetDnorm(0,sigmarfi);
3058 track->SetDnorm(1,sigmaz);
3060 track->SetChi2MIP(1,1000000);
3061 track->SetChi2MIP(2,1000000);
3062 track->SetChi2MIP(3,1000000);
3065 backtrack = new(backtrack) AliITStrackMI(*track);
3066 if (track->GetConstrain()) {
3067 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3068 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3069 backtrack->ResetCovariance(10.);
3071 backtrack->ResetCovariance(10.);
3073 backtrack->ResetClusters();
3075 Double_t x = original->GetX();
3076 if (!RefitAt(x,backtrack,track)) continue;
3078 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3079 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3080 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3081 track->SetChi22(GetMatchingChi2(backtrack,original));
3083 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3084 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3085 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3088 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3090 //forward track - without constraint
3091 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3092 forwardtrack->ResetClusters();
3094 RefitAt(x,forwardtrack,track);
3095 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3096 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3097 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3099 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3100 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3101 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3102 forwardtrack->SetD(0,track->GetD(0));
3103 forwardtrack->SetD(1,track->GetD(1));
3106 AliITSRecPoint* clist[6];
3107 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3108 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3111 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3112 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3113 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3114 track->SetChi2MIP(3,1000);
3117 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3119 for (Int_t ichi=0;ichi<5;ichi++){
3120 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3122 if (chi2 < minchi2){
3123 //besttrack = new AliITStrackMI(*forwardtrack);
3125 besttrack->SetLabel(track->GetLabel());
3126 besttrack->SetFakeRatio(track->GetFakeRatio());
3128 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3129 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3130 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3134 delete forwardtrack;
3136 for (Int_t i=0;i<entries;i++){
3137 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3138 if (!track) continue;
3140 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3141 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3142 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3143 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3144 delete array->RemoveAt(i);
3154 SortTrackHypothesys(esdindex,checkmax,1);
3155 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3156 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3157 besttrack = (AliITStrackMI*)array->At(0);
3158 if (!besttrack) return 0;
3159 besttrack->SetChi2MIP(8,0);
3160 fBestTrackIndex[esdindex]=0;
3161 entries = array->GetEntriesFast();
3162 AliITStrackMI *longtrack =0;
3164 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3165 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3166 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3167 if (!track->GetConstrain()) continue;
3168 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3169 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3170 if (track->GetChi2MIP(0)>4.) continue;
3171 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3174 //if (longtrack) besttrack=longtrack;
3177 AliITSRecPoint * clist[6];
3178 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3179 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3180 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3181 RegisterClusterTracks(besttrack,esdindex);
3188 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3189 if (sharedtrack>=0){
3191 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3193 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3199 if (shared>2.5) return 0;
3200 if (shared>1.0) return besttrack;
3202 // Don't sign clusters if not gold track
3204 if (!besttrack->IsGoldPrimary()) return besttrack;
3205 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3207 if (fConstraint[fPass]){
3211 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3212 for (Int_t i=0;i<6;i++){
3213 Int_t index = besttrack->GetClIndex(i);
3214 if (index<=0) continue;
3215 Int_t ilayer = (index & 0xf0000000) >> 28;
3216 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3217 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3219 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3220 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3221 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3222 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3223 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3224 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3226 Bool_t cansign = kTRUE;
3227 for (Int_t itrack=0;itrack<entries; itrack++){
3228 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3229 if (!track) continue;
3230 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3231 if ( (track->GetClIndex(ilayer)>0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3237 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3238 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3239 if (!c->IsUsed()) c->Use();
3245 //------------------------------------------------------------------------
3246 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3249 // get "best" hypothesys
3252 Int_t nentries = itsTracks.GetEntriesFast();
3253 for (Int_t i=0;i<nentries;i++){
3254 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3255 if (!track) continue;
3256 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3257 if (!array) continue;
3258 if (array->GetEntriesFast()<=0) continue;
3260 AliITStrackMI* longtrack=0;
3262 Float_t maxchi2=1000;
3263 for (Int_t j=0;j<array->GetEntriesFast();j++){
3264 AliITStrackMI* track = (AliITStrackMI*)array->At(j);
3265 if (!track) continue;
3266 if (track->GetGoldV0()) {
3267 longtrack = track; //gold V0 track taken
3270 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3271 Float_t chi2 = track->GetChi2MIP(0);
3273 if (!track->GetGoldV0()&&track->GetConstrain()==kFALSE) chi2+=5;
3275 if (track->GetNumberOfClusters()+track->GetNDeadZone()>minn) maxchi2 = track->GetChi2MIP(0);
3277 if (chi2 > maxchi2) continue;
3278 minn= track->GetNumberOfClusters()+track->GetNDeadZone();
3285 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3286 if (!longtrack) {longtrack = besttrack;}
3287 else besttrack= longtrack;
3291 AliITSRecPoint * clist[6];
3292 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3294 track->SetNUsed(shared);
3295 track->SetNSkipped(besttrack->GetNSkipped());
3296 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3298 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3302 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3303 //if (sharedtrack==-1) sharedtrack=0;
3304 if (sharedtrack>=0) {
3305 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3308 if (besttrack&&fAfterV0) {
3309 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3311 if (besttrack&&fConstraint[fPass])
3312 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3313 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3314 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3315 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3321 //------------------------------------------------------------------------
3322 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3323 //--------------------------------------------------------------------
3324 //This function "cooks" a track label. If label<0, this track is fake.
3325 //--------------------------------------------------------------------
3328 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3330 track->SetChi2MIP(9,0);
3332 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3333 Int_t cindex = track->GetClusterIndex(i);
3334 Int_t l=(cindex & 0xf0000000) >> 28;
3335 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3337 for (Int_t ind=0;ind<3;ind++){
3339 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3341 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3344 Int_t nclusters = track->GetNumberOfClusters();
3345 if (nclusters > 0) //PH Some tracks don't have any cluster
3346 track->SetFakeRatio(double(nwrong)/double(nclusters));
3348 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3350 track->SetLabel(tpcLabel);
3354 //------------------------------------------------------------------------
3355 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3360 //AliITSRecPoint * clist[6];
3361 // Int_t shared = GetNumberOfSharedClusters(track,index,list,clist);
3364 track->SetChi2MIP(9,0);
3365 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3366 Int_t cindex = track->GetClusterIndex(i);
3367 Int_t l=(cindex & 0xf0000000) >> 28;
3368 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3369 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3371 for (Int_t ind=0;ind<3;ind++){
3372 if (cl->GetLabel(ind)==lab) isWrong=0;
3374 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3376 //if (l>3 && (cl->GetNy()>4) || (cl->GetNz()>4)) continue; //shared track
3377 //if (l>3&& !(cl->GetType()==1||cl->GetType()==10)) continue;
3378 //if (l<4&& !(cl->GetType()==1)) continue;
3379 dedx[accepted]= track->GetSampledEdx(i);
3380 //dedx[accepted]= track->fNormQ[l];
3388 TMath::Sort(accepted,dedx,indexes,kFALSE);
3391 Double_t nl=low*accepted, nu =up*accepted;
3393 Float_t sumweight =0;
3394 for (Int_t i=0; i<accepted; i++) {
3396 if (i<nl+0.1) weight = TMath::Max(1.-(nl-i),0.);
3397 if (i>nu-1) weight = TMath::Max(nu-i,0.);
3398 sumamp+= dedx[indexes[i]]*weight;
3401 track->SetdEdx(sumamp/sumweight);
3403 //------------------------------------------------------------------------
3404 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3407 if (fCoefficients) delete []fCoefficients;
3408 fCoefficients = new Float_t[ntracks*48];
3409 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3411 //------------------------------------------------------------------------
3412 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3418 Float_t theta = track->GetTgl();
3419 Float_t phi = track->GetSnp();
3420 phi = TMath::Sqrt(phi*phi/(1.-phi*phi));
3421 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz);
3422 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz);
3424 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3425 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3427 chi2+=0.5*TMath::Min(delta/2,2.);
3428 chi2+=2.*cluster->GetDeltaProbability();
3431 track->SetNy(layer,ny);
3432 track->SetNz(layer,nz);
3433 track->SetSigmaY(layer,erry);
3434 track->SetSigmaZ(layer, errz);
3435 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3436 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/(1.- track->GetSnp()*track->GetSnp())));
3440 //------------------------------------------------------------------------
3441 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3446 Int_t layer = (index & 0xf0000000) >> 28;
3447 track->SetClIndex(layer, index);
3448 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3449 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3450 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3451 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3455 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3457 //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]);
3460 // Take into account the mis-alignment
3461 Double_t x=track->GetX()+cl->GetX();
3462 if (!track->PropagateTo(x,0.,0.)) return 0;
3465 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3466 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3468 return track->UpdateMI(&c,chi2,index);
3471 //------------------------------------------------------------------------
3472 void AliITStrackerMI::GetDCASigma(AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3475 //DCA sigmas parameterization
3476 //to be paramterized using external parameters in future
3479 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3480 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3482 //------------------------------------------------------------------------
3483 void AliITStrackerMI::SignDeltas( TObjArray *ClusterArray, Float_t vz)
3487 Int_t entries = ClusterArray->GetEntriesFast();
3488 if (entries<4) return;
3489 AliITSRecPoint* cluster = (AliITSRecPoint*)ClusterArray->At(0);
3490 Int_t layer = cluster->GetLayer();
3491 if (layer>1) return;
3493 Int_t ncandidates=0;
3494 Float_t r = (layer>0)? 7:4;
3496 for (Int_t i=0;i<entries;i++){
3497 AliITSRecPoint* cl0 = (AliITSRecPoint*)ClusterArray->At(i);
3498 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3499 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3500 index[ncandidates] = i; //candidate to belong to delta electron track
3502 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3503 cl0->SetDeltaProbability(1);
3509 for (Int_t i=0;i<ncandidates;i++){
3510 AliITSRecPoint* cl0 = (AliITSRecPoint*)ClusterArray->At(index[i]);
3511 if (cl0->GetDeltaProbability()>0.8) continue;
3514 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3515 sumy=sumz=sumy2=sumyz=sumw=0.0;
3516 for (Int_t j=0;j<ncandidates;j++){
3518 AliITSRecPoint* cl1 = (AliITSRecPoint*)ClusterArray->At(index[j]);
3520 Float_t dz = cl0->GetZ()-cl1->GetZ();
3521 Float_t dy = cl0->GetY()-cl1->GetY();
3522 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3523 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3524 y[ncl] = cl1->GetY();
3525 z[ncl] = cl1->GetZ();
3526 sumy+= y[ncl]*weight;
3527 sumz+= z[ncl]*weight;
3528 sumy2+=y[ncl]*y[ncl]*weight;
3529 sumyz+=y[ncl]*z[ncl]*weight;
3534 if (ncl<4) continue;
3535 Float_t det = sumw*sumy2 - sumy*sumy;
3537 if (TMath::Abs(det)>0.01){
3538 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3539 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3540 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3543 Float_t z0 = sumyz/sumy;
3544 delta = TMath::Abs(cl0->GetZ()-z0);
3547 cl0->SetDeltaProbability(1-20.*delta);
3551 //------------------------------------------------------------------------
3552 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3556 track->UpdateESDtrack(flags);
3557 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3558 if (oldtrack) delete oldtrack;
3559 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3560 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3561 printf("Problem\n");
3564 //------------------------------------------------------------------------
3565 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3567 // Get nearest upper layer close to the point xr.
3568 // rough approximation
3570 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3571 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3573 for (Int_t i=0;i<6;i++){
3574 if (radius<kRadiuses[i]){
3581 //------------------------------------------------------------------------
3582 void AliITStrackerMI::UpdateTPCV0(AliESDEvent *event){
3584 //try to update, or reject TPC V0s
3586 Int_t nv0s = event->GetNumberOfV0s();
3587 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3589 for (Int_t i=0;i<nv0s;i++){
3590 AliESDv0 * vertex = event->GetV0(i);
3591 Int_t ip = vertex->GetIndex(0);
3592 Int_t im = vertex->GetIndex(1);
3594 TObjArray * arrayp = (ip<nitstracks) ? (TObjArray*)fTrackHypothesys.At(ip):0;
3595 TObjArray * arraym = (im<nitstracks) ? (TObjArray*)fTrackHypothesys.At(im):0;
3596 AliITStrackMI * trackp = (arrayp!=0) ? (AliITStrackMI*)arrayp->At(0):0;
3597 AliITStrackMI * trackm = (arraym!=0) ? (AliITStrackMI*)arraym->At(0):0;
3601 if (trackp->GetNumberOfClusters()+trackp->GetNDeadZone()>5.5){
3602 if (trackp->GetConstrain()&&trackp->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3603 if (!trackp->GetConstrain()&&trackp->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3608 if (trackm->GetNumberOfClusters()+trackm->GetNDeadZone()>5.5){
3609 if (trackm->GetConstrain()&&trackm->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3610 if (!trackm->GetConstrain()&&trackm->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3613 if (vertex->GetStatus()==-100) continue;
3615 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
3616 Int_t clayer = GetNearestLayer(xrp); //I.B.
3617 vertex->SetNBefore(clayer); //
3618 vertex->SetChi2Before(9*clayer); //
3619 vertex->SetNAfter(6-clayer); //
3620 vertex->SetChi2After(0); //
3622 if (clayer >1 ){ // calculate chi2 before vertex
3623 Float_t chi2p = 0, chi2m=0;
3626 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3627 if (trackp->GetClIndex(ilayer)>0){
3628 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3629 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3640 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3641 if (trackm->GetClIndex(ilayer)>0){
3642 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3643 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3652 vertex->SetChi2Before(TMath::Min(chi2p,chi2m));
3653 if (TMath::Min(chi2p,chi2m)/Float_t(clayer)<4) vertex->SetStatus(-10); // track exist before vertex
3656 if (clayer < 5 ){ // calculate chi2 after vertex
3657 Float_t chi2p = 0, chi2m=0;
3659 if (trackp&&TMath::Abs(trackp->GetTgl())<1.){
3660 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3661 if (trackp->GetClIndex(ilayer)>0){
3662 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3663 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3673 if (trackm&&TMath::Abs(trackm->GetTgl())<1.){
3674 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3675 if (trackm->GetClIndex(ilayer)>0){
3676 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3677 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3686 vertex->SetChi2After(TMath::Max(chi2p,chi2m));
3687 if (TMath::Max(chi2m,chi2p)/Float_t(6-clayer)>9) vertex->SetStatus(-20); // track not found in ITS
3692 //------------------------------------------------------------------------
3693 void AliITStrackerMI::FindV02(AliESDEvent *event)
3698 // Cuts on DCA - R dependent
3699 // max distance DCA between 2 tracks cut
3700 // maxDist = TMath::Min(kMaxDist,kMaxDist0+pvertex->GetRr()*kMaxDist);
3702 const Float_t kMaxDist0 = 0.1;
3703 const Float_t kMaxDist1 = 0.1;
3704 const Float_t kMaxDist = 1;
3705 const Float_t kMinPointAngle = 0.85;
3706 const Float_t kMinPointAngle2 = 0.99;
3707 const Float_t kMinR = 0.5;
3708 const Float_t kMaxR = 220;
3709 //const Float_t kCausality0Cut = 0.19;
3710 //const Float_t kLikelihood01Cut = 0.25;
3711 //const Float_t kPointAngleCut = 0.9996;
3712 const Float_t kCausality0Cut = 0.19;
3713 const Float_t kLikelihood01Cut = 0.45;
3714 const Float_t kLikelihood1Cut = 0.5;
3715 const Float_t kCombinedCut = 0.55;
3719 TTreeSRedirector &cstream = *fDebugStreamer;
3720 Int_t ntracks = event->GetNumberOfTracks();
3721 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3722 fOriginal.Expand(ntracks);
3723 fTrackHypothesys.Expand(ntracks);
3724 fBestHypothesys.Expand(ntracks);
3726 AliHelix * helixes = new AliHelix[ntracks+2];
3727 TObjArray trackarray(ntracks+2); //array with tracks - with vertex constrain
3728 TObjArray trackarrayc(ntracks+2); //array of "best tracks" - without vertex constrain
3729 TObjArray trackarrayl(ntracks+2); //array of "longest tracks" - without vertex constrain
3730 Bool_t * forbidden = new Bool_t [ntracks+2];
3731 Int_t *itsmap = new Int_t [ntracks+2];
3732 Float_t *dist = new Float_t[ntracks+2];
3733 Float_t *normdist0 = new Float_t[ntracks+2];
3734 Float_t *normdist1 = new Float_t[ntracks+2];
3735 Float_t *normdist = new Float_t[ntracks+2];
3736 Float_t *norm = new Float_t[ntracks+2];
3737 Float_t *maxr = new Float_t[ntracks+2];
3738 Float_t *minr = new Float_t[ntracks+2];
3739 Float_t *minPointAngle= new Float_t[ntracks+2];
3741 AliV0 *pvertex = new AliV0;
3742 AliITStrackMI * dummy= new AliITStrackMI;
3744 AliITStrackMI trackat0; //temporary track for DCA calculation
3746 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
3748 // make ITS - ESD map
3750 for (Int_t itrack=0;itrack<ntracks+2;itrack++) {
3751 itsmap[itrack] = -1;
3752 forbidden[itrack] = kFALSE;
3753 maxr[itrack] = kMaxR;
3754 minr[itrack] = kMinR;
3755 minPointAngle[itrack] = kMinPointAngle;
3757 for (Int_t itrack=0;itrack<nitstracks;itrack++){
3758 AliITStrackMI * original = (AliITStrackMI*)(fOriginal.At(itrack));
3759 Int_t esdindex = original->GetESDtrack()->GetID();
3760 itsmap[esdindex] = itrack;
3763 // create ITS tracks from ESD tracks if not done before
3765 for (Int_t itrack=0;itrack<ntracks;itrack++){
3766 if (itsmap[itrack]>=0) continue;
3767 AliITStrackMI * tpctrack = new AliITStrackMI(*(event->GetTrack(itrack)));
3768 //tpctrack->fD[0] = tpctrack->GetD(GetX(),GetY());
3769 //tpctrack->fD[1] = tpctrack->GetZat(GetX())-GetZ();
3770 tpctrack->GetDZ(GetX(),GetY(),GetZ(),tpctrack->GetDP()); //I.B.
3771 if (tpctrack->GetD(0)<20 && tpctrack->GetD(1)<20){
3772 // tracks which can reach inner part of ITS
3773 // propagate track to outer its volume - with correction for material
3774 CorrectForTPCtoITSDeadZoneMaterial(tpctrack);
3776 itsmap[itrack] = nitstracks;
3777 fOriginal.AddAt(tpctrack,nitstracks);
3781 // fill temporary arrays
3783 for (Int_t itrack=0;itrack<ntracks;itrack++){
3784 AliESDtrack * esdtrack = event->GetTrack(itrack);
3785 Int_t itsindex = itsmap[itrack];
3786 AliITStrackMI *original = (AliITStrackMI*)fOriginal.At(itsmap[itrack]);
3787 if (!original) continue;
3788 AliITStrackMI *bestConst = 0;
3789 AliITStrackMI *bestLong = 0;
3790 AliITStrackMI *best = 0;
3793 TObjArray * array = (TObjArray*) fTrackHypothesys.At(itsindex);
3794 Int_t hentries = (array==0) ? 0 : array->GetEntriesFast();
3795 // Get best track with vertex constrain
3796 for (Int_t ih=0;ih<hentries;ih++){
3797 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
3798 if (!trackh->GetConstrain()) continue;
3799 if (!bestConst) bestConst = trackh;
3800 if (trackh->GetNumberOfClusters()>5.0){
3801 bestConst = trackh; // full track - with minimal chi2
3804 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()) continue;
3808 // Get best long track without vertex constrain and best track without vertex constrain
3809 for (Int_t ih=0;ih<hentries;ih++){
3810 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
3811 if (trackh->GetConstrain()) continue;
3812 if (!best) best = trackh;
3813 if (!bestLong) bestLong = trackh;
3814 if (trackh->GetNumberOfClusters()>5.0){
3815 bestLong = trackh; // full track - with minimal chi2
3818 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()) continue;
3823 bestLong = original;
3825 //I.B. trackat0 = *bestLong;
3826 new (&trackat0) AliITStrackMI(*bestLong);
3827 Double_t xx,yy,zz,alpha;
3828 bestLong->GetGlobalXYZat(bestLong->GetX(),xx,yy,zz);
3829 alpha = TMath::ATan2(yy,xx);
3830 trackat0.Propagate(alpha,0);
3831 // calculate normalized distances to the vertex
3833 Float_t ptfac = (1.+100.*TMath::Abs(trackat0.GetC()));
3834 if ( bestLong->GetNumberOfClusters()>3 ){
3835 dist[itsindex] = trackat0.GetY();
3836 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
3837 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
3838 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
3839 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3841 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<6) normdist[itsindex]*=2.;
3842 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<5) normdist[itsindex]*=2.;
3843 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<4) normdist[itsindex]*=2.;
3845 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<6) normdist[itsindex]*=1.5;
3846 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<5) normdist[itsindex]*=1.5;
3850 if (bestConst&&bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5){
3851 dist[itsindex] = bestConst->GetD(0);
3852 norm[itsindex] = bestConst->GetDnorm(0);
3853 normdist0[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
3854 normdist1[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
3855 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3857 dist[itsindex] = trackat0.GetY();
3858 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
3859 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
3860 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
3861 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3862 if (TMath::Abs(trackat0.GetTgl())>1.05){
3863 if (normdist[itsindex]<3) forbidden[itsindex]=kTRUE;
3864 if (normdist[itsindex]>3) {
3865 minr[itsindex] = TMath::Max(Float_t(40.),minr[itsindex]);
3871 //-----------------------------------------------------------
3872 //Forbid primary track candidates -
3874 //treetr->SetAlias("forbidden0","Tr0.fN<4&&Tr1.fN+Tr1.fNDeadZone>4.5");
3875 //treetr->SetAlias("forbidden1","ND<3&&Tr1.fN+Tr1.fNDeadZone>5.5");
3876 //treetr->SetAlias("forbidden2","ND<2&&Tr1.fClIndex[0]>0&&Tr1.fClIndex[0]>0");
3877 //treetr->SetAlias("forbidden3","ND<1&&Tr1.fClIndex[0]>0");
3878 //treetr->SetAlias("forbidden4","ND<4&&Tr1.fNormChi2[0]<2");
3879 //treetr->SetAlias("forbidden5","ND<5&&Tr1.fNormChi2[0]<1");
3880 //-----------------------------------------------------------
3882 if (bestLong->GetNumberOfClusters()<4 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5) forbidden[itsindex]=kTRUE;
3883 if (normdist[itsindex]<3 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>5.5) forbidden[itsindex]=kTRUE;
3884 if (normdist[itsindex]<2 && bestConst->GetClIndex(0)>0 && bestConst->GetClIndex(1)>0 ) forbidden[itsindex]=kTRUE;
3885 if (normdist[itsindex]<1 && bestConst->GetClIndex(0)>0) forbidden[itsindex]=kTRUE;
3886 if (normdist[itsindex]<4 && bestConst->GetNormChi2(0)<2) forbidden[itsindex]=kTRUE;
3887 if (normdist[itsindex]<5 && bestConst->GetNormChi2(0)<1) forbidden[itsindex]=kTRUE;
3888 if (bestConst->GetNormChi2(0)<2.5) {
3889 minPointAngle[itsindex]= 0.9999;
3890 maxr[itsindex] = 10;
3894 //forbid daughter kink candidates
3896 if (esdtrack->GetKinkIndex(0)>0) forbidden[itsindex] = kTRUE;
3897 Bool_t isElectron = kTRUE;
3898 Bool_t isProton = kTRUE;
3900 esdtrack->GetESDpid(pid);
3901 for (Int_t i=1;i<5;i++){
3902 if (pid[0]<pid[i]) isElectron= kFALSE;
3903 if (pid[4]<pid[i]) isProton= kFALSE;
3906 forbidden[itsindex]=kFALSE;
3907 normdist[itsindex]*=-1;
3910 if (normdist[itsindex]>2) forbidden[itsindex]=kFALSE;
3911 normdist[itsindex]*=-1;
3915 // Causality cuts in TPC volume
3917 if (esdtrack->GetTPCdensity(0,10) >0.6) maxr[itsindex] = TMath::Min(Float_t(110),maxr[itsindex]);
3918 if (esdtrack->GetTPCdensity(10,30)>0.6) maxr[itsindex] = TMath::Min(Float_t(120),maxr[itsindex]);
3919 if (esdtrack->GetTPCdensity(20,40)>0.6) maxr[itsindex] = TMath::Min(Float_t(130),maxr[itsindex]);
3920 if (esdtrack->GetTPCdensity(30,50)>0.6) maxr[itsindex] = TMath::Min(Float_t(140),maxr[itsindex]);
3922 if (esdtrack->GetTPCdensity(0,60)<0.4&&bestLong->GetNumberOfClusters()<3) minr[itsindex]=100;
3928 "Tr1.="<<((bestConst)? bestConst:dummy)<<
3930 "Tr3.="<<&trackat0<<
3932 "Dist="<<dist[itsindex]<<
3933 "ND0="<<normdist0[itsindex]<<
3934 "ND1="<<normdist1[itsindex]<<
3935 "ND="<<normdist[itsindex]<<
3936 "Pz="<<primvertex[2]<<
3937 "Forbid="<<forbidden[itsindex]<<
3941 trackarray.AddAt(best,itsindex);
3942 trackarrayc.AddAt(bestConst,itsindex);
3943 trackarrayl.AddAt(bestLong,itsindex);
3944 new (&helixes[itsindex]) AliHelix(*best);
3949 // first iterration of V0 finder
3951 for (Int_t iesd0=0;iesd0<ntracks;iesd0++){
3952 Int_t itrack0 = itsmap[iesd0];
3953 if (forbidden[itrack0]) continue;
3954 AliITStrackMI * btrack0 = (AliITStrackMI*)trackarray.At(itrack0);
3955 if (!btrack0) continue;
3956 if (btrack0->GetSign()>0) continue;
3957 AliITStrackMI *trackc0 = (AliITStrackMI*)trackarrayc.At(itrack0);
3959 for (Int_t iesd1=0;iesd1<ntracks;iesd1++){
3960 Int_t itrack1 = itsmap[iesd1];
3961 if (forbidden[itrack1]) continue;
3963 AliITStrackMI * btrack1 = (AliITStrackMI*)trackarray.At(itrack1);
3964 if (!btrack1) continue;
3965 if (btrack1->GetSign()<0) continue;
3966 Bool_t isGold = kFALSE;
3967 if (TMath::Abs(TMath::Abs(btrack0->GetLabel())-TMath::Abs(btrack1->GetLabel()))==1){
3970 AliITStrackMI *trackc1 = (AliITStrackMI*)trackarrayc.At(itrack1);
3971 AliHelix &h1 = helixes[itrack0];
3972 AliHelix &h2 = helixes[itrack1];
3974 // find linear distance
3979 Double_t phase[2][2],radius[2];
3980 Int_t points = h1.GetRPHIintersections(h2, phase, radius);
3981 if (points==0) continue;
3982 Double_t delta[2]={1000000,1000000};
3984 h1.ParabolicDCA(h2,phase[0][0],phase[0][1],radius[0],delta[0]);
3986 if (radius[1]<rmin) rmin = radius[1];
3987 h1.ParabolicDCA(h2,phase[1][0],phase[1][1],radius[1],delta[1]);
3989 rmin = TMath::Sqrt(rmin);
3990 Double_t distance = 0;
3991 Double_t radiusC = 0;
3993 if (points==1 || delta[0]<delta[1]){
3994 distance = TMath::Sqrt(delta[0]);
3995 radiusC = TMath::Sqrt(radius[0]);
3997 distance = TMath::Sqrt(delta[1]);
3998 radiusC = TMath::Sqrt(radius[1]);
4001 if (radiusC<TMath::Max(minr[itrack0],minr[itrack1])) continue;
4002 if (radiusC>TMath::Min(maxr[itrack0],maxr[itrack1])) continue;
4003 Float_t maxDist = TMath::Min(kMaxDist,Float_t(kMaxDist0+radiusC*kMaxDist1));
4004 if (distance>maxDist) continue;
4005 Float_t pointAngle = h1.GetPointAngle(h2,phase[iphase],primvertex);
4006 if (pointAngle<TMath::Max(minPointAngle[itrack0],minPointAngle[itrack1])) continue;
4009 // Double_t distance = TestV0(h1,h2,pvertex,rmin);
4011 // if (distance>maxDist) continue;
4012 // if (pvertex->GetRr()<kMinR) continue;
4013 // if (pvertex->GetRr()>kMaxR) continue;
4014 AliITStrackMI * track0=btrack0;
4015 AliITStrackMI * track1=btrack1;
4016 // if (pvertex->GetRr()<3.5){
4018 //use longest tracks inside the pipe
4019 track0 = (AliITStrackMI*)trackarrayl.At(itrack0);
4020 track1 = (AliITStrackMI*)trackarrayl.At(itrack1);
4024 pvertex->SetParamN(*track0);
4025 pvertex->SetParamP(*track1);
4026 pvertex->Update(primvertex);
4027 pvertex->SetClusters(track0->ClIndex(),track1->ClIndex()); // register clusters
4029 if (pvertex->GetRr()<kMinR) continue;
4030 if (pvertex->GetRr()>kMaxR) continue;
4031 if (pvertex->GetV0CosineOfPointingAngle()<kMinPointAngle) continue;
4032 //Bo: if (pvertex->GetDist2()>maxDist) continue;
4033 if (pvertex->GetDcaV0Daughters()>maxDist) continue;
4034 //Bo: pvertex->SetLab(0,track0->GetLabel());
4035 //Bo: pvertex->SetLab(1,track1->GetLabel());
4036 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4037 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4039 AliITStrackMI * htrackc0 = trackc0 ? trackc0:dummy;
4040 AliITStrackMI * htrackc1 = trackc1 ? trackc1:dummy;
4044 TObjArray * array0b = (TObjArray*)fBestHypothesys.At(itrack0);
4045 if (!array0b&&pvertex->GetRr()<40 && TMath::Abs(track0->GetTgl())<1.1) {
4046 fCurrentEsdTrack = itrack0;
4047 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack0),itrack0, kFALSE);
4049 TObjArray * array1b = (TObjArray*)fBestHypothesys.At(itrack1);
4050 if (!array1b&&pvertex->GetRr()<40 && TMath::Abs(track1->GetTgl())<1.1) {
4051 fCurrentEsdTrack = itrack1;
4052 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack1),itrack1, kFALSE);
4055 AliITStrackMI * track0b = (AliITStrackMI*)fOriginal.At(itrack0);
4056 AliITStrackMI * track1b = (AliITStrackMI*)fOriginal.At(itrack1);
4057 AliITStrackMI * track0l = (AliITStrackMI*)fOriginal.At(itrack0);
4058 AliITStrackMI * track1l = (AliITStrackMI*)fOriginal.At(itrack1);
4060 Float_t minchi2before0=16;
4061 Float_t minchi2before1=16;
4062 Float_t minchi2after0 =16;
4063 Float_t minchi2after1 =16;
4064 Double_t xrp[3]; pvertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
4065 Int_t maxLayer = GetNearestLayer(xrp); //I.B.
4067 if (array0b) for (Int_t i=0;i<5;i++){
4068 // best track after vertex
4069 AliITStrackMI * btrack = (AliITStrackMI*)array0b->At(i);
4070 if (!btrack) continue;
4071 if (btrack->GetNumberOfClusters()>track0l->GetNumberOfClusters()) track0l = btrack;
4072 // if (btrack->fX<pvertex->GetRr()-2.-0.5/(0.1+pvertex->GetAnglep()[2])) {
4073 if (btrack->GetX()<pvertex->GetRr()-2.) {
4074 if ( (maxLayer>i+2|| (i==0)) && btrack->GetNumberOfClusters()==(6-i)&&i<3){
4077 if (maxLayer<3){ // take prim vertex as additional measurement
4078 if (normdist[itrack0]>0 && htrackc0){
4079 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack0]*normdist[itrack0],16.);
4081 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack0]*normdist[itrack0]+3.),16.);
4085 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4087 if (!btrack->GetClIndex(ilayer)){
4091 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4092 for (Int_t itrack=0;itrack<4;itrack++){
4093 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack0){
4094 sumchi2+=18.; //shared cluster
4098 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4099 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4103 if (sumchi2<minchi2before0) minchi2before0=sumchi2;
4105 continue; //safety space - Geo manager will give exact layer
4108 minchi2after0 = btrack->GetNormChi2(i);
4111 if (array1b) for (Int_t i=0;i<5;i++){
4112 // best track after vertex
4113 AliITStrackMI * btrack = (AliITStrackMI*)array1b->At(i);
4114 if (!btrack) continue;
4115 if (btrack->GetNumberOfClusters()>track1l->GetNumberOfClusters()) track1l = btrack;
4116 // if (btrack->fX<pvertex->GetRr()-2-0.5/(0.1+pvertex->GetAnglep()[2])){
4117 if (btrack->GetX()<pvertex->GetRr()-2){
4118 if ((maxLayer>i+2 || (i==0))&&btrack->GetNumberOfClusters()==(6-i)&&(i<3)){
4121 if (maxLayer<3){ // take prim vertex as additional measurement
4122 if (normdist[itrack1]>0 && htrackc1){
4123 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack1]*normdist[itrack1],16.);
4125 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack1]*normdist[itrack1]+3.),16.);
4129 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4131 if (!btrack->GetClIndex(ilayer)){
4135 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4136 for (Int_t itrack=0;itrack<4;itrack++){
4137 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack1){
4138 sumchi2+=18.; //shared cluster
4142 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4143 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4147 if (sumchi2<minchi2before1) minchi2before1=sumchi2;
4149 continue; //safety space - Geo manager will give exact layer
4152 minchi2after1 = btrack->GetNormChi2(i);
4156 // position resolution - used for DCA cut
4157 Float_t sigmad = track0b->GetSigmaY2()+track0b->GetSigmaZ2()+track1b->GetSigmaY2()+track1b->GetSigmaZ2()+
4158 (track0b->GetX()-pvertex->GetRr())*(track0b->GetX()-pvertex->GetRr())*(track0b->GetSigmaSnp2()+track0b->GetSigmaTgl2())+
4159 (track1b->GetX()-pvertex->GetRr())*(track1b->GetX()-pvertex->GetRr())*(track1b->GetSigmaSnp2()+track1b->GetSigmaTgl2());
4160 sigmad =TMath::Sqrt(sigmad)+0.04;
4161 if (pvertex->GetRr()>50){
4162 Double_t cov0[15],cov1[15];
4163 track0b->GetESDtrack()->GetInnerExternalCovariance(cov0);
4164 track1b->GetESDtrack()->GetInnerExternalCovariance(cov1);
4165 sigmad = cov0[0]+cov0[2]+cov1[0]+cov1[2]+
4166 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov0[5]+cov0[9])+
4167 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov1[5]+cov1[9]);
4168 sigmad =TMath::Sqrt(sigmad)+0.05;
4172 vertex2.SetParamN(*track0b);
4173 vertex2.SetParamP(*track1b);
4174 vertex2.Update(primvertex);
4175 //Bo: if (vertex2.GetDist2()<=pvertex->GetDist2()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4176 if (vertex2.GetDcaV0Daughters()<=pvertex->GetDcaV0Daughters()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4177 pvertex->SetParamN(*track0b);
4178 pvertex->SetParamP(*track1b);
4179 pvertex->Update(primvertex);
4180 pvertex->SetClusters(track0b->ClIndex(),track1b->ClIndex()); // register clusters
4181 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4182 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4184 pvertex->SetDistSigma(sigmad);
4185 //Bo: pvertex->SetDistNorm(pvertex->GetDist2()/sigmad);
4186 pvertex->SetNormDCAPrim(normdist[itrack0],normdist[itrack1]);
4188 // define likelihhod and causalities
4190 Float_t pa0=1, pa1=1, pb0=0.26, pb1=0.26;
4192 Float_t fnorm0 = normdist[itrack0];
4193 if (fnorm0<0) fnorm0*=-3;
4194 Float_t fnorm1 = normdist[itrack1];
4195 if (fnorm1<0) fnorm1*=-3;
4196 if (pvertex->GetAnglep()[2]>0.1 || (pvertex->GetRr()<10.5)&& pvertex->GetAnglep()[2]>0.05 || pvertex->GetRr()<3){
4197 pb0 = TMath::Exp(-TMath::Min(fnorm0,Float_t(16.))/12.);
4198 pb1 = TMath::Exp(-TMath::Min(fnorm1,Float_t(16.))/12.);
4200 pvertex->SetChi2Before(normdist[itrack0]);
4201 pvertex->SetChi2After(normdist[itrack1]);
4202 pvertex->SetNAfter(0);
4203 pvertex->SetNBefore(0);
4205 pvertex->SetChi2Before(minchi2before0);
4206 pvertex->SetChi2After(minchi2before1);
4207 if (pvertex->GetAnglep()[2]>0.1 || ( pvertex->GetRr()<10.5 && pvertex->GetAnglep()[2]>0.05) || pvertex->GetRr()<3){
4208 pb0 = TMath::Exp(-TMath::Min(minchi2before0,Float_t(16))/12.);
4209 pb1 = TMath::Exp(-TMath::Min(minchi2before1,Float_t(16))/12.);
4211 pvertex->SetNAfter(maxLayer);
4212 pvertex->SetNBefore(maxLayer);
4214 if (pvertex->GetRr()<90){
4215 pa0 *= TMath::Min(track0->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4216 pa1 *= TMath::Min(track1->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4218 if (pvertex->GetRr()<20){
4219 pa0 *= (0.2+TMath::Exp(-TMath::Min(minchi2after0,Float_t(16))/8.))/1.2;
4220 pa1 *= (0.2+TMath::Exp(-TMath::Min(minchi2after1,Float_t(16))/8.))/1.2;
4223 pvertex->SetCausality(pb0,pb1,pa0,pa1);
4225 // Likelihood calculations - apply cuts
4227 Bool_t v0OK = kTRUE;
4228 Float_t p12 = pvertex->GetParamP()->GetParameter()[4]*pvertex->GetParamP()->GetParameter()[4];
4229 p12 += pvertex->GetParamN()->GetParameter()[4]*pvertex->GetParamN()->GetParameter()[4];
4230 p12 = TMath::Sqrt(p12); // "mean" momenta
4231 Float_t sigmap0 = 0.0001+0.001/(0.1+pvertex->GetRr());
4232 Float_t sigmap = 0.5*sigmap0*(0.6+0.4*p12); // "resolution: of point angle - as a function of radius and momenta
4234 Float_t causalityA = (1.0-pvertex->GetCausalityP()[0])*(1.0-pvertex->GetCausalityP()[1]);
4235 Float_t causalityB = TMath::Sqrt(TMath::Min(pvertex->GetCausalityP()[2],Double_t(0.7))*
4236 TMath::Min(pvertex->GetCausalityP()[3],Double_t(0.7)));
4238 //Bo: Float_t likelihood0 = (TMath::Exp(-pvertex->GetDistNorm())+0.1) *(pvertex->GetDist2()<0.5)*(pvertex->GetDistNorm()<5);
4239 Float_t lDistNorm = pvertex->GetDcaV0Daughters()/pvertex->GetDistSigma();
4240 Float_t likelihood0 = (TMath::Exp(-lDistNorm)+0.1) *(pvertex->GetDcaV0Daughters()<0.5)*(lDistNorm<5);
4242 Float_t likelihood1 = TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/sigmap)+
4243 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(4.*sigmap))+
4244 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(8.*sigmap))+
4245 0.1*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/0.01);
4247 if (causalityA<kCausality0Cut) v0OK = kFALSE;
4248 if (TMath::Sqrt(likelihood0*likelihood1)<kLikelihood01Cut) v0OK = kFALSE;
4249 if (likelihood1<kLikelihood1Cut) v0OK = kFALSE;
4250 if (TMath::Power(likelihood0*likelihood1*causalityB,0.33)<kCombinedCut) v0OK = kFALSE;
4255 Bool_t gold = TMath::Abs(TMath::Abs(track0->GetLabel())-TMath::Abs(track1->GetLabel()))==1;
4257 "Tr0.="<<track0<< //best without constrain
4258 "Tr1.="<<track1<< //best without constrain
4259 "Tr0B.="<<track0b<< //best without constrain after vertex
4260 "Tr1B.="<<track1b<< //best without constrain after vertex
4261 "Tr0C.="<<htrackc0<< //best with constrain if exist
4262 "Tr1C.="<<htrackc1<< //best with constrain if exist
4263 "Tr0L.="<<track0l<< //longest best
4264 "Tr1L.="<<track1l<< //longest best
4265 "Esd0.="<<track0->GetESDtrack()<< // esd track0 params
4266 "Esd1.="<<track1->GetESDtrack()<< // esd track1 params
4267 "V0.="<<pvertex<< //vertex properties
4268 "V0b.="<<&vertex2<< //vertex properties at "best" track
4269 "ND0="<<normdist[itrack0]<< //normalize distance for track0
4270 "ND1="<<normdist[itrack1]<< //normalize distance for track1
4272 // "RejectBase="<<rejectBase<< //rejection in First itteration
4278 //if (rejectBase) continue;
4280 pvertex->SetStatus(0);
4281 // if (rejectBase) {
4282 // pvertex->SetStatus(-100);
4284 if (pvertex->GetV0CosineOfPointingAngle()>kMinPointAngle2) {
4285 //Bo: pvertex->SetESDindexes(track0->GetESDtrack()->GetID(),track1->GetESDtrack()->GetID());
4286 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());//Bo: consistency 0 for neg
4287 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());//Bo: consistency 1 for pos
4289 // AliV0vertex vertexjuri(*track0,*track1);
4290 // vertexjuri.SetESDindexes(track0->fESDtrack->GetID(),track1->fESDtrack->GetID());
4291 // event->AddV0(&vertexjuri);
4292 pvertex->SetStatus(100);
4294 pvertex->SetOnFlyStatus(kTRUE);
4295 pvertex->ChangeMassHypothesis(kK0Short);
4296 event->AddV0(pvertex);
4302 // delete temporary arrays
4305 delete[] minPointAngle;
4317 //------------------------------------------------------------------------
4318 void AliITStrackerMI::RefitV02(AliESDEvent *event)
4321 //try to refit V0s in the third path of the reconstruction
4323 TTreeSRedirector &cstream = *fDebugStreamer;
4325 Int_t nv0s = event->GetNumberOfV0s();
4326 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
4328 for (Int_t iv0 = 0; iv0<nv0s;iv0++){
4329 AliV0 * v0mi = (AliV0*)event->GetV0(iv0);
4330 if (!v0mi) continue;
4331 Int_t itrack0 = v0mi->GetIndex(0);
4332 Int_t itrack1 = v0mi->GetIndex(1);
4333 AliESDtrack *esd0 = event->GetTrack(itrack0);
4334 AliESDtrack *esd1 = event->GetTrack(itrack1);
4335 if (!esd0||!esd1) continue;
4336 AliITStrackMI tpc0(*esd0);
4337 AliITStrackMI tpc1(*esd1);
4338 Double_t x,y,z; v0mi->GetXYZ(x,y,z); //I.B.
4339 Double_t alpha =TMath::ATan2(y,x); //I.B.
4340 if (v0mi->GetRr()>85){
4341 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4342 v0temp.SetParamN(tpc0);
4343 v0temp.SetParamP(tpc1);
4344 v0temp.Update(primvertex);
4345 if (kFALSE) cstream<<"Refit"<<
4347 "V0refit.="<<&v0temp<<
4351 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4352 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4353 v0mi->SetParamN(tpc0);
4354 v0mi->SetParamP(tpc1);
4355 v0mi->Update(primvertex);
4360 if (v0mi->GetRr()>35){
4361 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4362 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4363 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4364 v0temp.SetParamN(tpc0);
4365 v0temp.SetParamP(tpc1);
4366 v0temp.Update(primvertex);
4367 if (kFALSE) cstream<<"Refit"<<
4369 "V0refit.="<<&v0temp<<
4373 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4374 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4375 v0mi->SetParamN(tpc0);
4376 v0mi->SetParamP(tpc1);
4377 v0mi->Update(primvertex);
4382 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4383 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4384 // if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4385 if (RefitAt(v0mi->GetRr(),&tpc0, v0mi->GetClusters(0)) && RefitAt(v0mi->GetRr(),&tpc1, v0mi->GetClusters(1))){
4386 v0temp.SetParamN(tpc0);
4387 v0temp.SetParamP(tpc1);
4388 v0temp.Update(primvertex);
4389 if (kFALSE) cstream<<"Refit"<<
4391 "V0refit.="<<&v0temp<<
4395 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4396 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4397 v0mi->SetParamN(tpc0);
4398 v0mi->SetParamP(tpc1);
4399 v0mi->Update(primvertex);
4404 //------------------------------------------------------------------------
4405 void AliITStrackerMI::BuildMaterialLUT(TString material) {
4406 //--------------------------------------------------------------------
4407 // Fill a look-up table with mean material
4408 //--------------------------------------------------------------------
4412 Double_t point1[3],point2[3];
4413 Double_t phi,cosphi,sinphi,z;
4414 // 0-5 layers, 6 pipe, 7-8 shields
4415 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 7.5,25.0};
4416 Double_t rmax[9]={ 5.5, 7.3,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
4418 Int_t ifirst=0,ilast=0;
4419 if(material.Contains("Pipe")) {
4421 } else if(material.Contains("Shields")) {
4423 } else if(material.Contains("Layers")) {
4426 Error("BuildMaterialLUT","Wrong layer name\n");
4429 for(Int_t imat=ifirst; imat<=ilast; imat++) {
4430 Double_t param[5]={0.,0.,0.,0.,0.};
4431 for (Int_t i=0; i<n; i++) {
4432 phi = 2.*TMath::Pi()*gRandom->Rndm();
4433 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
4434 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
4435 point1[0] = rmin[imat]*cosphi;
4436 point1[1] = rmin[imat]*sinphi;
4438 point2[0] = rmax[imat]*cosphi;
4439 point2[1] = rmax[imat]*sinphi;
4441 AliTracker::MeanMaterialBudget(point1,point2,mparam);
4442 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
4444 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
4446 fxOverX0Layer[imat] = param[1];
4447 fxTimesRhoLayer[imat] = param[0]*param[4];
4448 } else if(imat==6) {
4449 fxOverX0Pipe = param[1];
4450 fxTimesRhoPipe = param[0]*param[4];
4451 } else if(imat==7) {
4452 fxOverX0Shield[0] = param[1];
4453 fxTimesRhoShield[0] = param[0]*param[4];
4454 } else if(imat==8) {
4455 fxOverX0Shield[1] = param[1];
4456 fxTimesRhoShield[1] = param[0]*param[4];
4460 printf("%s\n",material.Data());
4461 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
4462 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
4463 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
4464 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
4465 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
4466 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
4467 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
4468 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
4469 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
4473 //------------------------------------------------------------------------
4474 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
4475 TString direction) {
4476 //-------------------------------------------------------------------
4477 // Propagate beyond beam pipe and correct for material
4478 // (material budget in different ways according to fUseTGeo value)
4479 //-------------------------------------------------------------------
4481 // Define budget mode:
4482 // 0: material from AliITSRecoParam (hard coded)
4483 // 1: material from TGeo (on the fly)
4484 // 2: material from lut
4485 // 3: material from TGeo (same for all hypotheses)
4498 if(fTrackingPhase.Contains("Clusters2Tracks"))
4499 { mode=3; } else { mode=1; }
4502 if(fTrackingPhase.Contains("Clusters2Tracks"))
4503 { mode=3; } else { mode=2; }
4509 if(fTrackingPhase.Contains("Default")) mode=0;
4511 Int_t index=fCurrentEsdTrack;
4513 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4514 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4515 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4517 Double_t xOverX0,x0,lengthTimesMeanDensity;
4518 Bool_t anglecorr=kTRUE;
4522 xOverX0 = AliITSRecoParam::GetdPipe();
4523 x0 = AliITSRecoParam::GetX0Be();
4524 lengthTimesMeanDensity = xOverX0*x0;
4527 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4531 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4532 xOverX0 = fxOverX0Pipe;
4533 lengthTimesMeanDensity = fxTimesRhoPipe;
4536 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4537 if(fxOverX0PipeTrks[index]<0) {
4538 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4539 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4540 (1.-t->GetSnp()*t->GetSnp()));
4541 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4542 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4545 xOverX0 = fxOverX0PipeTrks[index];
4546 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4550 lengthTimesMeanDensity *= dir;
4552 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4553 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4557 //------------------------------------------------------------------------
4558 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4560 TString direction) {
4561 //-------------------------------------------------------------------
4562 // Propagate beyond SPD or SDD shield and correct for material
4563 // (material budget in different ways according to fUseTGeo value)
4564 //-------------------------------------------------------------------
4566 // Define budget mode:
4567 // 0: material from AliITSRecoParam (hard coded)
4568 // 1: material from TGeo (on the fly)
4569 // 2: material from lut
4570 // 3: material from TGeo (same for all hypotheses)
4583 if(fTrackingPhase.Contains("Clusters2Tracks"))
4584 { mode=3; } else { mode=1; }
4587 if(fTrackingPhase.Contains("Clusters2Tracks"))
4588 { mode=3; } else { mode=2; }
4594 if(fTrackingPhase.Contains("Default")) mode=0;
4596 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4598 Int_t shieldindex=0;
4599 if (shield.Contains("SDD")) { // SDDouter
4600 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4602 } else if (shield.Contains("SPD")) { // SPDouter
4603 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4606 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4609 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4611 Int_t index=2*fCurrentEsdTrack+shieldindex;
4613 Double_t xOverX0,x0,lengthTimesMeanDensity;
4614 Bool_t anglecorr=kTRUE;
4618 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4619 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4620 lengthTimesMeanDensity = xOverX0*x0;
4623 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4627 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4628 xOverX0 = fxOverX0Shield[shieldindex];
4629 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4632 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4633 if(fxOverX0ShieldTrks[index]<0) {
4634 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4635 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4636 (1.-t->GetSnp()*t->GetSnp()));
4637 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4638 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4641 xOverX0 = fxOverX0ShieldTrks[index];
4642 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4646 lengthTimesMeanDensity *= dir;
4648 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4649 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4653 //------------------------------------------------------------------------
4654 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4656 Double_t oldGlobXYZ[3],
4657 TString direction) {
4658 //-------------------------------------------------------------------
4659 // Propagate beyond layer and correct for material
4660 // (material budget in different ways according to fUseTGeo value)
4661 //-------------------------------------------------------------------
4663 // Define budget mode:
4664 // 0: material from AliITSRecoParam (hard coded)
4665 // 1: material from TGeo (on the fly)
4666 // 2: material from lut
4667 // 3: material from TGeo (same for all hypotheses)
4680 if(fTrackingPhase.Contains("Clusters2Tracks"))
4681 { mode=3; } else { mode=1; }
4684 if(fTrackingPhase.Contains("Clusters2Tracks"))
4685 { mode=3; } else { mode=2; }
4691 if(fTrackingPhase.Contains("Default")) mode=0;
4693 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4695 Double_t r=fgLayers[layerindex].GetR();
4696 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4698 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4699 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4701 Int_t index=6*fCurrentEsdTrack+layerindex;
4703 // Bring the track beyond the material
4704 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4705 Double_t globXYZ[3];
4708 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4710 Bool_t anglecorr=kTRUE;
4714 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4715 lengthTimesMeanDensity = xOverX0*x0;
4718 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4719 if(mparam[1]>900000) return 0;
4721 lengthTimesMeanDensity=mparam[0]*mparam[4];
4725 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4726 xOverX0 = fxOverX0Layer[layerindex];
4727 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4730 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4731 if(fxOverX0LayerTrks[index]<0) {
4732 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4733 if(mparam[1]>900000) return 0;
4734 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4735 (1.-t->GetSnp()*t->GetSnp()));
4736 xOverX0=mparam[1]/angle;
4737 lengthTimesMeanDensity=mparam[0]*mparam[4]/angle;
4738 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0);
4739 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity);
4741 xOverX0 = fxOverX0LayerTrks[index];
4742 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4746 lengthTimesMeanDensity *= dir;
4748 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4752 //------------------------------------------------------------------------
4753 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4754 //-----------------------------------------------------------------
4755 // Initialize LUT for storing material for each prolonged track
4756 //-----------------------------------------------------------------
4757 fxOverX0PipeTrks = new Float_t[ntracks];
4758 fxTimesRhoPipeTrks = new Float_t[ntracks];
4759 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4760 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4761 fxOverX0LayerTrks = new Float_t[ntracks*6];
4762 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4764 for(Int_t i=0; i<ntracks; i++) {
4765 fxOverX0PipeTrks[i] = -1.;
4766 fxTimesRhoPipeTrks[i] = -1.;
4768 for(Int_t j=0; j<ntracks*2; j++) {
4769 fxOverX0ShieldTrks[j] = -1.;
4770 fxTimesRhoShieldTrks[j] = -1.;
4772 for(Int_t k=0; k<ntracks*6; k++) {
4773 fxOverX0LayerTrks[k] = -1.;
4774 fxTimesRhoLayerTrks[k] = -1.;
4781 //------------------------------------------------------------------------
4782 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4783 //-----------------------------------------------------------------
4784 // Delete LUT for storing material for each prolonged track
4785 //-----------------------------------------------------------------
4786 if(fxOverX0PipeTrks) {
4787 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4789 if(fxOverX0ShieldTrks) {
4790 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4793 if(fxOverX0LayerTrks) {
4794 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4796 if(fxTimesRhoPipeTrks) {
4797 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4799 if(fxTimesRhoShieldTrks) {
4800 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4802 if(fxTimesRhoLayerTrks) {
4803 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4807 //------------------------------------------------------------------------
4808 Int_t AliITStrackerMI::CheckSkipLayer(AliITStrackMI *track,
4809 Int_t ilayer,Int_t idet) const {
4810 //-----------------------------------------------------------------
4811 // This method is used to decide whether to allow a prolongation
4812 // without clusters, because we want to skip the layer.
4813 // In this case the return value is > 0:
4814 // return 1: the user requested to skip a layer
4815 // return 2: track outside z acceptance of SSD/SDD and will cross both SPD
4816 //-----------------------------------------------------------------
4818 if (AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) return 1;
4820 if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4821 // check if track will cross SPD outer layer
4822 Double_t phiAtSPD2,zAtSPD2;
4823 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4824 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4830 //------------------------------------------------------------------------
4831 Int_t AliITStrackerMI::CheckDeadZone(/*AliITStrackMI *track,*/
4832 Int_t ilayer,Int_t idet,
4833 Double_t zmin,Double_t zmax/*,Double_t ymin,Double_t ymax*/) const {
4834 //-----------------------------------------------------------------
4835 // This method is used to decide whether to allow a prolongation
4836 // without clusters, because there is a dead zone in the road.
4837 // In this case the return value is > 0:
4838 // return 1: dead zone at z=0,+-7cm in SPD
4839 // return 2: dead area from the OCDB // NOT YET IMPLEMENTED
4840 //-----------------------------------------------------------------
4842 // check dead zones at z=0,+-7cm in the SPD
4843 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4844 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4845 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4846 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4847 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4848 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4849 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4850 for (Int_t i=0; i<3; i++)
4851 if (zmin<zmaxdead[i] && zmax>zmindead[i]) return 1;
4854 // check dead zones from OCDB
4855 if (!AliITSReconstructor::GetRecoParam()->GetUseDeadZonesFromOCDB()) return 0;
4857 if(idet<0) return 0;
4859 // look in OCDB (only entire dead modules for the moment)
4860 if (ilayer==0 || ilayer==1) { // SPD
4861 AliCDBEntry* cdbEntry = AliCDBManager::Instance()->Get("ITS/Calib/SPDDead");
4863 Error("CheckDeadZone","Cannot get CDB entry for SPD\n");
4866 TObjArray* spdEntry = (TObjArray*)cdbEntry->GetObject();
4868 Error("CheckDeadZone","Cannot get CDB entry for SPD\n");
4871 if(ilayer==1) idet += AliITSgeomTGeo::GetNLadders(1)*AliITSgeomTGeo::GetNDetectors(1);
4872 //printf("SPD det: %d\n",idet);
4873 AliITSCalibrationSPD *calibSPD = (AliITSCalibrationSPD*)spdEntry->At(idet);
4874 if (calibSPD->IsBad()) return 2;
4875 } else if (ilayer==2 || ilayer==3) { // SDD
4876 AliCDBEntry* cdbEntry = AliCDBManager::Instance()->Get("ITS/Calib/CalibSDD");
4878 Error("CheckDeadZone","Cannot get CDB entry for SDD\n");
4881 TObjArray* sddEntry = (TObjArray*)cdbEntry->GetObject();
4883 Error("CheckDeadZone","Cannot get CDB entry for SDD\n");
4886 if(ilayer==3) idet += AliITSgeomTGeo::GetNLadders(3)*AliITSgeomTGeo::GetNDetectors(3);
4887 //printf("SDD det: %d\n",idet);
4888 AliITSCalibrationSDD *calibSDD = (AliITSCalibrationSDD*)sddEntry->At(idet);
4889 if (calibSDD->IsDead()) return 2;
4890 } else if (ilayer==4 || ilayer==5) { // SSD
4892 Error("CheckDeadZone","Wrong layer number\n");
4893 if(ilayer==5) idet += AliITSgeomTGeo::GetNLadders(5)*AliITSgeomTGeo::GetNDetectors(5);
4899 //------------------------------------------------------------------------
4900 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4901 AliITStrackMI *track,
4902 Float_t &xloc,Float_t &zloc) const {
4903 //-----------------------------------------------------------------
4904 // Gives position of track in local module ref. frame
4905 //-----------------------------------------------------------------
4910 if(idet<0) return kFALSE;
4912 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4914 Int_t lad = Int_t(idet/ndet) + 1;
4916 Int_t det = idet - (lad-1)*ndet + 1;
4918 Double_t xyzGlob[3],xyzLoc[3];
4920 track->GetXYZ(xyzGlob);
4922 AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc);
4924 xloc = (Float_t)xyzLoc[0];
4925 zloc = (Float_t)xyzLoc[2];
4929 //------------------------------------------------------------------------
4930 Bool_t AliITStrackerMI::IsOKForPlaneEff(AliITStrackMI* track, Int_t ilayer) const {
4931 // Method still to be implemented:
4933 // it will apply a pre-selection to obtain good quality tracks.
4934 // Here also you will have the possibility to put a control on the
4935 // impact point of the track on the basic block, in order to exclude border regions
4936 // this will be done by calling a proper method of the AliITSPlaneEff class.
4938 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4939 // output: Bool_t -> kTRUE 2f usable track, kFALSE if not usable.
4940 AliITSlayer &layer=fgLayers[ilayer];
4941 Double_t r=layer.GetR();
4942 //AliITStrackV2 tmp(*track);
4943 AliITStrackMI tmp(*track);
4947 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4948 Int_t idet=layer.FindDetectorIndex(phi,z);
4949 if(idet<0) { AliInfo(Form("cannot find detector"));
4952 // here check if it has good Chi Square.
4954 //propagate to the intersection with the detector plane
4955 const AliITSdetector &det=layer.GetDetector(idet);
4956 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4960 LocalModuleCoord(ilayer,idet,&tmp,locx,locz);
4961 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4962 if(key>fPlaneEff->Nblock()) return kFALSE;
4963 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4964 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4965 // transform Local boundaries of the basic block into Global (i.e. tracking) coordinate
4967 Double_t a1[3]={blockXmn,0.,blockZmn};
4968 Double_t a2[3]={blockXmx,0.,blockZmn};
4969 Double_t a3[3]={blockXmn,0.,blockZmx};
4970 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4971 Int_t lad = Int_t(idet/ndet) + 1;
4972 Int_t hdet = idet - (lad-1)*ndet + 1;
4973 AliITSgeomTGeo::LocalToGlobal(ilayer+1,lad,hdet,a1,a1);
4974 AliITSgeomTGeo::LocalToGlobal(ilayer+1,lad,hdet,a2,a2);
4975 AliITSgeomTGeo::LocalToGlobal(ilayer+1,lad,hdet,a3,a3);
4976 Double_t gBlockYmn,gBlockYmx,gBlockZmn,gBlockZmx;
4977 if(a1[1]>a2[1]) {gBlockYmn=a2[1]; gBlockYmx=a1[1];}
4978 else {gBlockYmn=a1[1]; gBlockYmx=a2[1];}
4979 if(a2[2]>a3[2]) {gBlockZmn=a2[2]; gBlockZmx=a3[2];}
4980 else {gBlockZmn=a3[2]; gBlockZmx=a2[2];}
4983 // DEFINITION OF SEARCH ROAD FOR accepting a track
4985 //For the time being they are hard-wired, later on from AliITSRecoParam
4986 Double_t dz=4.*TMath::Sqrt(tmp.GetSigmaZ2());
4987 Double_t dy=4.*TMath::Sqrt(tmp.GetSigmaY2());
4989 // exclude tracks at boundary between detectors
4990 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
4991 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4992 if ( (tmp.GetY()-dy < gBlockYmn+boundaryWidth) ||
4993 (tmp.GetY()+dy > gBlockYmx-boundaryWidth) ||
4994 (tmp.GetZ()-dz < gBlockZmn+boundaryWidth) ||
4995 (tmp.GetZ()+dz > gBlockZmx-boundaryWidth) ) return kFALSE;
4999 //------------------------------------------------------------------------
5000 void AliITStrackerMI::UseTrackForPlaneEff(AliITStrackMI* track, Int_t ilayer) {
5002 // This Method has to be optimized! For the time-being it uses the same criteria
5003 // as those used in the search of extra clusters for overlapping modules.
5005 // Method Purpose: estabilish whether a track has produced a recpoint or not
5006 // in the layer under study (For Plane efficiency)
5008 // inputs: AliITStrackMI* track (pointer to a usable track)
5010 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
5011 // traversed by this very track. In details:
5012 // - if a cluster can be associated to the track then call
5013 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
5014 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
5016 AliITSlayer &layer=fgLayers[ilayer];
5017 Double_t r=layer.GetR();
5018 //AliITStrackV2 tmp(*track);
5019 AliITStrackMI tmp(*track);
5023 if (!tmp.GetPhiZat(r,phi,z)) return;
5024 Int_t idet=layer.FindDetectorIndex(phi,z);
5026 if(idet<0) { AliInfo(Form("cannot find detector"));
5029 //Double_t trackGlobXYZ1[3];
5030 //tmp.GetXYZ(trackGlobXYZ1);
5032 //propagate to the intersection with the detector plane
5033 const AliITSdetector &det=layer.GetDetector(idet);
5034 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
5036 //Float_t xloc,zloc;
5039 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
5041 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
5042 TMath::Sqrt(tmp.GetSigmaZ2() +
5043 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5044 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5045 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
5046 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
5047 TMath::Sqrt(tmp.GetSigmaY2() +
5048 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5049 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5050 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
5052 // road in global (rphi,z) [i.e. in tracking ref. system]
5053 Double_t zmin = tmp.GetZ() - dz;
5054 Double_t zmax = tmp.GetZ() + dz;
5055 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
5056 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
5058 // select clusters in road
5059 layer.SelectClusters(zmin,zmax,ymin,ymax);
5061 // Define criteria for track-cluster association
5062 Double_t msz = tmp.GetSigmaZ2() +
5063 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5064 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5065 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
5066 Double_t msy = tmp.GetSigmaY2() +
5067 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5068 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5069 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
5070 if (tmp.GetConstrain()) {
5071 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
5072 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
5074 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
5075 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
5077 msz = 1./msz; // 1/RoadZ^2
5078 msy = 1./msy; // 1/RoadY^2
5081 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
5083 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
5084 //Double_t tolerance=0.2;
5085 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
5086 idetc = cl->GetDetectorIndex();
5087 if(idet!=idetc) continue;
5088 //Int_t ilay = cl->GetLayer();
5090 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
5091 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
5093 Double_t chi2=tmp.GetPredictedChi2(cl);
5094 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
5098 LocalModuleCoord(ilayer,idet,&tmp,locx,locz);
5100 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
5101 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5102 if(key>fPlaneEff->Nblock()) return;
5103 Bool_t found=kFALSE;
5105 while ((cl=layer.GetNextCluster(clidx))!=0) {
5106 idetc = cl->GetDetectorIndex();
5107 if(idet!=idetc) continue;
5108 // here real control to see whether the cluster can be associated to the track.
5109 // cluster not associated to track
5110 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
5111 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
5112 // calculate track-clusters chi2
5113 Double_t chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
5114 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
5116 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
5118 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
5119 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
5120 // track->SetExtraModule(ilayer,idetExtra);
5122 if(!fPlaneEff->UpDatePlaneEff(found,key))
5123 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));