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 "AliITSRecPointContainer.h"
54 #include "AliITSgeomTGeo.h"
55 #include "AliITSReconstructor.h"
56 #include "AliITSClusterParam.h"
57 #include "AliITSsegmentation.h"
58 #include "AliITSCalibration.h"
59 #include "AliITSPlaneEffSPD.h"
60 #include "AliITSPlaneEffSDD.h"
61 #include "AliITSPlaneEffSSD.h"
62 #include "AliITSV0Finder.h"
63 #include "AliITStrackerMI.h"
65 ClassImp(AliITStrackerMI)
67 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
69 AliITStrackerMI::AliITStrackerMI():AliTracker(),
79 fLastLayerToTrackTo(0),
82 fTrackingPhase("Default"),
88 fxTimesRhoPipeTrks(0),
89 fxOverX0ShieldTrks(0),
90 fxTimesRhoShieldTrks(0),
92 fxTimesRhoLayerTrks(0),
99 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
100 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
101 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
103 //------------------------------------------------------------------------
104 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
105 fI(AliITSgeomTGeo::GetNLayers()),
114 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
117 fTrackingPhase("Default"),
123 fxTimesRhoPipeTrks(0),
124 fxOverX0ShieldTrks(0),
125 fxTimesRhoShieldTrks(0),
126 fxOverX0LayerTrks(0),
127 fxTimesRhoLayerTrks(0),
129 fITSChannelStatus(0),
132 //--------------------------------------------------------------------
133 //This is the AliITStrackerMI constructor
134 //--------------------------------------------------------------------
136 AliWarning("\"geom\" is actually a dummy argument !");
142 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
143 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
144 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
146 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
147 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
148 Double_t poff=TMath::ATan2(y,x);
150 Double_t r=TMath::Sqrt(x*x + y*y);
152 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
153 r += TMath::Sqrt(x*x + y*y);
154 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
155 r += TMath::Sqrt(x*x + y*y);
156 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
157 r += TMath::Sqrt(x*x + y*y);
160 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
162 for (Int_t j=1; j<nlad+1; j++) {
163 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
164 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
165 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
167 Double_t txyz[3]={0.};
168 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
169 m.LocalToMaster(txyz,xyz);
170 r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
171 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
173 if (phi<0) phi+=TMath::TwoPi();
174 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
176 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
177 new(&det) AliITSdetector(r,phi);
178 // compute the real radius (with misalignment)
179 TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
181 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
182 mmisal.LocalToMaster(txyz,xyz);
183 Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
184 det.SetRmisal(rmisal);
186 } // end loop on detectors
187 } // end loop on ladders
188 fForceSkippingOfLayer[i] = 0;
189 } // end loop on layers
192 fI=AliITSgeomTGeo::GetNLayers();
195 fConstraint[0]=1; fConstraint[1]=0;
197 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
198 AliITSReconstructor::GetRecoParam()->GetYVdef(),
199 AliITSReconstructor::GetRecoParam()->GetZVdef()};
200 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
201 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
202 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
203 SetVertex(xyzVtx,ersVtx);
205 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
206 for (Int_t i=0;i<100000;i++){
207 fBestTrackIndex[i]=0;
210 // store positions of centre of SPD modules (in z)
212 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
213 fSPDdetzcentre[0] = tr[2];
214 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
215 fSPDdetzcentre[1] = tr[2];
216 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
217 fSPDdetzcentre[2] = tr[2];
218 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
219 fSPDdetzcentre[3] = tr[2];
221 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
222 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
223 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
227 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
228 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
230 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
232 // only for plane efficiency evaluation
233 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
234 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
235 Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
236 if(!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)==1)
237 AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
238 if (iplane<2) fPlaneEff = new AliITSPlaneEffSPD();
239 else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
240 else fPlaneEff = new AliITSPlaneEffSSD();
241 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
242 if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
243 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
246 //------------------------------------------------------------------------
247 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
249 fBestTrack(tracker.fBestTrack),
250 fTrackToFollow(tracker.fTrackToFollow),
251 fTrackHypothesys(tracker.fTrackHypothesys),
252 fBestHypothesys(tracker.fBestHypothesys),
253 fOriginal(tracker.fOriginal),
254 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
255 fPass(tracker.fPass),
256 fAfterV0(tracker.fAfterV0),
257 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
258 fCoefficients(tracker.fCoefficients),
260 fTrackingPhase(tracker.fTrackingPhase),
261 fUseTGeo(tracker.fUseTGeo),
262 fNtracks(tracker.fNtracks),
263 fxOverX0Pipe(tracker.fxOverX0Pipe),
264 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
266 fxTimesRhoPipeTrks(0),
267 fxOverX0ShieldTrks(0),
268 fxTimesRhoShieldTrks(0),
269 fxOverX0LayerTrks(0),
270 fxTimesRhoLayerTrks(0),
271 fDebugStreamer(tracker.fDebugStreamer),
272 fITSChannelStatus(tracker.fITSChannelStatus),
273 fkDetTypeRec(tracker.fkDetTypeRec),
274 fPlaneEff(tracker.fPlaneEff) {
278 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
281 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
282 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
285 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
286 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
289 //------------------------------------------------------------------------
290 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
291 //Assignment operator
292 this->~AliITStrackerMI();
293 new(this) AliITStrackerMI(tracker);
296 //------------------------------------------------------------------------
297 AliITStrackerMI::~AliITStrackerMI()
302 if (fCoefficients) delete [] fCoefficients;
303 DeleteTrksMaterialLUT();
304 if (fDebugStreamer) {
305 //fDebugStreamer->Close();
306 delete fDebugStreamer;
308 if(fITSChannelStatus) delete fITSChannelStatus;
309 if(fPlaneEff) delete fPlaneEff;
311 //------------------------------------------------------------------------
312 void AliITStrackerMI::ReadBadFromDetTypeRec() {
313 //--------------------------------------------------------------------
314 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
316 //--------------------------------------------------------------------
318 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
320 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
322 if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
325 if(fITSChannelStatus) delete fITSChannelStatus;
326 fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
328 // ITS detectors and chips
329 Int_t i=0,j=0,k=0,ndet=0;
330 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
331 Int_t nBadDetsPerLayer=0;
332 ndet=AliITSgeomTGeo::GetNDetectors(i);
333 for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
334 for (k=1; k<ndet+1; k++) {
335 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
336 det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fkDetTypeRec);
337 if(det.IsBad()) {nBadDetsPerLayer++;}
338 } // end loop on detectors
339 } // end loop on ladders
340 Info("ReadBadFromDetTypeRec",Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
341 } // end loop on layers
345 //------------------------------------------------------------------------
346 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
347 //--------------------------------------------------------------------
348 //This function loads ITS clusters
349 //--------------------------------------------------------------------
351 TBranch *branch=cTree->GetBranch("ITSRecPoints");
353 Error("LoadClusters"," can't get the branch !\n");
357 static TClonesArray dummy("AliITSRecPoint",10000), *clusters=&dummy;
358 branch->SetAddress(&clusters);
360 TClonesArray *clusters = NULL;
361 AliITSRecPointContainer* rpcont=AliITSRecPointContainer::Instance();
362 clusters=rpcont->FetchClusters(0,cTree);
363 if(!(rpcont->IsSPDActive() || rpcont->IsSDDActive() || rpcont->IsSSDActive())){
364 AliError("ITS is not in a known running configuration: SPD, SDD and SSD are not active");
367 Int_t i=0,j=0,ndet=0;
369 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
370 ndet=fgLayers[i].GetNdetectors();
371 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
372 for (; j<jmax; j++) {
373 // if (!cTree->GetEvent(j)) continue;
374 clusters = rpcont->UncheckedGetClusters(j);
375 if(!clusters)continue;
376 Int_t ncl=clusters->GetEntriesFast();
377 SignDeltas(clusters,GetZ());
380 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
381 detector=c->GetDetectorIndex();
383 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
385 fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
387 // clusters->Clear();
388 // add dead zone "virtual" cluster in SPD, if there is a cluster within
389 // zwindow cm from the dead zone
390 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
391 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
392 Int_t lab[4] = {0,0,0,detector};
393 Int_t info[3] = {0,0,i};
394 Float_t q = 0.; // this identifies virtual clusters
395 Float_t hit[5] = {xdead,
397 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
398 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
400 Bool_t local = kTRUE;
401 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
402 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
403 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
404 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
405 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
406 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
407 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
408 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
409 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
410 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
411 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
412 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
413 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
414 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
415 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
416 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
417 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
418 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
419 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
421 } // "virtual" clusters in SPD
425 fgLayers[i].ResetRoad(); //road defined by the cluster density
426 fgLayers[i].SortClusters();
429 // check whether we have to skip some layers
430 SetForceSkippingOfLayer();
434 //------------------------------------------------------------------------
435 void AliITStrackerMI::UnloadClusters() {
436 //--------------------------------------------------------------------
437 //This function unloads ITS clusters
438 //--------------------------------------------------------------------
439 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
441 //------------------------------------------------------------------------
442 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
443 //--------------------------------------------------------------------
444 // Publishes all pointers to clusters known to the tracker into the
445 // passed object array.
446 // The ownership is not transfered - the caller is not expected to delete
448 //--------------------------------------------------------------------
450 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
451 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
452 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
459 //------------------------------------------------------------------------
460 Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
461 //--------------------------------------------------------------------
462 // Correction for the material between the TPC and the ITS
463 //--------------------------------------------------------------------
464 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
465 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
466 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
467 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
468 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
469 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
470 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
471 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
473 printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
479 //------------------------------------------------------------------------
480 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
481 //--------------------------------------------------------------------
482 // This functions reconstructs ITS tracks
483 // The clusters must be already loaded !
484 //--------------------------------------------------------------------
486 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
488 fTrackingPhase="Clusters2Tracks";
490 TObjArray itsTracks(15000);
492 fEsd = event; // store pointer to the esd
494 // temporary (for cosmics)
495 if(event->GetVertex()) {
496 TString title = event->GetVertex()->GetTitle();
497 if(title.Contains("cosmics")) {
498 Double_t xyz[3]={GetX(),GetY(),GetZ()};
499 Double_t exyz[3]={0.1,0.1,0.1};
505 {/* Read ESD tracks */
506 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
507 Int_t nentr=event->GetNumberOfTracks();
508 Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
510 AliESDtrack *esd=event->GetTrack(nentr);
511 // ---- for debugging:
512 //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); }
514 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
515 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
516 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
517 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
520 t=new AliITStrackMI(*esd);
521 } catch (const Char_t *msg) {
522 //Warning("Clusters2Tracks",msg);
526 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
527 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
530 // look at the ESD mass hypothesys !
531 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
533 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
535 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
536 //track - can be V0 according to TPC
538 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
542 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
546 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
550 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
555 t->SetReconstructed(kFALSE);
556 itsTracks.AddLast(t);
557 fOriginal.AddLast(t);
559 } /* End Read ESD tracks */
563 Int_t nentr=itsTracks.GetEntriesFast();
564 fTrackHypothesys.Expand(nentr);
565 fBestHypothesys.Expand(nentr);
566 MakeCoefficients(nentr);
567 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
569 // THE TWO TRACKING PASSES
570 for (fPass=0; fPass<2; fPass++) {
571 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
572 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
573 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
574 if (t==0) continue; //this track has been already tracked
575 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
576 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
577 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
578 if (fConstraint[fPass]) {
579 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
580 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
583 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
584 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
586 ResetTrackToFollow(*t);
589 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
592 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
594 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
595 if (!besttrack) continue;
596 besttrack->SetLabel(tpcLabel);
597 // besttrack->CookdEdx();
599 besttrack->SetFakeRatio(1.);
600 CookLabel(besttrack,0.); //For comparison only
601 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
603 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
605 t->SetReconstructed(kTRUE);
607 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
609 GetBestHypothesysMIP(itsTracks);
610 } // end loop on the two tracking passes
612 if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
613 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
618 Int_t entries = fTrackHypothesys.GetEntriesFast();
619 for (Int_t ientry=0; ientry<entries; ientry++) {
620 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
621 if (array) array->Delete();
622 delete fTrackHypothesys.RemoveAt(ientry);
625 fTrackHypothesys.Delete();
626 fBestHypothesys.Delete();
628 delete [] fCoefficients;
630 DeleteTrksMaterialLUT();
632 Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
634 fTrackingPhase="Default";
638 //------------------------------------------------------------------------
639 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
640 //--------------------------------------------------------------------
641 // This functions propagates reconstructed ITS tracks back
642 // The clusters must be loaded !
643 //--------------------------------------------------------------------
644 fTrackingPhase="PropagateBack";
645 Int_t nentr=event->GetNumberOfTracks();
646 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
649 for (Int_t i=0; i<nentr; i++) {
650 AliESDtrack *esd=event->GetTrack(i);
652 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
653 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
657 t=new AliITStrackMI(*esd);
658 } catch (const Char_t *msg) {
659 //Warning("PropagateBack",msg);
663 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
665 ResetTrackToFollow(*t);
668 // propagate to vertex [SR, GSI 17.02.2003]
669 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
670 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
671 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
672 fTrackToFollow.StartTimeIntegral();
673 // from vertex to outside pipe
674 CorrectForPipeMaterial(&fTrackToFollow,"outward");
676 // Start time integral and add distance from current position to vertex
677 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
678 fTrackToFollow.GetXYZ(xyzTrk);
680 for (Int_t icoord=0; icoord<3; icoord++) {
681 Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
684 fTrackToFollow.StartTimeIntegral();
685 fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
687 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
688 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
689 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
693 fTrackToFollow.SetLabel(t->GetLabel());
694 //fTrackToFollow.CookdEdx();
695 CookLabel(&fTrackToFollow,0.); //For comparison only
696 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
697 //UseClusters(&fTrackToFollow);
703 Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
705 fTrackingPhase="Default";
709 //------------------------------------------------------------------------
710 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
711 //--------------------------------------------------------------------
712 // This functions refits ITS tracks using the
713 // "inward propagated" TPC tracks
714 // The clusters must be loaded !
715 //--------------------------------------------------------------------
716 fTrackingPhase="RefitInward";
718 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
720 Int_t nentr=event->GetNumberOfTracks();
721 Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
724 for (Int_t i=0; i<nentr; i++) {
725 AliESDtrack *esd=event->GetTrack(i);
727 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
728 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
729 if (esd->GetStatus()&AliESDtrack::kTPCout)
730 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
734 t=new AliITStrackMI(*esd);
735 } catch (const Char_t *msg) {
736 //Warning("RefitInward",msg);
740 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
741 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
746 ResetTrackToFollow(*t);
747 fTrackToFollow.ResetClusters();
749 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
750 fTrackToFollow.ResetCovariance(10.);
753 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
754 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
756 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
757 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
758 AliDebug(2," refit OK");
759 fTrackToFollow.SetLabel(t->GetLabel());
760 // fTrackToFollow.CookdEdx();
761 CookdEdx(&fTrackToFollow);
763 CookLabel(&fTrackToFollow,0.0); //For comparison only
766 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
767 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
768 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
769 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
770 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
771 Double_t r[3]={0.,0.,0.};
773 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
780 Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
782 fTrackingPhase="Default";
786 //------------------------------------------------------------------------
787 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
788 //--------------------------------------------------------------------
789 // Return pointer to a given cluster
790 //--------------------------------------------------------------------
791 Int_t l=(index & 0xf0000000) >> 28;
792 Int_t c=(index & 0x0fffffff) >> 00;
793 return fgLayers[l].GetCluster(c);
795 //------------------------------------------------------------------------
796 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
797 //--------------------------------------------------------------------
798 // Get track space point with index i
799 //--------------------------------------------------------------------
801 Int_t l=(index & 0xf0000000) >> 28;
802 Int_t c=(index & 0x0fffffff) >> 00;
803 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
804 Int_t idet = cl->GetDetectorIndex();
808 cl->GetGlobalXYZ(xyz);
809 cl->GetGlobalCov(cov);
811 p.SetCharge(cl->GetQ());
812 p.SetDriftTime(cl->GetDriftTime());
813 p.SetChargeRatio(cl->GetChargeRatio());
814 p.SetClusterType(cl->GetClusterType());
815 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
818 iLayer = AliGeomManager::kSPD1;
821 iLayer = AliGeomManager::kSPD2;
824 iLayer = AliGeomManager::kSDD1;
827 iLayer = AliGeomManager::kSDD2;
830 iLayer = AliGeomManager::kSSD1;
833 iLayer = AliGeomManager::kSSD2;
836 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
839 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
840 p.SetVolumeID((UShort_t)volid);
843 //------------------------------------------------------------------------
844 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
845 AliTrackPoint& p, const AliESDtrack *t) {
846 //--------------------------------------------------------------------
847 // Get track space point with index i
848 // (assign error estimated during the tracking)
849 //--------------------------------------------------------------------
851 Int_t l=(index & 0xf0000000) >> 28;
852 Int_t c=(index & 0x0fffffff) >> 00;
853 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
854 Int_t idet = cl->GetDetectorIndex();
856 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
858 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
860 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
861 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
862 Double_t alpha = t->GetAlpha();
863 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
864 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,GetBz()));
865 phi += alpha-det.GetPhi();
866 Float_t tgphi = TMath::Tan(phi);
868 Float_t tgl = t->GetTgl(); // tgl about const along track
869 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
871 Float_t errtrky,errtrkz,covyz;
872 Bool_t addMisalErr=kFALSE;
873 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
877 cl->GetGlobalXYZ(xyz);
878 // cl->GetGlobalCov(cov);
879 Float_t pos[3] = {0.,0.,0.};
880 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
881 tmpcl.GetGlobalCov(cov);
884 p.SetCharge(cl->GetQ());
885 p.SetDriftTime(cl->GetDriftTime());
886 p.SetChargeRatio(cl->GetChargeRatio());
887 p.SetClusterType(cl->GetClusterType());
889 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
892 iLayer = AliGeomManager::kSPD1;
895 iLayer = AliGeomManager::kSPD2;
898 iLayer = AliGeomManager::kSDD1;
901 iLayer = AliGeomManager::kSDD2;
904 iLayer = AliGeomManager::kSSD1;
907 iLayer = AliGeomManager::kSSD2;
910 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
913 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
915 p.SetVolumeID((UShort_t)volid);
918 //------------------------------------------------------------------------
919 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
921 //--------------------------------------------------------------------
922 // Follow prolongation tree
923 //--------------------------------------------------------------------
925 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
926 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
929 AliESDtrack * esd = otrack->GetESDtrack();
930 if (esd->GetV0Index(0)>0) {
931 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
932 // mapping of ESD track is different as ITS track in Containers
933 // Need something more stable
934 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
935 for (Int_t i=0;i<3;i++){
936 Int_t index = esd->GetV0Index(i);
938 AliESDv0 * vertex = fEsd->GetV0(index);
939 if (vertex->GetStatus()<0) continue; // rejected V0
941 if (esd->GetSign()>0) {
942 vertex->SetIndex(0,esdindex);
944 vertex->SetIndex(1,esdindex);
948 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
950 bestarray = new TObjArray(5);
951 fBestHypothesys.AddAt(bestarray,esdindex);
955 //setup tree of the prolongations
957 static AliITStrackMI tracks[7][100];
958 AliITStrackMI *currenttrack;
959 static AliITStrackMI currenttrack1;
960 static AliITStrackMI currenttrack2;
961 static AliITStrackMI backuptrack;
963 Int_t nindexes[7][100];
964 Float_t normalizedchi2[100];
965 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
966 otrack->SetNSkipped(0);
967 new (&(tracks[6][0])) AliITStrackMI(*otrack);
969 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
970 Int_t modstatus = 1; // found
974 // follow prolongations
975 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
976 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
979 AliITSlayer &layer=fgLayers[ilayer];
980 Double_t r = layer.GetR();
986 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
988 if (ntracks[ilayer]>=100) break;
989 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
990 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
991 if (ntracks[ilayer]>15+ilayer){
992 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
993 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
996 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
998 // material between SSD and SDD, SDD and SPD
1000 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
1002 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
1006 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
1007 Int_t idet=layer.FindDetectorIndex(phi,z);
1009 Double_t trackGlobXYZ1[3];
1010 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1012 // Get the budget to the primary vertex for the current track being prolonged
1013 Double_t budgetToPrimVertex = GetEffectiveThickness();
1015 // check if we allow a prolongation without point
1016 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1018 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1019 // propagate to the layer radius
1020 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1021 if(!vtrack->Propagate(xToGo)) continue;
1022 // apply correction for material of the current layer
1023 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1024 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1025 vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1026 vtrack->SetClIndex(ilayer,-1);
1027 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1028 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1029 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1031 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1036 // track outside layer acceptance in z
1037 if (idet<0) continue;
1039 //propagate to the intersection with the detector plane
1040 const AliITSdetector &det=layer.GetDetector(idet);
1041 new(¤ttrack2) AliITStrackMI(currenttrack1);
1042 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1043 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1044 currenttrack1.SetDetectorIndex(idet);
1045 currenttrack2.SetDetectorIndex(idet);
1046 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1049 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1051 // road in global (rphi,z) [i.e. in tracking ref. system]
1052 Double_t zmin,zmax,ymin,ymax;
1053 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1055 // select clusters in road
1056 layer.SelectClusters(zmin,zmax,ymin,ymax);
1057 //********************
1059 // Define criteria for track-cluster association
1060 Double_t msz = currenttrack1.GetSigmaZ2() +
1061 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1062 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1063 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1064 Double_t msy = currenttrack1.GetSigmaY2() +
1065 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1066 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1067 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1069 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1070 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1072 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1073 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1075 msz = 1./msz; // 1/RoadZ^2
1076 msy = 1./msy; // 1/RoadY^2
1080 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1082 const AliITSRecPoint *cl=0;
1084 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1085 Bool_t deadzoneSPD=kFALSE;
1086 currenttrack = ¤ttrack1;
1088 // check if the road contains a dead zone
1089 Bool_t noClusters = kFALSE;
1090 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1091 if (noClusters) AliDebug(2,"no clusters in road");
1092 Double_t dz=0.5*(zmax-zmin);
1093 Double_t dy=0.5*(ymax-ymin);
1094 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1095 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1096 // create a prolongation without clusters (check also if there are no clusters in the road)
1099 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1100 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1101 updatetrack->SetClIndex(ilayer,-1);
1103 modstatus = 5; // no cls in road
1104 } else if (dead==1) {
1105 modstatus = 7; // holes in z in SPD
1106 } else if (dead==2 || dead==3 || dead==4) {
1107 modstatus = 2; // dead from OCDB
1109 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1110 // apply correction for material of the current layer
1111 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1112 if (constrain) { // apply vertex constrain
1113 updatetrack->SetConstrain(constrain);
1114 Bool_t isPrim = kTRUE;
1115 if (ilayer<4) { // check that it's close to the vertex
1116 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1117 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1118 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1119 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1120 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1122 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1124 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1126 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1127 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1129 } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1130 updatetrack->SetDeadZoneProbability(ilayer,1.);
1131 } else if (dead==4) { // at least a single dead channel from OCDB
1132 updatetrack->SetDeadZoneProbability(ilayer,0.);
1139 // loop over clusters in the road
1140 while ((cl=layer.GetNextCluster(clidx))!=0) {
1141 if (ntracks[ilayer]>95) break; //space for skipped clusters
1142 Bool_t changedet =kFALSE;
1143 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
1144 Int_t idetc=cl->GetDetectorIndex();
1146 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1147 // take into account misalignment (bring track to real detector plane)
1148 Double_t xTrOrig = currenttrack->GetX();
1149 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1150 // a first cut on track-cluster distance
1151 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1152 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1153 { // cluster not associated to track
1154 AliDebug(2,"not associated");
1157 // bring track back to ideal detector plane
1158 if (!currenttrack->Propagate(xTrOrig)) continue;
1159 } else { // have to move track to cluster's detector
1160 const AliITSdetector &detc=layer.GetDetector(idetc);
1161 // a first cut on track-cluster distance
1163 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1164 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1165 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1166 continue; // cluster not associated to track
1168 new (&backuptrack) AliITStrackMI(currenttrack2);
1170 currenttrack =¤ttrack2;
1171 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1172 new (currenttrack) AliITStrackMI(backuptrack);
1176 currenttrack->SetDetectorIndex(idetc);
1177 // Get again the budget to the primary vertex
1178 // for the current track being prolonged, if had to change detector
1179 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1182 // calculate track-clusters chi2
1183 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1185 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1186 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1187 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1188 if (ntracks[ilayer]>=100) continue;
1189 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1190 updatetrack->SetClIndex(ilayer,-1);
1191 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1193 if (cl->GetQ()!=0) { // real cluster
1194 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1195 AliDebug(2,"update failed");
1198 updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1199 modstatus = 1; // found
1200 } else { // virtual cluster in dead zone
1201 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1202 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1203 modstatus = 7; // holes in z in SPD
1207 Float_t xlocnewdet,zlocnewdet;
1208 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1209 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1212 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1214 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1216 // apply correction for material of the current layer
1217 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1219 if (constrain) { // apply vertex constrain
1220 updatetrack->SetConstrain(constrain);
1221 Bool_t isPrim = kTRUE;
1222 if (ilayer<4) { // check that it's close to the vertex
1223 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1224 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1225 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1226 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1227 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1229 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1230 } //apply vertex constrain
1232 } // create new hypothesis
1234 AliDebug(2,"chi2 too large");
1237 } // loop over possible prolongations
1239 // allow one prolongation without clusters
1240 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1241 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1242 // apply correction for material of the current layer
1243 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1244 vtrack->SetClIndex(ilayer,-1);
1245 modstatus = 3; // skipped
1246 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1247 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1248 vtrack->IncrementNSkipped();
1252 // allow one prolongation without clusters for tracks with |tgl|>1.1
1253 if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) { //big theta - for low flux
1254 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1255 // apply correction for material of the current layer
1256 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1257 vtrack->SetClIndex(ilayer,-1);
1258 modstatus = 3; // skipped
1259 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1260 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1261 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1266 } // loop over tracks in layer ilayer+1
1268 //loop over track candidates for the current layer
1274 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1275 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1276 if (normalizedchi2[itrack] <
1277 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1281 if (constrain) { // constrain
1282 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1284 } else { // !constrain
1285 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1290 // sort tracks by increasing normalized chi2
1291 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1292 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1293 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1294 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1295 } // end loop over layers
1299 // Now select tracks to be kept
1301 Int_t max = constrain ? 20 : 5;
1303 // tracks that reach layer 0 (SPD inner)
1304 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1305 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1306 if (track.GetNumberOfClusters()<2) continue;
1307 if (!constrain && track.GetNormChi2(0) >
1308 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1311 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1314 // tracks that reach layer 1 (SPD outer)
1315 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1316 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1317 if (track.GetNumberOfClusters()<4) continue;
1318 if (!constrain && track.GetNormChi2(1) >
1319 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1320 if (constrain) track.IncrementNSkipped();
1322 track.SetD(0,track.GetD(GetX(),GetY()));
1323 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1324 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1325 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1328 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1331 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1333 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1334 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1335 if (track.GetNumberOfClusters()<3) continue;
1336 if (!constrain && track.GetNormChi2(2) >
1337 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1338 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1340 track.SetD(0,track.GetD(GetX(),GetY()));
1341 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1342 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1343 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1346 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1352 // register best track of each layer - important for V0 finder
1354 for (Int_t ilayer=0;ilayer<5;ilayer++){
1355 if (ntracks[ilayer]==0) continue;
1356 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1357 if (track.GetNumberOfClusters()<1) continue;
1358 CookLabel(&track,0);
1359 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1363 // update TPC V0 information
1365 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1366 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1367 for (Int_t i=0;i<3;i++){
1368 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1369 if (index==0) break;
1370 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1371 if (vertex->GetStatus()<0) continue; // rejected V0
1373 if (otrack->GetSign()>0) {
1374 vertex->SetIndex(0,esdindex);
1377 vertex->SetIndex(1,esdindex);
1379 //find nearest layer with track info
1380 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1381 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1382 Int_t nearest = nearestold;
1383 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1384 if (ntracks[nearest]==0){
1389 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1390 if (nearestold<5&&nearest<5){
1391 Bool_t accept = track.GetNormChi2(nearest)<10;
1393 if (track.GetSign()>0) {
1394 vertex->SetParamP(track);
1395 vertex->Update(fprimvertex);
1396 //vertex->SetIndex(0,track.fESDtrack->GetID());
1397 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1399 vertex->SetParamN(track);
1400 vertex->Update(fprimvertex);
1401 //vertex->SetIndex(1,track.fESDtrack->GetID());
1402 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1404 vertex->SetStatus(vertex->GetStatus()+1);
1406 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1413 //------------------------------------------------------------------------
1414 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1416 //--------------------------------------------------------------------
1419 return fgLayers[layer];
1421 //------------------------------------------------------------------------
1422 AliITStrackerMI::AliITSlayer::AliITSlayer():
1452 //--------------------------------------------------------------------
1453 //default AliITSlayer constructor
1454 //--------------------------------------------------------------------
1455 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1456 fClusterWeight[i]=0;
1457 fClusterTracks[0][i]=-1;
1458 fClusterTracks[1][i]=-1;
1459 fClusterTracks[2][i]=-1;
1460 fClusterTracks[3][i]=-1;
1463 //------------------------------------------------------------------------
1464 AliITStrackerMI::AliITSlayer::
1465 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1494 //--------------------------------------------------------------------
1495 //main AliITSlayer constructor
1496 //--------------------------------------------------------------------
1497 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1498 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1500 //------------------------------------------------------------------------
1501 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1503 fPhiOffset(layer.fPhiOffset),
1504 fNladders(layer.fNladders),
1505 fZOffset(layer.fZOffset),
1506 fNdetectors(layer.fNdetectors),
1507 fDetectors(layer.fDetectors),
1512 fClustersCs(layer.fClustersCs),
1513 fClusterIndexCs(layer.fClusterIndexCs),
1517 fCurrentSlice(layer.fCurrentSlice),
1525 fAccepted(layer.fAccepted),
1527 fMaxSigmaClY(layer.fMaxSigmaClY),
1528 fMaxSigmaClZ(layer.fMaxSigmaClZ),
1529 fNMaxSigmaCl(layer.fNMaxSigmaCl)
1533 //------------------------------------------------------------------------
1534 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1535 //--------------------------------------------------------------------
1536 // AliITSlayer destructor
1537 //--------------------------------------------------------------------
1538 delete [] fDetectors;
1539 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1540 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1541 fClusterWeight[i]=0;
1542 fClusterTracks[0][i]=-1;
1543 fClusterTracks[1][i]=-1;
1544 fClusterTracks[2][i]=-1;
1545 fClusterTracks[3][i]=-1;
1548 //------------------------------------------------------------------------
1549 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1550 //--------------------------------------------------------------------
1551 // This function removes loaded clusters
1552 //--------------------------------------------------------------------
1553 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1554 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1555 fClusterWeight[i]=0;
1556 fClusterTracks[0][i]=-1;
1557 fClusterTracks[1][i]=-1;
1558 fClusterTracks[2][i]=-1;
1559 fClusterTracks[3][i]=-1;
1565 //------------------------------------------------------------------------
1566 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1567 //--------------------------------------------------------------------
1568 // This function reset weights of the clusters
1569 //--------------------------------------------------------------------
1570 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1571 fClusterWeight[i]=0;
1572 fClusterTracks[0][i]=-1;
1573 fClusterTracks[1][i]=-1;
1574 fClusterTracks[2][i]=-1;
1575 fClusterTracks[3][i]=-1;
1577 for (Int_t i=0; i<fN;i++) {
1578 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1579 if (cl&&cl->IsUsed()) cl->Use();
1583 //------------------------------------------------------------------------
1584 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1585 //--------------------------------------------------------------------
1586 // This function calculates the road defined by the cluster density
1587 //--------------------------------------------------------------------
1589 for (Int_t i=0; i<fN; i++) {
1590 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1592 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1594 //------------------------------------------------------------------------
1595 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1596 //--------------------------------------------------------------------
1597 //This function adds a cluster to this layer
1598 //--------------------------------------------------------------------
1599 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1600 ::Error("InsertCluster","Too many clusters !\n");
1606 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1608 Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
1609 Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2());
1610 if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
1611 if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
1612 if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
1613 if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
1616 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1617 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1618 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1619 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1623 //------------------------------------------------------------------------
1624 void AliITStrackerMI::AliITSlayer::SortClusters()
1629 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1630 Float_t *z = new Float_t[fN];
1631 Int_t * index = new Int_t[fN];
1633 fMaxSigmaClY=0.; //AD
1634 fMaxSigmaClZ=0.; //AD
1636 for (Int_t i=0;i<fN;i++){
1637 z[i] = fClusters[i]->GetZ();
1638 // save largest errors in y and z for this layer
1639 fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
1640 fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
1642 TMath::Sort(fN,z,index,kFALSE);
1643 for (Int_t i=0;i<fN;i++){
1644 clusters[i] = fClusters[index[i]];
1647 for (Int_t i=0;i<fN;i++){
1648 fClusters[i] = clusters[i];
1649 fZ[i] = fClusters[i]->GetZ();
1650 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1651 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1652 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1662 for (Int_t i=0;i<fN;i++){
1663 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1664 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1665 fClusterIndex[i] = i;
1669 fDy5 = (fYB[1]-fYB[0])/5.;
1670 fDy10 = (fYB[1]-fYB[0])/10.;
1671 fDy20 = (fYB[1]-fYB[0])/20.;
1672 for (Int_t i=0;i<6;i++) fN5[i] =0;
1673 for (Int_t i=0;i<11;i++) fN10[i]=0;
1674 for (Int_t i=0;i<21;i++) fN20[i]=0;
1676 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;}
1677 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;}
1678 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;}
1681 for (Int_t i=0;i<fN;i++)
1682 for (Int_t irot=-1;irot<=1;irot++){
1683 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1685 for (Int_t slice=0; slice<6;slice++){
1686 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1687 fClusters5[slice][fN5[slice]] = fClusters[i];
1688 fY5[slice][fN5[slice]] = curY;
1689 fZ5[slice][fN5[slice]] = fZ[i];
1690 fClusterIndex5[slice][fN5[slice]]=i;
1695 for (Int_t slice=0; slice<11;slice++){
1696 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1697 fClusters10[slice][fN10[slice]] = fClusters[i];
1698 fY10[slice][fN10[slice]] = curY;
1699 fZ10[slice][fN10[slice]] = fZ[i];
1700 fClusterIndex10[slice][fN10[slice]]=i;
1705 for (Int_t slice=0; slice<21;slice++){
1706 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1707 fClusters20[slice][fN20[slice]] = fClusters[i];
1708 fY20[slice][fN20[slice]] = curY;
1709 fZ20[slice][fN20[slice]] = fZ[i];
1710 fClusterIndex20[slice][fN20[slice]]=i;
1717 // consistency check
1719 for (Int_t i=0;i<fN-1;i++){
1725 for (Int_t slice=0;slice<21;slice++)
1726 for (Int_t i=0;i<fN20[slice]-1;i++){
1727 if (fZ20[slice][i]>fZ20[slice][i+1]){
1734 //------------------------------------------------------------------------
1735 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1736 //--------------------------------------------------------------------
1737 // This function returns the index of the nearest cluster
1738 //--------------------------------------------------------------------
1741 if (fCurrentSlice<0) {
1750 if (ncl==0) return 0;
1751 Int_t b=0, e=ncl-1, m=(b+e)/2;
1752 for (; b<e; m=(b+e)/2) {
1753 // if (z > fClusters[m]->GetZ()) b=m+1;
1754 if (z > zcl[m]) b=m+1;
1759 //------------------------------------------------------------------------
1760 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 {
1761 //--------------------------------------------------------------------
1762 // This function computes the rectangular road for this track
1763 //--------------------------------------------------------------------
1766 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1767 // take into account the misalignment: propagate track to misaligned detector plane
1768 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1770 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1771 TMath::Sqrt(track->GetSigmaZ2() +
1772 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1773 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1774 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1775 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1776 TMath::Sqrt(track->GetSigmaY2() +
1777 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1778 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1779 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1781 // track at boundary between detectors, enlarge road
1782 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1783 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1784 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1785 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1786 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1787 Float_t tgl = TMath::Abs(track->GetTgl());
1788 if (tgl > 1.) tgl=1.;
1789 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1790 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1791 Float_t snp = TMath::Abs(track->GetSnp());
1792 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1793 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1796 // add to the road a term (up to 2-3 mm) to deal with misalignments
1797 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1798 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1800 Double_t r = fgLayers[ilayer].GetR();
1801 zmin = track->GetZ() - dz;
1802 zmax = track->GetZ() + dz;
1803 ymin = track->GetY() + r*det.GetPhi() - dy;
1804 ymax = track->GetY() + r*det.GetPhi() + dy;
1806 // bring track back to idead detector plane
1807 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1811 //------------------------------------------------------------------------
1812 void AliITStrackerMI::AliITSlayer::
1813 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1814 //--------------------------------------------------------------------
1815 // This function sets the "window"
1816 //--------------------------------------------------------------------
1818 Double_t circle=2*TMath::Pi()*fR;
1824 // enlarge road in y by maximum cluster error on this layer (3 sigma)
1825 fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
1826 fYmax += fNMaxSigmaCl*fMaxSigmaClY;
1827 fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
1828 fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
1830 Float_t ymiddle = (fYmin+fYmax)*0.5;
1831 if (ymiddle<fYB[0]) {
1832 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1833 } else if (ymiddle>fYB[1]) {
1834 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1840 fClustersCs = fClusters;
1841 fClusterIndexCs = fClusterIndex;
1847 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1848 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1849 if (slice<0) slice=0;
1850 if (slice>20) slice=20;
1851 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1853 fCurrentSlice=slice;
1854 fClustersCs = fClusters20[fCurrentSlice];
1855 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1856 fYcs = fY20[fCurrentSlice];
1857 fZcs = fZ20[fCurrentSlice];
1858 fNcs = fN20[fCurrentSlice];
1863 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1864 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1865 if (slice<0) slice=0;
1866 if (slice>10) slice=10;
1867 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1869 fCurrentSlice=slice;
1870 fClustersCs = fClusters10[fCurrentSlice];
1871 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1872 fYcs = fY10[fCurrentSlice];
1873 fZcs = fZ10[fCurrentSlice];
1874 fNcs = fN10[fCurrentSlice];
1879 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1880 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1881 if (slice<0) slice=0;
1882 if (slice>5) slice=5;
1883 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1885 fCurrentSlice=slice;
1886 fClustersCs = fClusters5[fCurrentSlice];
1887 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1888 fYcs = fY5[fCurrentSlice];
1889 fZcs = fZ5[fCurrentSlice];
1890 fNcs = fN5[fCurrentSlice];
1894 fI = FindClusterIndex(fZmin);
1895 fImax = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
1901 //------------------------------------------------------------------------
1902 Int_t AliITStrackerMI::AliITSlayer::
1903 FindDetectorIndex(Double_t phi, Double_t z) const {
1904 //--------------------------------------------------------------------
1905 //This function finds the detector crossed by the track
1906 //--------------------------------------------------------------------
1908 if (fZOffset<0) // old geometry
1909 dphi = -(phi-fPhiOffset);
1910 else // new geometry
1911 dphi = phi-fPhiOffset;
1914 if (dphi < 0) dphi += 2*TMath::Pi();
1915 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1916 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1917 if (np>=fNladders) np-=fNladders;
1918 if (np<0) np+=fNladders;
1921 Double_t dz=fZOffset-z;
1922 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1923 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1924 if (nz>=fNdetectors) return -1;
1925 if (nz<0) return -1;
1927 // ad hoc correction for 3rd ladder of SDD inner layer,
1928 // which is reversed (rotated by pi around local y)
1929 // this correction is OK only from AliITSv11Hybrid onwards
1930 if (GetR()>12. && GetR()<20.) { // SDD inner
1931 if(np==2) { // 3rd ladder
1932 nz = (fNdetectors-1) - nz;
1935 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1938 return np*fNdetectors + nz;
1940 //------------------------------------------------------------------------
1941 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1943 //--------------------------------------------------------------------
1944 // This function returns clusters within the "window"
1945 //--------------------------------------------------------------------
1947 if (fCurrentSlice<0) {
1948 Double_t rpi2 = 2.*fR*TMath::Pi();
1949 for (Int_t i=fI; i<fImax; i++) {
1952 if (fYmax<y) y -= rpi2;
1953 if (fYmin>y) y += rpi2;
1954 if (y<fYmin) continue;
1955 if (y>fYmax) continue;
1957 // skip clusters that are in "extended" road but they
1958 // 3sigma error does not touch the original road
1959 if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
1960 if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
1962 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1965 return fClusters[i];
1968 for (Int_t i=fI; i<fImax; i++) {
1969 if (fYcs[i]<fYmin) continue;
1970 if (fYcs[i]>fYmax) continue;
1971 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1972 ci=fClusterIndexCs[i];
1974 return fClustersCs[i];
1979 //------------------------------------------------------------------------
1980 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1982 //--------------------------------------------------------------------
1983 // This function returns the layer thickness at this point (units X0)
1984 //--------------------------------------------------------------------
1986 x0=AliITSRecoParam::GetX0Air();
1987 if (43<fR&&fR<45) { //SSD2
1990 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1991 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1992 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1993 for (Int_t i=0; i<12; i++) {
1994 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1995 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1999 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
2000 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2004 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2005 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2008 if (37<fR&&fR<41) { //SSD1
2011 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2012 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2013 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2014 for (Int_t i=0; i<11; i++) {
2015 if (TMath::Abs(z-3.9*i)<0.15) {
2016 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2020 if (TMath::Abs(z+3.9*i)<0.15) {
2021 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2025 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2026 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2029 if (13<fR&&fR<26) { //SDD
2032 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2034 if (TMath::Abs(y-1.80)<0.55) {
2036 for (Int_t j=0; j<20; j++) {
2037 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2038 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2041 if (TMath::Abs(y+1.80)<0.55) {
2043 for (Int_t j=0; j<20; j++) {
2044 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2045 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2049 for (Int_t i=0; i<4; i++) {
2050 if (TMath::Abs(z-7.3*i)<0.60) {
2052 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2055 if (TMath::Abs(z+7.3*i)<0.60) {
2057 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2062 if (6<fR&&fR<8) { //SPD2
2063 Double_t dd=0.0063; x0=21.5;
2065 if (TMath::Abs(y-3.08)>0.5) d+=dd;
2066 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2068 if (3<fR&&fR<5) { //SPD1
2069 Double_t dd=0.0063; x0=21.5;
2071 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2072 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2077 //------------------------------------------------------------------------
2078 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2080 fRmisal(det.fRmisal),
2082 fSinPhi(det.fSinPhi),
2083 fCosPhi(det.fCosPhi),
2089 fNChips(det.fNChips),
2090 fChipIsBad(det.fChipIsBad)
2094 //------------------------------------------------------------------------
2095 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2096 const AliITSDetTypeRec *detTypeRec)
2098 //--------------------------------------------------------------------
2099 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2100 //--------------------------------------------------------------------
2102 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2103 // while in the tracker they start from 0 for each layer
2104 for(Int_t il=0; il<ilayer; il++)
2105 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2108 if (ilayer==0 || ilayer==1) { // ---------- SPD
2110 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2112 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2115 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2119 // Get calibration from AliITSDetTypeRec
2120 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2121 calib->SetModuleIndex(idet);
2122 AliITSCalibration *calibSPDdead = 0;
2123 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2124 if (calib->IsBad() ||
2125 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2128 // printf("lay %d bad %d\n",ilayer,idet);
2131 // Get segmentation from AliITSDetTypeRec
2132 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2134 // Read info about bad chips
2135 fNChips = segm->GetMaximumChipIndex()+1;
2136 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2137 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2138 fChipIsBad = new Bool_t[fNChips];
2139 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2140 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2141 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2142 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2147 //------------------------------------------------------------------------
2148 Double_t AliITStrackerMI::GetEffectiveThickness()
2150 //--------------------------------------------------------------------
2151 // Returns the thickness between the current layer and the vertex (units X0)
2152 //--------------------------------------------------------------------
2155 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2156 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2157 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2161 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2162 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2166 Double_t xn=fgLayers[fI].GetR();
2167 for (Int_t i=0; i<fI; i++) {
2168 Double_t xi=fgLayers[i].GetR();
2169 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2175 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2176 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2179 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2180 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2184 //------------------------------------------------------------------------
2185 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2186 //-------------------------------------------------------------------
2187 // This function returns number of clusters within the "window"
2188 //--------------------------------------------------------------------
2190 for (Int_t i=fI; i<fN; i++) {
2191 const AliITSRecPoint *c=fClusters[i];
2192 if (c->GetZ() > fZmax) break;
2193 if (c->IsUsed()) continue;
2194 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2195 Double_t y=fR*det.GetPhi() + c->GetY();
2197 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2198 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2200 if (y<fYmin) continue;
2201 if (y>fYmax) continue;
2206 //------------------------------------------------------------------------
2207 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2208 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2210 //--------------------------------------------------------------------
2211 // This function refits the track "track" at the position "x" using
2212 // the clusters from "clusters"
2213 // If "extra"==kTRUE,
2214 // the clusters from overlapped modules get attached to "track"
2215 // If "planeff"==kTRUE,
2216 // special approach for plane efficiency evaluation is applyed
2217 //--------------------------------------------------------------------
2219 Int_t index[AliITSgeomTGeo::kNLayers];
2221 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2222 Int_t nc=clusters->GetNumberOfClusters();
2223 for (k=0; k<nc; k++) {
2224 Int_t idx=clusters->GetClusterIndex(k);
2225 Int_t ilayer=(idx&0xf0000000)>>28;
2229 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2231 //------------------------------------------------------------------------
2232 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2233 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2235 //--------------------------------------------------------------------
2236 // This function refits the track "track" at the position "x" using
2237 // the clusters from array
2238 // If "extra"==kTRUE,
2239 // the clusters from overlapped modules get attached to "track"
2240 // If "planeff"==kTRUE,
2241 // special approach for plane efficiency evaluation is applyed
2242 //--------------------------------------------------------------------
2243 Int_t index[AliITSgeomTGeo::kNLayers];
2245 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2247 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2248 index[k]=clusters[k];
2251 // special for cosmics: check which the innermost layer crossed
2253 Int_t innermostlayer=5;
2254 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2255 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2256 if(drphi < fgLayers[innermostlayer].GetR()) break;
2258 AliDebug(2,Form(" drphi %f innermost %d",drphi,innermostlayer));
2260 Int_t modstatus=1; // found
2262 Int_t from, to, step;
2263 if (xx > track->GetX()) {
2264 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2267 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2270 TString dir = (step>0 ? "outward" : "inward");
2272 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2273 AliITSlayer &layer=fgLayers[ilayer];
2274 Double_t r=layer.GetR();
2276 if (step<0 && xx>r) break;
2278 // material between SSD and SDD, SDD and SPD
2279 Double_t hI=ilayer-0.5*step;
2280 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2281 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2282 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2283 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2286 Double_t oldGlobXYZ[3];
2287 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2289 // continue if we are already beyond this layer
2290 Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2291 if(step>0 && oldGlobR > r) continue; // going outward
2292 if(step<0 && oldGlobR < r) continue; // going inward
2295 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2297 Int_t idet=layer.FindDetectorIndex(phi,z);
2299 // check if we allow a prolongation without point for large-eta tracks
2300 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2302 modstatus = 4; // out in z
2303 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2304 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2307 // apply correction for material of the current layer
2308 // add time if going outward
2309 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2313 if (idet<0) return kFALSE;
2316 const AliITSdetector &det=layer.GetDetector(idet);
2317 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2319 track->SetDetectorIndex(idet);
2320 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2322 Double_t dz,zmin,zmax,dy,ymin,ymax;
2324 const AliITSRecPoint *clAcc=0;
2325 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2327 Int_t idx=index[ilayer];
2328 if (idx>=0) { // cluster in this layer
2329 modstatus = 6; // no refit
2330 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2332 if (idet != cl->GetDetectorIndex()) {
2333 idet=cl->GetDetectorIndex();
2334 const AliITSdetector &detc=layer.GetDetector(idet);
2335 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2336 track->SetDetectorIndex(idet);
2337 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2339 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2340 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2344 modstatus = 1; // found
2349 } else { // no cluster in this layer
2351 modstatus = 3; // skipped
2352 // Plane Eff determination:
2353 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2354 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2355 UseTrackForPlaneEff(track,ilayer);
2358 modstatus = 5; // no cls in road
2360 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2361 dz = 0.5*(zmax-zmin);
2362 dy = 0.5*(ymax-ymin);
2363 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2364 if (dead==1) modstatus = 7; // holes in z in SPD
2365 if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2370 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2371 track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2373 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2376 if (extra) { // search for extra clusters in overlapped modules
2377 AliITStrackV2 tmp(*track);
2378 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2379 layer.SelectClusters(zmin,zmax,ymin,ymax);
2381 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2383 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2384 Double_t tolerance=0.1;
2385 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2386 // only clusters in another module! (overlaps)
2387 idetExtra = clExtra->GetDetectorIndex();
2388 if (idet == idetExtra) continue;
2390 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2392 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2393 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2394 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2395 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2397 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2398 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2401 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2402 track->SetExtraModule(ilayer,idetExtra);
2404 } // end search for extra clusters in overlapped modules
2406 // Correct for material of the current layer
2408 // add time if going outward
2409 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2411 } // end loop on layers
2413 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2417 //------------------------------------------------------------------------
2418 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2421 // calculate normalized chi2
2422 // return NormalizedChi2(track,0);
2425 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2426 // track->fdEdxMismatch=0;
2427 Float_t dedxmismatch =0;
2428 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2430 for (Int_t i = 0;i<6;i++){
2431 if (track->GetClIndex(i)>=0){
2432 Float_t cerry, cerrz;
2433 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2435 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2438 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2439 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2440 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2442 cchi2+=(0.5-ratio)*10.;
2443 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2444 dedxmismatch+=(0.5-ratio)*10.;
2448 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2449 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2450 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2451 if (i<2) chi2+=2*cl->GetDeltaProbability();
2457 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2458 track->SetdEdxMismatch(dedxmismatch);
2462 for (Int_t i = 0;i<4;i++){
2463 if (track->GetClIndex(i)>=0){
2464 Float_t cerry, cerrz;
2465 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2466 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2469 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2470 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2474 for (Int_t i = 4;i<6;i++){
2475 if (track->GetClIndex(i)>=0){
2476 Float_t cerry, cerrz;
2477 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2478 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2481 Float_t cerryb, cerrzb;
2482 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2483 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2486 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2487 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2492 if (track->GetESDtrack()->GetTPCsignal()>85){
2493 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2495 chi2+=(0.5-ratio)*5.;
2498 chi2+=(ratio-2.0)*3;
2502 Double_t match = TMath::Sqrt(track->GetChi22());
2503 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2504 if (!track->GetConstrain()) {
2505 if (track->GetNumberOfClusters()>2) {
2506 match/=track->GetNumberOfClusters()-2.;
2511 if (match<0) match=0;
2513 // penalty factor for missing points (NDeadZone>0), but no penalty
2514 // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2515 // or there is a dead from OCDB)
2516 Float_t deadzonefactor = 0.;
2517 if (track->GetNDeadZone()>0.) {
2518 Float_t sumDeadZoneProbability=0;
2519 for(Int_t ilay=0;ilay<6;ilay++) sumDeadZoneProbability+=track->GetDeadZoneProbability(ilay);
2520 Float_t nDeadZoneWithProbNot1=(Float_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2521 if(nDeadZoneWithProbNot1>0.) {
2522 Float_t deadZoneProbability = sumDeadZoneProbability - (Float_t)((Int_t)sumDeadZoneProbability);
2523 deadZoneProbability /= nDeadZoneWithProbNot1;
2524 deadzonefactor = 3.*(1.1-deadZoneProbability);
2528 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2529 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2530 1./(1.+track->GetNSkipped()));
2534 //------------------------------------------------------------------------
2535 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2538 // return matching chi2 between two tracks
2539 Double_t largeChi2=1000.;
2541 AliITStrackMI track3(*track2);
2542 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2544 vec(0,0)=track1->GetY() - track3.GetY();
2545 vec(1,0)=track1->GetZ() - track3.GetZ();
2546 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2547 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2548 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2551 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2552 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2553 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2554 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2555 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2557 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2558 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2559 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2560 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2562 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2563 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2564 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2566 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2567 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2569 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2572 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2573 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2576 //------------------------------------------------------------------------
2577 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2580 // return probability that given point (characterized by z position and error)
2581 // is in SPD dead zone
2583 Double_t probability = 0.;
2584 Double_t absz = TMath::Abs(zpos);
2585 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2586 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2587 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2588 Double_t zmin, zmax;
2589 if (zpos<-6.) { // dead zone at z = -7
2590 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2591 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2592 } else if (zpos>6.) { // dead zone at z = +7
2593 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2594 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2595 } else if (absz<2.) { // dead zone at z = 0
2596 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2597 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2602 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2604 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2605 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2608 //------------------------------------------------------------------------
2609 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2612 // calculate normalized chi2
2614 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2616 for (Int_t i = 0;i<6;i++){
2617 if (TMath::Abs(track->GetDy(i))>0){
2618 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2619 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2622 else{chi2[i]=10000;}
2625 TMath::Sort(6,chi2,index,kFALSE);
2626 Float_t max = float(ncl)*fac-1.;
2627 Float_t sumchi=0, sumweight=0;
2628 for (Int_t i=0;i<max+1;i++){
2629 Float_t weight = (i<max)?1.:(max+1.-i);
2630 sumchi+=weight*chi2[index[i]];
2633 Double_t normchi2 = sumchi/sumweight;
2636 //------------------------------------------------------------------------
2637 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2640 // calculate normalized chi2
2641 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2644 for (Int_t i=0;i<6;i++){
2645 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2646 Double_t sy1 = forwardtrack->GetSigmaY(i);
2647 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2648 Double_t sy2 = backtrack->GetSigmaY(i);
2649 Double_t sz2 = backtrack->GetSigmaZ(i);
2650 if (i<2){ sy2=1000.;sz2=1000;}
2652 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2653 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2655 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2656 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2658 res+= nz0*nz0+ny0*ny0;
2661 if (npoints>1) return
2662 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2663 //2*forwardtrack->fNUsed+
2664 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2665 1./(1.+forwardtrack->GetNSkipped()));
2668 //------------------------------------------------------------------------
2669 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2670 //--------------------------------------------------------------------
2671 // Return pointer to a given cluster
2672 //--------------------------------------------------------------------
2673 Int_t l=(index & 0xf0000000) >> 28;
2674 Int_t c=(index & 0x0fffffff) >> 00;
2675 return fgLayers[l].GetWeight(c);
2677 //------------------------------------------------------------------------
2678 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2680 //---------------------------------------------
2681 // register track to the list
2683 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2686 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2687 Int_t index = track->GetClusterIndex(icluster);
2688 Int_t l=(index & 0xf0000000) >> 28;
2689 Int_t c=(index & 0x0fffffff) >> 00;
2690 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2691 for (Int_t itrack=0;itrack<4;itrack++){
2692 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2693 fgLayers[l].SetClusterTracks(itrack,c,id);
2699 //------------------------------------------------------------------------
2700 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2702 //---------------------------------------------
2703 // unregister track from the list
2704 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2705 Int_t index = track->GetClusterIndex(icluster);
2706 Int_t l=(index & 0xf0000000) >> 28;
2707 Int_t c=(index & 0x0fffffff) >> 00;
2708 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2709 for (Int_t itrack=0;itrack<4;itrack++){
2710 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2711 fgLayers[l].SetClusterTracks(itrack,c,-1);
2716 //------------------------------------------------------------------------
2717 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2719 //-------------------------------------------------------------
2720 //get number of shared clusters
2721 //-------------------------------------------------------------
2723 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2724 // mean number of clusters
2725 Float_t *ny = GetNy(id), *nz = GetNz(id);
2728 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2729 Int_t index = track->GetClusterIndex(icluster);
2730 Int_t l=(index & 0xf0000000) >> 28;
2731 Int_t c=(index & 0x0fffffff) >> 00;
2732 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2734 printf("problem\n");
2736 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2740 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2741 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2742 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2744 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2747 deltan = (cl->GetNz()-nz[l]);
2749 if (deltan>2.0) continue; // extended - highly probable shared cluster
2750 weight = 2./TMath::Max(3.+deltan,2.);
2752 for (Int_t itrack=0;itrack<4;itrack++){
2753 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2755 clist[l] = (AliITSRecPoint*)GetCluster(index);
2761 track->SetNUsed(shared);
2764 //------------------------------------------------------------------------
2765 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2768 // find first shared track
2770 // mean number of clusters
2771 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2773 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2774 Int_t sharedtrack=100000;
2775 Int_t tracks[24],trackindex=0;
2776 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2778 for (Int_t icluster=0;icluster<6;icluster++){
2779 if (clusterlist[icluster]<0) continue;
2780 Int_t index = clusterlist[icluster];
2781 Int_t l=(index & 0xf0000000) >> 28;
2782 Int_t c=(index & 0x0fffffff) >> 00;
2784 printf("problem\n");
2786 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2787 //if (l>3) continue;
2788 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2791 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2792 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2793 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2795 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2798 deltan = (cl->GetNz()-nz[l]);
2800 if (deltan>2.0) continue; // extended - highly probable shared cluster
2802 for (Int_t itrack=3;itrack>=0;itrack--){
2803 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2804 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2805 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2810 if (trackindex==0) return -1;
2812 sharedtrack = tracks[0];
2814 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2817 Int_t tracks2[24], cluster[24];
2818 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2821 for (Int_t i=0;i<trackindex;i++){
2822 if (tracks[i]<0) continue;
2823 tracks2[index] = tracks[i];
2825 for (Int_t j=i+1;j<trackindex;j++){
2826 if (tracks[j]<0) continue;
2827 if (tracks[j]==tracks[i]){
2835 for (Int_t i=0;i<index;i++){
2836 if (cluster[index]>max) {
2837 sharedtrack=tracks2[index];
2844 if (sharedtrack>=100000) return -1;
2846 // make list of overlaps
2848 for (Int_t icluster=0;icluster<6;icluster++){
2849 if (clusterlist[icluster]<0) continue;
2850 Int_t index = clusterlist[icluster];
2851 Int_t l=(index & 0xf0000000) >> 28;
2852 Int_t c=(index & 0x0fffffff) >> 00;
2853 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2854 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2856 if (cl->GetNy()>2) continue;
2857 if (cl->GetNz()>2) continue;
2860 if (cl->GetNy()>3) continue;
2861 if (cl->GetNz()>3) continue;
2864 for (Int_t itrack=3;itrack>=0;itrack--){
2865 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2866 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2874 //------------------------------------------------------------------------
2875 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2877 // try to find track hypothesys without conflicts
2878 // with minimal chi2;
2879 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2880 Int_t entries1 = arr1->GetEntriesFast();
2881 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2882 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2883 Int_t entries2 = arr2->GetEntriesFast();
2884 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2886 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2887 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2888 if (track10->Pt()>0.5+track20->Pt()) return track10;
2890 for (Int_t itrack=0;itrack<entries1;itrack++){
2891 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2892 UnRegisterClusterTracks(track,trackID1);
2895 for (Int_t itrack=0;itrack<entries2;itrack++){
2896 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2897 UnRegisterClusterTracks(track,trackID2);
2901 Float_t maxconflicts=6;
2902 Double_t maxchi2 =1000.;
2904 // get weight of hypothesys - using best hypothesy
2907 Int_t list1[6],list2[6];
2908 AliITSRecPoint *clist1[6], *clist2[6] ;
2909 RegisterClusterTracks(track10,trackID1);
2910 RegisterClusterTracks(track20,trackID2);
2911 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2912 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2913 UnRegisterClusterTracks(track10,trackID1);
2914 UnRegisterClusterTracks(track20,trackID2);
2917 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2918 Float_t nerry[6],nerrz[6];
2919 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2920 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2921 for (Int_t i=0;i<6;i++){
2922 if ( (erry1[i]>0) && (erry2[i]>0)) {
2923 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2924 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2926 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2927 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2929 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2930 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2931 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2934 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2935 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2936 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2944 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2945 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2946 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2947 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2949 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2950 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2951 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2953 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2954 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2955 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2958 Double_t sumw = w1+w2;
2962 w1 = (d2+0.5)/(d1+d2+1.);
2963 w2 = (d1+0.5)/(d1+d2+1.);
2965 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2966 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2968 // get pair of "best" hypothesys
2970 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2971 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2973 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2974 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2975 //if (track1->fFakeRatio>0) continue;
2976 RegisterClusterTracks(track1,trackID1);
2977 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2978 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2980 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2981 //if (track2->fFakeRatio>0) continue;
2983 RegisterClusterTracks(track2,trackID2);
2984 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2985 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2986 UnRegisterClusterTracks(track2,trackID2);
2988 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2989 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2990 if (nskipped>0.5) continue;
2992 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2993 if (conflict1+1<cconflict1) continue;
2994 if (conflict2+1<cconflict2) continue;
2998 for (Int_t i=0;i<6;i++){
3000 Float_t c1 =0.; // conflict coeficients
3002 if (clist1[i]&&clist2[i]){
3005 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
3008 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
3010 c1 = 2./TMath::Max(3.+deltan,2.);
3011 c2 = 2./TMath::Max(3.+deltan,2.);
3017 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
3020 deltan = (clist1[i]->GetNz()-nz1[i]);
3022 c1 = 2./TMath::Max(3.+deltan,2.);
3029 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
3032 deltan = (clist2[i]->GetNz()-nz2[i]);
3034 c2 = 2./TMath::Max(3.+deltan,2.);
3040 if (TMath::Abs(track1->GetDy(i))>0.) {
3041 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
3042 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
3043 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
3044 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
3046 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
3049 if (TMath::Abs(track2->GetDy(i))>0.) {
3050 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
3051 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
3052 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
3053 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3056 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3058 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3059 if (chi21>0) sum+=w1;
3060 if (chi22>0) sum+=w2;
3063 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3064 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3065 Double_t normchi2 = 2*conflict+sumchi2/sum;
3066 if ( normchi2 <maxchi2 ){
3069 maxconflicts = conflict;
3073 UnRegisterClusterTracks(track1,trackID1);
3076 // if (maxconflicts<4 && maxchi2<th0){
3077 if (maxchi2<th0*2.){
3078 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3079 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3080 track1->SetChi2MIP(5,maxconflicts);
3081 track1->SetChi2MIP(6,maxchi2);
3082 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3083 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3084 track1->SetChi2MIP(8,index1);
3085 fBestTrackIndex[trackID1] =index1;
3086 UpdateESDtrack(track1, AliESDtrack::kITSin);
3088 else if (track10->GetChi2MIP(0)<th1){
3089 track10->SetChi2MIP(5,maxconflicts);
3090 track10->SetChi2MIP(6,maxchi2);
3091 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3092 UpdateESDtrack(track10,AliESDtrack::kITSin);
3095 for (Int_t itrack=0;itrack<entries1;itrack++){
3096 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3097 UnRegisterClusterTracks(track,trackID1);
3100 for (Int_t itrack=0;itrack<entries2;itrack++){
3101 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3102 UnRegisterClusterTracks(track,trackID2);
3105 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3106 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3107 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3108 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3109 RegisterClusterTracks(track10,trackID1);
3111 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3112 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3113 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3114 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3115 RegisterClusterTracks(track20,trackID2);
3120 //------------------------------------------------------------------------
3121 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3122 //--------------------------------------------------------------------
3123 // This function marks clusters assigned to the track
3124 //--------------------------------------------------------------------
3125 AliTracker::UseClusters(t,from);
3127 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3128 //if (c->GetQ()>2) c->Use();
3129 if (c->GetSigmaZ2()>0.1) c->Use();
3130 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3131 //if (c->GetQ()>2) c->Use();
3132 if (c->GetSigmaZ2()>0.1) c->Use();
3135 //------------------------------------------------------------------------
3136 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3138 //------------------------------------------------------------------
3139 // add track to the list of hypothesys
3140 //------------------------------------------------------------------
3142 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3143 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3145 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3147 array = new TObjArray(10);
3148 fTrackHypothesys.AddAt(array,esdindex);
3150 array->AddLast(track);
3152 //------------------------------------------------------------------------
3153 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3155 //-------------------------------------------------------------------
3156 // compress array of track hypothesys
3157 // keep only maxsize best hypothesys
3158 //-------------------------------------------------------------------
3159 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3160 if (! (fTrackHypothesys.At(esdindex)) ) return;
3161 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3162 Int_t entries = array->GetEntriesFast();
3164 //- find preliminary besttrack as a reference
3165 Float_t minchi2=10000;
3167 AliITStrackMI * besttrack=0;
3168 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3169 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3170 if (!track) continue;
3171 Float_t chi2 = NormalizedChi2(track,0);
3173 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3174 track->SetLabel(tpcLabel);
3176 track->SetFakeRatio(1.);
3177 CookLabel(track,0.); //For comparison only
3179 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3180 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3181 if (track->GetNumberOfClusters()<maxn) continue;
3182 maxn = track->GetNumberOfClusters();
3189 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3190 delete array->RemoveAt(itrack);
3194 if (!besttrack) return;
3197 //take errors of best track as a reference
3198 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3199 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3200 for (Int_t j=0;j<6;j++) {
3201 if (besttrack->GetClIndex(j)>=0){
3202 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3203 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3204 ny[j] = besttrack->GetNy(j);
3205 nz[j] = besttrack->GetNz(j);
3209 // calculate normalized chi2
3211 Float_t * chi2 = new Float_t[entries];
3212 Int_t * index = new Int_t[entries];
3213 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3214 for (Int_t itrack=0;itrack<entries;itrack++){
3215 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3217 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3218 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3219 chi2[itrack] = track->GetChi2MIP(0);
3221 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3222 delete array->RemoveAt(itrack);
3228 TMath::Sort(entries,chi2,index,kFALSE);
3229 besttrack = (AliITStrackMI*)array->At(index[0]);
3230 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3231 for (Int_t j=0;j<6;j++){
3232 if (besttrack->GetClIndex(j)>=0){
3233 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3234 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3235 ny[j] = besttrack->GetNy(j);
3236 nz[j] = besttrack->GetNz(j);
3241 // calculate one more time with updated normalized errors
3242 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3243 for (Int_t itrack=0;itrack<entries;itrack++){
3244 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3246 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3247 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3248 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3251 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3252 delete array->RemoveAt(itrack);
3257 entries = array->GetEntriesFast();
3261 TObjArray * newarray = new TObjArray();
3262 TMath::Sort(entries,chi2,index,kFALSE);
3263 besttrack = (AliITStrackMI*)array->At(index[0]);
3266 for (Int_t j=0;j<6;j++){
3267 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3268 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3269 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3270 ny[j] = besttrack->GetNy(j);
3271 nz[j] = besttrack->GetNz(j);
3274 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3275 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3276 Float_t minn = besttrack->GetNumberOfClusters()-3;
3278 for (Int_t i=0;i<entries;i++){
3279 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3280 if (!track) continue;
3281 if (accepted>maxcut) break;
3282 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3283 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3284 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3285 delete array->RemoveAt(index[i]);
3289 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3290 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3291 if (!shortbest) accepted++;
3293 newarray->AddLast(array->RemoveAt(index[i]));
3294 for (Int_t j=0;j<6;j++){
3296 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3297 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3298 ny[j] = track->GetNy(j);
3299 nz[j] = track->GetNz(j);
3304 delete array->RemoveAt(index[i]);
3308 delete fTrackHypothesys.RemoveAt(esdindex);
3309 fTrackHypothesys.AddAt(newarray,esdindex);
3313 delete fTrackHypothesys.RemoveAt(esdindex);
3319 //------------------------------------------------------------------------
3320 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3322 //-------------------------------------------------------------
3323 // try to find best hypothesy
3324 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3325 //-------------------------------------------------------------
3326 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3327 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3328 if (!array) return 0;
3329 Int_t entries = array->GetEntriesFast();
3330 if (!entries) return 0;
3331 Float_t minchi2 = 100000;
3332 AliITStrackMI * besttrack=0;
3334 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3335 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3336 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3337 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3339 for (Int_t i=0;i<entries;i++){
3340 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3341 if (!track) continue;
3342 Float_t sigmarfi,sigmaz;
3343 GetDCASigma(track,sigmarfi,sigmaz);
3344 track->SetDnorm(0,sigmarfi);
3345 track->SetDnorm(1,sigmaz);
3347 track->SetChi2MIP(1,1000000);
3348 track->SetChi2MIP(2,1000000);
3349 track->SetChi2MIP(3,1000000);
3352 backtrack = new(backtrack) AliITStrackMI(*track);
3353 if (track->GetConstrain()) {
3354 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3355 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3356 backtrack->ResetCovariance(10.);
3358 backtrack->ResetCovariance(10.);
3360 backtrack->ResetClusters();
3362 Double_t x = original->GetX();
3363 if (!RefitAt(x,backtrack,track)) continue;
3365 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3366 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3367 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3368 track->SetChi22(GetMatchingChi2(backtrack,original));
3370 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3371 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3372 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3375 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3377 //forward track - without constraint
3378 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3379 forwardtrack->ResetClusters();
3381 RefitAt(x,forwardtrack,track);
3382 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3383 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3384 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3386 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3387 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3388 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3389 forwardtrack->SetD(0,track->GetD(0));
3390 forwardtrack->SetD(1,track->GetD(1));
3393 AliITSRecPoint* clist[6];
3394 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3395 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3398 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3399 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3400 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3401 track->SetChi2MIP(3,1000);
3404 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3406 for (Int_t ichi=0;ichi<5;ichi++){
3407 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3409 if (chi2 < minchi2){
3410 //besttrack = new AliITStrackMI(*forwardtrack);
3412 besttrack->SetLabel(track->GetLabel());
3413 besttrack->SetFakeRatio(track->GetFakeRatio());
3415 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3416 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3417 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3421 delete forwardtrack;
3423 for (Int_t i=0;i<entries;i++){
3424 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3426 if (!track) continue;
3428 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3429 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3430 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3431 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3432 delete array->RemoveAt(i);
3442 SortTrackHypothesys(esdindex,checkmax,1);
3444 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3445 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3446 besttrack = (AliITStrackMI*)array->At(0);
3447 if (!besttrack) return 0;
3448 besttrack->SetChi2MIP(8,0);
3449 fBestTrackIndex[esdindex]=0;
3450 entries = array->GetEntriesFast();
3451 AliITStrackMI *longtrack =0;
3453 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3454 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3455 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3456 if (!track->GetConstrain()) continue;
3457 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3458 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3459 if (track->GetChi2MIP(0)>4.) continue;
3460 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3463 //if (longtrack) besttrack=longtrack;
3466 AliITSRecPoint * clist[6];
3467 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3468 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3469 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3470 RegisterClusterTracks(besttrack,esdindex);
3477 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3478 if (sharedtrack>=0){
3480 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3482 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3488 if (shared>2.5) return 0;
3489 if (shared>1.0) return besttrack;
3491 // Don't sign clusters if not gold track
3493 if (!besttrack->IsGoldPrimary()) return besttrack;
3494 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3496 if (fConstraint[fPass]){
3500 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3501 for (Int_t i=0;i<6;i++){
3502 Int_t index = besttrack->GetClIndex(i);
3503 if (index<0) continue;
3504 Int_t ilayer = (index & 0xf0000000) >> 28;
3505 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3506 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3508 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3509 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3510 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3511 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3512 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3513 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3515 Bool_t cansign = kTRUE;
3516 for (Int_t itrack=0;itrack<entries; itrack++){
3517 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3518 if (!track) continue;
3519 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3520 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3526 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3527 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3528 if (!c->IsUsed()) c->Use();
3534 //------------------------------------------------------------------------
3535 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3538 // get "best" hypothesys
3541 Int_t nentries = itsTracks.GetEntriesFast();
3542 for (Int_t i=0;i<nentries;i++){
3543 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3544 if (!track) continue;
3545 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3546 if (!array) continue;
3547 if (array->GetEntriesFast()<=0) continue;
3549 AliITStrackMI* longtrack=0;
3551 Float_t maxchi2=1000;
3552 for (Int_t j=0;j<array->GetEntriesFast();j++){
3553 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3554 if (!trackHyp) continue;
3555 if (trackHyp->GetGoldV0()) {
3556 longtrack = trackHyp; //gold V0 track taken
3559 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3560 Float_t chi2 = trackHyp->GetChi2MIP(0);
3562 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3564 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3566 if (chi2 > maxchi2) continue;
3567 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3574 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3575 if (!longtrack) {longtrack = besttrack;}
3576 else besttrack= longtrack;
3580 AliITSRecPoint * clist[6];
3581 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3583 track->SetNUsed(shared);
3584 track->SetNSkipped(besttrack->GetNSkipped());
3585 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3587 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3591 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3592 //if (sharedtrack==-1) sharedtrack=0;
3593 if (sharedtrack>=0) {
3594 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3597 if (besttrack&&fAfterV0) {
3598 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3600 if (besttrack&&fConstraint[fPass])
3601 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3602 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3603 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3604 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3610 //------------------------------------------------------------------------
3611 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3612 //--------------------------------------------------------------------
3613 //This function "cooks" a track label. If label<0, this track is fake.
3614 //--------------------------------------------------------------------
3617 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3619 track->SetChi2MIP(9,0);
3621 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3622 Int_t cindex = track->GetClusterIndex(i);
3623 Int_t l=(cindex & 0xf0000000) >> 28;
3624 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3626 for (Int_t ind=0;ind<3;ind++){
3628 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3629 AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3631 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3634 Int_t nclusters = track->GetNumberOfClusters();
3635 if (nclusters > 0) //PH Some tracks don't have any cluster
3636 track->SetFakeRatio(double(nwrong)/double(nclusters));
3638 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3640 track->SetLabel(tpcLabel);
3642 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3645 //------------------------------------------------------------------------
3646 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3649 track->SetChi2MIP(9,0);
3650 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3651 Int_t cindex = track->GetClusterIndex(i);
3652 Int_t l=(cindex & 0xf0000000) >> 28;
3653 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3654 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3656 for (Int_t ind=0;ind<3;ind++){
3657 if (cl->GetLabel(ind)==lab) isWrong=0;
3659 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3663 track->CookdEdx(low,up);
3665 //------------------------------------------------------------------------
3666 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3668 // Create some arrays
3670 if (fCoefficients) delete []fCoefficients;
3671 fCoefficients = new Float_t[ntracks*48];
3672 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3674 //------------------------------------------------------------------------
3675 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3678 // Compute predicted chi2
3680 Float_t erry,errz,covyz;
3681 Float_t theta = track->GetTgl();
3682 Float_t phi = track->GetSnp();
3683 phi = TMath::Abs(phi)*TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3684 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
3685 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()));
3686 // Take into account the mis-alignment (bring track to cluster plane)
3687 Double_t xTrOrig=track->GetX();
3688 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3689 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()));
3690 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
3691 // Bring the track back to detector plane in ideal geometry
3692 // [mis-alignment will be accounted for in UpdateMI()]
3693 if (!track->Propagate(xTrOrig)) return 1000.;
3695 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3696 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3698 chi2+=0.5*TMath::Min(delta/2,2.);
3699 chi2+=2.*cluster->GetDeltaProbability();
3702 track->SetNy(layer,ny);
3703 track->SetNz(layer,nz);
3704 track->SetSigmaY(layer,erry);
3705 track->SetSigmaZ(layer, errz);
3706 track->SetSigmaYZ(layer,covyz);
3707 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3708 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3712 //------------------------------------------------------------------------
3713 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3718 Int_t layer = (index & 0xf0000000) >> 28;
3719 track->SetClIndex(layer, index);
3720 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3721 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3722 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3723 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3727 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3730 // Take into account the mis-alignment (bring track to cluster plane)
3731 Double_t xTrOrig=track->GetX();
3732 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3733 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3734 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3735 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3737 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3740 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3741 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3742 c.SetSigmaYZ(track->GetSigmaYZ(layer));
3745 Int_t updated = track->UpdateMI(&c,chi2,index);
3746 // Bring the track back to detector plane in ideal geometry
3747 if (!track->Propagate(xTrOrig)) return 0;
3749 if(!updated) AliDebug(2,"update failed");
3753 //------------------------------------------------------------------------
3754 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3757 //DCA sigmas parameterization
3758 //to be paramterized using external parameters in future
3761 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3762 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3764 //------------------------------------------------------------------------
3765 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3768 // Clusters from delta electrons?
3770 Int_t entries = clusterArray->GetEntriesFast();
3771 if (entries<4) return;
3772 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3773 Int_t layer = cluster->GetLayer();
3774 if (layer>1) return;
3776 Int_t ncandidates=0;
3777 Float_t r = (layer>0)? 7:4;
3779 for (Int_t i=0;i<entries;i++){
3780 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3781 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3782 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3783 index[ncandidates] = i; //candidate to belong to delta electron track
3785 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3786 cl0->SetDeltaProbability(1);
3792 for (Int_t i=0;i<ncandidates;i++){
3793 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3794 if (cl0->GetDeltaProbability()>0.8) continue;
3797 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3798 sumy=sumz=sumy2=sumyz=sumw=0.0;
3799 for (Int_t j=0;j<ncandidates;j++){
3801 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3803 Float_t dz = cl0->GetZ()-cl1->GetZ();
3804 Float_t dy = cl0->GetY()-cl1->GetY();
3805 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3806 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3807 y[ncl] = cl1->GetY();
3808 z[ncl] = cl1->GetZ();
3809 sumy+= y[ncl]*weight;
3810 sumz+= z[ncl]*weight;
3811 sumy2+=y[ncl]*y[ncl]*weight;
3812 sumyz+=y[ncl]*z[ncl]*weight;
3817 if (ncl<4) continue;
3818 Float_t det = sumw*sumy2 - sumy*sumy;
3820 if (TMath::Abs(det)>0.01){
3821 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3822 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3823 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3826 Float_t z0 = sumyz/sumy;
3827 delta = TMath::Abs(cl0->GetZ()-z0);
3830 cl0->SetDeltaProbability(1-20.*delta);
3834 //------------------------------------------------------------------------
3835 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3840 track->UpdateESDtrack(flags);
3841 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3842 if (oldtrack) delete oldtrack;
3843 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3844 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3845 printf("Problem\n");
3848 //------------------------------------------------------------------------
3849 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3851 // Get nearest upper layer close to the point xr.
3852 // rough approximation
3854 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3855 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3857 for (Int_t i=0;i<6;i++){
3858 if (radius<kRadiuses[i]){
3865 //------------------------------------------------------------------------
3866 void AliITStrackerMI::BuildMaterialLUT(TString material) {
3867 //--------------------------------------------------------------------
3868 // Fill a look-up table with mean material
3869 //--------------------------------------------------------------------
3873 Double_t point1[3],point2[3];
3874 Double_t phi,cosphi,sinphi,z;
3875 // 0-5 layers, 6 pipe, 7-8 shields
3876 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
3877 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
3879 Int_t ifirst=0,ilast=0;
3880 if(material.Contains("Pipe")) {
3882 } else if(material.Contains("Shields")) {
3884 } else if(material.Contains("Layers")) {
3887 Error("BuildMaterialLUT","Wrong layer name\n");
3890 for(Int_t imat=ifirst; imat<=ilast; imat++) {
3891 Double_t param[5]={0.,0.,0.,0.,0.};
3892 for (Int_t i=0; i<n; i++) {
3893 phi = 2.*TMath::Pi()*gRandom->Rndm();
3894 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
3895 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
3896 point1[0] = rmin[imat]*cosphi;
3897 point1[1] = rmin[imat]*sinphi;
3899 point2[0] = rmax[imat]*cosphi;
3900 point2[1] = rmax[imat]*sinphi;
3902 AliTracker::MeanMaterialBudget(point1,point2,mparam);
3903 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
3905 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
3907 fxOverX0Layer[imat] = param[1];
3908 fxTimesRhoLayer[imat] = param[0]*param[4];
3909 } else if(imat==6) {
3910 fxOverX0Pipe = param[1];
3911 fxTimesRhoPipe = param[0]*param[4];
3912 } else if(imat==7) {
3913 fxOverX0Shield[0] = param[1];
3914 fxTimesRhoShield[0] = param[0]*param[4];
3915 } else if(imat==8) {
3916 fxOverX0Shield[1] = param[1];
3917 fxTimesRhoShield[1] = param[0]*param[4];
3921 printf("%s\n",material.Data());
3922 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
3923 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
3924 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
3925 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
3926 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
3927 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
3928 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
3929 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
3930 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
3934 //------------------------------------------------------------------------
3935 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
3936 TString direction) {
3937 //-------------------------------------------------------------------
3938 // Propagate beyond beam pipe and correct for material
3939 // (material budget in different ways according to fUseTGeo value)
3940 // Add time if going outward (PropagateTo or PropagateToTGeo)
3941 //-------------------------------------------------------------------
3943 // Define budget mode:
3944 // 0: material from AliITSRecoParam (hard coded)
3945 // 1: material from TGeo in one step (on the fly)
3946 // 2: material from lut
3947 // 3: material from TGeo in one step (same for all hypotheses)
3960 if(fTrackingPhase.Contains("Clusters2Tracks"))
3961 { mode=3; } else { mode=1; }
3964 if(fTrackingPhase.Contains("Clusters2Tracks"))
3965 { mode=3; } else { mode=2; }
3971 if(fTrackingPhase.Contains("Default")) mode=0;
3973 Int_t index=fCurrentEsdTrack;
3975 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
3976 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
3978 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
3980 Double_t xOverX0,x0,lengthTimesMeanDensity;
3984 xOverX0 = AliITSRecoParam::GetdPipe();
3985 x0 = AliITSRecoParam::GetX0Be();
3986 lengthTimesMeanDensity = xOverX0*x0;
3987 lengthTimesMeanDensity *= dir;
3988 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3991 if (!t->PropagateToTGeo(xToGo,1)) return 0;
3994 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
3995 xOverX0 = fxOverX0Pipe;
3996 lengthTimesMeanDensity = fxTimesRhoPipe;
3997 lengthTimesMeanDensity *= dir;
3998 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4001 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4002 if(fxOverX0PipeTrks[index]<0) {
4003 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4004 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4005 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4006 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4007 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4010 xOverX0 = fxOverX0PipeTrks[index];
4011 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4012 lengthTimesMeanDensity *= dir;
4013 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4019 //------------------------------------------------------------------------
4020 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4022 TString direction) {
4023 //-------------------------------------------------------------------
4024 // Propagate beyond SPD or SDD shield and correct for material
4025 // (material budget in different ways according to fUseTGeo value)
4026 // Add time if going outward (PropagateTo or PropagateToTGeo)
4027 //-------------------------------------------------------------------
4029 // Define budget mode:
4030 // 0: material from AliITSRecoParam (hard coded)
4031 // 1: material from TGeo in steps of X cm (on the fly)
4032 // X = AliITSRecoParam::GetStepSizeTGeo()
4033 // 2: material from lut
4034 // 3: material from TGeo in one step (same for all hypotheses)
4047 if(fTrackingPhase.Contains("Clusters2Tracks"))
4048 { mode=3; } else { mode=1; }
4051 if(fTrackingPhase.Contains("Clusters2Tracks"))
4052 { mode=3; } else { mode=2; }
4058 if(fTrackingPhase.Contains("Default")) mode=0;
4060 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4062 Int_t shieldindex=0;
4063 if (shield.Contains("SDD")) { // SDDouter
4064 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4066 } else if (shield.Contains("SPD")) { // SPDouter
4067 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4070 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4074 // do nothing if we are already beyond the shield
4075 Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4076 if(dir<0 && rTrack > rToGo) return 1; // going outward
4077 if(dir>0 && rTrack < rToGo) return 1; // going inward
4081 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4083 Int_t index=2*fCurrentEsdTrack+shieldindex;
4085 Double_t xOverX0,x0,lengthTimesMeanDensity;
4090 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4091 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4092 lengthTimesMeanDensity = xOverX0*x0;
4093 lengthTimesMeanDensity *= dir;
4094 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4097 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4098 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4101 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4102 xOverX0 = fxOverX0Shield[shieldindex];
4103 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4104 lengthTimesMeanDensity *= dir;
4105 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4108 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4109 if(fxOverX0ShieldTrks[index]<0) {
4110 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4111 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4112 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4113 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4114 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4117 xOverX0 = fxOverX0ShieldTrks[index];
4118 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4119 lengthTimesMeanDensity *= dir;
4120 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4126 //------------------------------------------------------------------------
4127 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4129 Double_t oldGlobXYZ[3],
4130 TString direction) {
4131 //-------------------------------------------------------------------
4132 // Propagate beyond layer and correct for material
4133 // (material budget in different ways according to fUseTGeo value)
4134 // Add time if going outward (PropagateTo or PropagateToTGeo)
4135 //-------------------------------------------------------------------
4137 // Define budget mode:
4138 // 0: material from AliITSRecoParam (hard coded)
4139 // 1: material from TGeo in stepsof X cm (on the fly)
4140 // X = AliITSRecoParam::GetStepSizeTGeo()
4141 // 2: material from lut
4142 // 3: material from TGeo in one step (same for all hypotheses)
4155 if(fTrackingPhase.Contains("Clusters2Tracks"))
4156 { mode=3; } else { mode=1; }
4159 if(fTrackingPhase.Contains("Clusters2Tracks"))
4160 { mode=3; } else { mode=2; }
4166 if(fTrackingPhase.Contains("Default")) mode=0;
4168 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4170 Double_t r=fgLayers[layerindex].GetR();
4171 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4173 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4175 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4177 Int_t index=6*fCurrentEsdTrack+layerindex;
4180 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4183 // back before material (no correction)
4185 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4186 if (!t->GetLocalXat(rOld,xOld)) return 0;
4187 if (!t->Propagate(xOld)) return 0;
4191 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4192 lengthTimesMeanDensity = xOverX0*x0;
4193 lengthTimesMeanDensity *= dir;
4194 // Bring the track beyond the material
4195 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4198 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4199 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4202 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4203 xOverX0 = fxOverX0Layer[layerindex];
4204 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4205 lengthTimesMeanDensity *= dir;
4206 // Bring the track beyond the material
4207 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4210 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4211 if(fxOverX0LayerTrks[index]<0) {
4212 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4213 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4214 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4215 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4216 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4217 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4220 xOverX0 = fxOverX0LayerTrks[index];
4221 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4222 lengthTimesMeanDensity *= dir;
4223 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4230 //------------------------------------------------------------------------
4231 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4232 //-----------------------------------------------------------------
4233 // Initialize LUT for storing material for each prolonged track
4234 //-----------------------------------------------------------------
4235 fxOverX0PipeTrks = new Float_t[ntracks];
4236 fxTimesRhoPipeTrks = new Float_t[ntracks];
4237 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4238 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4239 fxOverX0LayerTrks = new Float_t[ntracks*6];
4240 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4242 for(Int_t i=0; i<ntracks; i++) {
4243 fxOverX0PipeTrks[i] = -1.;
4244 fxTimesRhoPipeTrks[i] = -1.;
4246 for(Int_t j=0; j<ntracks*2; j++) {
4247 fxOverX0ShieldTrks[j] = -1.;
4248 fxTimesRhoShieldTrks[j] = -1.;
4250 for(Int_t k=0; k<ntracks*6; k++) {
4251 fxOverX0LayerTrks[k] = -1.;
4252 fxTimesRhoLayerTrks[k] = -1.;
4259 //------------------------------------------------------------------------
4260 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4261 //-----------------------------------------------------------------
4262 // Delete LUT for storing material for each prolonged track
4263 //-----------------------------------------------------------------
4264 if(fxOverX0PipeTrks) {
4265 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4267 if(fxOverX0ShieldTrks) {
4268 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4271 if(fxOverX0LayerTrks) {
4272 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4274 if(fxTimesRhoPipeTrks) {
4275 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4277 if(fxTimesRhoShieldTrks) {
4278 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4280 if(fxTimesRhoLayerTrks) {
4281 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4285 //------------------------------------------------------------------------
4286 void AliITStrackerMI::SetForceSkippingOfLayer() {
4287 //-----------------------------------------------------------------
4288 // Check if we are forced to skip layers
4289 // either we set to skip them in RecoParam
4290 // or they were off during data-taking
4291 //-----------------------------------------------------------------
4293 const AliEventInfo *eventInfo = GetEventInfo();
4295 for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
4296 fForceSkippingOfLayer[l] = 0;
4298 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
4302 AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
4304 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
4305 } else if(l==2 || l==3) {
4306 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1;
4308 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
4314 //------------------------------------------------------------------------
4315 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4316 Int_t ilayer,Int_t idet) const {
4317 //-----------------------------------------------------------------
4318 // This method is used to decide whether to allow a prolongation
4319 // without clusters, because we want to skip the layer.
4320 // In this case the return value is > 0:
4321 // return 1: the user requested to skip a layer
4322 // return 2: track outside z acceptance
4323 //-----------------------------------------------------------------
4325 if (ForceSkippingOfLayer(ilayer)) return 1;
4327 Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
4329 if (idet<0 && // out in z
4330 ilayer>innerLayCanSkip &&
4331 AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4332 // check if track will cross SPD outer layer
4333 Double_t phiAtSPD2,zAtSPD2;
4334 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4335 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4337 return 2; // always allow skipping, changed on 05.11.2009
4342 //------------------------------------------------------------------------
4343 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4344 Int_t ilayer,Int_t idet,
4345 Double_t dz,Double_t dy,
4346 Bool_t noClusters) const {
4347 //-----------------------------------------------------------------
4348 // This method is used to decide whether to allow a prolongation
4349 // without clusters, because there is a dead zone in the road.
4350 // In this case the return value is > 0:
4351 // return 1: dead zone at z=0,+-7cm in SPD
4352 // return 2: all road is "bad" (dead or noisy) from the OCDB
4353 // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4354 // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4355 //-----------------------------------------------------------------
4357 // check dead zones at z=0,+-7cm in the SPD
4358 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4359 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4360 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4361 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4362 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4363 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4364 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4365 for (Int_t i=0; i<3; i++)
4366 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4367 AliDebug(2,Form("crack SPD %d",ilayer));
4372 // check bad zones from OCDB
4373 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4375 if (idet<0) return 0;
4377 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4380 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4381 if (ilayer==0 || ilayer==1) { // ---------- SPD
4383 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4385 detSizeFactorX *= 2.;
4386 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4389 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4390 if (detType==2) segm->SetLayer(ilayer+1);
4391 Float_t detSizeX = detSizeFactorX*segm->Dx();
4392 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4394 // check if the road overlaps with bad chips
4396 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
4397 Float_t zlocmin = zloc-dz;
4398 Float_t zlocmax = zloc+dz;
4399 Float_t xlocmin = xloc-dy;
4400 Float_t xlocmax = xloc+dy;
4401 Int_t chipsInRoad[100];
4403 // check if road goes out of detector
4404 Bool_t touchNeighbourDet=kFALSE;
4405 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.5*detSizeX; touchNeighbourDet=kTRUE;}
4406 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.5*detSizeX; touchNeighbourDet=kTRUE;}
4407 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.5*detSizeZ; touchNeighbourDet=kTRUE;}
4408 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.5*detSizeZ; touchNeighbourDet=kTRUE;}
4409 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));
4411 // check if this detector is bad
4413 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4414 if(!touchNeighbourDet) {
4415 return 2; // all detectors in road are bad
4417 return 3; // at least one is bad
4421 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4422 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4423 if (!nChipsInRoad) return 0;
4425 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4426 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4427 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4428 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4429 if (det.IsChipBad(chipsInRoad[iCh])) {
4437 if(!touchNeighbourDet) {
4438 AliDebug(2,"all bad in road");
4439 return 2; // all chips in road are bad
4441 return 3; // at least a bad chip in road
4446 AliDebug(2,"at least a bad in road");
4447 return 3; // at least a bad chip in road
4451 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4452 || !noClusters) return 0;
4454 // There are no clusters in road: check if there is at least
4455 // a bad SPD pixel or SDD anode or SSD strips on both sides
4457 Int_t idetInITS=idet;
4458 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4460 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4461 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4464 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4468 //------------------------------------------------------------------------
4469 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4470 const AliITStrackMI *track,
4471 Float_t &xloc,Float_t &zloc) const {
4472 //-----------------------------------------------------------------
4473 // Gives position of track in local module ref. frame
4474 //-----------------------------------------------------------------
4479 if(idet<0) return kTRUE; // track out of z acceptance of layer
4481 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4483 Int_t lad = Int_t(idet/ndet) + 1;
4485 Int_t det = idet - (lad-1)*ndet + 1;
4487 Double_t xyzGlob[3],xyzLoc[3];
4489 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4490 // take into account the misalignment: xyz at real detector plane
4491 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4493 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4495 xloc = (Float_t)xyzLoc[0];
4496 zloc = (Float_t)xyzLoc[2];
4500 //------------------------------------------------------------------------
4501 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
4503 // Method to be optimized further:
4504 // Aim: decide whether a track can be used for PlaneEff evaluation
4505 // the decision is taken based on the track quality at the layer under study
4506 // no information on the clusters on this layer has to be used
4507 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4508 // the cut is done on number of sigmas from the boundaries
4510 // Input: Actual track, layer [0,5] under study
4512 // Return: kTRUE if this is a good track
4514 // it will apply a pre-selection to obtain good quality tracks.
4515 // Here also you will have the possibility to put a control on the
4516 // impact point of the track on the basic block, in order to exclude border regions
4517 // this will be done by calling a proper method of the AliITSPlaneEff class.
4519 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4520 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4522 Int_t index[AliITSgeomTGeo::kNLayers];
4524 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4526 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4527 index[k]=clusters[k];
4531 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4532 AliITSlayer &layer=fgLayers[ilayer];
4533 Double_t r=layer.GetR();
4534 AliITStrackMI tmp(*track);
4536 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4538 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) {
4539 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4540 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4541 if (tmp.GetClIndex(lay)>=0) ncl++;
4543 Bool_t nextout = kFALSE;
4544 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4545 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4546 Bool_t nextin = kFALSE;
4547 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4548 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4549 if(ncl<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
4551 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
4552 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
4553 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
4554 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
4558 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4559 Int_t idet=layer.FindDetectorIndex(phi,z);
4560 if(idet<0) { AliInfo(Form("cannot find detector"));
4563 // here check if it has good Chi Square.
4565 //propagate to the intersection with the detector plane
4566 const AliITSdetector &det=layer.GetDetector(idet);
4567 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4571 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
4572 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4573 if(key>fPlaneEff->Nblock()) return kFALSE;
4574 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4575 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4577 // DEFINITION OF SEARCH ROAD FOR accepting a track
4579 //For the time being they are hard-wired, later on from AliITSRecoParam
4580 // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
4581 // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
4584 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4585 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4586 // done for RecPoints
4588 // exclude tracks at boundary between detectors
4589 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
4590 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4591 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
4592 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
4593 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
4595 if ( (locx-dx < blockXmn+boundaryWidth) ||
4596 (locx+dx > blockXmx-boundaryWidth) ||
4597 (locz-dz < blockZmn+boundaryWidth) ||
4598 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
4601 //------------------------------------------------------------------------
4602 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
4604 // This Method has to be optimized! For the time-being it uses the same criteria
4605 // as those used in the search of extra clusters for overlapping modules.
4607 // Method Purpose: estabilish whether a track has produced a recpoint or not
4608 // in the layer under study (For Plane efficiency)
4610 // inputs: AliITStrackMI* track (pointer to a usable track)
4612 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
4613 // traversed by this very track. In details:
4614 // - if a cluster can be associated to the track then call
4615 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
4616 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
4619 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
4620 AliITSlayer &layer=fgLayers[ilayer];
4621 Double_t r=layer.GetR();
4622 AliITStrackMI tmp(*track);
4626 if (!tmp.GetPhiZat(r,phi,z)) return;
4627 Int_t idet=layer.FindDetectorIndex(phi,z);
4629 if(idet<0) { AliInfo(Form("cannot find detector"));
4633 //propagate to the intersection with the detector plane
4634 const AliITSdetector &det=layer.GetDetector(idet);
4635 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
4639 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
4641 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
4642 TMath::Sqrt(tmp.GetSigmaZ2() +
4643 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4644 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4645 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
4646 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
4647 TMath::Sqrt(tmp.GetSigmaY2() +
4648 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4649 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4650 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
4652 // road in global (rphi,z) [i.e. in tracking ref. system]
4653 Double_t zmin = tmp.GetZ() - dz;
4654 Double_t zmax = tmp.GetZ() + dz;
4655 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
4656 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
4658 // select clusters in road
4659 layer.SelectClusters(zmin,zmax,ymin,ymax);
4661 // Define criteria for track-cluster association
4662 Double_t msz = tmp.GetSigmaZ2() +
4663 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4664 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4665 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
4666 Double_t msy = tmp.GetSigmaY2() +
4667 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4668 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4669 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
4670 if (tmp.GetConstrain()) {
4671 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
4672 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
4674 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
4675 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
4677 msz = 1./msz; // 1/RoadZ^2
4678 msy = 1./msy; // 1/RoadY^2
4681 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
4683 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
4684 //Double_t tolerance=0.2;
4685 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
4686 idetc = cl->GetDetectorIndex();
4687 if(idet!=idetc) continue;
4688 //Int_t ilay = cl->GetLayer();
4690 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
4691 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
4693 Double_t chi2=tmp.GetPredictedChi2(cl);
4694 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
4698 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
4700 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
4701 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4702 if(key>fPlaneEff->Nblock()) return;
4703 Bool_t found=kFALSE;
4706 while ((cl=layer.GetNextCluster(clidx))!=0) {
4707 idetc = cl->GetDetectorIndex();
4708 if(idet!=idetc) continue;
4709 // here real control to see whether the cluster can be associated to the track.
4710 // cluster not associated to track
4711 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
4712 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
4713 // calculate track-clusters chi2
4714 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
4715 // in particular, the error associated to the cluster
4716 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
4718 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
4720 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
4721 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
4722 // track->SetExtraModule(ilayer,idetExtra);
4724 if(!fPlaneEff->UpDatePlaneEff(found,key))
4725 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
4726 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
4727 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
4728 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
4729 Int_t cltype[2]={-999,-999};
4733 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4734 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4737 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
4738 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
4739 cltype[0]=layer.GetCluster(ci)->GetNy();
4740 cltype[1]=layer.GetCluster(ci)->GetNz();
4742 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
4743 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
4744 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
4745 // It is computed properly by calling the method
4746 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4748 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
4749 //if (tmp.PropagateTo(x,0.,0.)) {
4750 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
4751 AliCluster c(*layer.GetCluster(ci));
4752 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
4753 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
4754 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
4755 clu[2]=TMath::Sqrt(c.GetSigmaY2());
4756 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
4759 fPlaneEff->FillHistos(key,found,tr,clu,cltype);