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>
37 #include "AliITSPlaneEff.h"
38 #include "AliITSCalibrationSPD.h"
39 #include "AliITSCalibrationSDD.h"
40 #include "AliITSCalibrationSSD.h"
41 #include "AliCDBEntry.h"
42 #include "AliCDBManager.h"
43 #include "AliAlignObj.h"
44 #include "AliTrackPointArray.h"
45 #include "AliESDVertex.h"
46 #include "AliESDEvent.h"
47 #include "AliESDtrack.h"
50 #include "AliITSChannelStatus.h"
51 #include "AliITSDetTypeRec.h"
52 #include "AliITSRecPoint.h"
53 #include "AliITSgeomTGeo.h"
54 #include "AliITSReconstructor.h"
55 #include "AliITSClusterParam.h"
56 #include "AliITSsegmentation.h"
57 #include "AliITSCalibration.h"
58 #include "AliITSPlaneEffSPD.h"
59 #include "AliITSPlaneEffSDD.h"
60 #include "AliITSPlaneEffSSD.h"
61 #include "AliITSV0Finder.h"
62 #include "AliITStrackerMI.h"
64 ClassImp(AliITStrackerMI)
66 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
68 AliITStrackerMI::AliITStrackerMI():AliTracker(),
78 fLastLayerToTrackTo(0),
81 fTrackingPhase("Default"),
87 fxTimesRhoPipeTrks(0),
88 fxOverX0ShieldTrks(0),
89 fxTimesRhoShieldTrks(0),
91 fxTimesRhoLayerTrks(0),
98 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
99 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
100 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
102 //------------------------------------------------------------------------
103 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
104 fI(AliITSgeomTGeo::GetNLayers()),
113 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
116 fTrackingPhase("Default"),
122 fxTimesRhoPipeTrks(0),
123 fxOverX0ShieldTrks(0),
124 fxTimesRhoShieldTrks(0),
125 fxOverX0LayerTrks(0),
126 fxTimesRhoLayerTrks(0),
128 fITSChannelStatus(0),
131 //--------------------------------------------------------------------
132 //This is the AliITStrackerMI constructor
133 //--------------------------------------------------------------------
135 AliWarning("\"geom\" is actually a dummy argument !");
141 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
142 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
143 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
145 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
146 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
147 Double_t poff=TMath::ATan2(y,x);
149 Double_t r=TMath::Sqrt(x*x + y*y);
151 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
152 r += TMath::Sqrt(x*x + y*y);
153 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
154 r += TMath::Sqrt(x*x + y*y);
155 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
156 r += TMath::Sqrt(x*x + y*y);
159 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
161 for (Int_t j=1; j<nlad+1; j++) {
162 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
163 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
164 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
166 Double_t txyz[3]={0.};
167 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
168 m.LocalToMaster(txyz,xyz);
169 r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
170 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
172 if (phi<0) phi+=TMath::TwoPi();
173 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
175 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
176 new(&det) AliITSdetector(r,phi);
177 // compute the real radius (with misalignment)
178 TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
180 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
181 mmisal.LocalToMaster(txyz,xyz);
182 Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
183 det.SetRmisal(rmisal);
185 } // end loop on detectors
186 } // end loop on ladders
187 fForceSkippingOfLayer[i] = 0;
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 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
205 for (Int_t i=0;i<100000;i++){
206 fBestTrackIndex[i]=0;
209 // store positions of centre of SPD modules (in z)
211 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
212 fSPDdetzcentre[0] = tr[2];
213 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
214 fSPDdetzcentre[1] = tr[2];
215 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
216 fSPDdetzcentre[2] = tr[2];
217 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
218 fSPDdetzcentre[3] = tr[2];
220 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
221 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
222 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
226 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
227 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
229 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
231 // only for plane efficiency evaluation
232 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
233 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
234 Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
235 if(!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)==1)
236 AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
237 if (iplane<2) fPlaneEff = new AliITSPlaneEffSPD();
238 else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
239 else fPlaneEff = new AliITSPlaneEffSSD();
240 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
241 if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
242 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
245 //------------------------------------------------------------------------
246 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
248 fBestTrack(tracker.fBestTrack),
249 fTrackToFollow(tracker.fTrackToFollow),
250 fTrackHypothesys(tracker.fTrackHypothesys),
251 fBestHypothesys(tracker.fBestHypothesys),
252 fOriginal(tracker.fOriginal),
253 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
254 fPass(tracker.fPass),
255 fAfterV0(tracker.fAfterV0),
256 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
257 fCoefficients(tracker.fCoefficients),
259 fTrackingPhase(tracker.fTrackingPhase),
260 fUseTGeo(tracker.fUseTGeo),
261 fNtracks(tracker.fNtracks),
262 fxOverX0Pipe(tracker.fxOverX0Pipe),
263 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
265 fxTimesRhoPipeTrks(0),
266 fxOverX0ShieldTrks(0),
267 fxTimesRhoShieldTrks(0),
268 fxOverX0LayerTrks(0),
269 fxTimesRhoLayerTrks(0),
270 fDebugStreamer(tracker.fDebugStreamer),
271 fITSChannelStatus(tracker.fITSChannelStatus),
272 fkDetTypeRec(tracker.fkDetTypeRec),
273 fPlaneEff(tracker.fPlaneEff) {
277 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
280 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
281 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
284 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
285 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
288 //------------------------------------------------------------------------
289 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
290 //Assignment operator
291 this->~AliITStrackerMI();
292 new(this) AliITStrackerMI(tracker);
295 //------------------------------------------------------------------------
296 AliITStrackerMI::~AliITStrackerMI()
301 if (fCoefficients) delete [] fCoefficients;
302 DeleteTrksMaterialLUT();
303 if (fDebugStreamer) {
304 //fDebugStreamer->Close();
305 delete fDebugStreamer;
307 if(fITSChannelStatus) delete fITSChannelStatus;
308 if(fPlaneEff) delete fPlaneEff;
310 //------------------------------------------------------------------------
311 void AliITStrackerMI::ReadBadFromDetTypeRec() {
312 //--------------------------------------------------------------------
313 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
315 //--------------------------------------------------------------------
317 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
319 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
321 if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
324 if(fITSChannelStatus) delete fITSChannelStatus;
325 fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
327 // ITS detectors and chips
328 Int_t i=0,j=0,k=0,ndet=0;
329 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
330 Int_t nBadDetsPerLayer=0;
331 ndet=AliITSgeomTGeo::GetNDetectors(i);
332 for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
333 for (k=1; k<ndet+1; k++) {
334 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
335 det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fkDetTypeRec);
336 if(det.IsBad()) {nBadDetsPerLayer++;}
337 } // end loop on detectors
338 } // end loop on ladders
339 Info("ReadBadFromDetTypeRec",Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
340 } // end loop on layers
344 //------------------------------------------------------------------------
345 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
346 //--------------------------------------------------------------------
347 //This function loads ITS clusters
348 //--------------------------------------------------------------------
349 TBranch *branch=cTree->GetBranch("ITSRecPoints");
351 Error("LoadClusters"," can't get the branch !\n");
355 static TClonesArray dummy("AliITSRecPoint",10000), *clusters=&dummy;
356 branch->SetAddress(&clusters);
358 Int_t i=0,j=0,ndet=0;
360 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
361 ndet=fgLayers[i].GetNdetectors();
362 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
363 for (; j<jmax; j++) {
364 if (!cTree->GetEvent(j)) continue;
365 Int_t ncl=clusters->GetEntriesFast();
366 SignDeltas(clusters,GetZ());
369 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
370 detector=c->GetDetectorIndex();
372 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
374 fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
377 // add dead zone "virtual" cluster in SPD, if there is a cluster within
378 // zwindow cm from the dead zone
379 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
380 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
381 Int_t lab[4] = {0,0,0,detector};
382 Int_t info[3] = {0,0,i};
383 Float_t q = 0.; // this identifies virtual clusters
384 Float_t hit[5] = {xdead,
386 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
387 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
389 Bool_t local = kTRUE;
390 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
391 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
392 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
393 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
394 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
395 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
396 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
397 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
398 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
399 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
400 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
401 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
402 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
403 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
404 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
405 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
406 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
407 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
408 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
410 } // "virtual" clusters in SPD
414 fgLayers[i].ResetRoad(); //road defined by the cluster density
415 fgLayers[i].SortClusters();
420 // check whether we have to skip some layers
421 SetForceSkippingOfLayer();
425 //------------------------------------------------------------------------
426 void AliITStrackerMI::UnloadClusters() {
427 //--------------------------------------------------------------------
428 //This function unloads ITS clusters
429 //--------------------------------------------------------------------
430 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
432 //------------------------------------------------------------------------
433 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
434 //--------------------------------------------------------------------
435 // Publishes all pointers to clusters known to the tracker into the
436 // passed object array.
437 // The ownership is not transfered - the caller is not expected to delete
439 //--------------------------------------------------------------------
441 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
442 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
443 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
450 //------------------------------------------------------------------------
451 Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
452 //--------------------------------------------------------------------
453 // Correction for the material between the TPC and the ITS
454 //--------------------------------------------------------------------
455 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
456 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
457 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
458 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
459 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
460 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
461 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
462 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
464 printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
470 //------------------------------------------------------------------------
471 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
472 //--------------------------------------------------------------------
473 // This functions reconstructs ITS tracks
474 // The clusters must be already loaded !
475 //--------------------------------------------------------------------
477 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
479 fTrackingPhase="Clusters2Tracks";
481 TObjArray itsTracks(15000);
483 fEsd = event; // store pointer to the esd
485 // temporary (for cosmics)
486 if(event->GetVertex()) {
487 TString title = event->GetVertex()->GetTitle();
488 if(title.Contains("cosmics")) {
489 Double_t xyz[3]={GetX(),GetY(),GetZ()};
490 Double_t exyz[3]={0.1,0.1,0.1};
496 {/* Read ESD tracks */
497 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
498 Int_t nentr=event->GetNumberOfTracks();
499 Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
501 AliESDtrack *esd=event->GetTrack(nentr);
502 // ---- for debugging:
503 //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); }
505 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
506 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
507 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
508 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
511 t=new AliITStrackMI(*esd);
512 } catch (const Char_t *msg) {
513 //Warning("Clusters2Tracks",msg);
517 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
518 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
521 // look at the ESD mass hypothesys !
522 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
524 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
526 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
527 //track - can be V0 according to TPC
529 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
533 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
537 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
541 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
546 t->SetReconstructed(kFALSE);
547 itsTracks.AddLast(t);
548 fOriginal.AddLast(t);
550 } /* End Read ESD tracks */
554 Int_t nentr=itsTracks.GetEntriesFast();
555 fTrackHypothesys.Expand(nentr);
556 fBestHypothesys.Expand(nentr);
557 MakeCoefficients(nentr);
558 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
560 // THE TWO TRACKING PASSES
561 for (fPass=0; fPass<2; fPass++) {
562 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
563 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
564 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
565 if (t==0) continue; //this track has been already tracked
566 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
567 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
568 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
569 if (fConstraint[fPass]) {
570 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
571 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
574 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
575 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
577 ResetTrackToFollow(*t);
580 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
583 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
585 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
586 if (!besttrack) continue;
587 besttrack->SetLabel(tpcLabel);
588 // besttrack->CookdEdx();
590 besttrack->SetFakeRatio(1.);
591 CookLabel(besttrack,0.); //For comparison only
592 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
594 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
596 t->SetReconstructed(kTRUE);
598 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
600 GetBestHypothesysMIP(itsTracks);
601 } // end loop on the two tracking passes
603 if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
604 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
609 Int_t entries = fTrackHypothesys.GetEntriesFast();
610 for (Int_t ientry=0; ientry<entries; ientry++) {
611 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
612 if (array) array->Delete();
613 delete fTrackHypothesys.RemoveAt(ientry);
616 fTrackHypothesys.Delete();
617 fBestHypothesys.Delete();
619 delete [] fCoefficients;
621 DeleteTrksMaterialLUT();
623 Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
625 fTrackingPhase="Default";
629 //------------------------------------------------------------------------
630 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
631 //--------------------------------------------------------------------
632 // This functions propagates reconstructed ITS tracks back
633 // The clusters must be loaded !
634 //--------------------------------------------------------------------
635 fTrackingPhase="PropagateBack";
636 Int_t nentr=event->GetNumberOfTracks();
637 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
640 for (Int_t i=0; i<nentr; i++) {
641 AliESDtrack *esd=event->GetTrack(i);
643 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
644 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
648 t=new AliITStrackMI(*esd);
649 } catch (const Char_t *msg) {
650 //Warning("PropagateBack",msg);
654 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
656 ResetTrackToFollow(*t);
659 // propagate to vertex [SR, GSI 17.02.2003]
660 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
661 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
662 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
663 fTrackToFollow.StartTimeIntegral();
664 // from vertex to outside pipe
665 CorrectForPipeMaterial(&fTrackToFollow,"outward");
667 // Start time integral and add distance from current position to vertex
668 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
669 fTrackToFollow.GetXYZ(xyzTrk);
671 for (Int_t icoord=0; icoord<3; icoord++) {
672 Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
675 fTrackToFollow.StartTimeIntegral();
676 fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
678 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
679 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
680 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
684 fTrackToFollow.SetLabel(t->GetLabel());
685 //fTrackToFollow.CookdEdx();
686 CookLabel(&fTrackToFollow,0.); //For comparison only
687 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
688 //UseClusters(&fTrackToFollow);
694 Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
696 fTrackingPhase="Default";
700 //------------------------------------------------------------------------
701 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
702 //--------------------------------------------------------------------
703 // This functions refits ITS tracks using the
704 // "inward propagated" TPC tracks
705 // The clusters must be loaded !
706 //--------------------------------------------------------------------
707 fTrackingPhase="RefitInward";
709 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
711 Int_t nentr=event->GetNumberOfTracks();
712 Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
715 for (Int_t i=0; i<nentr; i++) {
716 AliESDtrack *esd=event->GetTrack(i);
718 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
719 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
720 if (esd->GetStatus()&AliESDtrack::kTPCout)
721 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
725 t=new AliITStrackMI(*esd);
726 } catch (const Char_t *msg) {
727 //Warning("RefitInward",msg);
731 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
732 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
737 ResetTrackToFollow(*t);
738 fTrackToFollow.ResetClusters();
740 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
741 fTrackToFollow.ResetCovariance(10.);
744 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
745 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
747 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
748 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
749 AliDebug(2," refit OK");
750 fTrackToFollow.SetLabel(t->GetLabel());
751 // fTrackToFollow.CookdEdx();
752 CookdEdx(&fTrackToFollow);
754 CookLabel(&fTrackToFollow,0.0); //For comparison only
757 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
758 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
759 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
760 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
761 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
762 Double_t r[3]={0.,0.,0.};
764 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
771 Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
773 fTrackingPhase="Default";
777 //------------------------------------------------------------------------
778 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
779 //--------------------------------------------------------------------
780 // Return pointer to a given cluster
781 //--------------------------------------------------------------------
782 Int_t l=(index & 0xf0000000) >> 28;
783 Int_t c=(index & 0x0fffffff) >> 00;
784 return fgLayers[l].GetCluster(c);
786 //------------------------------------------------------------------------
787 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
788 //--------------------------------------------------------------------
789 // Get track space point with index i
790 //--------------------------------------------------------------------
792 Int_t l=(index & 0xf0000000) >> 28;
793 Int_t c=(index & 0x0fffffff) >> 00;
794 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
795 Int_t idet = cl->GetDetectorIndex();
799 cl->GetGlobalXYZ(xyz);
800 cl->GetGlobalCov(cov);
802 p.SetCharge(cl->GetQ());
803 p.SetDriftTime(cl->GetDriftTime());
804 p.SetChargeRatio(cl->GetChargeRatio());
805 p.SetClusterType(cl->GetClusterType());
806 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
809 iLayer = AliGeomManager::kSPD1;
812 iLayer = AliGeomManager::kSPD2;
815 iLayer = AliGeomManager::kSDD1;
818 iLayer = AliGeomManager::kSDD2;
821 iLayer = AliGeomManager::kSSD1;
824 iLayer = AliGeomManager::kSSD2;
827 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
830 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
831 p.SetVolumeID((UShort_t)volid);
834 //------------------------------------------------------------------------
835 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
836 AliTrackPoint& p, const AliESDtrack *t) {
837 //--------------------------------------------------------------------
838 // Get track space point with index i
839 // (assign error estimated during the tracking)
840 //--------------------------------------------------------------------
842 Int_t l=(index & 0xf0000000) >> 28;
843 Int_t c=(index & 0x0fffffff) >> 00;
844 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
845 Int_t idet = cl->GetDetectorIndex();
847 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
849 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
851 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
852 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
853 Double_t alpha = t->GetAlpha();
854 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
855 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,GetBz()));
856 phi += alpha-det.GetPhi();
857 Float_t tgphi = TMath::Tan(phi);
859 Float_t tgl = t->GetTgl(); // tgl about const along track
860 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
862 Float_t errtrky,errtrkz,covyz;
863 Bool_t addMisalErr=kFALSE;
864 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
868 cl->GetGlobalXYZ(xyz);
869 // cl->GetGlobalCov(cov);
870 Float_t pos[3] = {0.,0.,0.};
871 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
872 tmpcl.GetGlobalCov(cov);
875 p.SetCharge(cl->GetQ());
876 p.SetDriftTime(cl->GetDriftTime());
877 p.SetChargeRatio(cl->GetChargeRatio());
878 p.SetClusterType(cl->GetClusterType());
880 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
883 iLayer = AliGeomManager::kSPD1;
886 iLayer = AliGeomManager::kSPD2;
889 iLayer = AliGeomManager::kSDD1;
892 iLayer = AliGeomManager::kSDD2;
895 iLayer = AliGeomManager::kSSD1;
898 iLayer = AliGeomManager::kSSD2;
901 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
904 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
906 p.SetVolumeID((UShort_t)volid);
909 //------------------------------------------------------------------------
910 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
912 //--------------------------------------------------------------------
913 // Follow prolongation tree
914 //--------------------------------------------------------------------
916 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
917 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
920 AliESDtrack * esd = otrack->GetESDtrack();
921 if (esd->GetV0Index(0)>0) {
922 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
923 // mapping of ESD track is different as ITS track in Containers
924 // Need something more stable
925 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
926 for (Int_t i=0;i<3;i++){
927 Int_t index = esd->GetV0Index(i);
929 AliESDv0 * vertex = fEsd->GetV0(index);
930 if (vertex->GetStatus()<0) continue; // rejected V0
932 if (esd->GetSign()>0) {
933 vertex->SetIndex(0,esdindex);
935 vertex->SetIndex(1,esdindex);
939 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
941 bestarray = new TObjArray(5);
942 fBestHypothesys.AddAt(bestarray,esdindex);
946 //setup tree of the prolongations
948 static AliITStrackMI tracks[7][100];
949 AliITStrackMI *currenttrack;
950 static AliITStrackMI currenttrack1;
951 static AliITStrackMI currenttrack2;
952 static AliITStrackMI backuptrack;
954 Int_t nindexes[7][100];
955 Float_t normalizedchi2[100];
956 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
957 otrack->SetNSkipped(0);
958 new (&(tracks[6][0])) AliITStrackMI(*otrack);
960 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
961 Int_t modstatus = 1; // found
965 // follow prolongations
966 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
967 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
970 AliITSlayer &layer=fgLayers[ilayer];
971 Double_t r = layer.GetR();
977 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
979 if (ntracks[ilayer]>=100) break;
980 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
981 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
982 if (ntracks[ilayer]>15+ilayer){
983 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
984 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
987 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
989 // material between SSD and SDD, SDD and SPD
991 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
993 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
997 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
998 Int_t idet=layer.FindDetectorIndex(phi,z);
1000 Double_t trackGlobXYZ1[3];
1001 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1003 // Get the budget to the primary vertex for the current track being prolonged
1004 Double_t budgetToPrimVertex = GetEffectiveThickness();
1006 // check if we allow a prolongation without point
1007 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1009 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1010 // propagate to the layer radius
1011 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1012 if(!vtrack->Propagate(xToGo)) continue;
1013 // apply correction for material of the current layer
1014 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1015 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1016 vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1017 vtrack->SetClIndex(ilayer,-1);
1018 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1019 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1020 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1022 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1027 // track outside layer acceptance in z
1028 if (idet<0) continue;
1030 //propagate to the intersection with the detector plane
1031 const AliITSdetector &det=layer.GetDetector(idet);
1032 new(¤ttrack2) AliITStrackMI(currenttrack1);
1033 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1034 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1035 currenttrack1.SetDetectorIndex(idet);
1036 currenttrack2.SetDetectorIndex(idet);
1037 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1040 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1042 // road in global (rphi,z) [i.e. in tracking ref. system]
1043 Double_t zmin,zmax,ymin,ymax;
1044 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1046 // select clusters in road
1047 layer.SelectClusters(zmin,zmax,ymin,ymax);
1048 //********************
1050 // Define criteria for track-cluster association
1051 Double_t msz = currenttrack1.GetSigmaZ2() +
1052 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1053 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1054 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1055 Double_t msy = currenttrack1.GetSigmaY2() +
1056 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1057 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1058 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1060 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1061 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1063 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1064 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1066 msz = 1./msz; // 1/RoadZ^2
1067 msy = 1./msy; // 1/RoadY^2
1071 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1073 const AliITSRecPoint *cl=0;
1075 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1076 Bool_t deadzoneSPD=kFALSE;
1077 currenttrack = ¤ttrack1;
1079 // check if the road contains a dead zone
1080 Bool_t noClusters = kFALSE;
1081 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1082 if (noClusters) AliDebug(2,"no clusters in road");
1083 Double_t dz=0.5*(zmax-zmin);
1084 Double_t dy=0.5*(ymax-ymin);
1085 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1086 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1087 // create a prolongation without clusters (check also if there are no clusters in the road)
1090 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1091 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1092 updatetrack->SetClIndex(ilayer,-1);
1094 modstatus = 5; // no cls in road
1095 } else if (dead==1) {
1096 modstatus = 7; // holes in z in SPD
1097 } else if (dead==2 || dead==3 || dead==4) {
1098 modstatus = 2; // dead from OCDB
1100 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1101 // apply correction for material of the current layer
1102 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1103 if (constrain) { // apply vertex constrain
1104 updatetrack->SetConstrain(constrain);
1105 Bool_t isPrim = kTRUE;
1106 if (ilayer<4) { // check that it's close to the vertex
1107 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1108 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1109 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1110 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1111 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1113 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1115 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1117 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1118 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1120 } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1121 updatetrack->SetDeadZoneProbability(ilayer,1.);
1122 } else if (dead==4) { // at least a single dead channel from OCDB
1123 updatetrack->SetDeadZoneProbability(ilayer,0.);
1130 // loop over clusters in the road
1131 while ((cl=layer.GetNextCluster(clidx))!=0) {
1132 if (ntracks[ilayer]>95) break; //space for skipped clusters
1133 Bool_t changedet =kFALSE;
1134 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
1135 Int_t idetc=cl->GetDetectorIndex();
1137 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1138 // take into account misalignment (bring track to real detector plane)
1139 Double_t xTrOrig = currenttrack->GetX();
1140 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1141 // a first cut on track-cluster distance
1142 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1143 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1144 { // cluster not associated to track
1145 AliDebug(2,"not associated");
1148 // bring track back to ideal detector plane
1149 if (!currenttrack->Propagate(xTrOrig)) continue;
1150 } else { // have to move track to cluster's detector
1151 const AliITSdetector &detc=layer.GetDetector(idetc);
1152 // a first cut on track-cluster distance
1154 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1155 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1156 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1157 continue; // cluster not associated to track
1159 new (&backuptrack) AliITStrackMI(currenttrack2);
1161 currenttrack =¤ttrack2;
1162 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1163 new (currenttrack) AliITStrackMI(backuptrack);
1167 currenttrack->SetDetectorIndex(idetc);
1168 // Get again the budget to the primary vertex
1169 // for the current track being prolonged, if had to change detector
1170 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1173 // calculate track-clusters chi2
1174 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1176 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1177 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1178 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1179 if (ntracks[ilayer]>=100) continue;
1180 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1181 updatetrack->SetClIndex(ilayer,-1);
1182 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1184 if (cl->GetQ()!=0) { // real cluster
1185 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1186 AliDebug(2,"update failed");
1189 updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1190 modstatus = 1; // found
1191 } else { // virtual cluster in dead zone
1192 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1193 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1194 modstatus = 7; // holes in z in SPD
1198 Float_t xlocnewdet,zlocnewdet;
1199 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1200 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1203 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1205 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1207 // apply correction for material of the current layer
1208 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1210 if (constrain) { // apply vertex constrain
1211 updatetrack->SetConstrain(constrain);
1212 Bool_t isPrim = kTRUE;
1213 if (ilayer<4) { // check that it's close to the vertex
1214 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1215 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1216 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1217 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1218 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1220 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1221 } //apply vertex constrain
1223 } // create new hypothesis
1225 AliDebug(2,"chi2 too large");
1228 } // loop over possible prolongations
1230 // allow one prolongation without clusters
1231 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1232 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1233 // apply correction for material of the current layer
1234 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1235 vtrack->SetClIndex(ilayer,-1);
1236 modstatus = 3; // skipped
1237 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1238 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1239 vtrack->IncrementNSkipped();
1243 // allow one prolongation without clusters for tracks with |tgl|>1.1
1244 if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) { //big theta - for low flux
1245 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1246 // apply correction for material of the current layer
1247 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1248 vtrack->SetClIndex(ilayer,-1);
1249 modstatus = 3; // skipped
1250 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1251 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1252 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1257 } // loop over tracks in layer ilayer+1
1259 //loop over track candidates for the current layer
1265 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1266 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1267 if (normalizedchi2[itrack] <
1268 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1272 if (constrain) { // constrain
1273 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1275 } else { // !constrain
1276 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1281 // sort tracks by increasing normalized chi2
1282 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1283 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1284 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1285 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1286 } // end loop over layers
1290 // Now select tracks to be kept
1292 Int_t max = constrain ? 20 : 5;
1294 // tracks that reach layer 0 (SPD inner)
1295 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1296 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1297 if (track.GetNumberOfClusters()<2) continue;
1298 if (!constrain && track.GetNormChi2(0) >
1299 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1302 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1305 // tracks that reach layer 1 (SPD outer)
1306 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1307 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1308 if (track.GetNumberOfClusters()<4) continue;
1309 if (!constrain && track.GetNormChi2(1) >
1310 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1311 if (constrain) track.IncrementNSkipped();
1313 track.SetD(0,track.GetD(GetX(),GetY()));
1314 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1315 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1316 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1319 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1322 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1324 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1325 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1326 if (track.GetNumberOfClusters()<3) continue;
1327 if (!constrain && track.GetNormChi2(2) >
1328 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1329 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1331 track.SetD(0,track.GetD(GetX(),GetY()));
1332 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1333 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1334 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1337 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1343 // register best track of each layer - important for V0 finder
1345 for (Int_t ilayer=0;ilayer<5;ilayer++){
1346 if (ntracks[ilayer]==0) continue;
1347 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1348 if (track.GetNumberOfClusters()<1) continue;
1349 CookLabel(&track,0);
1350 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1354 // update TPC V0 information
1356 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1357 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1358 for (Int_t i=0;i<3;i++){
1359 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1360 if (index==0) break;
1361 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1362 if (vertex->GetStatus()<0) continue; // rejected V0
1364 if (otrack->GetSign()>0) {
1365 vertex->SetIndex(0,esdindex);
1368 vertex->SetIndex(1,esdindex);
1370 //find nearest layer with track info
1371 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1372 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1373 Int_t nearest = nearestold;
1374 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1375 if (ntracks[nearest]==0){
1380 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1381 if (nearestold<5&&nearest<5){
1382 Bool_t accept = track.GetNormChi2(nearest)<10;
1384 if (track.GetSign()>0) {
1385 vertex->SetParamP(track);
1386 vertex->Update(fprimvertex);
1387 //vertex->SetIndex(0,track.fESDtrack->GetID());
1388 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1390 vertex->SetParamN(track);
1391 vertex->Update(fprimvertex);
1392 //vertex->SetIndex(1,track.fESDtrack->GetID());
1393 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1395 vertex->SetStatus(vertex->GetStatus()+1);
1397 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1404 //------------------------------------------------------------------------
1405 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1407 //--------------------------------------------------------------------
1410 return fgLayers[layer];
1412 //------------------------------------------------------------------------
1413 AliITStrackerMI::AliITSlayer::AliITSlayer():
1443 //--------------------------------------------------------------------
1444 //default AliITSlayer constructor
1445 //--------------------------------------------------------------------
1446 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1447 fClusterWeight[i]=0;
1448 fClusterTracks[0][i]=-1;
1449 fClusterTracks[1][i]=-1;
1450 fClusterTracks[2][i]=-1;
1451 fClusterTracks[3][i]=-1;
1454 //------------------------------------------------------------------------
1455 AliITStrackerMI::AliITSlayer::
1456 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1485 //--------------------------------------------------------------------
1486 //main AliITSlayer constructor
1487 //--------------------------------------------------------------------
1488 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1489 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1491 //------------------------------------------------------------------------
1492 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1494 fPhiOffset(layer.fPhiOffset),
1495 fNladders(layer.fNladders),
1496 fZOffset(layer.fZOffset),
1497 fNdetectors(layer.fNdetectors),
1498 fDetectors(layer.fDetectors),
1503 fClustersCs(layer.fClustersCs),
1504 fClusterIndexCs(layer.fClusterIndexCs),
1508 fCurrentSlice(layer.fCurrentSlice),
1516 fAccepted(layer.fAccepted),
1518 fMaxSigmaClY(layer.fMaxSigmaClY),
1519 fMaxSigmaClZ(layer.fMaxSigmaClZ),
1520 fNMaxSigmaCl(layer.fNMaxSigmaCl)
1524 //------------------------------------------------------------------------
1525 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1526 //--------------------------------------------------------------------
1527 // AliITSlayer destructor
1528 //--------------------------------------------------------------------
1529 delete [] fDetectors;
1530 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1531 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1532 fClusterWeight[i]=0;
1533 fClusterTracks[0][i]=-1;
1534 fClusterTracks[1][i]=-1;
1535 fClusterTracks[2][i]=-1;
1536 fClusterTracks[3][i]=-1;
1539 //------------------------------------------------------------------------
1540 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1541 //--------------------------------------------------------------------
1542 // This function removes loaded clusters
1543 //--------------------------------------------------------------------
1544 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1545 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1546 fClusterWeight[i]=0;
1547 fClusterTracks[0][i]=-1;
1548 fClusterTracks[1][i]=-1;
1549 fClusterTracks[2][i]=-1;
1550 fClusterTracks[3][i]=-1;
1556 //------------------------------------------------------------------------
1557 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1558 //--------------------------------------------------------------------
1559 // This function reset weights of the clusters
1560 //--------------------------------------------------------------------
1561 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1562 fClusterWeight[i]=0;
1563 fClusterTracks[0][i]=-1;
1564 fClusterTracks[1][i]=-1;
1565 fClusterTracks[2][i]=-1;
1566 fClusterTracks[3][i]=-1;
1568 for (Int_t i=0; i<fN;i++) {
1569 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1570 if (cl&&cl->IsUsed()) cl->Use();
1574 //------------------------------------------------------------------------
1575 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1576 //--------------------------------------------------------------------
1577 // This function calculates the road defined by the cluster density
1578 //--------------------------------------------------------------------
1580 for (Int_t i=0; i<fN; i++) {
1581 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1583 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1585 //------------------------------------------------------------------------
1586 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1587 //--------------------------------------------------------------------
1588 //This function adds a cluster to this layer
1589 //--------------------------------------------------------------------
1590 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1591 ::Error("InsertCluster","Too many clusters !\n");
1597 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1599 Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
1600 Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2());
1601 if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
1602 if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
1603 if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
1604 if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
1607 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1608 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1609 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1610 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1614 //------------------------------------------------------------------------
1615 void AliITStrackerMI::AliITSlayer::SortClusters()
1620 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1621 Float_t *z = new Float_t[fN];
1622 Int_t * index = new Int_t[fN];
1624 fMaxSigmaClY=0.; //AD
1625 fMaxSigmaClZ=0.; //AD
1627 for (Int_t i=0;i<fN;i++){
1628 z[i] = fClusters[i]->GetZ();
1629 // save largest errors in y and z for this layer
1630 fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
1631 fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
1633 TMath::Sort(fN,z,index,kFALSE);
1634 for (Int_t i=0;i<fN;i++){
1635 clusters[i] = fClusters[index[i]];
1638 for (Int_t i=0;i<fN;i++){
1639 fClusters[i] = clusters[i];
1640 fZ[i] = fClusters[i]->GetZ();
1641 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1642 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1643 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1653 for (Int_t i=0;i<fN;i++){
1654 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1655 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1656 fClusterIndex[i] = i;
1660 fDy5 = (fYB[1]-fYB[0])/5.;
1661 fDy10 = (fYB[1]-fYB[0])/10.;
1662 fDy20 = (fYB[1]-fYB[0])/20.;
1663 for (Int_t i=0;i<6;i++) fN5[i] =0;
1664 for (Int_t i=0;i<11;i++) fN10[i]=0;
1665 for (Int_t i=0;i<21;i++) fN20[i]=0;
1667 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;}
1668 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;}
1669 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;}
1672 for (Int_t i=0;i<fN;i++)
1673 for (Int_t irot=-1;irot<=1;irot++){
1674 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1676 for (Int_t slice=0; slice<6;slice++){
1677 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1678 fClusters5[slice][fN5[slice]] = fClusters[i];
1679 fY5[slice][fN5[slice]] = curY;
1680 fZ5[slice][fN5[slice]] = fZ[i];
1681 fClusterIndex5[slice][fN5[slice]]=i;
1686 for (Int_t slice=0; slice<11;slice++){
1687 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1688 fClusters10[slice][fN10[slice]] = fClusters[i];
1689 fY10[slice][fN10[slice]] = curY;
1690 fZ10[slice][fN10[slice]] = fZ[i];
1691 fClusterIndex10[slice][fN10[slice]]=i;
1696 for (Int_t slice=0; slice<21;slice++){
1697 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1698 fClusters20[slice][fN20[slice]] = fClusters[i];
1699 fY20[slice][fN20[slice]] = curY;
1700 fZ20[slice][fN20[slice]] = fZ[i];
1701 fClusterIndex20[slice][fN20[slice]]=i;
1708 // consistency check
1710 for (Int_t i=0;i<fN-1;i++){
1716 for (Int_t slice=0;slice<21;slice++)
1717 for (Int_t i=0;i<fN20[slice]-1;i++){
1718 if (fZ20[slice][i]>fZ20[slice][i+1]){
1725 //------------------------------------------------------------------------
1726 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1727 //--------------------------------------------------------------------
1728 // This function returns the index of the nearest cluster
1729 //--------------------------------------------------------------------
1732 if (fCurrentSlice<0) {
1741 if (ncl==0) return 0;
1742 Int_t b=0, e=ncl-1, m=(b+e)/2;
1743 for (; b<e; m=(b+e)/2) {
1744 // if (z > fClusters[m]->GetZ()) b=m+1;
1745 if (z > zcl[m]) b=m+1;
1750 //------------------------------------------------------------------------
1751 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 {
1752 //--------------------------------------------------------------------
1753 // This function computes the rectangular road for this track
1754 //--------------------------------------------------------------------
1757 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1758 // take into account the misalignment: propagate track to misaligned detector plane
1759 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1761 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1762 TMath::Sqrt(track->GetSigmaZ2() +
1763 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1764 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1765 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1766 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1767 TMath::Sqrt(track->GetSigmaY2() +
1768 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1769 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1770 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1772 // track at boundary between detectors, enlarge road
1773 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1774 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1775 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1776 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1777 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1778 Float_t tgl = TMath::Abs(track->GetTgl());
1779 if (tgl > 1.) tgl=1.;
1780 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1781 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1782 Float_t snp = TMath::Abs(track->GetSnp());
1783 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1784 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1787 // add to the road a term (up to 2-3 mm) to deal with misalignments
1788 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1789 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1791 Double_t r = fgLayers[ilayer].GetR();
1792 zmin = track->GetZ() - dz;
1793 zmax = track->GetZ() + dz;
1794 ymin = track->GetY() + r*det.GetPhi() - dy;
1795 ymax = track->GetY() + r*det.GetPhi() + dy;
1797 // bring track back to idead detector plane
1798 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1802 //------------------------------------------------------------------------
1803 void AliITStrackerMI::AliITSlayer::
1804 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1805 //--------------------------------------------------------------------
1806 // This function sets the "window"
1807 //--------------------------------------------------------------------
1809 Double_t circle=2*TMath::Pi()*fR;
1815 // enlarge road in y by maximum cluster error on this layer (3 sigma)
1816 fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
1817 fYmax += fNMaxSigmaCl*fMaxSigmaClY;
1818 fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
1819 fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
1821 Float_t ymiddle = (fYmin+fYmax)*0.5;
1822 if (ymiddle<fYB[0]) {
1823 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1824 } else if (ymiddle>fYB[1]) {
1825 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1831 fClustersCs = fClusters;
1832 fClusterIndexCs = fClusterIndex;
1838 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1839 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1840 if (slice<0) slice=0;
1841 if (slice>20) slice=20;
1842 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1844 fCurrentSlice=slice;
1845 fClustersCs = fClusters20[fCurrentSlice];
1846 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1847 fYcs = fY20[fCurrentSlice];
1848 fZcs = fZ20[fCurrentSlice];
1849 fNcs = fN20[fCurrentSlice];
1854 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1855 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1856 if (slice<0) slice=0;
1857 if (slice>10) slice=10;
1858 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1860 fCurrentSlice=slice;
1861 fClustersCs = fClusters10[fCurrentSlice];
1862 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1863 fYcs = fY10[fCurrentSlice];
1864 fZcs = fZ10[fCurrentSlice];
1865 fNcs = fN10[fCurrentSlice];
1870 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1871 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1872 if (slice<0) slice=0;
1873 if (slice>5) slice=5;
1874 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1876 fCurrentSlice=slice;
1877 fClustersCs = fClusters5[fCurrentSlice];
1878 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1879 fYcs = fY5[fCurrentSlice];
1880 fZcs = fZ5[fCurrentSlice];
1881 fNcs = fN5[fCurrentSlice];
1885 fI = FindClusterIndex(fZmin);
1886 fImax = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
1892 //------------------------------------------------------------------------
1893 Int_t AliITStrackerMI::AliITSlayer::
1894 FindDetectorIndex(Double_t phi, Double_t z) const {
1895 //--------------------------------------------------------------------
1896 //This function finds the detector crossed by the track
1897 //--------------------------------------------------------------------
1899 if (fZOffset<0) // old geometry
1900 dphi = -(phi-fPhiOffset);
1901 else // new geometry
1902 dphi = phi-fPhiOffset;
1905 if (dphi < 0) dphi += 2*TMath::Pi();
1906 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1907 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1908 if (np>=fNladders) np-=fNladders;
1909 if (np<0) np+=fNladders;
1912 Double_t dz=fZOffset-z;
1913 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1914 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1915 if (nz>=fNdetectors) return -1;
1916 if (nz<0) return -1;
1918 // ad hoc correction for 3rd ladder of SDD inner layer,
1919 // which is reversed (rotated by pi around local y)
1920 // this correction is OK only from AliITSv11Hybrid onwards
1921 if (GetR()>12. && GetR()<20.) { // SDD inner
1922 if(np==2) { // 3rd ladder
1923 nz = (fNdetectors-1) - nz;
1926 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1929 return np*fNdetectors + nz;
1931 //------------------------------------------------------------------------
1932 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1934 //--------------------------------------------------------------------
1935 // This function returns clusters within the "window"
1936 //--------------------------------------------------------------------
1938 if (fCurrentSlice<0) {
1939 Double_t rpi2 = 2.*fR*TMath::Pi();
1940 for (Int_t i=fI; i<fImax; i++) {
1943 if (fYmax<y) y -= rpi2;
1944 if (fYmin>y) y += rpi2;
1945 if (y<fYmin) continue;
1946 if (y>fYmax) continue;
1948 // skip clusters that are in "extended" road but they
1949 // 3sigma error does not touch the original road
1950 if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
1951 if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
1953 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1956 return fClusters[i];
1959 for (Int_t i=fI; i<fImax; i++) {
1960 if (fYcs[i]<fYmin) continue;
1961 if (fYcs[i]>fYmax) continue;
1962 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1963 ci=fClusterIndexCs[i];
1965 return fClustersCs[i];
1970 //------------------------------------------------------------------------
1971 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1973 //--------------------------------------------------------------------
1974 // This function returns the layer thickness at this point (units X0)
1975 //--------------------------------------------------------------------
1977 x0=AliITSRecoParam::GetX0Air();
1978 if (43<fR&&fR<45) { //SSD2
1981 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1982 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1983 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1984 for (Int_t i=0; i<12; i++) {
1985 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1986 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1990 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1991 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1995 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1996 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1999 if (37<fR&&fR<41) { //SSD1
2002 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2003 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2004 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2005 for (Int_t i=0; i<11; i++) {
2006 if (TMath::Abs(z-3.9*i)<0.15) {
2007 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2011 if (TMath::Abs(z+3.9*i)<0.15) {
2012 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2016 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2017 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2020 if (13<fR&&fR<26) { //SDD
2023 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2025 if (TMath::Abs(y-1.80)<0.55) {
2027 for (Int_t j=0; j<20; j++) {
2028 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2029 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2032 if (TMath::Abs(y+1.80)<0.55) {
2034 for (Int_t j=0; j<20; j++) {
2035 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2036 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2040 for (Int_t i=0; i<4; i++) {
2041 if (TMath::Abs(z-7.3*i)<0.60) {
2043 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2046 if (TMath::Abs(z+7.3*i)<0.60) {
2048 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2053 if (6<fR&&fR<8) { //SPD2
2054 Double_t dd=0.0063; x0=21.5;
2056 if (TMath::Abs(y-3.08)>0.5) d+=dd;
2057 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2059 if (3<fR&&fR<5) { //SPD1
2060 Double_t dd=0.0063; x0=21.5;
2062 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2063 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2068 //------------------------------------------------------------------------
2069 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2071 fRmisal(det.fRmisal),
2073 fSinPhi(det.fSinPhi),
2074 fCosPhi(det.fCosPhi),
2080 fNChips(det.fNChips),
2081 fChipIsBad(det.fChipIsBad)
2085 //------------------------------------------------------------------------
2086 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2087 const AliITSDetTypeRec *detTypeRec)
2089 //--------------------------------------------------------------------
2090 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2091 //--------------------------------------------------------------------
2093 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2094 // while in the tracker they start from 0 for each layer
2095 for(Int_t il=0; il<ilayer; il++)
2096 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2099 if (ilayer==0 || ilayer==1) { // ---------- SPD
2101 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2103 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2106 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2110 // Get calibration from AliITSDetTypeRec
2111 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2112 calib->SetModuleIndex(idet);
2113 AliITSCalibration *calibSPDdead = 0;
2114 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2115 if (calib->IsBad() ||
2116 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2119 // printf("lay %d bad %d\n",ilayer,idet);
2122 // Get segmentation from AliITSDetTypeRec
2123 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2125 // Read info about bad chips
2126 fNChips = segm->GetMaximumChipIndex()+1;
2127 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2128 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2129 fChipIsBad = new Bool_t[fNChips];
2130 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2131 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2132 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2133 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2138 //------------------------------------------------------------------------
2139 Double_t AliITStrackerMI::GetEffectiveThickness()
2141 //--------------------------------------------------------------------
2142 // Returns the thickness between the current layer and the vertex (units X0)
2143 //--------------------------------------------------------------------
2146 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2147 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2148 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2152 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2153 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2157 Double_t xn=fgLayers[fI].GetR();
2158 for (Int_t i=0; i<fI; i++) {
2159 Double_t xi=fgLayers[i].GetR();
2160 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2166 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2167 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2170 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2171 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2175 //------------------------------------------------------------------------
2176 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2177 //-------------------------------------------------------------------
2178 // This function returns number of clusters within the "window"
2179 //--------------------------------------------------------------------
2181 for (Int_t i=fI; i<fN; i++) {
2182 const AliITSRecPoint *c=fClusters[i];
2183 if (c->GetZ() > fZmax) break;
2184 if (c->IsUsed()) continue;
2185 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2186 Double_t y=fR*det.GetPhi() + c->GetY();
2188 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2189 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2191 if (y<fYmin) continue;
2192 if (y>fYmax) continue;
2197 //------------------------------------------------------------------------
2198 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2199 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2201 //--------------------------------------------------------------------
2202 // This function refits the track "track" at the position "x" using
2203 // the clusters from "clusters"
2204 // If "extra"==kTRUE,
2205 // the clusters from overlapped modules get attached to "track"
2206 // If "planeff"==kTRUE,
2207 // special approach for plane efficiency evaluation is applyed
2208 //--------------------------------------------------------------------
2210 Int_t index[AliITSgeomTGeo::kNLayers];
2212 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2213 Int_t nc=clusters->GetNumberOfClusters();
2214 for (k=0; k<nc; k++) {
2215 Int_t idx=clusters->GetClusterIndex(k);
2216 Int_t ilayer=(idx&0xf0000000)>>28;
2220 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2222 //------------------------------------------------------------------------
2223 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2224 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2226 //--------------------------------------------------------------------
2227 // This function refits the track "track" at the position "x" using
2228 // the clusters from array
2229 // If "extra"==kTRUE,
2230 // the clusters from overlapped modules get attached to "track"
2231 // If "planeff"==kTRUE,
2232 // special approach for plane efficiency evaluation is applyed
2233 //--------------------------------------------------------------------
2234 Int_t index[AliITSgeomTGeo::kNLayers];
2236 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2238 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2239 index[k]=clusters[k];
2242 // special for cosmics: check which the innermost layer crossed
2244 Int_t innermostlayer=5;
2245 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2246 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2247 if(drphi < fgLayers[innermostlayer].GetR()) break;
2249 AliDebug(2,Form(" drphi %f innermost %d",drphi,innermostlayer));
2251 Int_t modstatus=1; // found
2253 Int_t from, to, step;
2254 if (xx > track->GetX()) {
2255 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2258 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2261 TString dir = (step>0 ? "outward" : "inward");
2263 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2264 AliITSlayer &layer=fgLayers[ilayer];
2265 Double_t r=layer.GetR();
2267 if (step<0 && xx>r) break;
2269 // material between SSD and SDD, SDD and SPD
2270 Double_t hI=ilayer-0.5*step;
2271 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2272 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2273 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2274 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2277 Double_t oldGlobXYZ[3];
2278 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2280 // continue if we are already beyond this layer
2281 Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2282 if(step>0 && oldGlobR > r) continue; // going outward
2283 if(step<0 && oldGlobR < r) continue; // going inward
2286 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2288 Int_t idet=layer.FindDetectorIndex(phi,z);
2290 // check if we allow a prolongation without point for large-eta tracks
2291 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2293 modstatus = 4; // out in z
2294 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2295 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2298 // apply correction for material of the current layer
2299 // add time if going outward
2300 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2304 if (idet<0) return kFALSE;
2307 const AliITSdetector &det=layer.GetDetector(idet);
2308 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2310 track->SetDetectorIndex(idet);
2311 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2313 Double_t dz,zmin,zmax,dy,ymin,ymax;
2315 const AliITSRecPoint *clAcc=0;
2316 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2318 Int_t idx=index[ilayer];
2319 if (idx>=0) { // cluster in this layer
2320 modstatus = 6; // no refit
2321 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2323 if (idet != cl->GetDetectorIndex()) {
2324 idet=cl->GetDetectorIndex();
2325 const AliITSdetector &detc=layer.GetDetector(idet);
2326 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2327 track->SetDetectorIndex(idet);
2328 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2330 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2331 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2335 modstatus = 1; // found
2340 } else { // no cluster in this layer
2342 modstatus = 3; // skipped
2343 // Plane Eff determination:
2344 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2345 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2346 UseTrackForPlaneEff(track,ilayer);
2349 modstatus = 5; // no cls in road
2351 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2352 dz = 0.5*(zmax-zmin);
2353 dy = 0.5*(ymax-ymin);
2354 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2355 if (dead==1) modstatus = 7; // holes in z in SPD
2356 if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2361 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2362 track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2364 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2367 if (extra) { // search for extra clusters in overlapped modules
2368 AliITStrackV2 tmp(*track);
2369 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2370 layer.SelectClusters(zmin,zmax,ymin,ymax);
2372 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2374 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2375 Double_t tolerance=0.1;
2376 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2377 // only clusters in another module! (overlaps)
2378 idetExtra = clExtra->GetDetectorIndex();
2379 if (idet == idetExtra) continue;
2381 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2383 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2384 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2385 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2386 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2388 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2389 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2392 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2393 track->SetExtraModule(ilayer,idetExtra);
2395 } // end search for extra clusters in overlapped modules
2397 // Correct for material of the current layer
2399 // add time if going outward
2400 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2402 } // end loop on layers
2404 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2408 //------------------------------------------------------------------------
2409 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2412 // calculate normalized chi2
2413 // return NormalizedChi2(track,0);
2416 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2417 // track->fdEdxMismatch=0;
2418 Float_t dedxmismatch =0;
2419 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2421 for (Int_t i = 0;i<6;i++){
2422 if (track->GetClIndex(i)>=0){
2423 Float_t cerry, cerrz;
2424 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2426 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2429 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2430 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2431 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2433 cchi2+=(0.5-ratio)*10.;
2434 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2435 dedxmismatch+=(0.5-ratio)*10.;
2439 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2440 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2441 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2442 if (i<2) chi2+=2*cl->GetDeltaProbability();
2448 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2449 track->SetdEdxMismatch(dedxmismatch);
2453 for (Int_t i = 0;i<4;i++){
2454 if (track->GetClIndex(i)>=0){
2455 Float_t cerry, cerrz;
2456 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2457 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2460 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2461 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2465 for (Int_t i = 4;i<6;i++){
2466 if (track->GetClIndex(i)>=0){
2467 Float_t cerry, cerrz;
2468 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2469 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2472 Float_t cerryb, cerrzb;
2473 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2474 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2477 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2478 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2483 if (track->GetESDtrack()->GetTPCsignal()>85){
2484 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2486 chi2+=(0.5-ratio)*5.;
2489 chi2+=(ratio-2.0)*3;
2493 Double_t match = TMath::Sqrt(track->GetChi22());
2494 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2495 if (!track->GetConstrain()) {
2496 if (track->GetNumberOfClusters()>2) {
2497 match/=track->GetNumberOfClusters()-2.;
2502 if (match<0) match=0;
2504 // penalty factor for missing points (NDeadZone>0), but no penalty
2505 // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2506 // or there is a dead from OCDB)
2507 Float_t deadzonefactor = 0.;
2508 if (track->GetNDeadZone()>0.) {
2509 Float_t sumDeadZoneProbability=0;
2510 for(Int_t ilay=0;ilay<6;ilay++) sumDeadZoneProbability+=track->GetDeadZoneProbability(ilay);
2511 Float_t nDeadZoneWithProbNot1=(Float_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2512 if(nDeadZoneWithProbNot1>0.) {
2513 Float_t deadZoneProbability = sumDeadZoneProbability - (Float_t)((Int_t)sumDeadZoneProbability);
2514 deadZoneProbability /= nDeadZoneWithProbNot1;
2515 deadzonefactor = 3.*(1.1-deadZoneProbability);
2519 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2520 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2521 1./(1.+track->GetNSkipped()));
2525 //------------------------------------------------------------------------
2526 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2529 // return matching chi2 between two tracks
2530 Double_t largeChi2=1000.;
2532 AliITStrackMI track3(*track2);
2533 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2535 vec(0,0)=track1->GetY() - track3.GetY();
2536 vec(1,0)=track1->GetZ() - track3.GetZ();
2537 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2538 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2539 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2542 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2543 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2544 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2545 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2546 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2548 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2549 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2550 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2551 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2553 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2554 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2555 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2557 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2558 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2560 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2563 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2564 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2567 //------------------------------------------------------------------------
2568 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2571 // return probability that given point (characterized by z position and error)
2572 // is in SPD dead zone
2574 Double_t probability = 0.;
2575 Double_t absz = TMath::Abs(zpos);
2576 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2577 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2578 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2579 Double_t zmin, zmax;
2580 if (zpos<-6.) { // dead zone at z = -7
2581 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2582 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2583 } else if (zpos>6.) { // dead zone at z = +7
2584 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2585 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2586 } else if (absz<2.) { // dead zone at z = 0
2587 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2588 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2593 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2595 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2596 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2599 //------------------------------------------------------------------------
2600 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2603 // calculate normalized chi2
2605 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2607 for (Int_t i = 0;i<6;i++){
2608 if (TMath::Abs(track->GetDy(i))>0){
2609 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2610 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2613 else{chi2[i]=10000;}
2616 TMath::Sort(6,chi2,index,kFALSE);
2617 Float_t max = float(ncl)*fac-1.;
2618 Float_t sumchi=0, sumweight=0;
2619 for (Int_t i=0;i<max+1;i++){
2620 Float_t weight = (i<max)?1.:(max+1.-i);
2621 sumchi+=weight*chi2[index[i]];
2624 Double_t normchi2 = sumchi/sumweight;
2627 //------------------------------------------------------------------------
2628 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2631 // calculate normalized chi2
2632 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2635 for (Int_t i=0;i<6;i++){
2636 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2637 Double_t sy1 = forwardtrack->GetSigmaY(i);
2638 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2639 Double_t sy2 = backtrack->GetSigmaY(i);
2640 Double_t sz2 = backtrack->GetSigmaZ(i);
2641 if (i<2){ sy2=1000.;sz2=1000;}
2643 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2644 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2646 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2647 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2649 res+= nz0*nz0+ny0*ny0;
2652 if (npoints>1) return
2653 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2654 //2*forwardtrack->fNUsed+
2655 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2656 1./(1.+forwardtrack->GetNSkipped()));
2659 //------------------------------------------------------------------------
2660 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2661 //--------------------------------------------------------------------
2662 // Return pointer to a given cluster
2663 //--------------------------------------------------------------------
2664 Int_t l=(index & 0xf0000000) >> 28;
2665 Int_t c=(index & 0x0fffffff) >> 00;
2666 return fgLayers[l].GetWeight(c);
2668 //------------------------------------------------------------------------
2669 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2671 //---------------------------------------------
2672 // register track to the list
2674 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2677 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2678 Int_t index = track->GetClusterIndex(icluster);
2679 Int_t l=(index & 0xf0000000) >> 28;
2680 Int_t c=(index & 0x0fffffff) >> 00;
2681 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2682 for (Int_t itrack=0;itrack<4;itrack++){
2683 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2684 fgLayers[l].SetClusterTracks(itrack,c,id);
2690 //------------------------------------------------------------------------
2691 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2693 //---------------------------------------------
2694 // unregister track from the list
2695 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2696 Int_t index = track->GetClusterIndex(icluster);
2697 Int_t l=(index & 0xf0000000) >> 28;
2698 Int_t c=(index & 0x0fffffff) >> 00;
2699 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2700 for (Int_t itrack=0;itrack<4;itrack++){
2701 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2702 fgLayers[l].SetClusterTracks(itrack,c,-1);
2707 //------------------------------------------------------------------------
2708 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2710 //-------------------------------------------------------------
2711 //get number of shared clusters
2712 //-------------------------------------------------------------
2714 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2715 // mean number of clusters
2716 Float_t *ny = GetNy(id), *nz = GetNz(id);
2719 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2720 Int_t index = track->GetClusterIndex(icluster);
2721 Int_t l=(index & 0xf0000000) >> 28;
2722 Int_t c=(index & 0x0fffffff) >> 00;
2723 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2725 printf("problem\n");
2727 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2731 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2732 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2733 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2735 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2738 deltan = (cl->GetNz()-nz[l]);
2740 if (deltan>2.0) continue; // extended - highly probable shared cluster
2741 weight = 2./TMath::Max(3.+deltan,2.);
2743 for (Int_t itrack=0;itrack<4;itrack++){
2744 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2746 clist[l] = (AliITSRecPoint*)GetCluster(index);
2752 track->SetNUsed(shared);
2755 //------------------------------------------------------------------------
2756 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2759 // find first shared track
2761 // mean number of clusters
2762 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2764 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2765 Int_t sharedtrack=100000;
2766 Int_t tracks[24],trackindex=0;
2767 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2769 for (Int_t icluster=0;icluster<6;icluster++){
2770 if (clusterlist[icluster]<0) continue;
2771 Int_t index = clusterlist[icluster];
2772 Int_t l=(index & 0xf0000000) >> 28;
2773 Int_t c=(index & 0x0fffffff) >> 00;
2775 printf("problem\n");
2777 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2778 //if (l>3) continue;
2779 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2782 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2783 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2784 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2786 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2789 deltan = (cl->GetNz()-nz[l]);
2791 if (deltan>2.0) continue; // extended - highly probable shared cluster
2793 for (Int_t itrack=3;itrack>=0;itrack--){
2794 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2795 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2796 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2801 if (trackindex==0) return -1;
2803 sharedtrack = tracks[0];
2805 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2808 Int_t tracks2[24], cluster[24];
2809 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2812 for (Int_t i=0;i<trackindex;i++){
2813 if (tracks[i]<0) continue;
2814 tracks2[index] = tracks[i];
2816 for (Int_t j=i+1;j<trackindex;j++){
2817 if (tracks[j]<0) continue;
2818 if (tracks[j]==tracks[i]){
2826 for (Int_t i=0;i<index;i++){
2827 if (cluster[index]>max) {
2828 sharedtrack=tracks2[index];
2835 if (sharedtrack>=100000) return -1;
2837 // make list of overlaps
2839 for (Int_t icluster=0;icluster<6;icluster++){
2840 if (clusterlist[icluster]<0) continue;
2841 Int_t index = clusterlist[icluster];
2842 Int_t l=(index & 0xf0000000) >> 28;
2843 Int_t c=(index & 0x0fffffff) >> 00;
2844 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2845 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2847 if (cl->GetNy()>2) continue;
2848 if (cl->GetNz()>2) continue;
2851 if (cl->GetNy()>3) continue;
2852 if (cl->GetNz()>3) continue;
2855 for (Int_t itrack=3;itrack>=0;itrack--){
2856 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2857 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2865 //------------------------------------------------------------------------
2866 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2868 // try to find track hypothesys without conflicts
2869 // with minimal chi2;
2870 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2871 Int_t entries1 = arr1->GetEntriesFast();
2872 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2873 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2874 Int_t entries2 = arr2->GetEntriesFast();
2875 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2877 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2878 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2879 if (track10->Pt()>0.5+track20->Pt()) return track10;
2881 for (Int_t itrack=0;itrack<entries1;itrack++){
2882 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2883 UnRegisterClusterTracks(track,trackID1);
2886 for (Int_t itrack=0;itrack<entries2;itrack++){
2887 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2888 UnRegisterClusterTracks(track,trackID2);
2892 Float_t maxconflicts=6;
2893 Double_t maxchi2 =1000.;
2895 // get weight of hypothesys - using best hypothesy
2898 Int_t list1[6],list2[6];
2899 AliITSRecPoint *clist1[6], *clist2[6] ;
2900 RegisterClusterTracks(track10,trackID1);
2901 RegisterClusterTracks(track20,trackID2);
2902 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2903 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2904 UnRegisterClusterTracks(track10,trackID1);
2905 UnRegisterClusterTracks(track20,trackID2);
2908 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2909 Float_t nerry[6],nerrz[6];
2910 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2911 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2912 for (Int_t i=0;i<6;i++){
2913 if ( (erry1[i]>0) && (erry2[i]>0)) {
2914 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2915 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2917 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2918 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2920 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2921 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2922 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2925 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2926 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2927 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2935 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2936 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2937 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2938 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2940 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2941 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2942 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2944 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2945 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2946 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2949 Double_t sumw = w1+w2;
2953 w1 = (d2+0.5)/(d1+d2+1.);
2954 w2 = (d1+0.5)/(d1+d2+1.);
2956 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2957 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2959 // get pair of "best" hypothesys
2961 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2962 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2964 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2965 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2966 //if (track1->fFakeRatio>0) continue;
2967 RegisterClusterTracks(track1,trackID1);
2968 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2969 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2971 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2972 //if (track2->fFakeRatio>0) continue;
2974 RegisterClusterTracks(track2,trackID2);
2975 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2976 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2977 UnRegisterClusterTracks(track2,trackID2);
2979 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2980 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2981 if (nskipped>0.5) continue;
2983 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2984 if (conflict1+1<cconflict1) continue;
2985 if (conflict2+1<cconflict2) continue;
2989 for (Int_t i=0;i<6;i++){
2991 Float_t c1 =0.; // conflict coeficients
2993 if (clist1[i]&&clist2[i]){
2996 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2999 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
3001 c1 = 2./TMath::Max(3.+deltan,2.);
3002 c2 = 2./TMath::Max(3.+deltan,2.);
3008 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
3011 deltan = (clist1[i]->GetNz()-nz1[i]);
3013 c1 = 2./TMath::Max(3.+deltan,2.);
3020 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
3023 deltan = (clist2[i]->GetNz()-nz2[i]);
3025 c2 = 2./TMath::Max(3.+deltan,2.);
3031 if (TMath::Abs(track1->GetDy(i))>0.) {
3032 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
3033 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
3034 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
3035 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
3037 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
3040 if (TMath::Abs(track2->GetDy(i))>0.) {
3041 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
3042 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
3043 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
3044 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3047 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3049 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3050 if (chi21>0) sum+=w1;
3051 if (chi22>0) sum+=w2;
3054 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3055 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3056 Double_t normchi2 = 2*conflict+sumchi2/sum;
3057 if ( normchi2 <maxchi2 ){
3060 maxconflicts = conflict;
3064 UnRegisterClusterTracks(track1,trackID1);
3067 // if (maxconflicts<4 && maxchi2<th0){
3068 if (maxchi2<th0*2.){
3069 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3070 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3071 track1->SetChi2MIP(5,maxconflicts);
3072 track1->SetChi2MIP(6,maxchi2);
3073 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3074 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3075 track1->SetChi2MIP(8,index1);
3076 fBestTrackIndex[trackID1] =index1;
3077 UpdateESDtrack(track1, AliESDtrack::kITSin);
3079 else if (track10->GetChi2MIP(0)<th1){
3080 track10->SetChi2MIP(5,maxconflicts);
3081 track10->SetChi2MIP(6,maxchi2);
3082 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3083 UpdateESDtrack(track10,AliESDtrack::kITSin);
3086 for (Int_t itrack=0;itrack<entries1;itrack++){
3087 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3088 UnRegisterClusterTracks(track,trackID1);
3091 for (Int_t itrack=0;itrack<entries2;itrack++){
3092 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3093 UnRegisterClusterTracks(track,trackID2);
3096 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3097 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3098 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3099 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3100 RegisterClusterTracks(track10,trackID1);
3102 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3103 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3104 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3105 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3106 RegisterClusterTracks(track20,trackID2);
3111 //------------------------------------------------------------------------
3112 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3113 //--------------------------------------------------------------------
3114 // This function marks clusters assigned to the track
3115 //--------------------------------------------------------------------
3116 AliTracker::UseClusters(t,from);
3118 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3119 //if (c->GetQ()>2) c->Use();
3120 if (c->GetSigmaZ2()>0.1) c->Use();
3121 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3122 //if (c->GetQ()>2) c->Use();
3123 if (c->GetSigmaZ2()>0.1) c->Use();
3126 //------------------------------------------------------------------------
3127 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3129 //------------------------------------------------------------------
3130 // add track to the list of hypothesys
3131 //------------------------------------------------------------------
3133 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3134 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3136 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3138 array = new TObjArray(10);
3139 fTrackHypothesys.AddAt(array,esdindex);
3141 array->AddLast(track);
3143 //------------------------------------------------------------------------
3144 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3146 //-------------------------------------------------------------------
3147 // compress array of track hypothesys
3148 // keep only maxsize best hypothesys
3149 //-------------------------------------------------------------------
3150 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3151 if (! (fTrackHypothesys.At(esdindex)) ) return;
3152 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3153 Int_t entries = array->GetEntriesFast();
3155 //- find preliminary besttrack as a reference
3156 Float_t minchi2=10000;
3158 AliITStrackMI * besttrack=0;
3159 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3160 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3161 if (!track) continue;
3162 Float_t chi2 = NormalizedChi2(track,0);
3164 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3165 track->SetLabel(tpcLabel);
3167 track->SetFakeRatio(1.);
3168 CookLabel(track,0.); //For comparison only
3170 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3171 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3172 if (track->GetNumberOfClusters()<maxn) continue;
3173 maxn = track->GetNumberOfClusters();
3180 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3181 delete array->RemoveAt(itrack);
3185 if (!besttrack) return;
3188 //take errors of best track as a reference
3189 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3190 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3191 for (Int_t j=0;j<6;j++) {
3192 if (besttrack->GetClIndex(j)>=0){
3193 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3194 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3195 ny[j] = besttrack->GetNy(j);
3196 nz[j] = besttrack->GetNz(j);
3200 // calculate normalized chi2
3202 Float_t * chi2 = new Float_t[entries];
3203 Int_t * index = new Int_t[entries];
3204 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3205 for (Int_t itrack=0;itrack<entries;itrack++){
3206 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3208 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3209 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3210 chi2[itrack] = track->GetChi2MIP(0);
3212 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3213 delete array->RemoveAt(itrack);
3219 TMath::Sort(entries,chi2,index,kFALSE);
3220 besttrack = (AliITStrackMI*)array->At(index[0]);
3221 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3222 for (Int_t j=0;j<6;j++){
3223 if (besttrack->GetClIndex(j)>=0){
3224 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3225 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3226 ny[j] = besttrack->GetNy(j);
3227 nz[j] = besttrack->GetNz(j);
3232 // calculate one more time with updated normalized errors
3233 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3234 for (Int_t itrack=0;itrack<entries;itrack++){
3235 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3237 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3238 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3239 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3242 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3243 delete array->RemoveAt(itrack);
3248 entries = array->GetEntriesFast();
3252 TObjArray * newarray = new TObjArray();
3253 TMath::Sort(entries,chi2,index,kFALSE);
3254 besttrack = (AliITStrackMI*)array->At(index[0]);
3257 for (Int_t j=0;j<6;j++){
3258 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3259 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3260 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3261 ny[j] = besttrack->GetNy(j);
3262 nz[j] = besttrack->GetNz(j);
3265 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3266 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3267 Float_t minn = besttrack->GetNumberOfClusters()-3;
3269 for (Int_t i=0;i<entries;i++){
3270 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3271 if (!track) continue;
3272 if (accepted>maxcut) break;
3273 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3274 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3275 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3276 delete array->RemoveAt(index[i]);
3280 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3281 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3282 if (!shortbest) accepted++;
3284 newarray->AddLast(array->RemoveAt(index[i]));
3285 for (Int_t j=0;j<6;j++){
3287 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3288 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3289 ny[j] = track->GetNy(j);
3290 nz[j] = track->GetNz(j);
3295 delete array->RemoveAt(index[i]);
3299 delete fTrackHypothesys.RemoveAt(esdindex);
3300 fTrackHypothesys.AddAt(newarray,esdindex);
3304 delete fTrackHypothesys.RemoveAt(esdindex);
3310 //------------------------------------------------------------------------
3311 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3313 //-------------------------------------------------------------
3314 // try to find best hypothesy
3315 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3316 //-------------------------------------------------------------
3317 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3318 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3319 if (!array) return 0;
3320 Int_t entries = array->GetEntriesFast();
3321 if (!entries) return 0;
3322 Float_t minchi2 = 100000;
3323 AliITStrackMI * besttrack=0;
3325 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3326 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3327 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3328 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3330 for (Int_t i=0;i<entries;i++){
3331 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3332 if (!track) continue;
3333 Float_t sigmarfi,sigmaz;
3334 GetDCASigma(track,sigmarfi,sigmaz);
3335 track->SetDnorm(0,sigmarfi);
3336 track->SetDnorm(1,sigmaz);
3338 track->SetChi2MIP(1,1000000);
3339 track->SetChi2MIP(2,1000000);
3340 track->SetChi2MIP(3,1000000);
3343 backtrack = new(backtrack) AliITStrackMI(*track);
3344 if (track->GetConstrain()) {
3345 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3346 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3347 backtrack->ResetCovariance(10.);
3349 backtrack->ResetCovariance(10.);
3351 backtrack->ResetClusters();
3353 Double_t x = original->GetX();
3354 if (!RefitAt(x,backtrack,track)) continue;
3356 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3357 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3358 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3359 track->SetChi22(GetMatchingChi2(backtrack,original));
3361 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3362 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3363 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3366 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3368 //forward track - without constraint
3369 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3370 forwardtrack->ResetClusters();
3372 RefitAt(x,forwardtrack,track);
3373 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3374 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3375 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3377 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3378 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3379 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3380 forwardtrack->SetD(0,track->GetD(0));
3381 forwardtrack->SetD(1,track->GetD(1));
3384 AliITSRecPoint* clist[6];
3385 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3386 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3389 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3390 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3391 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3392 track->SetChi2MIP(3,1000);
3395 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3397 for (Int_t ichi=0;ichi<5;ichi++){
3398 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3400 if (chi2 < minchi2){
3401 //besttrack = new AliITStrackMI(*forwardtrack);
3403 besttrack->SetLabel(track->GetLabel());
3404 besttrack->SetFakeRatio(track->GetFakeRatio());
3406 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3407 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3408 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3412 delete forwardtrack;
3414 for (Int_t i=0;i<entries;i++){
3415 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3417 if (!track) continue;
3419 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3420 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3421 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3422 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3423 delete array->RemoveAt(i);
3433 SortTrackHypothesys(esdindex,checkmax,1);
3435 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3436 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3437 besttrack = (AliITStrackMI*)array->At(0);
3438 if (!besttrack) return 0;
3439 besttrack->SetChi2MIP(8,0);
3440 fBestTrackIndex[esdindex]=0;
3441 entries = array->GetEntriesFast();
3442 AliITStrackMI *longtrack =0;
3444 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3445 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3446 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3447 if (!track->GetConstrain()) continue;
3448 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3449 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3450 if (track->GetChi2MIP(0)>4.) continue;
3451 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3454 //if (longtrack) besttrack=longtrack;
3457 AliITSRecPoint * clist[6];
3458 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3459 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3460 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3461 RegisterClusterTracks(besttrack,esdindex);
3468 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3469 if (sharedtrack>=0){
3471 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3473 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3479 if (shared>2.5) return 0;
3480 if (shared>1.0) return besttrack;
3482 // Don't sign clusters if not gold track
3484 if (!besttrack->IsGoldPrimary()) return besttrack;
3485 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3487 if (fConstraint[fPass]){
3491 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3492 for (Int_t i=0;i<6;i++){
3493 Int_t index = besttrack->GetClIndex(i);
3494 if (index<0) continue;
3495 Int_t ilayer = (index & 0xf0000000) >> 28;
3496 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3497 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3499 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3500 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3501 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3502 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3503 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3504 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3506 Bool_t cansign = kTRUE;
3507 for (Int_t itrack=0;itrack<entries; itrack++){
3508 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3509 if (!track) continue;
3510 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3511 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3517 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3518 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3519 if (!c->IsUsed()) c->Use();
3525 //------------------------------------------------------------------------
3526 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3529 // get "best" hypothesys
3532 Int_t nentries = itsTracks.GetEntriesFast();
3533 for (Int_t i=0;i<nentries;i++){
3534 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3535 if (!track) continue;
3536 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3537 if (!array) continue;
3538 if (array->GetEntriesFast()<=0) continue;
3540 AliITStrackMI* longtrack=0;
3542 Float_t maxchi2=1000;
3543 for (Int_t j=0;j<array->GetEntriesFast();j++){
3544 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3545 if (!trackHyp) continue;
3546 if (trackHyp->GetGoldV0()) {
3547 longtrack = trackHyp; //gold V0 track taken
3550 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3551 Float_t chi2 = trackHyp->GetChi2MIP(0);
3553 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3555 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3557 if (chi2 > maxchi2) continue;
3558 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3565 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3566 if (!longtrack) {longtrack = besttrack;}
3567 else besttrack= longtrack;
3571 AliITSRecPoint * clist[6];
3572 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3574 track->SetNUsed(shared);
3575 track->SetNSkipped(besttrack->GetNSkipped());
3576 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3578 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3582 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3583 //if (sharedtrack==-1) sharedtrack=0;
3584 if (sharedtrack>=0) {
3585 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3588 if (besttrack&&fAfterV0) {
3589 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3591 if (besttrack&&fConstraint[fPass])
3592 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3593 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3594 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3595 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3601 //------------------------------------------------------------------------
3602 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3603 //--------------------------------------------------------------------
3604 //This function "cooks" a track label. If label<0, this track is fake.
3605 //--------------------------------------------------------------------
3608 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3610 track->SetChi2MIP(9,0);
3612 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3613 Int_t cindex = track->GetClusterIndex(i);
3614 Int_t l=(cindex & 0xf0000000) >> 28;
3615 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3617 for (Int_t ind=0;ind<3;ind++){
3619 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3620 AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3622 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3625 Int_t nclusters = track->GetNumberOfClusters();
3626 if (nclusters > 0) //PH Some tracks don't have any cluster
3627 track->SetFakeRatio(double(nwrong)/double(nclusters));
3629 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3631 track->SetLabel(tpcLabel);
3633 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3636 //------------------------------------------------------------------------
3637 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3640 track->SetChi2MIP(9,0);
3641 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3642 Int_t cindex = track->GetClusterIndex(i);
3643 Int_t l=(cindex & 0xf0000000) >> 28;
3644 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3645 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3647 for (Int_t ind=0;ind<3;ind++){
3648 if (cl->GetLabel(ind)==lab) isWrong=0;
3650 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3654 track->CookdEdx(low,up);
3656 //------------------------------------------------------------------------
3657 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3659 // Create some arrays
3661 if (fCoefficients) delete []fCoefficients;
3662 fCoefficients = new Float_t[ntracks*48];
3663 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3665 //------------------------------------------------------------------------
3666 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3669 // Compute predicted chi2
3671 Float_t erry,errz,covyz;
3672 Float_t theta = track->GetTgl();
3673 Float_t phi = track->GetSnp();
3674 phi = TMath::Abs(phi)*TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3675 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
3676 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()));
3677 // Take into account the mis-alignment (bring track to cluster plane)
3678 Double_t xTrOrig=track->GetX();
3679 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3680 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()));
3681 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
3682 // Bring the track back to detector plane in ideal geometry
3683 // [mis-alignment will be accounted for in UpdateMI()]
3684 if (!track->Propagate(xTrOrig)) return 1000.;
3686 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3687 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3689 chi2+=0.5*TMath::Min(delta/2,2.);
3690 chi2+=2.*cluster->GetDeltaProbability();
3693 track->SetNy(layer,ny);
3694 track->SetNz(layer,nz);
3695 track->SetSigmaY(layer,erry);
3696 track->SetSigmaZ(layer, errz);
3697 track->SetSigmaYZ(layer,covyz);
3698 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3699 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3703 //------------------------------------------------------------------------
3704 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3709 Int_t layer = (index & 0xf0000000) >> 28;
3710 track->SetClIndex(layer, index);
3711 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3712 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3713 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3714 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3718 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3721 // Take into account the mis-alignment (bring track to cluster plane)
3722 Double_t xTrOrig=track->GetX();
3723 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3724 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3725 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3726 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3728 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3731 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3732 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3733 c.SetSigmaYZ(track->GetSigmaYZ(layer));
3736 Int_t updated = track->UpdateMI(&c,chi2,index);
3737 // Bring the track back to detector plane in ideal geometry
3738 if (!track->Propagate(xTrOrig)) return 0;
3740 if(!updated) AliDebug(2,"update failed");
3744 //------------------------------------------------------------------------
3745 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3748 //DCA sigmas parameterization
3749 //to be paramterized using external parameters in future
3752 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3753 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3755 //------------------------------------------------------------------------
3756 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3759 // Clusters from delta electrons?
3761 Int_t entries = clusterArray->GetEntriesFast();
3762 if (entries<4) return;
3763 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3764 Int_t layer = cluster->GetLayer();
3765 if (layer>1) return;
3767 Int_t ncandidates=0;
3768 Float_t r = (layer>0)? 7:4;
3770 for (Int_t i=0;i<entries;i++){
3771 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3772 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3773 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3774 index[ncandidates] = i; //candidate to belong to delta electron track
3776 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3777 cl0->SetDeltaProbability(1);
3783 for (Int_t i=0;i<ncandidates;i++){
3784 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3785 if (cl0->GetDeltaProbability()>0.8) continue;
3788 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3789 sumy=sumz=sumy2=sumyz=sumw=0.0;
3790 for (Int_t j=0;j<ncandidates;j++){
3792 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3794 Float_t dz = cl0->GetZ()-cl1->GetZ();
3795 Float_t dy = cl0->GetY()-cl1->GetY();
3796 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3797 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3798 y[ncl] = cl1->GetY();
3799 z[ncl] = cl1->GetZ();
3800 sumy+= y[ncl]*weight;
3801 sumz+= z[ncl]*weight;
3802 sumy2+=y[ncl]*y[ncl]*weight;
3803 sumyz+=y[ncl]*z[ncl]*weight;
3808 if (ncl<4) continue;
3809 Float_t det = sumw*sumy2 - sumy*sumy;
3811 if (TMath::Abs(det)>0.01){
3812 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3813 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3814 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3817 Float_t z0 = sumyz/sumy;
3818 delta = TMath::Abs(cl0->GetZ()-z0);
3821 cl0->SetDeltaProbability(1-20.*delta);
3825 //------------------------------------------------------------------------
3826 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3831 track->UpdateESDtrack(flags);
3832 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3833 if (oldtrack) delete oldtrack;
3834 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3835 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3836 printf("Problem\n");
3839 //------------------------------------------------------------------------
3840 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3842 // Get nearest upper layer close to the point xr.
3843 // rough approximation
3845 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3846 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3848 for (Int_t i=0;i<6;i++){
3849 if (radius<kRadiuses[i]){
3856 //------------------------------------------------------------------------
3857 void AliITStrackerMI::BuildMaterialLUT(TString material) {
3858 //--------------------------------------------------------------------
3859 // Fill a look-up table with mean material
3860 //--------------------------------------------------------------------
3864 Double_t point1[3],point2[3];
3865 Double_t phi,cosphi,sinphi,z;
3866 // 0-5 layers, 6 pipe, 7-8 shields
3867 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
3868 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
3870 Int_t ifirst=0,ilast=0;
3871 if(material.Contains("Pipe")) {
3873 } else if(material.Contains("Shields")) {
3875 } else if(material.Contains("Layers")) {
3878 Error("BuildMaterialLUT","Wrong layer name\n");
3881 for(Int_t imat=ifirst; imat<=ilast; imat++) {
3882 Double_t param[5]={0.,0.,0.,0.,0.};
3883 for (Int_t i=0; i<n; i++) {
3884 phi = 2.*TMath::Pi()*gRandom->Rndm();
3885 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
3886 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
3887 point1[0] = rmin[imat]*cosphi;
3888 point1[1] = rmin[imat]*sinphi;
3890 point2[0] = rmax[imat]*cosphi;
3891 point2[1] = rmax[imat]*sinphi;
3893 AliTracker::MeanMaterialBudget(point1,point2,mparam);
3894 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
3896 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
3898 fxOverX0Layer[imat] = param[1];
3899 fxTimesRhoLayer[imat] = param[0]*param[4];
3900 } else if(imat==6) {
3901 fxOverX0Pipe = param[1];
3902 fxTimesRhoPipe = param[0]*param[4];
3903 } else if(imat==7) {
3904 fxOverX0Shield[0] = param[1];
3905 fxTimesRhoShield[0] = param[0]*param[4];
3906 } else if(imat==8) {
3907 fxOverX0Shield[1] = param[1];
3908 fxTimesRhoShield[1] = param[0]*param[4];
3912 printf("%s\n",material.Data());
3913 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
3914 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
3915 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
3916 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
3917 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
3918 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
3919 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
3920 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
3921 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
3925 //------------------------------------------------------------------------
3926 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
3927 TString direction) {
3928 //-------------------------------------------------------------------
3929 // Propagate beyond beam pipe and correct for material
3930 // (material budget in different ways according to fUseTGeo value)
3931 // Add time if going outward (PropagateTo or PropagateToTGeo)
3932 //-------------------------------------------------------------------
3934 // Define budget mode:
3935 // 0: material from AliITSRecoParam (hard coded)
3936 // 1: material from TGeo in one step (on the fly)
3937 // 2: material from lut
3938 // 3: material from TGeo in one step (same for all hypotheses)
3951 if(fTrackingPhase.Contains("Clusters2Tracks"))
3952 { mode=3; } else { mode=1; }
3955 if(fTrackingPhase.Contains("Clusters2Tracks"))
3956 { mode=3; } else { mode=2; }
3962 if(fTrackingPhase.Contains("Default")) mode=0;
3964 Int_t index=fCurrentEsdTrack;
3966 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
3967 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
3969 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
3971 Double_t xOverX0,x0,lengthTimesMeanDensity;
3975 xOverX0 = AliITSRecoParam::GetdPipe();
3976 x0 = AliITSRecoParam::GetX0Be();
3977 lengthTimesMeanDensity = xOverX0*x0;
3978 lengthTimesMeanDensity *= dir;
3979 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3982 if (!t->PropagateToTGeo(xToGo,1)) return 0;
3985 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
3986 xOverX0 = fxOverX0Pipe;
3987 lengthTimesMeanDensity = fxTimesRhoPipe;
3988 lengthTimesMeanDensity *= dir;
3989 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3992 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
3993 if(fxOverX0PipeTrks[index]<0) {
3994 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
3995 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
3996 ((1.-t->GetSnp())*(1.+t->GetSnp())));
3997 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
3998 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4001 xOverX0 = fxOverX0PipeTrks[index];
4002 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4003 lengthTimesMeanDensity *= dir;
4004 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4010 //------------------------------------------------------------------------
4011 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4013 TString direction) {
4014 //-------------------------------------------------------------------
4015 // Propagate beyond SPD or SDD shield and correct for material
4016 // (material budget in different ways according to fUseTGeo value)
4017 // Add time if going outward (PropagateTo or PropagateToTGeo)
4018 //-------------------------------------------------------------------
4020 // Define budget mode:
4021 // 0: material from AliITSRecoParam (hard coded)
4022 // 1: material from TGeo in steps of X cm (on the fly)
4023 // X = AliITSRecoParam::GetStepSizeTGeo()
4024 // 2: material from lut
4025 // 3: material from TGeo in one step (same for all hypotheses)
4038 if(fTrackingPhase.Contains("Clusters2Tracks"))
4039 { mode=3; } else { mode=1; }
4042 if(fTrackingPhase.Contains("Clusters2Tracks"))
4043 { mode=3; } else { mode=2; }
4049 if(fTrackingPhase.Contains("Default")) mode=0;
4051 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4053 Int_t shieldindex=0;
4054 if (shield.Contains("SDD")) { // SDDouter
4055 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4057 } else if (shield.Contains("SPD")) { // SPDouter
4058 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4061 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4065 // do nothing if we are already beyond the shield
4066 Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4067 if(dir<0 && rTrack > rToGo) return 1; // going outward
4068 if(dir>0 && rTrack < rToGo) return 1; // going inward
4072 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4074 Int_t index=2*fCurrentEsdTrack+shieldindex;
4076 Double_t xOverX0,x0,lengthTimesMeanDensity;
4081 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4082 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4083 lengthTimesMeanDensity = xOverX0*x0;
4084 lengthTimesMeanDensity *= dir;
4085 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4088 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4089 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4092 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4093 xOverX0 = fxOverX0Shield[shieldindex];
4094 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4095 lengthTimesMeanDensity *= dir;
4096 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4099 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4100 if(fxOverX0ShieldTrks[index]<0) {
4101 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4102 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4103 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4104 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4105 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4108 xOverX0 = fxOverX0ShieldTrks[index];
4109 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4110 lengthTimesMeanDensity *= dir;
4111 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4117 //------------------------------------------------------------------------
4118 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4120 Double_t oldGlobXYZ[3],
4121 TString direction) {
4122 //-------------------------------------------------------------------
4123 // Propagate beyond layer and correct for material
4124 // (material budget in different ways according to fUseTGeo value)
4125 // Add time if going outward (PropagateTo or PropagateToTGeo)
4126 //-------------------------------------------------------------------
4128 // Define budget mode:
4129 // 0: material from AliITSRecoParam (hard coded)
4130 // 1: material from TGeo in stepsof X cm (on the fly)
4131 // X = AliITSRecoParam::GetStepSizeTGeo()
4132 // 2: material from lut
4133 // 3: material from TGeo in one step (same for all hypotheses)
4146 if(fTrackingPhase.Contains("Clusters2Tracks"))
4147 { mode=3; } else { mode=1; }
4150 if(fTrackingPhase.Contains("Clusters2Tracks"))
4151 { mode=3; } else { mode=2; }
4157 if(fTrackingPhase.Contains("Default")) mode=0;
4159 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4161 Double_t r=fgLayers[layerindex].GetR();
4162 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4164 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4166 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4168 Int_t index=6*fCurrentEsdTrack+layerindex;
4171 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4174 // back before material (no correction)
4176 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4177 if (!t->GetLocalXat(rOld,xOld)) return 0;
4178 if (!t->Propagate(xOld)) return 0;
4182 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4183 lengthTimesMeanDensity = xOverX0*x0;
4184 lengthTimesMeanDensity *= dir;
4185 // Bring the track beyond the material
4186 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4189 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4190 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4193 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4194 xOverX0 = fxOverX0Layer[layerindex];
4195 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4196 lengthTimesMeanDensity *= dir;
4197 // Bring the track beyond the material
4198 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4201 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4202 if(fxOverX0LayerTrks[index]<0) {
4203 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4204 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4205 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4206 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4207 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4208 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4211 xOverX0 = fxOverX0LayerTrks[index];
4212 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4213 lengthTimesMeanDensity *= dir;
4214 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4221 //------------------------------------------------------------------------
4222 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4223 //-----------------------------------------------------------------
4224 // Initialize LUT for storing material for each prolonged track
4225 //-----------------------------------------------------------------
4226 fxOverX0PipeTrks = new Float_t[ntracks];
4227 fxTimesRhoPipeTrks = new Float_t[ntracks];
4228 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4229 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4230 fxOverX0LayerTrks = new Float_t[ntracks*6];
4231 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4233 for(Int_t i=0; i<ntracks; i++) {
4234 fxOverX0PipeTrks[i] = -1.;
4235 fxTimesRhoPipeTrks[i] = -1.;
4237 for(Int_t j=0; j<ntracks*2; j++) {
4238 fxOverX0ShieldTrks[j] = -1.;
4239 fxTimesRhoShieldTrks[j] = -1.;
4241 for(Int_t k=0; k<ntracks*6; k++) {
4242 fxOverX0LayerTrks[k] = -1.;
4243 fxTimesRhoLayerTrks[k] = -1.;
4250 //------------------------------------------------------------------------
4251 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4252 //-----------------------------------------------------------------
4253 // Delete LUT for storing material for each prolonged track
4254 //-----------------------------------------------------------------
4255 if(fxOverX0PipeTrks) {
4256 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4258 if(fxOverX0ShieldTrks) {
4259 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4262 if(fxOverX0LayerTrks) {
4263 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4265 if(fxTimesRhoPipeTrks) {
4266 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4268 if(fxTimesRhoShieldTrks) {
4269 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4271 if(fxTimesRhoLayerTrks) {
4272 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4276 //------------------------------------------------------------------------
4277 void AliITStrackerMI::SetForceSkippingOfLayer() {
4278 //-----------------------------------------------------------------
4279 // Check if we are forced to skip layers
4280 // either we set to skip them in RecoParam
4281 // or they were off during data-taking
4282 //-----------------------------------------------------------------
4284 const AliEventInfo *eventInfo = GetEventInfo();
4286 for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
4287 fForceSkippingOfLayer[l] = 0;
4289 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
4293 AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
4295 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
4296 } else if(l==2 || l==3) {
4297 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1;
4299 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
4305 //------------------------------------------------------------------------
4306 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4307 Int_t ilayer,Int_t idet) const {
4308 //-----------------------------------------------------------------
4309 // This method is used to decide whether to allow a prolongation
4310 // without clusters, because we want to skip the layer.
4311 // In this case the return value is > 0:
4312 // return 1: the user requested to skip a layer
4313 // return 2: track outside z acceptance of SSD/SDD and will cross both SPD
4314 //-----------------------------------------------------------------
4316 if (ForceSkippingOfLayer(ilayer)) return 1;
4318 if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4319 // check if track will cross SPD outer layer
4320 Double_t phiAtSPD2,zAtSPD2;
4321 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4322 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4328 //------------------------------------------------------------------------
4329 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4330 Int_t ilayer,Int_t idet,
4331 Double_t dz,Double_t dy,
4332 Bool_t noClusters) const {
4333 //-----------------------------------------------------------------
4334 // This method is used to decide whether to allow a prolongation
4335 // without clusters, because there is a dead zone in the road.
4336 // In this case the return value is > 0:
4337 // return 1: dead zone at z=0,+-7cm in SPD
4338 // return 2: all road is "bad" (dead or noisy) from the OCDB
4339 // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4340 // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4341 //-----------------------------------------------------------------
4343 // check dead zones at z=0,+-7cm in the SPD
4344 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4345 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4346 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4347 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4348 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4349 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4350 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4351 for (Int_t i=0; i<3; i++)
4352 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4353 AliDebug(2,Form("crack SPD %d",ilayer));
4358 // check bad zones from OCDB
4359 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4361 if (idet<0) return 0;
4363 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4366 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4367 if (ilayer==0 || ilayer==1) { // ---------- SPD
4369 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4371 detSizeFactorX *= 2.;
4372 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4375 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4376 if (detType==2) segm->SetLayer(ilayer+1);
4377 Float_t detSizeX = detSizeFactorX*segm->Dx();
4378 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4380 // check if the road overlaps with bad chips
4382 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
4383 Float_t zlocmin = zloc-dz;
4384 Float_t zlocmax = zloc+dz;
4385 Float_t xlocmin = xloc-dy;
4386 Float_t xlocmax = xloc+dy;
4387 Int_t chipsInRoad[100];
4389 // check if road goes out of detector
4390 Bool_t touchNeighbourDet=kFALSE;
4391 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.5*detSizeX; touchNeighbourDet=kTRUE;}
4392 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.5*detSizeX; touchNeighbourDet=kTRUE;}
4393 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.5*detSizeZ; touchNeighbourDet=kTRUE;}
4394 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.5*detSizeZ; touchNeighbourDet=kTRUE;}
4395 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));
4397 // check if this detector is bad
4399 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4400 if(!touchNeighbourDet) {
4401 return 2; // all detectors in road are bad
4403 return 3; // at least one is bad
4407 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4408 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4409 if (!nChipsInRoad) return 0;
4411 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4412 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4413 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4414 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4415 if (det.IsChipBad(chipsInRoad[iCh])) {
4423 if(!touchNeighbourDet) {
4424 AliDebug(2,"all bad in road");
4425 return 2; // all chips in road are bad
4427 return 3; // at least a bad chip in road
4432 AliDebug(2,"at least a bad in road");
4433 return 3; // at least a bad chip in road
4437 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4438 || !noClusters) return 0;
4440 // There are no clusters in road: check if there is at least
4441 // a bad SPD pixel or SDD anode or SSD strips on both sides
4443 Int_t idetInITS=idet;
4444 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4446 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4447 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4450 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4454 //------------------------------------------------------------------------
4455 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4456 const AliITStrackMI *track,
4457 Float_t &xloc,Float_t &zloc) const {
4458 //-----------------------------------------------------------------
4459 // Gives position of track in local module ref. frame
4460 //-----------------------------------------------------------------
4465 if(idet<0) return kFALSE;
4467 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4469 Int_t lad = Int_t(idet/ndet) + 1;
4471 Int_t det = idet - (lad-1)*ndet + 1;
4473 Double_t xyzGlob[3],xyzLoc[3];
4475 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4476 // take into account the misalignment: xyz at real detector plane
4477 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4479 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4481 xloc = (Float_t)xyzLoc[0];
4482 zloc = (Float_t)xyzLoc[2];
4486 //------------------------------------------------------------------------
4487 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
4489 // Method to be optimized further:
4490 // Aim: decide whether a track can be used for PlaneEff evaluation
4491 // the decision is taken based on the track quality at the layer under study
4492 // no information on the clusters on this layer has to be used
4493 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4494 // the cut is done on number of sigmas from the boundaries
4496 // Input: Actual track, layer [0,5] under study
4498 // Return: kTRUE if this is a good track
4500 // it will apply a pre-selection to obtain good quality tracks.
4501 // Here also you will have the possibility to put a control on the
4502 // impact point of the track on the basic block, in order to exclude border regions
4503 // this will be done by calling a proper method of the AliITSPlaneEff class.
4505 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4506 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4508 Int_t index[AliITSgeomTGeo::kNLayers];
4510 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4512 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4513 index[k]=clusters[k];
4517 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4518 AliITSlayer &layer=fgLayers[ilayer];
4519 Double_t r=layer.GetR();
4520 AliITStrackMI tmp(*track);
4522 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4524 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) {
4525 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4526 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4527 if (tmp.GetClIndex(lay)>=0) ncl++;
4529 Bool_t nextout = kFALSE;
4530 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4531 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4532 Bool_t nextin = kFALSE;
4533 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4534 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4535 if(ncl<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
4537 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
4538 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
4539 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
4540 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
4544 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4545 Int_t idet=layer.FindDetectorIndex(phi,z);
4546 if(idet<0) { AliInfo(Form("cannot find detector"));
4549 // here check if it has good Chi Square.
4551 //propagate to the intersection with the detector plane
4552 const AliITSdetector &det=layer.GetDetector(idet);
4553 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4557 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
4558 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4559 if(key>fPlaneEff->Nblock()) return kFALSE;
4560 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4561 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4563 // DEFINITION OF SEARCH ROAD FOR accepting a track
4565 //For the time being they are hard-wired, later on from AliITSRecoParam
4566 // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
4567 // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
4570 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4571 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4572 // done for RecPoints
4574 // exclude tracks at boundary between detectors
4575 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
4576 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4577 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
4578 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
4579 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
4581 if ( (locx-dx < blockXmn+boundaryWidth) ||
4582 (locx+dx > blockXmx-boundaryWidth) ||
4583 (locz-dz < blockZmn+boundaryWidth) ||
4584 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
4587 //------------------------------------------------------------------------
4588 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
4590 // This Method has to be optimized! For the time-being it uses the same criteria
4591 // as those used in the search of extra clusters for overlapping modules.
4593 // Method Purpose: estabilish whether a track has produced a recpoint or not
4594 // in the layer under study (For Plane efficiency)
4596 // inputs: AliITStrackMI* track (pointer to a usable track)
4598 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
4599 // traversed by this very track. In details:
4600 // - if a cluster can be associated to the track then call
4601 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
4602 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
4605 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
4606 AliITSlayer &layer=fgLayers[ilayer];
4607 Double_t r=layer.GetR();
4608 AliITStrackMI tmp(*track);
4612 if (!tmp.GetPhiZat(r,phi,z)) return;
4613 Int_t idet=layer.FindDetectorIndex(phi,z);
4615 if(idet<0) { AliInfo(Form("cannot find detector"));
4619 //propagate to the intersection with the detector plane
4620 const AliITSdetector &det=layer.GetDetector(idet);
4621 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
4625 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
4627 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
4628 TMath::Sqrt(tmp.GetSigmaZ2() +
4629 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4630 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4631 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
4632 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
4633 TMath::Sqrt(tmp.GetSigmaY2() +
4634 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4635 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4636 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
4638 // road in global (rphi,z) [i.e. in tracking ref. system]
4639 Double_t zmin = tmp.GetZ() - dz;
4640 Double_t zmax = tmp.GetZ() + dz;
4641 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
4642 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
4644 // select clusters in road
4645 layer.SelectClusters(zmin,zmax,ymin,ymax);
4647 // Define criteria for track-cluster association
4648 Double_t msz = tmp.GetSigmaZ2() +
4649 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4650 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4651 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
4652 Double_t msy = tmp.GetSigmaY2() +
4653 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4654 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4655 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
4656 if (tmp.GetConstrain()) {
4657 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
4658 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
4660 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
4661 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
4663 msz = 1./msz; // 1/RoadZ^2
4664 msy = 1./msy; // 1/RoadY^2
4667 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
4669 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
4670 //Double_t tolerance=0.2;
4671 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
4672 idetc = cl->GetDetectorIndex();
4673 if(idet!=idetc) continue;
4674 //Int_t ilay = cl->GetLayer();
4676 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
4677 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
4679 Double_t chi2=tmp.GetPredictedChi2(cl);
4680 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
4684 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
4686 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
4687 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4688 if(key>fPlaneEff->Nblock()) return;
4689 Bool_t found=kFALSE;
4692 while ((cl=layer.GetNextCluster(clidx))!=0) {
4693 idetc = cl->GetDetectorIndex();
4694 if(idet!=idetc) continue;
4695 // here real control to see whether the cluster can be associated to the track.
4696 // cluster not associated to track
4697 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
4698 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
4699 // calculate track-clusters chi2
4700 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
4701 // in particular, the error associated to the cluster
4702 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
4704 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
4706 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
4707 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
4708 // track->SetExtraModule(ilayer,idetExtra);
4710 if(!fPlaneEff->UpDatePlaneEff(found,key))
4711 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
4712 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
4713 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
4714 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
4715 Int_t cltype[2]={-999,-999};
4719 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4720 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4723 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
4724 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
4725 cltype[0]=layer.GetCluster(ci)->GetNy();
4726 cltype[1]=layer.GetCluster(ci)->GetNz();
4728 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
4729 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
4730 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
4731 // It is computed properly by calling the method
4732 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4734 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
4735 //if (tmp.PropagateTo(x,0.,0.)) {
4736 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
4737 AliCluster c(*layer.GetCluster(ci));
4738 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
4739 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
4740 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
4741 clu[2]=TMath::Sqrt(c.GetSigmaY2());
4742 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
4745 fPlaneEff->FillHistos(key,found,tr,clu,cltype);