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();
418 // check whether we have to skip some layers
419 SetForceSkippingOfLayer();
423 //------------------------------------------------------------------------
424 void AliITStrackerMI::UnloadClusters() {
425 //--------------------------------------------------------------------
426 //This function unloads ITS clusters
427 //--------------------------------------------------------------------
428 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
430 //------------------------------------------------------------------------
431 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
432 //--------------------------------------------------------------------
433 // Publishes all pointers to clusters known to the tracker into the
434 // passed object array.
435 // The ownership is not transfered - the caller is not expected to delete
437 //--------------------------------------------------------------------
439 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
440 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
441 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
448 //------------------------------------------------------------------------
449 Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
450 //--------------------------------------------------------------------
451 // Correction for the material between the TPC and the ITS
452 //--------------------------------------------------------------------
453 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
454 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
455 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
456 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
457 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
458 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
459 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
460 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
462 printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
468 //------------------------------------------------------------------------
469 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
470 //--------------------------------------------------------------------
471 // This functions reconstructs ITS tracks
472 // The clusters must be already loaded !
473 //--------------------------------------------------------------------
475 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
477 fTrackingPhase="Clusters2Tracks";
479 TObjArray itsTracks(15000);
481 fEsd = event; // store pointer to the esd
483 // temporary (for cosmics)
484 if(event->GetVertex()) {
485 TString title = event->GetVertex()->GetTitle();
486 if(title.Contains("cosmics")) {
487 Double_t xyz[3]={GetX(),GetY(),GetZ()};
488 Double_t exyz[3]={0.1,0.1,0.1};
494 {/* Read ESD tracks */
495 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
496 Int_t nentr=event->GetNumberOfTracks();
498 // Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
500 AliESDtrack *esd=event->GetTrack(nentr);
501 // ---- for debugging:
502 //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); }
504 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
505 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
506 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
507 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
510 t=new AliITStrackMI(*esd);
511 } catch (const Char_t *msg) {
512 //Warning("Clusters2Tracks",msg);
516 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
517 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
520 // look at the ESD mass hypothesys !
521 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
523 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
525 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
526 //track - can be V0 according to TPC
528 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
532 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
536 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
540 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
545 t->SetReconstructed(kFALSE);
546 itsTracks.AddLast(t);
547 fOriginal.AddLast(t);
549 } /* End Read ESD tracks */
553 Int_t nentr=itsTracks.GetEntriesFast();
554 fTrackHypothesys.Expand(nentr);
555 fBestHypothesys.Expand(nentr);
556 MakeCoefficients(nentr);
557 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
559 // THE TWO TRACKING PASSES
560 for (fPass=0; fPass<2; fPass++) {
561 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
562 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
563 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
564 if (t==0) continue; //this track has been already tracked
565 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
566 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
567 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
568 if (fConstraint[fPass]) {
569 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
570 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
573 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
574 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
576 ResetTrackToFollow(*t);
579 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
582 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
584 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
585 if (!besttrack) continue;
586 besttrack->SetLabel(tpcLabel);
587 // besttrack->CookdEdx();
589 besttrack->SetFakeRatio(1.);
590 CookLabel(besttrack,0.); //For comparison only
591 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
593 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
595 t->SetReconstructed(kTRUE);
597 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
599 GetBestHypothesysMIP(itsTracks);
600 } // end loop on the two tracking passes
602 if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
603 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
608 Int_t entries = fTrackHypothesys.GetEntriesFast();
609 for (Int_t ientry=0; ientry<entries; ientry++) {
610 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
611 if (array) array->Delete();
612 delete fTrackHypothesys.RemoveAt(ientry);
615 fTrackHypothesys.Delete();
616 fBestHypothesys.Delete();
618 delete [] fCoefficients;
620 DeleteTrksMaterialLUT();
622 AliInfo(Form("Number of prolonged tracks: %d out of %d ESD tracks",ntrk,noesd));
624 fTrackingPhase="Default";
628 //------------------------------------------------------------------------
629 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
630 //--------------------------------------------------------------------
631 // This functions propagates reconstructed ITS tracks back
632 // The clusters must be loaded !
633 //--------------------------------------------------------------------
634 fTrackingPhase="PropagateBack";
635 Int_t nentr=event->GetNumberOfTracks();
636 // Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
639 for (Int_t i=0; i<nentr; i++) {
640 AliESDtrack *esd=event->GetTrack(i);
642 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
643 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
647 t=new AliITStrackMI(*esd);
648 } catch (const Char_t *msg) {
649 //Warning("PropagateBack",msg);
653 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
655 ResetTrackToFollow(*t);
658 // propagate to vertex [SR, GSI 17.02.2003]
659 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
660 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
661 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
662 fTrackToFollow.StartTimeIntegral();
663 // from vertex to outside pipe
664 CorrectForPipeMaterial(&fTrackToFollow,"outward");
666 // Start time integral and add distance from current position to vertex
667 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
668 fTrackToFollow.GetXYZ(xyzTrk);
670 for (Int_t icoord=0; icoord<3; icoord++) {
671 Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
674 fTrackToFollow.StartTimeIntegral();
675 fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
677 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
678 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
679 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
683 fTrackToFollow.SetLabel(t->GetLabel());
684 //fTrackToFollow.CookdEdx();
685 CookLabel(&fTrackToFollow,0.); //For comparison only
686 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
687 //UseClusters(&fTrackToFollow);
693 AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
695 fTrackingPhase="Default";
699 //------------------------------------------------------------------------
700 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
701 //--------------------------------------------------------------------
702 // This functions refits ITS tracks using the
703 // "inward propagated" TPC tracks
704 // The clusters must be loaded !
705 //--------------------------------------------------------------------
706 fTrackingPhase="RefitInward";
708 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
710 Int_t nentr=event->GetNumberOfTracks();
711 // Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
714 for (Int_t i=0; i<nentr; i++) {
715 AliESDtrack *esd=event->GetTrack(i);
717 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
718 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
719 if (esd->GetStatus()&AliESDtrack::kTPCout)
720 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
724 t=new AliITStrackMI(*esd);
725 } catch (const Char_t *msg) {
726 //Warning("RefitInward",msg);
730 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
731 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
736 ResetTrackToFollow(*t);
737 fTrackToFollow.ResetClusters();
739 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
740 fTrackToFollow.ResetCovariance(10.);
743 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
744 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
746 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
747 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
748 AliDebug(2," refit OK");
749 fTrackToFollow.SetLabel(t->GetLabel());
750 // fTrackToFollow.CookdEdx();
751 CookdEdx(&fTrackToFollow);
753 CookLabel(&fTrackToFollow,0.0); //For comparison only
756 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
757 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
758 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
759 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
760 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
761 Double_t r[3]={0.,0.,0.};
763 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
770 AliInfo(Form("Number of refitted tracks: %d out of %d ESD tracks",ntrk,nentr));
772 fTrackingPhase="Default";
776 //------------------------------------------------------------------------
777 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
778 //--------------------------------------------------------------------
779 // Return pointer to a given cluster
780 //--------------------------------------------------------------------
781 Int_t l=(index & 0xf0000000) >> 28;
782 Int_t c=(index & 0x0fffffff) >> 00;
783 return fgLayers[l].GetCluster(c);
785 //------------------------------------------------------------------------
786 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
787 //--------------------------------------------------------------------
788 // Get track space point with index i
789 //--------------------------------------------------------------------
791 Int_t l=(index & 0xf0000000) >> 28;
792 Int_t c=(index & 0x0fffffff) >> 00;
793 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
794 Int_t idet = cl->GetDetectorIndex();
798 cl->GetGlobalXYZ(xyz);
799 cl->GetGlobalCov(cov);
801 p.SetCharge(cl->GetQ());
802 p.SetDriftTime(cl->GetDriftTime());
803 p.SetChargeRatio(cl->GetChargeRatio());
804 p.SetClusterType(cl->GetClusterType());
805 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
808 iLayer = AliGeomManager::kSPD1;
811 iLayer = AliGeomManager::kSPD2;
814 iLayer = AliGeomManager::kSDD1;
817 iLayer = AliGeomManager::kSDD2;
820 iLayer = AliGeomManager::kSSD1;
823 iLayer = AliGeomManager::kSSD2;
826 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
829 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
830 p.SetVolumeID((UShort_t)volid);
833 //------------------------------------------------------------------------
834 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
835 AliTrackPoint& p, const AliESDtrack *t) {
836 //--------------------------------------------------------------------
837 // Get track space point with index i
838 // (assign error estimated during the tracking)
839 //--------------------------------------------------------------------
841 Int_t l=(index & 0xf0000000) >> 28;
842 Int_t c=(index & 0x0fffffff) >> 00;
843 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
844 Int_t idet = cl->GetDetectorIndex();
846 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
848 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
850 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
851 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
852 Double_t alpha = t->GetAlpha();
853 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
854 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,GetBz()));
855 phi += alpha-det.GetPhi();
856 Float_t tgphi = TMath::Tan(phi);
858 Float_t tgl = t->GetTgl(); // tgl about const along track
859 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
861 Float_t errtrky,errtrkz,covyz;
862 Bool_t addMisalErr=kFALSE;
863 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
867 cl->GetGlobalXYZ(xyz);
868 // cl->GetGlobalCov(cov);
869 Float_t pos[3] = {0.,0.,0.};
870 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
871 tmpcl.GetGlobalCov(cov);
874 p.SetCharge(cl->GetQ());
875 p.SetDriftTime(cl->GetDriftTime());
876 p.SetChargeRatio(cl->GetChargeRatio());
877 p.SetClusterType(cl->GetClusterType());
879 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
882 iLayer = AliGeomManager::kSPD1;
885 iLayer = AliGeomManager::kSPD2;
888 iLayer = AliGeomManager::kSDD1;
891 iLayer = AliGeomManager::kSDD2;
894 iLayer = AliGeomManager::kSSD1;
897 iLayer = AliGeomManager::kSSD2;
900 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
903 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
905 p.SetVolumeID((UShort_t)volid);
908 //------------------------------------------------------------------------
909 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
911 //--------------------------------------------------------------------
912 // Follow prolongation tree
913 //--------------------------------------------------------------------
915 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
916 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
919 AliESDtrack * esd = otrack->GetESDtrack();
920 if (esd->GetV0Index(0)>0) {
921 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
922 // mapping of ESD track is different as ITS track in Containers
923 // Need something more stable
924 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
925 for (Int_t i=0;i<3;i++){
926 Int_t index = esd->GetV0Index(i);
928 AliESDv0 * vertex = fEsd->GetV0(index);
929 if (vertex->GetStatus()<0) continue; // rejected V0
931 if (esd->GetSign()>0) {
932 vertex->SetIndex(0,esdindex);
934 vertex->SetIndex(1,esdindex);
938 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
940 bestarray = new TObjArray(5);
941 fBestHypothesys.AddAt(bestarray,esdindex);
945 //setup tree of the prolongations
947 static AliITStrackMI tracks[7][100];
948 AliITStrackMI *currenttrack;
949 static AliITStrackMI currenttrack1;
950 static AliITStrackMI currenttrack2;
951 static AliITStrackMI backuptrack;
953 Int_t nindexes[7][100];
954 Float_t normalizedchi2[100];
955 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
956 otrack->SetNSkipped(0);
957 new (&(tracks[6][0])) AliITStrackMI(*otrack);
959 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
960 Int_t modstatus = 1; // found
964 // follow prolongations
965 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
966 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
969 AliITSlayer &layer=fgLayers[ilayer];
970 Double_t r = layer.GetR();
976 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
978 if (ntracks[ilayer]>=100) break;
979 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
980 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
981 if (ntracks[ilayer]>15+ilayer){
982 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
983 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
986 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
988 // material between SSD and SDD, SDD and SPD
990 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
992 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
996 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
997 Int_t idet=layer.FindDetectorIndex(phi,z);
999 Double_t trackGlobXYZ1[3];
1000 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1002 // Get the budget to the primary vertex for the current track being prolonged
1003 Double_t budgetToPrimVertex = GetEffectiveThickness();
1005 // check if we allow a prolongation without point
1006 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1008 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1009 // propagate to the layer radius
1010 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1011 if(!vtrack->Propagate(xToGo)) continue;
1012 // apply correction for material of the current layer
1013 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1014 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1015 vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1016 vtrack->SetClIndex(ilayer,-1);
1017 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1018 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1019 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1021 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1026 // track outside layer acceptance in z
1027 if (idet<0) continue;
1029 //propagate to the intersection with the detector plane
1030 const AliITSdetector &det=layer.GetDetector(idet);
1031 new(¤ttrack2) AliITStrackMI(currenttrack1);
1032 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1033 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1034 currenttrack1.SetDetectorIndex(idet);
1035 currenttrack2.SetDetectorIndex(idet);
1036 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1039 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1041 // road in global (rphi,z) [i.e. in tracking ref. system]
1042 Double_t zmin,zmax,ymin,ymax;
1043 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1045 // select clusters in road
1046 layer.SelectClusters(zmin,zmax,ymin,ymax);
1047 //********************
1049 // Define criteria for track-cluster association
1050 Double_t msz = currenttrack1.GetSigmaZ2() +
1051 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1052 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1053 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1054 Double_t msy = currenttrack1.GetSigmaY2() +
1055 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1056 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1057 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1059 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1060 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1062 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1063 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1065 msz = 1./msz; // 1/RoadZ^2
1066 msy = 1./msy; // 1/RoadY^2
1070 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1072 const AliITSRecPoint *cl=0;
1074 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1075 Bool_t deadzoneSPD=kFALSE;
1076 currenttrack = ¤ttrack1;
1078 // check if the road contains a dead zone
1079 Bool_t noClusters = kFALSE;
1080 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1081 if (noClusters) AliDebug(2,"no clusters in road");
1082 Double_t dz=0.5*(zmax-zmin);
1083 Double_t dy=0.5*(ymax-ymin);
1084 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1085 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1086 // create a prolongation without clusters (check also if there are no clusters in the road)
1089 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1090 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1091 updatetrack->SetClIndex(ilayer,-1);
1093 modstatus = 5; // no cls in road
1094 } else if (dead==1) {
1095 modstatus = 7; // holes in z in SPD
1096 } else if (dead==2 || dead==3 || dead==4) {
1097 modstatus = 2; // dead from OCDB
1099 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1100 // apply correction for material of the current layer
1101 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1102 if (constrain) { // apply vertex constrain
1103 updatetrack->SetConstrain(constrain);
1104 Bool_t isPrim = kTRUE;
1105 if (ilayer<4) { // check that it's close to the vertex
1106 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1107 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1108 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1109 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1110 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1112 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1114 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1116 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1117 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1119 } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1120 updatetrack->SetDeadZoneProbability(ilayer,1.);
1121 } else if (dead==4) { // at least a single dead channel from OCDB
1122 updatetrack->SetDeadZoneProbability(ilayer,0.);
1129 // loop over clusters in the road
1130 while ((cl=layer.GetNextCluster(clidx))!=0) {
1131 if (ntracks[ilayer]>95) break; //space for skipped clusters
1132 Bool_t changedet =kFALSE;
1133 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
1134 Int_t idetc=cl->GetDetectorIndex();
1136 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1137 // take into account misalignment (bring track to real detector plane)
1138 Double_t xTrOrig = currenttrack->GetX();
1139 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1140 // a first cut on track-cluster distance
1141 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1142 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1143 { // cluster not associated to track
1144 AliDebug(2,"not associated");
1147 // bring track back to ideal detector plane
1148 if (!currenttrack->Propagate(xTrOrig)) continue;
1149 } else { // have to move track to cluster's detector
1150 const AliITSdetector &detc=layer.GetDetector(idetc);
1151 // a first cut on track-cluster distance
1153 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1154 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1155 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1156 continue; // cluster not associated to track
1158 new (&backuptrack) AliITStrackMI(currenttrack2);
1160 currenttrack =¤ttrack2;
1161 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1162 new (currenttrack) AliITStrackMI(backuptrack);
1166 currenttrack->SetDetectorIndex(idetc);
1167 // Get again the budget to the primary vertex
1168 // for the current track being prolonged, if had to change detector
1169 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1172 // calculate track-clusters chi2
1173 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1175 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1176 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1177 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1178 if (ntracks[ilayer]>=100) continue;
1179 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1180 updatetrack->SetClIndex(ilayer,-1);
1181 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1183 if (cl->GetQ()!=0) { // real cluster
1184 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1185 AliDebug(2,"update failed");
1188 updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1189 modstatus = 1; // found
1190 } else { // virtual cluster in dead zone
1191 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1192 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1193 modstatus = 7; // holes in z in SPD
1197 Float_t xlocnewdet,zlocnewdet;
1198 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1199 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1202 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1204 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1206 // apply correction for material of the current layer
1207 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1209 if (constrain) { // apply vertex constrain
1210 updatetrack->SetConstrain(constrain);
1211 Bool_t isPrim = kTRUE;
1212 if (ilayer<4) { // check that it's close to the vertex
1213 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1214 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1215 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1216 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1217 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1219 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1220 } //apply vertex constrain
1222 } // create new hypothesis
1224 AliDebug(2,"chi2 too large");
1227 } // loop over possible prolongations
1229 // allow one prolongation without clusters
1230 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1231 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1232 // apply correction for material of the current layer
1233 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1234 vtrack->SetClIndex(ilayer,-1);
1235 modstatus = 3; // skipped
1236 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1237 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1238 vtrack->IncrementNSkipped();
1242 // allow one prolongation without clusters for tracks with |tgl|>1.1
1243 if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) { //big theta - for low flux
1244 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1245 // apply correction for material of the current layer
1246 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1247 vtrack->SetClIndex(ilayer,-1);
1248 modstatus = 3; // skipped
1249 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1250 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1251 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1256 } // loop over tracks in layer ilayer+1
1258 //loop over track candidates for the current layer
1264 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1265 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1266 if (normalizedchi2[itrack] <
1267 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1271 if (constrain) { // constrain
1272 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1274 } else { // !constrain
1275 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1280 // sort tracks by increasing normalized chi2
1281 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1282 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1283 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1284 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1285 } // end loop over layers
1289 // Now select tracks to be kept
1291 Int_t max = constrain ? 20 : 5;
1293 // tracks that reach layer 0 (SPD inner)
1294 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1295 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1296 if (track.GetNumberOfClusters()<2) continue;
1297 if (!constrain && track.GetNormChi2(0) >
1298 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1301 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1304 // tracks that reach layer 1 (SPD outer)
1305 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1306 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1307 if (track.GetNumberOfClusters()<4) continue;
1308 if (!constrain && track.GetNormChi2(1) >
1309 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1310 if (constrain) track.IncrementNSkipped();
1312 track.SetD(0,track.GetD(GetX(),GetY()));
1313 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1314 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1315 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1318 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1321 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1323 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1324 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1325 if (track.GetNumberOfClusters()<3) continue;
1326 if (!constrain && track.GetNormChi2(2) >
1327 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1328 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1330 track.SetD(0,track.GetD(GetX(),GetY()));
1331 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1332 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1333 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1336 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1342 // register best track of each layer - important for V0 finder
1344 for (Int_t ilayer=0;ilayer<5;ilayer++){
1345 if (ntracks[ilayer]==0) continue;
1346 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1347 if (track.GetNumberOfClusters()<1) continue;
1348 CookLabel(&track,0);
1349 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1353 // update TPC V0 information
1355 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1356 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1357 for (Int_t i=0;i<3;i++){
1358 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1359 if (index==0) break;
1360 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1361 if (vertex->GetStatus()<0) continue; // rejected V0
1363 if (otrack->GetSign()>0) {
1364 vertex->SetIndex(0,esdindex);
1367 vertex->SetIndex(1,esdindex);
1369 //find nearest layer with track info
1370 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1371 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1372 Int_t nearest = nearestold;
1373 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1374 if (ntracks[nearest]==0){
1379 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1380 if (nearestold<5&&nearest<5){
1381 Bool_t accept = track.GetNormChi2(nearest)<10;
1383 if (track.GetSign()>0) {
1384 vertex->SetParamP(track);
1385 vertex->Update(fprimvertex);
1386 //vertex->SetIndex(0,track.fESDtrack->GetID());
1387 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1389 vertex->SetParamN(track);
1390 vertex->Update(fprimvertex);
1391 //vertex->SetIndex(1,track.fESDtrack->GetID());
1392 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1394 vertex->SetStatus(vertex->GetStatus()+1);
1396 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1403 //------------------------------------------------------------------------
1404 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1406 //--------------------------------------------------------------------
1409 return fgLayers[layer];
1411 //------------------------------------------------------------------------
1412 AliITStrackerMI::AliITSlayer::AliITSlayer():
1442 //--------------------------------------------------------------------
1443 //default AliITSlayer constructor
1444 //--------------------------------------------------------------------
1445 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1446 fClusterWeight[i]=0;
1447 fClusterTracks[0][i]=-1;
1448 fClusterTracks[1][i]=-1;
1449 fClusterTracks[2][i]=-1;
1450 fClusterTracks[3][i]=-1;
1453 //------------------------------------------------------------------------
1454 AliITStrackerMI::AliITSlayer::
1455 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1484 //--------------------------------------------------------------------
1485 //main AliITSlayer constructor
1486 //--------------------------------------------------------------------
1487 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1488 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1490 //------------------------------------------------------------------------
1491 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1493 fPhiOffset(layer.fPhiOffset),
1494 fNladders(layer.fNladders),
1495 fZOffset(layer.fZOffset),
1496 fNdetectors(layer.fNdetectors),
1497 fDetectors(layer.fDetectors),
1502 fClustersCs(layer.fClustersCs),
1503 fClusterIndexCs(layer.fClusterIndexCs),
1507 fCurrentSlice(layer.fCurrentSlice),
1515 fAccepted(layer.fAccepted),
1517 fMaxSigmaClY(layer.fMaxSigmaClY),
1518 fMaxSigmaClZ(layer.fMaxSigmaClZ),
1519 fNMaxSigmaCl(layer.fNMaxSigmaCl)
1523 //------------------------------------------------------------------------
1524 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1525 //--------------------------------------------------------------------
1526 // AliITSlayer destructor
1527 //--------------------------------------------------------------------
1528 delete [] fDetectors;
1529 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1530 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1531 fClusterWeight[i]=0;
1532 fClusterTracks[0][i]=-1;
1533 fClusterTracks[1][i]=-1;
1534 fClusterTracks[2][i]=-1;
1535 fClusterTracks[3][i]=-1;
1538 //------------------------------------------------------------------------
1539 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1540 //--------------------------------------------------------------------
1541 // This function removes loaded clusters
1542 //--------------------------------------------------------------------
1543 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1544 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1545 fClusterWeight[i]=0;
1546 fClusterTracks[0][i]=-1;
1547 fClusterTracks[1][i]=-1;
1548 fClusterTracks[2][i]=-1;
1549 fClusterTracks[3][i]=-1;
1555 //------------------------------------------------------------------------
1556 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1557 //--------------------------------------------------------------------
1558 // This function reset weights of the clusters
1559 //--------------------------------------------------------------------
1560 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1561 fClusterWeight[i]=0;
1562 fClusterTracks[0][i]=-1;
1563 fClusterTracks[1][i]=-1;
1564 fClusterTracks[2][i]=-1;
1565 fClusterTracks[3][i]=-1;
1567 for (Int_t i=0; i<fN;i++) {
1568 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1569 if (cl&&cl->IsUsed()) cl->Use();
1573 //------------------------------------------------------------------------
1574 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1575 //--------------------------------------------------------------------
1576 // This function calculates the road defined by the cluster density
1577 //--------------------------------------------------------------------
1579 for (Int_t i=0; i<fN; i++) {
1580 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1582 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1584 //------------------------------------------------------------------------
1585 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1586 //--------------------------------------------------------------------
1587 //This function adds a cluster to this layer
1588 //--------------------------------------------------------------------
1589 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1590 ::Error("InsertCluster","Too many clusters !\n");
1596 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1598 Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
1599 Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2());
1600 if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
1601 if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
1602 if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
1603 if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
1606 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1607 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1608 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1609 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1613 //------------------------------------------------------------------------
1614 void AliITStrackerMI::AliITSlayer::SortClusters()
1619 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1620 Float_t *z = new Float_t[fN];
1621 Int_t * index = new Int_t[fN];
1623 fMaxSigmaClY=0.; //AD
1624 fMaxSigmaClZ=0.; //AD
1626 for (Int_t i=0;i<fN;i++){
1627 z[i] = fClusters[i]->GetZ();
1628 // save largest errors in y and z for this layer
1629 fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
1630 fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
1632 TMath::Sort(fN,z,index,kFALSE);
1633 for (Int_t i=0;i<fN;i++){
1634 clusters[i] = fClusters[index[i]];
1637 for (Int_t i=0;i<fN;i++){
1638 fClusters[i] = clusters[i];
1639 fZ[i] = fClusters[i]->GetZ();
1640 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1641 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1642 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1652 for (Int_t i=0;i<fN;i++){
1653 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1654 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1655 fClusterIndex[i] = i;
1659 fDy5 = (fYB[1]-fYB[0])/5.;
1660 fDy10 = (fYB[1]-fYB[0])/10.;
1661 fDy20 = (fYB[1]-fYB[0])/20.;
1662 for (Int_t i=0;i<6;i++) fN5[i] =0;
1663 for (Int_t i=0;i<11;i++) fN10[i]=0;
1664 for (Int_t i=0;i<21;i++) fN20[i]=0;
1666 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;}
1667 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;}
1668 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;}
1671 for (Int_t i=0;i<fN;i++)
1672 for (Int_t irot=-1;irot<=1;irot++){
1673 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1675 for (Int_t slice=0; slice<6;slice++){
1676 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1677 fClusters5[slice][fN5[slice]] = fClusters[i];
1678 fY5[slice][fN5[slice]] = curY;
1679 fZ5[slice][fN5[slice]] = fZ[i];
1680 fClusterIndex5[slice][fN5[slice]]=i;
1685 for (Int_t slice=0; slice<11;slice++){
1686 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1687 fClusters10[slice][fN10[slice]] = fClusters[i];
1688 fY10[slice][fN10[slice]] = curY;
1689 fZ10[slice][fN10[slice]] = fZ[i];
1690 fClusterIndex10[slice][fN10[slice]]=i;
1695 for (Int_t slice=0; slice<21;slice++){
1696 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1697 fClusters20[slice][fN20[slice]] = fClusters[i];
1698 fY20[slice][fN20[slice]] = curY;
1699 fZ20[slice][fN20[slice]] = fZ[i];
1700 fClusterIndex20[slice][fN20[slice]]=i;
1707 // consistency check
1709 for (Int_t i=0;i<fN-1;i++){
1715 for (Int_t slice=0;slice<21;slice++)
1716 for (Int_t i=0;i<fN20[slice]-1;i++){
1717 if (fZ20[slice][i]>fZ20[slice][i+1]){
1724 //------------------------------------------------------------------------
1725 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1726 //--------------------------------------------------------------------
1727 // This function returns the index of the nearest cluster
1728 //--------------------------------------------------------------------
1731 if (fCurrentSlice<0) {
1740 if (ncl==0) return 0;
1741 Int_t b=0, e=ncl-1, m=(b+e)/2;
1742 for (; b<e; m=(b+e)/2) {
1743 // if (z > fClusters[m]->GetZ()) b=m+1;
1744 if (z > zcl[m]) b=m+1;
1749 //------------------------------------------------------------------------
1750 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 {
1751 //--------------------------------------------------------------------
1752 // This function computes the rectangular road for this track
1753 //--------------------------------------------------------------------
1756 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1757 // take into account the misalignment: propagate track to misaligned detector plane
1758 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1760 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1761 TMath::Sqrt(track->GetSigmaZ2() +
1762 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1763 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1764 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1765 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1766 TMath::Sqrt(track->GetSigmaY2() +
1767 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1768 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1769 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1771 // track at boundary between detectors, enlarge road
1772 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1773 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1774 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1775 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1776 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1777 Float_t tgl = TMath::Abs(track->GetTgl());
1778 if (tgl > 1.) tgl=1.;
1779 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1780 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1781 Float_t snp = TMath::Abs(track->GetSnp());
1782 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1783 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1786 // add to the road a term (up to 2-3 mm) to deal with misalignments
1787 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1788 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1790 Double_t r = fgLayers[ilayer].GetR();
1791 zmin = track->GetZ() - dz;
1792 zmax = track->GetZ() + dz;
1793 ymin = track->GetY() + r*det.GetPhi() - dy;
1794 ymax = track->GetY() + r*det.GetPhi() + dy;
1796 // bring track back to idead detector plane
1797 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1801 //------------------------------------------------------------------------
1802 void AliITStrackerMI::AliITSlayer::
1803 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1804 //--------------------------------------------------------------------
1805 // This function sets the "window"
1806 //--------------------------------------------------------------------
1808 Double_t circle=2*TMath::Pi()*fR;
1814 // enlarge road in y by maximum cluster error on this layer (3 sigma)
1815 fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
1816 fYmax += fNMaxSigmaCl*fMaxSigmaClY;
1817 fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
1818 fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
1820 Float_t ymiddle = (fYmin+fYmax)*0.5;
1821 if (ymiddle<fYB[0]) {
1822 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1823 } else if (ymiddle>fYB[1]) {
1824 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1830 fClustersCs = fClusters;
1831 fClusterIndexCs = fClusterIndex;
1837 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1838 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1839 if (slice<0) slice=0;
1840 if (slice>20) slice=20;
1841 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1843 fCurrentSlice=slice;
1844 fClustersCs = fClusters20[fCurrentSlice];
1845 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1846 fYcs = fY20[fCurrentSlice];
1847 fZcs = fZ20[fCurrentSlice];
1848 fNcs = fN20[fCurrentSlice];
1853 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1854 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1855 if (slice<0) slice=0;
1856 if (slice>10) slice=10;
1857 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1859 fCurrentSlice=slice;
1860 fClustersCs = fClusters10[fCurrentSlice];
1861 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1862 fYcs = fY10[fCurrentSlice];
1863 fZcs = fZ10[fCurrentSlice];
1864 fNcs = fN10[fCurrentSlice];
1869 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1870 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1871 if (slice<0) slice=0;
1872 if (slice>5) slice=5;
1873 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1875 fCurrentSlice=slice;
1876 fClustersCs = fClusters5[fCurrentSlice];
1877 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1878 fYcs = fY5[fCurrentSlice];
1879 fZcs = fZ5[fCurrentSlice];
1880 fNcs = fN5[fCurrentSlice];
1884 fI = FindClusterIndex(fZmin);
1885 fImax = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
1891 //------------------------------------------------------------------------
1892 Int_t AliITStrackerMI::AliITSlayer::
1893 FindDetectorIndex(Double_t phi, Double_t z) const {
1894 //--------------------------------------------------------------------
1895 //This function finds the detector crossed by the track
1896 //--------------------------------------------------------------------
1898 if (fZOffset<0) // old geometry
1899 dphi = -(phi-fPhiOffset);
1900 else // new geometry
1901 dphi = phi-fPhiOffset;
1904 if (dphi < 0) dphi += 2*TMath::Pi();
1905 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1906 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1907 if (np>=fNladders) np-=fNladders;
1908 if (np<0) np+=fNladders;
1911 Double_t dz=fZOffset-z;
1912 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1913 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1914 if (nz>=fNdetectors) return -1;
1915 if (nz<0) return -1;
1917 // ad hoc correction for 3rd ladder of SDD inner layer,
1918 // which is reversed (rotated by pi around local y)
1919 // this correction is OK only from AliITSv11Hybrid onwards
1920 if (GetR()>12. && GetR()<20.) { // SDD inner
1921 if(np==2) { // 3rd ladder
1922 nz = (fNdetectors-1) - nz;
1925 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1928 return np*fNdetectors + nz;
1930 //------------------------------------------------------------------------
1931 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1933 //--------------------------------------------------------------------
1934 // This function returns clusters within the "window"
1935 //--------------------------------------------------------------------
1937 if (fCurrentSlice<0) {
1938 Double_t rpi2 = 2.*fR*TMath::Pi();
1939 for (Int_t i=fI; i<fImax; i++) {
1942 if (fYmax<y) y -= rpi2;
1943 if (fYmin>y) y += rpi2;
1944 if (y<fYmin) continue;
1945 if (y>fYmax) continue;
1947 // skip clusters that are in "extended" road but they
1948 // 3sigma error does not touch the original road
1949 if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
1950 if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
1952 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1955 return fClusters[i];
1958 for (Int_t i=fI; i<fImax; i++) {
1959 if (fYcs[i]<fYmin) continue;
1960 if (fYcs[i]>fYmax) continue;
1961 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1962 ci=fClusterIndexCs[i];
1964 return fClustersCs[i];
1969 //------------------------------------------------------------------------
1970 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1972 //--------------------------------------------------------------------
1973 // This function returns the layer thickness at this point (units X0)
1974 //--------------------------------------------------------------------
1976 x0=AliITSRecoParam::GetX0Air();
1977 if (43<fR&&fR<45) { //SSD2
1980 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1981 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1982 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1983 for (Int_t i=0; i<12; i++) {
1984 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1985 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1989 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1990 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1994 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1995 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1998 if (37<fR&&fR<41) { //SSD1
2001 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2002 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2003 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2004 for (Int_t i=0; i<11; i++) {
2005 if (TMath::Abs(z-3.9*i)<0.15) {
2006 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2010 if (TMath::Abs(z+3.9*i)<0.15) {
2011 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2015 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2016 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2019 if (13<fR&&fR<26) { //SDD
2022 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2024 if (TMath::Abs(y-1.80)<0.55) {
2026 for (Int_t j=0; j<20; j++) {
2027 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2028 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2031 if (TMath::Abs(y+1.80)<0.55) {
2033 for (Int_t j=0; j<20; j++) {
2034 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2035 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2039 for (Int_t i=0; i<4; i++) {
2040 if (TMath::Abs(z-7.3*i)<0.60) {
2042 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2045 if (TMath::Abs(z+7.3*i)<0.60) {
2047 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2052 if (6<fR&&fR<8) { //SPD2
2053 Double_t dd=0.0063; x0=21.5;
2055 if (TMath::Abs(y-3.08)>0.5) d+=dd;
2056 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2058 if (3<fR&&fR<5) { //SPD1
2059 Double_t dd=0.0063; x0=21.5;
2061 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2062 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2067 //------------------------------------------------------------------------
2068 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2070 fRmisal(det.fRmisal),
2072 fSinPhi(det.fSinPhi),
2073 fCosPhi(det.fCosPhi),
2079 fNChips(det.fNChips),
2080 fChipIsBad(det.fChipIsBad)
2084 //------------------------------------------------------------------------
2085 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2086 const AliITSDetTypeRec *detTypeRec)
2088 //--------------------------------------------------------------------
2089 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2090 //--------------------------------------------------------------------
2092 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2093 // while in the tracker they start from 0 for each layer
2094 for(Int_t il=0; il<ilayer; il++)
2095 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2098 if (ilayer==0 || ilayer==1) { // ---------- SPD
2100 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2102 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2105 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2109 // Get calibration from AliITSDetTypeRec
2110 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2111 calib->SetModuleIndex(idet);
2112 AliITSCalibration *calibSPDdead = 0;
2113 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2114 if (calib->IsBad() ||
2115 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2118 // printf("lay %d bad %d\n",ilayer,idet);
2121 // Get segmentation from AliITSDetTypeRec
2122 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2124 // Read info about bad chips
2125 fNChips = segm->GetMaximumChipIndex()+1;
2126 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2127 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2128 fChipIsBad = new Bool_t[fNChips];
2129 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2130 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2131 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2132 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2137 //------------------------------------------------------------------------
2138 Double_t AliITStrackerMI::GetEffectiveThickness()
2140 //--------------------------------------------------------------------
2141 // Returns the thickness between the current layer and the vertex (units X0)
2142 //--------------------------------------------------------------------
2145 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2146 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2147 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2151 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2152 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2156 Double_t xn=fgLayers[fI].GetR();
2157 for (Int_t i=0; i<fI; i++) {
2158 Double_t xi=fgLayers[i].GetR();
2159 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2165 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2166 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2169 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2170 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2174 //------------------------------------------------------------------------
2175 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2176 //-------------------------------------------------------------------
2177 // This function returns number of clusters within the "window"
2178 //--------------------------------------------------------------------
2180 for (Int_t i=fI; i<fN; i++) {
2181 const AliITSRecPoint *c=fClusters[i];
2182 if (c->GetZ() > fZmax) break;
2183 if (c->IsUsed()) continue;
2184 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2185 Double_t y=fR*det.GetPhi() + c->GetY();
2187 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2188 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2190 if (y<fYmin) continue;
2191 if (y>fYmax) continue;
2196 //------------------------------------------------------------------------
2197 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2198 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2200 //--------------------------------------------------------------------
2201 // This function refits the track "track" at the position "x" using
2202 // the clusters from "clusters"
2203 // If "extra"==kTRUE,
2204 // the clusters from overlapped modules get attached to "track"
2205 // If "planeff"==kTRUE,
2206 // special approach for plane efficiency evaluation is applyed
2207 //--------------------------------------------------------------------
2209 Int_t index[AliITSgeomTGeo::kNLayers];
2211 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2212 Int_t nc=clusters->GetNumberOfClusters();
2213 for (k=0; k<nc; k++) {
2214 Int_t idx=clusters->GetClusterIndex(k);
2215 Int_t ilayer=(idx&0xf0000000)>>28;
2219 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2221 //------------------------------------------------------------------------
2222 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2223 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2225 //--------------------------------------------------------------------
2226 // This function refits the track "track" at the position "x" using
2227 // the clusters from array
2228 // If "extra"==kTRUE,
2229 // the clusters from overlapped modules get attached to "track"
2230 // If "planeff"==kTRUE,
2231 // special approach for plane efficiency evaluation is applyed
2232 //--------------------------------------------------------------------
2233 Int_t index[AliITSgeomTGeo::kNLayers];
2235 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2237 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2238 index[k]=clusters[k];
2241 // special for cosmics: check which the innermost layer crossed
2243 Int_t innermostlayer=5;
2244 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2245 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2246 if(drphi < fgLayers[innermostlayer].GetR()) break;
2248 AliDebug(2,Form(" drphi %f innermost %d",drphi,innermostlayer));
2250 Int_t modstatus=1; // found
2252 Int_t from, to, step;
2253 if (xx > track->GetX()) {
2254 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2257 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2260 TString dir = (step>0 ? "outward" : "inward");
2262 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2263 AliITSlayer &layer=fgLayers[ilayer];
2264 Double_t r=layer.GetR();
2266 if (step<0 && xx>r) break;
2268 // material between SSD and SDD, SDD and SPD
2269 Double_t hI=ilayer-0.5*step;
2270 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2271 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2272 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2273 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2276 Double_t oldGlobXYZ[3];
2277 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2279 // continue if we are already beyond this layer
2280 Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2281 if(step>0 && oldGlobR > r) continue; // going outward
2282 if(step<0 && oldGlobR < r) continue; // going inward
2285 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2287 Int_t idet=layer.FindDetectorIndex(phi,z);
2289 // check if we allow a prolongation without point for large-eta tracks
2290 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2292 modstatus = 4; // out in z
2293 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2294 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2297 // apply correction for material of the current layer
2298 // add time if going outward
2299 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2303 if (idet<0) return kFALSE;
2306 const AliITSdetector &det=layer.GetDetector(idet);
2307 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2309 track->SetDetectorIndex(idet);
2310 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2312 Double_t dz,zmin,zmax,dy,ymin,ymax;
2314 const AliITSRecPoint *clAcc=0;
2315 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2317 Int_t idx=index[ilayer];
2318 if (idx>=0) { // cluster in this layer
2319 modstatus = 6; // no refit
2320 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2322 if (idet != cl->GetDetectorIndex()) {
2323 idet=cl->GetDetectorIndex();
2324 const AliITSdetector &detc=layer.GetDetector(idet);
2325 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2326 track->SetDetectorIndex(idet);
2327 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2329 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2330 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2334 modstatus = 1; // found
2339 } else { // no cluster in this layer
2341 modstatus = 3; // skipped
2342 // Plane Eff determination:
2343 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2344 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2345 UseTrackForPlaneEff(track,ilayer);
2348 modstatus = 5; // no cls in road
2350 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2351 dz = 0.5*(zmax-zmin);
2352 dy = 0.5*(ymax-ymin);
2353 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2354 if (dead==1) modstatus = 7; // holes in z in SPD
2355 if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2360 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2361 track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2363 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2366 if (extra) { // search for extra clusters in overlapped modules
2367 AliITStrackV2 tmp(*track);
2368 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2369 layer.SelectClusters(zmin,zmax,ymin,ymax);
2371 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2373 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2374 Double_t tolerance=0.1;
2375 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2376 // only clusters in another module! (overlaps)
2377 idetExtra = clExtra->GetDetectorIndex();
2378 if (idet == idetExtra) continue;
2380 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2382 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2383 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2384 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2385 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2387 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2388 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2391 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2392 track->SetExtraModule(ilayer,idetExtra);
2394 } // end search for extra clusters in overlapped modules
2396 // Correct for material of the current layer
2398 // add time if going outward
2399 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2401 } // end loop on layers
2403 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2407 //------------------------------------------------------------------------
2408 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2411 // calculate normalized chi2
2412 // return NormalizedChi2(track,0);
2415 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2416 // track->fdEdxMismatch=0;
2417 Float_t dedxmismatch =0;
2418 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2420 for (Int_t i = 0;i<6;i++){
2421 if (track->GetClIndex(i)>=0){
2422 Float_t cerry, cerrz;
2423 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2425 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2428 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2429 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2430 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2432 cchi2+=(0.5-ratio)*10.;
2433 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2434 dedxmismatch+=(0.5-ratio)*10.;
2438 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2439 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2440 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2441 if (i<2) chi2+=2*cl->GetDeltaProbability();
2447 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2448 track->SetdEdxMismatch(dedxmismatch);
2452 for (Int_t i = 0;i<4;i++){
2453 if (track->GetClIndex(i)>=0){
2454 Float_t cerry, cerrz;
2455 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2456 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2459 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2460 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2464 for (Int_t i = 4;i<6;i++){
2465 if (track->GetClIndex(i)>=0){
2466 Float_t cerry, cerrz;
2467 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2468 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2471 Float_t cerryb, cerrzb;
2472 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2473 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2476 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2477 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2482 if (track->GetESDtrack()->GetTPCsignal()>85){
2483 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2485 chi2+=(0.5-ratio)*5.;
2488 chi2+=(ratio-2.0)*3;
2492 Double_t match = TMath::Sqrt(track->GetChi22());
2493 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2494 if (!track->GetConstrain()) {
2495 if (track->GetNumberOfClusters()>2) {
2496 match/=track->GetNumberOfClusters()-2.;
2501 if (match<0) match=0;
2503 // penalty factor for missing points (NDeadZone>0), but no penalty
2504 // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2505 // or there is a dead from OCDB)
2506 Float_t deadzonefactor = 0.;
2507 if (track->GetNDeadZone()>0.) {
2508 Float_t sumDeadZoneProbability=0;
2509 for(Int_t ilay=0;ilay<6;ilay++) sumDeadZoneProbability+=track->GetDeadZoneProbability(ilay);
2510 Float_t nDeadZoneWithProbNot1=(Float_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2511 if(nDeadZoneWithProbNot1>0.) {
2512 Float_t deadZoneProbability = sumDeadZoneProbability - (Float_t)((Int_t)sumDeadZoneProbability);
2513 deadZoneProbability /= nDeadZoneWithProbNot1;
2514 deadzonefactor = 3.*(1.1-deadZoneProbability);
2518 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2519 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2520 1./(1.+track->GetNSkipped()));
2524 //------------------------------------------------------------------------
2525 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2528 // return matching chi2 between two tracks
2529 Double_t largeChi2=1000.;
2531 AliITStrackMI track3(*track2);
2532 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2534 vec(0,0)=track1->GetY() - track3.GetY();
2535 vec(1,0)=track1->GetZ() - track3.GetZ();
2536 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2537 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2538 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2541 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2542 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2543 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2544 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2545 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2547 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2548 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2549 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2550 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2552 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2553 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2554 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2556 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2557 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2559 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2562 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2563 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2566 //------------------------------------------------------------------------
2567 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2570 // return probability that given point (characterized by z position and error)
2571 // is in SPD dead zone
2573 Double_t probability = 0.;
2574 Double_t absz = TMath::Abs(zpos);
2575 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2576 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2577 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2578 Double_t zmin, zmax;
2579 if (zpos<-6.) { // dead zone at z = -7
2580 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2581 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2582 } else if (zpos>6.) { // dead zone at z = +7
2583 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2584 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2585 } else if (absz<2.) { // dead zone at z = 0
2586 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2587 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2592 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2594 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2595 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2598 //------------------------------------------------------------------------
2599 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2602 // calculate normalized chi2
2604 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2606 for (Int_t i = 0;i<6;i++){
2607 if (TMath::Abs(track->GetDy(i))>0){
2608 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2609 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2612 else{chi2[i]=10000;}
2615 TMath::Sort(6,chi2,index,kFALSE);
2616 Float_t max = float(ncl)*fac-1.;
2617 Float_t sumchi=0, sumweight=0;
2618 for (Int_t i=0;i<max+1;i++){
2619 Float_t weight = (i<max)?1.:(max+1.-i);
2620 sumchi+=weight*chi2[index[i]];
2623 Double_t normchi2 = sumchi/sumweight;
2626 //------------------------------------------------------------------------
2627 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2630 // calculate normalized chi2
2631 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2634 for (Int_t i=0;i<6;i++){
2635 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2636 Double_t sy1 = forwardtrack->GetSigmaY(i);
2637 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2638 Double_t sy2 = backtrack->GetSigmaY(i);
2639 Double_t sz2 = backtrack->GetSigmaZ(i);
2640 if (i<2){ sy2=1000.;sz2=1000;}
2642 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2643 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2645 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2646 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2648 res+= nz0*nz0+ny0*ny0;
2651 if (npoints>1) return
2652 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2653 //2*forwardtrack->fNUsed+
2654 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2655 1./(1.+forwardtrack->GetNSkipped()));
2658 //------------------------------------------------------------------------
2659 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2660 //--------------------------------------------------------------------
2661 // Return pointer to a given cluster
2662 //--------------------------------------------------------------------
2663 Int_t l=(index & 0xf0000000) >> 28;
2664 Int_t c=(index & 0x0fffffff) >> 00;
2665 return fgLayers[l].GetWeight(c);
2667 //------------------------------------------------------------------------
2668 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2670 //---------------------------------------------
2671 // register track to the list
2673 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2676 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2677 Int_t index = track->GetClusterIndex(icluster);
2678 Int_t l=(index & 0xf0000000) >> 28;
2679 Int_t c=(index & 0x0fffffff) >> 00;
2680 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2681 for (Int_t itrack=0;itrack<4;itrack++){
2682 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2683 fgLayers[l].SetClusterTracks(itrack,c,id);
2689 //------------------------------------------------------------------------
2690 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2692 //---------------------------------------------
2693 // unregister track from the list
2694 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2695 Int_t index = track->GetClusterIndex(icluster);
2696 Int_t l=(index & 0xf0000000) >> 28;
2697 Int_t c=(index & 0x0fffffff) >> 00;
2698 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2699 for (Int_t itrack=0;itrack<4;itrack++){
2700 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2701 fgLayers[l].SetClusterTracks(itrack,c,-1);
2706 //------------------------------------------------------------------------
2707 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2709 //-------------------------------------------------------------
2710 //get number of shared clusters
2711 //-------------------------------------------------------------
2713 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2714 // mean number of clusters
2715 Float_t *ny = GetNy(id), *nz = GetNz(id);
2718 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2719 Int_t index = track->GetClusterIndex(icluster);
2720 Int_t l=(index & 0xf0000000) >> 28;
2721 Int_t c=(index & 0x0fffffff) >> 00;
2722 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2724 printf("problem\n");
2726 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2730 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2731 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2732 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2734 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2737 deltan = (cl->GetNz()-nz[l]);
2739 if (deltan>2.0) continue; // extended - highly probable shared cluster
2740 weight = 2./TMath::Max(3.+deltan,2.);
2742 for (Int_t itrack=0;itrack<4;itrack++){
2743 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2745 clist[l] = (AliITSRecPoint*)GetCluster(index);
2751 track->SetNUsed(shared);
2754 //------------------------------------------------------------------------
2755 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2758 // find first shared track
2760 // mean number of clusters
2761 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2763 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2764 Int_t sharedtrack=100000;
2765 Int_t tracks[24],trackindex=0;
2766 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2768 for (Int_t icluster=0;icluster<6;icluster++){
2769 if (clusterlist[icluster]<0) continue;
2770 Int_t index = clusterlist[icluster];
2771 Int_t l=(index & 0xf0000000) >> 28;
2772 Int_t c=(index & 0x0fffffff) >> 00;
2774 printf("problem\n");
2776 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2777 //if (l>3) continue;
2778 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2781 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2782 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2783 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2785 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2788 deltan = (cl->GetNz()-nz[l]);
2790 if (deltan>2.0) continue; // extended - highly probable shared cluster
2792 for (Int_t itrack=3;itrack>=0;itrack--){
2793 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2794 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2795 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2800 if (trackindex==0) return -1;
2802 sharedtrack = tracks[0];
2804 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2807 Int_t tracks2[24], cluster[24];
2808 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2811 for (Int_t i=0;i<trackindex;i++){
2812 if (tracks[i]<0) continue;
2813 tracks2[index] = tracks[i];
2815 for (Int_t j=i+1;j<trackindex;j++){
2816 if (tracks[j]<0) continue;
2817 if (tracks[j]==tracks[i]){
2825 for (Int_t i=0;i<index;i++){
2826 if (cluster[index]>max) {
2827 sharedtrack=tracks2[index];
2834 if (sharedtrack>=100000) return -1;
2836 // make list of overlaps
2838 for (Int_t icluster=0;icluster<6;icluster++){
2839 if (clusterlist[icluster]<0) continue;
2840 Int_t index = clusterlist[icluster];
2841 Int_t l=(index & 0xf0000000) >> 28;
2842 Int_t c=(index & 0x0fffffff) >> 00;
2843 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2844 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2846 if (cl->GetNy()>2) continue;
2847 if (cl->GetNz()>2) continue;
2850 if (cl->GetNy()>3) continue;
2851 if (cl->GetNz()>3) continue;
2854 for (Int_t itrack=3;itrack>=0;itrack--){
2855 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2856 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2864 //------------------------------------------------------------------------
2865 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2867 // try to find track hypothesys without conflicts
2868 // with minimal chi2;
2869 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2870 Int_t entries1 = arr1->GetEntriesFast();
2871 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2872 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2873 Int_t entries2 = arr2->GetEntriesFast();
2874 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2876 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2877 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2878 if (track10->Pt()>0.5+track20->Pt()) return track10;
2880 for (Int_t itrack=0;itrack<entries1;itrack++){
2881 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2882 UnRegisterClusterTracks(track,trackID1);
2885 for (Int_t itrack=0;itrack<entries2;itrack++){
2886 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2887 UnRegisterClusterTracks(track,trackID2);
2891 Float_t maxconflicts=6;
2892 Double_t maxchi2 =1000.;
2894 // get weight of hypothesys - using best hypothesy
2897 Int_t list1[6],list2[6];
2898 AliITSRecPoint *clist1[6], *clist2[6] ;
2899 RegisterClusterTracks(track10,trackID1);
2900 RegisterClusterTracks(track20,trackID2);
2901 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2902 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2903 UnRegisterClusterTracks(track10,trackID1);
2904 UnRegisterClusterTracks(track20,trackID2);
2907 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2908 Float_t nerry[6],nerrz[6];
2909 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2910 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2911 for (Int_t i=0;i<6;i++){
2912 if ( (erry1[i]>0) && (erry2[i]>0)) {
2913 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2914 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2916 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2917 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2919 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2920 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2921 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2924 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2925 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2926 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2934 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2935 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2936 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2937 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2939 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2940 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2941 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2943 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2944 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2945 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2948 Double_t sumw = w1+w2;
2952 w1 = (d2+0.5)/(d1+d2+1.);
2953 w2 = (d1+0.5)/(d1+d2+1.);
2955 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2956 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2958 // get pair of "best" hypothesys
2960 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2961 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2963 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2964 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2965 //if (track1->fFakeRatio>0) continue;
2966 RegisterClusterTracks(track1,trackID1);
2967 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2968 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2970 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2971 //if (track2->fFakeRatio>0) continue;
2973 RegisterClusterTracks(track2,trackID2);
2974 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2975 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2976 UnRegisterClusterTracks(track2,trackID2);
2978 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2979 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2980 if (nskipped>0.5) continue;
2982 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2983 if (conflict1+1<cconflict1) continue;
2984 if (conflict2+1<cconflict2) continue;
2988 for (Int_t i=0;i<6;i++){
2990 Float_t c1 =0.; // conflict coeficients
2992 if (clist1[i]&&clist2[i]){
2995 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2998 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
3000 c1 = 2./TMath::Max(3.+deltan,2.);
3001 c2 = 2./TMath::Max(3.+deltan,2.);
3007 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
3010 deltan = (clist1[i]->GetNz()-nz1[i]);
3012 c1 = 2./TMath::Max(3.+deltan,2.);
3019 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
3022 deltan = (clist2[i]->GetNz()-nz2[i]);
3024 c2 = 2./TMath::Max(3.+deltan,2.);
3030 if (TMath::Abs(track1->GetDy(i))>0.) {
3031 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
3032 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
3033 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
3034 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
3036 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
3039 if (TMath::Abs(track2->GetDy(i))>0.) {
3040 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
3041 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
3042 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
3043 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3046 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3048 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3049 if (chi21>0) sum+=w1;
3050 if (chi22>0) sum+=w2;
3053 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3054 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3055 Double_t normchi2 = 2*conflict+sumchi2/sum;
3056 if ( normchi2 <maxchi2 ){
3059 maxconflicts = conflict;
3063 UnRegisterClusterTracks(track1,trackID1);
3066 // if (maxconflicts<4 && maxchi2<th0){
3067 if (maxchi2<th0*2.){
3068 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3069 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3070 track1->SetChi2MIP(5,maxconflicts);
3071 track1->SetChi2MIP(6,maxchi2);
3072 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3073 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3074 track1->SetChi2MIP(8,index1);
3075 fBestTrackIndex[trackID1] =index1;
3076 UpdateESDtrack(track1, AliESDtrack::kITSin);
3078 else if (track10->GetChi2MIP(0)<th1){
3079 track10->SetChi2MIP(5,maxconflicts);
3080 track10->SetChi2MIP(6,maxchi2);
3081 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3082 UpdateESDtrack(track10,AliESDtrack::kITSin);
3085 for (Int_t itrack=0;itrack<entries1;itrack++){
3086 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3087 UnRegisterClusterTracks(track,trackID1);
3090 for (Int_t itrack=0;itrack<entries2;itrack++){
3091 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3092 UnRegisterClusterTracks(track,trackID2);
3095 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3096 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3097 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3098 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3099 RegisterClusterTracks(track10,trackID1);
3101 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3102 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3103 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3104 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3105 RegisterClusterTracks(track20,trackID2);
3110 //------------------------------------------------------------------------
3111 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3112 //--------------------------------------------------------------------
3113 // This function marks clusters assigned to the track
3114 //--------------------------------------------------------------------
3115 AliTracker::UseClusters(t,from);
3117 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3118 //if (c->GetQ()>2) c->Use();
3119 if (c->GetSigmaZ2()>0.1) c->Use();
3120 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3121 //if (c->GetQ()>2) c->Use();
3122 if (c->GetSigmaZ2()>0.1) c->Use();
3125 //------------------------------------------------------------------------
3126 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3128 //------------------------------------------------------------------
3129 // add track to the list of hypothesys
3130 //------------------------------------------------------------------
3132 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3133 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3135 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3137 array = new TObjArray(10);
3138 fTrackHypothesys.AddAt(array,esdindex);
3140 array->AddLast(track);
3142 //------------------------------------------------------------------------
3143 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3145 //-------------------------------------------------------------------
3146 // compress array of track hypothesys
3147 // keep only maxsize best hypothesys
3148 //-------------------------------------------------------------------
3149 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3150 if (! (fTrackHypothesys.At(esdindex)) ) return;
3151 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3152 Int_t entries = array->GetEntriesFast();
3154 //- find preliminary besttrack as a reference
3155 Float_t minchi2=10000;
3157 AliITStrackMI * besttrack=0;
3158 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3159 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3160 if (!track) continue;
3161 Float_t chi2 = NormalizedChi2(track,0);
3163 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3164 track->SetLabel(tpcLabel);
3166 track->SetFakeRatio(1.);
3167 CookLabel(track,0.); //For comparison only
3169 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3170 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3171 if (track->GetNumberOfClusters()<maxn) continue;
3172 maxn = track->GetNumberOfClusters();
3179 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3180 delete array->RemoveAt(itrack);
3184 if (!besttrack) return;
3187 //take errors of best track as a reference
3188 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3189 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3190 for (Int_t j=0;j<6;j++) {
3191 if (besttrack->GetClIndex(j)>=0){
3192 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3193 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3194 ny[j] = besttrack->GetNy(j);
3195 nz[j] = besttrack->GetNz(j);
3199 // calculate normalized chi2
3201 Float_t * chi2 = new Float_t[entries];
3202 Int_t * index = new Int_t[entries];
3203 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3204 for (Int_t itrack=0;itrack<entries;itrack++){
3205 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3207 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3208 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3209 chi2[itrack] = track->GetChi2MIP(0);
3211 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3212 delete array->RemoveAt(itrack);
3218 TMath::Sort(entries,chi2,index,kFALSE);
3219 besttrack = (AliITStrackMI*)array->At(index[0]);
3220 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3221 for (Int_t j=0;j<6;j++){
3222 if (besttrack->GetClIndex(j)>=0){
3223 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3224 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3225 ny[j] = besttrack->GetNy(j);
3226 nz[j] = besttrack->GetNz(j);
3231 // calculate one more time with updated normalized errors
3232 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3233 for (Int_t itrack=0;itrack<entries;itrack++){
3234 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3236 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3237 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3238 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3241 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3242 delete array->RemoveAt(itrack);
3247 entries = array->GetEntriesFast();
3251 TObjArray * newarray = new TObjArray();
3252 TMath::Sort(entries,chi2,index,kFALSE);
3253 besttrack = (AliITStrackMI*)array->At(index[0]);
3256 for (Int_t j=0;j<6;j++){
3257 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3258 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3259 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3260 ny[j] = besttrack->GetNy(j);
3261 nz[j] = besttrack->GetNz(j);
3264 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3265 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3266 Float_t minn = besttrack->GetNumberOfClusters()-3;
3268 for (Int_t i=0;i<entries;i++){
3269 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3270 if (!track) continue;
3271 if (accepted>maxcut) break;
3272 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3273 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3274 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3275 delete array->RemoveAt(index[i]);
3279 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3280 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3281 if (!shortbest) accepted++;
3283 newarray->AddLast(array->RemoveAt(index[i]));
3284 for (Int_t j=0;j<6;j++){
3286 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3287 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3288 ny[j] = track->GetNy(j);
3289 nz[j] = track->GetNz(j);
3294 delete array->RemoveAt(index[i]);
3298 delete fTrackHypothesys.RemoveAt(esdindex);
3299 fTrackHypothesys.AddAt(newarray,esdindex);
3303 delete fTrackHypothesys.RemoveAt(esdindex);
3309 //------------------------------------------------------------------------
3310 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3312 //-------------------------------------------------------------
3313 // try to find best hypothesy
3314 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3315 //-------------------------------------------------------------
3316 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3317 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3318 if (!array) return 0;
3319 Int_t entries = array->GetEntriesFast();
3320 if (!entries) return 0;
3321 Float_t minchi2 = 100000;
3322 AliITStrackMI * besttrack=0;
3324 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3325 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3326 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3327 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3329 for (Int_t i=0;i<entries;i++){
3330 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3331 if (!track) continue;
3332 Float_t sigmarfi,sigmaz;
3333 GetDCASigma(track,sigmarfi,sigmaz);
3334 track->SetDnorm(0,sigmarfi);
3335 track->SetDnorm(1,sigmaz);
3337 track->SetChi2MIP(1,1000000);
3338 track->SetChi2MIP(2,1000000);
3339 track->SetChi2MIP(3,1000000);
3342 backtrack = new(backtrack) AliITStrackMI(*track);
3343 if (track->GetConstrain()) {
3344 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3345 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3346 backtrack->ResetCovariance(10.);
3348 backtrack->ResetCovariance(10.);
3350 backtrack->ResetClusters();
3352 Double_t x = original->GetX();
3353 if (!RefitAt(x,backtrack,track)) continue;
3355 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3356 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3357 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3358 track->SetChi22(GetMatchingChi2(backtrack,original));
3360 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3361 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3362 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3365 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3367 //forward track - without constraint
3368 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3369 forwardtrack->ResetClusters();
3371 RefitAt(x,forwardtrack,track);
3372 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3373 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3374 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3376 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3377 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3378 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3379 forwardtrack->SetD(0,track->GetD(0));
3380 forwardtrack->SetD(1,track->GetD(1));
3383 AliITSRecPoint* clist[6];
3384 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3385 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3388 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3389 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3390 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3391 track->SetChi2MIP(3,1000);
3394 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3396 for (Int_t ichi=0;ichi<5;ichi++){
3397 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3399 if (chi2 < minchi2){
3400 //besttrack = new AliITStrackMI(*forwardtrack);
3402 besttrack->SetLabel(track->GetLabel());
3403 besttrack->SetFakeRatio(track->GetFakeRatio());
3405 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3406 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3407 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3411 delete forwardtrack;
3413 for (Int_t i=0;i<entries;i++){
3414 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3416 if (!track) continue;
3418 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3419 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3420 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3421 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3422 delete array->RemoveAt(i);
3432 SortTrackHypothesys(esdindex,checkmax,1);
3434 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3435 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3436 besttrack = (AliITStrackMI*)array->At(0);
3437 if (!besttrack) return 0;
3438 besttrack->SetChi2MIP(8,0);
3439 fBestTrackIndex[esdindex]=0;
3440 entries = array->GetEntriesFast();
3441 AliITStrackMI *longtrack =0;
3443 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3444 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3445 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3446 if (!track->GetConstrain()) continue;
3447 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3448 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3449 if (track->GetChi2MIP(0)>4.) continue;
3450 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3453 //if (longtrack) besttrack=longtrack;
3456 AliITSRecPoint * clist[6];
3457 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3458 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3459 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3460 RegisterClusterTracks(besttrack,esdindex);
3467 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3468 if (sharedtrack>=0){
3470 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3472 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3478 if (shared>2.5) return 0;
3479 if (shared>1.0) return besttrack;
3481 // Don't sign clusters if not gold track
3483 if (!besttrack->IsGoldPrimary()) return besttrack;
3484 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3486 if (fConstraint[fPass]){
3490 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3491 for (Int_t i=0;i<6;i++){
3492 Int_t index = besttrack->GetClIndex(i);
3493 if (index<0) continue;
3494 Int_t ilayer = (index & 0xf0000000) >> 28;
3495 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3496 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3498 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3499 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3500 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3501 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3502 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3503 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3505 Bool_t cansign = kTRUE;
3506 for (Int_t itrack=0;itrack<entries; itrack++){
3507 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3508 if (!track) continue;
3509 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3510 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3516 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3517 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3518 if (!c->IsUsed()) c->Use();
3524 //------------------------------------------------------------------------
3525 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3528 // get "best" hypothesys
3531 Int_t nentries = itsTracks.GetEntriesFast();
3532 for (Int_t i=0;i<nentries;i++){
3533 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3534 if (!track) continue;
3535 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3536 if (!array) continue;
3537 if (array->GetEntriesFast()<=0) continue;
3539 AliITStrackMI* longtrack=0;
3541 Float_t maxchi2=1000;
3542 for (Int_t j=0;j<array->GetEntriesFast();j++){
3543 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3544 if (!trackHyp) continue;
3545 if (trackHyp->GetGoldV0()) {
3546 longtrack = trackHyp; //gold V0 track taken
3549 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3550 Float_t chi2 = trackHyp->GetChi2MIP(0);
3552 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3554 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3556 if (chi2 > maxchi2) continue;
3557 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3564 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3565 if (!longtrack) {longtrack = besttrack;}
3566 else besttrack= longtrack;
3570 AliITSRecPoint * clist[6];
3571 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3573 track->SetNUsed(shared);
3574 track->SetNSkipped(besttrack->GetNSkipped());
3575 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3577 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3581 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3582 //if (sharedtrack==-1) sharedtrack=0;
3583 if (sharedtrack>=0) {
3584 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3587 if (besttrack&&fAfterV0) {
3588 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3590 if (besttrack&&fConstraint[fPass])
3591 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3592 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3593 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3594 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3600 //------------------------------------------------------------------------
3601 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3602 //--------------------------------------------------------------------
3603 //This function "cooks" a track label. If label<0, this track is fake.
3604 //--------------------------------------------------------------------
3607 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3609 track->SetChi2MIP(9,0);
3611 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3612 Int_t cindex = track->GetClusterIndex(i);
3613 Int_t l=(cindex & 0xf0000000) >> 28;
3614 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3616 for (Int_t ind=0;ind<3;ind++){
3618 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3619 AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3621 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3624 Int_t nclusters = track->GetNumberOfClusters();
3625 if (nclusters > 0) //PH Some tracks don't have any cluster
3626 track->SetFakeRatio(double(nwrong)/double(nclusters));
3628 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3630 track->SetLabel(tpcLabel);
3632 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3635 //------------------------------------------------------------------------
3636 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3639 track->SetChi2MIP(9,0);
3640 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3641 Int_t cindex = track->GetClusterIndex(i);
3642 Int_t l=(cindex & 0xf0000000) >> 28;
3643 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3644 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3646 for (Int_t ind=0;ind<3;ind++){
3647 if (cl->GetLabel(ind)==lab) isWrong=0;
3649 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3653 track->CookdEdx(low,up);
3655 //------------------------------------------------------------------------
3656 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3658 // Create some arrays
3660 if (fCoefficients) delete []fCoefficients;
3661 fCoefficients = new Float_t[ntracks*48];
3662 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3664 //------------------------------------------------------------------------
3665 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3668 // Compute predicted chi2
3670 Float_t erry,errz,covyz;
3671 Float_t theta = track->GetTgl();
3672 Float_t phi = track->GetSnp();
3673 phi = TMath::Abs(phi)*TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3674 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
3675 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()));
3676 // Take into account the mis-alignment (bring track to cluster plane)
3677 Double_t xTrOrig=track->GetX();
3678 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3679 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()));
3680 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
3681 // Bring the track back to detector plane in ideal geometry
3682 // [mis-alignment will be accounted for in UpdateMI()]
3683 if (!track->Propagate(xTrOrig)) return 1000.;
3685 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3686 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3688 chi2+=0.5*TMath::Min(delta/2,2.);
3689 chi2+=2.*cluster->GetDeltaProbability();
3692 track->SetNy(layer,ny);
3693 track->SetNz(layer,nz);
3694 track->SetSigmaY(layer,erry);
3695 track->SetSigmaZ(layer, errz);
3696 track->SetSigmaYZ(layer,covyz);
3697 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3698 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3702 //------------------------------------------------------------------------
3703 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3708 Int_t layer = (index & 0xf0000000) >> 28;
3709 track->SetClIndex(layer, index);
3710 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3711 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3712 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3713 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3717 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3720 // Take into account the mis-alignment (bring track to cluster plane)
3721 Double_t xTrOrig=track->GetX();
3722 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3723 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3724 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3725 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3727 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3730 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3731 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3732 c.SetSigmaYZ(track->GetSigmaYZ(layer));
3735 Int_t updated = track->UpdateMI(&c,chi2,index);
3736 // Bring the track back to detector plane in ideal geometry
3737 if (!track->Propagate(xTrOrig)) return 0;
3739 if(!updated) AliDebug(2,"update failed");
3743 //------------------------------------------------------------------------
3744 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3747 //DCA sigmas parameterization
3748 //to be paramterized using external parameters in future
3751 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3752 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3754 //------------------------------------------------------------------------
3755 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3758 // Clusters from delta electrons?
3760 Int_t entries = clusterArray->GetEntriesFast();
3761 if (entries<4) return;
3762 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3763 Int_t layer = cluster->GetLayer();
3764 if (layer>1) return;
3766 Int_t ncandidates=0;
3767 Float_t r = (layer>0)? 7:4;
3769 for (Int_t i=0;i<entries;i++){
3770 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3771 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3772 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3773 index[ncandidates] = i; //candidate to belong to delta electron track
3775 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3776 cl0->SetDeltaProbability(1);
3782 for (Int_t i=0;i<ncandidates;i++){
3783 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3784 if (cl0->GetDeltaProbability()>0.8) continue;
3787 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3788 sumy=sumz=sumy2=sumyz=sumw=0.0;
3789 for (Int_t j=0;j<ncandidates;j++){
3791 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3793 Float_t dz = cl0->GetZ()-cl1->GetZ();
3794 Float_t dy = cl0->GetY()-cl1->GetY();
3795 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3796 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3797 y[ncl] = cl1->GetY();
3798 z[ncl] = cl1->GetZ();
3799 sumy+= y[ncl]*weight;
3800 sumz+= z[ncl]*weight;
3801 sumy2+=y[ncl]*y[ncl]*weight;
3802 sumyz+=y[ncl]*z[ncl]*weight;
3807 if (ncl<4) continue;
3808 Float_t det = sumw*sumy2 - sumy*sumy;
3810 if (TMath::Abs(det)>0.01){
3811 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3812 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3813 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3816 Float_t z0 = sumyz/sumy;
3817 delta = TMath::Abs(cl0->GetZ()-z0);
3820 cl0->SetDeltaProbability(1-20.*delta);
3824 //------------------------------------------------------------------------
3825 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3830 track->UpdateESDtrack(flags);
3831 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3832 if (oldtrack) delete oldtrack;
3833 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3834 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3835 printf("Problem\n");
3838 //------------------------------------------------------------------------
3839 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3841 // Get nearest upper layer close to the point xr.
3842 // rough approximation
3844 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3845 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3847 for (Int_t i=0;i<6;i++){
3848 if (radius<kRadiuses[i]){
3855 //------------------------------------------------------------------------
3856 void AliITStrackerMI::BuildMaterialLUT(TString material) {
3857 //--------------------------------------------------------------------
3858 // Fill a look-up table with mean material
3859 //--------------------------------------------------------------------
3863 Double_t point1[3],point2[3];
3864 Double_t phi,cosphi,sinphi,z;
3865 // 0-5 layers, 6 pipe, 7-8 shields
3866 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
3867 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
3869 Int_t ifirst=0,ilast=0;
3870 if(material.Contains("Pipe")) {
3872 } else if(material.Contains("Shields")) {
3874 } else if(material.Contains("Layers")) {
3877 Error("BuildMaterialLUT","Wrong layer name\n");
3880 for(Int_t imat=ifirst; imat<=ilast; imat++) {
3881 Double_t param[5]={0.,0.,0.,0.,0.};
3882 for (Int_t i=0; i<n; i++) {
3883 phi = 2.*TMath::Pi()*gRandom->Rndm();
3884 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
3885 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
3886 point1[0] = rmin[imat]*cosphi;
3887 point1[1] = rmin[imat]*sinphi;
3889 point2[0] = rmax[imat]*cosphi;
3890 point2[1] = rmax[imat]*sinphi;
3892 AliTracker::MeanMaterialBudget(point1,point2,mparam);
3893 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
3895 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
3897 fxOverX0Layer[imat] = param[1];
3898 fxTimesRhoLayer[imat] = param[0]*param[4];
3899 } else if(imat==6) {
3900 fxOverX0Pipe = param[1];
3901 fxTimesRhoPipe = param[0]*param[4];
3902 } else if(imat==7) {
3903 fxOverX0Shield[0] = param[1];
3904 fxTimesRhoShield[0] = param[0]*param[4];
3905 } else if(imat==8) {
3906 fxOverX0Shield[1] = param[1];
3907 fxTimesRhoShield[1] = param[0]*param[4];
3911 printf("%s\n",material.Data());
3912 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
3913 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
3914 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
3915 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
3916 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
3917 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
3918 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
3919 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
3920 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
3924 //------------------------------------------------------------------------
3925 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
3926 TString direction) {
3927 //-------------------------------------------------------------------
3928 // Propagate beyond beam pipe and correct for material
3929 // (material budget in different ways according to fUseTGeo value)
3930 // Add time if going outward (PropagateTo or PropagateToTGeo)
3931 //-------------------------------------------------------------------
3933 // Define budget mode:
3934 // 0: material from AliITSRecoParam (hard coded)
3935 // 1: material from TGeo in one step (on the fly)
3936 // 2: material from lut
3937 // 3: material from TGeo in one step (same for all hypotheses)
3950 if(fTrackingPhase.Contains("Clusters2Tracks"))
3951 { mode=3; } else { mode=1; }
3954 if(fTrackingPhase.Contains("Clusters2Tracks"))
3955 { mode=3; } else { mode=2; }
3961 if(fTrackingPhase.Contains("Default")) mode=0;
3963 Int_t index=fCurrentEsdTrack;
3965 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
3966 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
3968 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
3970 Double_t xOverX0,x0,lengthTimesMeanDensity;
3974 xOverX0 = AliITSRecoParam::GetdPipe();
3975 x0 = AliITSRecoParam::GetX0Be();
3976 lengthTimesMeanDensity = xOverX0*x0;
3977 lengthTimesMeanDensity *= dir;
3978 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3981 if (!t->PropagateToTGeo(xToGo,1)) return 0;
3984 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
3985 xOverX0 = fxOverX0Pipe;
3986 lengthTimesMeanDensity = fxTimesRhoPipe;
3987 lengthTimesMeanDensity *= dir;
3988 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3991 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
3992 if(fxOverX0PipeTrks[index]<0) {
3993 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
3994 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
3995 ((1.-t->GetSnp())*(1.+t->GetSnp())));
3996 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
3997 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4000 xOverX0 = fxOverX0PipeTrks[index];
4001 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4002 lengthTimesMeanDensity *= dir;
4003 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4009 //------------------------------------------------------------------------
4010 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4012 TString direction) {
4013 //-------------------------------------------------------------------
4014 // Propagate beyond SPD or SDD shield and correct for material
4015 // (material budget in different ways according to fUseTGeo value)
4016 // Add time if going outward (PropagateTo or PropagateToTGeo)
4017 //-------------------------------------------------------------------
4019 // Define budget mode:
4020 // 0: material from AliITSRecoParam (hard coded)
4021 // 1: material from TGeo in steps of X cm (on the fly)
4022 // X = AliITSRecoParam::GetStepSizeTGeo()
4023 // 2: material from lut
4024 // 3: material from TGeo in one step (same for all hypotheses)
4037 if(fTrackingPhase.Contains("Clusters2Tracks"))
4038 { mode=3; } else { mode=1; }
4041 if(fTrackingPhase.Contains("Clusters2Tracks"))
4042 { mode=3; } else { mode=2; }
4048 if(fTrackingPhase.Contains("Default")) mode=0;
4050 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4052 Int_t shieldindex=0;
4053 if (shield.Contains("SDD")) { // SDDouter
4054 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4056 } else if (shield.Contains("SPD")) { // SPDouter
4057 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4060 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4064 // do nothing if we are already beyond the shield
4065 Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4066 if(dir<0 && rTrack > rToGo) return 1; // going outward
4067 if(dir>0 && rTrack < rToGo) return 1; // going inward
4071 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4073 Int_t index=2*fCurrentEsdTrack+shieldindex;
4075 Double_t xOverX0,x0,lengthTimesMeanDensity;
4080 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4081 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4082 lengthTimesMeanDensity = xOverX0*x0;
4083 lengthTimesMeanDensity *= dir;
4084 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4087 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4088 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4091 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4092 xOverX0 = fxOverX0Shield[shieldindex];
4093 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4094 lengthTimesMeanDensity *= dir;
4095 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4098 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4099 if(fxOverX0ShieldTrks[index]<0) {
4100 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4101 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4102 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4103 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4104 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4107 xOverX0 = fxOverX0ShieldTrks[index];
4108 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4109 lengthTimesMeanDensity *= dir;
4110 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4116 //------------------------------------------------------------------------
4117 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4119 Double_t oldGlobXYZ[3],
4120 TString direction) {
4121 //-------------------------------------------------------------------
4122 // Propagate beyond layer and correct for material
4123 // (material budget in different ways according to fUseTGeo value)
4124 // Add time if going outward (PropagateTo or PropagateToTGeo)
4125 //-------------------------------------------------------------------
4127 // Define budget mode:
4128 // 0: material from AliITSRecoParam (hard coded)
4129 // 1: material from TGeo in stepsof X cm (on the fly)
4130 // X = AliITSRecoParam::GetStepSizeTGeo()
4131 // 2: material from lut
4132 // 3: material from TGeo in one step (same for all hypotheses)
4145 if(fTrackingPhase.Contains("Clusters2Tracks"))
4146 { mode=3; } else { mode=1; }
4149 if(fTrackingPhase.Contains("Clusters2Tracks"))
4150 { mode=3; } else { mode=2; }
4156 if(fTrackingPhase.Contains("Default")) mode=0;
4158 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4160 Double_t r=fgLayers[layerindex].GetR();
4161 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4163 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4165 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4167 Int_t index=6*fCurrentEsdTrack+layerindex;
4170 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4173 // back before material (no correction)
4175 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4176 if (!t->GetLocalXat(rOld,xOld)) return 0;
4177 if (!t->Propagate(xOld)) return 0;
4181 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4182 lengthTimesMeanDensity = xOverX0*x0;
4183 lengthTimesMeanDensity *= dir;
4184 // Bring the track beyond the material
4185 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4188 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4189 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4192 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4193 xOverX0 = fxOverX0Layer[layerindex];
4194 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4195 lengthTimesMeanDensity *= dir;
4196 // Bring the track beyond the material
4197 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4200 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4201 if(fxOverX0LayerTrks[index]<0) {
4202 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4203 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4204 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4205 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4206 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4207 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4210 xOverX0 = fxOverX0LayerTrks[index];
4211 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4212 lengthTimesMeanDensity *= dir;
4213 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4220 //------------------------------------------------------------------------
4221 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4222 //-----------------------------------------------------------------
4223 // Initialize LUT for storing material for each prolonged track
4224 //-----------------------------------------------------------------
4225 fxOverX0PipeTrks = new Float_t[ntracks];
4226 fxTimesRhoPipeTrks = new Float_t[ntracks];
4227 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4228 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4229 fxOverX0LayerTrks = new Float_t[ntracks*6];
4230 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4232 for(Int_t i=0; i<ntracks; i++) {
4233 fxOverX0PipeTrks[i] = -1.;
4234 fxTimesRhoPipeTrks[i] = -1.;
4236 for(Int_t j=0; j<ntracks*2; j++) {
4237 fxOverX0ShieldTrks[j] = -1.;
4238 fxTimesRhoShieldTrks[j] = -1.;
4240 for(Int_t k=0; k<ntracks*6; k++) {
4241 fxOverX0LayerTrks[k] = -1.;
4242 fxTimesRhoLayerTrks[k] = -1.;
4249 //------------------------------------------------------------------------
4250 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4251 //-----------------------------------------------------------------
4252 // Delete LUT for storing material for each prolonged track
4253 //-----------------------------------------------------------------
4254 if(fxOverX0PipeTrks) {
4255 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4257 if(fxOverX0ShieldTrks) {
4258 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4261 if(fxOverX0LayerTrks) {
4262 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4264 if(fxTimesRhoPipeTrks) {
4265 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4267 if(fxTimesRhoShieldTrks) {
4268 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4270 if(fxTimesRhoLayerTrks) {
4271 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4275 //------------------------------------------------------------------------
4276 void AliITStrackerMI::SetForceSkippingOfLayer() {
4277 //-----------------------------------------------------------------
4278 // Check if we are forced to skip layers
4279 // either we set to skip them in RecoParam
4280 // or they were off during data-taking
4281 //-----------------------------------------------------------------
4283 const AliEventInfo *eventInfo = GetEventInfo();
4285 for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
4286 fForceSkippingOfLayer[l] = 0;
4288 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
4292 AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
4294 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
4295 } else if(l==2 || l==3) {
4296 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1;
4298 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
4304 //------------------------------------------------------------------------
4305 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4306 Int_t ilayer,Int_t idet) const {
4307 //-----------------------------------------------------------------
4308 // This method is used to decide whether to allow a prolongation
4309 // without clusters, because we want to skip the layer.
4310 // In this case the return value is > 0:
4311 // return 1: the user requested to skip a layer
4312 // return 2: track outside z acceptance
4313 //-----------------------------------------------------------------
4315 if (ForceSkippingOfLayer(ilayer)) return 1;
4317 Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
4319 if (idet<0 && // out in z
4320 ilayer>innerLayCanSkip &&
4321 AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4322 // check if track will cross SPD outer layer
4323 Double_t phiAtSPD2,zAtSPD2;
4324 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4325 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4327 return 2; // always allow skipping, changed on 05.11.2009
4332 //------------------------------------------------------------------------
4333 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4334 Int_t ilayer,Int_t idet,
4335 Double_t dz,Double_t dy,
4336 Bool_t noClusters) const {
4337 //-----------------------------------------------------------------
4338 // This method is used to decide whether to allow a prolongation
4339 // without clusters, because there is a dead zone in the road.
4340 // In this case the return value is > 0:
4341 // return 1: dead zone at z=0,+-7cm in SPD
4342 // return 2: all road is "bad" (dead or noisy) from the OCDB
4343 // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4344 // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4345 //-----------------------------------------------------------------
4347 // check dead zones at z=0,+-7cm in the SPD
4348 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4349 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4350 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4351 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4352 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4353 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4354 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4355 for (Int_t i=0; i<3; i++)
4356 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4357 AliDebug(2,Form("crack SPD %d",ilayer));
4362 // check bad zones from OCDB
4363 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4365 if (idet<0) return 0;
4367 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4370 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4371 if (ilayer==0 || ilayer==1) { // ---------- SPD
4373 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4375 detSizeFactorX *= 2.;
4376 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4379 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4380 if (detType==2) segm->SetLayer(ilayer+1);
4381 Float_t detSizeX = detSizeFactorX*segm->Dx();
4382 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4384 // check if the road overlaps with bad chips
4386 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
4387 Float_t zlocmin = zloc-dz;
4388 Float_t zlocmax = zloc+dz;
4389 Float_t xlocmin = xloc-dy;
4390 Float_t xlocmax = xloc+dy;
4391 Int_t chipsInRoad[100];
4393 // check if road goes out of detector
4394 Bool_t touchNeighbourDet=kFALSE;
4395 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.5*detSizeX; touchNeighbourDet=kTRUE;}
4396 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.5*detSizeX; touchNeighbourDet=kTRUE;}
4397 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.5*detSizeZ; touchNeighbourDet=kTRUE;}
4398 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.5*detSizeZ; touchNeighbourDet=kTRUE;}
4399 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));
4401 // check if this detector is bad
4403 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4404 if(!touchNeighbourDet) {
4405 return 2; // all detectors in road are bad
4407 return 3; // at least one is bad
4411 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4412 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4413 if (!nChipsInRoad) return 0;
4415 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4416 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4417 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4418 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4419 if (det.IsChipBad(chipsInRoad[iCh])) {
4427 if(!touchNeighbourDet) {
4428 AliDebug(2,"all bad in road");
4429 return 2; // all chips in road are bad
4431 return 3; // at least a bad chip in road
4436 AliDebug(2,"at least a bad in road");
4437 return 3; // at least a bad chip in road
4441 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4442 || !noClusters) return 0;
4444 // There are no clusters in road: check if there is at least
4445 // a bad SPD pixel or SDD anode or SSD strips on both sides
4447 Int_t idetInITS=idet;
4448 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4450 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4451 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4454 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4458 //------------------------------------------------------------------------
4459 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4460 const AliITStrackMI *track,
4461 Float_t &xloc,Float_t &zloc) const {
4462 //-----------------------------------------------------------------
4463 // Gives position of track in local module ref. frame
4464 //-----------------------------------------------------------------
4469 if(idet<0) return kTRUE; // track out of z acceptance of layer
4471 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4473 Int_t lad = Int_t(idet/ndet) + 1;
4475 Int_t det = idet - (lad-1)*ndet + 1;
4477 Double_t xyzGlob[3],xyzLoc[3];
4479 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4480 // take into account the misalignment: xyz at real detector plane
4481 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4483 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4485 xloc = (Float_t)xyzLoc[0];
4486 zloc = (Float_t)xyzLoc[2];
4490 //------------------------------------------------------------------------
4491 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
4493 // Method to be optimized further:
4494 // Aim: decide whether a track can be used for PlaneEff evaluation
4495 // the decision is taken based on the track quality at the layer under study
4496 // no information on the clusters on this layer has to be used
4497 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4498 // the cut is done on number of sigmas from the boundaries
4500 // Input: Actual track, layer [0,5] under study
4502 // Return: kTRUE if this is a good track
4504 // it will apply a pre-selection to obtain good quality tracks.
4505 // Here also you will have the possibility to put a control on the
4506 // impact point of the track on the basic block, in order to exclude border regions
4507 // this will be done by calling a proper method of the AliITSPlaneEff class.
4509 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4510 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4512 Int_t index[AliITSgeomTGeo::kNLayers];
4514 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4516 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4517 index[k]=clusters[k];
4521 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4522 AliITSlayer &layer=fgLayers[ilayer];
4523 Double_t r=layer.GetR();
4524 AliITStrackMI tmp(*track);
4526 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4528 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) {
4529 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4530 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4531 if (tmp.GetClIndex(lay)>=0) ncl++;
4533 Bool_t nextout = kFALSE;
4534 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4535 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4536 Bool_t nextin = kFALSE;
4537 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4538 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4539 if(ncl<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
4541 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
4542 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
4543 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
4544 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
4548 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4549 Int_t idet=layer.FindDetectorIndex(phi,z);
4550 if(idet<0) { AliInfo(Form("cannot find detector"));
4553 // here check if it has good Chi Square.
4555 //propagate to the intersection with the detector plane
4556 const AliITSdetector &det=layer.GetDetector(idet);
4557 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4561 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
4562 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4563 if(key>fPlaneEff->Nblock()) return kFALSE;
4564 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4565 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4567 // DEFINITION OF SEARCH ROAD FOR accepting a track
4569 //For the time being they are hard-wired, later on from AliITSRecoParam
4570 // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
4571 // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
4574 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4575 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4576 // done for RecPoints
4578 // exclude tracks at boundary between detectors
4579 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
4580 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4581 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
4582 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
4583 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
4585 if ( (locx-dx < blockXmn+boundaryWidth) ||
4586 (locx+dx > blockXmx-boundaryWidth) ||
4587 (locz-dz < blockZmn+boundaryWidth) ||
4588 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
4591 //------------------------------------------------------------------------
4592 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
4594 // This Method has to be optimized! For the time-being it uses the same criteria
4595 // as those used in the search of extra clusters for overlapping modules.
4597 // Method Purpose: estabilish whether a track has produced a recpoint or not
4598 // in the layer under study (For Plane efficiency)
4600 // inputs: AliITStrackMI* track (pointer to a usable track)
4602 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
4603 // traversed by this very track. In details:
4604 // - if a cluster can be associated to the track then call
4605 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
4606 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
4609 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
4610 AliITSlayer &layer=fgLayers[ilayer];
4611 Double_t r=layer.GetR();
4612 AliITStrackMI tmp(*track);
4616 if (!tmp.GetPhiZat(r,phi,z)) return;
4617 Int_t idet=layer.FindDetectorIndex(phi,z);
4619 if(idet<0) { AliInfo(Form("cannot find detector"));
4623 //propagate to the intersection with the detector plane
4624 const AliITSdetector &det=layer.GetDetector(idet);
4625 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
4629 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
4631 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
4632 TMath::Sqrt(tmp.GetSigmaZ2() +
4633 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4634 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4635 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
4636 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
4637 TMath::Sqrt(tmp.GetSigmaY2() +
4638 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4639 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4640 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
4642 // road in global (rphi,z) [i.e. in tracking ref. system]
4643 Double_t zmin = tmp.GetZ() - dz;
4644 Double_t zmax = tmp.GetZ() + dz;
4645 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
4646 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
4648 // select clusters in road
4649 layer.SelectClusters(zmin,zmax,ymin,ymax);
4651 // Define criteria for track-cluster association
4652 Double_t msz = tmp.GetSigmaZ2() +
4653 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4654 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4655 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
4656 Double_t msy = tmp.GetSigmaY2() +
4657 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4658 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4659 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
4660 if (tmp.GetConstrain()) {
4661 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
4662 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
4664 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
4665 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
4667 msz = 1./msz; // 1/RoadZ^2
4668 msy = 1./msy; // 1/RoadY^2
4671 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
4673 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
4674 //Double_t tolerance=0.2;
4675 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
4676 idetc = cl->GetDetectorIndex();
4677 if(idet!=idetc) continue;
4678 //Int_t ilay = cl->GetLayer();
4680 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
4681 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
4683 Double_t chi2=tmp.GetPredictedChi2(cl);
4684 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
4688 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
4690 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
4691 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4692 if(key>fPlaneEff->Nblock()) return;
4693 Bool_t found=kFALSE;
4696 while ((cl=layer.GetNextCluster(clidx))!=0) {
4697 idetc = cl->GetDetectorIndex();
4698 if(idet!=idetc) continue;
4699 // here real control to see whether the cluster can be associated to the track.
4700 // cluster not associated to track
4701 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
4702 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
4703 // calculate track-clusters chi2
4704 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
4705 // in particular, the error associated to the cluster
4706 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
4708 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
4710 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
4711 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
4712 // track->SetExtraModule(ilayer,idetExtra);
4714 if(!fPlaneEff->UpDatePlaneEff(found,key))
4715 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
4716 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
4717 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
4718 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
4719 Int_t cltype[2]={-999,-999};
4723 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4724 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4727 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
4728 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
4729 cltype[0]=layer.GetCluster(ci)->GetNy();
4730 cltype[1]=layer.GetCluster(ci)->GetNz();
4732 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
4733 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
4734 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
4735 // It is computed properly by calling the method
4736 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4738 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
4739 //if (tmp.PropagateTo(x,0.,0.)) {
4740 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
4741 AliCluster c(*layer.GetCluster(ci));
4742 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
4743 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
4744 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
4745 clu[2]=TMath::Sqrt(c.GetSigmaY2());
4746 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
4749 fPlaneEff->FillHistos(key,found,tr,clu,cltype);