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");
670 // Start time integral and add distance from current position to vertex
671 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
672 fTrackToFollow.GetXYZ(xyzTrk);
674 for (Int_t icoord=0; icoord<3; icoord++) {
675 Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
678 fTrackToFollow.StartTimeIntegral();
679 fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
681 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
682 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
683 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
687 fTrackToFollow.SetLabel(t->GetLabel());
688 //fTrackToFollow.CookdEdx();
689 CookLabel(&fTrackToFollow,0.); //For comparison only
690 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
691 //UseClusters(&fTrackToFollow);
697 Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
699 fTrackingPhase="Default";
703 //------------------------------------------------------------------------
704 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
705 //--------------------------------------------------------------------
706 // This functions refits ITS tracks using the
707 // "inward propagated" TPC tracks
708 // The clusters must be loaded !
709 //--------------------------------------------------------------------
710 fTrackingPhase="RefitInward";
712 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
714 Int_t nentr=event->GetNumberOfTracks();
715 Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
718 for (Int_t i=0; i<nentr; i++) {
719 AliESDtrack *esd=event->GetTrack(i);
721 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
722 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
723 if (esd->GetStatus()&AliESDtrack::kTPCout)
724 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
728 t=new AliITStrackMI(*esd);
729 } catch (const Char_t *msg) {
730 //Warning("RefitInward",msg);
734 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
735 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
740 ResetTrackToFollow(*t);
741 fTrackToFollow.ResetClusters();
743 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
744 fTrackToFollow.ResetCovariance(10.);
747 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
748 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
750 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
751 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
752 AliDebug(2," refit OK");
753 fTrackToFollow.SetLabel(t->GetLabel());
754 // fTrackToFollow.CookdEdx();
755 CookdEdx(&fTrackToFollow);
757 CookLabel(&fTrackToFollow,0.0); //For comparison only
760 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
761 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
762 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
763 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
764 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
765 Double_t r[3]={0.,0.,0.};
767 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
774 Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
776 fTrackingPhase="Default";
780 //------------------------------------------------------------------------
781 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
782 //--------------------------------------------------------------------
783 // Return pointer to a given cluster
784 //--------------------------------------------------------------------
785 Int_t l=(index & 0xf0000000) >> 28;
786 Int_t c=(index & 0x0fffffff) >> 00;
787 return fgLayers[l].GetCluster(c);
789 //------------------------------------------------------------------------
790 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
791 //--------------------------------------------------------------------
792 // Get track space point with index i
793 //--------------------------------------------------------------------
795 Int_t l=(index & 0xf0000000) >> 28;
796 Int_t c=(index & 0x0fffffff) >> 00;
797 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
798 Int_t idet = cl->GetDetectorIndex();
802 cl->GetGlobalXYZ(xyz);
803 cl->GetGlobalCov(cov);
805 p.SetCharge(cl->GetQ());
806 p.SetDriftTime(cl->GetDriftTime());
807 p.SetChargeRatio(cl->GetChargeRatio());
808 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
811 iLayer = AliGeomManager::kSPD1;
814 iLayer = AliGeomManager::kSPD2;
817 iLayer = AliGeomManager::kSDD1;
820 iLayer = AliGeomManager::kSDD2;
823 iLayer = AliGeomManager::kSSD1;
826 iLayer = AliGeomManager::kSSD2;
829 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
832 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
833 p.SetVolumeID((UShort_t)volid);
836 //------------------------------------------------------------------------
837 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
838 AliTrackPoint& p, const AliESDtrack *t) {
839 //--------------------------------------------------------------------
840 // Get track space point with index i
841 // (assign error estimated during the tracking)
842 //--------------------------------------------------------------------
844 Int_t l=(index & 0xf0000000) >> 28;
845 Int_t c=(index & 0x0fffffff) >> 00;
846 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
847 Int_t idet = cl->GetDetectorIndex();
849 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
851 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
853 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
854 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
855 Double_t alpha = t->GetAlpha();
856 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
857 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,GetBz()));
858 phi += alpha-det.GetPhi();
859 Float_t tgphi = TMath::Tan(phi);
861 Float_t tgl = t->GetTgl(); // tgl about const along track
862 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
864 Float_t errlocalx,errlocalz;
865 Bool_t addMisalErr=kFALSE;
866 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errlocalx,errlocalz,addMisalErr);
870 cl->GetGlobalXYZ(xyz);
871 // cl->GetGlobalCov(cov);
872 Float_t pos[3] = {0.,0.,0.};
873 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errlocalx*errlocalx,errlocalz*errlocalz,0);
874 tmpcl.GetGlobalCov(cov);
877 p.SetCharge(cl->GetQ());
878 p.SetDriftTime(cl->GetDriftTime());
879 p.SetChargeRatio(cl->GetChargeRatio());
881 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
884 iLayer = AliGeomManager::kSPD1;
887 iLayer = AliGeomManager::kSPD2;
890 iLayer = AliGeomManager::kSDD1;
893 iLayer = AliGeomManager::kSDD2;
896 iLayer = AliGeomManager::kSSD1;
899 iLayer = AliGeomManager::kSSD2;
902 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
905 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
907 p.SetVolumeID((UShort_t)volid);
910 //------------------------------------------------------------------------
911 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
913 //--------------------------------------------------------------------
914 // Follow prolongation tree
915 //--------------------------------------------------------------------
917 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
918 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
921 AliESDtrack * esd = otrack->GetESDtrack();
922 if (esd->GetV0Index(0)>0) {
923 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
924 // mapping of ESD track is different as ITS track in Containers
925 // Need something more stable
926 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
927 for (Int_t i=0;i<3;i++){
928 Int_t index = esd->GetV0Index(i);
930 AliESDv0 * vertex = fEsd->GetV0(index);
931 if (vertex->GetStatus()<0) continue; // rejected V0
933 if (esd->GetSign()>0) {
934 vertex->SetIndex(0,esdindex);
936 vertex->SetIndex(1,esdindex);
940 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
942 bestarray = new TObjArray(5);
943 fBestHypothesys.AddAt(bestarray,esdindex);
947 //setup tree of the prolongations
949 static AliITStrackMI tracks[7][100];
950 AliITStrackMI *currenttrack;
951 static AliITStrackMI currenttrack1;
952 static AliITStrackMI currenttrack2;
953 static AliITStrackMI backuptrack;
955 Int_t nindexes[7][100];
956 Float_t normalizedchi2[100];
957 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
958 otrack->SetNSkipped(0);
959 new (&(tracks[6][0])) AliITStrackMI(*otrack);
961 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
962 Int_t modstatus = 1; // found
966 // follow prolongations
967 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
968 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
971 AliITSlayer &layer=fgLayers[ilayer];
972 Double_t r = layer.GetR();
978 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
980 if (ntracks[ilayer]>=100) break;
981 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
982 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
983 if (ntracks[ilayer]>15+ilayer){
984 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
985 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
988 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
990 // material between SSD and SDD, SDD and SPD
992 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
994 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
998 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
999 Int_t idet=layer.FindDetectorIndex(phi,z);
1001 Double_t trackGlobXYZ1[3];
1002 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1004 // Get the budget to the primary vertex for the current track being prolonged
1005 Double_t budgetToPrimVertex = GetEffectiveThickness();
1007 // check if we allow a prolongation without point
1008 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1010 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1011 // propagate to the layer radius
1012 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1013 if(!vtrack->Propagate(xToGo)) continue;
1014 // apply correction for material of the current layer
1015 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1016 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1017 vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1018 vtrack->SetClIndex(ilayer,-1);
1019 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1020 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1021 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1023 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1028 // track outside layer acceptance in z
1029 if (idet<0) continue;
1031 //propagate to the intersection with the detector plane
1032 const AliITSdetector &det=layer.GetDetector(idet);
1033 new(¤ttrack2) AliITStrackMI(currenttrack1);
1034 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1035 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1036 currenttrack1.SetDetectorIndex(idet);
1037 currenttrack2.SetDetectorIndex(idet);
1038 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1041 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1043 // road in global (rphi,z) [i.e. in tracking ref. system]
1044 Double_t zmin,zmax,ymin,ymax;
1045 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1047 // select clusters in road
1048 layer.SelectClusters(zmin,zmax,ymin,ymax);
1049 //********************
1051 // Define criteria for track-cluster association
1052 Double_t msz = currenttrack1.GetSigmaZ2() +
1053 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1054 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1055 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1056 Double_t msy = currenttrack1.GetSigmaY2() +
1057 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1058 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1059 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1061 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1062 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1064 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1065 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1067 msz = 1./msz; // 1/RoadZ^2
1068 msy = 1./msy; // 1/RoadY^2
1072 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1074 const AliITSRecPoint *cl=0;
1076 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1077 Bool_t deadzoneSPD=kFALSE;
1078 currenttrack = ¤ttrack1;
1080 // check if the road contains a dead zone
1081 Bool_t noClusters = kFALSE;
1082 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1083 if (noClusters) AliDebug(2,"no clusters in road");
1084 Double_t dz=0.5*(zmax-zmin);
1085 Double_t dy=0.5*(ymax-ymin);
1086 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1087 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1088 // create a prolongation without clusters (check also if there are no clusters in the road)
1091 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1092 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1093 updatetrack->SetClIndex(ilayer,-1);
1095 modstatus = 5; // no cls in road
1096 } else if (dead==1) {
1097 modstatus = 7; // holes in z in SPD
1098 } else if (dead==2 || dead==3 || dead==4) {
1099 modstatus = 2; // dead from OCDB
1101 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1102 // apply correction for material of the current layer
1103 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1104 if (constrain) { // apply vertex constrain
1105 updatetrack->SetConstrain(constrain);
1106 Bool_t isPrim = kTRUE;
1107 if (ilayer<4) { // check that it's close to the vertex
1108 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1109 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1110 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1111 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1112 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1114 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1116 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1118 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1119 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1121 } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1122 updatetrack->SetDeadZoneProbability(ilayer,1.);
1123 } else if (dead==4) { // at least a single dead channel from OCDB
1124 updatetrack->SetDeadZoneProbability(ilayer,0.);
1131 // loop over clusters in the road
1132 while ((cl=layer.GetNextCluster(clidx))!=0) {
1133 if (ntracks[ilayer]>95) break; //space for skipped clusters
1134 Bool_t changedet =kFALSE;
1135 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
1136 Int_t idetc=cl->GetDetectorIndex();
1138 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1139 // take into account misalignment (bring track to real detector plane)
1140 Double_t xTrOrig = currenttrack->GetX();
1141 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1142 // a first cut on track-cluster distance
1143 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1144 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1145 { // cluster not associated to track
1146 AliDebug(2,"not associated");
1149 // bring track back to ideal detector plane
1150 if (!currenttrack->Propagate(xTrOrig)) continue;
1151 } else { // have to move track to cluster's detector
1152 const AliITSdetector &detc=layer.GetDetector(idetc);
1153 // a first cut on track-cluster distance
1155 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1156 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1157 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1158 continue; // cluster not associated to track
1160 new (&backuptrack) AliITStrackMI(currenttrack2);
1162 currenttrack =¤ttrack2;
1163 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1164 new (currenttrack) AliITStrackMI(backuptrack);
1168 currenttrack->SetDetectorIndex(idetc);
1169 // Get again the budget to the primary vertex
1170 // for the current track being prolonged, if had to change detector
1171 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1174 // calculate track-clusters chi2
1175 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1177 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1178 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1179 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1180 if (ntracks[ilayer]>=100) continue;
1181 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1182 updatetrack->SetClIndex(ilayer,-1);
1183 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1185 if (cl->GetQ()!=0) { // real cluster
1186 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1187 AliDebug(2,"update failed");
1190 updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1191 modstatus = 1; // found
1192 } else { // virtual cluster in dead zone
1193 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1194 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1195 modstatus = 7; // holes in z in SPD
1199 Float_t xlocnewdet,zlocnewdet;
1200 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1201 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1204 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1206 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1208 // apply correction for material of the current layer
1209 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1211 if (constrain) { // apply vertex constrain
1212 updatetrack->SetConstrain(constrain);
1213 Bool_t isPrim = kTRUE;
1214 if (ilayer<4) { // check that it's close to the vertex
1215 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1216 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1217 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1218 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1219 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1221 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1222 } //apply vertex constrain
1224 } // create new hypothesis
1226 AliDebug(2,"chi2 too large");
1229 } // loop over possible prolongations
1231 // allow one prolongation without clusters
1232 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1233 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1234 // apply correction for material of the current layer
1235 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1236 vtrack->SetClIndex(ilayer,-1);
1237 modstatus = 3; // skipped
1238 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1239 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1240 vtrack->IncrementNSkipped();
1244 // allow one prolongation without clusters for tracks with |tgl|>1.1
1245 if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) { //big theta - for low flux
1246 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1247 // apply correction for material of the current layer
1248 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1249 vtrack->SetClIndex(ilayer,-1);
1250 modstatus = 3; // skipped
1251 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1252 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1253 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1258 } // loop over tracks in layer ilayer+1
1260 //loop over track candidates for the current layer
1266 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1267 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1268 if (normalizedchi2[itrack] <
1269 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1273 if (constrain) { // constrain
1274 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1276 } else { // !constrain
1277 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1282 // sort tracks by increasing normalized chi2
1283 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1284 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1285 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1286 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1287 } // end loop over layers
1291 // Now select tracks to be kept
1293 Int_t max = constrain ? 20 : 5;
1295 // tracks that reach layer 0 (SPD inner)
1296 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1297 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1298 if (track.GetNumberOfClusters()<2) continue;
1299 if (!constrain && track.GetNormChi2(0) >
1300 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1303 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1306 // tracks that reach layer 1 (SPD outer)
1307 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1308 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1309 if (track.GetNumberOfClusters()<4) continue;
1310 if (!constrain && track.GetNormChi2(1) >
1311 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1312 if (constrain) track.IncrementNSkipped();
1314 track.SetD(0,track.GetD(GetX(),GetY()));
1315 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1316 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1317 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1320 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1323 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1325 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1326 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1327 if (track.GetNumberOfClusters()<3) continue;
1328 if (!constrain && track.GetNormChi2(2) >
1329 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1330 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1332 track.SetD(0,track.GetD(GetX(),GetY()));
1333 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1334 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1335 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1338 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1344 // register best track of each layer - important for V0 finder
1346 for (Int_t ilayer=0;ilayer<5;ilayer++){
1347 if (ntracks[ilayer]==0) continue;
1348 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1349 if (track.GetNumberOfClusters()<1) continue;
1350 CookLabel(&track,0);
1351 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1355 // update TPC V0 information
1357 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1358 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1359 for (Int_t i=0;i<3;i++){
1360 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1361 if (index==0) break;
1362 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1363 if (vertex->GetStatus()<0) continue; // rejected V0
1365 if (otrack->GetSign()>0) {
1366 vertex->SetIndex(0,esdindex);
1369 vertex->SetIndex(1,esdindex);
1371 //find nearest layer with track info
1372 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1373 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1374 Int_t nearest = nearestold;
1375 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1376 if (ntracks[nearest]==0){
1381 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1382 if (nearestold<5&&nearest<5){
1383 Bool_t accept = track.GetNormChi2(nearest)<10;
1385 if (track.GetSign()>0) {
1386 vertex->SetParamP(track);
1387 vertex->Update(fprimvertex);
1388 //vertex->SetIndex(0,track.fESDtrack->GetID());
1389 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1391 vertex->SetParamN(track);
1392 vertex->Update(fprimvertex);
1393 //vertex->SetIndex(1,track.fESDtrack->GetID());
1394 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1396 vertex->SetStatus(vertex->GetStatus()+1);
1398 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1405 //------------------------------------------------------------------------
1406 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1408 //--------------------------------------------------------------------
1411 return fgLayers[layer];
1413 //------------------------------------------------------------------------
1414 AliITStrackerMI::AliITSlayer::AliITSlayer():
1439 //--------------------------------------------------------------------
1440 //default AliITSlayer constructor
1441 //--------------------------------------------------------------------
1442 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1443 fClusterWeight[i]=0;
1444 fClusterTracks[0][i]=-1;
1445 fClusterTracks[1][i]=-1;
1446 fClusterTracks[2][i]=-1;
1447 fClusterTracks[3][i]=-1;
1450 //------------------------------------------------------------------------
1451 AliITStrackerMI::AliITSlayer::
1452 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1477 //--------------------------------------------------------------------
1478 //main AliITSlayer constructor
1479 //--------------------------------------------------------------------
1480 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1481 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1483 //------------------------------------------------------------------------
1484 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1486 fPhiOffset(layer.fPhiOffset),
1487 fNladders(layer.fNladders),
1488 fZOffset(layer.fZOffset),
1489 fNdetectors(layer.fNdetectors),
1490 fDetectors(layer.fDetectors),
1495 fClustersCs(layer.fClustersCs),
1496 fClusterIndexCs(layer.fClusterIndexCs),
1500 fCurrentSlice(layer.fCurrentSlice),
1507 fAccepted(layer.fAccepted),
1511 //------------------------------------------------------------------------
1512 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1513 //--------------------------------------------------------------------
1514 // AliITSlayer destructor
1515 //--------------------------------------------------------------------
1516 delete [] fDetectors;
1517 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1518 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1519 fClusterWeight[i]=0;
1520 fClusterTracks[0][i]=-1;
1521 fClusterTracks[1][i]=-1;
1522 fClusterTracks[2][i]=-1;
1523 fClusterTracks[3][i]=-1;
1526 //------------------------------------------------------------------------
1527 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1528 //--------------------------------------------------------------------
1529 // This function removes loaded clusters
1530 //--------------------------------------------------------------------
1531 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1532 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1533 fClusterWeight[i]=0;
1534 fClusterTracks[0][i]=-1;
1535 fClusterTracks[1][i]=-1;
1536 fClusterTracks[2][i]=-1;
1537 fClusterTracks[3][i]=-1;
1543 //------------------------------------------------------------------------
1544 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1545 //--------------------------------------------------------------------
1546 // This function reset weights of the clusters
1547 //--------------------------------------------------------------------
1548 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1549 fClusterWeight[i]=0;
1550 fClusterTracks[0][i]=-1;
1551 fClusterTracks[1][i]=-1;
1552 fClusterTracks[2][i]=-1;
1553 fClusterTracks[3][i]=-1;
1555 for (Int_t i=0; i<fN;i++) {
1556 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1557 if (cl&&cl->IsUsed()) cl->Use();
1561 //------------------------------------------------------------------------
1562 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1563 //--------------------------------------------------------------------
1564 // This function calculates the road defined by the cluster density
1565 //--------------------------------------------------------------------
1567 for (Int_t i=0; i<fN; i++) {
1568 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1570 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1572 //------------------------------------------------------------------------
1573 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1574 //--------------------------------------------------------------------
1575 //This function adds a cluster to this layer
1576 //--------------------------------------------------------------------
1577 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1578 ::Error("InsertCluster","Too many clusters !\n");
1584 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1585 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1586 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1587 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1588 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1592 //------------------------------------------------------------------------
1593 void AliITStrackerMI::AliITSlayer::SortClusters()
1598 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1599 Float_t *z = new Float_t[fN];
1600 Int_t * index = new Int_t[fN];
1602 for (Int_t i=0;i<fN;i++){
1603 z[i] = fClusters[i]->GetZ();
1605 TMath::Sort(fN,z,index,kFALSE);
1606 for (Int_t i=0;i<fN;i++){
1607 clusters[i] = fClusters[index[i]];
1610 for (Int_t i=0;i<fN;i++){
1611 fClusters[i] = clusters[i];
1612 fZ[i] = fClusters[i]->GetZ();
1613 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1614 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1615 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1625 for (Int_t i=0;i<fN;i++){
1626 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1627 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1628 fClusterIndex[i] = i;
1632 fDy5 = (fYB[1]-fYB[0])/5.;
1633 fDy10 = (fYB[1]-fYB[0])/10.;
1634 fDy20 = (fYB[1]-fYB[0])/20.;
1635 for (Int_t i=0;i<6;i++) fN5[i] =0;
1636 for (Int_t i=0;i<11;i++) fN10[i]=0;
1637 for (Int_t i=0;i<21;i++) fN20[i]=0;
1639 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;}
1640 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;}
1641 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;}
1644 for (Int_t i=0;i<fN;i++)
1645 for (Int_t irot=-1;irot<=1;irot++){
1646 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1648 for (Int_t slice=0; slice<6;slice++){
1649 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1650 fClusters5[slice][fN5[slice]] = fClusters[i];
1651 fY5[slice][fN5[slice]] = curY;
1652 fZ5[slice][fN5[slice]] = fZ[i];
1653 fClusterIndex5[slice][fN5[slice]]=i;
1658 for (Int_t slice=0; slice<11;slice++){
1659 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1660 fClusters10[slice][fN10[slice]] = fClusters[i];
1661 fY10[slice][fN10[slice]] = curY;
1662 fZ10[slice][fN10[slice]] = fZ[i];
1663 fClusterIndex10[slice][fN10[slice]]=i;
1668 for (Int_t slice=0; slice<21;slice++){
1669 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1670 fClusters20[slice][fN20[slice]] = fClusters[i];
1671 fY20[slice][fN20[slice]] = curY;
1672 fZ20[slice][fN20[slice]] = fZ[i];
1673 fClusterIndex20[slice][fN20[slice]]=i;
1680 // consistency check
1682 for (Int_t i=0;i<fN-1;i++){
1688 for (Int_t slice=0;slice<21;slice++)
1689 for (Int_t i=0;i<fN20[slice]-1;i++){
1690 if (fZ20[slice][i]>fZ20[slice][i+1]){
1697 //------------------------------------------------------------------------
1698 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1699 //--------------------------------------------------------------------
1700 // This function returns the index of the nearest cluster
1701 //--------------------------------------------------------------------
1704 if (fCurrentSlice<0) {
1713 if (ncl==0) return 0;
1714 Int_t b=0, e=ncl-1, m=(b+e)/2;
1715 for (; b<e; m=(b+e)/2) {
1716 // if (z > fClusters[m]->GetZ()) b=m+1;
1717 if (z > zcl[m]) b=m+1;
1722 //------------------------------------------------------------------------
1723 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 {
1724 //--------------------------------------------------------------------
1725 // This function computes the rectangular road for this track
1726 //--------------------------------------------------------------------
1729 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1730 // take into account the misalignment: propagate track to misaligned detector plane
1731 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1733 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1734 TMath::Sqrt(track->GetSigmaZ2() +
1735 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1736 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1737 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1738 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1739 TMath::Sqrt(track->GetSigmaY2() +
1740 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1741 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1742 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1744 // track at boundary between detectors, enlarge road
1745 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1746 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1747 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1748 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1749 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1750 Float_t tgl = TMath::Abs(track->GetTgl());
1751 if (tgl > 1.) tgl=1.;
1752 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1753 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1754 Float_t snp = TMath::Abs(track->GetSnp());
1755 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1756 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1759 // add to the road a term (up to 2-3 mm) to deal with misalignments
1760 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1761 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1763 Double_t r = fgLayers[ilayer].GetR();
1764 zmin = track->GetZ() - dz;
1765 zmax = track->GetZ() + dz;
1766 ymin = track->GetY() + r*det.GetPhi() - dy;
1767 ymax = track->GetY() + r*det.GetPhi() + dy;
1769 // bring track back to idead detector plane
1770 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1774 //------------------------------------------------------------------------
1775 void AliITStrackerMI::AliITSlayer::
1776 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1777 //--------------------------------------------------------------------
1778 // This function sets the "window"
1779 //--------------------------------------------------------------------
1781 Double_t circle=2*TMath::Pi()*fR;
1782 fYmin = ymin; fYmax =ymax;
1783 Float_t ymiddle = (fYmin+fYmax)*0.5;
1784 if (ymiddle<fYB[0]) {
1785 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1786 } else if (ymiddle>fYB[1]) {
1787 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1793 fClustersCs = fClusters;
1794 fClusterIndexCs = fClusterIndex;
1800 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1801 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1802 if (slice<0) slice=0;
1803 if (slice>20) slice=20;
1804 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1806 fCurrentSlice=slice;
1807 fClustersCs = fClusters20[fCurrentSlice];
1808 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1809 fYcs = fY20[fCurrentSlice];
1810 fZcs = fZ20[fCurrentSlice];
1811 fNcs = fN20[fCurrentSlice];
1816 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1817 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1818 if (slice<0) slice=0;
1819 if (slice>10) slice=10;
1820 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1822 fCurrentSlice=slice;
1823 fClustersCs = fClusters10[fCurrentSlice];
1824 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1825 fYcs = fY10[fCurrentSlice];
1826 fZcs = fZ10[fCurrentSlice];
1827 fNcs = fN10[fCurrentSlice];
1832 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1833 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1834 if (slice<0) slice=0;
1835 if (slice>5) slice=5;
1836 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1838 fCurrentSlice=slice;
1839 fClustersCs = fClusters5[fCurrentSlice];
1840 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1841 fYcs = fY5[fCurrentSlice];
1842 fZcs = fZ5[fCurrentSlice];
1843 fNcs = fN5[fCurrentSlice];
1847 fI=FindClusterIndex(zmin); fZmax=zmax;
1848 fImax = TMath::Min(FindClusterIndex(zmax)+1,fNcs);
1854 //------------------------------------------------------------------------
1855 Int_t AliITStrackerMI::AliITSlayer::
1856 FindDetectorIndex(Double_t phi, Double_t z) const {
1857 //--------------------------------------------------------------------
1858 //This function finds the detector crossed by the track
1859 //--------------------------------------------------------------------
1861 if (fZOffset<0) // old geometry
1862 dphi = -(phi-fPhiOffset);
1863 else // new geometry
1864 dphi = phi-fPhiOffset;
1867 if (dphi < 0) dphi += 2*TMath::Pi();
1868 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1869 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1870 if (np>=fNladders) np-=fNladders;
1871 if (np<0) np+=fNladders;
1874 Double_t dz=fZOffset-z;
1875 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1876 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1877 if (nz>=fNdetectors) return -1;
1878 if (nz<0) return -1;
1880 // ad hoc correction for 3rd ladder of SDD inner layer,
1881 // which is reversed (rotated by pi around local y)
1882 // this correction is OK only from AliITSv11Hybrid onwards
1883 if (GetR()>12. && GetR()<20.) { // SDD inner
1884 if(np==2) { // 3rd ladder
1885 nz = (fNdetectors-1) - nz;
1888 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1891 return np*fNdetectors + nz;
1893 //------------------------------------------------------------------------
1894 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1896 //--------------------------------------------------------------------
1897 // This function returns clusters within the "window"
1898 //--------------------------------------------------------------------
1900 if (fCurrentSlice<0) {
1901 Double_t rpi2 = 2.*fR*TMath::Pi();
1902 for (Int_t i=fI; i<fImax; i++) {
1904 if (fYmax<y) y -= rpi2;
1905 if (fYmin>y) y += rpi2;
1906 if (y<fYmin) continue;
1907 if (y>fYmax) continue;
1908 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1911 return fClusters[i];
1914 for (Int_t i=fI; i<fImax; i++) {
1915 if (fYcs[i]<fYmin) continue;
1916 if (fYcs[i]>fYmax) continue;
1917 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1918 ci=fClusterIndexCs[i];
1920 return fClustersCs[i];
1925 //------------------------------------------------------------------------
1926 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1928 //--------------------------------------------------------------------
1929 // This function returns the layer thickness at this point (units X0)
1930 //--------------------------------------------------------------------
1932 x0=AliITSRecoParam::GetX0Air();
1933 if (43<fR&&fR<45) { //SSD2
1936 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1937 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1938 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1939 for (Int_t i=0; i<12; i++) {
1940 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1941 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1945 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1946 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1950 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1951 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1954 if (37<fR&&fR<41) { //SSD1
1957 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1958 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1959 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1960 for (Int_t i=0; i<11; i++) {
1961 if (TMath::Abs(z-3.9*i)<0.15) {
1962 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1966 if (TMath::Abs(z+3.9*i)<0.15) {
1967 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1971 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1972 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1975 if (13<fR&&fR<26) { //SDD
1978 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1980 if (TMath::Abs(y-1.80)<0.55) {
1982 for (Int_t j=0; j<20; j++) {
1983 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1984 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1987 if (TMath::Abs(y+1.80)<0.55) {
1989 for (Int_t j=0; j<20; j++) {
1990 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1991 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1995 for (Int_t i=0; i<4; i++) {
1996 if (TMath::Abs(z-7.3*i)<0.60) {
1998 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2001 if (TMath::Abs(z+7.3*i)<0.60) {
2003 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2008 if (6<fR&&fR<8) { //SPD2
2009 Double_t dd=0.0063; x0=21.5;
2011 if (TMath::Abs(y-3.08)>0.5) d+=dd;
2012 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2014 if (3<fR&&fR<5) { //SPD1
2015 Double_t dd=0.0063; x0=21.5;
2017 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2018 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2023 //------------------------------------------------------------------------
2024 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2026 fRmisal(det.fRmisal),
2028 fSinPhi(det.fSinPhi),
2029 fCosPhi(det.fCosPhi),
2035 fNChips(det.fNChips),
2036 fChipIsBad(det.fChipIsBad)
2040 //------------------------------------------------------------------------
2041 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2042 const AliITSDetTypeRec *detTypeRec)
2044 //--------------------------------------------------------------------
2045 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2046 //--------------------------------------------------------------------
2048 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2049 // while in the tracker they start from 0 for each layer
2050 for(Int_t il=0; il<ilayer; il++)
2051 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2054 if (ilayer==0 || ilayer==1) { // ---------- SPD
2056 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2058 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2061 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2065 // Get calibration from AliITSDetTypeRec
2066 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2067 calib->SetModuleIndex(idet);
2068 AliITSCalibration *calibSPDdead = 0;
2069 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2070 if (calib->IsBad() ||
2071 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2074 // printf("lay %d bad %d\n",ilayer,idet);
2077 // Get segmentation from AliITSDetTypeRec
2078 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2080 // Read info about bad chips
2081 fNChips = segm->GetMaximumChipIndex()+1;
2082 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2083 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2084 fChipIsBad = new Bool_t[fNChips];
2085 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2086 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2087 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2088 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2093 //------------------------------------------------------------------------
2094 Double_t AliITStrackerMI::GetEffectiveThickness()
2096 //--------------------------------------------------------------------
2097 // Returns the thickness between the current layer and the vertex (units X0)
2098 //--------------------------------------------------------------------
2101 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2102 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2103 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2107 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2108 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2112 Double_t xn=fgLayers[fI].GetR();
2113 for (Int_t i=0; i<fI; i++) {
2114 Double_t xi=fgLayers[i].GetR();
2115 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2121 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2122 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2125 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2126 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2130 //------------------------------------------------------------------------
2131 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2132 //-------------------------------------------------------------------
2133 // This function returns number of clusters within the "window"
2134 //--------------------------------------------------------------------
2136 for (Int_t i=fI; i<fN; i++) {
2137 const AliITSRecPoint *c=fClusters[i];
2138 if (c->GetZ() > fZmax) break;
2139 if (c->IsUsed()) continue;
2140 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2141 Double_t y=fR*det.GetPhi() + c->GetY();
2143 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2144 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2146 if (y<fYmin) continue;
2147 if (y>fYmax) continue;
2152 //------------------------------------------------------------------------
2153 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2154 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2156 //--------------------------------------------------------------------
2157 // This function refits the track "track" at the position "x" using
2158 // the clusters from "clusters"
2159 // If "extra"==kTRUE,
2160 // the clusters from overlapped modules get attached to "track"
2161 // If "planeff"==kTRUE,
2162 // special approach for plane efficiency evaluation is applyed
2163 //--------------------------------------------------------------------
2165 Int_t index[AliITSgeomTGeo::kNLayers];
2167 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2168 Int_t nc=clusters->GetNumberOfClusters();
2169 for (k=0; k<nc; k++) {
2170 Int_t idx=clusters->GetClusterIndex(k);
2171 Int_t ilayer=(idx&0xf0000000)>>28;
2175 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2177 //------------------------------------------------------------------------
2178 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2179 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2181 //--------------------------------------------------------------------
2182 // This function refits the track "track" at the position "x" using
2183 // the clusters from array
2184 // If "extra"==kTRUE,
2185 // the clusters from overlapped modules get attached to "track"
2186 // If "planeff"==kTRUE,
2187 // special approach for plane efficiency evaluation is applyed
2188 //--------------------------------------------------------------------
2189 Int_t index[AliITSgeomTGeo::kNLayers];
2191 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2193 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2194 index[k]=clusters[k];
2197 // special for cosmics: check which the innermost layer crossed
2199 Int_t innermostlayer=5;
2200 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2201 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2202 if(drphi < fgLayers[innermostlayer].GetR()) break;
2204 //printf(" drphi %f innermost %d\n",drphi,innermostlayer);
2206 Int_t modstatus=1; // found
2208 Int_t from, to, step;
2209 if (xx > track->GetX()) {
2210 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2213 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2216 TString dir = (step>0 ? "outward" : "inward");
2218 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2219 AliITSlayer &layer=fgLayers[ilayer];
2220 Double_t r=layer.GetR();
2221 if (step<0 && xx>r) break;
2223 // material between SSD and SDD, SDD and SPD
2224 Double_t hI=ilayer-0.5*step;
2225 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2226 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2227 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2228 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2231 Double_t oldGlobXYZ[3];
2232 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2234 // continue if we are already beyond this layer
2235 Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2236 if(step>0 && oldGlobR > r) continue; // going outward
2237 if(step<0 && oldGlobR < r) continue; // going inward
2240 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2242 Int_t idet=layer.FindDetectorIndex(phi,z);
2244 // check if we allow a prolongation without point for large-eta tracks
2245 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2247 modstatus = 4; // out in z
2248 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2249 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2252 // apply correction for material of the current layer
2253 // add time if going outward
2254 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2258 if (idet<0) return kFALSE;
2260 const AliITSdetector &det=layer.GetDetector(idet);
2261 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2263 track->SetDetectorIndex(idet);
2264 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2266 Double_t dz,zmin,zmax,dy,ymin,ymax;
2268 const AliITSRecPoint *clAcc=0;
2269 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2271 Int_t idx=index[ilayer];
2272 if (idx>=0) { // cluster in this layer
2273 modstatus = 6; // no refit
2274 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2276 if (idet != cl->GetDetectorIndex()) {
2277 idet=cl->GetDetectorIndex();
2278 const AliITSdetector &detc=layer.GetDetector(idet);
2279 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2280 track->SetDetectorIndex(idet);
2281 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2283 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2284 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2288 modstatus = 1; // found
2293 } else { // no cluster in this layer
2295 modstatus = 3; // skipped
2296 // Plane Eff determination:
2297 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2298 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2299 UseTrackForPlaneEff(track,ilayer);
2302 modstatus = 5; // no cls in road
2304 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2305 dz = 0.5*(zmax-zmin);
2306 dy = 0.5*(ymax-ymin);
2307 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2308 if (dead==1) modstatus = 7; // holes in z in SPD
2309 if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2314 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2315 track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2317 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2320 if (extra) { // search for extra clusters in overlapped modules
2321 AliITStrackV2 tmp(*track);
2322 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2323 layer.SelectClusters(zmin,zmax,ymin,ymax);
2325 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2327 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2328 Double_t tolerance=0.1;
2329 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2330 // only clusters in another module! (overlaps)
2331 idetExtra = clExtra->GetDetectorIndex();
2332 if (idet == idetExtra) continue;
2334 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2336 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2337 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2338 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2339 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2341 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2342 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2345 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2346 track->SetExtraModule(ilayer,idetExtra);
2348 } // end search for extra clusters in overlapped modules
2350 // Correct for material of the current layer
2352 // add time if going outward
2353 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2355 } // end loop on layers
2357 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2361 //------------------------------------------------------------------------
2362 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2365 // calculate normalized chi2
2366 // return NormalizedChi2(track,0);
2369 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2370 // track->fdEdxMismatch=0;
2371 Float_t dedxmismatch =0;
2372 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2374 for (Int_t i = 0;i<6;i++){
2375 if (track->GetClIndex(i)>=0){
2376 Float_t cerry, cerrz;
2377 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2379 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2382 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2383 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2384 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2386 cchi2+=(0.5-ratio)*10.;
2387 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2388 dedxmismatch+=(0.5-ratio)*10.;
2392 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2393 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2394 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2395 if (i<2) chi2+=2*cl->GetDeltaProbability();
2401 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2402 track->SetdEdxMismatch(dedxmismatch);
2406 for (Int_t i = 0;i<4;i++){
2407 if (track->GetClIndex(i)>=0){
2408 Float_t cerry, cerrz;
2409 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2410 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2413 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2414 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2418 for (Int_t i = 4;i<6;i++){
2419 if (track->GetClIndex(i)>=0){
2420 Float_t cerry, cerrz;
2421 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2422 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2425 Float_t cerryb, cerrzb;
2426 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2427 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2430 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2431 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2436 if (track->GetESDtrack()->GetTPCsignal()>85){
2437 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2439 chi2+=(0.5-ratio)*5.;
2442 chi2+=(ratio-2.0)*3;
2446 Double_t match = TMath::Sqrt(track->GetChi22());
2447 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2448 if (!track->GetConstrain()) {
2449 if (track->GetNumberOfClusters()>2) {
2450 match/=track->GetNumberOfClusters()-2.;
2455 if (match<0) match=0;
2457 // penalty factor for missing points (NDeadZone>0), but no penalty
2458 // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2459 // or there is a dead from OCDB)
2460 Float_t deadzonefactor = 0.;
2461 if (track->GetNDeadZone()>0.) {
2462 Float_t sumDeadZoneProbability=0;
2463 for(Int_t ilay=0;ilay<6;ilay++) sumDeadZoneProbability+=track->GetDeadZoneProbability(ilay);
2464 Float_t nDeadZoneWithProbNot1=(Float_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2465 if(nDeadZoneWithProbNot1>0.) {
2466 Float_t deadZoneProbability = sumDeadZoneProbability - (Float_t)((Int_t)sumDeadZoneProbability);
2467 deadZoneProbability /= nDeadZoneWithProbNot1;
2468 deadzonefactor = 3.*(1.1-deadZoneProbability);
2472 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2473 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2474 1./(1.+track->GetNSkipped()));
2478 //------------------------------------------------------------------------
2479 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2482 // return matching chi2 between two tracks
2483 Double_t largeChi2=1000.;
2485 AliITStrackMI track3(*track2);
2486 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2488 vec(0,0)=track1->GetY() - track3.GetY();
2489 vec(1,0)=track1->GetZ() - track3.GetZ();
2490 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2491 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2492 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2495 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2496 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2497 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2498 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2499 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2501 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2502 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2503 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2504 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2506 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2507 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2508 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2510 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2511 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2513 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2516 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2517 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2520 //------------------------------------------------------------------------
2521 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2524 // return probability that given point (characterized by z position and error)
2525 // is in SPD dead zone
2527 Double_t probability = 0.;
2528 Double_t absz = TMath::Abs(zpos);
2529 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2530 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2531 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2532 Double_t zmin, zmax;
2533 if (zpos<-6.) { // dead zone at z = -7
2534 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2535 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2536 } else if (zpos>6.) { // dead zone at z = +7
2537 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2538 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2539 } else if (absz<2.) { // dead zone at z = 0
2540 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2541 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2546 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2548 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2549 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2552 //------------------------------------------------------------------------
2553 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2556 // calculate normalized chi2
2558 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2560 for (Int_t i = 0;i<6;i++){
2561 if (TMath::Abs(track->GetDy(i))>0){
2562 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2563 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2566 else{chi2[i]=10000;}
2569 TMath::Sort(6,chi2,index,kFALSE);
2570 Float_t max = float(ncl)*fac-1.;
2571 Float_t sumchi=0, sumweight=0;
2572 for (Int_t i=0;i<max+1;i++){
2573 Float_t weight = (i<max)?1.:(max+1.-i);
2574 sumchi+=weight*chi2[index[i]];
2577 Double_t normchi2 = sumchi/sumweight;
2580 //------------------------------------------------------------------------
2581 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2584 // calculate normalized chi2
2585 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2588 for (Int_t i=0;i<6;i++){
2589 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2590 Double_t sy1 = forwardtrack->GetSigmaY(i);
2591 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2592 Double_t sy2 = backtrack->GetSigmaY(i);
2593 Double_t sz2 = backtrack->GetSigmaZ(i);
2594 if (i<2){ sy2=1000.;sz2=1000;}
2596 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2597 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2599 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2600 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2602 res+= nz0*nz0+ny0*ny0;
2605 if (npoints>1) return
2606 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2607 //2*forwardtrack->fNUsed+
2608 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2609 1./(1.+forwardtrack->GetNSkipped()));
2612 //------------------------------------------------------------------------
2613 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2614 //--------------------------------------------------------------------
2615 // Return pointer to a given cluster
2616 //--------------------------------------------------------------------
2617 Int_t l=(index & 0xf0000000) >> 28;
2618 Int_t c=(index & 0x0fffffff) >> 00;
2619 return fgLayers[l].GetWeight(c);
2621 //------------------------------------------------------------------------
2622 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2624 //---------------------------------------------
2625 // register track to the list
2627 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2630 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2631 Int_t index = track->GetClusterIndex(icluster);
2632 Int_t l=(index & 0xf0000000) >> 28;
2633 Int_t c=(index & 0x0fffffff) >> 00;
2634 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2635 for (Int_t itrack=0;itrack<4;itrack++){
2636 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2637 fgLayers[l].SetClusterTracks(itrack,c,id);
2643 //------------------------------------------------------------------------
2644 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2646 //---------------------------------------------
2647 // unregister track from the list
2648 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2649 Int_t index = track->GetClusterIndex(icluster);
2650 Int_t l=(index & 0xf0000000) >> 28;
2651 Int_t c=(index & 0x0fffffff) >> 00;
2652 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2653 for (Int_t itrack=0;itrack<4;itrack++){
2654 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2655 fgLayers[l].SetClusterTracks(itrack,c,-1);
2660 //------------------------------------------------------------------------
2661 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2663 //-------------------------------------------------------------
2664 //get number of shared clusters
2665 //-------------------------------------------------------------
2667 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2668 // mean number of clusters
2669 Float_t *ny = GetNy(id), *nz = GetNz(id);
2672 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2673 Int_t index = track->GetClusterIndex(icluster);
2674 Int_t l=(index & 0xf0000000) >> 28;
2675 Int_t c=(index & 0x0fffffff) >> 00;
2676 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2678 printf("problem\n");
2680 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2684 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2685 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2686 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2688 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2691 deltan = (cl->GetNz()-nz[l]);
2693 if (deltan>2.0) continue; // extended - highly probable shared cluster
2694 weight = 2./TMath::Max(3.+deltan,2.);
2696 for (Int_t itrack=0;itrack<4;itrack++){
2697 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2699 clist[l] = (AliITSRecPoint*)GetCluster(index);
2705 track->SetNUsed(shared);
2708 //------------------------------------------------------------------------
2709 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2712 // find first shared track
2714 // mean number of clusters
2715 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2717 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2718 Int_t sharedtrack=100000;
2719 Int_t tracks[24],trackindex=0;
2720 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2722 for (Int_t icluster=0;icluster<6;icluster++){
2723 if (clusterlist[icluster]<0) continue;
2724 Int_t index = clusterlist[icluster];
2725 Int_t l=(index & 0xf0000000) >> 28;
2726 Int_t c=(index & 0x0fffffff) >> 00;
2728 printf("problem\n");
2730 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2731 //if (l>3) continue;
2732 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2735 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2736 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2737 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2739 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2742 deltan = (cl->GetNz()-nz[l]);
2744 if (deltan>2.0) continue; // extended - highly probable shared cluster
2746 for (Int_t itrack=3;itrack>=0;itrack--){
2747 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2748 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2749 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2754 if (trackindex==0) return -1;
2756 sharedtrack = tracks[0];
2758 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2761 Int_t tracks2[24], cluster[24];
2762 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2765 for (Int_t i=0;i<trackindex;i++){
2766 if (tracks[i]<0) continue;
2767 tracks2[index] = tracks[i];
2769 for (Int_t j=i+1;j<trackindex;j++){
2770 if (tracks[j]<0) continue;
2771 if (tracks[j]==tracks[i]){
2779 for (Int_t i=0;i<index;i++){
2780 if (cluster[index]>max) {
2781 sharedtrack=tracks2[index];
2788 if (sharedtrack>=100000) return -1;
2790 // make list of overlaps
2792 for (Int_t icluster=0;icluster<6;icluster++){
2793 if (clusterlist[icluster]<0) continue;
2794 Int_t index = clusterlist[icluster];
2795 Int_t l=(index & 0xf0000000) >> 28;
2796 Int_t c=(index & 0x0fffffff) >> 00;
2797 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2798 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2800 if (cl->GetNy()>2) continue;
2801 if (cl->GetNz()>2) continue;
2804 if (cl->GetNy()>3) continue;
2805 if (cl->GetNz()>3) continue;
2808 for (Int_t itrack=3;itrack>=0;itrack--){
2809 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2810 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2818 //------------------------------------------------------------------------
2819 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2821 // try to find track hypothesys without conflicts
2822 // with minimal chi2;
2823 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2824 Int_t entries1 = arr1->GetEntriesFast();
2825 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2826 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2827 Int_t entries2 = arr2->GetEntriesFast();
2828 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2830 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2831 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2832 if (track10->Pt()>0.5+track20->Pt()) return track10;
2834 for (Int_t itrack=0;itrack<entries1;itrack++){
2835 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2836 UnRegisterClusterTracks(track,trackID1);
2839 for (Int_t itrack=0;itrack<entries2;itrack++){
2840 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2841 UnRegisterClusterTracks(track,trackID2);
2845 Float_t maxconflicts=6;
2846 Double_t maxchi2 =1000.;
2848 // get weight of hypothesys - using best hypothesy
2851 Int_t list1[6],list2[6];
2852 AliITSRecPoint *clist1[6], *clist2[6] ;
2853 RegisterClusterTracks(track10,trackID1);
2854 RegisterClusterTracks(track20,trackID2);
2855 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2856 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2857 UnRegisterClusterTracks(track10,trackID1);
2858 UnRegisterClusterTracks(track20,trackID2);
2861 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2862 Float_t nerry[6],nerrz[6];
2863 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2864 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2865 for (Int_t i=0;i<6;i++){
2866 if ( (erry1[i]>0) && (erry2[i]>0)) {
2867 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2868 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2870 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2871 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2873 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2874 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2875 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2878 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2879 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2880 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2888 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2889 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2890 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2891 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2893 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2894 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2895 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2897 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2898 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2899 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2902 Double_t sumw = w1+w2;
2906 w1 = (d2+0.5)/(d1+d2+1.);
2907 w2 = (d1+0.5)/(d1+d2+1.);
2909 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2910 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2912 // get pair of "best" hypothesys
2914 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2915 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2917 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2918 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2919 //if (track1->fFakeRatio>0) continue;
2920 RegisterClusterTracks(track1,trackID1);
2921 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2922 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2924 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2925 //if (track2->fFakeRatio>0) continue;
2927 RegisterClusterTracks(track2,trackID2);
2928 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2929 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2930 UnRegisterClusterTracks(track2,trackID2);
2932 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2933 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2934 if (nskipped>0.5) continue;
2936 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2937 if (conflict1+1<cconflict1) continue;
2938 if (conflict2+1<cconflict2) continue;
2942 for (Int_t i=0;i<6;i++){
2944 Float_t c1 =0.; // conflict coeficients
2946 if (clist1[i]&&clist2[i]){
2949 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2952 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
2954 c1 = 2./TMath::Max(3.+deltan,2.);
2955 c2 = 2./TMath::Max(3.+deltan,2.);
2961 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
2964 deltan = (clist1[i]->GetNz()-nz1[i]);
2966 c1 = 2./TMath::Max(3.+deltan,2.);
2973 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
2976 deltan = (clist2[i]->GetNz()-nz2[i]);
2978 c2 = 2./TMath::Max(3.+deltan,2.);
2984 if (TMath::Abs(track1->GetDy(i))>0.) {
2985 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
2986 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
2987 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
2988 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
2990 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
2993 if (TMath::Abs(track2->GetDy(i))>0.) {
2994 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
2995 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
2996 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
2997 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3000 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3002 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3003 if (chi21>0) sum+=w1;
3004 if (chi22>0) sum+=w2;
3007 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3008 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3009 Double_t normchi2 = 2*conflict+sumchi2/sum;
3010 if ( normchi2 <maxchi2 ){
3013 maxconflicts = conflict;
3017 UnRegisterClusterTracks(track1,trackID1);
3020 // if (maxconflicts<4 && maxchi2<th0){
3021 if (maxchi2<th0*2.){
3022 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3023 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3024 track1->SetChi2MIP(5,maxconflicts);
3025 track1->SetChi2MIP(6,maxchi2);
3026 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3027 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3028 track1->SetChi2MIP(8,index1);
3029 fBestTrackIndex[trackID1] =index1;
3030 UpdateESDtrack(track1, AliESDtrack::kITSin);
3032 else if (track10->GetChi2MIP(0)<th1){
3033 track10->SetChi2MIP(5,maxconflicts);
3034 track10->SetChi2MIP(6,maxchi2);
3035 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3036 UpdateESDtrack(track10,AliESDtrack::kITSin);
3039 for (Int_t itrack=0;itrack<entries1;itrack++){
3040 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3041 UnRegisterClusterTracks(track,trackID1);
3044 for (Int_t itrack=0;itrack<entries2;itrack++){
3045 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3046 UnRegisterClusterTracks(track,trackID2);
3049 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3050 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3051 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3052 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3053 RegisterClusterTracks(track10,trackID1);
3055 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3056 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3057 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3058 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3059 RegisterClusterTracks(track20,trackID2);
3064 //------------------------------------------------------------------------
3065 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3066 //--------------------------------------------------------------------
3067 // This function marks clusters assigned to the track
3068 //--------------------------------------------------------------------
3069 AliTracker::UseClusters(t,from);
3071 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3072 //if (c->GetQ()>2) c->Use();
3073 if (c->GetSigmaZ2()>0.1) c->Use();
3074 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3075 //if (c->GetQ()>2) c->Use();
3076 if (c->GetSigmaZ2()>0.1) c->Use();
3079 //------------------------------------------------------------------------
3080 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3082 //------------------------------------------------------------------
3083 // add track to the list of hypothesys
3084 //------------------------------------------------------------------
3086 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3087 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3089 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3091 array = new TObjArray(10);
3092 fTrackHypothesys.AddAt(array,esdindex);
3094 array->AddLast(track);
3096 //------------------------------------------------------------------------
3097 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3099 //-------------------------------------------------------------------
3100 // compress array of track hypothesys
3101 // keep only maxsize best hypothesys
3102 //-------------------------------------------------------------------
3103 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3104 if (! (fTrackHypothesys.At(esdindex)) ) return;
3105 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3106 Int_t entries = array->GetEntriesFast();
3108 //- find preliminary besttrack as a reference
3109 Float_t minchi2=10000;
3111 AliITStrackMI * besttrack=0;
3112 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3113 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3114 if (!track) continue;
3115 Float_t chi2 = NormalizedChi2(track,0);
3117 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3118 track->SetLabel(tpcLabel);
3120 track->SetFakeRatio(1.);
3121 CookLabel(track,0.); //For comparison only
3123 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3124 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3125 if (track->GetNumberOfClusters()<maxn) continue;
3126 maxn = track->GetNumberOfClusters();
3133 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3134 delete array->RemoveAt(itrack);
3138 if (!besttrack) return;
3141 //take errors of best track as a reference
3142 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3143 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3144 for (Int_t j=0;j<6;j++) {
3145 if (besttrack->GetClIndex(j)>=0){
3146 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3147 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3148 ny[j] = besttrack->GetNy(j);
3149 nz[j] = besttrack->GetNz(j);
3153 // calculate normalized chi2
3155 Float_t * chi2 = new Float_t[entries];
3156 Int_t * index = new Int_t[entries];
3157 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3158 for (Int_t itrack=0;itrack<entries;itrack++){
3159 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3161 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3162 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3163 chi2[itrack] = track->GetChi2MIP(0);
3165 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3166 delete array->RemoveAt(itrack);
3172 TMath::Sort(entries,chi2,index,kFALSE);
3173 besttrack = (AliITStrackMI*)array->At(index[0]);
3174 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3175 for (Int_t j=0;j<6;j++){
3176 if (besttrack->GetClIndex(j)>=0){
3177 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3178 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3179 ny[j] = besttrack->GetNy(j);
3180 nz[j] = besttrack->GetNz(j);
3185 // calculate one more time with updated normalized errors
3186 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3187 for (Int_t itrack=0;itrack<entries;itrack++){
3188 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3190 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3191 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3192 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3195 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3196 delete array->RemoveAt(itrack);
3201 entries = array->GetEntriesFast();
3205 TObjArray * newarray = new TObjArray();
3206 TMath::Sort(entries,chi2,index,kFALSE);
3207 besttrack = (AliITStrackMI*)array->At(index[0]);
3210 for (Int_t j=0;j<6;j++){
3211 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3212 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3213 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3214 ny[j] = besttrack->GetNy(j);
3215 nz[j] = besttrack->GetNz(j);
3218 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3219 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3220 Float_t minn = besttrack->GetNumberOfClusters()-3;
3222 for (Int_t i=0;i<entries;i++){
3223 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3224 if (!track) continue;
3225 if (accepted>maxcut) break;
3226 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3227 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3228 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3229 delete array->RemoveAt(index[i]);
3233 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3234 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3235 if (!shortbest) accepted++;
3237 newarray->AddLast(array->RemoveAt(index[i]));
3238 for (Int_t j=0;j<6;j++){
3240 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3241 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3242 ny[j] = track->GetNy(j);
3243 nz[j] = track->GetNz(j);
3248 delete array->RemoveAt(index[i]);
3252 delete fTrackHypothesys.RemoveAt(esdindex);
3253 fTrackHypothesys.AddAt(newarray,esdindex);
3257 delete fTrackHypothesys.RemoveAt(esdindex);
3263 //------------------------------------------------------------------------
3264 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3266 //-------------------------------------------------------------
3267 // try to find best hypothesy
3268 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3269 //-------------------------------------------------------------
3270 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3271 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3272 if (!array) return 0;
3273 Int_t entries = array->GetEntriesFast();
3274 if (!entries) return 0;
3275 Float_t minchi2 = 100000;
3276 AliITStrackMI * besttrack=0;
3278 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3279 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3280 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3281 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3283 for (Int_t i=0;i<entries;i++){
3284 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3285 if (!track) continue;
3286 Float_t sigmarfi,sigmaz;
3287 GetDCASigma(track,sigmarfi,sigmaz);
3288 track->SetDnorm(0,sigmarfi);
3289 track->SetDnorm(1,sigmaz);
3291 track->SetChi2MIP(1,1000000);
3292 track->SetChi2MIP(2,1000000);
3293 track->SetChi2MIP(3,1000000);
3296 backtrack = new(backtrack) AliITStrackMI(*track);
3297 if (track->GetConstrain()) {
3298 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3299 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3300 backtrack->ResetCovariance(10.);
3302 backtrack->ResetCovariance(10.);
3304 backtrack->ResetClusters();
3306 Double_t x = original->GetX();
3307 if (!RefitAt(x,backtrack,track)) continue;
3309 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3310 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3311 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3312 track->SetChi22(GetMatchingChi2(backtrack,original));
3314 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3315 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3316 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3319 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3321 //forward track - without constraint
3322 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3323 forwardtrack->ResetClusters();
3325 RefitAt(x,forwardtrack,track);
3326 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3327 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3328 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3330 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3331 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3332 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3333 forwardtrack->SetD(0,track->GetD(0));
3334 forwardtrack->SetD(1,track->GetD(1));
3337 AliITSRecPoint* clist[6];
3338 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3339 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3342 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3343 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3344 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3345 track->SetChi2MIP(3,1000);
3348 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3350 for (Int_t ichi=0;ichi<5;ichi++){
3351 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3353 if (chi2 < minchi2){
3354 //besttrack = new AliITStrackMI(*forwardtrack);
3356 besttrack->SetLabel(track->GetLabel());
3357 besttrack->SetFakeRatio(track->GetFakeRatio());
3359 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3360 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3361 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3365 delete forwardtrack;
3367 for (Int_t i=0;i<entries;i++){
3368 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3370 if (!track) continue;
3372 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3373 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3374 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3375 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3376 delete array->RemoveAt(i);
3386 SortTrackHypothesys(esdindex,checkmax,1);
3388 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3389 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3390 besttrack = (AliITStrackMI*)array->At(0);
3391 if (!besttrack) return 0;
3392 besttrack->SetChi2MIP(8,0);
3393 fBestTrackIndex[esdindex]=0;
3394 entries = array->GetEntriesFast();
3395 AliITStrackMI *longtrack =0;
3397 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3398 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3399 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3400 if (!track->GetConstrain()) continue;
3401 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3402 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3403 if (track->GetChi2MIP(0)>4.) continue;
3404 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3407 //if (longtrack) besttrack=longtrack;
3410 AliITSRecPoint * clist[6];
3411 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3412 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3413 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3414 RegisterClusterTracks(besttrack,esdindex);
3421 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3422 if (sharedtrack>=0){
3424 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3426 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3432 if (shared>2.5) return 0;
3433 if (shared>1.0) return besttrack;
3435 // Don't sign clusters if not gold track
3437 if (!besttrack->IsGoldPrimary()) return besttrack;
3438 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3440 if (fConstraint[fPass]){
3444 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3445 for (Int_t i=0;i<6;i++){
3446 Int_t index = besttrack->GetClIndex(i);
3447 if (index<0) continue;
3448 Int_t ilayer = (index & 0xf0000000) >> 28;
3449 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3450 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3452 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3453 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3454 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3455 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3456 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3457 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3459 Bool_t cansign = kTRUE;
3460 for (Int_t itrack=0;itrack<entries; itrack++){
3461 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3462 if (!track) continue;
3463 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3464 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3470 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3471 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3472 if (!c->IsUsed()) c->Use();
3478 //------------------------------------------------------------------------
3479 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3482 // get "best" hypothesys
3485 Int_t nentries = itsTracks.GetEntriesFast();
3486 for (Int_t i=0;i<nentries;i++){
3487 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3488 if (!track) continue;
3489 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3490 if (!array) continue;
3491 if (array->GetEntriesFast()<=0) continue;
3493 AliITStrackMI* longtrack=0;
3495 Float_t maxchi2=1000;
3496 for (Int_t j=0;j<array->GetEntriesFast();j++){
3497 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3498 if (!trackHyp) continue;
3499 if (trackHyp->GetGoldV0()) {
3500 longtrack = trackHyp; //gold V0 track taken
3503 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3504 Float_t chi2 = trackHyp->GetChi2MIP(0);
3506 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3508 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3510 if (chi2 > maxchi2) continue;
3511 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3518 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3519 if (!longtrack) {longtrack = besttrack;}
3520 else besttrack= longtrack;
3524 AliITSRecPoint * clist[6];
3525 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3527 track->SetNUsed(shared);
3528 track->SetNSkipped(besttrack->GetNSkipped());
3529 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3531 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3535 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3536 //if (sharedtrack==-1) sharedtrack=0;
3537 if (sharedtrack>=0) {
3538 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3541 if (besttrack&&fAfterV0) {
3542 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3544 if (besttrack&&fConstraint[fPass])
3545 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3546 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3547 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3548 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3554 //------------------------------------------------------------------------
3555 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3556 //--------------------------------------------------------------------
3557 //This function "cooks" a track label. If label<0, this track is fake.
3558 //--------------------------------------------------------------------
3561 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3563 track->SetChi2MIP(9,0);
3565 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3566 Int_t cindex = track->GetClusterIndex(i);
3567 Int_t l=(cindex & 0xf0000000) >> 28;
3568 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3570 for (Int_t ind=0;ind<3;ind++){
3572 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3573 AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3575 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3578 Int_t nclusters = track->GetNumberOfClusters();
3579 if (nclusters > 0) //PH Some tracks don't have any cluster
3580 track->SetFakeRatio(double(nwrong)/double(nclusters));
3582 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3584 track->SetLabel(tpcLabel);
3586 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3589 //------------------------------------------------------------------------
3590 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3593 track->SetChi2MIP(9,0);
3594 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3595 Int_t cindex = track->GetClusterIndex(i);
3596 Int_t l=(cindex & 0xf0000000) >> 28;
3597 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3598 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3600 for (Int_t ind=0;ind<3;ind++){
3601 if (cl->GetLabel(ind)==lab) isWrong=0;
3603 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3607 track->CookdEdx(low,up);
3609 //------------------------------------------------------------------------
3610 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3612 // Create some arrays
3614 if (fCoefficients) delete []fCoefficients;
3615 fCoefficients = new Float_t[ntracks*48];
3616 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3618 //------------------------------------------------------------------------
3619 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3622 // Compute predicted chi2
3625 Float_t theta = track->GetTgl();
3626 Float_t phi = track->GetSnp();
3627 phi = TMath::Abs(phi)*TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3628 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz);
3629 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()));
3630 // Take into account the mis-alignment (bring track to cluster plane)
3631 Double_t xTrOrig=track->GetX();
3632 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3633 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()));
3634 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz);
3635 // Bring the track back to detector plane in ideal geometry
3636 // [mis-alignment will be accounted for in UpdateMI()]
3637 if (!track->Propagate(xTrOrig)) return 1000.;
3639 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3640 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3642 chi2+=0.5*TMath::Min(delta/2,2.);
3643 chi2+=2.*cluster->GetDeltaProbability();
3646 track->SetNy(layer,ny);
3647 track->SetNz(layer,nz);
3648 track->SetSigmaY(layer,erry);
3649 track->SetSigmaZ(layer, errz);
3650 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3651 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3655 //------------------------------------------------------------------------
3656 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3661 Int_t layer = (index & 0xf0000000) >> 28;
3662 track->SetClIndex(layer, index);
3663 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3664 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3665 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3666 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3670 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3673 // Take into account the mis-alignment (bring track to cluster plane)
3674 Double_t xTrOrig=track->GetX();
3675 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3676 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3677 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3678 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3680 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3684 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3685 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3688 Int_t updated = track->UpdateMI(&c,chi2,index);
3690 // Bring the track back to detector plane in ideal geometry
3691 if (!track->Propagate(xTrOrig)) return 0;
3693 if(!updated) AliDebug(2,"update failed");
3697 //------------------------------------------------------------------------
3698 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3701 //DCA sigmas parameterization
3702 //to be paramterized using external parameters in future
3705 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3706 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3708 //------------------------------------------------------------------------
3709 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3712 // Clusters from delta electrons?
3714 Int_t entries = clusterArray->GetEntriesFast();
3715 if (entries<4) return;
3716 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3717 Int_t layer = cluster->GetLayer();
3718 if (layer>1) return;
3720 Int_t ncandidates=0;
3721 Float_t r = (layer>0)? 7:4;
3723 for (Int_t i=0;i<entries;i++){
3724 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3725 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3726 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3727 index[ncandidates] = i; //candidate to belong to delta electron track
3729 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3730 cl0->SetDeltaProbability(1);
3736 for (Int_t i=0;i<ncandidates;i++){
3737 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3738 if (cl0->GetDeltaProbability()>0.8) continue;
3741 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3742 sumy=sumz=sumy2=sumyz=sumw=0.0;
3743 for (Int_t j=0;j<ncandidates;j++){
3745 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3747 Float_t dz = cl0->GetZ()-cl1->GetZ();
3748 Float_t dy = cl0->GetY()-cl1->GetY();
3749 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3750 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3751 y[ncl] = cl1->GetY();
3752 z[ncl] = cl1->GetZ();
3753 sumy+= y[ncl]*weight;
3754 sumz+= z[ncl]*weight;
3755 sumy2+=y[ncl]*y[ncl]*weight;
3756 sumyz+=y[ncl]*z[ncl]*weight;
3761 if (ncl<4) continue;
3762 Float_t det = sumw*sumy2 - sumy*sumy;
3764 if (TMath::Abs(det)>0.01){
3765 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3766 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3767 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3770 Float_t z0 = sumyz/sumy;
3771 delta = TMath::Abs(cl0->GetZ()-z0);
3774 cl0->SetDeltaProbability(1-20.*delta);
3778 //------------------------------------------------------------------------
3779 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3784 track->UpdateESDtrack(flags);
3785 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3786 if (oldtrack) delete oldtrack;
3787 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3788 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3789 printf("Problem\n");
3792 //------------------------------------------------------------------------
3793 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3795 // Get nearest upper layer close to the point xr.
3796 // rough approximation
3798 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3799 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3801 for (Int_t i=0;i<6;i++){
3802 if (radius<kRadiuses[i]){
3809 //------------------------------------------------------------------------
3810 void AliITStrackerMI::BuildMaterialLUT(TString material) {
3811 //--------------------------------------------------------------------
3812 // Fill a look-up table with mean material
3813 //--------------------------------------------------------------------
3817 Double_t point1[3],point2[3];
3818 Double_t phi,cosphi,sinphi,z;
3819 // 0-5 layers, 6 pipe, 7-8 shields
3820 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
3821 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
3823 Int_t ifirst=0,ilast=0;
3824 if(material.Contains("Pipe")) {
3826 } else if(material.Contains("Shields")) {
3828 } else if(material.Contains("Layers")) {
3831 Error("BuildMaterialLUT","Wrong layer name\n");
3834 for(Int_t imat=ifirst; imat<=ilast; imat++) {
3835 Double_t param[5]={0.,0.,0.,0.,0.};
3836 for (Int_t i=0; i<n; i++) {
3837 phi = 2.*TMath::Pi()*gRandom->Rndm();
3838 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
3839 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
3840 point1[0] = rmin[imat]*cosphi;
3841 point1[1] = rmin[imat]*sinphi;
3843 point2[0] = rmax[imat]*cosphi;
3844 point2[1] = rmax[imat]*sinphi;
3846 AliTracker::MeanMaterialBudget(point1,point2,mparam);
3847 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
3849 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
3851 fxOverX0Layer[imat] = param[1];
3852 fxTimesRhoLayer[imat] = param[0]*param[4];
3853 } else if(imat==6) {
3854 fxOverX0Pipe = param[1];
3855 fxTimesRhoPipe = param[0]*param[4];
3856 } else if(imat==7) {
3857 fxOverX0Shield[0] = param[1];
3858 fxTimesRhoShield[0] = param[0]*param[4];
3859 } else if(imat==8) {
3860 fxOverX0Shield[1] = param[1];
3861 fxTimesRhoShield[1] = param[0]*param[4];
3865 printf("%s\n",material.Data());
3866 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
3867 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
3868 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
3869 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
3870 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
3871 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
3872 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
3873 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
3874 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
3878 //------------------------------------------------------------------------
3879 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
3880 TString direction) {
3881 //-------------------------------------------------------------------
3882 // Propagate beyond beam pipe and correct for material
3883 // (material budget in different ways according to fUseTGeo value)
3884 // Add time if going outward (PropagateTo or PropagateToTGeo)
3885 //-------------------------------------------------------------------
3887 // Define budget mode:
3888 // 0: material from AliITSRecoParam (hard coded)
3889 // 1: material from TGeo in one step (on the fly)
3890 // 2: material from lut
3891 // 3: material from TGeo in one step (same for all hypotheses)
3904 if(fTrackingPhase.Contains("Clusters2Tracks"))
3905 { mode=3; } else { mode=1; }
3908 if(fTrackingPhase.Contains("Clusters2Tracks"))
3909 { mode=3; } else { mode=2; }
3915 if(fTrackingPhase.Contains("Default")) mode=0;
3917 Int_t index=fCurrentEsdTrack;
3919 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
3920 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
3922 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
3924 Double_t xOverX0,x0,lengthTimesMeanDensity;
3928 xOverX0 = AliITSRecoParam::GetdPipe();
3929 x0 = AliITSRecoParam::GetX0Be();
3930 lengthTimesMeanDensity = xOverX0*x0;
3931 lengthTimesMeanDensity *= dir;
3932 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3935 if (!t->PropagateToTGeo(xToGo,1)) return 0;
3938 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
3939 xOverX0 = fxOverX0Pipe;
3940 lengthTimesMeanDensity = fxTimesRhoPipe;
3941 lengthTimesMeanDensity *= dir;
3942 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3945 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
3946 if(fxOverX0PipeTrks[index]<0) {
3947 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
3948 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
3949 ((1.-t->GetSnp())*(1.+t->GetSnp())));
3950 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
3951 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
3954 xOverX0 = fxOverX0PipeTrks[index];
3955 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
3956 lengthTimesMeanDensity *= dir;
3957 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3963 //------------------------------------------------------------------------
3964 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
3966 TString direction) {
3967 //-------------------------------------------------------------------
3968 // Propagate beyond SPD or SDD shield and correct for material
3969 // (material budget in different ways according to fUseTGeo value)
3970 // Add time if going outward (PropagateTo or PropagateToTGeo)
3971 //-------------------------------------------------------------------
3973 // Define budget mode:
3974 // 0: material from AliITSRecoParam (hard coded)
3975 // 1: material from TGeo in steps of X cm (on the fly)
3976 // X = AliITSRecoParam::GetStepSizeTGeo()
3977 // 2: material from lut
3978 // 3: material from TGeo in one step (same for all hypotheses)
3991 if(fTrackingPhase.Contains("Clusters2Tracks"))
3992 { mode=3; } else { mode=1; }
3995 if(fTrackingPhase.Contains("Clusters2Tracks"))
3996 { mode=3; } else { mode=2; }
4002 if(fTrackingPhase.Contains("Default")) mode=0;
4004 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4006 Int_t shieldindex=0;
4007 if (shield.Contains("SDD")) { // SDDouter
4008 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4010 } else if (shield.Contains("SPD")) { // SPDouter
4011 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4014 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4018 // do nothing if we are already beyond the shield
4019 Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4020 if(dir<0 && rTrack > rToGo) return 1; // going outward
4021 if(dir>0 && rTrack < rToGo) return 1; // going inward
4025 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4027 Int_t index=2*fCurrentEsdTrack+shieldindex;
4029 Double_t xOverX0,x0,lengthTimesMeanDensity;
4034 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4035 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4036 lengthTimesMeanDensity = xOverX0*x0;
4037 lengthTimesMeanDensity *= dir;
4038 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4041 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4042 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4045 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4046 xOverX0 = fxOverX0Shield[shieldindex];
4047 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4048 lengthTimesMeanDensity *= dir;
4049 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4052 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4053 if(fxOverX0ShieldTrks[index]<0) {
4054 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4055 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4056 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4057 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4058 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4061 xOverX0 = fxOverX0ShieldTrks[index];
4062 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4063 lengthTimesMeanDensity *= dir;
4064 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4070 //------------------------------------------------------------------------
4071 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4073 Double_t oldGlobXYZ[3],
4074 TString direction) {
4075 //-------------------------------------------------------------------
4076 // Propagate beyond layer and correct for material
4077 // (material budget in different ways according to fUseTGeo value)
4078 // Add time if going outward (PropagateTo or PropagateToTGeo)
4079 //-------------------------------------------------------------------
4081 // Define budget mode:
4082 // 0: material from AliITSRecoParam (hard coded)
4083 // 1: material from TGeo in stepsof X cm (on the fly)
4084 // X = AliITSRecoParam::GetStepSizeTGeo()
4085 // 2: material from lut
4086 // 3: material from TGeo in one step (same for all hypotheses)
4099 if(fTrackingPhase.Contains("Clusters2Tracks"))
4100 { mode=3; } else { mode=1; }
4103 if(fTrackingPhase.Contains("Clusters2Tracks"))
4104 { mode=3; } else { mode=2; }
4110 if(fTrackingPhase.Contains("Default")) mode=0;
4112 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4114 Double_t r=fgLayers[layerindex].GetR();
4115 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4117 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4119 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4121 Int_t index=6*fCurrentEsdTrack+layerindex;
4124 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4127 // back before material (no correction)
4129 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4130 if (!t->GetLocalXat(rOld,xOld)) return 0;
4131 if (!t->Propagate(xOld)) return 0;
4135 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4136 lengthTimesMeanDensity = xOverX0*x0;
4137 lengthTimesMeanDensity *= dir;
4138 // Bring the track beyond the material
4139 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4142 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4143 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4146 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4147 xOverX0 = fxOverX0Layer[layerindex];
4148 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4149 lengthTimesMeanDensity *= dir;
4150 // Bring the track beyond the material
4151 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4154 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4155 if(fxOverX0LayerTrks[index]<0) {
4156 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4157 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4158 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4159 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4160 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4161 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4164 xOverX0 = fxOverX0LayerTrks[index];
4165 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4166 lengthTimesMeanDensity *= dir;
4167 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4174 //------------------------------------------------------------------------
4175 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4176 //-----------------------------------------------------------------
4177 // Initialize LUT for storing material for each prolonged track
4178 //-----------------------------------------------------------------
4179 fxOverX0PipeTrks = new Float_t[ntracks];
4180 fxTimesRhoPipeTrks = new Float_t[ntracks];
4181 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4182 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4183 fxOverX0LayerTrks = new Float_t[ntracks*6];
4184 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4186 for(Int_t i=0; i<ntracks; i++) {
4187 fxOverX0PipeTrks[i] = -1.;
4188 fxTimesRhoPipeTrks[i] = -1.;
4190 for(Int_t j=0; j<ntracks*2; j++) {
4191 fxOverX0ShieldTrks[j] = -1.;
4192 fxTimesRhoShieldTrks[j] = -1.;
4194 for(Int_t k=0; k<ntracks*6; k++) {
4195 fxOverX0LayerTrks[k] = -1.;
4196 fxTimesRhoLayerTrks[k] = -1.;
4203 //------------------------------------------------------------------------
4204 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4205 //-----------------------------------------------------------------
4206 // Delete LUT for storing material for each prolonged track
4207 //-----------------------------------------------------------------
4208 if(fxOverX0PipeTrks) {
4209 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4211 if(fxOverX0ShieldTrks) {
4212 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4215 if(fxOverX0LayerTrks) {
4216 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4218 if(fxTimesRhoPipeTrks) {
4219 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4221 if(fxTimesRhoShieldTrks) {
4222 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4224 if(fxTimesRhoLayerTrks) {
4225 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4229 //------------------------------------------------------------------------
4230 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4231 Int_t ilayer,Int_t idet) const {
4232 //-----------------------------------------------------------------
4233 // This method is used to decide whether to allow a prolongation
4234 // without clusters, because we want to skip the layer.
4235 // In this case the return value is > 0:
4236 // return 1: the user requested to skip a layer
4237 // return 2: track outside z acceptance of SSD/SDD and will cross both SPD
4238 //-----------------------------------------------------------------
4240 if (AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) return 1;
4242 if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4243 // check if track will cross SPD outer layer
4244 Double_t phiAtSPD2,zAtSPD2;
4245 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4246 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4252 //------------------------------------------------------------------------
4253 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4254 Int_t ilayer,Int_t idet,
4255 Double_t dz,Double_t dy,
4256 Bool_t noClusters) const {
4257 //-----------------------------------------------------------------
4258 // This method is used to decide whether to allow a prolongation
4259 // without clusters, because there is a dead zone in the road.
4260 // In this case the return value is > 0:
4261 // return 1: dead zone at z=0,+-7cm in SPD
4262 // return 2: all road is "bad" (dead or noisy) from the OCDB
4263 // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4264 // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4265 //-----------------------------------------------------------------
4267 // check dead zones at z=0,+-7cm in the SPD
4268 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4269 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4270 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4271 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4272 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4273 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4274 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4275 for (Int_t i=0; i<3; i++)
4276 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4277 AliDebug(2,Form("crack SPD %d",ilayer));
4282 // check bad zones from OCDB
4283 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4285 if (idet<0) return 0;
4287 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4290 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4291 if (ilayer==0 || ilayer==1) { // ---------- SPD
4293 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4295 detSizeFactorX *= 2.;
4296 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4299 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4300 if (detType==2) segm->SetLayer(ilayer+1);
4301 Float_t detSizeX = detSizeFactorX*segm->Dx();
4302 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4304 // check if the road overlaps with bad chips
4306 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
4307 Float_t zlocmin = zloc-dz;
4308 Float_t zlocmax = zloc+dz;
4309 Float_t xlocmin = xloc-dy;
4310 Float_t xlocmax = xloc+dy;
4311 Int_t chipsInRoad[100];
4313 // check if road goes out of detector
4314 Bool_t touchNeighbourDet=kFALSE;
4315 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.5*detSizeX; touchNeighbourDet=kTRUE;}
4316 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.5*detSizeX; touchNeighbourDet=kTRUE;}
4317 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.5*detSizeZ; touchNeighbourDet=kTRUE;}
4318 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.5*detSizeZ; touchNeighbourDet=kTRUE;}
4319 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));
4321 // check if this detector is bad
4323 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4324 if(!touchNeighbourDet) {
4325 return 2; // all detectors in road are bad
4327 return 3; // at least one is bad
4331 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4332 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4333 if (!nChipsInRoad) return 0;
4335 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4336 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4337 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4338 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4339 if (det.IsChipBad(chipsInRoad[iCh])) {
4347 if(!touchNeighbourDet) {
4348 AliDebug(2,"all bad in road");
4349 return 2; // all chips in road are bad
4351 return 3; // at least a bad chip in road
4356 AliDebug(2,"at least a bad in road");
4357 return 3; // at least a bad chip in road
4361 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4362 || !noClusters) return 0;
4364 // There are no clusters in road: check if there is at least
4365 // a bad SPD pixel or SDD anode or SSD strips on both sides
4367 Int_t idetInITS=idet;
4368 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4370 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4371 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4374 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4378 //------------------------------------------------------------------------
4379 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4380 const AliITStrackMI *track,
4381 Float_t &xloc,Float_t &zloc) const {
4382 //-----------------------------------------------------------------
4383 // Gives position of track in local module ref. frame
4384 //-----------------------------------------------------------------
4389 if(idet<0) return kFALSE;
4391 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4393 Int_t lad = Int_t(idet/ndet) + 1;
4395 Int_t det = idet - (lad-1)*ndet + 1;
4397 Double_t xyzGlob[3],xyzLoc[3];
4399 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4400 // take into account the misalignment: xyz at real detector plane
4401 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4403 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4405 xloc = (Float_t)xyzLoc[0];
4406 zloc = (Float_t)xyzLoc[2];
4410 //------------------------------------------------------------------------
4411 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
4413 // Method to be optimized further:
4414 // Aim: decide whether a track can be used for PlaneEff evaluation
4415 // the decision is taken based on the track quality at the layer under study
4416 // no information on the clusters on this layer has to be used
4417 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4418 // the cut is done on number of sigmas from the boundaries
4420 // Input: Actual track, layer [0,5] under study
4422 // Return: kTRUE if this is a good track
4424 // it will apply a pre-selection to obtain good quality tracks.
4425 // Here also you will have the possibility to put a control on the
4426 // impact point of the track on the basic block, in order to exclude border regions
4427 // this will be done by calling a proper method of the AliITSPlaneEff class.
4429 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4430 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4432 Int_t index[AliITSgeomTGeo::kNLayers];
4434 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4436 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4437 index[k]=clusters[k];
4441 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4442 AliITSlayer &layer=fgLayers[ilayer];
4443 Double_t r=layer.GetR();
4444 AliITStrackMI tmp(*track);
4446 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4448 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) {
4449 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4450 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4451 if (tmp.GetClIndex(lay)>=0) ncl++;
4453 Bool_t nextout = kFALSE;
4454 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4455 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4456 Bool_t nextin = kFALSE;
4457 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4458 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4459 if(ncl<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
4461 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
4462 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
4463 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
4464 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
4468 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4469 Int_t idet=layer.FindDetectorIndex(phi,z);
4470 if(idet<0) { AliInfo(Form("cannot find detector"));
4473 // here check if it has good Chi Square.
4475 //propagate to the intersection with the detector plane
4476 const AliITSdetector &det=layer.GetDetector(idet);
4477 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4481 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
4482 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4483 if(key>fPlaneEff->Nblock()) return kFALSE;
4484 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4485 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4487 // DEFINITION OF SEARCH ROAD FOR accepting a track
4489 //For the time being they are hard-wired, later on from AliITSRecoParam
4490 // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
4491 // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
4494 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4495 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4496 // done for RecPoints
4498 // exclude tracks at boundary between detectors
4499 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
4500 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4501 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
4502 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
4503 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
4505 if ( (locx-dx < blockXmn+boundaryWidth) ||
4506 (locx+dx > blockXmx-boundaryWidth) ||
4507 (locz-dz < blockZmn+boundaryWidth) ||
4508 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
4511 //------------------------------------------------------------------------
4512 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
4514 // This Method has to be optimized! For the time-being it uses the same criteria
4515 // as those used in the search of extra clusters for overlapping modules.
4517 // Method Purpose: estabilish whether a track has produced a recpoint or not
4518 // in the layer under study (For Plane efficiency)
4520 // inputs: AliITStrackMI* track (pointer to a usable track)
4522 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
4523 // traversed by this very track. In details:
4524 // - if a cluster can be associated to the track then call
4525 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
4526 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
4529 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
4530 AliITSlayer &layer=fgLayers[ilayer];
4531 Double_t r=layer.GetR();
4532 AliITStrackMI tmp(*track);
4536 if (!tmp.GetPhiZat(r,phi,z)) return;
4537 Int_t idet=layer.FindDetectorIndex(phi,z);
4539 if(idet<0) { AliInfo(Form("cannot find detector"));
4543 //propagate to the intersection with the detector plane
4544 const AliITSdetector &det=layer.GetDetector(idet);
4545 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
4549 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
4551 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
4552 TMath::Sqrt(tmp.GetSigmaZ2() +
4553 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4554 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4555 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
4556 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
4557 TMath::Sqrt(tmp.GetSigmaY2() +
4558 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4559 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4560 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
4562 // road in global (rphi,z) [i.e. in tracking ref. system]
4563 Double_t zmin = tmp.GetZ() - dz;
4564 Double_t zmax = tmp.GetZ() + dz;
4565 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
4566 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
4568 // select clusters in road
4569 layer.SelectClusters(zmin,zmax,ymin,ymax);
4571 // Define criteria for track-cluster association
4572 Double_t msz = tmp.GetSigmaZ2() +
4573 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4574 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4575 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
4576 Double_t msy = tmp.GetSigmaY2() +
4577 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4578 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4579 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
4580 if (tmp.GetConstrain()) {
4581 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
4582 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
4584 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
4585 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
4587 msz = 1./msz; // 1/RoadZ^2
4588 msy = 1./msy; // 1/RoadY^2
4591 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
4593 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
4594 //Double_t tolerance=0.2;
4595 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
4596 idetc = cl->GetDetectorIndex();
4597 if(idet!=idetc) continue;
4598 //Int_t ilay = cl->GetLayer();
4600 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
4601 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
4603 Double_t chi2=tmp.GetPredictedChi2(cl);
4604 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
4608 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
4610 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
4611 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4612 if(key>fPlaneEff->Nblock()) return;
4613 Bool_t found=kFALSE;
4616 while ((cl=layer.GetNextCluster(clidx))!=0) {
4617 idetc = cl->GetDetectorIndex();
4618 if(idet!=idetc) continue;
4619 // here real control to see whether the cluster can be associated to the track.
4620 // cluster not associated to track
4621 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
4622 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
4623 // calculate track-clusters chi2
4624 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
4625 // in particular, the error associated to the cluster
4626 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
4628 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
4630 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
4631 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
4632 // track->SetExtraModule(ilayer,idetExtra);
4634 if(!fPlaneEff->UpDatePlaneEff(found,key))
4635 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
4636 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
4637 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
4638 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
4639 Int_t cltype[2]={-999,-999};
4643 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4644 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4647 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
4648 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
4649 cltype[0]=layer.GetCluster(ci)->GetNy();
4650 cltype[1]=layer.GetCluster(ci)->GetNz();
4652 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
4653 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
4654 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
4655 // It is computed properly by calling the method
4656 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4658 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
4659 //if (tmp.PropagateTo(x,0.,0.)) {
4660 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
4661 AliCluster c(*layer.GetCluster(ci));
4662 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
4663 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
4664 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
4665 clu[2]=TMath::Sqrt(c.GetSigmaY2());
4666 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
4669 fPlaneEff->FillHistos(key,found,tr,clu,cltype);