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 <TDatabasePDG.h>
34 #include <TTreeStream.h>
38 #include "AliITSPlaneEff.h"
39 #include "AliITSCalibrationSPD.h"
40 #include "AliITSCalibrationSDD.h"
41 #include "AliITSCalibrationSSD.h"
42 #include "AliCDBEntry.h"
43 #include "AliCDBManager.h"
44 #include "AliAlignObj.h"
45 #include "AliTrackPointArray.h"
46 #include "AliESDVertex.h"
47 #include "AliESDEvent.h"
48 #include "AliESDtrack.h"
51 #include "AliITSChannelStatus.h"
52 #include "AliITSDetTypeRec.h"
53 #include "AliITSRecPoint.h"
54 #include "AliITSgeomTGeo.h"
55 #include "AliITSReconstructor.h"
56 #include "AliITSClusterParam.h"
57 #include "AliITSsegmentation.h"
58 #include "AliITSCalibration.h"
59 #include "AliITSPlaneEffSPD.h"
60 #include "AliITSPlaneEffSDD.h"
61 #include "AliITSPlaneEffSSD.h"
62 #include "AliITSV0Finder.h"
63 #include "AliITStrackerMI.h"
65 ClassImp(AliITStrackerMI)
67 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
69 AliITStrackerMI::AliITStrackerMI():AliTracker(),
79 fLastLayerToTrackTo(0),
82 fTrackingPhase("Default"),
88 fxTimesRhoPipeTrks(0),
89 fxOverX0ShieldTrks(0),
90 fxTimesRhoShieldTrks(0),
92 fxTimesRhoLayerTrks(0),
99 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
100 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
101 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
103 //------------------------------------------------------------------------
104 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
105 fI(AliITSgeomTGeo::GetNLayers()),
114 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
117 fTrackingPhase("Default"),
123 fxTimesRhoPipeTrks(0),
124 fxOverX0ShieldTrks(0),
125 fxTimesRhoShieldTrks(0),
126 fxOverX0LayerTrks(0),
127 fxTimesRhoLayerTrks(0),
129 fITSChannelStatus(0),
132 //--------------------------------------------------------------------
133 //This is the AliITStrackerMI constructor
134 //--------------------------------------------------------------------
136 AliWarning("\"geom\" is actually a dummy argument !");
142 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
143 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
144 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
146 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
147 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
148 Double_t poff=TMath::ATan2(y,x);
150 Double_t r=TMath::Sqrt(x*x + y*y);
152 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
153 r += TMath::Sqrt(x*x + y*y);
154 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
155 r += TMath::Sqrt(x*x + y*y);
156 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
157 r += TMath::Sqrt(x*x + y*y);
160 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
162 for (Int_t j=1; j<nlad+1; j++) {
163 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
164 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
165 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
167 Double_t txyz[3]={0.};
168 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
169 m.LocalToMaster(txyz,xyz);
170 r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
171 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
173 if (phi<0) phi+=TMath::TwoPi();
174 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
176 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
177 new(&det) AliITSdetector(r,phi);
178 // compute the real radius (with misalignment)
179 TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
181 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
182 mmisal.LocalToMaster(txyz,xyz);
183 Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
184 det.SetRmisal(rmisal);
186 } // end loop on detectors
187 } // end loop on ladders
188 } // end loop on layers
191 fI=AliITSgeomTGeo::GetNLayers();
194 fConstraint[0]=1; fConstraint[1]=0;
196 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
197 AliITSReconstructor::GetRecoParam()->GetYVdef(),
198 AliITSReconstructor::GetRecoParam()->GetZVdef()};
199 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
200 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
201 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
202 SetVertex(xyzVtx,ersVtx);
204 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=AliITSRecoParam::GetLayersNotToSkip(i);
205 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
206 for (Int_t i=0;i<100000;i++){
207 fBestTrackIndex[i]=0;
210 // store positions of centre of SPD modules (in z)
212 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
213 fSPDdetzcentre[0] = tr[2];
214 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
215 fSPDdetzcentre[1] = tr[2];
216 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
217 fSPDdetzcentre[2] = tr[2];
218 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
219 fSPDdetzcentre[3] = tr[2];
221 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
222 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
223 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
227 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
228 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
230 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
232 // only for plane efficiency evaluation
233 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
234 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
235 Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
236 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane))
237 AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
238 if (iplane<2) fPlaneEff = new AliITSPlaneEffSPD();
239 else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
240 else fPlaneEff = new AliITSPlaneEffSSD();
241 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
242 if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
243 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
246 //------------------------------------------------------------------------
247 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
249 fBestTrack(tracker.fBestTrack),
250 fTrackToFollow(tracker.fTrackToFollow),
251 fTrackHypothesys(tracker.fTrackHypothesys),
252 fBestHypothesys(tracker.fBestHypothesys),
253 fOriginal(tracker.fOriginal),
254 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
255 fPass(tracker.fPass),
256 fAfterV0(tracker.fAfterV0),
257 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
258 fCoefficients(tracker.fCoefficients),
260 fTrackingPhase(tracker.fTrackingPhase),
261 fUseTGeo(tracker.fUseTGeo),
262 fNtracks(tracker.fNtracks),
263 fxOverX0Pipe(tracker.fxOverX0Pipe),
264 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
266 fxTimesRhoPipeTrks(0),
267 fxOverX0ShieldTrks(0),
268 fxTimesRhoShieldTrks(0),
269 fxOverX0LayerTrks(0),
270 fxTimesRhoLayerTrks(0),
271 fDebugStreamer(tracker.fDebugStreamer),
272 fITSChannelStatus(tracker.fITSChannelStatus),
273 fkDetTypeRec(tracker.fkDetTypeRec),
274 fPlaneEff(tracker.fPlaneEff) {
278 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
281 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
282 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
285 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
286 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
289 //------------------------------------------------------------------------
290 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
291 //Assignment operator
292 this->~AliITStrackerMI();
293 new(this) AliITStrackerMI(tracker);
296 //------------------------------------------------------------------------
297 AliITStrackerMI::~AliITStrackerMI()
302 if (fCoefficients) delete [] fCoefficients;
303 DeleteTrksMaterialLUT();
304 if (fDebugStreamer) {
305 //fDebugStreamer->Close();
306 delete fDebugStreamer;
308 if(fITSChannelStatus) delete fITSChannelStatus;
309 if(fPlaneEff) delete fPlaneEff;
311 //------------------------------------------------------------------------
312 void AliITStrackerMI::SetLayersNotToSkip(const Int_t *l) {
313 //--------------------------------------------------------------------
314 //This function set masks of the layers which must be not skipped
315 //--------------------------------------------------------------------
316 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=l[i];
318 //------------------------------------------------------------------------
319 void AliITStrackerMI::ReadBadFromDetTypeRec() {
320 //--------------------------------------------------------------------
321 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
323 //--------------------------------------------------------------------
325 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
327 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
329 if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
332 if(fITSChannelStatus) delete fITSChannelStatus;
333 fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
335 // ITS detectors and chips
336 Int_t i=0,j=0,k=0,ndet=0;
337 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
338 Int_t nBadDetsPerLayer=0;
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,fkDetTypeRec);
344 if(det.IsBad()) {nBadDetsPerLayer++;}
345 } // end loop on detectors
346 } // end loop on ladders
347 Info("ReadBadFromDetTypeRec",Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
348 } // end loop on layers
352 //------------------------------------------------------------------------
353 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
354 //--------------------------------------------------------------------
355 //This function loads ITS clusters
356 //--------------------------------------------------------------------
357 TBranch *branch=cTree->GetBranch("ITSRecPoints");
359 Error("LoadClusters"," can't get the branch !\n");
363 static TClonesArray dummy("AliITSRecPoint",10000), *clusters=&dummy;
364 branch->SetAddress(&clusters);
366 Int_t i=0,j=0,ndet=0;
368 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
369 ndet=fgLayers[i].GetNdetectors();
370 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
371 for (; j<jmax; j++) {
372 if (!cTree->GetEvent(j)) continue;
373 Int_t ncl=clusters->GetEntriesFast();
374 SignDeltas(clusters,GetZ());
377 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
378 detector=c->GetDetectorIndex();
380 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
382 fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
385 // add dead zone "virtual" cluster in SPD, if there is a cluster within
386 // zwindow cm from the dead zone
387 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
388 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
389 Int_t lab[4] = {0,0,0,detector};
390 Int_t info[3] = {0,0,i};
391 Float_t q = 0.; // this identifies virtual clusters
392 Float_t hit[5] = {xdead,
394 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
395 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
397 Bool_t local = kTRUE;
398 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
399 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
400 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
401 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
402 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
403 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
404 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
405 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
406 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
407 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
408 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
409 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
410 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
411 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
412 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
413 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
414 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
415 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
416 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
418 } // "virtual" clusters in SPD
422 fgLayers[i].ResetRoad(); //road defined by the cluster density
423 fgLayers[i].SortClusters();
430 //------------------------------------------------------------------------
431 void AliITStrackerMI::UnloadClusters() {
432 //--------------------------------------------------------------------
433 //This function unloads ITS clusters
434 //--------------------------------------------------------------------
435 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
437 //------------------------------------------------------------------------
438 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
439 //--------------------------------------------------------------------
440 // Publishes all pointers to clusters known to the tracker into the
441 // passed object array.
442 // The ownership is not transfered - the caller is not expected to delete
444 //--------------------------------------------------------------------
446 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
447 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
448 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
455 //------------------------------------------------------------------------
456 Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
457 //--------------------------------------------------------------------
458 // Correction for the material between the TPC and the ITS
459 //--------------------------------------------------------------------
460 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
461 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
462 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
463 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
464 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
465 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
466 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
467 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
469 printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
475 //------------------------------------------------------------------------
476 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
477 //--------------------------------------------------------------------
478 // This functions reconstructs ITS tracks
479 // The clusters must be already loaded !
480 //--------------------------------------------------------------------
483 fTrackingPhase="Clusters2Tracks";
485 TObjArray itsTracks(15000);
487 fEsd = event; // store pointer to the esd
489 // temporary (for cosmics)
490 if(event->GetVertex()) {
491 TString title = event->GetVertex()->GetTitle();
492 if(title.Contains("cosmics")) {
493 Double_t xyz[3]={GetX(),GetY(),GetZ()};
494 Double_t exyz[3]={0.1,0.1,0.1};
500 {/* Read ESD tracks */
501 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
502 Int_t nentr=event->GetNumberOfTracks();
503 Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
505 AliESDtrack *esd=event->GetTrack(nentr);
506 // ---- for debugging:
507 //if(TMath::Abs(esd->GetX()-83.65)<0.1) { FILE *f=fopen("tpc.dat","a"); fprintf(f,"%f %f %f %f %f %f\n",(Float_t)event->GetEventNumberInFile(),(Float_t)TMath::Abs(esd->GetLabel()),(Float_t)esd->GetX(),(Float_t)esd->GetY(),(Float_t)esd->GetZ(),(Float_t)esd->Pt()); fclose(f); }
509 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
510 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
511 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
512 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
515 t=new AliITStrackMI(*esd);
516 } catch (const Char_t *msg) {
517 //Warning("Clusters2Tracks",msg);
521 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
522 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
525 // look at the ESD mass hypothesys !
526 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
528 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
530 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
531 //track - can be V0 according to TPC
533 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
537 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
541 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
545 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
550 t->SetReconstructed(kFALSE);
551 itsTracks.AddLast(t);
552 fOriginal.AddLast(t);
554 } /* End Read ESD tracks */
558 Int_t nentr=itsTracks.GetEntriesFast();
559 fTrackHypothesys.Expand(nentr);
560 fBestHypothesys.Expand(nentr);
561 MakeCoefficients(nentr);
562 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
564 // THE TWO TRACKING PASSES
565 for (fPass=0; fPass<2; fPass++) {
566 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
567 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
568 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
569 if (t==0) continue; //this track has been already tracked
570 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
571 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
572 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
573 if (fConstraint[fPass]) {
574 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
575 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
578 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
579 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
581 ResetTrackToFollow(*t);
584 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
587 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
589 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
590 if (!besttrack) continue;
591 besttrack->SetLabel(tpcLabel);
592 // besttrack->CookdEdx();
594 besttrack->SetFakeRatio(1.);
595 CookLabel(besttrack,0.); //For comparison only
596 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
598 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
600 t->SetReconstructed(kTRUE);
602 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
604 GetBestHypothesysMIP(itsTracks);
605 } // end loop on the two tracking passes
607 if(event->GetNumberOfV0s()>0) UpdateTPCV0(event);
608 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) FindV02(event);
609 //if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
610 //if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
615 Int_t entries = fTrackHypothesys.GetEntriesFast();
616 for (Int_t ientry=0; ientry<entries; ientry++) {
617 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
618 if (array) array->Delete();
619 delete fTrackHypothesys.RemoveAt(ientry);
622 fTrackHypothesys.Delete();
623 fBestHypothesys.Delete();
625 delete [] fCoefficients;
627 DeleteTrksMaterialLUT();
629 Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
631 fTrackingPhase="Default";
635 //------------------------------------------------------------------------
636 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
637 //--------------------------------------------------------------------
638 // This functions propagates reconstructed ITS tracks back
639 // The clusters must be loaded !
640 //--------------------------------------------------------------------
641 fTrackingPhase="PropagateBack";
642 Int_t nentr=event->GetNumberOfTracks();
643 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
646 for (Int_t i=0; i<nentr; i++) {
647 AliESDtrack *esd=event->GetTrack(i);
649 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
650 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
654 t=new AliITStrackMI(*esd);
655 } catch (const Char_t *msg) {
656 //Warning("PropagateBack",msg);
660 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
662 ResetTrackToFollow(*t);
664 // propagate to vertex [SR, GSI 17.02.2003]
665 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
666 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
667 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
668 fTrackToFollow.StartTimeIntegral();
669 // from vertex to outside pipe
670 CorrectForPipeMaterial(&fTrackToFollow,"outward");
673 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
674 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
675 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
679 fTrackToFollow.SetLabel(t->GetLabel());
680 //fTrackToFollow.CookdEdx();
681 CookLabel(&fTrackToFollow,0.); //For comparison only
682 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
683 //UseClusters(&fTrackToFollow);
689 Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
691 fTrackingPhase="Default";
695 //------------------------------------------------------------------------
696 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
697 //--------------------------------------------------------------------
698 // This functions refits ITS tracks using the
699 // "inward propagated" TPC tracks
700 // The clusters must be loaded !
701 //--------------------------------------------------------------------
702 fTrackingPhase="RefitInward";
704 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) RefitV02(event);
705 //if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
707 Int_t nentr=event->GetNumberOfTracks();
708 Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
711 for (Int_t i=0; i<nentr; i++) {
712 AliESDtrack *esd=event->GetTrack(i);
714 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
715 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
716 if (esd->GetStatus()&AliESDtrack::kTPCout)
717 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
721 t=new AliITStrackMI(*esd);
722 } catch (const Char_t *msg) {
723 //Warning("RefitInward",msg);
727 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
728 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
733 ResetTrackToFollow(*t);
734 fTrackToFollow.ResetClusters();
736 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
737 fTrackToFollow.ResetCovariance(10.);
740 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
741 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
742 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
743 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
744 AliDebug(2," refit OK");
745 fTrackToFollow.SetLabel(t->GetLabel());
746 // fTrackToFollow.CookdEdx();
747 CookdEdx(&fTrackToFollow);
749 CookLabel(&fTrackToFollow,0.0); //For comparison only
752 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
753 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
754 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
755 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
756 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
757 Double_t r[3]={0.,0.,0.};
759 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
766 Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
768 fTrackingPhase="Default";
772 //------------------------------------------------------------------------
773 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
774 //--------------------------------------------------------------------
775 // Return pointer to a given cluster
776 //--------------------------------------------------------------------
777 Int_t l=(index & 0xf0000000) >> 28;
778 Int_t c=(index & 0x0fffffff) >> 00;
779 return fgLayers[l].GetCluster(c);
781 //------------------------------------------------------------------------
782 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
783 //--------------------------------------------------------------------
784 // Get track space point with index i
785 //--------------------------------------------------------------------
787 Int_t l=(index & 0xf0000000) >> 28;
788 Int_t c=(index & 0x0fffffff) >> 00;
789 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
790 Int_t idet = cl->GetDetectorIndex();
794 cl->GetGlobalXYZ(xyz);
795 cl->GetGlobalCov(cov);
797 p.SetCharge(cl->GetQ());
798 p.SetDriftTime(cl->GetDriftTime());
799 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
802 iLayer = AliGeomManager::kSPD1;
805 iLayer = AliGeomManager::kSPD2;
808 iLayer = AliGeomManager::kSDD1;
811 iLayer = AliGeomManager::kSDD2;
814 iLayer = AliGeomManager::kSSD1;
817 iLayer = AliGeomManager::kSSD2;
820 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
823 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
824 p.SetVolumeID((UShort_t)volid);
827 //------------------------------------------------------------------------
828 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
829 AliTrackPoint& p, const AliESDtrack *t) {
830 //--------------------------------------------------------------------
831 // Get track space point with index i
832 // (assign error estimated during the tracking)
833 //--------------------------------------------------------------------
835 Int_t l=(index & 0xf0000000) >> 28;
836 Int_t c=(index & 0x0fffffff) >> 00;
837 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
838 Int_t idet = cl->GetDetectorIndex();
840 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
842 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
844 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
845 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
846 Double_t alpha = t->GetAlpha();
847 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
848 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,GetBz()));
849 phi += alpha-det.GetPhi();
850 Float_t tgphi = TMath::Tan(phi);
852 Float_t tgl = t->GetTgl(); // tgl about const along track
853 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
855 Float_t errlocalx,errlocalz;
856 Bool_t addMisalErr=kFALSE;
857 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errlocalx,errlocalz,addMisalErr);
861 cl->GetGlobalXYZ(xyz);
862 // cl->GetGlobalCov(cov);
863 Float_t pos[3] = {0.,0.,0.};
864 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errlocalx*errlocalx,errlocalz*errlocalz,0);
865 tmpcl.GetGlobalCov(cov);
868 p.SetCharge(cl->GetQ());
869 p.SetDriftTime(cl->GetDriftTime());
871 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
874 iLayer = AliGeomManager::kSPD1;
877 iLayer = AliGeomManager::kSPD2;
880 iLayer = AliGeomManager::kSDD1;
883 iLayer = AliGeomManager::kSDD2;
886 iLayer = AliGeomManager::kSSD1;
889 iLayer = AliGeomManager::kSSD2;
892 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
895 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
897 p.SetVolumeID((UShort_t)volid);
900 //------------------------------------------------------------------------
901 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
903 //--------------------------------------------------------------------
904 // Follow prolongation tree
905 //--------------------------------------------------------------------
907 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
908 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
911 AliESDtrack * esd = otrack->GetESDtrack();
912 if (esd->GetV0Index(0)>0) {
913 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
914 // mapping of ESD track is different as ITS track in Containers
915 // Need something more stable
916 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
917 for (Int_t i=0;i<3;i++){
918 Int_t index = esd->GetV0Index(i);
920 AliESDv0 * vertex = fEsd->GetV0(index);
921 if (vertex->GetStatus()<0) continue; // rejected V0
923 if (esd->GetSign()>0) {
924 vertex->SetIndex(0,esdindex);
926 vertex->SetIndex(1,esdindex);
930 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
932 bestarray = new TObjArray(5);
933 fBestHypothesys.AddAt(bestarray,esdindex);
937 //setup tree of the prolongations
939 static AliITStrackMI tracks[7][100];
940 AliITStrackMI *currenttrack;
941 static AliITStrackMI currenttrack1;
942 static AliITStrackMI currenttrack2;
943 static AliITStrackMI backuptrack;
945 Int_t nindexes[7][100];
946 Float_t normalizedchi2[100];
947 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
948 otrack->SetNSkipped(0);
949 new (&(tracks[6][0])) AliITStrackMI(*otrack);
951 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
952 Int_t modstatus = 1; // found
956 // follow prolongations
957 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
958 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
961 AliITSlayer &layer=fgLayers[ilayer];
962 Double_t r = layer.GetR();
968 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
970 if (ntracks[ilayer]>=100) break;
971 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
972 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
973 if (ntracks[ilayer]>15+ilayer){
974 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
975 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
978 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
980 // material between SSD and SDD, SDD and SPD
982 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
984 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
988 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
989 Int_t idet=layer.FindDetectorIndex(phi,z);
991 Double_t trackGlobXYZ1[3];
992 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
994 // Get the budget to the primary vertex for the current track being prolonged
995 Double_t budgetToPrimVertex = GetEffectiveThickness();
997 // check if we allow a prolongation without point
998 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1000 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1001 // propagate to the layer radius
1002 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1003 if(!vtrack->Propagate(xToGo)) continue;
1004 // apply correction for material of the current layer
1005 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1006 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1007 vtrack->SetClIndex(ilayer,-1);
1008 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1009 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1010 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1012 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1017 // track outside layer acceptance in z
1018 if (idet<0) continue;
1020 //propagate to the intersection with the detector plane
1021 const AliITSdetector &det=layer.GetDetector(idet);
1022 new(¤ttrack2) AliITStrackMI(currenttrack1);
1023 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1024 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1025 currenttrack1.SetDetectorIndex(idet);
1026 currenttrack2.SetDetectorIndex(idet);
1027 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1030 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1032 // road in global (rphi,z) [i.e. in tracking ref. system]
1033 Double_t zmin,zmax,ymin,ymax;
1034 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1036 // select clusters in road
1037 layer.SelectClusters(zmin,zmax,ymin,ymax);
1038 //********************
1040 // Define criteria for track-cluster association
1041 Double_t msz = currenttrack1.GetSigmaZ2() +
1042 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1043 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1044 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1045 Double_t msy = currenttrack1.GetSigmaY2() +
1046 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1047 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1048 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1050 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1051 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1053 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1054 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1056 msz = 1./msz; // 1/RoadZ^2
1057 msy = 1./msy; // 1/RoadY^2
1061 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1063 const AliITSRecPoint *cl=0;
1065 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1066 Bool_t deadzoneSPD=kFALSE;
1067 currenttrack = ¤ttrack1;
1069 // check if the road contains a dead zone
1070 Bool_t noClusters = kFALSE;
1071 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1072 if (noClusters) AliDebug(2,"no clusters in road");
1073 Double_t dz=0.5*(zmax-zmin);
1074 Double_t dy=0.5*(ymax-ymin);
1075 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1076 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1077 // create a prolongation without clusters (check also if there are no clusters in the road)
1080 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1081 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1082 updatetrack->SetClIndex(ilayer,-1);
1084 modstatus = 5; // no cls in road
1085 } else if (dead==1) {
1086 modstatus = 7; // holes in z in SPD
1087 } else if (dead==2 || dead==3) {
1088 modstatus = 2; // dead from OCDB
1090 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1091 // apply correction for material of the current layer
1092 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1093 if (constrain) { // apply vertex constrain
1094 updatetrack->SetConstrain(constrain);
1095 Bool_t isPrim = kTRUE;
1096 if (ilayer<4) { // check that it's close to the vertex
1097 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1098 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1099 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1100 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1101 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1103 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1106 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1107 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1108 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1116 // loop over clusters in the road
1117 while ((cl=layer.GetNextCluster(clidx))!=0) {
1118 if (ntracks[ilayer]>95) break; //space for skipped clusters
1119 Bool_t changedet =kFALSE;
1120 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
1121 Int_t idetc=cl->GetDetectorIndex();
1123 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1124 // take into account misalignment (bring track to real detector plane)
1125 Double_t xTrOrig = currenttrack->GetX();
1126 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1127 // a first cut on track-cluster distance
1128 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1129 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1130 { // cluster not associated to track
1131 AliDebug(2,"not associated");
1134 // bring track back to ideal detector plane
1135 if (!currenttrack->Propagate(xTrOrig)) continue;
1136 } else { // have to move track to cluster's detector
1137 const AliITSdetector &detc=layer.GetDetector(idetc);
1138 // a first cut on track-cluster distance
1140 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1141 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1142 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1143 continue; // cluster not associated to track
1145 new (&backuptrack) AliITStrackMI(currenttrack2);
1147 currenttrack =¤ttrack2;
1148 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1149 new (currenttrack) AliITStrackMI(backuptrack);
1153 currenttrack->SetDetectorIndex(idetc);
1154 // Get again the budget to the primary vertex
1155 // for the current track being prolonged, if had to change detector
1156 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1159 // calculate track-clusters chi2
1160 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1162 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1163 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1164 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1165 if (ntracks[ilayer]>=100) continue;
1166 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1167 updatetrack->SetClIndex(ilayer,-1);
1168 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1170 if (cl->GetQ()!=0) { // real cluster
1171 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1172 AliDebug(2,"update failed");
1175 updatetrack->SetSampledEdx(cl->GetQ(),updatetrack->GetNumberOfClusters()-1); //b.b.
1176 modstatus = 1; // found
1177 } else { // virtual cluster in dead zone
1178 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1179 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1180 modstatus = 7; // holes in z in SPD
1184 Float_t xlocnewdet,zlocnewdet;
1185 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1186 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1189 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1191 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1193 // apply correction for material of the current layer
1194 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1196 if (constrain) { // apply vertex constrain
1197 updatetrack->SetConstrain(constrain);
1198 Bool_t isPrim = kTRUE;
1199 if (ilayer<4) { // check that it's close to the vertex
1200 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1201 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1202 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1203 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1204 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1206 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1207 } //apply vertex constrain
1209 } // create new hypothesis
1211 AliDebug(2,"chi2 too large");
1214 } // loop over possible prolongations
1216 // allow one prolongation without clusters
1217 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1218 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1219 // apply correction for material of the current layer
1220 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1221 vtrack->SetClIndex(ilayer,-1);
1222 modstatus = 3; // skipped
1223 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1224 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1225 vtrack->IncrementNSkipped();
1229 // allow one prolongation without clusters for tracks with |tgl|>1.1
1230 if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) { //big theta - for low flux
1231 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1232 // apply correction for material of the current layer
1233 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1234 vtrack->SetClIndex(ilayer,-1);
1235 modstatus = 3; // skipped
1236 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1237 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1238 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1243 } // loop over tracks in layer ilayer+1
1245 //loop over track candidates for the current layer
1251 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1252 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1253 if (normalizedchi2[itrack] <
1254 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1258 if (constrain) { // constrain
1259 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1261 } else { // !constrain
1262 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1267 // sort tracks by increasing normalized chi2
1268 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1269 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1270 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1271 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1272 } // end loop over layers
1276 // Now select tracks to be kept
1278 Int_t max = constrain ? 20 : 5;
1280 // tracks that reach layer 0 (SPD inner)
1281 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1282 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1283 if (track.GetNumberOfClusters()<2) continue;
1284 if (!constrain && track.GetNormChi2(0) >
1285 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1288 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1291 // tracks that reach layer 1 (SPD outer)
1292 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1293 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1294 if (track.GetNumberOfClusters()<4) continue;
1295 if (!constrain && track.GetNormChi2(1) >
1296 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1297 if (constrain) track.IncrementNSkipped();
1299 track.SetD(0,track.GetD(GetX(),GetY()));
1300 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1301 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1302 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1305 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1308 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1310 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1311 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1312 if (track.GetNumberOfClusters()<3) continue;
1313 if (!constrain && track.GetNormChi2(2) >
1314 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1315 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1317 track.SetD(0,track.GetD(GetX(),GetY()));
1318 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1319 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1320 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1323 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1329 // register best track of each layer - important for V0 finder
1331 for (Int_t ilayer=0;ilayer<5;ilayer++){
1332 if (ntracks[ilayer]==0) continue;
1333 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1334 if (track.GetNumberOfClusters()<1) continue;
1335 CookLabel(&track,0);
1336 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1340 // update TPC V0 information
1342 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1343 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1344 for (Int_t i=0;i<3;i++){
1345 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1346 if (index==0) break;
1347 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1348 if (vertex->GetStatus()<0) continue; // rejected V0
1350 if (otrack->GetSign()>0) {
1351 vertex->SetIndex(0,esdindex);
1354 vertex->SetIndex(1,esdindex);
1356 //find nearest layer with track info
1357 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1358 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1359 Int_t nearest = nearestold;
1360 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1361 if (ntracks[nearest]==0){
1366 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1367 if (nearestold<5&&nearest<5){
1368 Bool_t accept = track.GetNormChi2(nearest)<10;
1370 if (track.GetSign()>0) {
1371 vertex->SetParamP(track);
1372 vertex->Update(fprimvertex);
1373 //vertex->SetIndex(0,track.fESDtrack->GetID());
1374 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1376 vertex->SetParamN(track);
1377 vertex->Update(fprimvertex);
1378 //vertex->SetIndex(1,track.fESDtrack->GetID());
1379 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1381 vertex->SetStatus(vertex->GetStatus()+1);
1383 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1390 //------------------------------------------------------------------------
1391 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1393 //--------------------------------------------------------------------
1396 return fgLayers[layer];
1398 //------------------------------------------------------------------------
1399 AliITStrackerMI::AliITSlayer::AliITSlayer():
1424 //--------------------------------------------------------------------
1425 //default AliITSlayer constructor
1426 //--------------------------------------------------------------------
1427 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1428 fClusterWeight[i]=0;
1429 fClusterTracks[0][i]=-1;
1430 fClusterTracks[1][i]=-1;
1431 fClusterTracks[2][i]=-1;
1432 fClusterTracks[3][i]=-1;
1435 //------------------------------------------------------------------------
1436 AliITStrackerMI::AliITSlayer::
1437 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1462 //--------------------------------------------------------------------
1463 //main AliITSlayer constructor
1464 //--------------------------------------------------------------------
1465 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1466 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1468 //------------------------------------------------------------------------
1469 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1471 fPhiOffset(layer.fPhiOffset),
1472 fNladders(layer.fNladders),
1473 fZOffset(layer.fZOffset),
1474 fNdetectors(layer.fNdetectors),
1475 fDetectors(layer.fDetectors),
1480 fClustersCs(layer.fClustersCs),
1481 fClusterIndexCs(layer.fClusterIndexCs),
1485 fCurrentSlice(layer.fCurrentSlice),
1492 fAccepted(layer.fAccepted),
1496 //------------------------------------------------------------------------
1497 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1498 //--------------------------------------------------------------------
1499 // AliITSlayer destructor
1500 //--------------------------------------------------------------------
1501 delete [] fDetectors;
1502 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1503 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1504 fClusterWeight[i]=0;
1505 fClusterTracks[0][i]=-1;
1506 fClusterTracks[1][i]=-1;
1507 fClusterTracks[2][i]=-1;
1508 fClusterTracks[3][i]=-1;
1511 //------------------------------------------------------------------------
1512 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1513 //--------------------------------------------------------------------
1514 // This function removes loaded clusters
1515 //--------------------------------------------------------------------
1516 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1517 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1518 fClusterWeight[i]=0;
1519 fClusterTracks[0][i]=-1;
1520 fClusterTracks[1][i]=-1;
1521 fClusterTracks[2][i]=-1;
1522 fClusterTracks[3][i]=-1;
1528 //------------------------------------------------------------------------
1529 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1530 //--------------------------------------------------------------------
1531 // This function reset weights of the clusters
1532 //--------------------------------------------------------------------
1533 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1534 fClusterWeight[i]=0;
1535 fClusterTracks[0][i]=-1;
1536 fClusterTracks[1][i]=-1;
1537 fClusterTracks[2][i]=-1;
1538 fClusterTracks[3][i]=-1;
1540 for (Int_t i=0; i<fN;i++) {
1541 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1542 if (cl&&cl->IsUsed()) cl->Use();
1546 //------------------------------------------------------------------------
1547 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1548 //--------------------------------------------------------------------
1549 // This function calculates the road defined by the cluster density
1550 //--------------------------------------------------------------------
1552 for (Int_t i=0; i<fN; i++) {
1553 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1555 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1557 //------------------------------------------------------------------------
1558 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1559 //--------------------------------------------------------------------
1560 //This function adds a cluster to this layer
1561 //--------------------------------------------------------------------
1562 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1563 ::Error("InsertCluster","Too many clusters !\n");
1569 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1570 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1571 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1572 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1573 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1577 //------------------------------------------------------------------------
1578 void AliITStrackerMI::AliITSlayer::SortClusters()
1583 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1584 Float_t *z = new Float_t[fN];
1585 Int_t * index = new Int_t[fN];
1587 for (Int_t i=0;i<fN;i++){
1588 z[i] = fClusters[i]->GetZ();
1590 TMath::Sort(fN,z,index,kFALSE);
1591 for (Int_t i=0;i<fN;i++){
1592 clusters[i] = fClusters[index[i]];
1595 for (Int_t i=0;i<fN;i++){
1596 fClusters[i] = clusters[i];
1597 fZ[i] = fClusters[i]->GetZ();
1598 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1599 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1600 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1610 for (Int_t i=0;i<fN;i++){
1611 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1612 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1613 fClusterIndex[i] = i;
1617 fDy5 = (fYB[1]-fYB[0])/5.;
1618 fDy10 = (fYB[1]-fYB[0])/10.;
1619 fDy20 = (fYB[1]-fYB[0])/20.;
1620 for (Int_t i=0;i<6;i++) fN5[i] =0;
1621 for (Int_t i=0;i<11;i++) fN10[i]=0;
1622 for (Int_t i=0;i<21;i++) fN20[i]=0;
1624 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;}
1625 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;}
1626 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;}
1629 for (Int_t i=0;i<fN;i++)
1630 for (Int_t irot=-1;irot<=1;irot++){
1631 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1633 for (Int_t slice=0; slice<6;slice++){
1634 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1635 fClusters5[slice][fN5[slice]] = fClusters[i];
1636 fY5[slice][fN5[slice]] = curY;
1637 fZ5[slice][fN5[slice]] = fZ[i];
1638 fClusterIndex5[slice][fN5[slice]]=i;
1643 for (Int_t slice=0; slice<11;slice++){
1644 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1645 fClusters10[slice][fN10[slice]] = fClusters[i];
1646 fY10[slice][fN10[slice]] = curY;
1647 fZ10[slice][fN10[slice]] = fZ[i];
1648 fClusterIndex10[slice][fN10[slice]]=i;
1653 for (Int_t slice=0; slice<21;slice++){
1654 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1655 fClusters20[slice][fN20[slice]] = fClusters[i];
1656 fY20[slice][fN20[slice]] = curY;
1657 fZ20[slice][fN20[slice]] = fZ[i];
1658 fClusterIndex20[slice][fN20[slice]]=i;
1665 // consistency check
1667 for (Int_t i=0;i<fN-1;i++){
1673 for (Int_t slice=0;slice<21;slice++)
1674 for (Int_t i=0;i<fN20[slice]-1;i++){
1675 if (fZ20[slice][i]>fZ20[slice][i+1]){
1682 //------------------------------------------------------------------------
1683 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1684 //--------------------------------------------------------------------
1685 // This function returns the index of the nearest cluster
1686 //--------------------------------------------------------------------
1689 if (fCurrentSlice<0) {
1698 if (ncl==0) return 0;
1699 Int_t b=0, e=ncl-1, m=(b+e)/2;
1700 for (; b<e; m=(b+e)/2) {
1701 // if (z > fClusters[m]->GetZ()) b=m+1;
1702 if (z > zcl[m]) b=m+1;
1707 //------------------------------------------------------------------------
1708 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 {
1709 //--------------------------------------------------------------------
1710 // This function computes the rectangular road for this track
1711 //--------------------------------------------------------------------
1714 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1715 // take into account the misalignment: propagate track to misaligned detector plane
1716 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1718 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1719 TMath::Sqrt(track->GetSigmaZ2() +
1720 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1721 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1722 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1723 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1724 TMath::Sqrt(track->GetSigmaY2() +
1725 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1726 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1727 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1729 // track at boundary between detectors, enlarge road
1730 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1731 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1732 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1733 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1734 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1735 Float_t tgl = TMath::Abs(track->GetTgl());
1736 if (tgl > 1.) tgl=1.;
1737 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1738 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1739 Float_t snp = TMath::Abs(track->GetSnp());
1740 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1741 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1744 // add to the road a term (up to 2-3 mm) to deal with misalignments
1745 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1746 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1748 Double_t r = fgLayers[ilayer].GetR();
1749 zmin = track->GetZ() - dz;
1750 zmax = track->GetZ() + dz;
1751 ymin = track->GetY() + r*det.GetPhi() - dy;
1752 ymax = track->GetY() + r*det.GetPhi() + dy;
1754 // bring track back to idead detector plane
1755 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1759 //------------------------------------------------------------------------
1760 void AliITStrackerMI::AliITSlayer::
1761 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1762 //--------------------------------------------------------------------
1763 // This function sets the "window"
1764 //--------------------------------------------------------------------
1766 Double_t circle=2*TMath::Pi()*fR;
1767 fYmin = ymin; fYmax =ymax;
1768 Float_t ymiddle = (fYmin+fYmax)*0.5;
1769 if (ymiddle<fYB[0]) {
1770 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1771 } else if (ymiddle>fYB[1]) {
1772 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1778 fClustersCs = fClusters;
1779 fClusterIndexCs = fClusterIndex;
1785 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1786 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1787 if (slice<0) slice=0;
1788 if (slice>20) slice=20;
1789 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1791 fCurrentSlice=slice;
1792 fClustersCs = fClusters20[fCurrentSlice];
1793 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1794 fYcs = fY20[fCurrentSlice];
1795 fZcs = fZ20[fCurrentSlice];
1796 fNcs = fN20[fCurrentSlice];
1801 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1802 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1803 if (slice<0) slice=0;
1804 if (slice>10) slice=10;
1805 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1807 fCurrentSlice=slice;
1808 fClustersCs = fClusters10[fCurrentSlice];
1809 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1810 fYcs = fY10[fCurrentSlice];
1811 fZcs = fZ10[fCurrentSlice];
1812 fNcs = fN10[fCurrentSlice];
1817 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1818 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1819 if (slice<0) slice=0;
1820 if (slice>5) slice=5;
1821 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1823 fCurrentSlice=slice;
1824 fClustersCs = fClusters5[fCurrentSlice];
1825 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1826 fYcs = fY5[fCurrentSlice];
1827 fZcs = fZ5[fCurrentSlice];
1828 fNcs = fN5[fCurrentSlice];
1832 fI=FindClusterIndex(zmin); fZmax=zmax;
1833 fImax = TMath::Min(FindClusterIndex(zmax)+1,fNcs);
1839 //------------------------------------------------------------------------
1840 Int_t AliITStrackerMI::AliITSlayer::
1841 FindDetectorIndex(Double_t phi, Double_t z) const {
1842 //--------------------------------------------------------------------
1843 //This function finds the detector crossed by the track
1844 //--------------------------------------------------------------------
1846 if (fZOffset<0) // old geometry
1847 dphi = -(phi-fPhiOffset);
1848 else // new geometry
1849 dphi = phi-fPhiOffset;
1852 if (dphi < 0) dphi += 2*TMath::Pi();
1853 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1854 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1855 if (np>=fNladders) np-=fNladders;
1856 if (np<0) np+=fNladders;
1859 Double_t dz=fZOffset-z;
1860 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1861 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1862 if (nz>=fNdetectors) return -1;
1863 if (nz<0) return -1;
1865 // ad hoc correction for 3rd ladder of SDD inner layer,
1866 // which is reversed (rotated by pi around local y)
1867 // this correction is OK only from AliITSv11Hybrid onwards
1868 if (GetR()>12. && GetR()<20.) { // SDD inner
1869 if(np==2) { // 3rd ladder
1870 nz = (fNdetectors-1) - nz;
1873 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1876 return np*fNdetectors + nz;
1878 //------------------------------------------------------------------------
1879 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1881 //--------------------------------------------------------------------
1882 // This function returns clusters within the "window"
1883 //--------------------------------------------------------------------
1885 if (fCurrentSlice<0) {
1886 Double_t rpi2 = 2.*fR*TMath::Pi();
1887 for (Int_t i=fI; i<fImax; i++) {
1889 if (fYmax<y) y -= rpi2;
1890 if (fYmin>y) y += rpi2;
1891 if (y<fYmin) continue;
1892 if (y>fYmax) continue;
1893 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1896 return fClusters[i];
1899 for (Int_t i=fI; i<fImax; i++) {
1900 if (fYcs[i]<fYmin) continue;
1901 if (fYcs[i]>fYmax) continue;
1902 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1903 ci=fClusterIndexCs[i];
1905 return fClustersCs[i];
1910 //------------------------------------------------------------------------
1911 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1913 //--------------------------------------------------------------------
1914 // This function returns the layer thickness at this point (units X0)
1915 //--------------------------------------------------------------------
1917 x0=AliITSRecoParam::GetX0Air();
1918 if (43<fR&&fR<45) { //SSD2
1921 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1922 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1923 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1924 for (Int_t i=0; i<12; i++) {
1925 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1926 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1930 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1931 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1935 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1936 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1939 if (37<fR&&fR<41) { //SSD1
1942 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1943 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1944 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1945 for (Int_t i=0; i<11; i++) {
1946 if (TMath::Abs(z-3.9*i)<0.15) {
1947 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1951 if (TMath::Abs(z+3.9*i)<0.15) {
1952 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1956 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1957 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1960 if (13<fR&&fR<26) { //SDD
1963 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1965 if (TMath::Abs(y-1.80)<0.55) {
1967 for (Int_t j=0; j<20; j++) {
1968 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1969 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1972 if (TMath::Abs(y+1.80)<0.55) {
1974 for (Int_t j=0; j<20; j++) {
1975 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1976 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1980 for (Int_t i=0; i<4; i++) {
1981 if (TMath::Abs(z-7.3*i)<0.60) {
1983 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1986 if (TMath::Abs(z+7.3*i)<0.60) {
1988 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1993 if (6<fR&&fR<8) { //SPD2
1994 Double_t dd=0.0063; x0=21.5;
1996 if (TMath::Abs(y-3.08)>0.5) d+=dd;
1997 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
1999 if (3<fR&&fR<5) { //SPD1
2000 Double_t dd=0.0063; x0=21.5;
2002 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2003 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2008 //------------------------------------------------------------------------
2009 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2011 fRmisal(det.fRmisal),
2013 fSinPhi(det.fSinPhi),
2014 fCosPhi(det.fCosPhi),
2020 fNChips(det.fNChips),
2021 fChipIsBad(det.fChipIsBad)
2025 //------------------------------------------------------------------------
2026 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2027 const AliITSDetTypeRec *detTypeRec)
2029 //--------------------------------------------------------------------
2030 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2031 //--------------------------------------------------------------------
2033 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2034 // while in the tracker they start from 0 for each layer
2035 for(Int_t il=0; il<ilayer; il++)
2036 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2039 if (ilayer==0 || ilayer==1) { // ---------- SPD
2041 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2043 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2046 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2050 // Get calibration from AliITSDetTypeRec
2051 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2052 calib->SetModuleIndex(idet);
2053 AliITSCalibration *calibSPDdead = 0;
2054 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2055 if (calib->IsBad() ||
2056 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2059 // printf("lay %d bad %d\n",ilayer,idet);
2062 // Get segmentation from AliITSDetTypeRec
2063 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2065 // Read info about bad chips
2066 fNChips = segm->GetMaximumChipIndex()+1;
2067 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2068 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2069 fChipIsBad = new Bool_t[fNChips];
2070 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2071 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2072 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2073 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2078 //------------------------------------------------------------------------
2079 Double_t AliITStrackerMI::GetEffectiveThickness()
2081 //--------------------------------------------------------------------
2082 // Returns the thickness between the current layer and the vertex (units X0)
2083 //--------------------------------------------------------------------
2086 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2087 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2088 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2092 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2093 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2097 Double_t xn=fgLayers[fI].GetR();
2098 for (Int_t i=0; i<fI; i++) {
2099 Double_t xi=fgLayers[i].GetR();
2100 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2106 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2107 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2110 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2111 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2115 //------------------------------------------------------------------------
2116 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2117 //-------------------------------------------------------------------
2118 // This function returns number of clusters within the "window"
2119 //--------------------------------------------------------------------
2121 for (Int_t i=fI; i<fN; i++) {
2122 const AliITSRecPoint *c=fClusters[i];
2123 if (c->GetZ() > fZmax) break;
2124 if (c->IsUsed()) continue;
2125 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2126 Double_t y=fR*det.GetPhi() + c->GetY();
2128 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2129 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2131 if (y<fYmin) continue;
2132 if (y>fYmax) continue;
2137 //------------------------------------------------------------------------
2138 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2139 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2141 //--------------------------------------------------------------------
2142 // This function refits the track "track" at the position "x" using
2143 // the clusters from "clusters"
2144 // If "extra"==kTRUE,
2145 // the clusters from overlapped modules get attached to "track"
2146 // If "planeff"==kTRUE,
2147 // special approach for plane efficiency evaluation is applyed
2148 //--------------------------------------------------------------------
2150 Int_t index[AliITSgeomTGeo::kNLayers];
2152 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2153 Int_t nc=clusters->GetNumberOfClusters();
2154 for (k=0; k<nc; k++) {
2155 Int_t idx=clusters->GetClusterIndex(k);
2156 Int_t ilayer=(idx&0xf0000000)>>28;
2160 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2162 //------------------------------------------------------------------------
2163 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2164 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2166 //--------------------------------------------------------------------
2167 // This function refits the track "track" at the position "x" using
2168 // the clusters from array
2169 // If "extra"==kTRUE,
2170 // the clusters from overlapped modules get attached to "track"
2171 // If "planeff"==kTRUE,
2172 // special approach for plane efficiency evaluation is applyed
2173 //--------------------------------------------------------------------
2174 Int_t index[AliITSgeomTGeo::kNLayers];
2176 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2178 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2179 index[k]=clusters[k];
2182 // special for cosmics: check which the innermost layer crossed
2184 Int_t innermostlayer=5;
2185 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2186 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2187 if(drphi < fgLayers[innermostlayer].GetR()) break;
2189 //printf(" drphi %f innermost %d\n",drphi,innermostlayer);
2191 Int_t modstatus=1; // found
2193 Int_t from, to, step;
2194 if (xx > track->GetX()) {
2195 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2198 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2201 TString dir = (step>0 ? "outward" : "inward");
2203 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2204 AliITSlayer &layer=fgLayers[ilayer];
2205 Double_t r=layer.GetR();
2206 if (step<0 && xx>r) break;
2208 // material between SSD and SDD, SDD and SPD
2209 Double_t hI=ilayer-0.5*step;
2210 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2211 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2212 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2213 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2216 Double_t oldGlobXYZ[3];
2217 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2220 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2222 Int_t idet=layer.FindDetectorIndex(phi,z);
2224 // check if we allow a prolongation without point for large-eta tracks
2225 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2227 modstatus = 4; // out in z
2228 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2229 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2232 // apply correction for material of the current layer
2233 // add time if going outward
2234 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2238 if (idet<0) return kFALSE;
2240 const AliITSdetector &det=layer.GetDetector(idet);
2241 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2243 track->SetDetectorIndex(idet);
2244 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2246 Double_t dz,zmin,zmax,dy,ymin,ymax;
2248 const AliITSRecPoint *clAcc=0;
2249 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2251 Int_t idx=index[ilayer];
2252 if (idx>=0) { // cluster in this layer
2253 modstatus = 6; // no refit
2254 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2256 if (idet != cl->GetDetectorIndex()) {
2257 idet=cl->GetDetectorIndex();
2258 const AliITSdetector &detc=layer.GetDetector(idet);
2259 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2260 track->SetDetectorIndex(idet);
2261 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2263 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2264 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2268 modstatus = 1; // found
2273 } else { // no cluster in this layer
2275 modstatus = 3; // skipped
2276 // Plane Eff determination:
2277 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2278 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2279 UseTrackForPlaneEff(track,ilayer);
2282 modstatus = 5; // no cls in road
2284 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2285 dz = 0.5*(zmax-zmin);
2286 dy = 0.5*(ymax-ymin);
2287 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2288 if (dead==1) modstatus = 7; // holes in z in SPD
2289 if (dead==2 || dead==3) modstatus = 2; // dead from OCDB
2294 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2295 track->SetSampledEdx(clAcc->GetQ(),track->GetNumberOfClusters()-1);
2297 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2300 if (extra) { // search for extra clusters in overlapped modules
2301 AliITStrackV2 tmp(*track);
2302 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2303 layer.SelectClusters(zmin,zmax,ymin,ymax);
2305 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2307 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2308 Double_t tolerance=0.1;
2309 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2310 // only clusters in another module! (overlaps)
2311 idetExtra = clExtra->GetDetectorIndex();
2312 if (idet == idetExtra) continue;
2314 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2316 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2317 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2318 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2319 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2321 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2322 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2325 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2326 track->SetExtraModule(ilayer,idetExtra);
2328 } // end search for extra clusters in overlapped modules
2330 // Correct for material of the current layer
2332 // add time if going outward
2333 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2335 } // end loop on layers
2337 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2341 //------------------------------------------------------------------------
2342 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2345 // calculate normalized chi2
2346 // return NormalizedChi2(track,0);
2349 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2350 // track->fdEdxMismatch=0;
2351 Float_t dedxmismatch =0;
2352 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2354 for (Int_t i = 0;i<6;i++){
2355 if (track->GetClIndex(i)>=0){
2356 Float_t cerry, cerrz;
2357 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2359 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2362 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2363 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2364 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2366 cchi2+=(0.5-ratio)*10.;
2367 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2368 dedxmismatch+=(0.5-ratio)*10.;
2372 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2373 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2374 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2375 if (i<2) chi2+=2*cl->GetDeltaProbability();
2381 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2382 track->SetdEdxMismatch(dedxmismatch);
2386 for (Int_t i = 0;i<4;i++){
2387 if (track->GetClIndex(i)>=0){
2388 Float_t cerry, cerrz;
2389 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2390 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2393 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2394 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2398 for (Int_t i = 4;i<6;i++){
2399 if (track->GetClIndex(i)>=0){
2400 Float_t cerry, cerrz;
2401 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2402 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2405 Float_t cerryb, cerrzb;
2406 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2407 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2410 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2411 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2416 if (track->GetESDtrack()->GetTPCsignal()>85){
2417 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2419 chi2+=(0.5-ratio)*5.;
2422 chi2+=(ratio-2.0)*3;
2426 Double_t match = TMath::Sqrt(track->GetChi22());
2427 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2428 if (!track->GetConstrain()) {
2429 if (track->GetNumberOfClusters()>2) {
2430 match/=track->GetNumberOfClusters()-2.;
2435 if (match<0) match=0;
2436 Float_t deadzonefactor = (track->GetNDeadZone()>0) ? 3*(1.1-track->GetDeadZoneProbability()):0.;
2437 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2438 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2439 1./(1.+track->GetNSkipped()));
2443 //------------------------------------------------------------------------
2444 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2447 // return matching chi2 between two tracks
2448 Double_t largeChi2=1000.;
2450 AliITStrackMI track3(*track2);
2451 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2453 vec(0,0)=track1->GetY() - track3.GetY();
2454 vec(1,0)=track1->GetZ() - track3.GetZ();
2455 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2456 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2457 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2460 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2461 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2462 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2463 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2464 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2466 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2467 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2468 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2469 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2471 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2472 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2473 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2475 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2476 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2478 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2481 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2482 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2485 //------------------------------------------------------------------------
2486 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2489 // return probability that given point (characterized by z position and error)
2490 // is in SPD dead zone
2492 Double_t probability = 0.;
2493 Double_t absz = TMath::Abs(zpos);
2494 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2495 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2496 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2497 Double_t zmin, zmax;
2498 if (zpos<-6.) { // dead zone at z = -7
2499 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2500 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2501 } else if (zpos>6.) { // dead zone at z = +7
2502 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2503 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2504 } else if (absz<2.) { // dead zone at z = 0
2505 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2506 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2511 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2513 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2514 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2517 //------------------------------------------------------------------------
2518 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2521 // calculate normalized chi2
2523 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2525 for (Int_t i = 0;i<6;i++){
2526 if (TMath::Abs(track->GetDy(i))>0){
2527 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2528 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2531 else{chi2[i]=10000;}
2534 TMath::Sort(6,chi2,index,kFALSE);
2535 Float_t max = float(ncl)*fac-1.;
2536 Float_t sumchi=0, sumweight=0;
2537 for (Int_t i=0;i<max+1;i++){
2538 Float_t weight = (i<max)?1.:(max+1.-i);
2539 sumchi+=weight*chi2[index[i]];
2542 Double_t normchi2 = sumchi/sumweight;
2545 //------------------------------------------------------------------------
2546 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2549 // calculate normalized chi2
2550 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2553 for (Int_t i=0;i<6;i++){
2554 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2555 Double_t sy1 = forwardtrack->GetSigmaY(i);
2556 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2557 Double_t sy2 = backtrack->GetSigmaY(i);
2558 Double_t sz2 = backtrack->GetSigmaZ(i);
2559 if (i<2){ sy2=1000.;sz2=1000;}
2561 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2562 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2564 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2565 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2567 res+= nz0*nz0+ny0*ny0;
2570 if (npoints>1) return
2571 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2572 //2*forwardtrack->fNUsed+
2573 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2574 1./(1.+forwardtrack->GetNSkipped()));
2577 //------------------------------------------------------------------------
2578 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2579 //--------------------------------------------------------------------
2580 // Return pointer to a given cluster
2581 //--------------------------------------------------------------------
2582 Int_t l=(index & 0xf0000000) >> 28;
2583 Int_t c=(index & 0x0fffffff) >> 00;
2584 return fgLayers[l].GetWeight(c);
2586 //------------------------------------------------------------------------
2587 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2589 //---------------------------------------------
2590 // register track to the list
2592 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2595 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2596 Int_t index = track->GetClusterIndex(icluster);
2597 Int_t l=(index & 0xf0000000) >> 28;
2598 Int_t c=(index & 0x0fffffff) >> 00;
2599 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2600 for (Int_t itrack=0;itrack<4;itrack++){
2601 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2602 fgLayers[l].SetClusterTracks(itrack,c,id);
2608 //------------------------------------------------------------------------
2609 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2611 //---------------------------------------------
2612 // unregister track from the list
2613 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2614 Int_t index = track->GetClusterIndex(icluster);
2615 Int_t l=(index & 0xf0000000) >> 28;
2616 Int_t c=(index & 0x0fffffff) >> 00;
2617 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2618 for (Int_t itrack=0;itrack<4;itrack++){
2619 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2620 fgLayers[l].SetClusterTracks(itrack,c,-1);
2625 //------------------------------------------------------------------------
2626 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2628 //-------------------------------------------------------------
2629 //get number of shared clusters
2630 //-------------------------------------------------------------
2632 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2633 // mean number of clusters
2634 Float_t *ny = GetNy(id), *nz = GetNz(id);
2637 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2638 Int_t index = track->GetClusterIndex(icluster);
2639 Int_t l=(index & 0xf0000000) >> 28;
2640 Int_t c=(index & 0x0fffffff) >> 00;
2641 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2643 printf("problem\n");
2645 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2649 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2650 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2651 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2653 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2656 deltan = (cl->GetNz()-nz[l]);
2658 if (deltan>2.0) continue; // extended - highly probable shared cluster
2659 weight = 2./TMath::Max(3.+deltan,2.);
2661 for (Int_t itrack=0;itrack<4;itrack++){
2662 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2664 clist[l] = (AliITSRecPoint*)GetCluster(index);
2670 track->SetNUsed(shared);
2673 //------------------------------------------------------------------------
2674 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2677 // find first shared track
2679 // mean number of clusters
2680 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2682 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2683 Int_t sharedtrack=100000;
2684 Int_t tracks[24],trackindex=0;
2685 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2687 for (Int_t icluster=0;icluster<6;icluster++){
2688 if (clusterlist[icluster]<0) continue;
2689 Int_t index = clusterlist[icluster];
2690 Int_t l=(index & 0xf0000000) >> 28;
2691 Int_t c=(index & 0x0fffffff) >> 00;
2693 printf("problem\n");
2695 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2696 //if (l>3) continue;
2697 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2700 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2701 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2702 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2704 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2707 deltan = (cl->GetNz()-nz[l]);
2709 if (deltan>2.0) continue; // extended - highly probable shared cluster
2711 for (Int_t itrack=3;itrack>=0;itrack--){
2712 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2713 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2714 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2719 if (trackindex==0) return -1;
2721 sharedtrack = tracks[0];
2723 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2726 Int_t tracks2[24], cluster[24];
2727 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2730 for (Int_t i=0;i<trackindex;i++){
2731 if (tracks[i]<0) continue;
2732 tracks2[index] = tracks[i];
2734 for (Int_t j=i+1;j<trackindex;j++){
2735 if (tracks[j]<0) continue;
2736 if (tracks[j]==tracks[i]){
2744 for (Int_t i=0;i<index;i++){
2745 if (cluster[index]>max) {
2746 sharedtrack=tracks2[index];
2753 if (sharedtrack>=100000) return -1;
2755 // make list of overlaps
2757 for (Int_t icluster=0;icluster<6;icluster++){
2758 if (clusterlist[icluster]<0) continue;
2759 Int_t index = clusterlist[icluster];
2760 Int_t l=(index & 0xf0000000) >> 28;
2761 Int_t c=(index & 0x0fffffff) >> 00;
2762 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2763 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2765 if (cl->GetNy()>2) continue;
2766 if (cl->GetNz()>2) continue;
2769 if (cl->GetNy()>3) continue;
2770 if (cl->GetNz()>3) continue;
2773 for (Int_t itrack=3;itrack>=0;itrack--){
2774 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2775 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2783 //------------------------------------------------------------------------
2784 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2786 // try to find track hypothesys without conflicts
2787 // with minimal chi2;
2788 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2789 Int_t entries1 = arr1->GetEntriesFast();
2790 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2791 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2792 Int_t entries2 = arr2->GetEntriesFast();
2793 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2795 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2796 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2797 if (track10->Pt()>0.5+track20->Pt()) return track10;
2799 for (Int_t itrack=0;itrack<entries1;itrack++){
2800 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2801 UnRegisterClusterTracks(track,trackID1);
2804 for (Int_t itrack=0;itrack<entries2;itrack++){
2805 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2806 UnRegisterClusterTracks(track,trackID2);
2810 Float_t maxconflicts=6;
2811 Double_t maxchi2 =1000.;
2813 // get weight of hypothesys - using best hypothesy
2816 Int_t list1[6],list2[6];
2817 AliITSRecPoint *clist1[6], *clist2[6] ;
2818 RegisterClusterTracks(track10,trackID1);
2819 RegisterClusterTracks(track20,trackID2);
2820 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2821 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2822 UnRegisterClusterTracks(track10,trackID1);
2823 UnRegisterClusterTracks(track20,trackID2);
2826 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2827 Float_t nerry[6],nerrz[6];
2828 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2829 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2830 for (Int_t i=0;i<6;i++){
2831 if ( (erry1[i]>0) && (erry2[i]>0)) {
2832 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2833 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2835 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2836 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2838 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2839 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2840 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2843 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2844 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2845 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2853 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2854 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2855 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2856 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2858 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2859 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2860 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2862 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2863 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2864 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2867 Double_t sumw = w1+w2;
2871 w1 = (d2+0.5)/(d1+d2+1.);
2872 w2 = (d1+0.5)/(d1+d2+1.);
2874 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2875 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2877 // get pair of "best" hypothesys
2879 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2880 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2882 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2883 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2884 //if (track1->fFakeRatio>0) continue;
2885 RegisterClusterTracks(track1,trackID1);
2886 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2887 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2889 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2890 //if (track2->fFakeRatio>0) continue;
2892 RegisterClusterTracks(track2,trackID2);
2893 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2894 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2895 UnRegisterClusterTracks(track2,trackID2);
2897 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2898 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2899 if (nskipped>0.5) continue;
2901 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2902 if (conflict1+1<cconflict1) continue;
2903 if (conflict2+1<cconflict2) continue;
2907 for (Int_t i=0;i<6;i++){
2909 Float_t c1 =0.; // conflict coeficients
2911 if (clist1[i]&&clist2[i]){
2914 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2917 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
2919 c1 = 2./TMath::Max(3.+deltan,2.);
2920 c2 = 2./TMath::Max(3.+deltan,2.);
2926 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
2929 deltan = (clist1[i]->GetNz()-nz1[i]);
2931 c1 = 2./TMath::Max(3.+deltan,2.);
2938 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
2941 deltan = (clist2[i]->GetNz()-nz2[i]);
2943 c2 = 2./TMath::Max(3.+deltan,2.);
2949 if (TMath::Abs(track1->GetDy(i))>0.) {
2950 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
2951 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
2952 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
2953 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
2955 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
2958 if (TMath::Abs(track2->GetDy(i))>0.) {
2959 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
2960 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
2961 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
2962 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
2965 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
2967 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
2968 if (chi21>0) sum+=w1;
2969 if (chi22>0) sum+=w2;
2972 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
2973 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
2974 Double_t normchi2 = 2*conflict+sumchi2/sum;
2975 if ( normchi2 <maxchi2 ){
2978 maxconflicts = conflict;
2982 UnRegisterClusterTracks(track1,trackID1);
2985 // if (maxconflicts<4 && maxchi2<th0){
2986 if (maxchi2<th0*2.){
2987 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
2988 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
2989 track1->SetChi2MIP(5,maxconflicts);
2990 track1->SetChi2MIP(6,maxchi2);
2991 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
2992 // track1->UpdateESDtrack(AliESDtrack::kITSin);
2993 track1->SetChi2MIP(8,index1);
2994 fBestTrackIndex[trackID1] =index1;
2995 UpdateESDtrack(track1, AliESDtrack::kITSin);
2997 else if (track10->GetChi2MIP(0)<th1){
2998 track10->SetChi2MIP(5,maxconflicts);
2999 track10->SetChi2MIP(6,maxchi2);
3000 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3001 UpdateESDtrack(track10,AliESDtrack::kITSin);
3004 for (Int_t itrack=0;itrack<entries1;itrack++){
3005 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3006 UnRegisterClusterTracks(track,trackID1);
3009 for (Int_t itrack=0;itrack<entries2;itrack++){
3010 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3011 UnRegisterClusterTracks(track,trackID2);
3014 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3015 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3016 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3017 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3018 RegisterClusterTracks(track10,trackID1);
3020 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3021 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3022 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3023 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3024 RegisterClusterTracks(track20,trackID2);
3029 //------------------------------------------------------------------------
3030 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3031 //--------------------------------------------------------------------
3032 // This function marks clusters assigned to the track
3033 //--------------------------------------------------------------------
3034 AliTracker::UseClusters(t,from);
3036 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3037 //if (c->GetQ()>2) c->Use();
3038 if (c->GetSigmaZ2()>0.1) c->Use();
3039 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3040 //if (c->GetQ()>2) c->Use();
3041 if (c->GetSigmaZ2()>0.1) c->Use();
3044 //------------------------------------------------------------------------
3045 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3047 //------------------------------------------------------------------
3048 // add track to the list of hypothesys
3049 //------------------------------------------------------------------
3051 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3052 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3054 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3056 array = new TObjArray(10);
3057 fTrackHypothesys.AddAt(array,esdindex);
3059 array->AddLast(track);
3061 //------------------------------------------------------------------------
3062 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3064 //-------------------------------------------------------------------
3065 // compress array of track hypothesys
3066 // keep only maxsize best hypothesys
3067 //-------------------------------------------------------------------
3068 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3069 if (! (fTrackHypothesys.At(esdindex)) ) return;
3070 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3071 Int_t entries = array->GetEntriesFast();
3073 //- find preliminary besttrack as a reference
3074 Float_t minchi2=10000;
3076 AliITStrackMI * besttrack=0;
3077 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3078 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3079 if (!track) continue;
3080 Float_t chi2 = NormalizedChi2(track,0);
3082 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3083 track->SetLabel(tpcLabel);
3085 track->SetFakeRatio(1.);
3086 CookLabel(track,0.); //For comparison only
3088 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3089 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3090 if (track->GetNumberOfClusters()<maxn) continue;
3091 maxn = track->GetNumberOfClusters();
3098 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3099 delete array->RemoveAt(itrack);
3103 if (!besttrack) return;
3106 //take errors of best track as a reference
3107 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3108 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3109 for (Int_t j=0;j<6;j++) {
3110 if (besttrack->GetClIndex(j)>=0){
3111 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3112 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3113 ny[j] = besttrack->GetNy(j);
3114 nz[j] = besttrack->GetNz(j);
3118 // calculate normalized chi2
3120 Float_t * chi2 = new Float_t[entries];
3121 Int_t * index = new Int_t[entries];
3122 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3123 for (Int_t itrack=0;itrack<entries;itrack++){
3124 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3126 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3127 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3128 chi2[itrack] = track->GetChi2MIP(0);
3130 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3131 delete array->RemoveAt(itrack);
3137 TMath::Sort(entries,chi2,index,kFALSE);
3138 besttrack = (AliITStrackMI*)array->At(index[0]);
3139 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3140 for (Int_t j=0;j<6;j++){
3141 if (besttrack->GetClIndex(j)>=0){
3142 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3143 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3144 ny[j] = besttrack->GetNy(j);
3145 nz[j] = besttrack->GetNz(j);
3150 // calculate one more time with updated normalized errors
3151 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3152 for (Int_t itrack=0;itrack<entries;itrack++){
3153 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3155 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3156 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3157 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3160 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3161 delete array->RemoveAt(itrack);
3166 entries = array->GetEntriesFast();
3170 TObjArray * newarray = new TObjArray();
3171 TMath::Sort(entries,chi2,index,kFALSE);
3172 besttrack = (AliITStrackMI*)array->At(index[0]);
3175 for (Int_t j=0;j<6;j++){
3176 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3177 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3178 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3179 ny[j] = besttrack->GetNy(j);
3180 nz[j] = besttrack->GetNz(j);
3183 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3184 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3185 Float_t minn = besttrack->GetNumberOfClusters()-3;
3187 for (Int_t i=0;i<entries;i++){
3188 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3189 if (!track) continue;
3190 if (accepted>maxcut) break;
3191 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3192 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3193 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3194 delete array->RemoveAt(index[i]);
3198 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3199 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3200 if (!shortbest) accepted++;
3202 newarray->AddLast(array->RemoveAt(index[i]));
3203 for (Int_t j=0;j<6;j++){
3205 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3206 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3207 ny[j] = track->GetNy(j);
3208 nz[j] = track->GetNz(j);
3213 delete array->RemoveAt(index[i]);
3217 delete fTrackHypothesys.RemoveAt(esdindex);
3218 fTrackHypothesys.AddAt(newarray,esdindex);
3222 delete fTrackHypothesys.RemoveAt(esdindex);
3228 //------------------------------------------------------------------------
3229 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3231 //-------------------------------------------------------------
3232 // try to find best hypothesy
3233 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3234 //-------------------------------------------------------------
3235 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3236 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3237 if (!array) return 0;
3238 Int_t entries = array->GetEntriesFast();
3239 if (!entries) return 0;
3240 Float_t minchi2 = 100000;
3241 AliITStrackMI * besttrack=0;
3243 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3244 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3245 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3246 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3248 for (Int_t i=0;i<entries;i++){
3249 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3250 if (!track) continue;
3251 Float_t sigmarfi,sigmaz;
3252 GetDCASigma(track,sigmarfi,sigmaz);
3253 track->SetDnorm(0,sigmarfi);
3254 track->SetDnorm(1,sigmaz);
3256 track->SetChi2MIP(1,1000000);
3257 track->SetChi2MIP(2,1000000);
3258 track->SetChi2MIP(3,1000000);
3261 backtrack = new(backtrack) AliITStrackMI(*track);
3262 if (track->GetConstrain()) {
3263 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3264 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3265 backtrack->ResetCovariance(10.);
3267 backtrack->ResetCovariance(10.);
3269 backtrack->ResetClusters();
3271 Double_t x = original->GetX();
3272 if (!RefitAt(x,backtrack,track)) continue;
3274 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3275 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3276 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3277 track->SetChi22(GetMatchingChi2(backtrack,original));
3279 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3280 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3281 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3284 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3286 //forward track - without constraint
3287 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3288 forwardtrack->ResetClusters();
3290 RefitAt(x,forwardtrack,track);
3291 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3292 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3293 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3295 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3296 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3297 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3298 forwardtrack->SetD(0,track->GetD(0));
3299 forwardtrack->SetD(1,track->GetD(1));
3302 AliITSRecPoint* clist[6];
3303 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3304 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3307 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3308 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3309 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3310 track->SetChi2MIP(3,1000);
3313 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3315 for (Int_t ichi=0;ichi<5;ichi++){
3316 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3318 if (chi2 < minchi2){
3319 //besttrack = new AliITStrackMI(*forwardtrack);
3321 besttrack->SetLabel(track->GetLabel());
3322 besttrack->SetFakeRatio(track->GetFakeRatio());
3324 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3325 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3326 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3330 delete forwardtrack;
3332 for (Int_t i=0;i<entries;i++){
3333 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3335 if (!track) continue;
3337 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3338 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3339 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3340 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3341 delete array->RemoveAt(i);
3351 SortTrackHypothesys(esdindex,checkmax,1);
3353 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3354 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3355 besttrack = (AliITStrackMI*)array->At(0);
3356 if (!besttrack) return 0;
3357 besttrack->SetChi2MIP(8,0);
3358 fBestTrackIndex[esdindex]=0;
3359 entries = array->GetEntriesFast();
3360 AliITStrackMI *longtrack =0;
3362 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3363 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3364 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3365 if (!track->GetConstrain()) continue;
3366 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3367 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3368 if (track->GetChi2MIP(0)>4.) continue;
3369 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3372 //if (longtrack) besttrack=longtrack;
3375 AliITSRecPoint * clist[6];
3376 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3377 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3378 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3379 RegisterClusterTracks(besttrack,esdindex);
3386 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3387 if (sharedtrack>=0){
3389 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3391 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3397 if (shared>2.5) return 0;
3398 if (shared>1.0) return besttrack;
3400 // Don't sign clusters if not gold track
3402 if (!besttrack->IsGoldPrimary()) return besttrack;
3403 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3405 if (fConstraint[fPass]){
3409 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3410 for (Int_t i=0;i<6;i++){
3411 Int_t index = besttrack->GetClIndex(i);
3412 if (index<0) continue;
3413 Int_t ilayer = (index & 0xf0000000) >> 28;
3414 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3415 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3417 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3418 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3419 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3420 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3421 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3422 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3424 Bool_t cansign = kTRUE;
3425 for (Int_t itrack=0;itrack<entries; itrack++){
3426 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3427 if (!track) continue;
3428 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3429 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3435 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3436 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3437 if (!c->IsUsed()) c->Use();
3443 //------------------------------------------------------------------------
3444 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3447 // get "best" hypothesys
3450 Int_t nentries = itsTracks.GetEntriesFast();
3451 for (Int_t i=0;i<nentries;i++){
3452 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3453 if (!track) continue;
3454 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3455 if (!array) continue;
3456 if (array->GetEntriesFast()<=0) continue;
3458 AliITStrackMI* longtrack=0;
3460 Float_t maxchi2=1000;
3461 for (Int_t j=0;j<array->GetEntriesFast();j++){
3462 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3463 if (!trackHyp) continue;
3464 if (trackHyp->GetGoldV0()) {
3465 longtrack = trackHyp; //gold V0 track taken
3468 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3469 Float_t chi2 = trackHyp->GetChi2MIP(0);
3471 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3473 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3475 if (chi2 > maxchi2) continue;
3476 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3483 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3484 if (!longtrack) {longtrack = besttrack;}
3485 else besttrack= longtrack;
3489 AliITSRecPoint * clist[6];
3490 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3492 track->SetNUsed(shared);
3493 track->SetNSkipped(besttrack->GetNSkipped());
3494 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3496 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3500 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3501 //if (sharedtrack==-1) sharedtrack=0;
3502 if (sharedtrack>=0) {
3503 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3506 if (besttrack&&fAfterV0) {
3507 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3509 if (besttrack&&fConstraint[fPass])
3510 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3511 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3512 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3513 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3519 //------------------------------------------------------------------------
3520 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3521 //--------------------------------------------------------------------
3522 //This function "cooks" a track label. If label<0, this track is fake.
3523 //--------------------------------------------------------------------
3526 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3528 track->SetChi2MIP(9,0);
3530 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3531 Int_t cindex = track->GetClusterIndex(i);
3532 Int_t l=(cindex & 0xf0000000) >> 28;
3533 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3535 for (Int_t ind=0;ind<3;ind++){
3537 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3538 AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3540 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3543 Int_t nclusters = track->GetNumberOfClusters();
3544 if (nclusters > 0) //PH Some tracks don't have any cluster
3545 track->SetFakeRatio(double(nwrong)/double(nclusters));
3547 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3549 track->SetLabel(tpcLabel);
3551 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3554 //------------------------------------------------------------------------
3555 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3560 //AliITSRecPoint * clist[6];
3561 // Int_t shared = GetNumberOfSharedClusters(track,index,list,clist);
3564 track->SetChi2MIP(9,0);
3565 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3566 Int_t cindex = track->GetClusterIndex(i);
3567 Int_t l=(cindex & 0xf0000000) >> 28;
3568 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3569 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3571 for (Int_t ind=0;ind<3;ind++){
3572 if (cl->GetLabel(ind)==lab) isWrong=0;
3574 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3576 //if (l>3 && (cl->GetNy()>4) || (cl->GetNz()>4)) continue; //shared track
3577 //if (l>3&& !(cl->GetType()==1||cl->GetType()==10)) continue;
3578 //if (l<4&& !(cl->GetType()==1)) continue;
3579 dedx[accepted]= track->GetSampledEdx(i);
3580 //dedx[accepted]= track->fNormQ[l];
3588 TMath::Sort(accepted,dedx,indexes,kFALSE);
3591 Double_t nl=low*accepted, nu =up*accepted;
3593 Float_t sumweight =0;
3594 for (Int_t i=0; i<accepted; i++) {
3596 if (i<nl+0.1) weight = TMath::Max(1.-(nl-i),0.);
3597 if (i>nu-1) weight = TMath::Max(nu-i,0.);
3598 sumamp+= dedx[indexes[i]]*weight;
3601 track->SetdEdx(sumamp/sumweight);
3603 //------------------------------------------------------------------------
3604 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3606 // Create some arrays
3608 if (fCoefficients) delete []fCoefficients;
3609 fCoefficients = new Float_t[ntracks*48];
3610 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3612 //------------------------------------------------------------------------
3613 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3616 // Compute predicted chi2
3619 Float_t theta = track->GetTgl();
3620 Float_t phi = track->GetSnp();
3621 phi = TMath::Abs(phi)*TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3622 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz);
3623 AliDebug(2,Form(" chi2: tr-cl %f %f tr X %f cl X %f",track->GetY()-cluster->GetY(),track->GetZ()-cluster->GetZ(),track->GetX(),cluster->GetX()));
3624 // Take into account the mis-alignment (bring track to cluster plane)
3625 Double_t xTrOrig=track->GetX();
3626 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3627 AliDebug(2,Form(" chi2: tr-cl %f %f tr X %f cl X %f",track->GetY()-cluster->GetY(),track->GetZ()-cluster->GetZ(),track->GetX(),cluster->GetX()));
3628 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz);
3629 // Bring the track back to detector plane in ideal geometry
3630 // [mis-alignment will be accounted for in UpdateMI()]
3631 if (!track->Propagate(xTrOrig)) return 1000.;
3633 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3634 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3636 chi2+=0.5*TMath::Min(delta/2,2.);
3637 chi2+=2.*cluster->GetDeltaProbability();
3640 track->SetNy(layer,ny);
3641 track->SetNz(layer,nz);
3642 track->SetSigmaY(layer,erry);
3643 track->SetSigmaZ(layer, errz);
3644 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3645 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3649 //------------------------------------------------------------------------
3650 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3655 Int_t layer = (index & 0xf0000000) >> 28;
3656 track->SetClIndex(layer, index);
3657 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3658 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3659 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3660 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3664 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3667 // Take into account the mis-alignment (bring track to cluster plane)
3668 Double_t xTrOrig=track->GetX();
3669 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3670 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3671 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3672 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3674 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3678 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3679 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3682 Int_t updated = track->UpdateMI(&c,chi2,index);
3684 // Bring the track back to detector plane in ideal geometry
3685 if (!track->Propagate(xTrOrig)) return 0;
3687 if(!updated) AliDebug(2,"update failed");
3691 //------------------------------------------------------------------------
3692 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3695 //DCA sigmas parameterization
3696 //to be paramterized using external parameters in future
3699 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3700 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3702 //------------------------------------------------------------------------
3703 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3706 // Clusters from delta electrons?
3708 Int_t entries = clusterArray->GetEntriesFast();
3709 if (entries<4) return;
3710 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3711 Int_t layer = cluster->GetLayer();
3712 if (layer>1) return;
3714 Int_t ncandidates=0;
3715 Float_t r = (layer>0)? 7:4;
3717 for (Int_t i=0;i<entries;i++){
3718 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3719 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3720 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3721 index[ncandidates] = i; //candidate to belong to delta electron track
3723 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3724 cl0->SetDeltaProbability(1);
3730 for (Int_t i=0;i<ncandidates;i++){
3731 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3732 if (cl0->GetDeltaProbability()>0.8) continue;
3735 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3736 sumy=sumz=sumy2=sumyz=sumw=0.0;
3737 for (Int_t j=0;j<ncandidates;j++){
3739 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3741 Float_t dz = cl0->GetZ()-cl1->GetZ();
3742 Float_t dy = cl0->GetY()-cl1->GetY();
3743 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3744 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3745 y[ncl] = cl1->GetY();
3746 z[ncl] = cl1->GetZ();
3747 sumy+= y[ncl]*weight;
3748 sumz+= z[ncl]*weight;
3749 sumy2+=y[ncl]*y[ncl]*weight;
3750 sumyz+=y[ncl]*z[ncl]*weight;
3755 if (ncl<4) continue;
3756 Float_t det = sumw*sumy2 - sumy*sumy;
3758 if (TMath::Abs(det)>0.01){
3759 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3760 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3761 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3764 Float_t z0 = sumyz/sumy;
3765 delta = TMath::Abs(cl0->GetZ()-z0);
3768 cl0->SetDeltaProbability(1-20.*delta);
3772 //------------------------------------------------------------------------
3773 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3778 track->UpdateESDtrack(flags);
3779 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3780 if (oldtrack) delete oldtrack;
3781 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3782 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3783 printf("Problem\n");
3786 //------------------------------------------------------------------------
3787 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3789 // Get nearest upper layer close to the point xr.
3790 // rough approximation
3792 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3793 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3795 for (Int_t i=0;i<6;i++){
3796 if (radius<kRadiuses[i]){
3804 //------------------------------------------------------------------------
3805 void AliITStrackerMI::UpdateTPCV0(const AliESDEvent *event){
3807 //try to update, or reject TPC V0s
3809 Int_t nv0s = event->GetNumberOfV0s();
3810 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3812 for (Int_t i=0;i<nv0s;i++){
3813 AliESDv0 * vertex = event->GetV0(i);
3814 Int_t ip = vertex->GetIndex(0);
3815 Int_t im = vertex->GetIndex(1);
3817 TObjArray * arrayp = (ip<nitstracks) ? (TObjArray*)fTrackHypothesys.At(ip):0;
3818 TObjArray * arraym = (im<nitstracks) ? (TObjArray*)fTrackHypothesys.At(im):0;
3819 AliITStrackMI * trackp = (arrayp!=0) ? (AliITStrackMI*)arrayp->At(0):0;
3820 AliITStrackMI * trackm = (arraym!=0) ? (AliITStrackMI*)arraym->At(0):0;
3824 if (trackp->GetNumberOfClusters()+trackp->GetNDeadZone()>5.5){
3825 if (trackp->GetConstrain()&&trackp->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3826 if (!trackp->GetConstrain()&&trackp->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3831 if (trackm->GetNumberOfClusters()+trackm->GetNDeadZone()>5.5){
3832 if (trackm->GetConstrain()&&trackm->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3833 if (!trackm->GetConstrain()&&trackm->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3836 if (vertex->GetStatus()==-100) continue;
3838 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
3839 Int_t clayer = GetNearestLayer(xrp); //I.B.
3840 vertex->SetNBefore(clayer); //
3841 vertex->SetChi2Before(9*clayer); //
3842 vertex->SetNAfter(6-clayer); //
3843 vertex->SetChi2After(0); //
3845 if (clayer >1 ){ // calculate chi2 before vertex
3846 Float_t chi2p = 0, chi2m=0;
3849 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3850 if (trackp->GetClIndex(ilayer)>=0){
3851 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3852 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3863 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3864 if (trackm->GetClIndex(ilayer)>=0){
3865 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3866 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3875 vertex->SetChi2Before(TMath::Min(chi2p,chi2m));
3876 if (TMath::Min(chi2p,chi2m)/Float_t(clayer)<4) vertex->SetStatus(-10); // track exist before vertex
3879 if (clayer < 5 ){ // calculate chi2 after vertex
3880 Float_t chi2p = 0, chi2m=0;
3882 if (trackp&&TMath::Abs(trackp->GetTgl())<1.){
3883 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3884 if (trackp->GetClIndex(ilayer)>=0){
3885 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3886 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3896 if (trackm&&TMath::Abs(trackm->GetTgl())<1.){
3897 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3898 if (trackm->GetClIndex(ilayer)>=0){
3899 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3900 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3909 vertex->SetChi2After(TMath::Max(chi2p,chi2m));
3910 if (TMath::Max(chi2m,chi2p)/Float_t(6-clayer)>9) vertex->SetStatus(-20); // track not found in ITS
3915 //------------------------------------------------------------------------
3916 void AliITStrackerMI::FindV02(AliESDEvent *event)
3921 // Cuts on DCA - R dependent
3922 // max distance DCA between 2 tracks cut
3923 // maxDist = TMath::Min(kMaxDist,kMaxDist0+pvertex->GetRr()*kMaxDist);
3925 const Float_t kMaxDist0 = 0.1;
3926 const Float_t kMaxDist1 = 0.1;
3927 const Float_t kMaxDist = 1;
3928 const Float_t kMinPointAngle = 0.85;
3929 const Float_t kMinPointAngle2 = 0.99;
3930 const Float_t kMinR = 0.5;
3931 const Float_t kMaxR = 220;
3932 //const Float_t kCausality0Cut = 0.19;
3933 //const Float_t kLikelihood01Cut = 0.25;
3934 //const Float_t kPointAngleCut = 0.9996;
3935 const Float_t kCausality0Cut = 0.19;
3936 const Float_t kLikelihood01Cut = 0.45;
3937 const Float_t kLikelihood1Cut = 0.5;
3938 const Float_t kCombinedCut = 0.55;
3942 TTreeSRedirector &cstream = *fDebugStreamer;
3943 Int_t ntracks = event->GetNumberOfTracks();
3944 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3945 fOriginal.Expand(ntracks);
3946 fTrackHypothesys.Expand(ntracks);
3947 fBestHypothesys.Expand(ntracks);
3949 AliHelix * helixes = new AliHelix[ntracks+2];
3950 TObjArray trackarray(ntracks+2); //array with tracks - with vertex constrain
3951 TObjArray trackarrayc(ntracks+2); //array of "best tracks" - without vertex constrain
3952 TObjArray trackarrayl(ntracks+2); //array of "longest tracks" - without vertex constrain
3953 Bool_t * forbidden = new Bool_t [ntracks+2];
3954 Int_t *itsmap = new Int_t [ntracks+2];
3955 Float_t *dist = new Float_t[ntracks+2];
3956 Float_t *normdist0 = new Float_t[ntracks+2];
3957 Float_t *normdist1 = new Float_t[ntracks+2];
3958 Float_t *normdist = new Float_t[ntracks+2];
3959 Float_t *norm = new Float_t[ntracks+2];
3960 Float_t *maxr = new Float_t[ntracks+2];
3961 Float_t *minr = new Float_t[ntracks+2];
3962 Float_t *minPointAngle= new Float_t[ntracks+2];
3964 AliV0 *pvertex = new AliV0;
3965 AliITStrackMI * dummy= new AliITStrackMI;
3967 AliITStrackMI trackat0; //temporary track for DCA calculation
3969 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
3971 // make ITS - ESD map
3973 for (Int_t itrack=0;itrack<ntracks+2;itrack++) {
3974 itsmap[itrack] = -1;
3975 forbidden[itrack] = kFALSE;
3976 maxr[itrack] = kMaxR;
3977 minr[itrack] = kMinR;
3978 minPointAngle[itrack] = kMinPointAngle;
3980 for (Int_t itrack=0;itrack<nitstracks;itrack++){
3981 AliITStrackMI * original = (AliITStrackMI*)(fOriginal.At(itrack));
3982 Int_t esdindex = original->GetESDtrack()->GetID();
3983 itsmap[esdindex] = itrack;
3986 // create ITS tracks from ESD tracks if not done before
3988 for (Int_t itrack=0;itrack<ntracks;itrack++){
3989 if (itsmap[itrack]>=0) continue;
3990 AliITStrackMI * tpctrack = new AliITStrackMI(*(event->GetTrack(itrack)));
3991 //tpctrack->fD[0] = tpctrack->GetD(GetX(),GetY());
3992 //tpctrack->fD[1] = tpctrack->GetZat(GetX())-GetZ();
3993 tpctrack->GetDZ(GetX(),GetY(),GetZ(),tpctrack->GetDP()); //I.B.
3994 if (tpctrack->GetD(0)<20 && tpctrack->GetD(1)<20){
3995 // tracks which can reach inner part of ITS
3996 // propagate track to outer its volume - with correction for material
3997 CorrectForTPCtoITSDeadZoneMaterial(tpctrack);
3999 itsmap[itrack] = nitstracks;
4000 fOriginal.AddAt(tpctrack,nitstracks);
4004 // fill temporary arrays
4006 for (Int_t itrack=0;itrack<ntracks;itrack++){
4007 AliESDtrack * esdtrack = event->GetTrack(itrack);
4008 Int_t itsindex = itsmap[itrack];
4009 AliITStrackMI *original = (AliITStrackMI*)fOriginal.At(itsmap[itrack]);
4010 if (!original) continue;
4011 AliITStrackMI *bestConst = 0;
4012 AliITStrackMI *bestLong = 0;
4013 AliITStrackMI *best = 0;
4016 TObjArray * array = (TObjArray*) fTrackHypothesys.At(itsindex);
4017 Int_t hentries = (array==0) ? 0 : array->GetEntriesFast();
4018 // Get best track with vertex constrain
4019 for (Int_t ih=0;ih<hentries;ih++){
4020 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
4021 if (!trackh->GetConstrain()) continue;
4022 if (!bestConst) bestConst = trackh;
4023 if (trackh->GetNumberOfClusters()>5.0){
4024 bestConst = trackh; // full track - with minimal chi2
4027 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()) continue;
4031 // Get best long track without vertex constrain and best track without vertex constrain
4032 for (Int_t ih=0;ih<hentries;ih++){
4033 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
4034 if (trackh->GetConstrain()) continue;
4035 if (!best) best = trackh;
4036 if (!bestLong) bestLong = trackh;
4037 if (trackh->GetNumberOfClusters()>5.0){
4038 bestLong = trackh; // full track - with minimal chi2
4041 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()) continue;
4046 bestLong = original;
4048 //I.B. trackat0 = *bestLong;
4049 new (&trackat0) AliITStrackMI(*bestLong);
4050 Double_t xx,yy,zz,alpha;
4051 if (!bestLong->GetGlobalXYZat(bestLong->GetX(),xx,yy,zz)) continue;
4052 alpha = TMath::ATan2(yy,xx);
4053 if (!trackat0.Propagate(alpha,0)) continue;
4054 // calculate normalized distances to the vertex
4056 Float_t ptfac = (1.+100.*TMath::Abs(trackat0.GetC()));
4057 if ( bestLong->GetNumberOfClusters()>3 ){
4058 dist[itsindex] = trackat0.GetY();
4059 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
4060 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
4061 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
4062 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
4064 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<6) normdist[itsindex]*=2.;
4065 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<5) normdist[itsindex]*=2.;
4066 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<4) normdist[itsindex]*=2.;
4068 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<6) normdist[itsindex]*=1.5;
4069 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<5) normdist[itsindex]*=1.5;
4073 if (bestConst&&bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5){
4074 dist[itsindex] = bestConst->GetD(0);
4075 norm[itsindex] = bestConst->GetDnorm(0);
4076 normdist0[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
4077 normdist1[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
4078 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
4080 dist[itsindex] = trackat0.GetY();
4081 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
4082 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
4083 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
4084 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
4085 if (TMath::Abs(trackat0.GetTgl())>1.05){
4086 if (normdist[itsindex]<3) forbidden[itsindex]=kTRUE;
4087 if (normdist[itsindex]>3) {
4088 minr[itsindex] = TMath::Max(Float_t(40.),minr[itsindex]);
4094 //-----------------------------------------------------------
4095 //Forbid primary track candidates -
4097 //treetr->SetAlias("forbidden0","Tr0.fN<4&&Tr1.fN+Tr1.fNDeadZone>4.5");
4098 //treetr->SetAlias("forbidden1","ND<3&&Tr1.fN+Tr1.fNDeadZone>5.5");
4099 //treetr->SetAlias("forbidden2","ND<2&&Tr1.fClIndex[0]>0&&Tr1.fClIndex[0]>0");
4100 //treetr->SetAlias("forbidden3","ND<1&&Tr1.fClIndex[0]>0");
4101 //treetr->SetAlias("forbidden4","ND<4&&Tr1.fNormChi2[0]<2");
4102 //treetr->SetAlias("forbidden5","ND<5&&Tr1.fNormChi2[0]<1");
4103 //-----------------------------------------------------------
4105 if (bestLong->GetNumberOfClusters()<4 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5) forbidden[itsindex]=kTRUE;
4106 if (normdist[itsindex]<3 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>5.5) forbidden[itsindex]=kTRUE;
4107 if (normdist[itsindex]<2 && bestConst->GetClIndex(0)>=0 && bestConst->GetClIndex(1)>=0 ) forbidden[itsindex]=kTRUE;
4108 if (normdist[itsindex]<1 && bestConst->GetClIndex(0)>=0) forbidden[itsindex]=kTRUE;
4109 if (normdist[itsindex]<4 && bestConst->GetNormChi2(0)<2) forbidden[itsindex]=kTRUE;
4110 if (normdist[itsindex]<5 && bestConst->GetNormChi2(0)<1) forbidden[itsindex]=kTRUE;
4111 if (bestConst->GetNormChi2(0)<2.5) {
4112 minPointAngle[itsindex]= 0.9999;
4113 maxr[itsindex] = 10;
4117 //forbid daughter kink candidates
4119 if (esdtrack->GetKinkIndex(0)>0) forbidden[itsindex] = kTRUE;
4120 Bool_t isElectron = kTRUE;
4121 Bool_t isProton = kTRUE;
4123 esdtrack->GetESDpid(pid);
4124 for (Int_t i=1;i<5;i++){
4125 if (pid[0]<pid[i]) isElectron= kFALSE;
4126 if (pid[4]<pid[i]) isProton= kFALSE;
4129 forbidden[itsindex]=kFALSE;
4130 normdist[itsindex]*=-1;
4133 if (normdist[itsindex]>2) forbidden[itsindex]=kFALSE;
4134 normdist[itsindex]*=-1;
4138 // Causality cuts in TPC volume
4140 if (esdtrack->GetTPCdensity(0,10) >0.6) maxr[itsindex] = TMath::Min(Float_t(110),maxr[itsindex]);
4141 if (esdtrack->GetTPCdensity(10,30)>0.6) maxr[itsindex] = TMath::Min(Float_t(120),maxr[itsindex]);
4142 if (esdtrack->GetTPCdensity(20,40)>0.6) maxr[itsindex] = TMath::Min(Float_t(130),maxr[itsindex]);
4143 if (esdtrack->GetTPCdensity(30,50)>0.6) maxr[itsindex] = TMath::Min(Float_t(140),maxr[itsindex]);
4145 if (esdtrack->GetTPCdensity(0,60)<0.4&&bestLong->GetNumberOfClusters()<3) minr[itsindex]=100;
4151 "Tr1.="<<((bestConst)? bestConst:dummy)<<
4153 "Tr3.="<<&trackat0<<
4155 "Dist="<<dist[itsindex]<<
4156 "ND0="<<normdist0[itsindex]<<
4157 "ND1="<<normdist1[itsindex]<<
4158 "ND="<<normdist[itsindex]<<
4159 "Pz="<<primvertex[2]<<
4160 "Forbid="<<forbidden[itsindex]<<
4164 trackarray.AddAt(best,itsindex);
4165 trackarrayc.AddAt(bestConst,itsindex);
4166 trackarrayl.AddAt(bestLong,itsindex);
4167 new (&helixes[itsindex]) AliHelix(*best);
4172 // first iterration of V0 finder
4174 for (Int_t iesd0=0;iesd0<ntracks;iesd0++){
4175 Int_t itrack0 = itsmap[iesd0];
4176 if (forbidden[itrack0]) continue;
4177 AliITStrackMI * btrack0 = (AliITStrackMI*)trackarray.At(itrack0);
4178 if (!btrack0) continue;
4179 if (btrack0->GetSign()>0 && !AliITSReconstructor::GetRecoParam()->GetStoreLikeSignV0s()) continue;
4180 AliITStrackMI *trackc0 = (AliITStrackMI*)trackarrayc.At(itrack0);
4182 for (Int_t iesd1=iesd0+1;iesd1<ntracks;iesd1++){
4183 Int_t itrack1 = itsmap[iesd1];
4184 if (forbidden[itrack1]) continue;
4186 AliITStrackMI * btrack1 = (AliITStrackMI*)trackarray.At(itrack1);
4187 if (!btrack1) continue;
4188 if (btrack1->GetSign()<0 && !AliITSReconstructor::GetRecoParam()->GetStoreLikeSignV0s()) continue;
4189 Bool_t isGold = kFALSE;
4190 if (TMath::Abs(TMath::Abs(btrack0->GetLabel())-TMath::Abs(btrack1->GetLabel()))==1){
4193 AliITStrackMI *trackc1 = (AliITStrackMI*)trackarrayc.At(itrack1);
4194 AliHelix &h1 = helixes[itrack0];
4195 AliHelix &h2 = helixes[itrack1];
4197 // find linear distance
4202 Double_t phase[2][2],radius[2];
4203 Int_t points = h1.GetRPHIintersections(h2, phase, radius);
4204 if (points==0) continue;
4205 Double_t delta[2]={1000000,1000000};
4207 h1.ParabolicDCA(h2,phase[0][0],phase[0][1],radius[0],delta[0]);
4209 if (radius[1]<rmin) rmin = radius[1];
4210 h1.ParabolicDCA(h2,phase[1][0],phase[1][1],radius[1],delta[1]);
4212 rmin = TMath::Sqrt(rmin);
4213 Double_t distance = 0;
4214 Double_t radiusC = 0;
4216 if (points==1 || delta[0]<delta[1]){
4217 distance = TMath::Sqrt(delta[0]);
4218 radiusC = TMath::Sqrt(radius[0]);
4220 distance = TMath::Sqrt(delta[1]);
4221 radiusC = TMath::Sqrt(radius[1]);
4224 if (radiusC<TMath::Max(minr[itrack0],minr[itrack1])) continue;
4225 if (radiusC>TMath::Min(maxr[itrack0],maxr[itrack1])) continue;
4226 Float_t maxDist = TMath::Min(kMaxDist,Float_t(kMaxDist0+radiusC*kMaxDist1));
4227 if (distance>maxDist) continue;
4228 Float_t pointAngle = h1.GetPointAngle(h2,phase[iphase],primvertex);
4229 if (pointAngle<TMath::Max(minPointAngle[itrack0],minPointAngle[itrack1])) continue;
4232 // Double_t distance = TestV0(h1,h2,pvertex,rmin);
4234 // if (distance>maxDist) continue;
4235 // if (pvertex->GetRr()<kMinR) continue;
4236 // if (pvertex->GetRr()>kMaxR) continue;
4237 AliITStrackMI * track0=btrack0;
4238 AliITStrackMI * track1=btrack1;
4239 // if (pvertex->GetRr()<3.5){
4241 //use longest tracks inside the pipe
4242 track0 = (AliITStrackMI*)trackarrayl.At(itrack0);
4243 track1 = (AliITStrackMI*)trackarrayl.At(itrack1);
4247 pvertex->SetParamN(*track0);
4248 pvertex->SetParamP(*track1);
4249 pvertex->Update(primvertex);
4250 pvertex->SetClusters(track0->ClIndex(),track1->ClIndex()); // register clusters
4252 if (pvertex->GetRr()<kMinR) continue;
4253 if (pvertex->GetRr()>kMaxR) continue;
4254 if (pvertex->GetV0CosineOfPointingAngle()<kMinPointAngle) continue;
4255 //Bo: if (pvertex->GetDist2()>maxDist) continue;
4256 if (pvertex->GetDcaV0Daughters()>maxDist) continue;
4257 //Bo: pvertex->SetLab(0,track0->GetLabel());
4258 //Bo: pvertex->SetLab(1,track1->GetLabel());
4259 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4260 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4262 AliITStrackMI * htrackc0 = trackc0 ? trackc0:dummy;
4263 AliITStrackMI * htrackc1 = trackc1 ? trackc1:dummy;
4267 TObjArray * array0b = (TObjArray*)fBestHypothesys.At(itrack0);
4268 if (!array0b&&pvertex->GetRr()<40 && TMath::Abs(track0->GetTgl())<1.1) {
4269 fCurrentEsdTrack = itrack0;
4270 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack0),itrack0, kFALSE);
4272 TObjArray * array1b = (TObjArray*)fBestHypothesys.At(itrack1);
4273 if (!array1b&&pvertex->GetRr()<40 && TMath::Abs(track1->GetTgl())<1.1) {
4274 fCurrentEsdTrack = itrack1;
4275 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack1),itrack1, kFALSE);
4278 AliITStrackMI * track0b = (AliITStrackMI*)fOriginal.At(itrack0);
4279 AliITStrackMI * track1b = (AliITStrackMI*)fOriginal.At(itrack1);
4280 AliITStrackMI * track0l = (AliITStrackMI*)fOriginal.At(itrack0);
4281 AliITStrackMI * track1l = (AliITStrackMI*)fOriginal.At(itrack1);
4283 Float_t minchi2before0=16;
4284 Float_t minchi2before1=16;
4285 Float_t minchi2after0 =16;
4286 Float_t minchi2after1 =16;
4287 Double_t xrp[3]; pvertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
4288 Int_t maxLayer = GetNearestLayer(xrp); //I.B.
4290 if (array0b) for (Int_t i=0;i<5;i++){
4291 // best track after vertex
4292 AliITStrackMI * btrack = (AliITStrackMI*)array0b->At(i);
4293 if (!btrack) continue;
4294 if (btrack->GetNumberOfClusters()>track0l->GetNumberOfClusters()) track0l = btrack;
4295 // if (btrack->fX<pvertex->GetRr()-2.-0.5/(0.1+pvertex->GetAnglep()[2])) {
4296 if (btrack->GetX()<pvertex->GetRr()-2.) {
4297 if ( (maxLayer>i+2|| (i==0)) && btrack->GetNumberOfClusters()==(6-i)&&i<3){
4300 if (maxLayer<3){ // take prim vertex as additional measurement
4301 if (normdist[itrack0]>0 && htrackc0){
4302 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack0]*normdist[itrack0],16.);
4304 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack0]*normdist[itrack0]+3.),16.);
4308 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4310 if (btrack->GetClIndex(ilayer)<0){
4314 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4315 for (Int_t itrack=0;itrack<4;itrack++){
4316 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack0){
4317 sumchi2+=18.; //shared cluster
4321 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4322 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4326 if (sumchi2<minchi2before0) minchi2before0=sumchi2;
4328 continue; //safety space - Geo manager will give exact layer
4331 minchi2after0 = btrack->GetNormChi2(i);
4334 if (array1b) for (Int_t i=0;i<5;i++){
4335 // best track after vertex
4336 AliITStrackMI * btrack = (AliITStrackMI*)array1b->At(i);
4337 if (!btrack) continue;
4338 if (btrack->GetNumberOfClusters()>track1l->GetNumberOfClusters()) track1l = btrack;
4339 // if (btrack->fX<pvertex->GetRr()-2-0.5/(0.1+pvertex->GetAnglep()[2])){
4340 if (btrack->GetX()<pvertex->GetRr()-2){
4341 if ((maxLayer>i+2 || (i==0))&&btrack->GetNumberOfClusters()==(6-i)&&(i<3)){
4344 if (maxLayer<3){ // take prim vertex as additional measurement
4345 if (normdist[itrack1]>0 && htrackc1){
4346 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack1]*normdist[itrack1],16.);
4348 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack1]*normdist[itrack1]+3.),16.);
4352 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4354 if (btrack->GetClIndex(ilayer)<0){
4358 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4359 for (Int_t itrack=0;itrack<4;itrack++){
4360 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack1){
4361 sumchi2+=18.; //shared cluster
4365 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4366 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4370 if (sumchi2<minchi2before1) minchi2before1=sumchi2;
4372 continue; //safety space - Geo manager will give exact layer
4375 minchi2after1 = btrack->GetNormChi2(i);
4379 // position resolution - used for DCA cut
4380 Float_t sigmad = track0b->GetSigmaY2()+track0b->GetSigmaZ2()+track1b->GetSigmaY2()+track1b->GetSigmaZ2()+
4381 (track0b->GetX()-pvertex->GetRr())*(track0b->GetX()-pvertex->GetRr())*(track0b->GetSigmaSnp2()+track0b->GetSigmaTgl2())+
4382 (track1b->GetX()-pvertex->GetRr())*(track1b->GetX()-pvertex->GetRr())*(track1b->GetSigmaSnp2()+track1b->GetSigmaTgl2());
4383 sigmad =TMath::Sqrt(sigmad)+0.04;
4384 if (pvertex->GetRr()>50){
4385 Double_t cov0[15],cov1[15];
4386 track0b->GetESDtrack()->GetInnerExternalCovariance(cov0);
4387 track1b->GetESDtrack()->GetInnerExternalCovariance(cov1);
4388 sigmad = cov0[0]+cov0[2]+cov1[0]+cov1[2]+
4389 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov0[5]+cov0[9])+
4390 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov1[5]+cov1[9]);
4391 sigmad =TMath::Sqrt(sigmad)+0.05;
4395 vertex2.SetParamN(*track0b);
4396 vertex2.SetParamP(*track1b);
4397 vertex2.Update(primvertex);
4398 //Bo: if (vertex2.GetDist2()<=pvertex->GetDist2()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4399 if (vertex2.GetDcaV0Daughters()<=pvertex->GetDcaV0Daughters()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4400 pvertex->SetParamN(*track0b);
4401 pvertex->SetParamP(*track1b);
4402 pvertex->Update(primvertex);
4403 pvertex->SetClusters(track0b->ClIndex(),track1b->ClIndex()); // register clusters
4404 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4405 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4407 pvertex->SetDistSigma(sigmad);
4408 //Bo: pvertex->SetDistNorm(pvertex->GetDist2()/sigmad);
4409 pvertex->SetNormDCAPrim(normdist[itrack0],normdist[itrack1]);
4411 // define likelihhod and causalities
4413 Float_t pa0=1, pa1=1, pb0=0.26, pb1=0.26;
4415 Float_t fnorm0 = normdist[itrack0];
4416 if (fnorm0<0) fnorm0*=-3;
4417 Float_t fnorm1 = normdist[itrack1];
4418 if (fnorm1<0) fnorm1*=-3;
4419 if ((pvertex->GetAnglep()[2]>0.1) || ( (pvertex->GetRr()<10.5)&& pvertex->GetAnglep()[2]>0.05 ) || (pvertex->GetRr()<3)){
4420 pb0 = TMath::Exp(-TMath::Min(fnorm0,Float_t(16.))/12.);
4421 pb1 = TMath::Exp(-TMath::Min(fnorm1,Float_t(16.))/12.);
4423 pvertex->SetChi2Before(normdist[itrack0]);
4424 pvertex->SetChi2After(normdist[itrack1]);
4425 pvertex->SetNAfter(0);
4426 pvertex->SetNBefore(0);
4428 pvertex->SetChi2Before(minchi2before0);
4429 pvertex->SetChi2After(minchi2before1);
4430 if (pvertex->GetAnglep()[2]>0.1 || ( pvertex->GetRr()<10.5 && pvertex->GetAnglep()[2]>0.05) || pvertex->GetRr()<3){
4431 pb0 = TMath::Exp(-TMath::Min(minchi2before0,Float_t(16))/12.);
4432 pb1 = TMath::Exp(-TMath::Min(minchi2before1,Float_t(16))/12.);
4434 pvertex->SetNAfter(maxLayer);
4435 pvertex->SetNBefore(maxLayer);
4437 if (pvertex->GetRr()<90){
4438 pa0 *= TMath::Min(track0->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4439 pa1 *= TMath::Min(track1->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4441 if (pvertex->GetRr()<20){
4442 pa0 *= (0.2+TMath::Exp(-TMath::Min(minchi2after0,Float_t(16))/8.))/1.2;
4443 pa1 *= (0.2+TMath::Exp(-TMath::Min(minchi2after1,Float_t(16))/8.))/1.2;
4446 pvertex->SetCausality(pb0,pb1,pa0,pa1);
4448 // Likelihood calculations - apply cuts
4450 Bool_t v0OK = kTRUE;
4451 Float_t p12 = pvertex->GetParamP()->GetParameter()[4]*pvertex->GetParamP()->GetParameter()[4];
4452 p12 += pvertex->GetParamN()->GetParameter()[4]*pvertex->GetParamN()->GetParameter()[4];
4453 p12 = TMath::Sqrt(p12); // "mean" momenta
4454 Float_t sigmap0 = 0.0001+0.001/(0.1+pvertex->GetRr());
4455 Float_t sigmap = 0.5*sigmap0*(0.6+0.4*p12); // "resolution: of point angle - as a function of radius and momenta
4457 Float_t causalityA = (1.0-pvertex->GetCausalityP()[0])*(1.0-pvertex->GetCausalityP()[1]);
4458 Float_t causalityB = TMath::Sqrt(TMath::Min(pvertex->GetCausalityP()[2],Double_t(0.7))*
4459 TMath::Min(pvertex->GetCausalityP()[3],Double_t(0.7)));
4461 //Bo: Float_t likelihood0 = (TMath::Exp(-pvertex->GetDistNorm())+0.1) *(pvertex->GetDist2()<0.5)*(pvertex->GetDistNorm()<5);
4462 Float_t lDistNorm = pvertex->GetDcaV0Daughters()/pvertex->GetDistSigma();
4463 Float_t likelihood0 = (TMath::Exp(-lDistNorm)+0.1) *(pvertex->GetDcaV0Daughters()<0.5)*(lDistNorm<5);
4465 Float_t likelihood1 = TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/sigmap)+
4466 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(4.*sigmap))+
4467 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(8.*sigmap))+
4468 0.1*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/0.01);
4470 if (causalityA<kCausality0Cut) v0OK = kFALSE;
4471 if (TMath::Sqrt(likelihood0*likelihood1)<kLikelihood01Cut) v0OK = kFALSE;
4472 if (likelihood1<kLikelihood1Cut) v0OK = kFALSE;
4473 if (TMath::Power(likelihood0*likelihood1*causalityB,0.33)<kCombinedCut) v0OK = kFALSE;
4478 Bool_t gold = TMath::Abs(TMath::Abs(track0->GetLabel())-TMath::Abs(track1->GetLabel()))==1;
4480 "Tr0.="<<track0<< //best without constrain
4481 "Tr1.="<<track1<< //best without constrain
4482 "Tr0B.="<<track0b<< //best without constrain after vertex
4483 "Tr1B.="<<track1b<< //best without constrain after vertex
4484 "Tr0C.="<<htrackc0<< //best with constrain if exist
4485 "Tr1C.="<<htrackc1<< //best with constrain if exist
4486 "Tr0L.="<<track0l<< //longest best
4487 "Tr1L.="<<track1l<< //longest best
4488 "Esd0.="<<track0->GetESDtrack()<< // esd track0 params
4489 "Esd1.="<<track1->GetESDtrack()<< // esd track1 params
4490 "V0.="<<pvertex<< //vertex properties
4491 "V0b.="<<&vertex2<< //vertex properties at "best" track
4492 "ND0="<<normdist[itrack0]<< //normalize distance for track0
4493 "ND1="<<normdist[itrack1]<< //normalize distance for track1
4495 // "RejectBase="<<rejectBase<< //rejection in First itteration
4501 //if (rejectBase) continue;
4503 pvertex->SetStatus(0);
4504 // if (rejectBase) {
4505 // pvertex->SetStatus(-100);
4507 if (pvertex->GetV0CosineOfPointingAngle()>kMinPointAngle2) {
4508 //Bo: pvertex->SetESDindexes(track0->GetESDtrack()->GetID(),track1->GetESDtrack()->GetID());
4509 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());//Bo: consistency 0 for neg
4510 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());//Bo: consistency 1 for pos
4512 // AliV0vertex vertexjuri(*track0,*track1);
4513 // vertexjuri.SetESDindexes(track0->fESDtrack->GetID(),track1->fESDtrack->GetID());
4514 // event->AddV0(&vertexjuri);
4515 pvertex->SetStatus(100);
4517 pvertex->SetOnFlyStatus(kTRUE);
4518 pvertex->ChangeMassHypothesis(kK0Short);
4519 event->AddV0(pvertex);
4525 // delete temporary arrays
4528 delete[] minPointAngle;
4540 //------------------------------------------------------------------------
4541 void AliITStrackerMI::RefitV02(const AliESDEvent *event)
4544 //try to refit V0s in the third path of the reconstruction
4546 TTreeSRedirector &cstream = *fDebugStreamer;
4548 Int_t nv0s = event->GetNumberOfV0s();
4549 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
4551 for (Int_t iv0 = 0; iv0<nv0s;iv0++){
4552 AliV0 * v0mi = (AliV0*)event->GetV0(iv0);
4553 if (!v0mi) continue;
4554 Int_t itrack0 = v0mi->GetIndex(0);
4555 Int_t itrack1 = v0mi->GetIndex(1);
4556 AliESDtrack *esd0 = event->GetTrack(itrack0);
4557 AliESDtrack *esd1 = event->GetTrack(itrack1);
4558 if (!esd0||!esd1) continue;
4559 AliITStrackMI tpc0(*esd0);
4560 AliITStrackMI tpc1(*esd1);
4561 Double_t x,y,z; v0mi->GetXYZ(x,y,z); //I.B.
4562 Double_t alpha =TMath::ATan2(y,x); //I.B.
4563 if (v0mi->GetRr()>85){
4564 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4565 v0temp.SetParamN(tpc0);
4566 v0temp.SetParamP(tpc1);
4567 v0temp.Update(primvertex);
4568 if (kFALSE) cstream<<"Refit"<<
4570 "V0refit.="<<&v0temp<<
4574 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4575 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4576 v0mi->SetParamN(tpc0);
4577 v0mi->SetParamP(tpc1);
4578 v0mi->Update(primvertex);
4583 if (v0mi->GetRr()>35){
4584 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4585 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4586 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4587 v0temp.SetParamN(tpc0);
4588 v0temp.SetParamP(tpc1);
4589 v0temp.Update(primvertex);
4590 if (kFALSE) cstream<<"Refit"<<
4592 "V0refit.="<<&v0temp<<
4596 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4597 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4598 v0mi->SetParamN(tpc0);
4599 v0mi->SetParamP(tpc1);
4600 v0mi->Update(primvertex);
4605 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4606 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4607 // if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4608 if (RefitAt(v0mi->GetRr(),&tpc0, v0mi->GetClusters(0)) && RefitAt(v0mi->GetRr(),&tpc1, v0mi->GetClusters(1))){
4609 v0temp.SetParamN(tpc0);
4610 v0temp.SetParamP(tpc1);
4611 v0temp.Update(primvertex);
4612 if (kFALSE) cstream<<"Refit"<<
4614 "V0refit.="<<&v0temp<<
4618 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4619 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4620 v0mi->SetParamN(tpc0);
4621 v0mi->SetParamP(tpc1);
4622 v0mi->Update(primvertex);
4628 //------------------------------------------------------------------------
4629 void AliITStrackerMI::BuildMaterialLUT(TString material) {
4630 //--------------------------------------------------------------------
4631 // Fill a look-up table with mean material
4632 //--------------------------------------------------------------------
4636 Double_t point1[3],point2[3];
4637 Double_t phi,cosphi,sinphi,z;
4638 // 0-5 layers, 6 pipe, 7-8 shields
4639 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
4640 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
4642 Int_t ifirst=0,ilast=0;
4643 if(material.Contains("Pipe")) {
4645 } else if(material.Contains("Shields")) {
4647 } else if(material.Contains("Layers")) {
4650 Error("BuildMaterialLUT","Wrong layer name\n");
4653 for(Int_t imat=ifirst; imat<=ilast; imat++) {
4654 Double_t param[5]={0.,0.,0.,0.,0.};
4655 for (Int_t i=0; i<n; i++) {
4656 phi = 2.*TMath::Pi()*gRandom->Rndm();
4657 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
4658 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
4659 point1[0] = rmin[imat]*cosphi;
4660 point1[1] = rmin[imat]*sinphi;
4662 point2[0] = rmax[imat]*cosphi;
4663 point2[1] = rmax[imat]*sinphi;
4665 AliTracker::MeanMaterialBudget(point1,point2,mparam);
4666 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
4668 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
4670 fxOverX0Layer[imat] = param[1];
4671 fxTimesRhoLayer[imat] = param[0]*param[4];
4672 } else if(imat==6) {
4673 fxOverX0Pipe = param[1];
4674 fxTimesRhoPipe = param[0]*param[4];
4675 } else if(imat==7) {
4676 fxOverX0Shield[0] = param[1];
4677 fxTimesRhoShield[0] = param[0]*param[4];
4678 } else if(imat==8) {
4679 fxOverX0Shield[1] = param[1];
4680 fxTimesRhoShield[1] = param[0]*param[4];
4684 printf("%s\n",material.Data());
4685 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
4686 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
4687 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
4688 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
4689 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
4690 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
4691 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
4692 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
4693 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
4697 //------------------------------------------------------------------------
4698 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
4699 TString direction) {
4700 //-------------------------------------------------------------------
4701 // Propagate beyond beam pipe and correct for material
4702 // (material budget in different ways according to fUseTGeo value)
4703 // Add time if going outward (PropagateTo or PropagateToTGeo)
4704 //-------------------------------------------------------------------
4706 // Define budget mode:
4707 // 0: material from AliITSRecoParam (hard coded)
4708 // 1: material from TGeo in one step (on the fly)
4709 // 2: material from lut
4710 // 3: material from TGeo in one step (same for all hypotheses)
4723 if(fTrackingPhase.Contains("Clusters2Tracks"))
4724 { mode=3; } else { mode=1; }
4727 if(fTrackingPhase.Contains("Clusters2Tracks"))
4728 { mode=3; } else { mode=2; }
4734 if(fTrackingPhase.Contains("Default")) mode=0;
4736 Int_t index=fCurrentEsdTrack;
4738 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4739 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4741 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4743 Double_t xOverX0,x0,lengthTimesMeanDensity;
4747 xOverX0 = AliITSRecoParam::GetdPipe();
4748 x0 = AliITSRecoParam::GetX0Be();
4749 lengthTimesMeanDensity = xOverX0*x0;
4750 lengthTimesMeanDensity *= dir;
4751 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4754 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4757 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4758 xOverX0 = fxOverX0Pipe;
4759 lengthTimesMeanDensity = fxTimesRhoPipe;
4760 lengthTimesMeanDensity *= dir;
4761 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4764 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4765 if(fxOverX0PipeTrks[index]<0) {
4766 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4767 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4768 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4769 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4770 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4773 xOverX0 = fxOverX0PipeTrks[index];
4774 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4775 lengthTimesMeanDensity *= dir;
4776 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4782 //------------------------------------------------------------------------
4783 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4785 TString direction) {
4786 //-------------------------------------------------------------------
4787 // Propagate beyond SPD or SDD shield and correct for material
4788 // (material budget in different ways according to fUseTGeo value)
4789 // Add time if going outward (PropagateTo or PropagateToTGeo)
4790 //-------------------------------------------------------------------
4792 // Define budget mode:
4793 // 0: material from AliITSRecoParam (hard coded)
4794 // 1: material from TGeo in steps of X cm (on the fly)
4795 // X = AliITSRecoParam::GetStepSizeTGeo()
4796 // 2: material from lut
4797 // 3: material from TGeo in one step (same for all hypotheses)
4810 if(fTrackingPhase.Contains("Clusters2Tracks"))
4811 { mode=3; } else { mode=1; }
4814 if(fTrackingPhase.Contains("Clusters2Tracks"))
4815 { mode=3; } else { mode=2; }
4821 if(fTrackingPhase.Contains("Default")) mode=0;
4823 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4825 Int_t shieldindex=0;
4826 if (shield.Contains("SDD")) { // SDDouter
4827 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4829 } else if (shield.Contains("SPD")) { // SPDouter
4830 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4833 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4837 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4839 Int_t index=2*fCurrentEsdTrack+shieldindex;
4841 Double_t xOverX0,x0,lengthTimesMeanDensity;
4846 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4847 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4848 lengthTimesMeanDensity = xOverX0*x0;
4849 lengthTimesMeanDensity *= dir;
4850 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4853 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4854 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4857 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4858 xOverX0 = fxOverX0Shield[shieldindex];
4859 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4860 lengthTimesMeanDensity *= dir;
4861 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4864 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4865 if(fxOverX0ShieldTrks[index]<0) {
4866 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4867 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4868 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4869 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4870 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4873 xOverX0 = fxOverX0ShieldTrks[index];
4874 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4875 lengthTimesMeanDensity *= dir;
4876 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4882 //------------------------------------------------------------------------
4883 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4885 Double_t oldGlobXYZ[3],
4886 TString direction) {
4887 //-------------------------------------------------------------------
4888 // Propagate beyond layer and correct for material
4889 // (material budget in different ways according to fUseTGeo value)
4890 // Add time if going outward (PropagateTo or PropagateToTGeo)
4891 //-------------------------------------------------------------------
4893 // Define budget mode:
4894 // 0: material from AliITSRecoParam (hard coded)
4895 // 1: material from TGeo in stepsof X cm (on the fly)
4896 // X = AliITSRecoParam::GetStepSizeTGeo()
4897 // 2: material from lut
4898 // 3: material from TGeo in one step (same for all hypotheses)
4911 if(fTrackingPhase.Contains("Clusters2Tracks"))
4912 { mode=3; } else { mode=1; }
4915 if(fTrackingPhase.Contains("Clusters2Tracks"))
4916 { mode=3; } else { mode=2; }
4922 if(fTrackingPhase.Contains("Default")) mode=0;
4924 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4926 Double_t r=fgLayers[layerindex].GetR();
4927 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4929 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4931 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4933 Int_t index=6*fCurrentEsdTrack+layerindex;
4936 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4939 // back before material (no correction)
4941 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4942 if (!t->GetLocalXat(rOld,xOld)) return 0;
4943 if (!t->Propagate(xOld)) return 0;
4947 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4948 lengthTimesMeanDensity = xOverX0*x0;
4949 lengthTimesMeanDensity *= dir;
4950 // Bring the track beyond the material
4951 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4954 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4955 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4958 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4959 xOverX0 = fxOverX0Layer[layerindex];
4960 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4961 lengthTimesMeanDensity *= dir;
4962 // Bring the track beyond the material
4963 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4966 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4967 if(fxOverX0LayerTrks[index]<0) {
4968 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4969 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4970 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4971 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4972 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4973 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4976 xOverX0 = fxOverX0LayerTrks[index];
4977 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4978 lengthTimesMeanDensity *= dir;
4979 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4986 //------------------------------------------------------------------------
4987 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4988 //-----------------------------------------------------------------
4989 // Initialize LUT for storing material for each prolonged track
4990 //-----------------------------------------------------------------
4991 fxOverX0PipeTrks = new Float_t[ntracks];
4992 fxTimesRhoPipeTrks = new Float_t[ntracks];
4993 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4994 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4995 fxOverX0LayerTrks = new Float_t[ntracks*6];
4996 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4998 for(Int_t i=0; i<ntracks; i++) {
4999 fxOverX0PipeTrks[i] = -1.;
5000 fxTimesRhoPipeTrks[i] = -1.;
5002 for(Int_t j=0; j<ntracks*2; j++) {
5003 fxOverX0ShieldTrks[j] = -1.;
5004 fxTimesRhoShieldTrks[j] = -1.;
5006 for(Int_t k=0; k<ntracks*6; k++) {
5007 fxOverX0LayerTrks[k] = -1.;
5008 fxTimesRhoLayerTrks[k] = -1.;
5015 //------------------------------------------------------------------------
5016 void AliITStrackerMI::DeleteTrksMaterialLUT() {
5017 //-----------------------------------------------------------------
5018 // Delete LUT for storing material for each prolonged track
5019 //-----------------------------------------------------------------
5020 if(fxOverX0PipeTrks) {
5021 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
5023 if(fxOverX0ShieldTrks) {
5024 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
5027 if(fxOverX0LayerTrks) {
5028 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
5030 if(fxTimesRhoPipeTrks) {
5031 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
5033 if(fxTimesRhoShieldTrks) {
5034 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
5036 if(fxTimesRhoLayerTrks) {
5037 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
5041 //------------------------------------------------------------------------
5042 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
5043 Int_t ilayer,Int_t idet) const {
5044 //-----------------------------------------------------------------
5045 // This method is used to decide whether to allow a prolongation
5046 // without clusters, because we want to skip the layer.
5047 // In this case the return value is > 0:
5048 // return 1: the user requested to skip a layer
5049 // return 2: track outside z acceptance of SSD/SDD and will cross both SPD
5050 //-----------------------------------------------------------------
5052 if (AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) return 1;
5054 if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
5055 // check if track will cross SPD outer layer
5056 Double_t phiAtSPD2,zAtSPD2;
5057 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
5058 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
5064 //------------------------------------------------------------------------
5065 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
5066 Int_t ilayer,Int_t idet,
5067 Double_t dz,Double_t dy,
5068 Bool_t noClusters) const {
5069 //-----------------------------------------------------------------
5070 // This method is used to decide whether to allow a prolongation
5071 // without clusters, because there is a dead zone in the road.
5072 // In this case the return value is > 0:
5073 // return 1: dead zone at z=0,+-7cm in SPD
5074 // return 2: all road is "bad" (dead or noisy) from the OCDB
5075 // return 3: something "bad" (dead or noisy) from the OCDB
5076 //-----------------------------------------------------------------
5078 // check dead zones at z=0,+-7cm in the SPD
5079 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
5080 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
5081 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
5082 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
5083 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
5084 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
5085 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
5086 for (Int_t i=0; i<3; i++)
5087 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
5088 AliDebug(2,Form("crack SPD %d",ilayer));
5093 // check bad zones from OCDB
5094 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
5096 if (idet<0) return 0;
5098 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
5101 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
5102 if (ilayer==0 || ilayer==1) { // ---------- SPD
5104 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
5106 detSizeFactorX *= 2.;
5107 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
5110 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
5111 if (detType==2) segm->SetLayer(ilayer+1);
5112 Float_t detSizeX = detSizeFactorX*segm->Dx();
5113 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
5115 // check if the road overlaps with bad chips
5117 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
5118 Float_t zlocmin = zloc-dz;
5119 Float_t zlocmax = zloc+dz;
5120 Float_t xlocmin = xloc-dy;
5121 Float_t xlocmax = xloc+dy;
5122 Int_t chipsInRoad[100];
5124 // check if road goes out of detector
5125 Bool_t touchNeighbourDet=kFALSE;
5126 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.5*detSizeX; touchNeighbourDet=kTRUE;}
5127 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.5*detSizeX; touchNeighbourDet=kTRUE;}
5128 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.5*detSizeZ; touchNeighbourDet=kTRUE;}
5129 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.5*detSizeZ; touchNeighbourDet=kTRUE;}
5130 AliDebug(2,Form("layer %d det %d zmim zmax %f %f xmin xmax %f %f %f %f",ilayer,idet,zlocmin,zlocmax,xlocmin,xlocmax,detSizeZ,detSizeX));
5132 // check if this detector is bad
5134 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
5135 if(!touchNeighbourDet) {
5136 return 2; // all detectors in road are bad
5138 return 3; // at least one is bad
5142 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
5143 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
5144 if (!nChipsInRoad) return 0;
5146 Bool_t anyBad=kFALSE,anyGood=kFALSE;
5147 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
5148 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
5149 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
5150 if (det.IsChipBad(chipsInRoad[iCh])) {
5158 if(!touchNeighbourDet) {
5159 AliDebug(2,"all bad in road");
5160 return 2; // all chips in road are bad
5162 return 3; // at least a bad chip in road
5167 AliDebug(2,"at least a bad in road");
5168 return 3; // at least a bad chip in road
5172 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
5173 || ilayer==4 || ilayer==5 // SSD
5174 || !noClusters) return 0;
5176 // There are no clusters in road: check if there is at least
5177 // a bad SPD pixel or SDD anode
5179 Int_t idetInITS=idet;
5180 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
5182 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
5183 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
5186 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
5190 //------------------------------------------------------------------------
5191 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
5192 const AliITStrackMI *track,
5193 Float_t &xloc,Float_t &zloc) const {
5194 //-----------------------------------------------------------------
5195 // Gives position of track in local module ref. frame
5196 //-----------------------------------------------------------------
5201 if(idet<0) return kFALSE;
5203 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
5205 Int_t lad = Int_t(idet/ndet) + 1;
5207 Int_t det = idet - (lad-1)*ndet + 1;
5209 Double_t xyzGlob[3],xyzLoc[3];
5211 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
5212 // take into account the misalignment: xyz at real detector plane
5213 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
5215 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
5217 xloc = (Float_t)xyzLoc[0];
5218 zloc = (Float_t)xyzLoc[2];
5222 //------------------------------------------------------------------------
5223 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
5225 // Method to be optimized further:
5226 // Aim: decide whether a track can be used for PlaneEff evaluation
5227 // the decision is taken based on the track quality at the layer under study
5228 // no information on the clusters on this layer has to be used
5229 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
5230 // the cut is done on number of sigmas from the boundaries
5232 // Input: Actual track, layer [0,5] under study
5234 // Return: kTRUE if this is a good track
5236 // it will apply a pre-selection to obtain good quality tracks.
5237 // Here also you will have the possibility to put a control on the
5238 // impact point of the track on the basic block, in order to exclude border regions
5239 // this will be done by calling a proper method of the AliITSPlaneEff class.
5241 // input: AliITStrackMI* track, ilayer= layer number [0,5]
5242 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
5244 Int_t index[AliITSgeomTGeo::kNLayers];
5246 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
5248 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
5249 index[k]=clusters[k];
5253 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
5254 AliITSlayer &layer=fgLayers[ilayer];
5255 Double_t r=layer.GetR();
5256 AliITStrackMI tmp(*track);
5258 // require a minimal number of cluster in other layers and eventually clusters in closest layers
5260 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) {
5261 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
5262 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
5263 if (tmp.GetClIndex(lay)>=0) ncl++;
5265 Bool_t nextout = kFALSE;
5266 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
5267 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
5268 Bool_t nextin = kFALSE;
5269 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
5270 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
5271 if(ncl<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
5273 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
5274 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
5275 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
5276 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
5280 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
5281 Int_t idet=layer.FindDetectorIndex(phi,z);
5282 if(idet<0) { AliInfo(Form("cannot find detector"));
5285 // here check if it has good Chi Square.
5287 //propagate to the intersection with the detector plane
5288 const AliITSdetector &det=layer.GetDetector(idet);
5289 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
5293 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
5294 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5295 if(key>fPlaneEff->Nblock()) return kFALSE;
5296 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
5297 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
5299 // DEFINITION OF SEARCH ROAD FOR accepting a track
5301 //For the time being they are hard-wired, later on from AliITSRecoParam
5302 // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
5303 // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
5306 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
5307 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
5308 // done for RecPoints
5310 // exclude tracks at boundary between detectors
5311 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
5312 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
5313 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
5314 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
5315 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
5317 if ( (locx-dx < blockXmn+boundaryWidth) ||
5318 (locx+dx > blockXmx-boundaryWidth) ||
5319 (locz-dz < blockZmn+boundaryWidth) ||
5320 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
5323 //------------------------------------------------------------------------
5324 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
5326 // This Method has to be optimized! For the time-being it uses the same criteria
5327 // as those used in the search of extra clusters for overlapping modules.
5329 // Method Purpose: estabilish whether a track has produced a recpoint or not
5330 // in the layer under study (For Plane efficiency)
5332 // inputs: AliITStrackMI* track (pointer to a usable track)
5334 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
5335 // traversed by this very track. In details:
5336 // - if a cluster can be associated to the track then call
5337 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
5338 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
5341 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
5342 AliITSlayer &layer=fgLayers[ilayer];
5343 Double_t r=layer.GetR();
5344 AliITStrackMI tmp(*track);
5348 if (!tmp.GetPhiZat(r,phi,z)) return;
5349 Int_t idet=layer.FindDetectorIndex(phi,z);
5351 if(idet<0) { AliInfo(Form("cannot find detector"));
5355 //propagate to the intersection with the detector plane
5356 const AliITSdetector &det=layer.GetDetector(idet);
5357 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
5361 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
5363 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
5364 TMath::Sqrt(tmp.GetSigmaZ2() +
5365 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5366 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5367 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
5368 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
5369 TMath::Sqrt(tmp.GetSigmaY2() +
5370 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5371 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5372 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
5374 // road in global (rphi,z) [i.e. in tracking ref. system]
5375 Double_t zmin = tmp.GetZ() - dz;
5376 Double_t zmax = tmp.GetZ() + dz;
5377 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
5378 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
5380 // select clusters in road
5381 layer.SelectClusters(zmin,zmax,ymin,ymax);
5383 // Define criteria for track-cluster association
5384 Double_t msz = tmp.GetSigmaZ2() +
5385 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5386 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5387 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
5388 Double_t msy = tmp.GetSigmaY2() +
5389 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5390 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5391 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
5392 if (tmp.GetConstrain()) {
5393 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
5394 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
5396 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
5397 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
5399 msz = 1./msz; // 1/RoadZ^2
5400 msy = 1./msy; // 1/RoadY^2
5403 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
5405 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
5406 //Double_t tolerance=0.2;
5407 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
5408 idetc = cl->GetDetectorIndex();
5409 if(idet!=idetc) continue;
5410 //Int_t ilay = cl->GetLayer();
5412 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
5413 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
5415 Double_t chi2=tmp.GetPredictedChi2(cl);
5416 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
5420 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
5422 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
5423 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5424 if(key>fPlaneEff->Nblock()) return;
5425 Bool_t found=kFALSE;
5428 while ((cl=layer.GetNextCluster(clidx))!=0) {
5429 idetc = cl->GetDetectorIndex();
5430 if(idet!=idetc) continue;
5431 // here real control to see whether the cluster can be associated to the track.
5432 // cluster not associated to track
5433 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
5434 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
5435 // calculate track-clusters chi2
5436 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
5437 // in particular, the error associated to the cluster
5438 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
5440 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
5442 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
5443 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
5444 // track->SetExtraModule(ilayer,idetExtra);
5446 if(!fPlaneEff->UpDatePlaneEff(found,key))
5447 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
5448 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
5449 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
5450 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
5451 Int_t cltype[2]={-999,-999};
5455 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
5456 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
5459 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
5460 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
5461 cltype[0]=layer.GetCluster(ci)->GetNy();
5462 cltype[1]=layer.GetCluster(ci)->GetNz();
5464 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
5465 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
5466 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
5467 // It is computed properly by calling the method
5468 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
5470 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
5471 //if (tmp.PropagateTo(x,0.,0.)) {
5472 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
5473 AliCluster c(*layer.GetCluster(ci));
5474 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
5475 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
5476 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
5477 clu[2]=TMath::Sqrt(c.GetSigmaY2());
5478 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
5481 fPlaneEff->FillHistos(key,found,tr,clu,cltype);