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)==1)
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) AliITSV0Finder::UpdateTPCV0(event,this);
608 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
613 Int_t entries = fTrackHypothesys.GetEntriesFast();
614 for (Int_t ientry=0; ientry<entries; ientry++) {
615 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
616 if (array) array->Delete();
617 delete fTrackHypothesys.RemoveAt(ientry);
620 fTrackHypothesys.Delete();
621 fBestHypothesys.Delete();
623 delete [] fCoefficients;
625 DeleteTrksMaterialLUT();
627 Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
629 fTrackingPhase="Default";
633 //------------------------------------------------------------------------
634 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
635 //--------------------------------------------------------------------
636 // This functions propagates reconstructed ITS tracks back
637 // The clusters must be loaded !
638 //--------------------------------------------------------------------
639 fTrackingPhase="PropagateBack";
640 Int_t nentr=event->GetNumberOfTracks();
641 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
644 for (Int_t i=0; i<nentr; i++) {
645 AliESDtrack *esd=event->GetTrack(i);
647 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
648 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
652 t=new AliITStrackMI(*esd);
653 } catch (const Char_t *msg) {
654 //Warning("PropagateBack",msg);
658 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
660 ResetTrackToFollow(*t);
662 // propagate to vertex [SR, GSI 17.02.2003]
663 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
664 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
665 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
666 fTrackToFollow.StartTimeIntegral();
667 // from vertex to outside pipe
668 CorrectForPipeMaterial(&fTrackToFollow,"outward");
671 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
672 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
673 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
677 fTrackToFollow.SetLabel(t->GetLabel());
678 //fTrackToFollow.CookdEdx();
679 CookLabel(&fTrackToFollow,0.); //For comparison only
680 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
681 //UseClusters(&fTrackToFollow);
687 Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
689 fTrackingPhase="Default";
693 //------------------------------------------------------------------------
694 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
695 //--------------------------------------------------------------------
696 // This functions refits ITS tracks using the
697 // "inward propagated" TPC tracks
698 // The clusters must be loaded !
699 //--------------------------------------------------------------------
700 fTrackingPhase="RefitInward";
702 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
704 Int_t nentr=event->GetNumberOfTracks();
705 Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
708 for (Int_t i=0; i<nentr; i++) {
709 AliESDtrack *esd=event->GetTrack(i);
711 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
712 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
713 if (esd->GetStatus()&AliESDtrack::kTPCout)
714 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
718 t=new AliITStrackMI(*esd);
719 } catch (const Char_t *msg) {
720 //Warning("RefitInward",msg);
724 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
725 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
730 ResetTrackToFollow(*t);
731 fTrackToFollow.ResetClusters();
733 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
734 fTrackToFollow.ResetCovariance(10.);
737 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
738 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
740 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
741 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
742 AliDebug(2," refit OK");
743 fTrackToFollow.SetLabel(t->GetLabel());
744 // fTrackToFollow.CookdEdx();
745 CookdEdx(&fTrackToFollow);
747 CookLabel(&fTrackToFollow,0.0); //For comparison only
750 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
751 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
752 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
753 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
754 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
755 Double_t r[3]={0.,0.,0.};
757 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
764 Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
766 fTrackingPhase="Default";
770 //------------------------------------------------------------------------
771 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
772 //--------------------------------------------------------------------
773 // Return pointer to a given cluster
774 //--------------------------------------------------------------------
775 Int_t l=(index & 0xf0000000) >> 28;
776 Int_t c=(index & 0x0fffffff) >> 00;
777 return fgLayers[l].GetCluster(c);
779 //------------------------------------------------------------------------
780 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
781 //--------------------------------------------------------------------
782 // Get track space point with index i
783 //--------------------------------------------------------------------
785 Int_t l=(index & 0xf0000000) >> 28;
786 Int_t c=(index & 0x0fffffff) >> 00;
787 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
788 Int_t idet = cl->GetDetectorIndex();
792 cl->GetGlobalXYZ(xyz);
793 cl->GetGlobalCov(cov);
795 p.SetCharge(cl->GetQ());
796 p.SetDriftTime(cl->GetDriftTime());
797 p.SetChargeRatio(cl->GetChargeRatio());
798 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
801 iLayer = AliGeomManager::kSPD1;
804 iLayer = AliGeomManager::kSPD2;
807 iLayer = AliGeomManager::kSDD1;
810 iLayer = AliGeomManager::kSDD2;
813 iLayer = AliGeomManager::kSSD1;
816 iLayer = AliGeomManager::kSSD2;
819 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
822 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
823 p.SetVolumeID((UShort_t)volid);
826 //------------------------------------------------------------------------
827 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
828 AliTrackPoint& p, const AliESDtrack *t) {
829 //--------------------------------------------------------------------
830 // Get track space point with index i
831 // (assign error estimated during the tracking)
832 //--------------------------------------------------------------------
834 Int_t l=(index & 0xf0000000) >> 28;
835 Int_t c=(index & 0x0fffffff) >> 00;
836 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
837 Int_t idet = cl->GetDetectorIndex();
839 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
841 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
843 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
844 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
845 Double_t alpha = t->GetAlpha();
846 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
847 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,GetBz()));
848 phi += alpha-det.GetPhi();
849 Float_t tgphi = TMath::Tan(phi);
851 Float_t tgl = t->GetTgl(); // tgl about const along track
852 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
854 Float_t errlocalx,errlocalz;
855 Bool_t addMisalErr=kFALSE;
856 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errlocalx,errlocalz,addMisalErr);
860 cl->GetGlobalXYZ(xyz);
861 // cl->GetGlobalCov(cov);
862 Float_t pos[3] = {0.,0.,0.};
863 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errlocalx*errlocalx,errlocalz*errlocalz,0);
864 tmpcl.GetGlobalCov(cov);
867 p.SetCharge(cl->GetQ());
868 p.SetDriftTime(cl->GetDriftTime());
869 p.SetChargeRatio(cl->GetChargeRatio());
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(),ilayer-2);
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(),ilayer-2);
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)
3558 track->SetChi2MIP(9,0);
3559 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3560 Int_t cindex = track->GetClusterIndex(i);
3561 Int_t l=(cindex & 0xf0000000) >> 28;
3562 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3563 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3565 for (Int_t ind=0;ind<3;ind++){
3566 if (cl->GetLabel(ind)==lab) isWrong=0;
3568 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3572 track->CookdEdx(low,up);
3574 //------------------------------------------------------------------------
3575 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3577 // Create some arrays
3579 if (fCoefficients) delete []fCoefficients;
3580 fCoefficients = new Float_t[ntracks*48];
3581 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3583 //------------------------------------------------------------------------
3584 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3587 // Compute predicted chi2
3590 Float_t theta = track->GetTgl();
3591 Float_t phi = track->GetSnp();
3592 phi = TMath::Abs(phi)*TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3593 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz);
3594 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()));
3595 // Take into account the mis-alignment (bring track to cluster plane)
3596 Double_t xTrOrig=track->GetX();
3597 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3598 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()));
3599 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz);
3600 // Bring the track back to detector plane in ideal geometry
3601 // [mis-alignment will be accounted for in UpdateMI()]
3602 if (!track->Propagate(xTrOrig)) return 1000.;
3604 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3605 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3607 chi2+=0.5*TMath::Min(delta/2,2.);
3608 chi2+=2.*cluster->GetDeltaProbability();
3611 track->SetNy(layer,ny);
3612 track->SetNz(layer,nz);
3613 track->SetSigmaY(layer,erry);
3614 track->SetSigmaZ(layer, errz);
3615 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3616 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3620 //------------------------------------------------------------------------
3621 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3626 Int_t layer = (index & 0xf0000000) >> 28;
3627 track->SetClIndex(layer, index);
3628 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3629 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3630 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3631 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3635 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3638 // Take into account the mis-alignment (bring track to cluster plane)
3639 Double_t xTrOrig=track->GetX();
3640 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3641 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3642 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3643 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3645 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3649 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3650 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3653 Int_t updated = track->UpdateMI(&c,chi2,index);
3655 // Bring the track back to detector plane in ideal geometry
3656 if (!track->Propagate(xTrOrig)) return 0;
3658 if(!updated) AliDebug(2,"update failed");
3662 //------------------------------------------------------------------------
3663 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3666 //DCA sigmas parameterization
3667 //to be paramterized using external parameters in future
3670 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3671 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3673 //------------------------------------------------------------------------
3674 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3677 // Clusters from delta electrons?
3679 Int_t entries = clusterArray->GetEntriesFast();
3680 if (entries<4) return;
3681 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3682 Int_t layer = cluster->GetLayer();
3683 if (layer>1) return;
3685 Int_t ncandidates=0;
3686 Float_t r = (layer>0)? 7:4;
3688 for (Int_t i=0;i<entries;i++){
3689 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3690 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3691 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3692 index[ncandidates] = i; //candidate to belong to delta electron track
3694 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3695 cl0->SetDeltaProbability(1);
3701 for (Int_t i=0;i<ncandidates;i++){
3702 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3703 if (cl0->GetDeltaProbability()>0.8) continue;
3706 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3707 sumy=sumz=sumy2=sumyz=sumw=0.0;
3708 for (Int_t j=0;j<ncandidates;j++){
3710 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3712 Float_t dz = cl0->GetZ()-cl1->GetZ();
3713 Float_t dy = cl0->GetY()-cl1->GetY();
3714 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3715 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3716 y[ncl] = cl1->GetY();
3717 z[ncl] = cl1->GetZ();
3718 sumy+= y[ncl]*weight;
3719 sumz+= z[ncl]*weight;
3720 sumy2+=y[ncl]*y[ncl]*weight;
3721 sumyz+=y[ncl]*z[ncl]*weight;
3726 if (ncl<4) continue;
3727 Float_t det = sumw*sumy2 - sumy*sumy;
3729 if (TMath::Abs(det)>0.01){
3730 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3731 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3732 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3735 Float_t z0 = sumyz/sumy;
3736 delta = TMath::Abs(cl0->GetZ()-z0);
3739 cl0->SetDeltaProbability(1-20.*delta);
3743 //------------------------------------------------------------------------
3744 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3749 track->UpdateESDtrack(flags);
3750 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3751 if (oldtrack) delete oldtrack;
3752 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3753 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3754 printf("Problem\n");
3757 //------------------------------------------------------------------------
3758 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3760 // Get nearest upper layer close to the point xr.
3761 // rough approximation
3763 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3764 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3766 for (Int_t i=0;i<6;i++){
3767 if (radius<kRadiuses[i]){
3774 //------------------------------------------------------------------------
3775 void AliITStrackerMI::BuildMaterialLUT(TString material) {
3776 //--------------------------------------------------------------------
3777 // Fill a look-up table with mean material
3778 //--------------------------------------------------------------------
3782 Double_t point1[3],point2[3];
3783 Double_t phi,cosphi,sinphi,z;
3784 // 0-5 layers, 6 pipe, 7-8 shields
3785 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
3786 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
3788 Int_t ifirst=0,ilast=0;
3789 if(material.Contains("Pipe")) {
3791 } else if(material.Contains("Shields")) {
3793 } else if(material.Contains("Layers")) {
3796 Error("BuildMaterialLUT","Wrong layer name\n");
3799 for(Int_t imat=ifirst; imat<=ilast; imat++) {
3800 Double_t param[5]={0.,0.,0.,0.,0.};
3801 for (Int_t i=0; i<n; i++) {
3802 phi = 2.*TMath::Pi()*gRandom->Rndm();
3803 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
3804 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
3805 point1[0] = rmin[imat]*cosphi;
3806 point1[1] = rmin[imat]*sinphi;
3808 point2[0] = rmax[imat]*cosphi;
3809 point2[1] = rmax[imat]*sinphi;
3811 AliTracker::MeanMaterialBudget(point1,point2,mparam);
3812 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
3814 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
3816 fxOverX0Layer[imat] = param[1];
3817 fxTimesRhoLayer[imat] = param[0]*param[4];
3818 } else if(imat==6) {
3819 fxOverX0Pipe = param[1];
3820 fxTimesRhoPipe = param[0]*param[4];
3821 } else if(imat==7) {
3822 fxOverX0Shield[0] = param[1];
3823 fxTimesRhoShield[0] = param[0]*param[4];
3824 } else if(imat==8) {
3825 fxOverX0Shield[1] = param[1];
3826 fxTimesRhoShield[1] = param[0]*param[4];
3830 printf("%s\n",material.Data());
3831 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
3832 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
3833 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
3834 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
3835 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
3836 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
3837 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
3838 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
3839 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
3843 //------------------------------------------------------------------------
3844 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
3845 TString direction) {
3846 //-------------------------------------------------------------------
3847 // Propagate beyond beam pipe and correct for material
3848 // (material budget in different ways according to fUseTGeo value)
3849 // Add time if going outward (PropagateTo or PropagateToTGeo)
3850 //-------------------------------------------------------------------
3852 // Define budget mode:
3853 // 0: material from AliITSRecoParam (hard coded)
3854 // 1: material from TGeo in one step (on the fly)
3855 // 2: material from lut
3856 // 3: material from TGeo in one step (same for all hypotheses)
3869 if(fTrackingPhase.Contains("Clusters2Tracks"))
3870 { mode=3; } else { mode=1; }
3873 if(fTrackingPhase.Contains("Clusters2Tracks"))
3874 { mode=3; } else { mode=2; }
3880 if(fTrackingPhase.Contains("Default")) mode=0;
3882 Int_t index=fCurrentEsdTrack;
3884 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
3885 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
3887 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
3889 Double_t xOverX0,x0,lengthTimesMeanDensity;
3893 xOverX0 = AliITSRecoParam::GetdPipe();
3894 x0 = AliITSRecoParam::GetX0Be();
3895 lengthTimesMeanDensity = xOverX0*x0;
3896 lengthTimesMeanDensity *= dir;
3897 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3900 if (!t->PropagateToTGeo(xToGo,1)) return 0;
3903 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
3904 xOverX0 = fxOverX0Pipe;
3905 lengthTimesMeanDensity = fxTimesRhoPipe;
3906 lengthTimesMeanDensity *= dir;
3907 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3910 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
3911 if(fxOverX0PipeTrks[index]<0) {
3912 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
3913 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
3914 ((1.-t->GetSnp())*(1.+t->GetSnp())));
3915 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
3916 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
3919 xOverX0 = fxOverX0PipeTrks[index];
3920 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
3921 lengthTimesMeanDensity *= dir;
3922 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3928 //------------------------------------------------------------------------
3929 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
3931 TString direction) {
3932 //-------------------------------------------------------------------
3933 // Propagate beyond SPD or SDD shield and correct for material
3934 // (material budget in different ways according to fUseTGeo value)
3935 // Add time if going outward (PropagateTo or PropagateToTGeo)
3936 //-------------------------------------------------------------------
3938 // Define budget mode:
3939 // 0: material from AliITSRecoParam (hard coded)
3940 // 1: material from TGeo in steps of X cm (on the fly)
3941 // X = AliITSRecoParam::GetStepSizeTGeo()
3942 // 2: material from lut
3943 // 3: material from TGeo in one step (same for all hypotheses)
3956 if(fTrackingPhase.Contains("Clusters2Tracks"))
3957 { mode=3; } else { mode=1; }
3960 if(fTrackingPhase.Contains("Clusters2Tracks"))
3961 { mode=3; } else { mode=2; }
3967 if(fTrackingPhase.Contains("Default")) mode=0;
3969 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
3971 Int_t shieldindex=0;
3972 if (shield.Contains("SDD")) { // SDDouter
3973 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
3975 } else if (shield.Contains("SPD")) { // SPDouter
3976 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
3979 Error("CorrectForShieldMaterial"," Wrong shield name\n");
3983 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
3985 Int_t index=2*fCurrentEsdTrack+shieldindex;
3987 Double_t xOverX0,x0,lengthTimesMeanDensity;
3992 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
3993 x0 = AliITSRecoParam::GetX0shield(shieldindex);
3994 lengthTimesMeanDensity = xOverX0*x0;
3995 lengthTimesMeanDensity *= dir;
3996 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3999 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4000 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4003 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4004 xOverX0 = fxOverX0Shield[shieldindex];
4005 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4006 lengthTimesMeanDensity *= dir;
4007 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4010 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4011 if(fxOverX0ShieldTrks[index]<0) {
4012 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4013 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4014 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4015 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4016 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4019 xOverX0 = fxOverX0ShieldTrks[index];
4020 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4021 lengthTimesMeanDensity *= dir;
4022 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4028 //------------------------------------------------------------------------
4029 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4031 Double_t oldGlobXYZ[3],
4032 TString direction) {
4033 //-------------------------------------------------------------------
4034 // Propagate beyond layer and correct for material
4035 // (material budget in different ways according to fUseTGeo value)
4036 // Add time if going outward (PropagateTo or PropagateToTGeo)
4037 //-------------------------------------------------------------------
4039 // Define budget mode:
4040 // 0: material from AliITSRecoParam (hard coded)
4041 // 1: material from TGeo in stepsof X cm (on the fly)
4042 // X = AliITSRecoParam::GetStepSizeTGeo()
4043 // 2: material from lut
4044 // 3: material from TGeo in one step (same for all hypotheses)
4057 if(fTrackingPhase.Contains("Clusters2Tracks"))
4058 { mode=3; } else { mode=1; }
4061 if(fTrackingPhase.Contains("Clusters2Tracks"))
4062 { mode=3; } else { mode=2; }
4068 if(fTrackingPhase.Contains("Default")) mode=0;
4070 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4072 Double_t r=fgLayers[layerindex].GetR();
4073 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4075 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4077 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4079 Int_t index=6*fCurrentEsdTrack+layerindex;
4082 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4085 // back before material (no correction)
4087 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4088 if (!t->GetLocalXat(rOld,xOld)) return 0;
4089 if (!t->Propagate(xOld)) return 0;
4093 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4094 lengthTimesMeanDensity = xOverX0*x0;
4095 lengthTimesMeanDensity *= dir;
4096 // Bring the track beyond the material
4097 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4100 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4101 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4104 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4105 xOverX0 = fxOverX0Layer[layerindex];
4106 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4107 lengthTimesMeanDensity *= dir;
4108 // Bring the track beyond the material
4109 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4112 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4113 if(fxOverX0LayerTrks[index]<0) {
4114 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4115 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4116 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4117 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4118 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4119 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4122 xOverX0 = fxOverX0LayerTrks[index];
4123 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4124 lengthTimesMeanDensity *= dir;
4125 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4132 //------------------------------------------------------------------------
4133 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4134 //-----------------------------------------------------------------
4135 // Initialize LUT for storing material for each prolonged track
4136 //-----------------------------------------------------------------
4137 fxOverX0PipeTrks = new Float_t[ntracks];
4138 fxTimesRhoPipeTrks = new Float_t[ntracks];
4139 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4140 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4141 fxOverX0LayerTrks = new Float_t[ntracks*6];
4142 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4144 for(Int_t i=0; i<ntracks; i++) {
4145 fxOverX0PipeTrks[i] = -1.;
4146 fxTimesRhoPipeTrks[i] = -1.;
4148 for(Int_t j=0; j<ntracks*2; j++) {
4149 fxOverX0ShieldTrks[j] = -1.;
4150 fxTimesRhoShieldTrks[j] = -1.;
4152 for(Int_t k=0; k<ntracks*6; k++) {
4153 fxOverX0LayerTrks[k] = -1.;
4154 fxTimesRhoLayerTrks[k] = -1.;
4161 //------------------------------------------------------------------------
4162 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4163 //-----------------------------------------------------------------
4164 // Delete LUT for storing material for each prolonged track
4165 //-----------------------------------------------------------------
4166 if(fxOverX0PipeTrks) {
4167 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4169 if(fxOverX0ShieldTrks) {
4170 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4173 if(fxOverX0LayerTrks) {
4174 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4176 if(fxTimesRhoPipeTrks) {
4177 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4179 if(fxTimesRhoShieldTrks) {
4180 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4182 if(fxTimesRhoLayerTrks) {
4183 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4187 //------------------------------------------------------------------------
4188 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4189 Int_t ilayer,Int_t idet) const {
4190 //-----------------------------------------------------------------
4191 // This method is used to decide whether to allow a prolongation
4192 // without clusters, because we want to skip the layer.
4193 // In this case the return value is > 0:
4194 // return 1: the user requested to skip a layer
4195 // return 2: track outside z acceptance of SSD/SDD and will cross both SPD
4196 //-----------------------------------------------------------------
4198 if (AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) return 1;
4200 if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4201 // check if track will cross SPD outer layer
4202 Double_t phiAtSPD2,zAtSPD2;
4203 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4204 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4210 //------------------------------------------------------------------------
4211 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4212 Int_t ilayer,Int_t idet,
4213 Double_t dz,Double_t dy,
4214 Bool_t noClusters) const {
4215 //-----------------------------------------------------------------
4216 // This method is used to decide whether to allow a prolongation
4217 // without clusters, because there is a dead zone in the road.
4218 // In this case the return value is > 0:
4219 // return 1: dead zone at z=0,+-7cm in SPD
4220 // return 2: all road is "bad" (dead or noisy) from the OCDB
4221 // return 3: something "bad" (dead or noisy) from the OCDB
4222 //-----------------------------------------------------------------
4224 // check dead zones at z=0,+-7cm in the SPD
4225 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4226 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4227 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4228 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4229 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4230 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4231 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4232 for (Int_t i=0; i<3; i++)
4233 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4234 AliDebug(2,Form("crack SPD %d",ilayer));
4239 // check bad zones from OCDB
4240 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4242 if (idet<0) return 0;
4244 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4247 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4248 if (ilayer==0 || ilayer==1) { // ---------- SPD
4250 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4252 detSizeFactorX *= 2.;
4253 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4256 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4257 if (detType==2) segm->SetLayer(ilayer+1);
4258 Float_t detSizeX = detSizeFactorX*segm->Dx();
4259 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4261 // check if the road overlaps with bad chips
4263 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
4264 Float_t zlocmin = zloc-dz;
4265 Float_t zlocmax = zloc+dz;
4266 Float_t xlocmin = xloc-dy;
4267 Float_t xlocmax = xloc+dy;
4268 Int_t chipsInRoad[100];
4270 // check if road goes out of detector
4271 Bool_t touchNeighbourDet=kFALSE;
4272 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.5*detSizeX; touchNeighbourDet=kTRUE;}
4273 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.5*detSizeX; touchNeighbourDet=kTRUE;}
4274 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.5*detSizeZ; touchNeighbourDet=kTRUE;}
4275 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.5*detSizeZ; touchNeighbourDet=kTRUE;}
4276 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));
4278 // check if this detector is bad
4280 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4281 if(!touchNeighbourDet) {
4282 return 2; // all detectors in road are bad
4284 return 3; // at least one is bad
4288 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4289 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4290 if (!nChipsInRoad) return 0;
4292 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4293 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4294 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4295 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4296 if (det.IsChipBad(chipsInRoad[iCh])) {
4304 if(!touchNeighbourDet) {
4305 AliDebug(2,"all bad in road");
4306 return 2; // all chips in road are bad
4308 return 3; // at least a bad chip in road
4313 AliDebug(2,"at least a bad in road");
4314 return 3; // at least a bad chip in road
4318 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4319 || ilayer==4 || ilayer==5 // SSD
4320 || !noClusters) return 0;
4322 // There are no clusters in road: check if there is at least
4323 // a bad SPD pixel or SDD anode
4325 Int_t idetInITS=idet;
4326 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4328 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4329 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4332 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4336 //------------------------------------------------------------------------
4337 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4338 const AliITStrackMI *track,
4339 Float_t &xloc,Float_t &zloc) const {
4340 //-----------------------------------------------------------------
4341 // Gives position of track in local module ref. frame
4342 //-----------------------------------------------------------------
4347 if(idet<0) return kFALSE;
4349 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4351 Int_t lad = Int_t(idet/ndet) + 1;
4353 Int_t det = idet - (lad-1)*ndet + 1;
4355 Double_t xyzGlob[3],xyzLoc[3];
4357 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4358 // take into account the misalignment: xyz at real detector plane
4359 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4361 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4363 xloc = (Float_t)xyzLoc[0];
4364 zloc = (Float_t)xyzLoc[2];
4368 //------------------------------------------------------------------------
4369 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
4371 // Method to be optimized further:
4372 // Aim: decide whether a track can be used for PlaneEff evaluation
4373 // the decision is taken based on the track quality at the layer under study
4374 // no information on the clusters on this layer has to be used
4375 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4376 // the cut is done on number of sigmas from the boundaries
4378 // Input: Actual track, layer [0,5] under study
4380 // Return: kTRUE if this is a good track
4382 // it will apply a pre-selection to obtain good quality tracks.
4383 // Here also you will have the possibility to put a control on the
4384 // impact point of the track on the basic block, in order to exclude border regions
4385 // this will be done by calling a proper method of the AliITSPlaneEff class.
4387 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4388 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4390 Int_t index[AliITSgeomTGeo::kNLayers];
4392 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4394 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4395 index[k]=clusters[k];
4399 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4400 AliITSlayer &layer=fgLayers[ilayer];
4401 Double_t r=layer.GetR();
4402 AliITStrackMI tmp(*track);
4404 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4406 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) {
4407 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4408 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4409 if (tmp.GetClIndex(lay)>=0) ncl++;
4411 Bool_t nextout = kFALSE;
4412 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4413 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4414 Bool_t nextin = kFALSE;
4415 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4416 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4417 if(ncl<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
4419 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
4420 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
4421 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
4422 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
4426 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4427 Int_t idet=layer.FindDetectorIndex(phi,z);
4428 if(idet<0) { AliInfo(Form("cannot find detector"));
4431 // here check if it has good Chi Square.
4433 //propagate to the intersection with the detector plane
4434 const AliITSdetector &det=layer.GetDetector(idet);
4435 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4439 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
4440 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4441 if(key>fPlaneEff->Nblock()) return kFALSE;
4442 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4443 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4445 // DEFINITION OF SEARCH ROAD FOR accepting a track
4447 //For the time being they are hard-wired, later on from AliITSRecoParam
4448 // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
4449 // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
4452 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4453 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4454 // done for RecPoints
4456 // exclude tracks at boundary between detectors
4457 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
4458 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4459 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
4460 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
4461 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
4463 if ( (locx-dx < blockXmn+boundaryWidth) ||
4464 (locx+dx > blockXmx-boundaryWidth) ||
4465 (locz-dz < blockZmn+boundaryWidth) ||
4466 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
4469 //------------------------------------------------------------------------
4470 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
4472 // This Method has to be optimized! For the time-being it uses the same criteria
4473 // as those used in the search of extra clusters for overlapping modules.
4475 // Method Purpose: estabilish whether a track has produced a recpoint or not
4476 // in the layer under study (For Plane efficiency)
4478 // inputs: AliITStrackMI* track (pointer to a usable track)
4480 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
4481 // traversed by this very track. In details:
4482 // - if a cluster can be associated to the track then call
4483 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
4484 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
4487 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
4488 AliITSlayer &layer=fgLayers[ilayer];
4489 Double_t r=layer.GetR();
4490 AliITStrackMI tmp(*track);
4494 if (!tmp.GetPhiZat(r,phi,z)) return;
4495 Int_t idet=layer.FindDetectorIndex(phi,z);
4497 if(idet<0) { AliInfo(Form("cannot find detector"));
4501 //propagate to the intersection with the detector plane
4502 const AliITSdetector &det=layer.GetDetector(idet);
4503 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
4507 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
4509 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
4510 TMath::Sqrt(tmp.GetSigmaZ2() +
4511 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4512 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4513 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
4514 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
4515 TMath::Sqrt(tmp.GetSigmaY2() +
4516 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4517 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4518 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
4520 // road in global (rphi,z) [i.e. in tracking ref. system]
4521 Double_t zmin = tmp.GetZ() - dz;
4522 Double_t zmax = tmp.GetZ() + dz;
4523 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
4524 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
4526 // select clusters in road
4527 layer.SelectClusters(zmin,zmax,ymin,ymax);
4529 // Define criteria for track-cluster association
4530 Double_t msz = tmp.GetSigmaZ2() +
4531 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4532 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4533 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
4534 Double_t msy = tmp.GetSigmaY2() +
4535 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4536 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4537 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
4538 if (tmp.GetConstrain()) {
4539 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
4540 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
4542 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
4543 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
4545 msz = 1./msz; // 1/RoadZ^2
4546 msy = 1./msy; // 1/RoadY^2
4549 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
4551 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
4552 //Double_t tolerance=0.2;
4553 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
4554 idetc = cl->GetDetectorIndex();
4555 if(idet!=idetc) continue;
4556 //Int_t ilay = cl->GetLayer();
4558 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
4559 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
4561 Double_t chi2=tmp.GetPredictedChi2(cl);
4562 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
4566 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
4568 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
4569 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4570 if(key>fPlaneEff->Nblock()) return;
4571 Bool_t found=kFALSE;
4574 while ((cl=layer.GetNextCluster(clidx))!=0) {
4575 idetc = cl->GetDetectorIndex();
4576 if(idet!=idetc) continue;
4577 // here real control to see whether the cluster can be associated to the track.
4578 // cluster not associated to track
4579 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
4580 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
4581 // calculate track-clusters chi2
4582 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
4583 // in particular, the error associated to the cluster
4584 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
4586 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
4588 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
4589 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
4590 // track->SetExtraModule(ilayer,idetExtra);
4592 if(!fPlaneEff->UpDatePlaneEff(found,key))
4593 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
4594 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
4595 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
4596 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
4597 Int_t cltype[2]={-999,-999};
4601 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4602 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4605 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
4606 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
4607 cltype[0]=layer.GetCluster(ci)->GetNy();
4608 cltype[1]=layer.GetCluster(ci)->GetNz();
4610 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
4611 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
4612 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
4613 // It is computed properly by calling the method
4614 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4616 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
4617 //if (tmp.PropagateTo(x,0.,0.)) {
4618 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
4619 AliCluster c(*layer.GetCluster(ci));
4620 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
4621 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
4622 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
4623 clu[2]=TMath::Sqrt(c.GetSigmaY2());
4624 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
4627 fPlaneEff->FillHistos(key,found,tr,clu,cltype);