1 /**************************************************************************
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 //-------------------------------------------------------------------------
18 // Implementation of the ITS tracker class
19 // It reads AliITSRecPoint clusters and creates AliITStrackMI tracks
20 // and fills with them the ESD
21 // Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch
22 // Current support and development:
23 // Andrea Dainese, andrea.dainese@lnl.infn.it
24 // dE/dx analysis by: Boris Batyunya, JINR, Boris.Batiounia@cern.ch
25 // Params moved to AliITSRecoParam by: Andrea Dainese, INFN
26 // Material budget from TGeo by: Ludovic Gaudichet & Andrea Dainese, INFN
27 //-------------------------------------------------------------------------
31 #include <TTreeStream.h>
32 #include <TDatabasePDG.h>
37 #include "AliESDEvent.h"
38 #include "AliESDtrack.h"
39 #include "AliESDVertex.h"
42 #include "AliITSRecPoint.h"
43 #include "AliITSgeomTGeo.h"
44 #include "AliITSReconstructor.h"
45 #include "AliTrackPointArray.h"
46 #include "AliAlignObj.h"
47 #include "AliITSClusterParam.h"
48 #include "AliCDBManager.h"
49 #include "AliCDBEntry.h"
50 #include "AliITSsegmentation.h"
51 #include "AliITSCalibration.h"
52 #include "AliITSCalibrationSPD.h"
53 #include "AliITSCalibrationSDD.h"
54 #include "AliITSCalibrationSSD.h"
55 #include "AliITSPlaneEff.h"
56 #include "AliITSPlaneEffSPD.h"
57 #include "AliITSPlaneEffSDD.h"
58 #include "AliITSPlaneEffSSD.h"
59 #include "AliITStrackerMI.h"
61 ClassImp(AliITStrackerMI)
63 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
65 AliITStrackerMI::AliITStrackerMI():AliTracker(),
75 fLastLayerToTrackTo(0),
78 fTrackingPhase("Default"),
84 fxTimesRhoPipeTrks(0),
85 fxOverX0ShieldTrks(0),
86 fxTimesRhoShieldTrks(0),
88 fxTimesRhoLayerTrks(0),
95 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
96 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
97 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
99 //------------------------------------------------------------------------
100 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
101 fI(AliITSgeomTGeo::GetNLayers()),
110 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
113 fTrackingPhase("Default"),
119 fxTimesRhoPipeTrks(0),
120 fxOverX0ShieldTrks(0),
121 fxTimesRhoShieldTrks(0),
122 fxOverX0LayerTrks(0),
123 fxTimesRhoLayerTrks(0),
125 fITSChannelStatus(0),
128 //--------------------------------------------------------------------
129 //This is the AliITStrackerMI constructor
130 //--------------------------------------------------------------------
132 AliWarning("\"geom\" is actually a dummy argument !");
138 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
139 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
140 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
142 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
143 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
144 Double_t poff=TMath::ATan2(y,x);
146 Double_t r=TMath::Sqrt(x*x + y*y);
148 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
149 r += TMath::Sqrt(x*x + y*y);
150 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
151 r += TMath::Sqrt(x*x + y*y);
152 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
153 r += TMath::Sqrt(x*x + y*y);
156 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
158 for (Int_t j=1; j<nlad+1; j++) {
159 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
160 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
161 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
163 Double_t txyz[3]={0.};
164 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
165 m.LocalToMaster(txyz,xyz);
166 r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
167 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
169 if (phi<0) phi+=TMath::TwoPi();
170 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
172 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
173 new(&det) AliITSdetector(r,phi);
174 // compute the real radius (with misalignment)
175 TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
177 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
178 mmisal.LocalToMaster(txyz,xyz);
179 Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
180 det.SetRmisal(rmisal);
182 } // end loop on detectors
183 } // end loop on ladders
184 } // end loop on layers
187 fI=AliITSgeomTGeo::GetNLayers();
190 fConstraint[0]=1; fConstraint[1]=0;
192 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
193 AliITSReconstructor::GetRecoParam()->GetYVdef(),
194 AliITSReconstructor::GetRecoParam()->GetZVdef()};
195 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
196 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
197 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
198 SetVertex(xyzVtx,ersVtx);
200 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=AliITSRecoParam::GetLayersNotToSkip(i);
201 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
202 for (Int_t i=0;i<100000;i++){
203 fBestTrackIndex[i]=0;
206 // store positions of centre of SPD modules (in z)
208 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
209 fSPDdetzcentre[0] = tr[2];
210 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
211 fSPDdetzcentre[1] = tr[2];
212 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
213 fSPDdetzcentre[2] = tr[2];
214 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
215 fSPDdetzcentre[3] = tr[2];
217 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
218 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
219 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
223 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
224 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
226 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
228 // only for plane efficiency evaluation
229 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff()) {
230 for(Int_t ilay=0;ilay<6;ilay++) {
231 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilay)) {
232 if (ilay<2) fPlaneEff = new AliITSPlaneEffSPD();
233 else if (ilay<4) fPlaneEff = new AliITSPlaneEffSDD();
234 else fPlaneEff = new AliITSPlaneEffSSD();
235 break; // only one layer type to skip at once
238 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
239 if(!fPlaneEff->ReadFromCDB())
240 {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
241 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
242 fPlaneEff->SetCreateHistos(kTRUE);
243 //fPlaneEff->ReadHistosFromFile();
247 //------------------------------------------------------------------------
248 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
250 fBestTrack(tracker.fBestTrack),
251 fTrackToFollow(tracker.fTrackToFollow),
252 fTrackHypothesys(tracker.fTrackHypothesys),
253 fBestHypothesys(tracker.fBestHypothesys),
254 fOriginal(tracker.fOriginal),
255 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
256 fPass(tracker.fPass),
257 fAfterV0(tracker.fAfterV0),
258 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
259 fCoefficients(tracker.fCoefficients),
261 fTrackingPhase(tracker.fTrackingPhase),
262 fUseTGeo(tracker.fUseTGeo),
263 fNtracks(tracker.fNtracks),
264 fxOverX0Pipe(tracker.fxOverX0Pipe),
265 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
267 fxTimesRhoPipeTrks(0),
268 fxOverX0ShieldTrks(0),
269 fxTimesRhoShieldTrks(0),
270 fxOverX0LayerTrks(0),
271 fxTimesRhoLayerTrks(0),
272 fDebugStreamer(tracker.fDebugStreamer),
273 fITSChannelStatus(tracker.fITSChannelStatus),
274 fDetTypeRec(tracker.fDetTypeRec),
275 fPlaneEff(tracker.fPlaneEff) {
279 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
282 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
283 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
286 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
287 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
290 //------------------------------------------------------------------------
291 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
292 //Assignment operator
293 this->~AliITStrackerMI();
294 new(this) AliITStrackerMI(tracker);
297 //------------------------------------------------------------------------
298 AliITStrackerMI::~AliITStrackerMI()
303 if (fCoefficients) delete [] fCoefficients;
304 DeleteTrksMaterialLUT();
305 if (fDebugStreamer) {
306 //fDebugStreamer->Close();
307 delete fDebugStreamer;
309 if(fITSChannelStatus) delete fITSChannelStatus;
310 if(fPlaneEff) delete fPlaneEff;
312 //------------------------------------------------------------------------
313 void AliITStrackerMI::SetLayersNotToSkip(Int_t *l) {
314 //--------------------------------------------------------------------
315 //This function set masks of the layers which must be not skipped
316 //--------------------------------------------------------------------
317 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=l[i];
319 //------------------------------------------------------------------------
320 void AliITStrackerMI::ReadBadFromDetTypeRec() {
321 //--------------------------------------------------------------------
322 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
324 //--------------------------------------------------------------------
326 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
328 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels\n");
330 if(!fDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
333 if(fITSChannelStatus) delete fITSChannelStatus;
334 fITSChannelStatus = new AliITSChannelStatus(AliCDBManager::Instance());
336 // ITS detectors and chips
337 Int_t i=0,j=0,k=0,ndet=0;
338 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
339 ndet=AliITSgeomTGeo::GetNDetectors(i);
340 for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
341 for (k=1; k<ndet+1; k++) {
342 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
343 det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fDetTypeRec);
344 } // end loop on detectors
345 } // end loop on ladders
346 } // end loop on layers
350 //------------------------------------------------------------------------
351 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
352 //--------------------------------------------------------------------
353 //This function loads ITS clusters
354 //--------------------------------------------------------------------
355 TBranch *branch=cTree->GetBranch("ITSRecPoints");
357 Error("LoadClusters"," can't get the branch !\n");
361 static TClonesArray dummy("AliITSRecPoint",10000), *clusters=&dummy;
362 branch->SetAddress(&clusters);
364 Int_t i=0,j=0,ndet=0;
366 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
367 ndet=fgLayers[i].GetNdetectors();
368 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
369 for (; j<jmax; j++) {
370 if (!cTree->GetEvent(j)) continue;
371 Int_t ncl=clusters->GetEntriesFast();
372 SignDeltas(clusters,GetZ());
375 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
376 detector=c->GetDetectorIndex();
378 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
380 fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
383 // add dead zone "virtual" cluster in SPD, if there is a cluster within
384 // zwindow cm from the dead zone
385 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
386 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
387 Int_t lab[4] = {0,0,0,detector};
388 Int_t info[3] = {0,0,i};
389 Float_t q = 0.; // this identifies virtual clusters
390 Float_t hit[5] = {xdead,
392 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
393 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
395 Bool_t local = kTRUE;
396 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
397 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
398 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
399 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
400 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
401 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
402 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
403 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
404 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
405 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
406 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
407 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
408 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
409 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
410 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
411 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
412 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
413 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
414 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
416 } // "virtual" clusters in SPD
420 fgLayers[i].ResetRoad(); //road defined by the cluster density
421 fgLayers[i].SortClusters();
428 //------------------------------------------------------------------------
429 void AliITStrackerMI::UnloadClusters() {
430 //--------------------------------------------------------------------
431 //This function unloads ITS clusters
432 //--------------------------------------------------------------------
433 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
435 //------------------------------------------------------------------------
436 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
437 //--------------------------------------------------------------------
438 // Publishes all pointers to clusters known to the tracker into the
439 // passed object array.
440 // The ownership is not transfered - the caller is not expected to delete
442 //--------------------------------------------------------------------
444 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
445 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
446 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
453 //------------------------------------------------------------------------
454 static Int_t CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
455 //--------------------------------------------------------------------
456 // Correction for the material between the TPC and the ITS
457 //--------------------------------------------------------------------
458 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
459 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
460 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
461 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
462 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
463 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
464 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
465 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
467 Error("CorrectForTPCtoITSDeadZoneMaterial","Track is already in the dead zone !");
473 //------------------------------------------------------------------------
474 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
475 //--------------------------------------------------------------------
476 // This functions reconstructs ITS tracks
477 // The clusters must be already loaded !
478 //--------------------------------------------------------------------
481 fTrackingPhase="Clusters2Tracks";
483 TObjArray itsTracks(15000);
485 fEsd = event; // store pointer to the esd
487 // temporary (for cosmics)
488 if(event->GetVertex()) {
489 TString title = event->GetVertex()->GetTitle();
490 if(title.Contains("cosmics")) {
491 Double_t xyz[3]={GetX(),GetY(),GetZ()};
492 Double_t exyz[3]={0.1,0.1,0.1};
498 {/* Read ESD tracks */
499 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
500 Int_t nentr=event->GetNumberOfTracks();
501 Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
503 AliESDtrack *esd=event->GetTrack(nentr);
505 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
506 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
507 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
508 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
511 t=new AliITStrackMI(*esd);
512 } catch (const Char_t *msg) {
513 //Warning("Clusters2Tracks",msg);
517 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
518 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
521 // look at the ESD mass hypothesys !
522 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
524 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
526 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
527 //track - can be V0 according to TPC
529 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
533 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
537 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
541 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
546 t->SetReconstructed(kFALSE);
547 itsTracks.AddLast(t);
548 fOriginal.AddLast(t);
550 } /* End Read ESD tracks */
554 Int_t nentr=itsTracks.GetEntriesFast();
555 fTrackHypothesys.Expand(nentr);
556 fBestHypothesys.Expand(nentr);
557 MakeCoefficients(nentr);
558 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
560 // THE TWO TRACKING PASSES
561 for (fPass=0; fPass<2; fPass++) {
562 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
563 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
564 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
565 if (t==0) continue; //this track has been already tracked
566 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
567 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
568 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
569 if (fConstraint[fPass]) {
570 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
571 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
574 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
576 ResetTrackToFollow(*t);
579 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
582 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
584 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
585 if (!besttrack) continue;
586 besttrack->SetLabel(tpcLabel);
587 // besttrack->CookdEdx();
589 besttrack->SetFakeRatio(1.);
590 CookLabel(besttrack,0.); //For comparison only
591 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
593 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
595 t->SetReconstructed(kTRUE);
598 GetBestHypothesysMIP(itsTracks);
599 } // end loop on the two tracking passes
601 if(event->GetNumberOfV0s()>0) UpdateTPCV0(event);
602 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) FindV02(event);
607 Int_t entries = fTrackHypothesys.GetEntriesFast();
608 for (Int_t ientry=0; ientry<entries; ientry++) {
609 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
610 if (array) array->Delete();
611 delete fTrackHypothesys.RemoveAt(ientry);
614 fTrackHypothesys.Delete();
615 fBestHypothesys.Delete();
617 delete [] fCoefficients;
619 DeleteTrksMaterialLUT();
621 Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
623 fTrackingPhase="Default";
627 //------------------------------------------------------------------------
628 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
629 //--------------------------------------------------------------------
630 // This functions propagates reconstructed ITS tracks back
631 // The clusters must be loaded !
632 //--------------------------------------------------------------------
633 fTrackingPhase="PropagateBack";
634 Int_t nentr=event->GetNumberOfTracks();
635 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
638 for (Int_t i=0; i<nentr; i++) {
639 AliESDtrack *esd=event->GetTrack(i);
641 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
642 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
646 t=new AliITStrackMI(*esd);
647 } catch (const Char_t *msg) {
648 //Warning("PropagateBack",msg);
652 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
654 ResetTrackToFollow(*t);
656 // propagate to vertex [SR, GSI 17.02.2003]
657 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
658 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
659 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
660 fTrackToFollow.StartTimeIntegral();
661 // from vertex to outside pipe
662 CorrectForPipeMaterial(&fTrackToFollow,"outward");
665 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
666 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
667 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
671 fTrackToFollow.SetLabel(t->GetLabel());
672 //fTrackToFollow.CookdEdx();
673 CookLabel(&fTrackToFollow,0.); //For comparison only
674 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
675 //UseClusters(&fTrackToFollow);
681 Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
683 fTrackingPhase="Default";
687 //------------------------------------------------------------------------
688 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
689 //--------------------------------------------------------------------
690 // This functions refits ITS tracks using the
691 // "inward propagated" TPC tracks
692 // The clusters must be loaded !
693 //--------------------------------------------------------------------
694 fTrackingPhase="RefitInward";
695 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) RefitV02(event);
696 Int_t nentr=event->GetNumberOfTracks();
697 Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
700 for (Int_t i=0; i<nentr; i++) {
701 AliESDtrack *esd=event->GetTrack(i);
703 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
704 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
705 if (esd->GetStatus()&AliESDtrack::kTPCout)
706 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
710 t=new AliITStrackMI(*esd);
711 } catch (const Char_t *msg) {
712 //Warning("RefitInward",msg);
716 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
717 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
722 ResetTrackToFollow(*t);
723 fTrackToFollow.ResetClusters();
725 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
726 fTrackToFollow.ResetCovariance(10.);
729 Bool_t pe=AliITSReconstructor::GetRecoParam()->GetComputePlaneEff();
730 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
731 fTrackToFollow.SetLabel(t->GetLabel());
732 // fTrackToFollow.CookdEdx();
733 CookdEdx(&fTrackToFollow);
735 CookLabel(&fTrackToFollow,0.0); //For comparison only
738 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
739 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
740 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
741 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
742 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
743 Float_t r[3]={0.,0.,0.};
745 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
752 Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
754 fTrackingPhase="Default";
758 //------------------------------------------------------------------------
759 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
760 //--------------------------------------------------------------------
761 // Return pointer to a given cluster
762 //--------------------------------------------------------------------
763 Int_t l=(index & 0xf0000000) >> 28;
764 Int_t c=(index & 0x0fffffff) >> 00;
765 return fgLayers[l].GetCluster(c);
767 //------------------------------------------------------------------------
768 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
769 //--------------------------------------------------------------------
770 // Get track space point with index i
771 //--------------------------------------------------------------------
773 Int_t l=(index & 0xf0000000) >> 28;
774 Int_t c=(index & 0x0fffffff) >> 00;
775 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
776 Int_t idet = cl->GetDetectorIndex();
780 cl->GetGlobalXYZ(xyz);
781 cl->GetGlobalCov(cov);
784 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
787 iLayer = AliGeomManager::kSPD1;
790 iLayer = AliGeomManager::kSPD2;
793 iLayer = AliGeomManager::kSDD1;
796 iLayer = AliGeomManager::kSDD2;
799 iLayer = AliGeomManager::kSSD1;
802 iLayer = AliGeomManager::kSSD2;
805 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
808 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
809 p.SetVolumeID((UShort_t)volid);
812 //------------------------------------------------------------------------
813 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
814 AliTrackPoint& p, const AliESDtrack *t) {
815 //--------------------------------------------------------------------
816 // Get track space point with index i
817 // (assign error estimated during the tracking)
818 //--------------------------------------------------------------------
820 Int_t l=(index & 0xf0000000) >> 28;
821 Int_t c=(index & 0x0fffffff) >> 00;
822 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
823 Int_t idet = cl->GetDetectorIndex();
824 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
826 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
828 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
829 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
830 Double_t alpha = t->GetAlpha();
831 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
832 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,AliTracker::GetBz()));
833 phi += alpha-det.GetPhi();
834 Float_t tgphi = TMath::Tan(phi);
836 Float_t tgl = t->GetTgl(); // tgl about const along track
837 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
839 Float_t errlocalx,errlocalz;
840 Bool_t addMisalErr=kFALSE;
841 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errlocalx,errlocalz,addMisalErr);
845 cl->GetGlobalXYZ(xyz);
846 // cl->GetGlobalCov(cov);
847 Float_t pos[3] = {0.,0.,0.};
848 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errlocalx*errlocalx,errlocalz*errlocalz,0);
849 tmpcl.GetGlobalCov(cov);
853 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
856 iLayer = AliGeomManager::kSPD1;
859 iLayer = AliGeomManager::kSPD2;
862 iLayer = AliGeomManager::kSDD1;
865 iLayer = AliGeomManager::kSDD2;
868 iLayer = AliGeomManager::kSSD1;
871 iLayer = AliGeomManager::kSSD2;
874 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
877 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
878 p.SetVolumeID((UShort_t)volid);
881 //------------------------------------------------------------------------
882 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
884 //--------------------------------------------------------------------
885 // Follow prolongation tree
886 //--------------------------------------------------------------------
888 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
889 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
892 AliESDtrack * esd = otrack->GetESDtrack();
893 if (esd->GetV0Index(0)>0) {
894 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
895 // mapping of ESD track is different as ITS track in Containers
896 // Need something more stable
897 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
898 for (Int_t i=0;i<3;i++){
899 Int_t index = esd->GetV0Index(i);
901 AliESDv0 * vertex = fEsd->GetV0(index);
902 if (vertex->GetStatus()<0) continue; // rejected V0
904 if (esd->GetSign()>0) {
905 vertex->SetIndex(0,esdindex);
907 vertex->SetIndex(1,esdindex);
911 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
913 bestarray = new TObjArray(5);
914 fBestHypothesys.AddAt(bestarray,esdindex);
918 //setup tree of the prolongations
920 static AliITStrackMI tracks[7][100];
921 AliITStrackMI *currenttrack;
922 static AliITStrackMI currenttrack1;
923 static AliITStrackMI currenttrack2;
924 static AliITStrackMI backuptrack;
926 Int_t nindexes[7][100];
927 Float_t normalizedchi2[100];
928 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
929 otrack->SetNSkipped(0);
930 new (&(tracks[6][0])) AliITStrackMI(*otrack);
932 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
933 Int_t modstatus = 1; // found
937 // follow prolongations
938 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
939 //printf("FollowProlongationTree: layer %d\n",ilayer);
942 AliITSlayer &layer=fgLayers[ilayer];
943 Double_t r = layer.GetR();
949 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
951 if (ntracks[ilayer]>=100) break;
952 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
953 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
954 if (ntracks[ilayer]>15+ilayer){
955 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
956 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
959 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
961 // material between SSD and SDD, SDD and SPD
963 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
965 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
969 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
970 Int_t idet=layer.FindDetectorIndex(phi,z);
972 Double_t trackGlobXYZ1[3];
973 currenttrack1.GetXYZ(trackGlobXYZ1);
975 // Get the budget to the primary vertex for the current track being prolonged
976 Double_t budgetToPrimVertex = GetEffectiveThickness();
978 // check if we allow a prolongation without point
979 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
981 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
982 // propagate to the layer radius
983 Double_t xToGo; vtrack->GetLocalXat(r,xToGo);
984 vtrack->AliExternalTrackParam::PropagateTo(xToGo,GetBz());
985 // apply correction for material of the current layer
986 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
987 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
988 vtrack->SetClIndex(ilayer,0);
989 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
990 LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc); // local module coords
991 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
992 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
997 // track outside layer acceptance in z
998 if (idet<0) continue;
1000 //propagate to the intersection with the detector plane
1001 const AliITSdetector &det=layer.GetDetector(idet);
1002 new(¤ttrack2) AliITStrackMI(currenttrack1);
1003 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1004 currenttrack2.Propagate(det.GetPhi(),det.GetR());
1005 currenttrack1.SetDetectorIndex(idet);
1006 currenttrack2.SetDetectorIndex(idet);
1007 LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc); // local module coords
1010 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1012 // road in global (rphi,z) [i.e. in tracking ref. system]
1013 Double_t zmin,zmax,ymin,ymax;
1014 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1016 // select clusters in road
1017 layer.SelectClusters(zmin,zmax,ymin,ymax);
1018 //********************
1020 // Define criteria for track-cluster association
1021 Double_t msz = currenttrack1.GetSigmaZ2() +
1022 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1023 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1024 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1025 Double_t msy = currenttrack1.GetSigmaY2() +
1026 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1027 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1028 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1030 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1031 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1033 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1034 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1036 msz = 1./msz; // 1/RoadZ^2
1037 msy = 1./msy; // 1/RoadY^2
1041 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1043 const AliITSRecPoint *cl=0;
1045 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1046 Bool_t deadzoneSPD=kFALSE;
1047 currenttrack = ¤ttrack1;
1049 // check if the road contains a dead zone
1050 Bool_t noClusters = kFALSE;
1051 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1052 //if (noClusters) printf("no clusters in road\n");
1053 Double_t dz=0.5*(zmax-zmin);
1054 Double_t dy=0.5*(ymax-ymin);
1055 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1056 // create a prolongation without clusters (check also if there are no clusters in the road)
1059 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1060 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1061 updatetrack->SetClIndex(ilayer,0);
1063 modstatus = 5; // no cls in road
1064 } else if (dead==1) {
1065 modstatus = 7; // holes in z in SPD
1066 } else if (dead==2 || dead==3) {
1067 modstatus = 2; // dead from OCDB
1069 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1070 // apply correction for material of the current layer
1071 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1072 if (constrain) { // apply vertex constrain
1073 updatetrack->SetConstrain(constrain);
1074 Bool_t isPrim = kTRUE;
1075 if (ilayer<4) { // check that it's close to the vertex
1076 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1077 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1078 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1079 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1080 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1082 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1085 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1086 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1087 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1095 // loop over clusters in the road
1096 while ((cl=layer.GetNextCluster(clidx))!=0) {
1097 if (ntracks[ilayer]>95) break; //space for skipped clusters
1098 Bool_t changedet =kFALSE;
1099 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
1100 Int_t idetc=cl->GetDetectorIndex();
1102 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1103 // take into account misalignment (bring track to real detector plane)
1104 Double_t xTrOrig = currenttrack->GetX();
1105 currenttrack->PropagateTo(xTrOrig+cl->GetX(),0.,0.);
1106 // a first cut on track-cluster distance
1107 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1108 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1109 { // cluster not associated to track
1110 //printf("not ass\n");
1113 // bring track back to ideal detector plane
1114 currenttrack->PropagateTo(xTrOrig,0.,0.);
1115 } else { // have to move track to cluster's detector
1116 const AliITSdetector &detc=layer.GetDetector(idetc);
1117 // a first cut on track-cluster distance
1119 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1120 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1121 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1122 continue; // cluster not associated to track
1124 new (&backuptrack) AliITStrackMI(currenttrack2);
1126 currenttrack =¤ttrack2;
1127 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1128 new (currenttrack) AliITStrackMI(backuptrack);
1132 currenttrack->SetDetectorIndex(idetc);
1133 // Get again the budget to the primary vertex
1134 // for the current track being prolonged, if had to change detector
1135 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1138 // calculate track-clusters chi2
1139 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1141 //printf("chi2 %f max %f\n",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer));
1142 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1143 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1144 if (ntracks[ilayer]>=100) continue;
1145 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1146 updatetrack->SetClIndex(ilayer,0);
1147 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1149 if (cl->GetQ()!=0) { // real cluster
1150 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1151 //printf("update failed\n");
1154 updatetrack->SetSampledEdx(cl->GetQ(),updatetrack->GetNumberOfClusters()-1); //b.b.
1155 modstatus = 1; // found
1156 } else { // virtual cluster in dead zone
1157 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1158 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1159 modstatus = 7; // holes in z in SPD
1163 Float_t xlocnewdet,zlocnewdet;
1164 LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet); // local module coords
1165 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1167 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1169 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1171 // apply correction for material of the current layer
1172 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1174 if (constrain) { // apply vertex constrain
1175 updatetrack->SetConstrain(constrain);
1176 Bool_t isPrim = kTRUE;
1177 if (ilayer<4) { // check that it's close to the vertex
1178 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1179 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1180 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1181 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1182 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1184 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1185 } //apply vertex constrain
1187 } // create new hypothesis
1188 //else printf("chi2 too large\n");
1189 } // loop over possible prolongations
1191 // allow one prolongation without clusters
1192 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1193 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1194 // apply correction for material of the current layer
1195 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1196 vtrack->SetClIndex(ilayer,0);
1197 modstatus = 3; // skipped
1198 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1199 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1200 vtrack->IncrementNSkipped();
1204 // allow one prolongation without clusters for tracks with |tgl|>1.1
1205 if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) { //big theta - for low flux
1206 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1207 // apply correction for material of the current layer
1208 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1209 vtrack->SetClIndex(ilayer,0);
1210 modstatus = 3; // skipped
1211 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1212 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1213 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1218 } // loop over tracks in layer ilayer+1
1220 //loop over track candidates for the current layer
1226 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1227 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1228 if (normalizedchi2[itrack] <
1229 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1233 if (constrain) { // constrain
1234 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1236 } else { // !constrain
1237 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1242 // sort tracks by increasing normalized chi2
1243 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1244 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1245 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1246 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1247 } // end loop over layers
1251 // Now select tracks to be kept
1253 Int_t max = constrain ? 20 : 5;
1255 // tracks that reach layer 0 (SPD inner)
1256 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1257 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1258 if (track.GetNumberOfClusters()<2) continue;
1259 if (!constrain && track.GetNormChi2(0) >
1260 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1263 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1266 // tracks that reach layer 1 (SPD outer)
1267 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1268 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1269 if (track.GetNumberOfClusters()<4) continue;
1270 if (!constrain && track.GetNormChi2(1) >
1271 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1272 if (constrain) track.IncrementNSkipped();
1274 track.SetD(0,track.GetD(GetX(),GetY()));
1275 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1276 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1277 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1280 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1283 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1285 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1286 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1287 if (track.GetNumberOfClusters()<3) continue;
1288 if (!constrain && track.GetNormChi2(2) >
1289 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1290 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1292 track.SetD(0,track.GetD(GetX(),GetY()));
1293 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1294 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1295 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1298 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1304 // register best track of each layer - important for V0 finder
1306 for (Int_t ilayer=0;ilayer<5;ilayer++){
1307 if (ntracks[ilayer]==0) continue;
1308 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1309 if (track.GetNumberOfClusters()<1) continue;
1310 CookLabel(&track,0);
1311 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1315 // update TPC V0 information
1317 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1318 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1319 for (Int_t i=0;i<3;i++){
1320 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1321 if (index==0) break;
1322 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1323 if (vertex->GetStatus()<0) continue; // rejected V0
1325 if (otrack->GetSign()>0) {
1326 vertex->SetIndex(0,esdindex);
1329 vertex->SetIndex(1,esdindex);
1331 //find nearest layer with track info
1332 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1333 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1334 Int_t nearest = nearestold;
1335 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1336 if (ntracks[nearest]==0){
1341 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1342 if (nearestold<5&&nearest<5){
1343 Bool_t accept = track.GetNormChi2(nearest)<10;
1345 if (track.GetSign()>0) {
1346 vertex->SetParamP(track);
1347 vertex->Update(fprimvertex);
1348 //vertex->SetIndex(0,track.fESDtrack->GetID());
1349 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1351 vertex->SetParamN(track);
1352 vertex->Update(fprimvertex);
1353 //vertex->SetIndex(1,track.fESDtrack->GetID());
1354 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1356 vertex->SetStatus(vertex->GetStatus()+1);
1358 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1365 //------------------------------------------------------------------------
1366 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1368 //--------------------------------------------------------------------
1371 return fgLayers[layer];
1373 //------------------------------------------------------------------------
1374 AliITStrackerMI::AliITSlayer::AliITSlayer():
1399 //--------------------------------------------------------------------
1400 //default AliITSlayer constructor
1401 //--------------------------------------------------------------------
1402 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1403 fClusterWeight[i]=0;
1404 fClusterTracks[0][i]=-1;
1405 fClusterTracks[1][i]=-1;
1406 fClusterTracks[2][i]=-1;
1407 fClusterTracks[3][i]=-1;
1410 //------------------------------------------------------------------------
1411 AliITStrackerMI::AliITSlayer::
1412 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1437 //--------------------------------------------------------------------
1438 //main AliITSlayer constructor
1439 //--------------------------------------------------------------------
1440 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1441 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1443 //------------------------------------------------------------------------
1444 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1446 fPhiOffset(layer.fPhiOffset),
1447 fNladders(layer.fNladders),
1448 fZOffset(layer.fZOffset),
1449 fNdetectors(layer.fNdetectors),
1450 fDetectors(layer.fDetectors),
1455 fClustersCs(layer.fClustersCs),
1456 fClusterIndexCs(layer.fClusterIndexCs),
1460 fCurrentSlice(layer.fCurrentSlice),
1467 fAccepted(layer.fAccepted),
1471 //------------------------------------------------------------------------
1472 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1473 //--------------------------------------------------------------------
1474 // AliITSlayer destructor
1475 //--------------------------------------------------------------------
1476 delete [] fDetectors;
1477 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1478 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1479 fClusterWeight[i]=0;
1480 fClusterTracks[0][i]=-1;
1481 fClusterTracks[1][i]=-1;
1482 fClusterTracks[2][i]=-1;
1483 fClusterTracks[3][i]=-1;
1486 //------------------------------------------------------------------------
1487 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1488 //--------------------------------------------------------------------
1489 // This function removes loaded clusters
1490 //--------------------------------------------------------------------
1491 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1492 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1493 fClusterWeight[i]=0;
1494 fClusterTracks[0][i]=-1;
1495 fClusterTracks[1][i]=-1;
1496 fClusterTracks[2][i]=-1;
1497 fClusterTracks[3][i]=-1;
1503 //------------------------------------------------------------------------
1504 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1505 //--------------------------------------------------------------------
1506 // This function reset weights of the clusters
1507 //--------------------------------------------------------------------
1508 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1509 fClusterWeight[i]=0;
1510 fClusterTracks[0][i]=-1;
1511 fClusterTracks[1][i]=-1;
1512 fClusterTracks[2][i]=-1;
1513 fClusterTracks[3][i]=-1;
1515 for (Int_t i=0; i<fN;i++) {
1516 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1517 if (cl&&cl->IsUsed()) cl->Use();
1521 //------------------------------------------------------------------------
1522 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1523 //--------------------------------------------------------------------
1524 // This function calculates the road defined by the cluster density
1525 //--------------------------------------------------------------------
1527 for (Int_t i=0; i<fN; i++) {
1528 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1530 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1532 //------------------------------------------------------------------------
1533 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1534 //--------------------------------------------------------------------
1535 //This function adds a cluster to this layer
1536 //--------------------------------------------------------------------
1537 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1538 ::Error("InsertCluster","Too many clusters !\n");
1544 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1545 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1546 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1547 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1548 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1552 //------------------------------------------------------------------------
1553 void AliITStrackerMI::AliITSlayer::SortClusters()
1558 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1559 Float_t *z = new Float_t[fN];
1560 Int_t * index = new Int_t[fN];
1562 for (Int_t i=0;i<fN;i++){
1563 z[i] = fClusters[i]->GetZ();
1565 TMath::Sort(fN,z,index,kFALSE);
1566 for (Int_t i=0;i<fN;i++){
1567 clusters[i] = fClusters[index[i]];
1570 for (Int_t i=0;i<fN;i++){
1571 fClusters[i] = clusters[i];
1572 fZ[i] = fClusters[i]->GetZ();
1573 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1574 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1575 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1585 for (Int_t i=0;i<fN;i++){
1586 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1587 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1588 fClusterIndex[i] = i;
1592 fDy5 = (fYB[1]-fYB[0])/5.;
1593 fDy10 = (fYB[1]-fYB[0])/10.;
1594 fDy20 = (fYB[1]-fYB[0])/20.;
1595 for (Int_t i=0;i<6;i++) fN5[i] =0;
1596 for (Int_t i=0;i<11;i++) fN10[i]=0;
1597 for (Int_t i=0;i<21;i++) fN20[i]=0;
1599 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;}
1600 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;}
1601 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;}
1604 for (Int_t i=0;i<fN;i++)
1605 for (Int_t irot=-1;irot<=1;irot++){
1606 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1608 for (Int_t slice=0; slice<6;slice++){
1609 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1610 fClusters5[slice][fN5[slice]] = fClusters[i];
1611 fY5[slice][fN5[slice]] = curY;
1612 fZ5[slice][fN5[slice]] = fZ[i];
1613 fClusterIndex5[slice][fN5[slice]]=i;
1618 for (Int_t slice=0; slice<11;slice++){
1619 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1620 fClusters10[slice][fN10[slice]] = fClusters[i];
1621 fY10[slice][fN10[slice]] = curY;
1622 fZ10[slice][fN10[slice]] = fZ[i];
1623 fClusterIndex10[slice][fN10[slice]]=i;
1628 for (Int_t slice=0; slice<21;slice++){
1629 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1630 fClusters20[slice][fN20[slice]] = fClusters[i];
1631 fY20[slice][fN20[slice]] = curY;
1632 fZ20[slice][fN20[slice]] = fZ[i];
1633 fClusterIndex20[slice][fN20[slice]]=i;
1640 // consistency check
1642 for (Int_t i=0;i<fN-1;i++){
1648 for (Int_t slice=0;slice<21;slice++)
1649 for (Int_t i=0;i<fN20[slice]-1;i++){
1650 if (fZ20[slice][i]>fZ20[slice][i+1]){
1657 //------------------------------------------------------------------------
1658 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1659 //--------------------------------------------------------------------
1660 // This function returns the index of the nearest cluster
1661 //--------------------------------------------------------------------
1664 if (fCurrentSlice<0) {
1673 if (ncl==0) return 0;
1674 Int_t b=0, e=ncl-1, m=(b+e)/2;
1675 for (; b<e; m=(b+e)/2) {
1676 // if (z > fClusters[m]->GetZ()) b=m+1;
1677 if (z > zcl[m]) b=m+1;
1682 //------------------------------------------------------------------------
1683 Bool_t AliITStrackerMI::ComputeRoad(AliITStrackMI* track,Int_t ilayer,Int_t idet,Double_t &zmin,Double_t &zmax,Double_t &ymin,Double_t &ymax) const {
1684 //--------------------------------------------------------------------
1685 // This function computes the rectangular road for this track
1686 //--------------------------------------------------------------------
1689 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1690 // take into account the misalignment: propagate track to misaligned detector plane
1691 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1693 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1694 TMath::Sqrt(track->GetSigmaZ2() +
1695 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1696 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1697 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1698 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1699 TMath::Sqrt(track->GetSigmaY2() +
1700 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1701 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1702 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1704 // track at boundary between detectors, enlarge road
1705 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1706 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1707 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1708 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1709 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1710 Float_t tgl = TMath::Abs(track->GetTgl());
1711 if (tgl > 1.) tgl=1.;
1712 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1713 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1714 Float_t snp = TMath::Abs(track->GetSnp());
1715 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1716 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1719 // add to the road a term (up to 2-3 mm) to deal with misalignments
1720 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1721 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1723 Double_t r = fgLayers[ilayer].GetR();
1724 zmin = track->GetZ() - dz;
1725 zmax = track->GetZ() + dz;
1726 ymin = track->GetY() + r*det.GetPhi() - dy;
1727 ymax = track->GetY() + r*det.GetPhi() + dy;
1729 // bring track back to idead detector plane
1730 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1734 //------------------------------------------------------------------------
1735 void AliITStrackerMI::AliITSlayer::
1736 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1737 //--------------------------------------------------------------------
1738 // This function sets the "window"
1739 //--------------------------------------------------------------------
1741 Double_t circle=2*TMath::Pi()*fR;
1742 fYmin = ymin; fYmax =ymax;
1743 Float_t ymiddle = (fYmin+fYmax)*0.5;
1744 if (ymiddle<fYB[0]) {
1745 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1746 } else if (ymiddle>fYB[1]) {
1747 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1753 fClustersCs = fClusters;
1754 fClusterIndexCs = fClusterIndex;
1760 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1761 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1762 if (slice<0) slice=0;
1763 if (slice>20) slice=20;
1764 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1766 fCurrentSlice=slice;
1767 fClustersCs = fClusters20[fCurrentSlice];
1768 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1769 fYcs = fY20[fCurrentSlice];
1770 fZcs = fZ20[fCurrentSlice];
1771 fNcs = fN20[fCurrentSlice];
1776 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1777 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1778 if (slice<0) slice=0;
1779 if (slice>10) slice=10;
1780 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1782 fCurrentSlice=slice;
1783 fClustersCs = fClusters10[fCurrentSlice];
1784 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1785 fYcs = fY10[fCurrentSlice];
1786 fZcs = fZ10[fCurrentSlice];
1787 fNcs = fN10[fCurrentSlice];
1792 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1793 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1794 if (slice<0) slice=0;
1795 if (slice>5) slice=5;
1796 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1798 fCurrentSlice=slice;
1799 fClustersCs = fClusters5[fCurrentSlice];
1800 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1801 fYcs = fY5[fCurrentSlice];
1802 fZcs = fZ5[fCurrentSlice];
1803 fNcs = fN5[fCurrentSlice];
1807 fI=FindClusterIndex(zmin); fZmax=zmax;
1808 fImax = TMath::Min(FindClusterIndex(zmax)+1,fNcs);
1814 //------------------------------------------------------------------------
1815 Int_t AliITStrackerMI::AliITSlayer::
1816 FindDetectorIndex(Double_t phi, Double_t z) const {
1817 //--------------------------------------------------------------------
1818 //This function finds the detector crossed by the track
1819 //--------------------------------------------------------------------
1821 if (fZOffset<0) // old geometry
1822 dphi = -(phi-fPhiOffset);
1823 else // new geometry
1824 dphi = phi-fPhiOffset;
1827 if (dphi < 0) dphi += 2*TMath::Pi();
1828 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1829 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1830 if (np>=fNladders) np-=fNladders;
1831 if (np<0) np+=fNladders;
1834 Double_t dz=fZOffset-z;
1835 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1836 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1837 if (nz>=fNdetectors) return -1;
1838 if (nz<0) return -1;
1840 // ad hoc correction for 3rd ladder of SDD inner layer,
1841 // which is reversed (rotated by pi around local y)
1842 // this correction is OK only from AliITSv11Hybrid onwards
1843 if (GetR()>12. && GetR()<20.) { // SDD inner
1844 if(np==2) { // 3rd ladder
1845 nz = (fNdetectors-1) - nz;
1848 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1851 return np*fNdetectors + nz;
1853 //------------------------------------------------------------------------
1854 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1856 //--------------------------------------------------------------------
1857 // This function returns clusters within the "window"
1858 //--------------------------------------------------------------------
1860 if (fCurrentSlice<0) {
1861 Double_t rpi2 = 2.*fR*TMath::Pi();
1862 for (Int_t i=fI; i<fImax; i++) {
1864 if (fYmax<y) y -= rpi2;
1865 if (fYmin>y) y += rpi2;
1866 if (y<fYmin) continue;
1867 if (y>fYmax) continue;
1868 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1871 return fClusters[i];
1874 for (Int_t i=fI; i<fImax; i++) {
1875 if (fYcs[i]<fYmin) continue;
1876 if (fYcs[i]>fYmax) continue;
1877 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1878 ci=fClusterIndexCs[i];
1880 return fClustersCs[i];
1885 //------------------------------------------------------------------------
1886 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1888 //--------------------------------------------------------------------
1889 // This function returns the layer thickness at this point (units X0)
1890 //--------------------------------------------------------------------
1892 x0=AliITSRecoParam::GetX0Air();
1893 if (43<fR&&fR<45) { //SSD2
1896 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1897 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1898 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1899 for (Int_t i=0; i<12; i++) {
1900 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1901 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1905 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1906 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1910 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1911 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1914 if (37<fR&&fR<41) { //SSD1
1917 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1918 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1919 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1920 for (Int_t i=0; i<11; i++) {
1921 if (TMath::Abs(z-3.9*i)<0.15) {
1922 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1926 if (TMath::Abs(z+3.9*i)<0.15) {
1927 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1931 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1932 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1935 if (13<fR&&fR<26) { //SDD
1938 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1940 if (TMath::Abs(y-1.80)<0.55) {
1942 for (Int_t j=0; j<20; j++) {
1943 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1944 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1947 if (TMath::Abs(y+1.80)<0.55) {
1949 for (Int_t j=0; j<20; j++) {
1950 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1951 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1955 for (Int_t i=0; i<4; i++) {
1956 if (TMath::Abs(z-7.3*i)<0.60) {
1958 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1961 if (TMath::Abs(z+7.3*i)<0.60) {
1963 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1968 if (6<fR&&fR<8) { //SPD2
1969 Double_t dd=0.0063; x0=21.5;
1971 if (TMath::Abs(y-3.08)>0.5) d+=dd;
1972 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
1974 if (3<fR&&fR<5) { //SPD1
1975 Double_t dd=0.0063; x0=21.5;
1977 if (TMath::Abs(y+0.21)>0.6) d+=dd;
1978 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
1983 //------------------------------------------------------------------------
1984 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
1986 fRmisal(det.fRmisal),
1988 fSinPhi(det.fSinPhi),
1989 fCosPhi(det.fCosPhi),
1995 fNChips(det.fNChips),
1996 fChipIsBad(det.fChipIsBad)
2000 //------------------------------------------------------------------------
2001 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2002 AliITSDetTypeRec *detTypeRec)
2004 //--------------------------------------------------------------------
2005 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2006 //--------------------------------------------------------------------
2008 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2009 // while in the tracker they start from 0 for each layer
2010 for(Int_t il=0; il<ilayer; il++)
2011 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2014 if (ilayer==0 || ilayer==1) { // ---------- SPD
2016 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2018 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2021 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2025 // Get calibration from AliITSDetTypeRec
2026 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2027 AliITSCalibration *calibSPDdead = 0;
2028 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2029 if (calib->IsBad() ||
2030 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2033 printf("lay %d bad %d\n",ilayer,idet);
2036 // Get segmentation from AliITSDetTypeRec
2037 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2039 // Read info about bad chips
2040 fNChips = segm->GetMaximumChipIndex()+1;
2041 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2042 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2043 fChipIsBad = new Bool_t[fNChips];
2044 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2045 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2046 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2051 //------------------------------------------------------------------------
2052 Double_t AliITStrackerMI::GetEffectiveThickness()
2054 //--------------------------------------------------------------------
2055 // Returns the thickness between the current layer and the vertex (units X0)
2056 //--------------------------------------------------------------------
2059 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2060 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2061 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2065 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2066 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2070 Double_t xn=fgLayers[fI].GetR();
2071 for (Int_t i=0; i<fI; i++) {
2072 Double_t xi=fgLayers[i].GetR();
2073 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2079 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2080 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2083 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2084 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2088 //------------------------------------------------------------------------
2089 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2090 //-------------------------------------------------------------------
2091 // This function returns number of clusters within the "window"
2092 //--------------------------------------------------------------------
2094 for (Int_t i=fI; i<fN; i++) {
2095 const AliITSRecPoint *c=fClusters[i];
2096 if (c->GetZ() > fZmax) break;
2097 if (c->IsUsed()) continue;
2098 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2099 Double_t y=fR*det.GetPhi() + c->GetY();
2101 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2102 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2104 if (y<fYmin) continue;
2105 if (y>fYmax) continue;
2110 //------------------------------------------------------------------------
2111 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2112 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2114 //--------------------------------------------------------------------
2115 // This function refits the track "track" at the position "x" using
2116 // the clusters from "clusters"
2117 // If "extra"==kTRUE,
2118 // the clusters from overlapped modules get attached to "track"
2119 // If "planeff"==kTRUE,
2120 // special approach for plane efficiency evaluation is applyed
2121 //--------------------------------------------------------------------
2123 Int_t index[AliITSgeomTGeo::kNLayers];
2125 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2126 Int_t nc=clusters->GetNumberOfClusters();
2127 for (k=0; k<nc; k++) {
2128 Int_t idx=clusters->GetClusterIndex(k);
2129 Int_t ilayer=(idx&0xf0000000)>>28;
2133 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2135 //------------------------------------------------------------------------
2136 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2137 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2139 //--------------------------------------------------------------------
2140 // This function refits the track "track" at the position "x" using
2141 // the clusters from array
2142 // If "extra"==kTRUE,
2143 // the clusters from overlapped modules get attached to "track"
2144 // If "planeff"==kTRUE,
2145 // special approach for plane efficiency evaluation is applyed
2146 //--------------------------------------------------------------------
2147 Int_t index[AliITSgeomTGeo::kNLayers];
2149 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2151 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2152 index[k]=clusters[k];
2155 // special for cosmics: check which the innermost layer crossed
2157 Int_t innermostlayer=5;
2158 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2159 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2160 if(drphi < fgLayers[innermostlayer].GetR()) break;
2162 //printf(" drphi %f innermost %d\n",drphi,innermostlayer);
2164 Int_t modstatus=1; // found
2166 Int_t from, to, step;
2167 if (xx > track->GetX()) {
2168 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2171 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2174 TString dir = (step>0 ? "outward" : "inward");
2176 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2177 AliITSlayer &layer=fgLayers[ilayer];
2178 Double_t r=layer.GetR();
2179 if (step<0 && xx>r) break;
2181 // material between SSD and SDD, SDD and SPD
2182 Double_t hI=ilayer-0.5*step;
2183 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2184 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2185 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2186 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2188 // remember old position [SR, GSI 18.02.2003]
2189 Double_t oldX=0., oldY=0., oldZ=0.;
2190 if (track->IsStartedTimeIntegral() && step==1) {
2191 track->GetGlobalXYZat(track->GetX(),oldX,oldY,oldZ);
2195 Double_t oldGlobXYZ[3];
2196 track->GetXYZ(oldGlobXYZ);
2199 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2201 Int_t idet=layer.FindDetectorIndex(phi,z);
2203 // check if we allow a prolongation without point for large-eta tracks
2204 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2206 // propagate to the layer radius
2207 Double_t xToGo; track->GetLocalXat(r,xToGo);
2208 track->AliExternalTrackParam::PropagateTo(xToGo,GetBz());
2209 // apply correction for material of the current layer
2210 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2211 modstatus = 4; // out in z
2212 LocalModuleCoord(ilayer,idet,track,xloc,zloc); // local module coords
2213 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2214 // track time update [SR, GSI 17.02.2003]
2215 if (track->IsStartedTimeIntegral() && step==1) {
2216 Double_t newX, newY, newZ;
2217 track->GetGlobalXYZat(track->GetX(),newX,newY,newZ);
2218 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2219 (oldZ-newZ)*(oldZ-newZ);
2220 track->AddTimeStep(TMath::Sqrt(dL2));
2225 if (idet<0) return kFALSE;
2227 const AliITSdetector &det=layer.GetDetector(idet);
2228 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2230 track->SetDetectorIndex(idet);
2231 LocalModuleCoord(ilayer,idet,track,xloc,zloc); // local module coords
2233 Double_t dz,zmin,zmax,dy,ymin,ymax;
2235 const AliITSRecPoint *clAcc=0;
2236 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2238 Int_t idx=index[ilayer];
2239 if (idx>=0) { // cluster in this layer
2240 modstatus = 6; // no refit
2241 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2243 if (idet != cl->GetDetectorIndex()) {
2244 idet=cl->GetDetectorIndex();
2245 const AliITSdetector &detc=layer.GetDetector(idet);
2246 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2247 track->SetDetectorIndex(idet);
2248 LocalModuleCoord(ilayer,idet,track,xloc,zloc); // local module coords
2250 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2251 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2255 modstatus = 1; // found
2260 } else { // no cluster in this layer
2262 modstatus = 3; // skipped
2263 // Plane Eff determination:
2264 if (planeeff && AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) {
2265 if (IsOKForPlaneEff(track,ilayer)) // only adequate track for plane eff. evaluation
2266 UseTrackForPlaneEff(track,ilayer);
2269 modstatus = 5; // no cls in road
2271 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2272 dz = 0.5*(zmax-zmin);
2273 dy = 0.5*(ymax-ymin);
2274 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2275 if (dead==1) modstatus = 7; // holes in z in SPD
2276 if (dead==2 || dead==3) modstatus = 2; // dead from OCDB
2281 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2282 track->SetSampledEdx(clAcc->GetQ(),track->GetNumberOfClusters()-1);
2284 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2287 if (extra) { // search for extra clusters in overlapped modules
2288 AliITStrackV2 tmp(*track);
2289 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2290 layer.SelectClusters(zmin,zmax,ymin,ymax);
2292 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2294 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2295 Double_t tolerance=0.1;
2296 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2297 // only clusters in another module! (overlaps)
2298 idetExtra = clExtra->GetDetectorIndex();
2299 if (idet == idetExtra) continue;
2301 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2303 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2304 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2305 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2306 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2308 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2309 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2312 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2313 track->SetExtraModule(ilayer,idetExtra);
2315 } // end search for extra clusters in overlapped modules
2317 // Correct for material of the current layer
2318 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2320 // track time update [SR, GSI 17.02.2003]
2321 if (track->IsStartedTimeIntegral() && step==1) {
2322 Double_t newX, newY, newZ;
2323 track->GetGlobalXYZat(track->GetX(),newX,newY,newZ);
2324 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2325 (oldZ-newZ)*(oldZ-newZ);
2326 track->AddTimeStep(TMath::Sqrt(dL2));
2330 } // end loop on layers
2332 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2336 //------------------------------------------------------------------------
2337 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2340 // calculate normalized chi2
2341 // return NormalizedChi2(track,0);
2344 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2345 // track->fdEdxMismatch=0;
2346 Float_t dedxmismatch =0;
2347 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2349 for (Int_t i = 0;i<6;i++){
2350 if (track->GetClIndex(i)>0){
2351 Float_t cerry, cerrz;
2352 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2354 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2357 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2358 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2359 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2361 cchi2+=(0.5-ratio)*10.;
2362 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2363 dedxmismatch+=(0.5-ratio)*10.;
2367 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2368 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2369 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2370 if (i<2) chi2+=2*cl->GetDeltaProbability();
2376 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2377 track->SetdEdxMismatch(dedxmismatch);
2381 for (Int_t i = 0;i<4;i++){
2382 if (track->GetClIndex(i)>0){
2383 Float_t cerry, cerrz;
2384 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2385 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2388 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2389 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2393 for (Int_t i = 4;i<6;i++){
2394 if (track->GetClIndex(i)>0){
2395 Float_t cerry, cerrz;
2396 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2397 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2400 Float_t cerryb, cerrzb;
2401 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2402 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2405 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2406 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2411 if (track->GetESDtrack()->GetTPCsignal()>85){
2412 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2414 chi2+=(0.5-ratio)*5.;
2417 chi2+=(ratio-2.0)*3;
2421 Double_t match = TMath::Sqrt(track->GetChi22());
2422 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2423 if (!track->GetConstrain()) {
2424 if (track->GetNumberOfClusters()>2) {
2425 match/=track->GetNumberOfClusters()-2.;
2430 if (match<0) match=0;
2431 Float_t deadzonefactor = (track->GetNDeadZone()>0) ? 3*(1.1-track->GetDeadZoneProbability()):0.;
2432 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2433 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2434 1./(1.+track->GetNSkipped()));
2438 //------------------------------------------------------------------------
2439 Double_t AliITStrackerMI::GetMatchingChi2(AliITStrackMI * track1, AliITStrackMI * track2)
2442 // return matching chi2 between two tracks
2443 AliITStrackMI track3(*track2);
2444 track3.Propagate(track1->GetAlpha(),track1->GetX());
2446 vec(0,0)=track1->GetY() - track3.GetY();
2447 vec(1,0)=track1->GetZ() - track3.GetZ();
2448 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2449 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2450 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2453 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2454 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2455 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2456 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2457 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2459 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2460 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2461 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2462 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2464 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2465 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2466 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2468 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2469 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2471 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2474 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2475 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2478 //------------------------------------------------------------------------
2479 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr)
2482 // return probability that given point (characterized by z position and error)
2483 // is in SPD dead zone
2485 Double_t probability = 0.;
2486 Double_t absz = TMath::Abs(zpos);
2487 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2488 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2489 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2490 Double_t zmin, zmax;
2491 if (zpos<-6.) { // dead zone at z = -7
2492 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2493 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2494 } else if (zpos>6.) { // dead zone at z = +7
2495 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2496 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2497 } else if (absz<2.) { // dead zone at z = 0
2498 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2499 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2504 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2506 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2507 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2510 //------------------------------------------------------------------------
2511 Double_t AliITStrackerMI::GetTruncatedChi2(AliITStrackMI * track, Float_t fac)
2514 // calculate normalized chi2
2516 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2518 for (Int_t i = 0;i<6;i++){
2519 if (TMath::Abs(track->GetDy(i))>0){
2520 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2521 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2524 else{chi2[i]=10000;}
2527 TMath::Sort(6,chi2,index,kFALSE);
2528 Float_t max = float(ncl)*fac-1.;
2529 Float_t sumchi=0, sumweight=0;
2530 for (Int_t i=0;i<max+1;i++){
2531 Float_t weight = (i<max)?1.:(max+1.-i);
2532 sumchi+=weight*chi2[index[i]];
2535 Double_t normchi2 = sumchi/sumweight;
2538 //------------------------------------------------------------------------
2539 Double_t AliITStrackerMI::GetInterpolatedChi2(AliITStrackMI * forwardtrack, AliITStrackMI * backtrack)
2542 // calculate normalized chi2
2543 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2546 for (Int_t i=0;i<6;i++){
2547 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2548 Double_t sy1 = forwardtrack->GetSigmaY(i);
2549 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2550 Double_t sy2 = backtrack->GetSigmaY(i);
2551 Double_t sz2 = backtrack->GetSigmaZ(i);
2552 if (i<2){ sy2=1000.;sz2=1000;}
2554 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2555 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2557 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2558 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2560 res+= nz0*nz0+ny0*ny0;
2563 if (npoints>1) return
2564 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2565 //2*forwardtrack->fNUsed+
2566 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2567 1./(1.+forwardtrack->GetNSkipped()));
2570 //------------------------------------------------------------------------
2571 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2572 //--------------------------------------------------------------------
2573 // Return pointer to a given cluster
2574 //--------------------------------------------------------------------
2575 Int_t l=(index & 0xf0000000) >> 28;
2576 Int_t c=(index & 0x0fffffff) >> 00;
2577 return fgLayers[l].GetWeight(c);
2579 //------------------------------------------------------------------------
2580 void AliITStrackerMI::RegisterClusterTracks(AliITStrackMI* track,Int_t id)
2582 //---------------------------------------------
2583 // register track to the list
2585 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2588 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2589 Int_t index = track->GetClusterIndex(icluster);
2590 Int_t l=(index & 0xf0000000) >> 28;
2591 Int_t c=(index & 0x0fffffff) >> 00;
2592 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2593 for (Int_t itrack=0;itrack<4;itrack++){
2594 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2595 fgLayers[l].SetClusterTracks(itrack,c,id);
2601 //------------------------------------------------------------------------
2602 void AliITStrackerMI::UnRegisterClusterTracks(AliITStrackMI* track, Int_t id)
2604 //---------------------------------------------
2605 // unregister track from the list
2606 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2607 Int_t index = track->GetClusterIndex(icluster);
2608 Int_t l=(index & 0xf0000000) >> 28;
2609 Int_t c=(index & 0x0fffffff) >> 00;
2610 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2611 for (Int_t itrack=0;itrack<4;itrack++){
2612 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2613 fgLayers[l].SetClusterTracks(itrack,c,-1);
2618 //------------------------------------------------------------------------
2619 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2621 //-------------------------------------------------------------
2622 //get number of shared clusters
2623 //-------------------------------------------------------------
2625 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2626 // mean number of clusters
2627 Float_t *ny = GetNy(id), *nz = GetNz(id);
2630 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2631 Int_t index = track->GetClusterIndex(icluster);
2632 Int_t l=(index & 0xf0000000) >> 28;
2633 Int_t c=(index & 0x0fffffff) >> 00;
2634 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2636 printf("problem\n");
2638 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2642 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2643 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2644 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2646 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2649 deltan = (cl->GetNz()-nz[l]);
2651 if (deltan>2.0) continue; // extended - highly probable shared cluster
2652 weight = 2./TMath::Max(3.+deltan,2.);
2654 for (Int_t itrack=0;itrack<4;itrack++){
2655 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2657 clist[l] = (AliITSRecPoint*)GetCluster(index);
2663 track->SetNUsed(shared);
2666 //------------------------------------------------------------------------
2667 Int_t AliITStrackerMI::GetOverlapTrack(AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2670 // find first shared track
2672 // mean number of clusters
2673 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2675 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2676 Int_t sharedtrack=100000;
2677 Int_t tracks[24],trackindex=0;
2678 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2680 for (Int_t icluster=0;icluster<6;icluster++){
2681 if (clusterlist[icluster]<0) continue;
2682 Int_t index = clusterlist[icluster];
2683 Int_t l=(index & 0xf0000000) >> 28;
2684 Int_t c=(index & 0x0fffffff) >> 00;
2686 printf("problem\n");
2688 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2689 //if (l>3) continue;
2690 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2693 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2694 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2695 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2697 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2700 deltan = (cl->GetNz()-nz[l]);
2702 if (deltan>2.0) continue; // extended - highly probable shared cluster
2704 for (Int_t itrack=3;itrack>=0;itrack--){
2705 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2706 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2707 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2712 if (trackindex==0) return -1;
2714 sharedtrack = tracks[0];
2716 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2719 Int_t tracks2[24], cluster[24];
2720 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2723 for (Int_t i=0;i<trackindex;i++){
2724 if (tracks[i]<0) continue;
2725 tracks2[index] = tracks[i];
2727 for (Int_t j=i+1;j<trackindex;j++){
2728 if (tracks[j]<0) continue;
2729 if (tracks[j]==tracks[i]){
2737 for (Int_t i=0;i<index;i++){
2738 if (cluster[index]>max) {
2739 sharedtrack=tracks2[index];
2746 if (sharedtrack>=100000) return -1;
2748 // make list of overlaps
2750 for (Int_t icluster=0;icluster<6;icluster++){
2751 if (clusterlist[icluster]<0) continue;
2752 Int_t index = clusterlist[icluster];
2753 Int_t l=(index & 0xf0000000) >> 28;
2754 Int_t c=(index & 0x0fffffff) >> 00;
2755 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2756 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2758 if (cl->GetNy()>2) continue;
2759 if (cl->GetNz()>2) continue;
2762 if (cl->GetNy()>3) continue;
2763 if (cl->GetNz()>3) continue;
2766 for (Int_t itrack=3;itrack>=0;itrack--){
2767 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2768 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2776 //------------------------------------------------------------------------
2777 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2779 // try to find track hypothesys without conflicts
2780 // with minimal chi2;
2781 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2782 Int_t entries1 = arr1->GetEntriesFast();
2783 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2784 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2785 Int_t entries2 = arr2->GetEntriesFast();
2786 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2788 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2789 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2790 if (track10->Pt()>0.5+track20->Pt()) return track10;
2792 for (Int_t itrack=0;itrack<entries1;itrack++){
2793 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2794 UnRegisterClusterTracks(track,trackID1);
2797 for (Int_t itrack=0;itrack<entries2;itrack++){
2798 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2799 UnRegisterClusterTracks(track,trackID2);
2803 Float_t maxconflicts=6;
2804 Double_t maxchi2 =1000.;
2806 // get weight of hypothesys - using best hypothesy
2809 Int_t list1[6],list2[6];
2810 AliITSRecPoint *clist1[6], *clist2[6] ;
2811 RegisterClusterTracks(track10,trackID1);
2812 RegisterClusterTracks(track20,trackID2);
2813 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2814 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2815 UnRegisterClusterTracks(track10,trackID1);
2816 UnRegisterClusterTracks(track20,trackID2);
2819 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2820 Float_t nerry[6],nerrz[6];
2821 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2822 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2823 for (Int_t i=0;i<6;i++){
2824 if ( (erry1[i]>0) && (erry2[i]>0)) {
2825 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2826 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2828 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2829 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2831 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2832 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2833 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2836 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2837 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2838 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2846 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2847 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2848 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2849 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2851 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2852 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2853 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2855 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2856 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2857 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2860 Double_t sumw = w1+w2;
2864 w1 = (d2+0.5)/(d1+d2+1.);
2865 w2 = (d1+0.5)/(d1+d2+1.);
2867 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2868 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2870 // get pair of "best" hypothesys
2872 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2873 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2875 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2876 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2877 //if (track1->fFakeRatio>0) continue;
2878 RegisterClusterTracks(track1,trackID1);
2879 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2880 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2882 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2883 //if (track2->fFakeRatio>0) continue;
2885 RegisterClusterTracks(track2,trackID2);
2886 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2887 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2888 UnRegisterClusterTracks(track2,trackID2);
2890 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2891 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2892 if (nskipped>0.5) continue;
2894 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2895 if (conflict1+1<cconflict1) continue;
2896 if (conflict2+1<cconflict2) continue;
2900 for (Int_t i=0;i<6;i++){
2902 Float_t c1 =0.; // conflict coeficients
2904 if (clist1[i]&&clist2[i]){
2907 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2910 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
2912 c1 = 2./TMath::Max(3.+deltan,2.);
2913 c2 = 2./TMath::Max(3.+deltan,2.);
2919 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
2922 deltan = (clist1[i]->GetNz()-nz1[i]);
2924 c1 = 2./TMath::Max(3.+deltan,2.);
2931 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
2934 deltan = (clist2[i]->GetNz()-nz2[i]);
2936 c2 = 2./TMath::Max(3.+deltan,2.);
2942 if (TMath::Abs(track1->GetDy(i))>0.) {
2943 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
2944 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
2945 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
2946 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
2948 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
2951 if (TMath::Abs(track2->GetDy(i))>0.) {
2952 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
2953 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
2954 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
2955 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
2958 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
2960 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
2961 if (chi21>0) sum+=w1;
2962 if (chi22>0) sum+=w2;
2965 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
2966 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
2967 Double_t normchi2 = 2*conflict+sumchi2/sum;
2968 if ( normchi2 <maxchi2 ){
2971 maxconflicts = conflict;
2975 UnRegisterClusterTracks(track1,trackID1);
2978 // if (maxconflicts<4 && maxchi2<th0){
2979 if (maxchi2<th0*2.){
2980 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
2981 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
2982 track1->SetChi2MIP(5,maxconflicts);
2983 track1->SetChi2MIP(6,maxchi2);
2984 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
2985 // track1->UpdateESDtrack(AliESDtrack::kITSin);
2986 track1->SetChi2MIP(8,index1);
2987 fBestTrackIndex[trackID1] =index1;
2988 UpdateESDtrack(track1, AliESDtrack::kITSin);
2990 else if (track10->GetChi2MIP(0)<th1){
2991 track10->SetChi2MIP(5,maxconflicts);
2992 track10->SetChi2MIP(6,maxchi2);
2993 // track10->UpdateESDtrack(AliESDtrack::kITSin);
2994 UpdateESDtrack(track10,AliESDtrack::kITSin);
2997 for (Int_t itrack=0;itrack<entries1;itrack++){
2998 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2999 UnRegisterClusterTracks(track,trackID1);
3002 for (Int_t itrack=0;itrack<entries2;itrack++){
3003 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3004 UnRegisterClusterTracks(track,trackID2);
3007 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3008 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3009 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3010 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3011 RegisterClusterTracks(track10,trackID1);
3013 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3014 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3015 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3016 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3017 RegisterClusterTracks(track20,trackID2);
3022 //------------------------------------------------------------------------
3023 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3024 //--------------------------------------------------------------------
3025 // This function marks clusters assigned to the track
3026 //--------------------------------------------------------------------
3027 AliTracker::UseClusters(t,from);
3029 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3030 //if (c->GetQ()>2) c->Use();
3031 if (c->GetSigmaZ2()>0.1) c->Use();
3032 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3033 //if (c->GetQ()>2) c->Use();
3034 if (c->GetSigmaZ2()>0.1) c->Use();
3037 //------------------------------------------------------------------------
3038 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3040 //------------------------------------------------------------------
3041 // add track to the list of hypothesys
3042 //------------------------------------------------------------------
3044 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3045 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3047 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3049 array = new TObjArray(10);
3050 fTrackHypothesys.AddAt(array,esdindex);
3052 array->AddLast(track);
3054 //------------------------------------------------------------------------
3055 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3057 //-------------------------------------------------------------------
3058 // compress array of track hypothesys
3059 // keep only maxsize best hypothesys
3060 //-------------------------------------------------------------------
3061 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3062 if (! (fTrackHypothesys.At(esdindex)) ) return;
3063 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3064 Int_t entries = array->GetEntriesFast();
3066 //- find preliminary besttrack as a reference
3067 Float_t minchi2=10000;
3069 AliITStrackMI * besttrack=0;
3070 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3071 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3072 if (!track) continue;
3073 Float_t chi2 = NormalizedChi2(track,0);
3075 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3076 track->SetLabel(tpcLabel);
3078 track->SetFakeRatio(1.);
3079 CookLabel(track,0.); //For comparison only
3081 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3082 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3083 if (track->GetNumberOfClusters()<maxn) continue;
3084 maxn = track->GetNumberOfClusters();
3091 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3092 delete array->RemoveAt(itrack);
3096 if (!besttrack) return;
3099 //take errors of best track as a reference
3100 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3101 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3102 for (Int_t j=0;j<6;j++) {
3103 if (besttrack->GetClIndex(j)>0){
3104 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3105 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3106 ny[j] = besttrack->GetNy(j);
3107 nz[j] = besttrack->GetNz(j);
3111 // calculate normalized chi2
3113 Float_t * chi2 = new Float_t[entries];
3114 Int_t * index = new Int_t[entries];
3115 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3116 for (Int_t itrack=0;itrack<entries;itrack++){
3117 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3119 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3120 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3121 chi2[itrack] = track->GetChi2MIP(0);
3123 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3124 delete array->RemoveAt(itrack);
3130 TMath::Sort(entries,chi2,index,kFALSE);
3131 besttrack = (AliITStrackMI*)array->At(index[0]);
3132 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3133 for (Int_t j=0;j<6;j++){
3134 if (besttrack->GetClIndex(j)>0){
3135 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3136 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3137 ny[j] = besttrack->GetNy(j);
3138 nz[j] = besttrack->GetNz(j);
3143 // calculate one more time with updated normalized errors
3144 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3145 for (Int_t itrack=0;itrack<entries;itrack++){
3146 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3148 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3149 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3150 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3153 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3154 delete array->RemoveAt(itrack);
3159 entries = array->GetEntriesFast();
3163 TObjArray * newarray = new TObjArray();
3164 TMath::Sort(entries,chi2,index,kFALSE);
3165 besttrack = (AliITStrackMI*)array->At(index[0]);
3168 for (Int_t j=0;j<6;j++){
3169 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3170 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3171 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3172 ny[j] = besttrack->GetNy(j);
3173 nz[j] = besttrack->GetNz(j);
3176 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3177 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3178 Float_t minn = besttrack->GetNumberOfClusters()-3;
3180 for (Int_t i=0;i<entries;i++){
3181 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3182 if (!track) continue;
3183 if (accepted>maxcut) break;
3184 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3185 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3186 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3187 delete array->RemoveAt(index[i]);
3191 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3192 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3193 if (!shortbest) accepted++;
3195 newarray->AddLast(array->RemoveAt(index[i]));
3196 for (Int_t j=0;j<6;j++){
3198 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3199 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3200 ny[j] = track->GetNy(j);
3201 nz[j] = track->GetNz(j);
3206 delete array->RemoveAt(index[i]);
3210 delete fTrackHypothesys.RemoveAt(esdindex);
3211 fTrackHypothesys.AddAt(newarray,esdindex);
3215 delete fTrackHypothesys.RemoveAt(esdindex);
3221 //------------------------------------------------------------------------
3222 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3224 //-------------------------------------------------------------
3225 // try to find best hypothesy
3226 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3227 //-------------------------------------------------------------
3228 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3229 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3230 if (!array) return 0;
3231 Int_t entries = array->GetEntriesFast();
3232 if (!entries) return 0;
3233 Float_t minchi2 = 100000;
3234 AliITStrackMI * besttrack=0;
3236 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3237 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3238 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3239 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3241 for (Int_t i=0;i<entries;i++){
3242 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3243 if (!track) continue;
3244 Float_t sigmarfi,sigmaz;
3245 GetDCASigma(track,sigmarfi,sigmaz);
3246 track->SetDnorm(0,sigmarfi);
3247 track->SetDnorm(1,sigmaz);
3249 track->SetChi2MIP(1,1000000);
3250 track->SetChi2MIP(2,1000000);
3251 track->SetChi2MIP(3,1000000);
3254 backtrack = new(backtrack) AliITStrackMI(*track);
3255 if (track->GetConstrain()) {
3256 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3257 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3258 backtrack->ResetCovariance(10.);
3260 backtrack->ResetCovariance(10.);
3262 backtrack->ResetClusters();
3264 Double_t x = original->GetX();
3265 if (!RefitAt(x,backtrack,track)) continue;
3267 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3268 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3269 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3270 track->SetChi22(GetMatchingChi2(backtrack,original));
3272 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3273 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3274 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3277 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3279 //forward track - without constraint
3280 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3281 forwardtrack->ResetClusters();
3283 RefitAt(x,forwardtrack,track);
3284 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3285 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3286 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3288 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3289 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3290 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3291 forwardtrack->SetD(0,track->GetD(0));
3292 forwardtrack->SetD(1,track->GetD(1));
3295 AliITSRecPoint* clist[6];
3296 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3297 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3300 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3301 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3302 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3303 track->SetChi2MIP(3,1000);
3306 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3308 for (Int_t ichi=0;ichi<5;ichi++){
3309 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3311 if (chi2 < minchi2){
3312 //besttrack = new AliITStrackMI(*forwardtrack);
3314 besttrack->SetLabel(track->GetLabel());
3315 besttrack->SetFakeRatio(track->GetFakeRatio());
3317 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3318 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3319 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3323 delete forwardtrack;
3325 for (Int_t i=0;i<entries;i++){
3326 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3328 if (!track) continue;
3330 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3331 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3332 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3333 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3334 delete array->RemoveAt(i);
3344 SortTrackHypothesys(esdindex,checkmax,1);
3346 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3347 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3348 besttrack = (AliITStrackMI*)array->At(0);
3349 if (!besttrack) return 0;
3350 besttrack->SetChi2MIP(8,0);
3351 fBestTrackIndex[esdindex]=0;
3352 entries = array->GetEntriesFast();
3353 AliITStrackMI *longtrack =0;
3355 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3356 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3357 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3358 if (!track->GetConstrain()) continue;
3359 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3360 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3361 if (track->GetChi2MIP(0)>4.) continue;
3362 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3365 //if (longtrack) besttrack=longtrack;
3368 AliITSRecPoint * clist[6];
3369 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3370 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3371 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3372 RegisterClusterTracks(besttrack,esdindex);
3379 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3380 if (sharedtrack>=0){
3382 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3384 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3390 if (shared>2.5) return 0;
3391 if (shared>1.0) return besttrack;
3393 // Don't sign clusters if not gold track
3395 if (!besttrack->IsGoldPrimary()) return besttrack;
3396 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3398 if (fConstraint[fPass]){
3402 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3403 for (Int_t i=0;i<6;i++){
3404 Int_t index = besttrack->GetClIndex(i);
3405 if (index<=0) continue;
3406 Int_t ilayer = (index & 0xf0000000) >> 28;
3407 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3408 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3410 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3411 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3412 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3413 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3414 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3415 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3417 Bool_t cansign = kTRUE;
3418 for (Int_t itrack=0;itrack<entries; itrack++){
3419 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3420 if (!track) continue;
3421 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3422 if ( (track->GetClIndex(ilayer)>0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3428 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3429 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3430 if (!c->IsUsed()) c->Use();
3436 //------------------------------------------------------------------------
3437 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3440 // get "best" hypothesys
3443 Int_t nentries = itsTracks.GetEntriesFast();
3444 for (Int_t i=0;i<nentries;i++){
3445 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3446 if (!track) continue;
3447 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3448 if (!array) continue;
3449 if (array->GetEntriesFast()<=0) continue;
3451 AliITStrackMI* longtrack=0;
3453 Float_t maxchi2=1000;
3454 for (Int_t j=0;j<array->GetEntriesFast();j++){
3455 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3456 if (!trackHyp) continue;
3457 if (trackHyp->GetGoldV0()) {
3458 longtrack = trackHyp; //gold V0 track taken
3461 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3462 Float_t chi2 = trackHyp->GetChi2MIP(0);
3464 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3466 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3468 if (chi2 > maxchi2) continue;
3469 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3476 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3477 if (!longtrack) {longtrack = besttrack;}
3478 else besttrack= longtrack;
3482 AliITSRecPoint * clist[6];
3483 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3485 track->SetNUsed(shared);
3486 track->SetNSkipped(besttrack->GetNSkipped());
3487 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3489 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3493 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3494 //if (sharedtrack==-1) sharedtrack=0;
3495 if (sharedtrack>=0) {
3496 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3499 if (besttrack&&fAfterV0) {
3500 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3502 if (besttrack&&fConstraint[fPass])
3503 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3504 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3505 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3506 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3512 //------------------------------------------------------------------------
3513 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3514 //--------------------------------------------------------------------
3515 //This function "cooks" a track label. If label<0, this track is fake.
3516 //--------------------------------------------------------------------
3519 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3521 track->SetChi2MIP(9,0);
3523 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3524 Int_t cindex = track->GetClusterIndex(i);
3525 Int_t l=(cindex & 0xf0000000) >> 28;
3526 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3528 for (Int_t ind=0;ind<3;ind++){
3530 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3532 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3535 Int_t nclusters = track->GetNumberOfClusters();
3536 if (nclusters > 0) //PH Some tracks don't have any cluster
3537 track->SetFakeRatio(double(nwrong)/double(nclusters));
3539 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3541 track->SetLabel(tpcLabel);
3545 //------------------------------------------------------------------------
3546 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3551 //AliITSRecPoint * clist[6];
3552 // Int_t shared = GetNumberOfSharedClusters(track,index,list,clist);
3555 track->SetChi2MIP(9,0);
3556 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3557 Int_t cindex = track->GetClusterIndex(i);
3558 Int_t l=(cindex & 0xf0000000) >> 28;
3559 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3560 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3562 for (Int_t ind=0;ind<3;ind++){
3563 if (cl->GetLabel(ind)==lab) isWrong=0;
3565 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3567 //if (l>3 && (cl->GetNy()>4) || (cl->GetNz()>4)) continue; //shared track
3568 //if (l>3&& !(cl->GetType()==1||cl->GetType()==10)) continue;
3569 //if (l<4&& !(cl->GetType()==1)) continue;
3570 dedx[accepted]= track->GetSampledEdx(i);
3571 //dedx[accepted]= track->fNormQ[l];
3579 TMath::Sort(accepted,dedx,indexes,kFALSE);
3582 Double_t nl=low*accepted, nu =up*accepted;
3584 Float_t sumweight =0;
3585 for (Int_t i=0; i<accepted; i++) {
3587 if (i<nl+0.1) weight = TMath::Max(1.-(nl-i),0.);
3588 if (i>nu-1) weight = TMath::Max(nu-i,0.);
3589 sumamp+= dedx[indexes[i]]*weight;
3592 track->SetdEdx(sumamp/sumweight);
3594 //------------------------------------------------------------------------
3595 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3598 if (fCoefficients) delete []fCoefficients;
3599 fCoefficients = new Float_t[ntracks*48];
3600 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3602 //------------------------------------------------------------------------
3603 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3609 Float_t theta = track->GetTgl();
3610 Float_t phi = track->GetSnp();
3611 phi = TMath::Sqrt(phi*phi/(1.-phi*phi));
3612 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz);
3613 //printf(" chi2: tr-cl %f %f tr X %f cl X %f\n",track->GetY()-cluster->GetY(),track->GetZ()-cluster->GetZ(),track->GetX(),cluster->GetX());
3615 // Take into account the mis-alignment (bring track to cluster plane)
3616 Double_t xTrOrig=track->GetX();
3617 if (!track->PropagateTo(xTrOrig+cluster->GetX(),0.,0.)) return 1000.;
3618 //printf(" chi2: tr-cl %f %f tr X %f cl X %f\n",track->GetY()-cluster->GetY(),track->GetZ()-cluster->GetZ(),track->GetX(),cluster->GetX());
3619 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz);
3620 // Bring the track back to detector plane in ideal geometry
3621 // [mis-alignment will be accounted for in UpdateMI()]
3622 if (!track->PropagateTo(xTrOrig,0.,0.)) return 1000.;
3624 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3625 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3627 chi2+=0.5*TMath::Min(delta/2,2.);
3628 chi2+=2.*cluster->GetDeltaProbability();
3631 track->SetNy(layer,ny);
3632 track->SetNz(layer,nz);
3633 track->SetSigmaY(layer,erry);
3634 track->SetSigmaZ(layer, errz);
3635 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3636 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/(1.- track->GetSnp()*track->GetSnp())));
3640 //------------------------------------------------------------------------
3641 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3646 Int_t layer = (index & 0xf0000000) >> 28;
3647 track->SetClIndex(layer, index);
3648 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3649 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3650 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3651 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3655 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3658 // Take into account the mis-alignment (bring track to cluster plane)
3659 Double_t xTrOrig=track->GetX();
3660 //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]);
3661 //printf(" xtr %f xcl %f\n",track->GetX(),cl->GetX());
3663 if (!track->PropagateTo(xTrOrig+cl->GetX(),0.,0.)) return 0;
3667 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3668 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3671 Int_t updated = track->UpdateMI(&c,chi2,index);
3673 // Bring the track back to detector plane in ideal geometry
3674 if (!track->PropagateTo(xTrOrig,0.,0.)) return 0;
3676 //if(!updated) printf("update failed\n");
3680 //------------------------------------------------------------------------
3681 void AliITStrackerMI::GetDCASigma(AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3684 //DCA sigmas parameterization
3685 //to be paramterized using external parameters in future
3688 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3689 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3691 //------------------------------------------------------------------------
3692 void AliITStrackerMI::SignDeltas( TObjArray *ClusterArray, Float_t vz)
3696 Int_t entries = ClusterArray->GetEntriesFast();
3697 if (entries<4) return;
3698 AliITSRecPoint* cluster = (AliITSRecPoint*)ClusterArray->At(0);
3699 Int_t layer = cluster->GetLayer();
3700 if (layer>1) return;
3702 Int_t ncandidates=0;
3703 Float_t r = (layer>0)? 7:4;
3705 for (Int_t i=0;i<entries;i++){
3706 AliITSRecPoint* cl0 = (AliITSRecPoint*)ClusterArray->At(i);
3707 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3708 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3709 index[ncandidates] = i; //candidate to belong to delta electron track
3711 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3712 cl0->SetDeltaProbability(1);
3718 for (Int_t i=0;i<ncandidates;i++){
3719 AliITSRecPoint* cl0 = (AliITSRecPoint*)ClusterArray->At(index[i]);
3720 if (cl0->GetDeltaProbability()>0.8) continue;
3723 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3724 sumy=sumz=sumy2=sumyz=sumw=0.0;
3725 for (Int_t j=0;j<ncandidates;j++){
3727 AliITSRecPoint* cl1 = (AliITSRecPoint*)ClusterArray->At(index[j]);
3729 Float_t dz = cl0->GetZ()-cl1->GetZ();
3730 Float_t dy = cl0->GetY()-cl1->GetY();
3731 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3732 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3733 y[ncl] = cl1->GetY();
3734 z[ncl] = cl1->GetZ();
3735 sumy+= y[ncl]*weight;
3736 sumz+= z[ncl]*weight;
3737 sumy2+=y[ncl]*y[ncl]*weight;
3738 sumyz+=y[ncl]*z[ncl]*weight;
3743 if (ncl<4) continue;
3744 Float_t det = sumw*sumy2 - sumy*sumy;
3746 if (TMath::Abs(det)>0.01){
3747 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3748 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3749 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3752 Float_t z0 = sumyz/sumy;
3753 delta = TMath::Abs(cl0->GetZ()-z0);
3756 cl0->SetDeltaProbability(1-20.*delta);
3760 //------------------------------------------------------------------------
3761 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3765 track->UpdateESDtrack(flags);
3766 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3767 if (oldtrack) delete oldtrack;
3768 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3769 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3770 printf("Problem\n");
3773 //------------------------------------------------------------------------
3774 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3776 // Get nearest upper layer close to the point xr.
3777 // rough approximation
3779 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3780 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3782 for (Int_t i=0;i<6;i++){
3783 if (radius<kRadiuses[i]){
3790 //------------------------------------------------------------------------
3791 void AliITStrackerMI::UpdateTPCV0(AliESDEvent *event){
3793 //try to update, or reject TPC V0s
3795 Int_t nv0s = event->GetNumberOfV0s();
3796 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3798 for (Int_t i=0;i<nv0s;i++){
3799 AliESDv0 * vertex = event->GetV0(i);
3800 Int_t ip = vertex->GetIndex(0);
3801 Int_t im = vertex->GetIndex(1);
3803 TObjArray * arrayp = (ip<nitstracks) ? (TObjArray*)fTrackHypothesys.At(ip):0;
3804 TObjArray * arraym = (im<nitstracks) ? (TObjArray*)fTrackHypothesys.At(im):0;
3805 AliITStrackMI * trackp = (arrayp!=0) ? (AliITStrackMI*)arrayp->At(0):0;
3806 AliITStrackMI * trackm = (arraym!=0) ? (AliITStrackMI*)arraym->At(0):0;
3810 if (trackp->GetNumberOfClusters()+trackp->GetNDeadZone()>5.5){
3811 if (trackp->GetConstrain()&&trackp->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3812 if (!trackp->GetConstrain()&&trackp->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3817 if (trackm->GetNumberOfClusters()+trackm->GetNDeadZone()>5.5){
3818 if (trackm->GetConstrain()&&trackm->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3819 if (!trackm->GetConstrain()&&trackm->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3822 if (vertex->GetStatus()==-100) continue;
3824 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
3825 Int_t clayer = GetNearestLayer(xrp); //I.B.
3826 vertex->SetNBefore(clayer); //
3827 vertex->SetChi2Before(9*clayer); //
3828 vertex->SetNAfter(6-clayer); //
3829 vertex->SetChi2After(0); //
3831 if (clayer >1 ){ // calculate chi2 before vertex
3832 Float_t chi2p = 0, chi2m=0;
3835 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3836 if (trackp->GetClIndex(ilayer)>0){
3837 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3838 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3849 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3850 if (trackm->GetClIndex(ilayer)>0){
3851 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3852 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3861 vertex->SetChi2Before(TMath::Min(chi2p,chi2m));
3862 if (TMath::Min(chi2p,chi2m)/Float_t(clayer)<4) vertex->SetStatus(-10); // track exist before vertex
3865 if (clayer < 5 ){ // calculate chi2 after vertex
3866 Float_t chi2p = 0, chi2m=0;
3868 if (trackp&&TMath::Abs(trackp->GetTgl())<1.){
3869 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3870 if (trackp->GetClIndex(ilayer)>0){
3871 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3872 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3882 if (trackm&&TMath::Abs(trackm->GetTgl())<1.){
3883 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3884 if (trackm->GetClIndex(ilayer)>0){
3885 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3886 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3895 vertex->SetChi2After(TMath::Max(chi2p,chi2m));
3896 if (TMath::Max(chi2m,chi2p)/Float_t(6-clayer)>9) vertex->SetStatus(-20); // track not found in ITS
3901 //------------------------------------------------------------------------
3902 void AliITStrackerMI::FindV02(AliESDEvent *event)
3907 // Cuts on DCA - R dependent
3908 // max distance DCA between 2 tracks cut
3909 // maxDist = TMath::Min(kMaxDist,kMaxDist0+pvertex->GetRr()*kMaxDist);
3911 const Float_t kMaxDist0 = 0.1;
3912 const Float_t kMaxDist1 = 0.1;
3913 const Float_t kMaxDist = 1;
3914 const Float_t kMinPointAngle = 0.85;
3915 const Float_t kMinPointAngle2 = 0.99;
3916 const Float_t kMinR = 0.5;
3917 const Float_t kMaxR = 220;
3918 //const Float_t kCausality0Cut = 0.19;
3919 //const Float_t kLikelihood01Cut = 0.25;
3920 //const Float_t kPointAngleCut = 0.9996;
3921 const Float_t kCausality0Cut = 0.19;
3922 const Float_t kLikelihood01Cut = 0.45;
3923 const Float_t kLikelihood1Cut = 0.5;
3924 const Float_t kCombinedCut = 0.55;
3928 TTreeSRedirector &cstream = *fDebugStreamer;
3929 Int_t ntracks = event->GetNumberOfTracks();
3930 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3931 fOriginal.Expand(ntracks);
3932 fTrackHypothesys.Expand(ntracks);
3933 fBestHypothesys.Expand(ntracks);
3935 AliHelix * helixes = new AliHelix[ntracks+2];
3936 TObjArray trackarray(ntracks+2); //array with tracks - with vertex constrain
3937 TObjArray trackarrayc(ntracks+2); //array of "best tracks" - without vertex constrain
3938 TObjArray trackarrayl(ntracks+2); //array of "longest tracks" - without vertex constrain
3939 Bool_t * forbidden = new Bool_t [ntracks+2];
3940 Int_t *itsmap = new Int_t [ntracks+2];
3941 Float_t *dist = new Float_t[ntracks+2];
3942 Float_t *normdist0 = new Float_t[ntracks+2];
3943 Float_t *normdist1 = new Float_t[ntracks+2];
3944 Float_t *normdist = new Float_t[ntracks+2];
3945 Float_t *norm = new Float_t[ntracks+2];
3946 Float_t *maxr = new Float_t[ntracks+2];
3947 Float_t *minr = new Float_t[ntracks+2];
3948 Float_t *minPointAngle= new Float_t[ntracks+2];
3950 AliV0 *pvertex = new AliV0;
3951 AliITStrackMI * dummy= new AliITStrackMI;
3953 AliITStrackMI trackat0; //temporary track for DCA calculation
3955 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
3957 // make ITS - ESD map
3959 for (Int_t itrack=0;itrack<ntracks+2;itrack++) {
3960 itsmap[itrack] = -1;
3961 forbidden[itrack] = kFALSE;
3962 maxr[itrack] = kMaxR;
3963 minr[itrack] = kMinR;
3964 minPointAngle[itrack] = kMinPointAngle;
3966 for (Int_t itrack=0;itrack<nitstracks;itrack++){
3967 AliITStrackMI * original = (AliITStrackMI*)(fOriginal.At(itrack));
3968 Int_t esdindex = original->GetESDtrack()->GetID();
3969 itsmap[esdindex] = itrack;
3972 // create ITS tracks from ESD tracks if not done before
3974 for (Int_t itrack=0;itrack<ntracks;itrack++){
3975 if (itsmap[itrack]>=0) continue;
3976 AliITStrackMI * tpctrack = new AliITStrackMI(*(event->GetTrack(itrack)));
3977 //tpctrack->fD[0] = tpctrack->GetD(GetX(),GetY());
3978 //tpctrack->fD[1] = tpctrack->GetZat(GetX())-GetZ();
3979 tpctrack->GetDZ(GetX(),GetY(),GetZ(),tpctrack->GetDP()); //I.B.
3980 if (tpctrack->GetD(0)<20 && tpctrack->GetD(1)<20){
3981 // tracks which can reach inner part of ITS
3982 // propagate track to outer its volume - with correction for material
3983 CorrectForTPCtoITSDeadZoneMaterial(tpctrack);
3985 itsmap[itrack] = nitstracks;
3986 fOriginal.AddAt(tpctrack,nitstracks);
3990 // fill temporary arrays
3992 for (Int_t itrack=0;itrack<ntracks;itrack++){
3993 AliESDtrack * esdtrack = event->GetTrack(itrack);
3994 Int_t itsindex = itsmap[itrack];
3995 AliITStrackMI *original = (AliITStrackMI*)fOriginal.At(itsmap[itrack]);
3996 if (!original) continue;
3997 AliITStrackMI *bestConst = 0;
3998 AliITStrackMI *bestLong = 0;
3999 AliITStrackMI *best = 0;
4002 TObjArray * array = (TObjArray*) fTrackHypothesys.At(itsindex);
4003 Int_t hentries = (array==0) ? 0 : array->GetEntriesFast();
4004 // Get best track with vertex constrain
4005 for (Int_t ih=0;ih<hentries;ih++){
4006 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
4007 if (!trackh->GetConstrain()) continue;
4008 if (!bestConst) bestConst = trackh;
4009 if (trackh->GetNumberOfClusters()>5.0){
4010 bestConst = trackh; // full track - with minimal chi2
4013 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()) continue;
4017 // Get best long track without vertex constrain and best track without vertex constrain
4018 for (Int_t ih=0;ih<hentries;ih++){
4019 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
4020 if (trackh->GetConstrain()) continue;
4021 if (!best) best = trackh;
4022 if (!bestLong) bestLong = trackh;
4023 if (trackh->GetNumberOfClusters()>5.0){
4024 bestLong = trackh; // full track - with minimal chi2
4027 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()) continue;
4032 bestLong = original;
4034 //I.B. trackat0 = *bestLong;
4035 new (&trackat0) AliITStrackMI(*bestLong);
4036 Double_t xx,yy,zz,alpha;
4037 bestLong->GetGlobalXYZat(bestLong->GetX(),xx,yy,zz);
4038 alpha = TMath::ATan2(yy,xx);
4039 trackat0.Propagate(alpha,0);
4040 // calculate normalized distances to the vertex
4042 Float_t ptfac = (1.+100.*TMath::Abs(trackat0.GetC()));
4043 if ( bestLong->GetNumberOfClusters()>3 ){
4044 dist[itsindex] = trackat0.GetY();
4045 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
4046 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
4047 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
4048 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
4050 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<6) normdist[itsindex]*=2.;
4051 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<5) normdist[itsindex]*=2.;
4052 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<4) normdist[itsindex]*=2.;
4054 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<6) normdist[itsindex]*=1.5;
4055 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<5) normdist[itsindex]*=1.5;
4059 if (bestConst&&bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5){
4060 dist[itsindex] = bestConst->GetD(0);
4061 norm[itsindex] = bestConst->GetDnorm(0);
4062 normdist0[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
4063 normdist1[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
4064 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
4066 dist[itsindex] = trackat0.GetY();
4067 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
4068 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
4069 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
4070 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
4071 if (TMath::Abs(trackat0.GetTgl())>1.05){
4072 if (normdist[itsindex]<3) forbidden[itsindex]=kTRUE;
4073 if (normdist[itsindex]>3) {
4074 minr[itsindex] = TMath::Max(Float_t(40.),minr[itsindex]);
4080 //-----------------------------------------------------------
4081 //Forbid primary track candidates -
4083 //treetr->SetAlias("forbidden0","Tr0.fN<4&&Tr1.fN+Tr1.fNDeadZone>4.5");
4084 //treetr->SetAlias("forbidden1","ND<3&&Tr1.fN+Tr1.fNDeadZone>5.5");
4085 //treetr->SetAlias("forbidden2","ND<2&&Tr1.fClIndex[0]>0&&Tr1.fClIndex[0]>0");
4086 //treetr->SetAlias("forbidden3","ND<1&&Tr1.fClIndex[0]>0");
4087 //treetr->SetAlias("forbidden4","ND<4&&Tr1.fNormChi2[0]<2");
4088 //treetr->SetAlias("forbidden5","ND<5&&Tr1.fNormChi2[0]<1");
4089 //-----------------------------------------------------------
4091 if (bestLong->GetNumberOfClusters()<4 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5) forbidden[itsindex]=kTRUE;
4092 if (normdist[itsindex]<3 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>5.5) forbidden[itsindex]=kTRUE;
4093 if (normdist[itsindex]<2 && bestConst->GetClIndex(0)>0 && bestConst->GetClIndex(1)>0 ) forbidden[itsindex]=kTRUE;
4094 if (normdist[itsindex]<1 && bestConst->GetClIndex(0)>0) forbidden[itsindex]=kTRUE;
4095 if (normdist[itsindex]<4 && bestConst->GetNormChi2(0)<2) forbidden[itsindex]=kTRUE;
4096 if (normdist[itsindex]<5 && bestConst->GetNormChi2(0)<1) forbidden[itsindex]=kTRUE;
4097 if (bestConst->GetNormChi2(0)<2.5) {
4098 minPointAngle[itsindex]= 0.9999;
4099 maxr[itsindex] = 10;
4103 //forbid daughter kink candidates
4105 if (esdtrack->GetKinkIndex(0)>0) forbidden[itsindex] = kTRUE;
4106 Bool_t isElectron = kTRUE;
4107 Bool_t isProton = kTRUE;
4109 esdtrack->GetESDpid(pid);
4110 for (Int_t i=1;i<5;i++){
4111 if (pid[0]<pid[i]) isElectron= kFALSE;
4112 if (pid[4]<pid[i]) isProton= kFALSE;
4115 forbidden[itsindex]=kFALSE;
4116 normdist[itsindex]*=-1;
4119 if (normdist[itsindex]>2) forbidden[itsindex]=kFALSE;
4120 normdist[itsindex]*=-1;
4124 // Causality cuts in TPC volume
4126 if (esdtrack->GetTPCdensity(0,10) >0.6) maxr[itsindex] = TMath::Min(Float_t(110),maxr[itsindex]);
4127 if (esdtrack->GetTPCdensity(10,30)>0.6) maxr[itsindex] = TMath::Min(Float_t(120),maxr[itsindex]);
4128 if (esdtrack->GetTPCdensity(20,40)>0.6) maxr[itsindex] = TMath::Min(Float_t(130),maxr[itsindex]);
4129 if (esdtrack->GetTPCdensity(30,50)>0.6) maxr[itsindex] = TMath::Min(Float_t(140),maxr[itsindex]);
4131 if (esdtrack->GetTPCdensity(0,60)<0.4&&bestLong->GetNumberOfClusters()<3) minr[itsindex]=100;
4137 "Tr1.="<<((bestConst)? bestConst:dummy)<<
4139 "Tr3.="<<&trackat0<<
4141 "Dist="<<dist[itsindex]<<
4142 "ND0="<<normdist0[itsindex]<<
4143 "ND1="<<normdist1[itsindex]<<
4144 "ND="<<normdist[itsindex]<<
4145 "Pz="<<primvertex[2]<<
4146 "Forbid="<<forbidden[itsindex]<<
4150 trackarray.AddAt(best,itsindex);
4151 trackarrayc.AddAt(bestConst,itsindex);
4152 trackarrayl.AddAt(bestLong,itsindex);
4153 new (&helixes[itsindex]) AliHelix(*best);
4158 // first iterration of V0 finder
4160 for (Int_t iesd0=0;iesd0<ntracks;iesd0++){
4161 Int_t itrack0 = itsmap[iesd0];
4162 if (forbidden[itrack0]) continue;
4163 AliITStrackMI * btrack0 = (AliITStrackMI*)trackarray.At(itrack0);
4164 if (!btrack0) continue;
4165 if (btrack0->GetSign()>0) continue;
4166 AliITStrackMI *trackc0 = (AliITStrackMI*)trackarrayc.At(itrack0);
4168 for (Int_t iesd1=0;iesd1<ntracks;iesd1++){
4169 Int_t itrack1 = itsmap[iesd1];
4170 if (forbidden[itrack1]) continue;
4172 AliITStrackMI * btrack1 = (AliITStrackMI*)trackarray.At(itrack1);
4173 if (!btrack1) continue;
4174 if (btrack1->GetSign()<0) continue;
4175 Bool_t isGold = kFALSE;
4176 if (TMath::Abs(TMath::Abs(btrack0->GetLabel())-TMath::Abs(btrack1->GetLabel()))==1){
4179 AliITStrackMI *trackc1 = (AliITStrackMI*)trackarrayc.At(itrack1);
4180 AliHelix &h1 = helixes[itrack0];
4181 AliHelix &h2 = helixes[itrack1];
4183 // find linear distance
4188 Double_t phase[2][2],radius[2];
4189 Int_t points = h1.GetRPHIintersections(h2, phase, radius);
4190 if (points==0) continue;
4191 Double_t delta[2]={1000000,1000000};
4193 h1.ParabolicDCA(h2,phase[0][0],phase[0][1],radius[0],delta[0]);
4195 if (radius[1]<rmin) rmin = radius[1];
4196 h1.ParabolicDCA(h2,phase[1][0],phase[1][1],radius[1],delta[1]);
4198 rmin = TMath::Sqrt(rmin);
4199 Double_t distance = 0;
4200 Double_t radiusC = 0;
4202 if (points==1 || delta[0]<delta[1]){
4203 distance = TMath::Sqrt(delta[0]);
4204 radiusC = TMath::Sqrt(radius[0]);
4206 distance = TMath::Sqrt(delta[1]);
4207 radiusC = TMath::Sqrt(radius[1]);
4210 if (radiusC<TMath::Max(minr[itrack0],minr[itrack1])) continue;
4211 if (radiusC>TMath::Min(maxr[itrack0],maxr[itrack1])) continue;
4212 Float_t maxDist = TMath::Min(kMaxDist,Float_t(kMaxDist0+radiusC*kMaxDist1));
4213 if (distance>maxDist) continue;
4214 Float_t pointAngle = h1.GetPointAngle(h2,phase[iphase],primvertex);
4215 if (pointAngle<TMath::Max(minPointAngle[itrack0],minPointAngle[itrack1])) continue;
4218 // Double_t distance = TestV0(h1,h2,pvertex,rmin);
4220 // if (distance>maxDist) continue;
4221 // if (pvertex->GetRr()<kMinR) continue;
4222 // if (pvertex->GetRr()>kMaxR) continue;
4223 AliITStrackMI * track0=btrack0;
4224 AliITStrackMI * track1=btrack1;
4225 // if (pvertex->GetRr()<3.5){
4227 //use longest tracks inside the pipe
4228 track0 = (AliITStrackMI*)trackarrayl.At(itrack0);
4229 track1 = (AliITStrackMI*)trackarrayl.At(itrack1);
4233 pvertex->SetParamN(*track0);
4234 pvertex->SetParamP(*track1);
4235 pvertex->Update(primvertex);
4236 pvertex->SetClusters(track0->ClIndex(),track1->ClIndex()); // register clusters
4238 if (pvertex->GetRr()<kMinR) continue;
4239 if (pvertex->GetRr()>kMaxR) continue;
4240 if (pvertex->GetV0CosineOfPointingAngle()<kMinPointAngle) continue;
4241 //Bo: if (pvertex->GetDist2()>maxDist) continue;
4242 if (pvertex->GetDcaV0Daughters()>maxDist) continue;
4243 //Bo: pvertex->SetLab(0,track0->GetLabel());
4244 //Bo: pvertex->SetLab(1,track1->GetLabel());
4245 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4246 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4248 AliITStrackMI * htrackc0 = trackc0 ? trackc0:dummy;
4249 AliITStrackMI * htrackc1 = trackc1 ? trackc1:dummy;
4253 TObjArray * array0b = (TObjArray*)fBestHypothesys.At(itrack0);
4254 if (!array0b&&pvertex->GetRr()<40 && TMath::Abs(track0->GetTgl())<1.1) {
4255 fCurrentEsdTrack = itrack0;
4256 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack0),itrack0, kFALSE);
4258 TObjArray * array1b = (TObjArray*)fBestHypothesys.At(itrack1);
4259 if (!array1b&&pvertex->GetRr()<40 && TMath::Abs(track1->GetTgl())<1.1) {
4260 fCurrentEsdTrack = itrack1;
4261 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack1),itrack1, kFALSE);
4264 AliITStrackMI * track0b = (AliITStrackMI*)fOriginal.At(itrack0);
4265 AliITStrackMI * track1b = (AliITStrackMI*)fOriginal.At(itrack1);
4266 AliITStrackMI * track0l = (AliITStrackMI*)fOriginal.At(itrack0);
4267 AliITStrackMI * track1l = (AliITStrackMI*)fOriginal.At(itrack1);
4269 Float_t minchi2before0=16;
4270 Float_t minchi2before1=16;
4271 Float_t minchi2after0 =16;
4272 Float_t minchi2after1 =16;
4273 Double_t xrp[3]; pvertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
4274 Int_t maxLayer = GetNearestLayer(xrp); //I.B.
4276 if (array0b) for (Int_t i=0;i<5;i++){
4277 // best track after vertex
4278 AliITStrackMI * btrack = (AliITStrackMI*)array0b->At(i);
4279 if (!btrack) continue;
4280 if (btrack->GetNumberOfClusters()>track0l->GetNumberOfClusters()) track0l = btrack;
4281 // if (btrack->fX<pvertex->GetRr()-2.-0.5/(0.1+pvertex->GetAnglep()[2])) {
4282 if (btrack->GetX()<pvertex->GetRr()-2.) {
4283 if ( (maxLayer>i+2|| (i==0)) && btrack->GetNumberOfClusters()==(6-i)&&i<3){
4286 if (maxLayer<3){ // take prim vertex as additional measurement
4287 if (normdist[itrack0]>0 && htrackc0){
4288 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack0]*normdist[itrack0],16.);
4290 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack0]*normdist[itrack0]+3.),16.);
4294 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4296 if (!btrack->GetClIndex(ilayer)){
4300 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4301 for (Int_t itrack=0;itrack<4;itrack++){
4302 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack0){
4303 sumchi2+=18.; //shared cluster
4307 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4308 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4312 if (sumchi2<minchi2before0) minchi2before0=sumchi2;
4314 continue; //safety space - Geo manager will give exact layer
4317 minchi2after0 = btrack->GetNormChi2(i);
4320 if (array1b) for (Int_t i=0;i<5;i++){
4321 // best track after vertex
4322 AliITStrackMI * btrack = (AliITStrackMI*)array1b->At(i);
4323 if (!btrack) continue;
4324 if (btrack->GetNumberOfClusters()>track1l->GetNumberOfClusters()) track1l = btrack;
4325 // if (btrack->fX<pvertex->GetRr()-2-0.5/(0.1+pvertex->GetAnglep()[2])){
4326 if (btrack->GetX()<pvertex->GetRr()-2){
4327 if ((maxLayer>i+2 || (i==0))&&btrack->GetNumberOfClusters()==(6-i)&&(i<3)){
4330 if (maxLayer<3){ // take prim vertex as additional measurement
4331 if (normdist[itrack1]>0 && htrackc1){
4332 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack1]*normdist[itrack1],16.);
4334 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack1]*normdist[itrack1]+3.),16.);
4338 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4340 if (!btrack->GetClIndex(ilayer)){
4344 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4345 for (Int_t itrack=0;itrack<4;itrack++){
4346 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack1){
4347 sumchi2+=18.; //shared cluster
4351 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4352 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4356 if (sumchi2<minchi2before1) minchi2before1=sumchi2;
4358 continue; //safety space - Geo manager will give exact layer
4361 minchi2after1 = btrack->GetNormChi2(i);
4365 // position resolution - used for DCA cut
4366 Float_t sigmad = track0b->GetSigmaY2()+track0b->GetSigmaZ2()+track1b->GetSigmaY2()+track1b->GetSigmaZ2()+
4367 (track0b->GetX()-pvertex->GetRr())*(track0b->GetX()-pvertex->GetRr())*(track0b->GetSigmaSnp2()+track0b->GetSigmaTgl2())+
4368 (track1b->GetX()-pvertex->GetRr())*(track1b->GetX()-pvertex->GetRr())*(track1b->GetSigmaSnp2()+track1b->GetSigmaTgl2());
4369 sigmad =TMath::Sqrt(sigmad)+0.04;
4370 if (pvertex->GetRr()>50){
4371 Double_t cov0[15],cov1[15];
4372 track0b->GetESDtrack()->GetInnerExternalCovariance(cov0);
4373 track1b->GetESDtrack()->GetInnerExternalCovariance(cov1);
4374 sigmad = cov0[0]+cov0[2]+cov1[0]+cov1[2]+
4375 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov0[5]+cov0[9])+
4376 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov1[5]+cov1[9]);
4377 sigmad =TMath::Sqrt(sigmad)+0.05;
4381 vertex2.SetParamN(*track0b);
4382 vertex2.SetParamP(*track1b);
4383 vertex2.Update(primvertex);
4384 //Bo: if (vertex2.GetDist2()<=pvertex->GetDist2()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4385 if (vertex2.GetDcaV0Daughters()<=pvertex->GetDcaV0Daughters()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4386 pvertex->SetParamN(*track0b);
4387 pvertex->SetParamP(*track1b);
4388 pvertex->Update(primvertex);
4389 pvertex->SetClusters(track0b->ClIndex(),track1b->ClIndex()); // register clusters
4390 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4391 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4393 pvertex->SetDistSigma(sigmad);
4394 //Bo: pvertex->SetDistNorm(pvertex->GetDist2()/sigmad);
4395 pvertex->SetNormDCAPrim(normdist[itrack0],normdist[itrack1]);
4397 // define likelihhod and causalities
4399 Float_t pa0=1, pa1=1, pb0=0.26, pb1=0.26;
4401 Float_t fnorm0 = normdist[itrack0];
4402 if (fnorm0<0) fnorm0*=-3;
4403 Float_t fnorm1 = normdist[itrack1];
4404 if (fnorm1<0) fnorm1*=-3;
4405 if (pvertex->GetAnglep()[2]>0.1 || (pvertex->GetRr()<10.5)&& pvertex->GetAnglep()[2]>0.05 || pvertex->GetRr()<3){
4406 pb0 = TMath::Exp(-TMath::Min(fnorm0,Float_t(16.))/12.);
4407 pb1 = TMath::Exp(-TMath::Min(fnorm1,Float_t(16.))/12.);
4409 pvertex->SetChi2Before(normdist[itrack0]);
4410 pvertex->SetChi2After(normdist[itrack1]);
4411 pvertex->SetNAfter(0);
4412 pvertex->SetNBefore(0);
4414 pvertex->SetChi2Before(minchi2before0);
4415 pvertex->SetChi2After(minchi2before1);
4416 if (pvertex->GetAnglep()[2]>0.1 || ( pvertex->GetRr()<10.5 && pvertex->GetAnglep()[2]>0.05) || pvertex->GetRr()<3){
4417 pb0 = TMath::Exp(-TMath::Min(minchi2before0,Float_t(16))/12.);
4418 pb1 = TMath::Exp(-TMath::Min(minchi2before1,Float_t(16))/12.);
4420 pvertex->SetNAfter(maxLayer);
4421 pvertex->SetNBefore(maxLayer);
4423 if (pvertex->GetRr()<90){
4424 pa0 *= TMath::Min(track0->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4425 pa1 *= TMath::Min(track1->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4427 if (pvertex->GetRr()<20){
4428 pa0 *= (0.2+TMath::Exp(-TMath::Min(minchi2after0,Float_t(16))/8.))/1.2;
4429 pa1 *= (0.2+TMath::Exp(-TMath::Min(minchi2after1,Float_t(16))/8.))/1.2;
4432 pvertex->SetCausality(pb0,pb1,pa0,pa1);
4434 // Likelihood calculations - apply cuts
4436 Bool_t v0OK = kTRUE;
4437 Float_t p12 = pvertex->GetParamP()->GetParameter()[4]*pvertex->GetParamP()->GetParameter()[4];
4438 p12 += pvertex->GetParamN()->GetParameter()[4]*pvertex->GetParamN()->GetParameter()[4];
4439 p12 = TMath::Sqrt(p12); // "mean" momenta
4440 Float_t sigmap0 = 0.0001+0.001/(0.1+pvertex->GetRr());
4441 Float_t sigmap = 0.5*sigmap0*(0.6+0.4*p12); // "resolution: of point angle - as a function of radius and momenta
4443 Float_t causalityA = (1.0-pvertex->GetCausalityP()[0])*(1.0-pvertex->GetCausalityP()[1]);
4444 Float_t causalityB = TMath::Sqrt(TMath::Min(pvertex->GetCausalityP()[2],Double_t(0.7))*
4445 TMath::Min(pvertex->GetCausalityP()[3],Double_t(0.7)));
4447 //Bo: Float_t likelihood0 = (TMath::Exp(-pvertex->GetDistNorm())+0.1) *(pvertex->GetDist2()<0.5)*(pvertex->GetDistNorm()<5);
4448 Float_t lDistNorm = pvertex->GetDcaV0Daughters()/pvertex->GetDistSigma();
4449 Float_t likelihood0 = (TMath::Exp(-lDistNorm)+0.1) *(pvertex->GetDcaV0Daughters()<0.5)*(lDistNorm<5);
4451 Float_t likelihood1 = TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/sigmap)+
4452 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(4.*sigmap))+
4453 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(8.*sigmap))+
4454 0.1*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/0.01);
4456 if (causalityA<kCausality0Cut) v0OK = kFALSE;
4457 if (TMath::Sqrt(likelihood0*likelihood1)<kLikelihood01Cut) v0OK = kFALSE;
4458 if (likelihood1<kLikelihood1Cut) v0OK = kFALSE;
4459 if (TMath::Power(likelihood0*likelihood1*causalityB,0.33)<kCombinedCut) v0OK = kFALSE;
4464 Bool_t gold = TMath::Abs(TMath::Abs(track0->GetLabel())-TMath::Abs(track1->GetLabel()))==1;
4466 "Tr0.="<<track0<< //best without constrain
4467 "Tr1.="<<track1<< //best without constrain
4468 "Tr0B.="<<track0b<< //best without constrain after vertex
4469 "Tr1B.="<<track1b<< //best without constrain after vertex
4470 "Tr0C.="<<htrackc0<< //best with constrain if exist
4471 "Tr1C.="<<htrackc1<< //best with constrain if exist
4472 "Tr0L.="<<track0l<< //longest best
4473 "Tr1L.="<<track1l<< //longest best
4474 "Esd0.="<<track0->GetESDtrack()<< // esd track0 params
4475 "Esd1.="<<track1->GetESDtrack()<< // esd track1 params
4476 "V0.="<<pvertex<< //vertex properties
4477 "V0b.="<<&vertex2<< //vertex properties at "best" track
4478 "ND0="<<normdist[itrack0]<< //normalize distance for track0
4479 "ND1="<<normdist[itrack1]<< //normalize distance for track1
4481 // "RejectBase="<<rejectBase<< //rejection in First itteration
4487 //if (rejectBase) continue;
4489 pvertex->SetStatus(0);
4490 // if (rejectBase) {
4491 // pvertex->SetStatus(-100);
4493 if (pvertex->GetV0CosineOfPointingAngle()>kMinPointAngle2) {
4494 //Bo: pvertex->SetESDindexes(track0->GetESDtrack()->GetID(),track1->GetESDtrack()->GetID());
4495 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());//Bo: consistency 0 for neg
4496 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());//Bo: consistency 1 for pos
4498 // AliV0vertex vertexjuri(*track0,*track1);
4499 // vertexjuri.SetESDindexes(track0->fESDtrack->GetID(),track1->fESDtrack->GetID());
4500 // event->AddV0(&vertexjuri);
4501 pvertex->SetStatus(100);
4503 pvertex->SetOnFlyStatus(kTRUE);
4504 pvertex->ChangeMassHypothesis(kK0Short);
4505 event->AddV0(pvertex);
4511 // delete temporary arrays
4514 delete[] minPointAngle;
4526 //------------------------------------------------------------------------
4527 void AliITStrackerMI::RefitV02(AliESDEvent *event)
4530 //try to refit V0s in the third path of the reconstruction
4532 TTreeSRedirector &cstream = *fDebugStreamer;
4534 Int_t nv0s = event->GetNumberOfV0s();
4535 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
4537 for (Int_t iv0 = 0; iv0<nv0s;iv0++){
4538 AliV0 * v0mi = (AliV0*)event->GetV0(iv0);
4539 if (!v0mi) continue;
4540 Int_t itrack0 = v0mi->GetIndex(0);
4541 Int_t itrack1 = v0mi->GetIndex(1);
4542 AliESDtrack *esd0 = event->GetTrack(itrack0);
4543 AliESDtrack *esd1 = event->GetTrack(itrack1);
4544 if (!esd0||!esd1) continue;
4545 AliITStrackMI tpc0(*esd0);
4546 AliITStrackMI tpc1(*esd1);
4547 Double_t x,y,z; v0mi->GetXYZ(x,y,z); //I.B.
4548 Double_t alpha =TMath::ATan2(y,x); //I.B.
4549 if (v0mi->GetRr()>85){
4550 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4551 v0temp.SetParamN(tpc0);
4552 v0temp.SetParamP(tpc1);
4553 v0temp.Update(primvertex);
4554 if (kFALSE) cstream<<"Refit"<<
4556 "V0refit.="<<&v0temp<<
4560 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4561 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4562 v0mi->SetParamN(tpc0);
4563 v0mi->SetParamP(tpc1);
4564 v0mi->Update(primvertex);
4569 if (v0mi->GetRr()>35){
4570 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4571 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4572 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4573 v0temp.SetParamN(tpc0);
4574 v0temp.SetParamP(tpc1);
4575 v0temp.Update(primvertex);
4576 if (kFALSE) cstream<<"Refit"<<
4578 "V0refit.="<<&v0temp<<
4582 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4583 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4584 v0mi->SetParamN(tpc0);
4585 v0mi->SetParamP(tpc1);
4586 v0mi->Update(primvertex);
4591 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4592 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4593 // if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4594 if (RefitAt(v0mi->GetRr(),&tpc0, v0mi->GetClusters(0)) && RefitAt(v0mi->GetRr(),&tpc1, v0mi->GetClusters(1))){
4595 v0temp.SetParamN(tpc0);
4596 v0temp.SetParamP(tpc1);
4597 v0temp.Update(primvertex);
4598 if (kFALSE) cstream<<"Refit"<<
4600 "V0refit.="<<&v0temp<<
4604 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4605 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4606 v0mi->SetParamN(tpc0);
4607 v0mi->SetParamP(tpc1);
4608 v0mi->Update(primvertex);
4613 //------------------------------------------------------------------------
4614 void AliITStrackerMI::BuildMaterialLUT(TString material) {
4615 //--------------------------------------------------------------------
4616 // Fill a look-up table with mean material
4617 //--------------------------------------------------------------------
4621 Double_t point1[3],point2[3];
4622 Double_t phi,cosphi,sinphi,z;
4623 // 0-5 layers, 6 pipe, 7-8 shields
4624 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
4625 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
4627 Int_t ifirst=0,ilast=0;
4628 if(material.Contains("Pipe")) {
4630 } else if(material.Contains("Shields")) {
4632 } else if(material.Contains("Layers")) {
4635 Error("BuildMaterialLUT","Wrong layer name\n");
4638 for(Int_t imat=ifirst; imat<=ilast; imat++) {
4639 Double_t param[5]={0.,0.,0.,0.,0.};
4640 for (Int_t i=0; i<n; i++) {
4641 phi = 2.*TMath::Pi()*gRandom->Rndm();
4642 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
4643 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
4644 point1[0] = rmin[imat]*cosphi;
4645 point1[1] = rmin[imat]*sinphi;
4647 point2[0] = rmax[imat]*cosphi;
4648 point2[1] = rmax[imat]*sinphi;
4650 AliTracker::MeanMaterialBudget(point1,point2,mparam);
4651 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
4653 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
4655 fxOverX0Layer[imat] = param[1];
4656 fxTimesRhoLayer[imat] = param[0]*param[4];
4657 } else if(imat==6) {
4658 fxOverX0Pipe = param[1];
4659 fxTimesRhoPipe = param[0]*param[4];
4660 } else if(imat==7) {
4661 fxOverX0Shield[0] = param[1];
4662 fxTimesRhoShield[0] = param[0]*param[4];
4663 } else if(imat==8) {
4664 fxOverX0Shield[1] = param[1];
4665 fxTimesRhoShield[1] = param[0]*param[4];
4669 printf("%s\n",material.Data());
4670 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
4671 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
4672 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
4673 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
4674 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
4675 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
4676 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
4677 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
4678 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
4682 //------------------------------------------------------------------------
4683 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
4684 TString direction) {
4685 //-------------------------------------------------------------------
4686 // Propagate beyond beam pipe and correct for material
4687 // (material budget in different ways according to fUseTGeo value)
4688 //-------------------------------------------------------------------
4690 // Define budget mode:
4691 // 0: material from AliITSRecoParam (hard coded)
4692 // 1: material from TGeo (on the fly)
4693 // 2: material from lut
4694 // 3: material from TGeo (same for all hypotheses)
4707 if(fTrackingPhase.Contains("Clusters2Tracks"))
4708 { mode=3; } else { mode=1; }
4711 if(fTrackingPhase.Contains("Clusters2Tracks"))
4712 { mode=3; } else { mode=2; }
4718 if(fTrackingPhase.Contains("Default")) mode=0;
4720 Int_t index=fCurrentEsdTrack;
4722 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4723 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4724 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4726 Double_t xOverX0,x0,lengthTimesMeanDensity;
4727 Bool_t anglecorr=kTRUE;
4731 xOverX0 = AliITSRecoParam::GetdPipe();
4732 x0 = AliITSRecoParam::GetX0Be();
4733 lengthTimesMeanDensity = xOverX0*x0;
4736 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4740 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4741 xOverX0 = fxOverX0Pipe;
4742 lengthTimesMeanDensity = fxTimesRhoPipe;
4745 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4746 if(fxOverX0PipeTrks[index]<0) {
4747 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4748 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4749 (1.-t->GetSnp()*t->GetSnp()));
4750 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4751 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4754 xOverX0 = fxOverX0PipeTrks[index];
4755 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4759 lengthTimesMeanDensity *= dir;
4761 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4762 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4766 //------------------------------------------------------------------------
4767 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4769 TString direction) {
4770 //-------------------------------------------------------------------
4771 // Propagate beyond SPD or SDD shield and correct for material
4772 // (material budget in different ways according to fUseTGeo value)
4773 //-------------------------------------------------------------------
4775 // Define budget mode:
4776 // 0: material from AliITSRecoParam (hard coded)
4777 // 1: material from TGeo (on the fly)
4778 // 2: material from lut
4779 // 3: material from TGeo (same for all hypotheses)
4792 if(fTrackingPhase.Contains("Clusters2Tracks"))
4793 { mode=3; } else { mode=1; }
4796 if(fTrackingPhase.Contains("Clusters2Tracks"))
4797 { mode=3; } else { mode=2; }
4803 if(fTrackingPhase.Contains("Default")) mode=0;
4805 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4807 Int_t shieldindex=0;
4808 if (shield.Contains("SDD")) { // SDDouter
4809 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4811 } else if (shield.Contains("SPD")) { // SPDouter
4812 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4815 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4818 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4820 Int_t index=2*fCurrentEsdTrack+shieldindex;
4822 Double_t xOverX0,x0,lengthTimesMeanDensity;
4823 Bool_t anglecorr=kTRUE;
4827 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4828 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4829 lengthTimesMeanDensity = xOverX0*x0;
4832 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4836 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4837 xOverX0 = fxOverX0Shield[shieldindex];
4838 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4841 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4842 if(fxOverX0ShieldTrks[index]<0) {
4843 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4844 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4845 (1.-t->GetSnp()*t->GetSnp()));
4846 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4847 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4850 xOverX0 = fxOverX0ShieldTrks[index];
4851 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4855 lengthTimesMeanDensity *= dir;
4857 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4858 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4862 //------------------------------------------------------------------------
4863 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4865 Double_t oldGlobXYZ[3],
4866 TString direction) {
4867 //-------------------------------------------------------------------
4868 // Propagate beyond layer and correct for material
4869 // (material budget in different ways according to fUseTGeo value)
4870 //-------------------------------------------------------------------
4872 // Define budget mode:
4873 // 0: material from AliITSRecoParam (hard coded)
4874 // 1: material from TGeo (on the fly)
4875 // 2: material from lut
4876 // 3: material from TGeo (same for all hypotheses)
4889 if(fTrackingPhase.Contains("Clusters2Tracks"))
4890 { mode=3; } else { mode=1; }
4893 if(fTrackingPhase.Contains("Clusters2Tracks"))
4894 { mode=3; } else { mode=2; }
4900 if(fTrackingPhase.Contains("Default")) mode=0;
4902 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4904 Double_t r=fgLayers[layerindex].GetR();
4905 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4907 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4908 Double_t xToGo; t->GetLocalXat(rToGo,xToGo);
4910 Int_t index=6*fCurrentEsdTrack+layerindex;
4912 // Bring the track beyond the material
4913 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4914 Double_t globXYZ[3];
4917 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4919 Bool_t anglecorr=kTRUE;
4923 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4924 lengthTimesMeanDensity = xOverX0*x0;
4927 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4928 if(mparam[1]>900000) return 0;
4930 lengthTimesMeanDensity=mparam[0]*mparam[4];
4934 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4935 xOverX0 = fxOverX0Layer[layerindex];
4936 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4939 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4940 if(fxOverX0LayerTrks[index]<0) {
4941 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4942 if(mparam[1]>900000) return 0;
4943 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4944 (1.-t->GetSnp()*t->GetSnp()));
4945 xOverX0=mparam[1]/angle;
4946 lengthTimesMeanDensity=mparam[0]*mparam[4]/angle;
4947 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0);
4948 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity);
4950 xOverX0 = fxOverX0LayerTrks[index];
4951 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4955 lengthTimesMeanDensity *= dir;
4957 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4961 //------------------------------------------------------------------------
4962 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4963 //-----------------------------------------------------------------
4964 // Initialize LUT for storing material for each prolonged track
4965 //-----------------------------------------------------------------
4966 fxOverX0PipeTrks = new Float_t[ntracks];
4967 fxTimesRhoPipeTrks = new Float_t[ntracks];
4968 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4969 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4970 fxOverX0LayerTrks = new Float_t[ntracks*6];
4971 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4973 for(Int_t i=0; i<ntracks; i++) {
4974 fxOverX0PipeTrks[i] = -1.;
4975 fxTimesRhoPipeTrks[i] = -1.;
4977 for(Int_t j=0; j<ntracks*2; j++) {
4978 fxOverX0ShieldTrks[j] = -1.;
4979 fxTimesRhoShieldTrks[j] = -1.;
4981 for(Int_t k=0; k<ntracks*6; k++) {
4982 fxOverX0LayerTrks[k] = -1.;
4983 fxTimesRhoLayerTrks[k] = -1.;
4990 //------------------------------------------------------------------------
4991 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4992 //-----------------------------------------------------------------
4993 // Delete LUT for storing material for each prolonged track
4994 //-----------------------------------------------------------------
4995 if(fxOverX0PipeTrks) {
4996 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4998 if(fxOverX0ShieldTrks) {
4999 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
5002 if(fxOverX0LayerTrks) {
5003 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
5005 if(fxTimesRhoPipeTrks) {
5006 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
5008 if(fxTimesRhoShieldTrks) {
5009 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
5011 if(fxTimesRhoLayerTrks) {
5012 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
5016 //------------------------------------------------------------------------
5017 Int_t AliITStrackerMI::CheckSkipLayer(AliITStrackMI *track,
5018 Int_t ilayer,Int_t idet) const {
5019 //-----------------------------------------------------------------
5020 // This method is used to decide whether to allow a prolongation
5021 // without clusters, because we want to skip the layer.
5022 // In this case the return value is > 0:
5023 // return 1: the user requested to skip a layer
5024 // return 2: track outside z acceptance of SSD/SDD and will cross both SPD
5025 //-----------------------------------------------------------------
5027 if (AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) return 1;
5029 if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
5030 // check if track will cross SPD outer layer
5031 Double_t phiAtSPD2,zAtSPD2;
5032 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
5033 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
5039 //------------------------------------------------------------------------
5040 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
5041 Int_t ilayer,Int_t idet,
5042 Double_t dz,Double_t dy,
5043 Bool_t noClusters) const {
5044 //-----------------------------------------------------------------
5045 // This method is used to decide whether to allow a prolongation
5046 // without clusters, because there is a dead zone in the road.
5047 // In this case the return value is > 0:
5048 // return 1: dead zone at z=0,+-7cm in SPD
5049 // return 2: all road is "bad" (dead or noisy) from the OCDB
5050 // return 3: something "bad" (dead or noisy) from the OCDB
5051 //-----------------------------------------------------------------
5053 // check dead zones at z=0,+-7cm in the SPD
5054 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
5055 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
5056 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
5057 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
5058 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
5059 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
5060 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
5061 for (Int_t i=0; i<3; i++)
5062 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) return 1;
5065 // check bad zones from OCDB
5066 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
5068 if (idet<0) return 0;
5070 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
5072 // check if this detector is bad
5074 //printf("lay %d bad detector %d\n",ilayer,idet);
5079 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
5080 if (ilayer==0 || ilayer==1) { // ---------- SPD
5082 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
5084 detSizeFactorX *= 2.;
5085 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
5088 AliITSsegmentation *segm = (AliITSsegmentation*)fDetTypeRec->GetSegmentationModel(detType);
5089 if (detType==2) segm->SetLayer(ilayer+1);
5090 Float_t detSizeX = detSizeFactorX*segm->Dx();
5091 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
5093 // check if the road overlaps with bad chips
5095 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
5096 Float_t zlocmin = zloc-dz;
5097 Float_t zlocmax = zloc+dz;
5098 Float_t xlocmin = xloc-dy;
5099 Float_t xlocmax = xloc+dy;
5100 Int_t chipsInRoad[100];
5102 if (TMath::Max(TMath::Abs(xlocmin),TMath::Abs(xlocmax))>0.5*detSizeX ||
5103 TMath::Max(TMath::Abs(zlocmin),TMath::Abs(zlocmax))>0.5*detSizeZ) return 0;
5104 //printf("lay %d det %d zmim zmax %f %f xmin xmax %f %f %f %f\n",ilayer,idet,zlocmin,zlocmax,xlocmin,xlocmax,segm->Dx(),segm->Dz());
5105 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
5106 //printf("lay %d nChipsInRoad %d\n",ilayer,nChipsInRoad);
5107 if (!nChipsInRoad) return 0;
5109 Bool_t anyBad=kFALSE,anyGood=kFALSE;
5110 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
5111 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
5112 //printf(" chip %d bad %d\n",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh]));
5113 if (det.IsChipBad(chipsInRoad[iCh])) {
5120 if (!anyGood) return 2; // all chips in road are bad
5122 if (anyBad) return 3; // at least a bad chip in road
5125 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
5126 || ilayer==4 || ilayer==5 // SSD
5127 || !noClusters) return 0;
5129 // There are no clusters in road: check if there is at least
5130 // a bad SPD pixel or SDD anode
5132 if(ilayer==1 || ilayer==3 || ilayer==5)
5133 idet += AliITSgeomTGeo::GetNLadders(ilayer)*AliITSgeomTGeo::GetNDetectors(ilayer);
5135 //if (fITSChannelStatus->AnyBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax)) return 3;
5137 if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
5141 //------------------------------------------------------------------------
5142 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
5143 AliITStrackMI *track,
5144 Float_t &xloc,Float_t &zloc) const {
5145 //-----------------------------------------------------------------
5146 // Gives position of track in local module ref. frame
5147 //-----------------------------------------------------------------
5152 if(idet<0) return kFALSE;
5154 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
5156 Int_t lad = Int_t(idet/ndet) + 1;
5158 Int_t det = idet - (lad-1)*ndet + 1;
5160 Double_t xyzGlob[3],xyzLoc[3];
5162 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
5163 // take into account the misalignment: xyz at real detector plane
5164 track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob);
5166 AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc);
5168 xloc = (Float_t)xyzLoc[0];
5169 zloc = (Float_t)xyzLoc[2];
5173 //------------------------------------------------------------------------
5174 Bool_t AliITStrackerMI::IsOKForPlaneEff(AliITStrackMI* track, Int_t ilayer) const {
5176 // Method to be optimized further:
5177 // Aim: decide whether a track can be used for PlaneEff evaluation
5178 // the decision is taken based on the track quality at the layer under study
5179 // no information on the clusters on this layer has to be used
5180 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
5181 // the cut is done on number of sigmas from the boundaries
5183 // Input: Actual track, layer [0,5] under study
5185 // Return: kTRUE if this is a good track
5187 // it will apply a pre-selection to obtain good quality tracks.
5188 // Here also you will have the possibility to put a control on the
5189 // impact point of the track on the basic block, in order to exclude border regions
5190 // this will be done by calling a proper method of the AliITSPlaneEff class.
5192 // input: AliITStrackMI* track, ilayer= layer number [0,5]
5193 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
5195 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
5196 AliITSlayer &layer=fgLayers[ilayer];
5197 Double_t r=layer.GetR();
5198 AliITStrackMI tmp(*track);
5202 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
5203 Int_t idet=layer.FindDetectorIndex(phi,z);
5204 if(idet<0) { AliInfo(Form("cannot find detector"));
5207 // here check if it has good Chi Square.
5209 //propagate to the intersection with the detector plane
5210 const AliITSdetector &det=layer.GetDetector(idet);
5211 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
5215 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
5216 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5217 if(key>fPlaneEff->Nblock()) return kFALSE;
5218 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
5219 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
5221 // DEFINITION OF SEARCH ROAD FOR accepting a track
5223 //For the time being they are hard-wired, later on from AliITSRecoParam
5224 // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
5225 // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
5228 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
5229 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
5230 // done for RecPoints
5232 // exclude tracks at boundary between detectors
5233 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
5234 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
5235 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
5236 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
5237 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
5239 if ( (locx-dx < blockXmn+boundaryWidth) ||
5240 (locx+dx > blockXmx-boundaryWidth) ||
5241 (locz-dz < blockZmn+boundaryWidth) ||
5242 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
5245 //------------------------------------------------------------------------
5246 void AliITStrackerMI::UseTrackForPlaneEff(AliITStrackMI* track, Int_t ilayer) {
5248 // This Method has to be optimized! For the time-being it uses the same criteria
5249 // as those used in the search of extra clusters for overlapping modules.
5251 // Method Purpose: estabilish whether a track has produced a recpoint or not
5252 // in the layer under study (For Plane efficiency)
5254 // inputs: AliITStrackMI* track (pointer to a usable track)
5256 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
5257 // traversed by this very track. In details:
5258 // - if a cluster can be associated to the track then call
5259 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
5260 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
5263 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
5264 AliITSlayer &layer=fgLayers[ilayer];
5265 Double_t r=layer.GetR();
5266 AliITStrackMI tmp(*track);
5270 if (!tmp.GetPhiZat(r,phi,z)) return;
5271 Int_t idet=layer.FindDetectorIndex(phi,z);
5273 if(idet<0) { AliInfo(Form("cannot find detector"));
5277 //propagate to the intersection with the detector plane
5278 const AliITSdetector &det=layer.GetDetector(idet);
5279 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
5283 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
5285 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
5286 TMath::Sqrt(tmp.GetSigmaZ2() +
5287 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5288 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5289 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
5290 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
5291 TMath::Sqrt(tmp.GetSigmaY2() +
5292 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5293 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5294 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
5296 // road in global (rphi,z) [i.e. in tracking ref. system]
5297 Double_t zmin = tmp.GetZ() - dz;
5298 Double_t zmax = tmp.GetZ() + dz;
5299 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
5300 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
5302 // select clusters in road
5303 layer.SelectClusters(zmin,zmax,ymin,ymax);
5305 // Define criteria for track-cluster association
5306 Double_t msz = tmp.GetSigmaZ2() +
5307 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5308 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5309 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
5310 Double_t msy = tmp.GetSigmaY2() +
5311 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5312 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5313 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
5314 if (tmp.GetConstrain()) {
5315 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
5316 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
5318 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
5319 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
5321 msz = 1./msz; // 1/RoadZ^2
5322 msy = 1./msy; // 1/RoadY^2
5325 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
5327 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
5328 //Double_t tolerance=0.2;
5329 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
5330 idetc = cl->GetDetectorIndex();
5331 if(idet!=idetc) continue;
5332 //Int_t ilay = cl->GetLayer();
5334 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
5335 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
5337 Double_t chi2=tmp.GetPredictedChi2(cl);
5338 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
5342 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
5344 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
5345 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5346 if(key>fPlaneEff->Nblock()) return;
5347 Bool_t found=kFALSE;
5350 while ((cl=layer.GetNextCluster(clidx))!=0) {
5351 idetc = cl->GetDetectorIndex();
5352 if(idet!=idetc) continue;
5353 // here real control to see whether the cluster can be associated to the track.
5354 // cluster not associated to track
5355 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
5356 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
5357 // calculate track-clusters chi2
5358 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
5359 // in particular, the error associated to the cluster
5360 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
5362 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
5364 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
5365 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
5366 // track->SetExtraModule(ilayer,idetExtra);
5368 if(!fPlaneEff->UpDatePlaneEff(found,key))
5369 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
5370 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
5371 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
5372 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
5373 Int_t cltype[2]={-999,-999};
5377 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
5378 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
5381 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
5382 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
5383 cltype[0]=layer.GetCluster(ci)->GetNy();
5384 cltype[1]=layer.GetCluster(ci)->GetNz();
5386 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
5387 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
5388 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
5389 // It is computed properly by calling the method
5390 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
5392 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
5393 //if (tmp.PropagateTo(x,0.,0.)) {
5394 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
5395 AliCluster c(*layer.GetCluster(ci));
5396 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
5397 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
5398 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
5399 clu[2]=TMath::Sqrt(c.GetSigmaY2());
5400 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
5403 fPlaneEff->FillHistos(key,found,tr,clu,cltype);