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 <TTreeStream.h>
32 #include <TDatabasePDG.h>
38 #include "AliESDEvent.h"
39 #include "AliESDtrack.h"
40 #include "AliESDVertex.h"
43 #include "AliITSRecPoint.h"
44 #include "AliITSgeomTGeo.h"
45 #include "AliITSReconstructor.h"
46 #include "AliTrackPointArray.h"
47 #include "AliAlignObj.h"
48 #include "AliITSClusterParam.h"
49 #include "AliCDBManager.h"
50 #include "AliCDBEntry.h"
51 #include "AliITSsegmentation.h"
52 #include "AliITSCalibration.h"
53 #include "AliITSCalibrationSPD.h"
54 #include "AliITSCalibrationSDD.h"
55 #include "AliITSCalibrationSSD.h"
56 #include "AliITSPlaneEff.h"
57 #include "AliITSPlaneEffSPD.h"
58 #include "AliITSPlaneEffSDD.h"
59 #include "AliITSPlaneEffSSD.h"
60 #include "AliITStrackerMI.h"
62 ClassImp(AliITStrackerMI)
64 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
66 AliITStrackerMI::AliITStrackerMI():AliTracker(),
76 fLastLayerToTrackTo(0),
79 fTrackingPhase("Default"),
85 fxTimesRhoPipeTrks(0),
86 fxOverX0ShieldTrks(0),
87 fxTimesRhoShieldTrks(0),
89 fxTimesRhoLayerTrks(0),
96 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
97 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
98 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
100 //------------------------------------------------------------------------
101 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
102 fI(AliITSgeomTGeo::GetNLayers()),
111 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
114 fTrackingPhase("Default"),
120 fxTimesRhoPipeTrks(0),
121 fxOverX0ShieldTrks(0),
122 fxTimesRhoShieldTrks(0),
123 fxOverX0LayerTrks(0),
124 fxTimesRhoLayerTrks(0),
126 fITSChannelStatus(0),
129 //--------------------------------------------------------------------
130 //This is the AliITStrackerMI constructor
131 //--------------------------------------------------------------------
133 AliWarning("\"geom\" is actually a dummy argument !");
139 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
140 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
141 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
143 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
144 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
145 Double_t poff=TMath::ATan2(y,x);
147 Double_t r=TMath::Sqrt(x*x + y*y);
149 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
150 r += TMath::Sqrt(x*x + y*y);
151 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
152 r += TMath::Sqrt(x*x + y*y);
153 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
154 r += TMath::Sqrt(x*x + y*y);
157 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
159 for (Int_t j=1; j<nlad+1; j++) {
160 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
161 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
162 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
164 Double_t txyz[3]={0.};
165 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
166 m.LocalToMaster(txyz,xyz);
167 r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
168 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
170 if (phi<0) phi+=TMath::TwoPi();
171 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
173 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
174 new(&det) AliITSdetector(r,phi);
175 // compute the real radius (with misalignment)
176 TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
178 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
179 mmisal.LocalToMaster(txyz,xyz);
180 Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
181 det.SetRmisal(rmisal);
183 } // end loop on detectors
184 } // end loop on ladders
185 } // end loop on layers
188 fI=AliITSgeomTGeo::GetNLayers();
191 fConstraint[0]=1; fConstraint[1]=0;
193 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
194 AliITSReconstructor::GetRecoParam()->GetYVdef(),
195 AliITSReconstructor::GetRecoParam()->GetZVdef()};
196 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
197 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
198 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
199 SetVertex(xyzVtx,ersVtx);
201 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=AliITSRecoParam::GetLayersNotToSkip(i);
202 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
203 for (Int_t i=0;i<100000;i++){
204 fBestTrackIndex[i]=0;
207 // store positions of centre of SPD modules (in z)
209 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
210 fSPDdetzcentre[0] = tr[2];
211 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
212 fSPDdetzcentre[1] = tr[2];
213 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
214 fSPDdetzcentre[2] = tr[2];
215 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
216 fSPDdetzcentre[3] = tr[2];
218 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
219 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
220 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
224 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
225 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
227 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
229 // only for plane efficiency evaluation
230 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff()) {
231 Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
232 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane))
233 AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
234 if (iplane<2) fPlaneEff = new AliITSPlaneEffSPD();
235 else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
236 else fPlaneEff = new AliITSPlaneEffSSD();
237 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
238 if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
239 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
242 //------------------------------------------------------------------------
243 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
245 fBestTrack(tracker.fBestTrack),
246 fTrackToFollow(tracker.fTrackToFollow),
247 fTrackHypothesys(tracker.fTrackHypothesys),
248 fBestHypothesys(tracker.fBestHypothesys),
249 fOriginal(tracker.fOriginal),
250 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
251 fPass(tracker.fPass),
252 fAfterV0(tracker.fAfterV0),
253 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
254 fCoefficients(tracker.fCoefficients),
256 fTrackingPhase(tracker.fTrackingPhase),
257 fUseTGeo(tracker.fUseTGeo),
258 fNtracks(tracker.fNtracks),
259 fxOverX0Pipe(tracker.fxOverX0Pipe),
260 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
262 fxTimesRhoPipeTrks(0),
263 fxOverX0ShieldTrks(0),
264 fxTimesRhoShieldTrks(0),
265 fxOverX0LayerTrks(0),
266 fxTimesRhoLayerTrks(0),
267 fDebugStreamer(tracker.fDebugStreamer),
268 fITSChannelStatus(tracker.fITSChannelStatus),
269 fDetTypeRec(tracker.fDetTypeRec),
270 fPlaneEff(tracker.fPlaneEff) {
274 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
277 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
278 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
281 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
282 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
285 //------------------------------------------------------------------------
286 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
287 //Assignment operator
288 this->~AliITStrackerMI();
289 new(this) AliITStrackerMI(tracker);
292 //------------------------------------------------------------------------
293 AliITStrackerMI::~AliITStrackerMI()
298 if (fCoefficients) delete [] fCoefficients;
299 DeleteTrksMaterialLUT();
300 if (fDebugStreamer) {
301 //fDebugStreamer->Close();
302 delete fDebugStreamer;
304 if(fITSChannelStatus) delete fITSChannelStatus;
305 if(fPlaneEff) delete fPlaneEff;
307 //------------------------------------------------------------------------
308 void AliITStrackerMI::SetLayersNotToSkip(Int_t *l) {
309 //--------------------------------------------------------------------
310 //This function set masks of the layers which must be not skipped
311 //--------------------------------------------------------------------
312 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=l[i];
314 //------------------------------------------------------------------------
315 void AliITStrackerMI::ReadBadFromDetTypeRec() {
316 //--------------------------------------------------------------------
317 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
319 //--------------------------------------------------------------------
321 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
323 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
325 if(!fDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
328 if(fITSChannelStatus) delete fITSChannelStatus;
329 fITSChannelStatus = new AliITSChannelStatus(fDetTypeRec);
331 // ITS detectors and chips
332 Int_t i=0,j=0,k=0,ndet=0;
333 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
334 Int_t nBadDetsPerLayer=0;
335 ndet=AliITSgeomTGeo::GetNDetectors(i);
336 for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
337 for (k=1; k<ndet+1; k++) {
338 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
339 det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fDetTypeRec);
340 if(det.IsBad()) {nBadDetsPerLayer++;}
341 } // end loop on detectors
342 } // end loop on ladders
343 Info("ReadBadFromDetTypeRec",Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
344 } // end loop on layers
348 //------------------------------------------------------------------------
349 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
350 //--------------------------------------------------------------------
351 //This function loads ITS clusters
352 //--------------------------------------------------------------------
353 TBranch *branch=cTree->GetBranch("ITSRecPoints");
355 Error("LoadClusters"," can't get the branch !\n");
359 static TClonesArray dummy("AliITSRecPoint",10000), *clusters=&dummy;
360 branch->SetAddress(&clusters);
362 Int_t i=0,j=0,ndet=0;
364 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
365 ndet=fgLayers[i].GetNdetectors();
366 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
367 for (; j<jmax; j++) {
368 if (!cTree->GetEvent(j)) continue;
369 Int_t ncl=clusters->GetEntriesFast();
370 SignDeltas(clusters,GetZ());
373 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
374 detector=c->GetDetectorIndex();
376 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
378 fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
381 // add dead zone "virtual" cluster in SPD, if there is a cluster within
382 // zwindow cm from the dead zone
383 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
384 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
385 Int_t lab[4] = {0,0,0,detector};
386 Int_t info[3] = {0,0,i};
387 Float_t q = 0.; // this identifies virtual clusters
388 Float_t hit[5] = {xdead,
390 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
391 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
393 Bool_t local = kTRUE;
394 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
395 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
396 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
397 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
398 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
399 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
400 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
401 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
402 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
403 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
404 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
405 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
406 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
407 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
408 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
409 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
410 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
411 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
412 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
414 } // "virtual" clusters in SPD
418 fgLayers[i].ResetRoad(); //road defined by the cluster density
419 fgLayers[i].SortClusters();
426 //------------------------------------------------------------------------
427 void AliITStrackerMI::UnloadClusters() {
428 //--------------------------------------------------------------------
429 //This function unloads ITS clusters
430 //--------------------------------------------------------------------
431 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
433 //------------------------------------------------------------------------
434 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
435 //--------------------------------------------------------------------
436 // Publishes all pointers to clusters known to the tracker into the
437 // passed object array.
438 // The ownership is not transfered - the caller is not expected to delete
440 //--------------------------------------------------------------------
442 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
443 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
444 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
451 //------------------------------------------------------------------------
452 static Int_t CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
453 //--------------------------------------------------------------------
454 // Correction for the material between the TPC and the ITS
455 //--------------------------------------------------------------------
456 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
457 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
458 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
459 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
460 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
461 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
462 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
463 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
465 Error("CorrectForTPCtoITSDeadZoneMaterial","Track is already in the dead zone !");
471 //------------------------------------------------------------------------
472 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
473 //--------------------------------------------------------------------
474 // This functions reconstructs ITS tracks
475 // The clusters must be already loaded !
476 //--------------------------------------------------------------------
479 fTrackingPhase="Clusters2Tracks";
481 TObjArray itsTracks(15000);
483 fEsd = event; // store pointer to the esd
485 // temporary (for cosmics)
486 if(event->GetVertex()) {
487 TString title = event->GetVertex()->GetTitle();
488 if(title.Contains("cosmics")) {
489 Double_t xyz[3]={GetX(),GetY(),GetZ()};
490 Double_t exyz[3]={0.1,0.1,0.1};
496 {/* Read ESD tracks */
497 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
498 Int_t nentr=event->GetNumberOfTracks();
499 Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
501 AliESDtrack *esd=event->GetTrack(nentr);
502 // ---- for debugging:
503 //if(TMath::Abs(esd->GetX()-83.65)<0.1) { FILE *f=fopen("tpc.dat","a"); fprintf(f,"%f %f %f %f %f %f\n",(Float_t)event->GetEventNumberInFile(),(Float_t)TMath::Abs(esd->GetLabel()),(Float_t)esd->GetX(),(Float_t)esd->GetY(),(Float_t)esd->GetZ(),(Float_t)esd->Pt()); fclose(f); }
505 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
506 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
507 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
508 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
511 t=new AliITStrackMI(*esd);
512 } catch (const Char_t *msg) {
513 //Warning("Clusters2Tracks",msg);
517 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
518 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
521 // look at the ESD mass hypothesys !
522 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
524 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
526 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
527 //track - can be V0 according to TPC
529 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
533 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
537 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
541 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
546 t->SetReconstructed(kFALSE);
547 itsTracks.AddLast(t);
548 fOriginal.AddLast(t);
550 } /* End Read ESD tracks */
554 Int_t nentr=itsTracks.GetEntriesFast();
555 fTrackHypothesys.Expand(nentr);
556 fBestHypothesys.Expand(nentr);
557 MakeCoefficients(nentr);
558 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
560 // THE TWO TRACKING PASSES
561 for (fPass=0; fPass<2; fPass++) {
562 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
563 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
564 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
565 if (t==0) continue; //this track has been already tracked
566 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
567 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
568 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
569 if (fConstraint[fPass]) {
570 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
571 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
574 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
575 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
577 ResetTrackToFollow(*t);
580 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
583 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
585 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
586 if (!besttrack) continue;
587 besttrack->SetLabel(tpcLabel);
588 // besttrack->CookdEdx();
590 besttrack->SetFakeRatio(1.);
591 CookLabel(besttrack,0.); //For comparison only
592 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
594 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
596 t->SetReconstructed(kTRUE);
598 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
600 GetBestHypothesysMIP(itsTracks);
601 } // end loop on the two tracking passes
603 if(event->GetNumberOfV0s()>0) UpdateTPCV0(event);
604 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) FindV02(event);
609 Int_t entries = fTrackHypothesys.GetEntriesFast();
610 for (Int_t ientry=0; ientry<entries; ientry++) {
611 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
612 if (array) array->Delete();
613 delete fTrackHypothesys.RemoveAt(ientry);
616 fTrackHypothesys.Delete();
617 fBestHypothesys.Delete();
619 delete [] fCoefficients;
621 DeleteTrksMaterialLUT();
623 Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
625 fTrackingPhase="Default";
629 //------------------------------------------------------------------------
630 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
631 //--------------------------------------------------------------------
632 // This functions propagates reconstructed ITS tracks back
633 // The clusters must be loaded !
634 //--------------------------------------------------------------------
635 fTrackingPhase="PropagateBack";
636 Int_t nentr=event->GetNumberOfTracks();
637 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
640 for (Int_t i=0; i<nentr; i++) {
641 AliESDtrack *esd=event->GetTrack(i);
643 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
644 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
648 t=new AliITStrackMI(*esd);
649 } catch (const Char_t *msg) {
650 //Warning("PropagateBack",msg);
654 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
656 ResetTrackToFollow(*t);
658 // propagate to vertex [SR, GSI 17.02.2003]
659 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
660 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
661 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
662 fTrackToFollow.StartTimeIntegral();
663 // from vertex to outside pipe
664 CorrectForPipeMaterial(&fTrackToFollow,"outward");
667 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
668 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
669 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
673 fTrackToFollow.SetLabel(t->GetLabel());
674 //fTrackToFollow.CookdEdx();
675 CookLabel(&fTrackToFollow,0.); //For comparison only
676 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
677 //UseClusters(&fTrackToFollow);
683 Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
685 fTrackingPhase="Default";
689 //------------------------------------------------------------------------
690 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
691 //--------------------------------------------------------------------
692 // This functions refits ITS tracks using the
693 // "inward propagated" TPC tracks
694 // The clusters must be loaded !
695 //--------------------------------------------------------------------
696 fTrackingPhase="RefitInward";
697 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) RefitV02(event);
698 Int_t nentr=event->GetNumberOfTracks();
699 Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
702 for (Int_t i=0; i<nentr; i++) {
703 AliESDtrack *esd=event->GetTrack(i);
705 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
706 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
707 if (esd->GetStatus()&AliESDtrack::kTPCout)
708 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
712 t=new AliITStrackMI(*esd);
713 } catch (const Char_t *msg) {
714 //Warning("RefitInward",msg);
718 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
719 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
724 ResetTrackToFollow(*t);
725 fTrackToFollow.ResetClusters();
727 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
728 fTrackToFollow.ResetCovariance(10.);
731 Bool_t pe=AliITSReconstructor::GetRecoParam()->GetComputePlaneEff();
732 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
733 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
734 AliDebug(2," refit OK");
735 fTrackToFollow.SetLabel(t->GetLabel());
736 // fTrackToFollow.CookdEdx();
737 CookdEdx(&fTrackToFollow);
739 CookLabel(&fTrackToFollow,0.0); //For comparison only
742 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
743 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
744 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
745 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
746 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
747 Float_t r[3]={0.,0.,0.};
749 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
756 Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
758 fTrackingPhase="Default";
762 //------------------------------------------------------------------------
763 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
764 //--------------------------------------------------------------------
765 // Return pointer to a given cluster
766 //--------------------------------------------------------------------
767 Int_t l=(index & 0xf0000000) >> 28;
768 Int_t c=(index & 0x0fffffff) >> 00;
769 return fgLayers[l].GetCluster(c);
771 //------------------------------------------------------------------------
772 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
773 //--------------------------------------------------------------------
774 // Get track space point with index i
775 //--------------------------------------------------------------------
777 Int_t l=(index & 0xf0000000) >> 28;
778 Int_t c=(index & 0x0fffffff) >> 00;
779 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
780 Int_t idet = cl->GetDetectorIndex();
784 cl->GetGlobalXYZ(xyz);
785 cl->GetGlobalCov(cov);
787 p.SetCharge(cl->GetQ());
788 p.SetDriftTime(cl->GetDriftTime());
789 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
792 iLayer = AliGeomManager::kSPD1;
795 iLayer = AliGeomManager::kSPD2;
798 iLayer = AliGeomManager::kSDD1;
801 iLayer = AliGeomManager::kSDD2;
804 iLayer = AliGeomManager::kSSD1;
807 iLayer = AliGeomManager::kSSD2;
810 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
813 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
814 p.SetVolumeID((UShort_t)volid);
817 //------------------------------------------------------------------------
818 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
819 AliTrackPoint& p, const AliESDtrack *t) {
820 //--------------------------------------------------------------------
821 // Get track space point with index i
822 // (assign error estimated during the tracking)
823 //--------------------------------------------------------------------
825 Int_t l=(index & 0xf0000000) >> 28;
826 Int_t c=(index & 0x0fffffff) >> 00;
827 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
828 Int_t idet = cl->GetDetectorIndex();
830 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
832 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
834 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
835 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
836 Double_t alpha = t->GetAlpha();
837 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
838 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,AliTracker::GetBz()));
839 phi += alpha-det.GetPhi();
840 Float_t tgphi = TMath::Tan(phi);
842 Float_t tgl = t->GetTgl(); // tgl about const along track
843 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
845 Float_t errlocalx,errlocalz;
846 Bool_t addMisalErr=kFALSE;
847 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errlocalx,errlocalz,addMisalErr);
851 cl->GetGlobalXYZ(xyz);
852 // cl->GetGlobalCov(cov);
853 Float_t pos[3] = {0.,0.,0.};
854 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errlocalx*errlocalx,errlocalz*errlocalz,0);
855 tmpcl.GetGlobalCov(cov);
858 p.SetCharge(cl->GetQ());
859 p.SetDriftTime(cl->GetDriftTime());
861 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
864 iLayer = AliGeomManager::kSPD1;
867 iLayer = AliGeomManager::kSPD2;
870 iLayer = AliGeomManager::kSDD1;
873 iLayer = AliGeomManager::kSDD2;
876 iLayer = AliGeomManager::kSSD1;
879 iLayer = AliGeomManager::kSSD2;
882 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
885 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
887 p.SetVolumeID((UShort_t)volid);
890 //------------------------------------------------------------------------
891 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
893 //--------------------------------------------------------------------
894 // Follow prolongation tree
895 //--------------------------------------------------------------------
897 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
898 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
901 AliESDtrack * esd = otrack->GetESDtrack();
902 if (esd->GetV0Index(0)>0) {
903 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
904 // mapping of ESD track is different as ITS track in Containers
905 // Need something more stable
906 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
907 for (Int_t i=0;i<3;i++){
908 Int_t index = esd->GetV0Index(i);
910 AliESDv0 * vertex = fEsd->GetV0(index);
911 if (vertex->GetStatus()<0) continue; // rejected V0
913 if (esd->GetSign()>0) {
914 vertex->SetIndex(0,esdindex);
916 vertex->SetIndex(1,esdindex);
920 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
922 bestarray = new TObjArray(5);
923 fBestHypothesys.AddAt(bestarray,esdindex);
927 //setup tree of the prolongations
929 static AliITStrackMI tracks[7][100];
930 AliITStrackMI *currenttrack;
931 static AliITStrackMI currenttrack1;
932 static AliITStrackMI currenttrack2;
933 static AliITStrackMI backuptrack;
935 Int_t nindexes[7][100];
936 Float_t normalizedchi2[100];
937 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
938 otrack->SetNSkipped(0);
939 new (&(tracks[6][0])) AliITStrackMI(*otrack);
941 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
942 Int_t modstatus = 1; // found
946 // follow prolongations
947 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
948 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
951 AliITSlayer &layer=fgLayers[ilayer];
952 Double_t r = layer.GetR();
958 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
960 if (ntracks[ilayer]>=100) break;
961 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
962 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
963 if (ntracks[ilayer]>15+ilayer){
964 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
965 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
968 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
970 // material between SSD and SDD, SDD and SPD
972 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
974 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
978 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
979 Int_t idet=layer.FindDetectorIndex(phi,z);
981 Double_t trackGlobXYZ1[3];
982 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
984 // Get the budget to the primary vertex for the current track being prolonged
985 Double_t budgetToPrimVertex = GetEffectiveThickness();
987 // check if we allow a prolongation without point
988 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
990 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
991 // propagate to the layer radius
992 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
993 if(!vtrack->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) continue;
994 // apply correction for material of the current layer
995 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
996 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
997 vtrack->SetClIndex(ilayer,0);
998 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
999 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1000 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1002 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1007 // track outside layer acceptance in z
1008 if (idet<0) continue;
1010 //propagate to the intersection with the detector plane
1011 const AliITSdetector &det=layer.GetDetector(idet);
1012 new(¤ttrack2) AliITStrackMI(currenttrack1);
1013 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1014 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1015 currenttrack1.SetDetectorIndex(idet);
1016 currenttrack2.SetDetectorIndex(idet);
1017 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1020 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1022 // road in global (rphi,z) [i.e. in tracking ref. system]
1023 Double_t zmin,zmax,ymin,ymax;
1024 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1026 // select clusters in road
1027 layer.SelectClusters(zmin,zmax,ymin,ymax);
1028 //********************
1030 // Define criteria for track-cluster association
1031 Double_t msz = currenttrack1.GetSigmaZ2() +
1032 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1033 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1034 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1035 Double_t msy = currenttrack1.GetSigmaY2() +
1036 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1037 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1038 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1040 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1041 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1043 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1044 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1046 msz = 1./msz; // 1/RoadZ^2
1047 msy = 1./msy; // 1/RoadY^2
1051 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1053 const AliITSRecPoint *cl=0;
1055 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1056 Bool_t deadzoneSPD=kFALSE;
1057 currenttrack = ¤ttrack1;
1059 // check if the road contains a dead zone
1060 Bool_t noClusters = kFALSE;
1061 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1062 if (noClusters) AliDebug(2,"no clusters in road");
1063 Double_t dz=0.5*(zmax-zmin);
1064 Double_t dy=0.5*(ymax-ymin);
1065 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1066 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1067 // create a prolongation without clusters (check also if there are no clusters in the road)
1070 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1071 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1072 updatetrack->SetClIndex(ilayer,0);
1074 modstatus = 5; // no cls in road
1075 } else if (dead==1) {
1076 modstatus = 7; // holes in z in SPD
1077 } else if (dead==2 || dead==3) {
1078 modstatus = 2; // dead from OCDB
1080 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1081 // apply correction for material of the current layer
1082 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1083 if (constrain) { // apply vertex constrain
1084 updatetrack->SetConstrain(constrain);
1085 Bool_t isPrim = kTRUE;
1086 if (ilayer<4) { // check that it's close to the vertex
1087 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1088 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1089 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1090 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1091 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1093 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1096 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1097 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1098 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1106 // loop over clusters in the road
1107 while ((cl=layer.GetNextCluster(clidx))!=0) {
1108 if (ntracks[ilayer]>95) break; //space for skipped clusters
1109 Bool_t changedet =kFALSE;
1110 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
1111 Int_t idetc=cl->GetDetectorIndex();
1113 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1114 // take into account misalignment (bring track to real detector plane)
1115 Double_t xTrOrig = currenttrack->GetX();
1116 if (!currenttrack->PropagateTo(xTrOrig+cl->GetX(),0.,0.)) continue;
1117 // a first cut on track-cluster distance
1118 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1119 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1120 { // cluster not associated to track
1121 AliDebug(2,"not associated");
1124 // bring track back to ideal detector plane
1125 if (!currenttrack->PropagateTo(xTrOrig,0.,0.)) continue;
1126 } else { // have to move track to cluster's detector
1127 const AliITSdetector &detc=layer.GetDetector(idetc);
1128 // a first cut on track-cluster distance
1130 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1131 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1132 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1133 continue; // cluster not associated to track
1135 new (&backuptrack) AliITStrackMI(currenttrack2);
1137 currenttrack =¤ttrack2;
1138 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1139 new (currenttrack) AliITStrackMI(backuptrack);
1143 currenttrack->SetDetectorIndex(idetc);
1144 // Get again the budget to the primary vertex
1145 // for the current track being prolonged, if had to change detector
1146 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1149 // calculate track-clusters chi2
1150 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1152 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1153 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1154 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1155 if (ntracks[ilayer]>=100) continue;
1156 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1157 updatetrack->SetClIndex(ilayer,0);
1158 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1160 if (cl->GetQ()!=0) { // real cluster
1161 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1162 AliDebug(2,"update failed");
1165 updatetrack->SetSampledEdx(cl->GetQ(),updatetrack->GetNumberOfClusters()-1); //b.b.
1166 modstatus = 1; // found
1167 } else { // virtual cluster in dead zone
1168 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1169 updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1170 modstatus = 7; // holes in z in SPD
1174 Float_t xlocnewdet,zlocnewdet;
1175 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1176 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1179 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1181 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1183 // apply correction for material of the current layer
1184 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1186 if (constrain) { // apply vertex constrain
1187 updatetrack->SetConstrain(constrain);
1188 Bool_t isPrim = kTRUE;
1189 if (ilayer<4) { // check that it's close to the vertex
1190 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1191 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1192 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1193 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1194 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1196 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1197 } //apply vertex constrain
1199 } // create new hypothesis
1201 AliDebug(2,"chi2 too large");
1204 } // loop over possible prolongations
1206 // allow one prolongation without clusters
1207 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1208 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1209 // apply correction for material of the current layer
1210 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1211 vtrack->SetClIndex(ilayer,0);
1212 modstatus = 3; // skipped
1213 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1214 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1215 vtrack->IncrementNSkipped();
1219 // allow one prolongation without clusters for tracks with |tgl|>1.1
1220 if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) { //big theta - for low flux
1221 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1222 // apply correction for material of the current layer
1223 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1224 vtrack->SetClIndex(ilayer,0);
1225 modstatus = 3; // skipped
1226 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1227 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1228 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1233 } // loop over tracks in layer ilayer+1
1235 //loop over track candidates for the current layer
1241 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1242 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1243 if (normalizedchi2[itrack] <
1244 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1248 if (constrain) { // constrain
1249 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1251 } else { // !constrain
1252 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1257 // sort tracks by increasing normalized chi2
1258 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1259 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1260 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1261 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1262 } // end loop over layers
1266 // Now select tracks to be kept
1268 Int_t max = constrain ? 20 : 5;
1270 // tracks that reach layer 0 (SPD inner)
1271 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1272 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1273 if (track.GetNumberOfClusters()<2) continue;
1274 if (!constrain && track.GetNormChi2(0) >
1275 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1278 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1281 // tracks that reach layer 1 (SPD outer)
1282 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1283 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1284 if (track.GetNumberOfClusters()<4) continue;
1285 if (!constrain && track.GetNormChi2(1) >
1286 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1287 if (constrain) track.IncrementNSkipped();
1289 track.SetD(0,track.GetD(GetX(),GetY()));
1290 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1291 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1292 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1295 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1298 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1300 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1301 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1302 if (track.GetNumberOfClusters()<3) continue;
1303 if (!constrain && track.GetNormChi2(2) >
1304 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1305 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1307 track.SetD(0,track.GetD(GetX(),GetY()));
1308 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1309 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1310 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1313 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1319 // register best track of each layer - important for V0 finder
1321 for (Int_t ilayer=0;ilayer<5;ilayer++){
1322 if (ntracks[ilayer]==0) continue;
1323 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1324 if (track.GetNumberOfClusters()<1) continue;
1325 CookLabel(&track,0);
1326 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1330 // update TPC V0 information
1332 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1333 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1334 for (Int_t i=0;i<3;i++){
1335 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1336 if (index==0) break;
1337 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1338 if (vertex->GetStatus()<0) continue; // rejected V0
1340 if (otrack->GetSign()>0) {
1341 vertex->SetIndex(0,esdindex);
1344 vertex->SetIndex(1,esdindex);
1346 //find nearest layer with track info
1347 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1348 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1349 Int_t nearest = nearestold;
1350 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1351 if (ntracks[nearest]==0){
1356 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1357 if (nearestold<5&&nearest<5){
1358 Bool_t accept = track.GetNormChi2(nearest)<10;
1360 if (track.GetSign()>0) {
1361 vertex->SetParamP(track);
1362 vertex->Update(fprimvertex);
1363 //vertex->SetIndex(0,track.fESDtrack->GetID());
1364 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1366 vertex->SetParamN(track);
1367 vertex->Update(fprimvertex);
1368 //vertex->SetIndex(1,track.fESDtrack->GetID());
1369 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1371 vertex->SetStatus(vertex->GetStatus()+1);
1373 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1380 //------------------------------------------------------------------------
1381 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1383 //--------------------------------------------------------------------
1386 return fgLayers[layer];
1388 //------------------------------------------------------------------------
1389 AliITStrackerMI::AliITSlayer::AliITSlayer():
1414 //--------------------------------------------------------------------
1415 //default AliITSlayer constructor
1416 //--------------------------------------------------------------------
1417 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1418 fClusterWeight[i]=0;
1419 fClusterTracks[0][i]=-1;
1420 fClusterTracks[1][i]=-1;
1421 fClusterTracks[2][i]=-1;
1422 fClusterTracks[3][i]=-1;
1425 //------------------------------------------------------------------------
1426 AliITStrackerMI::AliITSlayer::
1427 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1452 //--------------------------------------------------------------------
1453 //main AliITSlayer constructor
1454 //--------------------------------------------------------------------
1455 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1456 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1458 //------------------------------------------------------------------------
1459 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1461 fPhiOffset(layer.fPhiOffset),
1462 fNladders(layer.fNladders),
1463 fZOffset(layer.fZOffset),
1464 fNdetectors(layer.fNdetectors),
1465 fDetectors(layer.fDetectors),
1470 fClustersCs(layer.fClustersCs),
1471 fClusterIndexCs(layer.fClusterIndexCs),
1475 fCurrentSlice(layer.fCurrentSlice),
1482 fAccepted(layer.fAccepted),
1486 //------------------------------------------------------------------------
1487 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1488 //--------------------------------------------------------------------
1489 // AliITSlayer destructor
1490 //--------------------------------------------------------------------
1491 delete [] fDetectors;
1492 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1493 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1494 fClusterWeight[i]=0;
1495 fClusterTracks[0][i]=-1;
1496 fClusterTracks[1][i]=-1;
1497 fClusterTracks[2][i]=-1;
1498 fClusterTracks[3][i]=-1;
1501 //------------------------------------------------------------------------
1502 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1503 //--------------------------------------------------------------------
1504 // This function removes loaded clusters
1505 //--------------------------------------------------------------------
1506 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1507 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1508 fClusterWeight[i]=0;
1509 fClusterTracks[0][i]=-1;
1510 fClusterTracks[1][i]=-1;
1511 fClusterTracks[2][i]=-1;
1512 fClusterTracks[3][i]=-1;
1518 //------------------------------------------------------------------------
1519 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1520 //--------------------------------------------------------------------
1521 // This function reset weights of the clusters
1522 //--------------------------------------------------------------------
1523 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1524 fClusterWeight[i]=0;
1525 fClusterTracks[0][i]=-1;
1526 fClusterTracks[1][i]=-1;
1527 fClusterTracks[2][i]=-1;
1528 fClusterTracks[3][i]=-1;
1530 for (Int_t i=0; i<fN;i++) {
1531 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1532 if (cl&&cl->IsUsed()) cl->Use();
1536 //------------------------------------------------------------------------
1537 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1538 //--------------------------------------------------------------------
1539 // This function calculates the road defined by the cluster density
1540 //--------------------------------------------------------------------
1542 for (Int_t i=0; i<fN; i++) {
1543 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1545 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1547 //------------------------------------------------------------------------
1548 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1549 //--------------------------------------------------------------------
1550 //This function adds a cluster to this layer
1551 //--------------------------------------------------------------------
1552 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1553 ::Error("InsertCluster","Too many clusters !\n");
1559 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1560 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1561 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1562 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1563 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1567 //------------------------------------------------------------------------
1568 void AliITStrackerMI::AliITSlayer::SortClusters()
1573 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1574 Float_t *z = new Float_t[fN];
1575 Int_t * index = new Int_t[fN];
1577 for (Int_t i=0;i<fN;i++){
1578 z[i] = fClusters[i]->GetZ();
1580 TMath::Sort(fN,z,index,kFALSE);
1581 for (Int_t i=0;i<fN;i++){
1582 clusters[i] = fClusters[index[i]];
1585 for (Int_t i=0;i<fN;i++){
1586 fClusters[i] = clusters[i];
1587 fZ[i] = fClusters[i]->GetZ();
1588 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1589 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1590 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1600 for (Int_t i=0;i<fN;i++){
1601 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1602 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1603 fClusterIndex[i] = i;
1607 fDy5 = (fYB[1]-fYB[0])/5.;
1608 fDy10 = (fYB[1]-fYB[0])/10.;
1609 fDy20 = (fYB[1]-fYB[0])/20.;
1610 for (Int_t i=0;i<6;i++) fN5[i] =0;
1611 for (Int_t i=0;i<11;i++) fN10[i]=0;
1612 for (Int_t i=0;i<21;i++) fN20[i]=0;
1614 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;}
1615 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;}
1616 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;}
1619 for (Int_t i=0;i<fN;i++)
1620 for (Int_t irot=-1;irot<=1;irot++){
1621 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1623 for (Int_t slice=0; slice<6;slice++){
1624 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1625 fClusters5[slice][fN5[slice]] = fClusters[i];
1626 fY5[slice][fN5[slice]] = curY;
1627 fZ5[slice][fN5[slice]] = fZ[i];
1628 fClusterIndex5[slice][fN5[slice]]=i;
1633 for (Int_t slice=0; slice<11;slice++){
1634 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1635 fClusters10[slice][fN10[slice]] = fClusters[i];
1636 fY10[slice][fN10[slice]] = curY;
1637 fZ10[slice][fN10[slice]] = fZ[i];
1638 fClusterIndex10[slice][fN10[slice]]=i;
1643 for (Int_t slice=0; slice<21;slice++){
1644 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1645 fClusters20[slice][fN20[slice]] = fClusters[i];
1646 fY20[slice][fN20[slice]] = curY;
1647 fZ20[slice][fN20[slice]] = fZ[i];
1648 fClusterIndex20[slice][fN20[slice]]=i;
1655 // consistency check
1657 for (Int_t i=0;i<fN-1;i++){
1663 for (Int_t slice=0;slice<21;slice++)
1664 for (Int_t i=0;i<fN20[slice]-1;i++){
1665 if (fZ20[slice][i]>fZ20[slice][i+1]){
1672 //------------------------------------------------------------------------
1673 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1674 //--------------------------------------------------------------------
1675 // This function returns the index of the nearest cluster
1676 //--------------------------------------------------------------------
1679 if (fCurrentSlice<0) {
1688 if (ncl==0) return 0;
1689 Int_t b=0, e=ncl-1, m=(b+e)/2;
1690 for (; b<e; m=(b+e)/2) {
1691 // if (z > fClusters[m]->GetZ()) b=m+1;
1692 if (z > zcl[m]) b=m+1;
1697 //------------------------------------------------------------------------
1698 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 {
1699 //--------------------------------------------------------------------
1700 // This function computes the rectangular road for this track
1701 //--------------------------------------------------------------------
1704 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1705 // take into account the misalignment: propagate track to misaligned detector plane
1706 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1708 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1709 TMath::Sqrt(track->GetSigmaZ2() +
1710 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1711 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1712 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1713 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1714 TMath::Sqrt(track->GetSigmaY2() +
1715 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1716 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1717 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1719 // track at boundary between detectors, enlarge road
1720 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1721 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1722 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1723 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1724 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1725 Float_t tgl = TMath::Abs(track->GetTgl());
1726 if (tgl > 1.) tgl=1.;
1727 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1728 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1729 Float_t snp = TMath::Abs(track->GetSnp());
1730 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1731 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1734 // add to the road a term (up to 2-3 mm) to deal with misalignments
1735 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1736 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1738 Double_t r = fgLayers[ilayer].GetR();
1739 zmin = track->GetZ() - dz;
1740 zmax = track->GetZ() + dz;
1741 ymin = track->GetY() + r*det.GetPhi() - dy;
1742 ymax = track->GetY() + r*det.GetPhi() + dy;
1744 // bring track back to idead detector plane
1745 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1749 //------------------------------------------------------------------------
1750 void AliITStrackerMI::AliITSlayer::
1751 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1752 //--------------------------------------------------------------------
1753 // This function sets the "window"
1754 //--------------------------------------------------------------------
1756 Double_t circle=2*TMath::Pi()*fR;
1757 fYmin = ymin; fYmax =ymax;
1758 Float_t ymiddle = (fYmin+fYmax)*0.5;
1759 if (ymiddle<fYB[0]) {
1760 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1761 } else if (ymiddle>fYB[1]) {
1762 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1768 fClustersCs = fClusters;
1769 fClusterIndexCs = fClusterIndex;
1775 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1776 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1777 if (slice<0) slice=0;
1778 if (slice>20) slice=20;
1779 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1781 fCurrentSlice=slice;
1782 fClustersCs = fClusters20[fCurrentSlice];
1783 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1784 fYcs = fY20[fCurrentSlice];
1785 fZcs = fZ20[fCurrentSlice];
1786 fNcs = fN20[fCurrentSlice];
1791 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1792 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1793 if (slice<0) slice=0;
1794 if (slice>10) slice=10;
1795 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1797 fCurrentSlice=slice;
1798 fClustersCs = fClusters10[fCurrentSlice];
1799 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1800 fYcs = fY10[fCurrentSlice];
1801 fZcs = fZ10[fCurrentSlice];
1802 fNcs = fN10[fCurrentSlice];
1807 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1808 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1809 if (slice<0) slice=0;
1810 if (slice>5) slice=5;
1811 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1813 fCurrentSlice=slice;
1814 fClustersCs = fClusters5[fCurrentSlice];
1815 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1816 fYcs = fY5[fCurrentSlice];
1817 fZcs = fZ5[fCurrentSlice];
1818 fNcs = fN5[fCurrentSlice];
1822 fI=FindClusterIndex(zmin); fZmax=zmax;
1823 fImax = TMath::Min(FindClusterIndex(zmax)+1,fNcs);
1829 //------------------------------------------------------------------------
1830 Int_t AliITStrackerMI::AliITSlayer::
1831 FindDetectorIndex(Double_t phi, Double_t z) const {
1832 //--------------------------------------------------------------------
1833 //This function finds the detector crossed by the track
1834 //--------------------------------------------------------------------
1836 if (fZOffset<0) // old geometry
1837 dphi = -(phi-fPhiOffset);
1838 else // new geometry
1839 dphi = phi-fPhiOffset;
1842 if (dphi < 0) dphi += 2*TMath::Pi();
1843 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1844 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1845 if (np>=fNladders) np-=fNladders;
1846 if (np<0) np+=fNladders;
1849 Double_t dz=fZOffset-z;
1850 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1851 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1852 if (nz>=fNdetectors) return -1;
1853 if (nz<0) return -1;
1855 // ad hoc correction for 3rd ladder of SDD inner layer,
1856 // which is reversed (rotated by pi around local y)
1857 // this correction is OK only from AliITSv11Hybrid onwards
1858 if (GetR()>12. && GetR()<20.) { // SDD inner
1859 if(np==2) { // 3rd ladder
1860 nz = (fNdetectors-1) - nz;
1863 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1866 return np*fNdetectors + nz;
1868 //------------------------------------------------------------------------
1869 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1871 //--------------------------------------------------------------------
1872 // This function returns clusters within the "window"
1873 //--------------------------------------------------------------------
1875 if (fCurrentSlice<0) {
1876 Double_t rpi2 = 2.*fR*TMath::Pi();
1877 for (Int_t i=fI; i<fImax; i++) {
1879 if (fYmax<y) y -= rpi2;
1880 if (fYmin>y) y += rpi2;
1881 if (y<fYmin) continue;
1882 if (y>fYmax) continue;
1883 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1886 return fClusters[i];
1889 for (Int_t i=fI; i<fImax; i++) {
1890 if (fYcs[i]<fYmin) continue;
1891 if (fYcs[i]>fYmax) continue;
1892 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1893 ci=fClusterIndexCs[i];
1895 return fClustersCs[i];
1900 //------------------------------------------------------------------------
1901 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1903 //--------------------------------------------------------------------
1904 // This function returns the layer thickness at this point (units X0)
1905 //--------------------------------------------------------------------
1907 x0=AliITSRecoParam::GetX0Air();
1908 if (43<fR&&fR<45) { //SSD2
1911 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1912 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1913 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1914 for (Int_t i=0; i<12; i++) {
1915 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1916 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1920 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1921 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1925 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1926 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1929 if (37<fR&&fR<41) { //SSD1
1932 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1933 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1934 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1935 for (Int_t i=0; i<11; i++) {
1936 if (TMath::Abs(z-3.9*i)<0.15) {
1937 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1941 if (TMath::Abs(z+3.9*i)<0.15) {
1942 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1946 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1947 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1950 if (13<fR&&fR<26) { //SDD
1953 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1955 if (TMath::Abs(y-1.80)<0.55) {
1957 for (Int_t j=0; j<20; j++) {
1958 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1959 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1962 if (TMath::Abs(y+1.80)<0.55) {
1964 for (Int_t j=0; j<20; j++) {
1965 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1966 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1970 for (Int_t i=0; i<4; i++) {
1971 if (TMath::Abs(z-7.3*i)<0.60) {
1973 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1976 if (TMath::Abs(z+7.3*i)<0.60) {
1978 if (TMath::Abs(y-0.00)>3.30) d+=dd;
1983 if (6<fR&&fR<8) { //SPD2
1984 Double_t dd=0.0063; x0=21.5;
1986 if (TMath::Abs(y-3.08)>0.5) d+=dd;
1987 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
1989 if (3<fR&&fR<5) { //SPD1
1990 Double_t dd=0.0063; x0=21.5;
1992 if (TMath::Abs(y+0.21)>0.6) d+=dd;
1993 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
1998 //------------------------------------------------------------------------
1999 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2001 fRmisal(det.fRmisal),
2003 fSinPhi(det.fSinPhi),
2004 fCosPhi(det.fCosPhi),
2010 fNChips(det.fNChips),
2011 fChipIsBad(det.fChipIsBad)
2015 //------------------------------------------------------------------------
2016 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2017 AliITSDetTypeRec *detTypeRec)
2019 //--------------------------------------------------------------------
2020 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2021 //--------------------------------------------------------------------
2023 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2024 // while in the tracker they start from 0 for each layer
2025 for(Int_t il=0; il<ilayer; il++)
2026 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2029 if (ilayer==0 || ilayer==1) { // ---------- SPD
2031 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2033 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2036 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2040 // Get calibration from AliITSDetTypeRec
2041 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2042 calib->SetModuleIndex(idet);
2043 AliITSCalibration *calibSPDdead = 0;
2044 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2045 if (calib->IsBad() ||
2046 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2049 // printf("lay %d bad %d\n",ilayer,idet);
2052 // Get segmentation from AliITSDetTypeRec
2053 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2055 // Read info about bad chips
2056 fNChips = segm->GetMaximumChipIndex()+1;
2057 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2058 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2059 fChipIsBad = new Bool_t[fNChips];
2060 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2061 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2062 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2063 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2068 //------------------------------------------------------------------------
2069 Double_t AliITStrackerMI::GetEffectiveThickness()
2071 //--------------------------------------------------------------------
2072 // Returns the thickness between the current layer and the vertex (units X0)
2073 //--------------------------------------------------------------------
2076 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2077 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2078 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2082 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2083 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2087 Double_t xn=fgLayers[fI].GetR();
2088 for (Int_t i=0; i<fI; i++) {
2089 Double_t xi=fgLayers[i].GetR();
2090 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2096 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2097 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2100 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2101 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2105 //------------------------------------------------------------------------
2106 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2107 //-------------------------------------------------------------------
2108 // This function returns number of clusters within the "window"
2109 //--------------------------------------------------------------------
2111 for (Int_t i=fI; i<fN; i++) {
2112 const AliITSRecPoint *c=fClusters[i];
2113 if (c->GetZ() > fZmax) break;
2114 if (c->IsUsed()) continue;
2115 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2116 Double_t y=fR*det.GetPhi() + c->GetY();
2118 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2119 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2121 if (y<fYmin) continue;
2122 if (y>fYmax) continue;
2127 //------------------------------------------------------------------------
2128 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2129 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2131 //--------------------------------------------------------------------
2132 // This function refits the track "track" at the position "x" using
2133 // the clusters from "clusters"
2134 // If "extra"==kTRUE,
2135 // the clusters from overlapped modules get attached to "track"
2136 // If "planeff"==kTRUE,
2137 // special approach for plane efficiency evaluation is applyed
2138 //--------------------------------------------------------------------
2140 Int_t index[AliITSgeomTGeo::kNLayers];
2142 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2143 Int_t nc=clusters->GetNumberOfClusters();
2144 for (k=0; k<nc; k++) {
2145 Int_t idx=clusters->GetClusterIndex(k);
2146 Int_t ilayer=(idx&0xf0000000)>>28;
2150 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2152 //------------------------------------------------------------------------
2153 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2154 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2156 //--------------------------------------------------------------------
2157 // This function refits the track "track" at the position "x" using
2158 // the clusters from array
2159 // If "extra"==kTRUE,
2160 // the clusters from overlapped modules get attached to "track"
2161 // If "planeff"==kTRUE,
2162 // special approach for plane efficiency evaluation is applyed
2163 //--------------------------------------------------------------------
2164 Int_t index[AliITSgeomTGeo::kNLayers];
2166 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2168 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2169 index[k]=clusters[k];
2172 // special for cosmics: check which the innermost layer crossed
2174 Int_t innermostlayer=5;
2175 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2176 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2177 if(drphi < fgLayers[innermostlayer].GetR()) break;
2179 //printf(" drphi %f innermost %d\n",drphi,innermostlayer);
2181 Int_t modstatus=1; // found
2183 Int_t from, to, step;
2184 if (xx > track->GetX()) {
2185 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2188 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2191 TString dir = (step>0 ? "outward" : "inward");
2193 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2194 AliITSlayer &layer=fgLayers[ilayer];
2195 Double_t r=layer.GetR();
2196 if (step<0 && xx>r) break;
2198 // material between SSD and SDD, SDD and SPD
2199 Double_t hI=ilayer-0.5*step;
2200 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2201 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2202 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2203 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2205 // remember old position [SR, GSI 18.02.2003]
2206 Double_t oldX=0., oldY=0., oldZ=0.;
2207 if (track->IsStartedTimeIntegral() && step==1) {
2208 if (!track->GetGlobalXYZat(track->GetX(),oldX,oldY,oldZ)) return kFALSE;
2212 Double_t oldGlobXYZ[3];
2213 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2216 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2218 Int_t idet=layer.FindDetectorIndex(phi,z);
2220 // check if we allow a prolongation without point for large-eta tracks
2221 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2223 // propagate to the layer radius
2224 Double_t xToGo; if (!track->GetLocalXat(r,xToGo)) return kFALSE;
2225 if (!track->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return kFALSE;
2226 // apply correction for material of the current layer
2227 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2228 modstatus = 4; // out in z
2229 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2230 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2232 // track time update [SR, GSI 17.02.2003]
2233 if (track->IsStartedTimeIntegral() && step==1) {
2234 Double_t newX, newY, newZ;
2235 if (!track->GetGlobalXYZat(track->GetX(),newX,newY,newZ)) return kFALSE;
2236 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2237 (oldZ-newZ)*(oldZ-newZ);
2238 track->AddTimeStep(TMath::Sqrt(dL2));
2243 if (idet<0) return kFALSE;
2245 const AliITSdetector &det=layer.GetDetector(idet);
2246 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2248 track->SetDetectorIndex(idet);
2249 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2251 Double_t dz,zmin,zmax,dy,ymin,ymax;
2253 const AliITSRecPoint *clAcc=0;
2254 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2256 Int_t idx=index[ilayer];
2257 if (idx>=0) { // cluster in this layer
2258 modstatus = 6; // no refit
2259 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2261 if (idet != cl->GetDetectorIndex()) {
2262 idet=cl->GetDetectorIndex();
2263 const AliITSdetector &detc=layer.GetDetector(idet);
2264 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2265 track->SetDetectorIndex(idet);
2266 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2268 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2269 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2273 modstatus = 1; // found
2278 } else { // no cluster in this layer
2280 modstatus = 3; // skipped
2281 // Plane Eff determination:
2282 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2283 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2284 UseTrackForPlaneEff(track,ilayer);
2287 modstatus = 5; // no cls in road
2289 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2290 dz = 0.5*(zmax-zmin);
2291 dy = 0.5*(ymax-ymin);
2292 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2293 if (dead==1) modstatus = 7; // holes in z in SPD
2294 if (dead==2 || dead==3) modstatus = 2; // dead from OCDB
2299 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2300 track->SetSampledEdx(clAcc->GetQ(),track->GetNumberOfClusters()-1);
2302 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2305 if (extra) { // search for extra clusters in overlapped modules
2306 AliITStrackV2 tmp(*track);
2307 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2308 layer.SelectClusters(zmin,zmax,ymin,ymax);
2310 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2312 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2313 Double_t tolerance=0.1;
2314 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2315 // only clusters in another module! (overlaps)
2316 idetExtra = clExtra->GetDetectorIndex();
2317 if (idet == idetExtra) continue;
2319 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2321 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2322 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2323 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2324 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2326 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2327 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2330 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2331 track->SetExtraModule(ilayer,idetExtra);
2333 } // end search for extra clusters in overlapped modules
2335 // Correct for material of the current layer
2336 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2338 // track time update [SR, GSI 17.02.2003]
2339 if (track->IsStartedTimeIntegral() && step==1) {
2340 Double_t newX, newY, newZ;
2341 if (!track->GetGlobalXYZat(track->GetX(),newX,newY,newZ)) return kFALSE;
2342 Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) +
2343 (oldZ-newZ)*(oldZ-newZ);
2344 track->AddTimeStep(TMath::Sqrt(dL2));
2348 } // end loop on layers
2350 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2354 //------------------------------------------------------------------------
2355 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2358 // calculate normalized chi2
2359 // return NormalizedChi2(track,0);
2362 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2363 // track->fdEdxMismatch=0;
2364 Float_t dedxmismatch =0;
2365 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2367 for (Int_t i = 0;i<6;i++){
2368 if (track->GetClIndex(i)>0){
2369 Float_t cerry, cerrz;
2370 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2372 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2375 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2376 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2377 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2379 cchi2+=(0.5-ratio)*10.;
2380 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2381 dedxmismatch+=(0.5-ratio)*10.;
2385 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2386 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2387 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2388 if (i<2) chi2+=2*cl->GetDeltaProbability();
2394 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2395 track->SetdEdxMismatch(dedxmismatch);
2399 for (Int_t i = 0;i<4;i++){
2400 if (track->GetClIndex(i)>0){
2401 Float_t cerry, cerrz;
2402 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2403 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2406 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2407 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2411 for (Int_t i = 4;i<6;i++){
2412 if (track->GetClIndex(i)>0){
2413 Float_t cerry, cerrz;
2414 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2415 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2418 Float_t cerryb, cerrzb;
2419 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2420 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2423 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2424 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2429 if (track->GetESDtrack()->GetTPCsignal()>85){
2430 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2432 chi2+=(0.5-ratio)*5.;
2435 chi2+=(ratio-2.0)*3;
2439 Double_t match = TMath::Sqrt(track->GetChi22());
2440 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2441 if (!track->GetConstrain()) {
2442 if (track->GetNumberOfClusters()>2) {
2443 match/=track->GetNumberOfClusters()-2.;
2448 if (match<0) match=0;
2449 Float_t deadzonefactor = (track->GetNDeadZone()>0) ? 3*(1.1-track->GetDeadZoneProbability()):0.;
2450 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2451 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2452 1./(1.+track->GetNSkipped()));
2456 //------------------------------------------------------------------------
2457 Double_t AliITStrackerMI::GetMatchingChi2(AliITStrackMI * track1, AliITStrackMI * track2)
2460 // return matching chi2 between two tracks
2461 Double_t largeChi2=1000.;
2463 AliITStrackMI track3(*track2);
2464 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2466 vec(0,0)=track1->GetY() - track3.GetY();
2467 vec(1,0)=track1->GetZ() - track3.GetZ();
2468 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2469 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2470 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2473 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2474 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2475 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2476 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2477 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2479 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2480 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2481 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2482 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2484 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2485 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2486 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2488 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2489 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2491 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2494 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2495 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2498 //------------------------------------------------------------------------
2499 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr)
2502 // return probability that given point (characterized by z position and error)
2503 // is in SPD dead zone
2505 Double_t probability = 0.;
2506 Double_t absz = TMath::Abs(zpos);
2507 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2508 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2509 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2510 Double_t zmin, zmax;
2511 if (zpos<-6.) { // dead zone at z = -7
2512 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2513 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2514 } else if (zpos>6.) { // dead zone at z = +7
2515 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2516 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2517 } else if (absz<2.) { // dead zone at z = 0
2518 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2519 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2524 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2526 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2527 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2530 //------------------------------------------------------------------------
2531 Double_t AliITStrackerMI::GetTruncatedChi2(AliITStrackMI * track, Float_t fac)
2534 // calculate normalized chi2
2536 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2538 for (Int_t i = 0;i<6;i++){
2539 if (TMath::Abs(track->GetDy(i))>0){
2540 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2541 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2544 else{chi2[i]=10000;}
2547 TMath::Sort(6,chi2,index,kFALSE);
2548 Float_t max = float(ncl)*fac-1.;
2549 Float_t sumchi=0, sumweight=0;
2550 for (Int_t i=0;i<max+1;i++){
2551 Float_t weight = (i<max)?1.:(max+1.-i);
2552 sumchi+=weight*chi2[index[i]];
2555 Double_t normchi2 = sumchi/sumweight;
2558 //------------------------------------------------------------------------
2559 Double_t AliITStrackerMI::GetInterpolatedChi2(AliITStrackMI * forwardtrack, AliITStrackMI * backtrack)
2562 // calculate normalized chi2
2563 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2566 for (Int_t i=0;i<6;i++){
2567 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2568 Double_t sy1 = forwardtrack->GetSigmaY(i);
2569 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2570 Double_t sy2 = backtrack->GetSigmaY(i);
2571 Double_t sz2 = backtrack->GetSigmaZ(i);
2572 if (i<2){ sy2=1000.;sz2=1000;}
2574 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2575 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2577 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2578 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2580 res+= nz0*nz0+ny0*ny0;
2583 if (npoints>1) return
2584 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2585 //2*forwardtrack->fNUsed+
2586 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2587 1./(1.+forwardtrack->GetNSkipped()));
2590 //------------------------------------------------------------------------
2591 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2592 //--------------------------------------------------------------------
2593 // Return pointer to a given cluster
2594 //--------------------------------------------------------------------
2595 Int_t l=(index & 0xf0000000) >> 28;
2596 Int_t c=(index & 0x0fffffff) >> 00;
2597 return fgLayers[l].GetWeight(c);
2599 //------------------------------------------------------------------------
2600 void AliITStrackerMI::RegisterClusterTracks(AliITStrackMI* track,Int_t id)
2602 //---------------------------------------------
2603 // register track to the list
2605 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2608 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2609 Int_t index = track->GetClusterIndex(icluster);
2610 Int_t l=(index & 0xf0000000) >> 28;
2611 Int_t c=(index & 0x0fffffff) >> 00;
2612 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2613 for (Int_t itrack=0;itrack<4;itrack++){
2614 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2615 fgLayers[l].SetClusterTracks(itrack,c,id);
2621 //------------------------------------------------------------------------
2622 void AliITStrackerMI::UnRegisterClusterTracks(AliITStrackMI* track, Int_t id)
2624 //---------------------------------------------
2625 // unregister track from the list
2626 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2627 Int_t index = track->GetClusterIndex(icluster);
2628 Int_t l=(index & 0xf0000000) >> 28;
2629 Int_t c=(index & 0x0fffffff) >> 00;
2630 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2631 for (Int_t itrack=0;itrack<4;itrack++){
2632 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2633 fgLayers[l].SetClusterTracks(itrack,c,-1);
2638 //------------------------------------------------------------------------
2639 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2641 //-------------------------------------------------------------
2642 //get number of shared clusters
2643 //-------------------------------------------------------------
2645 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2646 // mean number of clusters
2647 Float_t *ny = GetNy(id), *nz = GetNz(id);
2650 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2651 Int_t index = track->GetClusterIndex(icluster);
2652 Int_t l=(index & 0xf0000000) >> 28;
2653 Int_t c=(index & 0x0fffffff) >> 00;
2654 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2656 printf("problem\n");
2658 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2662 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2663 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2664 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2666 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2669 deltan = (cl->GetNz()-nz[l]);
2671 if (deltan>2.0) continue; // extended - highly probable shared cluster
2672 weight = 2./TMath::Max(3.+deltan,2.);
2674 for (Int_t itrack=0;itrack<4;itrack++){
2675 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2677 clist[l] = (AliITSRecPoint*)GetCluster(index);
2683 track->SetNUsed(shared);
2686 //------------------------------------------------------------------------
2687 Int_t AliITStrackerMI::GetOverlapTrack(AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2690 // find first shared track
2692 // mean number of clusters
2693 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2695 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2696 Int_t sharedtrack=100000;
2697 Int_t tracks[24],trackindex=0;
2698 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2700 for (Int_t icluster=0;icluster<6;icluster++){
2701 if (clusterlist[icluster]<0) continue;
2702 Int_t index = clusterlist[icluster];
2703 Int_t l=(index & 0xf0000000) >> 28;
2704 Int_t c=(index & 0x0fffffff) >> 00;
2706 printf("problem\n");
2708 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2709 //if (l>3) continue;
2710 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2713 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2714 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2715 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2717 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2720 deltan = (cl->GetNz()-nz[l]);
2722 if (deltan>2.0) continue; // extended - highly probable shared cluster
2724 for (Int_t itrack=3;itrack>=0;itrack--){
2725 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2726 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2727 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2732 if (trackindex==0) return -1;
2734 sharedtrack = tracks[0];
2736 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2739 Int_t tracks2[24], cluster[24];
2740 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2743 for (Int_t i=0;i<trackindex;i++){
2744 if (tracks[i]<0) continue;
2745 tracks2[index] = tracks[i];
2747 for (Int_t j=i+1;j<trackindex;j++){
2748 if (tracks[j]<0) continue;
2749 if (tracks[j]==tracks[i]){
2757 for (Int_t i=0;i<index;i++){
2758 if (cluster[index]>max) {
2759 sharedtrack=tracks2[index];
2766 if (sharedtrack>=100000) return -1;
2768 // make list of overlaps
2770 for (Int_t icluster=0;icluster<6;icluster++){
2771 if (clusterlist[icluster]<0) continue;
2772 Int_t index = clusterlist[icluster];
2773 Int_t l=(index & 0xf0000000) >> 28;
2774 Int_t c=(index & 0x0fffffff) >> 00;
2775 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2776 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2778 if (cl->GetNy()>2) continue;
2779 if (cl->GetNz()>2) continue;
2782 if (cl->GetNy()>3) continue;
2783 if (cl->GetNz()>3) continue;
2786 for (Int_t itrack=3;itrack>=0;itrack--){
2787 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2788 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2796 //------------------------------------------------------------------------
2797 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2799 // try to find track hypothesys without conflicts
2800 // with minimal chi2;
2801 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2802 Int_t entries1 = arr1->GetEntriesFast();
2803 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2804 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2805 Int_t entries2 = arr2->GetEntriesFast();
2806 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2808 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2809 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2810 if (track10->Pt()>0.5+track20->Pt()) return track10;
2812 for (Int_t itrack=0;itrack<entries1;itrack++){
2813 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2814 UnRegisterClusterTracks(track,trackID1);
2817 for (Int_t itrack=0;itrack<entries2;itrack++){
2818 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2819 UnRegisterClusterTracks(track,trackID2);
2823 Float_t maxconflicts=6;
2824 Double_t maxchi2 =1000.;
2826 // get weight of hypothesys - using best hypothesy
2829 Int_t list1[6],list2[6];
2830 AliITSRecPoint *clist1[6], *clist2[6] ;
2831 RegisterClusterTracks(track10,trackID1);
2832 RegisterClusterTracks(track20,trackID2);
2833 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2834 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2835 UnRegisterClusterTracks(track10,trackID1);
2836 UnRegisterClusterTracks(track20,trackID2);
2839 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2840 Float_t nerry[6],nerrz[6];
2841 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2842 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2843 for (Int_t i=0;i<6;i++){
2844 if ( (erry1[i]>0) && (erry2[i]>0)) {
2845 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2846 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2848 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2849 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2851 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2852 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2853 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2856 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2857 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2858 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2866 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2867 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2868 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2869 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2871 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2872 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2873 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2875 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2876 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2877 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2880 Double_t sumw = w1+w2;
2884 w1 = (d2+0.5)/(d1+d2+1.);
2885 w2 = (d1+0.5)/(d1+d2+1.);
2887 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2888 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2890 // get pair of "best" hypothesys
2892 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2893 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2895 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2896 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2897 //if (track1->fFakeRatio>0) continue;
2898 RegisterClusterTracks(track1,trackID1);
2899 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2900 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2902 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2903 //if (track2->fFakeRatio>0) continue;
2905 RegisterClusterTracks(track2,trackID2);
2906 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2907 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2908 UnRegisterClusterTracks(track2,trackID2);
2910 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2911 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2912 if (nskipped>0.5) continue;
2914 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2915 if (conflict1+1<cconflict1) continue;
2916 if (conflict2+1<cconflict2) continue;
2920 for (Int_t i=0;i<6;i++){
2922 Float_t c1 =0.; // conflict coeficients
2924 if (clist1[i]&&clist2[i]){
2927 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2930 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
2932 c1 = 2./TMath::Max(3.+deltan,2.);
2933 c2 = 2./TMath::Max(3.+deltan,2.);
2939 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
2942 deltan = (clist1[i]->GetNz()-nz1[i]);
2944 c1 = 2./TMath::Max(3.+deltan,2.);
2951 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
2954 deltan = (clist2[i]->GetNz()-nz2[i]);
2956 c2 = 2./TMath::Max(3.+deltan,2.);
2962 if (TMath::Abs(track1->GetDy(i))>0.) {
2963 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
2964 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
2965 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
2966 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
2968 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
2971 if (TMath::Abs(track2->GetDy(i))>0.) {
2972 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
2973 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
2974 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
2975 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
2978 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
2980 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
2981 if (chi21>0) sum+=w1;
2982 if (chi22>0) sum+=w2;
2985 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
2986 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
2987 Double_t normchi2 = 2*conflict+sumchi2/sum;
2988 if ( normchi2 <maxchi2 ){
2991 maxconflicts = conflict;
2995 UnRegisterClusterTracks(track1,trackID1);
2998 // if (maxconflicts<4 && maxchi2<th0){
2999 if (maxchi2<th0*2.){
3000 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3001 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3002 track1->SetChi2MIP(5,maxconflicts);
3003 track1->SetChi2MIP(6,maxchi2);
3004 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3005 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3006 track1->SetChi2MIP(8,index1);
3007 fBestTrackIndex[trackID1] =index1;
3008 UpdateESDtrack(track1, AliESDtrack::kITSin);
3010 else if (track10->GetChi2MIP(0)<th1){
3011 track10->SetChi2MIP(5,maxconflicts);
3012 track10->SetChi2MIP(6,maxchi2);
3013 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3014 UpdateESDtrack(track10,AliESDtrack::kITSin);
3017 for (Int_t itrack=0;itrack<entries1;itrack++){
3018 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3019 UnRegisterClusterTracks(track,trackID1);
3022 for (Int_t itrack=0;itrack<entries2;itrack++){
3023 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3024 UnRegisterClusterTracks(track,trackID2);
3027 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3028 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3029 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3030 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3031 RegisterClusterTracks(track10,trackID1);
3033 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3034 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3035 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3036 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3037 RegisterClusterTracks(track20,trackID2);
3042 //------------------------------------------------------------------------
3043 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3044 //--------------------------------------------------------------------
3045 // This function marks clusters assigned to the track
3046 //--------------------------------------------------------------------
3047 AliTracker::UseClusters(t,from);
3049 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3050 //if (c->GetQ()>2) c->Use();
3051 if (c->GetSigmaZ2()>0.1) c->Use();
3052 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3053 //if (c->GetQ()>2) c->Use();
3054 if (c->GetSigmaZ2()>0.1) c->Use();
3057 //------------------------------------------------------------------------
3058 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3060 //------------------------------------------------------------------
3061 // add track to the list of hypothesys
3062 //------------------------------------------------------------------
3064 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3065 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3067 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3069 array = new TObjArray(10);
3070 fTrackHypothesys.AddAt(array,esdindex);
3072 array->AddLast(track);
3074 //------------------------------------------------------------------------
3075 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3077 //-------------------------------------------------------------------
3078 // compress array of track hypothesys
3079 // keep only maxsize best hypothesys
3080 //-------------------------------------------------------------------
3081 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3082 if (! (fTrackHypothesys.At(esdindex)) ) return;
3083 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3084 Int_t entries = array->GetEntriesFast();
3086 //- find preliminary besttrack as a reference
3087 Float_t minchi2=10000;
3089 AliITStrackMI * besttrack=0;
3090 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3091 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3092 if (!track) continue;
3093 Float_t chi2 = NormalizedChi2(track,0);
3095 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3096 track->SetLabel(tpcLabel);
3098 track->SetFakeRatio(1.);
3099 CookLabel(track,0.); //For comparison only
3101 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3102 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3103 if (track->GetNumberOfClusters()<maxn) continue;
3104 maxn = track->GetNumberOfClusters();
3111 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3112 delete array->RemoveAt(itrack);
3116 if (!besttrack) return;
3119 //take errors of best track as a reference
3120 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3121 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3122 for (Int_t j=0;j<6;j++) {
3123 if (besttrack->GetClIndex(j)>0){
3124 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3125 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3126 ny[j] = besttrack->GetNy(j);
3127 nz[j] = besttrack->GetNz(j);
3131 // calculate normalized chi2
3133 Float_t * chi2 = new Float_t[entries];
3134 Int_t * index = new Int_t[entries];
3135 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3136 for (Int_t itrack=0;itrack<entries;itrack++){
3137 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3139 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3140 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3141 chi2[itrack] = track->GetChi2MIP(0);
3143 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3144 delete array->RemoveAt(itrack);
3150 TMath::Sort(entries,chi2,index,kFALSE);
3151 besttrack = (AliITStrackMI*)array->At(index[0]);
3152 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3153 for (Int_t j=0;j<6;j++){
3154 if (besttrack->GetClIndex(j)>0){
3155 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3156 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3157 ny[j] = besttrack->GetNy(j);
3158 nz[j] = besttrack->GetNz(j);
3163 // calculate one more time with updated normalized errors
3164 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3165 for (Int_t itrack=0;itrack<entries;itrack++){
3166 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3168 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3169 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3170 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3173 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3174 delete array->RemoveAt(itrack);
3179 entries = array->GetEntriesFast();
3183 TObjArray * newarray = new TObjArray();
3184 TMath::Sort(entries,chi2,index,kFALSE);
3185 besttrack = (AliITStrackMI*)array->At(index[0]);
3188 for (Int_t j=0;j<6;j++){
3189 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3190 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3191 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3192 ny[j] = besttrack->GetNy(j);
3193 nz[j] = besttrack->GetNz(j);
3196 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3197 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3198 Float_t minn = besttrack->GetNumberOfClusters()-3;
3200 for (Int_t i=0;i<entries;i++){
3201 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3202 if (!track) continue;
3203 if (accepted>maxcut) break;
3204 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3205 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3206 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3207 delete array->RemoveAt(index[i]);
3211 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3212 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3213 if (!shortbest) accepted++;
3215 newarray->AddLast(array->RemoveAt(index[i]));
3216 for (Int_t j=0;j<6;j++){
3218 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3219 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3220 ny[j] = track->GetNy(j);
3221 nz[j] = track->GetNz(j);
3226 delete array->RemoveAt(index[i]);
3230 delete fTrackHypothesys.RemoveAt(esdindex);
3231 fTrackHypothesys.AddAt(newarray,esdindex);
3235 delete fTrackHypothesys.RemoveAt(esdindex);
3241 //------------------------------------------------------------------------
3242 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3244 //-------------------------------------------------------------
3245 // try to find best hypothesy
3246 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3247 //-------------------------------------------------------------
3248 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3249 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3250 if (!array) return 0;
3251 Int_t entries = array->GetEntriesFast();
3252 if (!entries) return 0;
3253 Float_t minchi2 = 100000;
3254 AliITStrackMI * besttrack=0;
3256 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3257 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3258 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3259 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3261 for (Int_t i=0;i<entries;i++){
3262 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3263 if (!track) continue;
3264 Float_t sigmarfi,sigmaz;
3265 GetDCASigma(track,sigmarfi,sigmaz);
3266 track->SetDnorm(0,sigmarfi);
3267 track->SetDnorm(1,sigmaz);
3269 track->SetChi2MIP(1,1000000);
3270 track->SetChi2MIP(2,1000000);
3271 track->SetChi2MIP(3,1000000);
3274 backtrack = new(backtrack) AliITStrackMI(*track);
3275 if (track->GetConstrain()) {
3276 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3277 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3278 backtrack->ResetCovariance(10.);
3280 backtrack->ResetCovariance(10.);
3282 backtrack->ResetClusters();
3284 Double_t x = original->GetX();
3285 if (!RefitAt(x,backtrack,track)) continue;
3287 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3288 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3289 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3290 track->SetChi22(GetMatchingChi2(backtrack,original));
3292 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3293 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3294 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3297 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3299 //forward track - without constraint
3300 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3301 forwardtrack->ResetClusters();
3303 RefitAt(x,forwardtrack,track);
3304 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3305 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3306 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3308 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3309 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3310 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3311 forwardtrack->SetD(0,track->GetD(0));
3312 forwardtrack->SetD(1,track->GetD(1));
3315 AliITSRecPoint* clist[6];
3316 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3317 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3320 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3321 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3322 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3323 track->SetChi2MIP(3,1000);
3326 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3328 for (Int_t ichi=0;ichi<5;ichi++){
3329 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3331 if (chi2 < minchi2){
3332 //besttrack = new AliITStrackMI(*forwardtrack);
3334 besttrack->SetLabel(track->GetLabel());
3335 besttrack->SetFakeRatio(track->GetFakeRatio());
3337 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3338 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3339 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3343 delete forwardtrack;
3345 for (Int_t i=0;i<entries;i++){
3346 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3348 if (!track) continue;
3350 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3351 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3352 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3353 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3354 delete array->RemoveAt(i);
3364 SortTrackHypothesys(esdindex,checkmax,1);
3366 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3367 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3368 besttrack = (AliITStrackMI*)array->At(0);
3369 if (!besttrack) return 0;
3370 besttrack->SetChi2MIP(8,0);
3371 fBestTrackIndex[esdindex]=0;
3372 entries = array->GetEntriesFast();
3373 AliITStrackMI *longtrack =0;
3375 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3376 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3377 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3378 if (!track->GetConstrain()) continue;
3379 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3380 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3381 if (track->GetChi2MIP(0)>4.) continue;
3382 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3385 //if (longtrack) besttrack=longtrack;
3388 AliITSRecPoint * clist[6];
3389 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3390 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3391 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3392 RegisterClusterTracks(besttrack,esdindex);
3399 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3400 if (sharedtrack>=0){
3402 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3404 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3410 if (shared>2.5) return 0;
3411 if (shared>1.0) return besttrack;
3413 // Don't sign clusters if not gold track
3415 if (!besttrack->IsGoldPrimary()) return besttrack;
3416 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3418 if (fConstraint[fPass]){
3422 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3423 for (Int_t i=0;i<6;i++){
3424 Int_t index = besttrack->GetClIndex(i);
3425 if (index<=0) continue;
3426 Int_t ilayer = (index & 0xf0000000) >> 28;
3427 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3428 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3430 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3431 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3432 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3433 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3434 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3435 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3437 Bool_t cansign = kTRUE;
3438 for (Int_t itrack=0;itrack<entries; itrack++){
3439 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3440 if (!track) continue;
3441 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3442 if ( (track->GetClIndex(ilayer)>0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3448 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3449 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3450 if (!c->IsUsed()) c->Use();
3456 //------------------------------------------------------------------------
3457 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3460 // get "best" hypothesys
3463 Int_t nentries = itsTracks.GetEntriesFast();
3464 for (Int_t i=0;i<nentries;i++){
3465 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3466 if (!track) continue;
3467 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3468 if (!array) continue;
3469 if (array->GetEntriesFast()<=0) continue;
3471 AliITStrackMI* longtrack=0;
3473 Float_t maxchi2=1000;
3474 for (Int_t j=0;j<array->GetEntriesFast();j++){
3475 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3476 if (!trackHyp) continue;
3477 if (trackHyp->GetGoldV0()) {
3478 longtrack = trackHyp; //gold V0 track taken
3481 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3482 Float_t chi2 = trackHyp->GetChi2MIP(0);
3484 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3486 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3488 if (chi2 > maxchi2) continue;
3489 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3496 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3497 if (!longtrack) {longtrack = besttrack;}
3498 else besttrack= longtrack;
3502 AliITSRecPoint * clist[6];
3503 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3505 track->SetNUsed(shared);
3506 track->SetNSkipped(besttrack->GetNSkipped());
3507 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3509 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3513 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3514 //if (sharedtrack==-1) sharedtrack=0;
3515 if (sharedtrack>=0) {
3516 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3519 if (besttrack&&fAfterV0) {
3520 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3522 if (besttrack&&fConstraint[fPass])
3523 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3524 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3525 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3526 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3532 //------------------------------------------------------------------------
3533 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3534 //--------------------------------------------------------------------
3535 //This function "cooks" a track label. If label<0, this track is fake.
3536 //--------------------------------------------------------------------
3539 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3541 track->SetChi2MIP(9,0);
3543 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3544 Int_t cindex = track->GetClusterIndex(i);
3545 Int_t l=(cindex & 0xf0000000) >> 28;
3546 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3548 for (Int_t ind=0;ind<3;ind++){
3550 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3552 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3555 Int_t nclusters = track->GetNumberOfClusters();
3556 if (nclusters > 0) //PH Some tracks don't have any cluster
3557 track->SetFakeRatio(double(nwrong)/double(nclusters));
3559 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3561 track->SetLabel(tpcLabel);
3565 //------------------------------------------------------------------------
3566 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3571 //AliITSRecPoint * clist[6];
3572 // Int_t shared = GetNumberOfSharedClusters(track,index,list,clist);
3575 track->SetChi2MIP(9,0);
3576 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3577 Int_t cindex = track->GetClusterIndex(i);
3578 Int_t l=(cindex & 0xf0000000) >> 28;
3579 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3580 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3582 for (Int_t ind=0;ind<3;ind++){
3583 if (cl->GetLabel(ind)==lab) isWrong=0;
3585 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3587 //if (l>3 && (cl->GetNy()>4) || (cl->GetNz()>4)) continue; //shared track
3588 //if (l>3&& !(cl->GetType()==1||cl->GetType()==10)) continue;
3589 //if (l<4&& !(cl->GetType()==1)) continue;
3590 dedx[accepted]= track->GetSampledEdx(i);
3591 //dedx[accepted]= track->fNormQ[l];
3599 TMath::Sort(accepted,dedx,indexes,kFALSE);
3602 Double_t nl=low*accepted, nu =up*accepted;
3604 Float_t sumweight =0;
3605 for (Int_t i=0; i<accepted; i++) {
3607 if (i<nl+0.1) weight = TMath::Max(1.-(nl-i),0.);
3608 if (i>nu-1) weight = TMath::Max(nu-i,0.);
3609 sumamp+= dedx[indexes[i]]*weight;
3612 track->SetdEdx(sumamp/sumweight);
3614 //------------------------------------------------------------------------
3615 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3618 if (fCoefficients) delete []fCoefficients;
3619 fCoefficients = new Float_t[ntracks*48];
3620 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3622 //------------------------------------------------------------------------
3623 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3629 Float_t theta = track->GetTgl();
3630 Float_t phi = track->GetSnp();
3631 phi = TMath::Sqrt(phi*phi/(1.-phi*phi));
3632 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz);
3633 AliDebug(2,Form(" chi2: tr-cl %f %f tr X %f cl X %f",track->GetY()-cluster->GetY(),track->GetZ()-cluster->GetZ(),track->GetX(),cluster->GetX()));
3634 // Take into account the mis-alignment (bring track to cluster plane)
3635 Double_t xTrOrig=track->GetX();
3636 if (!track->PropagateTo(xTrOrig+cluster->GetX(),0.,0.)) return 1000.;
3637 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()));
3638 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz);
3639 // Bring the track back to detector plane in ideal geometry
3640 // [mis-alignment will be accounted for in UpdateMI()]
3641 if (!track->PropagateTo(xTrOrig,0.,0.)) return 1000.;
3643 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3644 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3646 chi2+=0.5*TMath::Min(delta/2,2.);
3647 chi2+=2.*cluster->GetDeltaProbability();
3650 track->SetNy(layer,ny);
3651 track->SetNz(layer,nz);
3652 track->SetSigmaY(layer,erry);
3653 track->SetSigmaZ(layer, errz);
3654 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3655 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/(1.- track->GetSnp()*track->GetSnp())));
3659 //------------------------------------------------------------------------
3660 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3665 Int_t layer = (index & 0xf0000000) >> 28;
3666 track->SetClIndex(layer, index);
3667 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3668 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3669 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3670 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3674 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3677 // Take into account the mis-alignment (bring track to cluster plane)
3678 Double_t xTrOrig=track->GetX();
3679 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3680 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3681 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3682 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3684 if (!track->PropagateTo(xTrOrig+cl->GetX(),0.,0.)) return 0;
3688 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3689 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3692 Int_t updated = track->UpdateMI(&c,chi2,index);
3694 // Bring the track back to detector plane in ideal geometry
3695 if (!track->PropagateTo(xTrOrig,0.,0.)) return 0;
3697 if(!updated) AliDebug(2,"update failed");
3701 //------------------------------------------------------------------------
3702 void AliITStrackerMI::GetDCASigma(AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3705 //DCA sigmas parameterization
3706 //to be paramterized using external parameters in future
3709 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3710 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3712 //------------------------------------------------------------------------
3713 void AliITStrackerMI::SignDeltas( TObjArray *ClusterArray, Float_t vz)
3717 Int_t entries = ClusterArray->GetEntriesFast();
3718 if (entries<4) return;
3719 AliITSRecPoint* cluster = (AliITSRecPoint*)ClusterArray->At(0);
3720 Int_t layer = cluster->GetLayer();
3721 if (layer>1) return;
3723 Int_t ncandidates=0;
3724 Float_t r = (layer>0)? 7:4;
3726 for (Int_t i=0;i<entries;i++){
3727 AliITSRecPoint* cl0 = (AliITSRecPoint*)ClusterArray->At(i);
3728 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3729 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3730 index[ncandidates] = i; //candidate to belong to delta electron track
3732 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3733 cl0->SetDeltaProbability(1);
3739 for (Int_t i=0;i<ncandidates;i++){
3740 AliITSRecPoint* cl0 = (AliITSRecPoint*)ClusterArray->At(index[i]);
3741 if (cl0->GetDeltaProbability()>0.8) continue;
3744 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3745 sumy=sumz=sumy2=sumyz=sumw=0.0;
3746 for (Int_t j=0;j<ncandidates;j++){
3748 AliITSRecPoint* cl1 = (AliITSRecPoint*)ClusterArray->At(index[j]);
3750 Float_t dz = cl0->GetZ()-cl1->GetZ();
3751 Float_t dy = cl0->GetY()-cl1->GetY();
3752 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3753 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3754 y[ncl] = cl1->GetY();
3755 z[ncl] = cl1->GetZ();
3756 sumy+= y[ncl]*weight;
3757 sumz+= z[ncl]*weight;
3758 sumy2+=y[ncl]*y[ncl]*weight;
3759 sumyz+=y[ncl]*z[ncl]*weight;
3764 if (ncl<4) continue;
3765 Float_t det = sumw*sumy2 - sumy*sumy;
3767 if (TMath::Abs(det)>0.01){
3768 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3769 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3770 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3773 Float_t z0 = sumyz/sumy;
3774 delta = TMath::Abs(cl0->GetZ()-z0);
3777 cl0->SetDeltaProbability(1-20.*delta);
3781 //------------------------------------------------------------------------
3782 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3786 track->UpdateESDtrack(flags);
3787 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3788 if (oldtrack) delete oldtrack;
3789 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3790 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3791 printf("Problem\n");
3794 //------------------------------------------------------------------------
3795 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3797 // Get nearest upper layer close to the point xr.
3798 // rough approximation
3800 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3801 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3803 for (Int_t i=0;i<6;i++){
3804 if (radius<kRadiuses[i]){
3811 //------------------------------------------------------------------------
3812 void AliITStrackerMI::UpdateTPCV0(AliESDEvent *event){
3814 //try to update, or reject TPC V0s
3816 Int_t nv0s = event->GetNumberOfV0s();
3817 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3819 for (Int_t i=0;i<nv0s;i++){
3820 AliESDv0 * vertex = event->GetV0(i);
3821 Int_t ip = vertex->GetIndex(0);
3822 Int_t im = vertex->GetIndex(1);
3824 TObjArray * arrayp = (ip<nitstracks) ? (TObjArray*)fTrackHypothesys.At(ip):0;
3825 TObjArray * arraym = (im<nitstracks) ? (TObjArray*)fTrackHypothesys.At(im):0;
3826 AliITStrackMI * trackp = (arrayp!=0) ? (AliITStrackMI*)arrayp->At(0):0;
3827 AliITStrackMI * trackm = (arraym!=0) ? (AliITStrackMI*)arraym->At(0):0;
3831 if (trackp->GetNumberOfClusters()+trackp->GetNDeadZone()>5.5){
3832 if (trackp->GetConstrain()&&trackp->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3833 if (!trackp->GetConstrain()&&trackp->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3838 if (trackm->GetNumberOfClusters()+trackm->GetNDeadZone()>5.5){
3839 if (trackm->GetConstrain()&&trackm->GetChi2MIP(0)<3) vertex->SetStatus(-100);
3840 if (!trackm->GetConstrain()&&trackm->GetChi2MIP(0)<2) vertex->SetStatus(-100);
3843 if (vertex->GetStatus()==-100) continue;
3845 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
3846 Int_t clayer = GetNearestLayer(xrp); //I.B.
3847 vertex->SetNBefore(clayer); //
3848 vertex->SetChi2Before(9*clayer); //
3849 vertex->SetNAfter(6-clayer); //
3850 vertex->SetChi2After(0); //
3852 if (clayer >1 ){ // calculate chi2 before vertex
3853 Float_t chi2p = 0, chi2m=0;
3856 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3857 if (trackp->GetClIndex(ilayer)>0){
3858 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3859 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3870 for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3871 if (trackm->GetClIndex(ilayer)>0){
3872 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3873 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3882 vertex->SetChi2Before(TMath::Min(chi2p,chi2m));
3883 if (TMath::Min(chi2p,chi2m)/Float_t(clayer)<4) vertex->SetStatus(-10); // track exist before vertex
3886 if (clayer < 5 ){ // calculate chi2 after vertex
3887 Float_t chi2p = 0, chi2m=0;
3889 if (trackp&&TMath::Abs(trackp->GetTgl())<1.){
3890 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3891 if (trackp->GetClIndex(ilayer)>0){
3892 chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
3893 trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
3903 if (trackm&&TMath::Abs(trackm->GetTgl())<1.){
3904 for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3905 if (trackm->GetClIndex(ilayer)>0){
3906 chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
3907 trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
3916 vertex->SetChi2After(TMath::Max(chi2p,chi2m));
3917 if (TMath::Max(chi2m,chi2p)/Float_t(6-clayer)>9) vertex->SetStatus(-20); // track not found in ITS
3922 //------------------------------------------------------------------------
3923 void AliITStrackerMI::FindV02(AliESDEvent *event)
3928 // Cuts on DCA - R dependent
3929 // max distance DCA between 2 tracks cut
3930 // maxDist = TMath::Min(kMaxDist,kMaxDist0+pvertex->GetRr()*kMaxDist);
3932 const Float_t kMaxDist0 = 0.1;
3933 const Float_t kMaxDist1 = 0.1;
3934 const Float_t kMaxDist = 1;
3935 const Float_t kMinPointAngle = 0.85;
3936 const Float_t kMinPointAngle2 = 0.99;
3937 const Float_t kMinR = 0.5;
3938 const Float_t kMaxR = 220;
3939 //const Float_t kCausality0Cut = 0.19;
3940 //const Float_t kLikelihood01Cut = 0.25;
3941 //const Float_t kPointAngleCut = 0.9996;
3942 const Float_t kCausality0Cut = 0.19;
3943 const Float_t kLikelihood01Cut = 0.45;
3944 const Float_t kLikelihood1Cut = 0.5;
3945 const Float_t kCombinedCut = 0.55;
3949 TTreeSRedirector &cstream = *fDebugStreamer;
3950 Int_t ntracks = event->GetNumberOfTracks();
3951 Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3952 fOriginal.Expand(ntracks);
3953 fTrackHypothesys.Expand(ntracks);
3954 fBestHypothesys.Expand(ntracks);
3956 AliHelix * helixes = new AliHelix[ntracks+2];
3957 TObjArray trackarray(ntracks+2); //array with tracks - with vertex constrain
3958 TObjArray trackarrayc(ntracks+2); //array of "best tracks" - without vertex constrain
3959 TObjArray trackarrayl(ntracks+2); //array of "longest tracks" - without vertex constrain
3960 Bool_t * forbidden = new Bool_t [ntracks+2];
3961 Int_t *itsmap = new Int_t [ntracks+2];
3962 Float_t *dist = new Float_t[ntracks+2];
3963 Float_t *normdist0 = new Float_t[ntracks+2];
3964 Float_t *normdist1 = new Float_t[ntracks+2];
3965 Float_t *normdist = new Float_t[ntracks+2];
3966 Float_t *norm = new Float_t[ntracks+2];
3967 Float_t *maxr = new Float_t[ntracks+2];
3968 Float_t *minr = new Float_t[ntracks+2];
3969 Float_t *minPointAngle= new Float_t[ntracks+2];
3971 AliV0 *pvertex = new AliV0;
3972 AliITStrackMI * dummy= new AliITStrackMI;
3974 AliITStrackMI trackat0; //temporary track for DCA calculation
3976 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
3978 // make ITS - ESD map
3980 for (Int_t itrack=0;itrack<ntracks+2;itrack++) {
3981 itsmap[itrack] = -1;
3982 forbidden[itrack] = kFALSE;
3983 maxr[itrack] = kMaxR;
3984 minr[itrack] = kMinR;
3985 minPointAngle[itrack] = kMinPointAngle;
3987 for (Int_t itrack=0;itrack<nitstracks;itrack++){
3988 AliITStrackMI * original = (AliITStrackMI*)(fOriginal.At(itrack));
3989 Int_t esdindex = original->GetESDtrack()->GetID();
3990 itsmap[esdindex] = itrack;
3993 // create ITS tracks from ESD tracks if not done before
3995 for (Int_t itrack=0;itrack<ntracks;itrack++){
3996 if (itsmap[itrack]>=0) continue;
3997 AliITStrackMI * tpctrack = new AliITStrackMI(*(event->GetTrack(itrack)));
3998 //tpctrack->fD[0] = tpctrack->GetD(GetX(),GetY());
3999 //tpctrack->fD[1] = tpctrack->GetZat(GetX())-GetZ();
4000 tpctrack->GetDZ(GetX(),GetY(),GetZ(),tpctrack->GetDP()); //I.B.
4001 if (tpctrack->GetD(0)<20 && tpctrack->GetD(1)<20){
4002 // tracks which can reach inner part of ITS
4003 // propagate track to outer its volume - with correction for material
4004 CorrectForTPCtoITSDeadZoneMaterial(tpctrack);
4006 itsmap[itrack] = nitstracks;
4007 fOriginal.AddAt(tpctrack,nitstracks);
4011 // fill temporary arrays
4013 for (Int_t itrack=0;itrack<ntracks;itrack++){
4014 AliESDtrack * esdtrack = event->GetTrack(itrack);
4015 Int_t itsindex = itsmap[itrack];
4016 AliITStrackMI *original = (AliITStrackMI*)fOriginal.At(itsmap[itrack]);
4017 if (!original) continue;
4018 AliITStrackMI *bestConst = 0;
4019 AliITStrackMI *bestLong = 0;
4020 AliITStrackMI *best = 0;
4023 TObjArray * array = (TObjArray*) fTrackHypothesys.At(itsindex);
4024 Int_t hentries = (array==0) ? 0 : array->GetEntriesFast();
4025 // Get best track with vertex constrain
4026 for (Int_t ih=0;ih<hentries;ih++){
4027 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
4028 if (!trackh->GetConstrain()) continue;
4029 if (!bestConst) bestConst = trackh;
4030 if (trackh->GetNumberOfClusters()>5.0){
4031 bestConst = trackh; // full track - with minimal chi2
4034 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()) continue;
4038 // Get best long track without vertex constrain and best track without vertex constrain
4039 for (Int_t ih=0;ih<hentries;ih++){
4040 AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
4041 if (trackh->GetConstrain()) continue;
4042 if (!best) best = trackh;
4043 if (!bestLong) bestLong = trackh;
4044 if (trackh->GetNumberOfClusters()>5.0){
4045 bestLong = trackh; // full track - with minimal chi2
4048 if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()) continue;
4053 bestLong = original;
4055 //I.B. trackat0 = *bestLong;
4056 new (&trackat0) AliITStrackMI(*bestLong);
4057 Double_t xx,yy,zz,alpha;
4058 if (!bestLong->GetGlobalXYZat(bestLong->GetX(),xx,yy,zz)) continue;
4059 alpha = TMath::ATan2(yy,xx);
4060 if (!trackat0.Propagate(alpha,0)) continue;
4061 // calculate normalized distances to the vertex
4063 Float_t ptfac = (1.+100.*TMath::Abs(trackat0.GetC()));
4064 if ( bestLong->GetNumberOfClusters()>3 ){
4065 dist[itsindex] = trackat0.GetY();
4066 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
4067 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
4068 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
4069 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
4071 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<6) normdist[itsindex]*=2.;
4072 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<5) normdist[itsindex]*=2.;
4073 if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<4) normdist[itsindex]*=2.;
4075 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<6) normdist[itsindex]*=1.5;
4076 if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<5) normdist[itsindex]*=1.5;
4080 if (bestConst&&bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5){
4081 dist[itsindex] = bestConst->GetD(0);
4082 norm[itsindex] = bestConst->GetDnorm(0);
4083 normdist0[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
4084 normdist1[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
4085 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
4087 dist[itsindex] = trackat0.GetY();
4088 norm[itsindex] = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
4089 normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
4090 normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
4091 normdist[itsindex] = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
4092 if (TMath::Abs(trackat0.GetTgl())>1.05){
4093 if (normdist[itsindex]<3) forbidden[itsindex]=kTRUE;
4094 if (normdist[itsindex]>3) {
4095 minr[itsindex] = TMath::Max(Float_t(40.),minr[itsindex]);
4101 //-----------------------------------------------------------
4102 //Forbid primary track candidates -
4104 //treetr->SetAlias("forbidden0","Tr0.fN<4&&Tr1.fN+Tr1.fNDeadZone>4.5");
4105 //treetr->SetAlias("forbidden1","ND<3&&Tr1.fN+Tr1.fNDeadZone>5.5");
4106 //treetr->SetAlias("forbidden2","ND<2&&Tr1.fClIndex[0]>0&&Tr1.fClIndex[0]>0");
4107 //treetr->SetAlias("forbidden3","ND<1&&Tr1.fClIndex[0]>0");
4108 //treetr->SetAlias("forbidden4","ND<4&&Tr1.fNormChi2[0]<2");
4109 //treetr->SetAlias("forbidden5","ND<5&&Tr1.fNormChi2[0]<1");
4110 //-----------------------------------------------------------
4112 if (bestLong->GetNumberOfClusters()<4 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5) forbidden[itsindex]=kTRUE;
4113 if (normdist[itsindex]<3 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>5.5) forbidden[itsindex]=kTRUE;
4114 if (normdist[itsindex]<2 && bestConst->GetClIndex(0)>0 && bestConst->GetClIndex(1)>0 ) forbidden[itsindex]=kTRUE;
4115 if (normdist[itsindex]<1 && bestConst->GetClIndex(0)>0) forbidden[itsindex]=kTRUE;
4116 if (normdist[itsindex]<4 && bestConst->GetNormChi2(0)<2) forbidden[itsindex]=kTRUE;
4117 if (normdist[itsindex]<5 && bestConst->GetNormChi2(0)<1) forbidden[itsindex]=kTRUE;
4118 if (bestConst->GetNormChi2(0)<2.5) {
4119 minPointAngle[itsindex]= 0.9999;
4120 maxr[itsindex] = 10;
4124 //forbid daughter kink candidates
4126 if (esdtrack->GetKinkIndex(0)>0) forbidden[itsindex] = kTRUE;
4127 Bool_t isElectron = kTRUE;
4128 Bool_t isProton = kTRUE;
4130 esdtrack->GetESDpid(pid);
4131 for (Int_t i=1;i<5;i++){
4132 if (pid[0]<pid[i]) isElectron= kFALSE;
4133 if (pid[4]<pid[i]) isProton= kFALSE;
4136 forbidden[itsindex]=kFALSE;
4137 normdist[itsindex]*=-1;
4140 if (normdist[itsindex]>2) forbidden[itsindex]=kFALSE;
4141 normdist[itsindex]*=-1;
4145 // Causality cuts in TPC volume
4147 if (esdtrack->GetTPCdensity(0,10) >0.6) maxr[itsindex] = TMath::Min(Float_t(110),maxr[itsindex]);
4148 if (esdtrack->GetTPCdensity(10,30)>0.6) maxr[itsindex] = TMath::Min(Float_t(120),maxr[itsindex]);
4149 if (esdtrack->GetTPCdensity(20,40)>0.6) maxr[itsindex] = TMath::Min(Float_t(130),maxr[itsindex]);
4150 if (esdtrack->GetTPCdensity(30,50)>0.6) maxr[itsindex] = TMath::Min(Float_t(140),maxr[itsindex]);
4152 if (esdtrack->GetTPCdensity(0,60)<0.4&&bestLong->GetNumberOfClusters()<3) minr[itsindex]=100;
4158 "Tr1.="<<((bestConst)? bestConst:dummy)<<
4160 "Tr3.="<<&trackat0<<
4162 "Dist="<<dist[itsindex]<<
4163 "ND0="<<normdist0[itsindex]<<
4164 "ND1="<<normdist1[itsindex]<<
4165 "ND="<<normdist[itsindex]<<
4166 "Pz="<<primvertex[2]<<
4167 "Forbid="<<forbidden[itsindex]<<
4171 trackarray.AddAt(best,itsindex);
4172 trackarrayc.AddAt(bestConst,itsindex);
4173 trackarrayl.AddAt(bestLong,itsindex);
4174 new (&helixes[itsindex]) AliHelix(*best);
4179 // first iterration of V0 finder
4181 for (Int_t iesd0=0;iesd0<ntracks;iesd0++){
4182 Int_t itrack0 = itsmap[iesd0];
4183 if (forbidden[itrack0]) continue;
4184 AliITStrackMI * btrack0 = (AliITStrackMI*)trackarray.At(itrack0);
4185 if (!btrack0) continue;
4186 if (btrack0->GetSign()>0) continue;
4187 AliITStrackMI *trackc0 = (AliITStrackMI*)trackarrayc.At(itrack0);
4189 for (Int_t iesd1=0;iesd1<ntracks;iesd1++){
4190 Int_t itrack1 = itsmap[iesd1];
4191 if (forbidden[itrack1]) continue;
4193 AliITStrackMI * btrack1 = (AliITStrackMI*)trackarray.At(itrack1);
4194 if (!btrack1) continue;
4195 if (btrack1->GetSign()<0) continue;
4196 Bool_t isGold = kFALSE;
4197 if (TMath::Abs(TMath::Abs(btrack0->GetLabel())-TMath::Abs(btrack1->GetLabel()))==1){
4200 AliITStrackMI *trackc1 = (AliITStrackMI*)trackarrayc.At(itrack1);
4201 AliHelix &h1 = helixes[itrack0];
4202 AliHelix &h2 = helixes[itrack1];
4204 // find linear distance
4209 Double_t phase[2][2],radius[2];
4210 Int_t points = h1.GetRPHIintersections(h2, phase, radius);
4211 if (points==0) continue;
4212 Double_t delta[2]={1000000,1000000};
4214 h1.ParabolicDCA(h2,phase[0][0],phase[0][1],radius[0],delta[0]);
4216 if (radius[1]<rmin) rmin = radius[1];
4217 h1.ParabolicDCA(h2,phase[1][0],phase[1][1],radius[1],delta[1]);
4219 rmin = TMath::Sqrt(rmin);
4220 Double_t distance = 0;
4221 Double_t radiusC = 0;
4223 if (points==1 || delta[0]<delta[1]){
4224 distance = TMath::Sqrt(delta[0]);
4225 radiusC = TMath::Sqrt(radius[0]);
4227 distance = TMath::Sqrt(delta[1]);
4228 radiusC = TMath::Sqrt(radius[1]);
4231 if (radiusC<TMath::Max(minr[itrack0],minr[itrack1])) continue;
4232 if (radiusC>TMath::Min(maxr[itrack0],maxr[itrack1])) continue;
4233 Float_t maxDist = TMath::Min(kMaxDist,Float_t(kMaxDist0+radiusC*kMaxDist1));
4234 if (distance>maxDist) continue;
4235 Float_t pointAngle = h1.GetPointAngle(h2,phase[iphase],primvertex);
4236 if (pointAngle<TMath::Max(minPointAngle[itrack0],minPointAngle[itrack1])) continue;
4239 // Double_t distance = TestV0(h1,h2,pvertex,rmin);
4241 // if (distance>maxDist) continue;
4242 // if (pvertex->GetRr()<kMinR) continue;
4243 // if (pvertex->GetRr()>kMaxR) continue;
4244 AliITStrackMI * track0=btrack0;
4245 AliITStrackMI * track1=btrack1;
4246 // if (pvertex->GetRr()<3.5){
4248 //use longest tracks inside the pipe
4249 track0 = (AliITStrackMI*)trackarrayl.At(itrack0);
4250 track1 = (AliITStrackMI*)trackarrayl.At(itrack1);
4254 pvertex->SetParamN(*track0);
4255 pvertex->SetParamP(*track1);
4256 pvertex->Update(primvertex);
4257 pvertex->SetClusters(track0->ClIndex(),track1->ClIndex()); // register clusters
4259 if (pvertex->GetRr()<kMinR) continue;
4260 if (pvertex->GetRr()>kMaxR) continue;
4261 if (pvertex->GetV0CosineOfPointingAngle()<kMinPointAngle) continue;
4262 //Bo: if (pvertex->GetDist2()>maxDist) continue;
4263 if (pvertex->GetDcaV0Daughters()>maxDist) continue;
4264 //Bo: pvertex->SetLab(0,track0->GetLabel());
4265 //Bo: pvertex->SetLab(1,track1->GetLabel());
4266 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4267 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4269 AliITStrackMI * htrackc0 = trackc0 ? trackc0:dummy;
4270 AliITStrackMI * htrackc1 = trackc1 ? trackc1:dummy;
4274 TObjArray * array0b = (TObjArray*)fBestHypothesys.At(itrack0);
4275 if (!array0b&&pvertex->GetRr()<40 && TMath::Abs(track0->GetTgl())<1.1) {
4276 fCurrentEsdTrack = itrack0;
4277 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack0),itrack0, kFALSE);
4279 TObjArray * array1b = (TObjArray*)fBestHypothesys.At(itrack1);
4280 if (!array1b&&pvertex->GetRr()<40 && TMath::Abs(track1->GetTgl())<1.1) {
4281 fCurrentEsdTrack = itrack1;
4282 FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack1),itrack1, kFALSE);
4285 AliITStrackMI * track0b = (AliITStrackMI*)fOriginal.At(itrack0);
4286 AliITStrackMI * track1b = (AliITStrackMI*)fOriginal.At(itrack1);
4287 AliITStrackMI * track0l = (AliITStrackMI*)fOriginal.At(itrack0);
4288 AliITStrackMI * track1l = (AliITStrackMI*)fOriginal.At(itrack1);
4290 Float_t minchi2before0=16;
4291 Float_t minchi2before1=16;
4292 Float_t minchi2after0 =16;
4293 Float_t minchi2after1 =16;
4294 Double_t xrp[3]; pvertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
4295 Int_t maxLayer = GetNearestLayer(xrp); //I.B.
4297 if (array0b) for (Int_t i=0;i<5;i++){
4298 // best track after vertex
4299 AliITStrackMI * btrack = (AliITStrackMI*)array0b->At(i);
4300 if (!btrack) continue;
4301 if (btrack->GetNumberOfClusters()>track0l->GetNumberOfClusters()) track0l = btrack;
4302 // if (btrack->fX<pvertex->GetRr()-2.-0.5/(0.1+pvertex->GetAnglep()[2])) {
4303 if (btrack->GetX()<pvertex->GetRr()-2.) {
4304 if ( (maxLayer>i+2|| (i==0)) && btrack->GetNumberOfClusters()==(6-i)&&i<3){
4307 if (maxLayer<3){ // take prim vertex as additional measurement
4308 if (normdist[itrack0]>0 && htrackc0){
4309 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack0]*normdist[itrack0],16.);
4311 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack0]*normdist[itrack0]+3.),16.);
4315 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4317 if (!btrack->GetClIndex(ilayer)){
4321 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4322 for (Int_t itrack=0;itrack<4;itrack++){
4323 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack0){
4324 sumchi2+=18.; //shared cluster
4328 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4329 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4333 if (sumchi2<minchi2before0) minchi2before0=sumchi2;
4335 continue; //safety space - Geo manager will give exact layer
4338 minchi2after0 = btrack->GetNormChi2(i);
4341 if (array1b) for (Int_t i=0;i<5;i++){
4342 // best track after vertex
4343 AliITStrackMI * btrack = (AliITStrackMI*)array1b->At(i);
4344 if (!btrack) continue;
4345 if (btrack->GetNumberOfClusters()>track1l->GetNumberOfClusters()) track1l = btrack;
4346 // if (btrack->fX<pvertex->GetRr()-2-0.5/(0.1+pvertex->GetAnglep()[2])){
4347 if (btrack->GetX()<pvertex->GetRr()-2){
4348 if ((maxLayer>i+2 || (i==0))&&btrack->GetNumberOfClusters()==(6-i)&&(i<3)){
4351 if (maxLayer<3){ // take prim vertex as additional measurement
4352 if (normdist[itrack1]>0 && htrackc1){
4353 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack1]*normdist[itrack1],16.);
4355 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack1]*normdist[itrack1]+3.),16.);
4359 for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
4361 if (!btrack->GetClIndex(ilayer)){
4365 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
4366 for (Int_t itrack=0;itrack<4;itrack++){
4367 if (fgLayers[ilayer].GetClusterTracks(itrack,c)>=0 && fgLayers[ilayer].GetClusterTracks(itrack,c)!=itrack1){
4368 sumchi2+=18.; //shared cluster
4372 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
4373 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));
4377 if (sumchi2<minchi2before1) minchi2before1=sumchi2;
4379 continue; //safety space - Geo manager will give exact layer
4382 minchi2after1 = btrack->GetNormChi2(i);
4386 // position resolution - used for DCA cut
4387 Float_t sigmad = track0b->GetSigmaY2()+track0b->GetSigmaZ2()+track1b->GetSigmaY2()+track1b->GetSigmaZ2()+
4388 (track0b->GetX()-pvertex->GetRr())*(track0b->GetX()-pvertex->GetRr())*(track0b->GetSigmaSnp2()+track0b->GetSigmaTgl2())+
4389 (track1b->GetX()-pvertex->GetRr())*(track1b->GetX()-pvertex->GetRr())*(track1b->GetSigmaSnp2()+track1b->GetSigmaTgl2());
4390 sigmad =TMath::Sqrt(sigmad)+0.04;
4391 if (pvertex->GetRr()>50){
4392 Double_t cov0[15],cov1[15];
4393 track0b->GetESDtrack()->GetInnerExternalCovariance(cov0);
4394 track1b->GetESDtrack()->GetInnerExternalCovariance(cov1);
4395 sigmad = cov0[0]+cov0[2]+cov1[0]+cov1[2]+
4396 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov0[5]+cov0[9])+
4397 (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov1[5]+cov1[9]);
4398 sigmad =TMath::Sqrt(sigmad)+0.05;
4402 vertex2.SetParamN(*track0b);
4403 vertex2.SetParamP(*track1b);
4404 vertex2.Update(primvertex);
4405 //Bo: if (vertex2.GetDist2()<=pvertex->GetDist2()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4406 if (vertex2.GetDcaV0Daughters()<=pvertex->GetDcaV0Daughters()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
4407 pvertex->SetParamN(*track0b);
4408 pvertex->SetParamP(*track1b);
4409 pvertex->Update(primvertex);
4410 pvertex->SetClusters(track0b->ClIndex(),track1b->ClIndex()); // register clusters
4411 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
4412 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
4414 pvertex->SetDistSigma(sigmad);
4415 //Bo: pvertex->SetDistNorm(pvertex->GetDist2()/sigmad);
4416 pvertex->SetNormDCAPrim(normdist[itrack0],normdist[itrack1]);
4418 // define likelihhod and causalities
4420 Float_t pa0=1, pa1=1, pb0=0.26, pb1=0.26;
4422 Float_t fnorm0 = normdist[itrack0];
4423 if (fnorm0<0) fnorm0*=-3;
4424 Float_t fnorm1 = normdist[itrack1];
4425 if (fnorm1<0) fnorm1*=-3;
4426 if ((pvertex->GetAnglep()[2]>0.1) || ( (pvertex->GetRr()<10.5)&& pvertex->GetAnglep()[2]>0.05 ) || (pvertex->GetRr()<3)){
4427 pb0 = TMath::Exp(-TMath::Min(fnorm0,Float_t(16.))/12.);
4428 pb1 = TMath::Exp(-TMath::Min(fnorm1,Float_t(16.))/12.);
4430 pvertex->SetChi2Before(normdist[itrack0]);
4431 pvertex->SetChi2After(normdist[itrack1]);
4432 pvertex->SetNAfter(0);
4433 pvertex->SetNBefore(0);
4435 pvertex->SetChi2Before(minchi2before0);
4436 pvertex->SetChi2After(minchi2before1);
4437 if (pvertex->GetAnglep()[2]>0.1 || ( pvertex->GetRr()<10.5 && pvertex->GetAnglep()[2]>0.05) || pvertex->GetRr()<3){
4438 pb0 = TMath::Exp(-TMath::Min(minchi2before0,Float_t(16))/12.);
4439 pb1 = TMath::Exp(-TMath::Min(minchi2before1,Float_t(16))/12.);
4441 pvertex->SetNAfter(maxLayer);
4442 pvertex->SetNBefore(maxLayer);
4444 if (pvertex->GetRr()<90){
4445 pa0 *= TMath::Min(track0->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4446 pa1 *= TMath::Min(track1->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
4448 if (pvertex->GetRr()<20){
4449 pa0 *= (0.2+TMath::Exp(-TMath::Min(minchi2after0,Float_t(16))/8.))/1.2;
4450 pa1 *= (0.2+TMath::Exp(-TMath::Min(minchi2after1,Float_t(16))/8.))/1.2;
4453 pvertex->SetCausality(pb0,pb1,pa0,pa1);
4455 // Likelihood calculations - apply cuts
4457 Bool_t v0OK = kTRUE;
4458 Float_t p12 = pvertex->GetParamP()->GetParameter()[4]*pvertex->GetParamP()->GetParameter()[4];
4459 p12 += pvertex->GetParamN()->GetParameter()[4]*pvertex->GetParamN()->GetParameter()[4];
4460 p12 = TMath::Sqrt(p12); // "mean" momenta
4461 Float_t sigmap0 = 0.0001+0.001/(0.1+pvertex->GetRr());
4462 Float_t sigmap = 0.5*sigmap0*(0.6+0.4*p12); // "resolution: of point angle - as a function of radius and momenta
4464 Float_t causalityA = (1.0-pvertex->GetCausalityP()[0])*(1.0-pvertex->GetCausalityP()[1]);
4465 Float_t causalityB = TMath::Sqrt(TMath::Min(pvertex->GetCausalityP()[2],Double_t(0.7))*
4466 TMath::Min(pvertex->GetCausalityP()[3],Double_t(0.7)));
4468 //Bo: Float_t likelihood0 = (TMath::Exp(-pvertex->GetDistNorm())+0.1) *(pvertex->GetDist2()<0.5)*(pvertex->GetDistNorm()<5);
4469 Float_t lDistNorm = pvertex->GetDcaV0Daughters()/pvertex->GetDistSigma();
4470 Float_t likelihood0 = (TMath::Exp(-lDistNorm)+0.1) *(pvertex->GetDcaV0Daughters()<0.5)*(lDistNorm<5);
4472 Float_t likelihood1 = TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/sigmap)+
4473 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(4.*sigmap))+
4474 0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(8.*sigmap))+
4475 0.1*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/0.01);
4477 if (causalityA<kCausality0Cut) v0OK = kFALSE;
4478 if (TMath::Sqrt(likelihood0*likelihood1)<kLikelihood01Cut) v0OK = kFALSE;
4479 if (likelihood1<kLikelihood1Cut) v0OK = kFALSE;
4480 if (TMath::Power(likelihood0*likelihood1*causalityB,0.33)<kCombinedCut) v0OK = kFALSE;
4485 Bool_t gold = TMath::Abs(TMath::Abs(track0->GetLabel())-TMath::Abs(track1->GetLabel()))==1;
4487 "Tr0.="<<track0<< //best without constrain
4488 "Tr1.="<<track1<< //best without constrain
4489 "Tr0B.="<<track0b<< //best without constrain after vertex
4490 "Tr1B.="<<track1b<< //best without constrain after vertex
4491 "Tr0C.="<<htrackc0<< //best with constrain if exist
4492 "Tr1C.="<<htrackc1<< //best with constrain if exist
4493 "Tr0L.="<<track0l<< //longest best
4494 "Tr1L.="<<track1l<< //longest best
4495 "Esd0.="<<track0->GetESDtrack()<< // esd track0 params
4496 "Esd1.="<<track1->GetESDtrack()<< // esd track1 params
4497 "V0.="<<pvertex<< //vertex properties
4498 "V0b.="<<&vertex2<< //vertex properties at "best" track
4499 "ND0="<<normdist[itrack0]<< //normalize distance for track0
4500 "ND1="<<normdist[itrack1]<< //normalize distance for track1
4502 // "RejectBase="<<rejectBase<< //rejection in First itteration
4508 //if (rejectBase) continue;
4510 pvertex->SetStatus(0);
4511 // if (rejectBase) {
4512 // pvertex->SetStatus(-100);
4514 if (pvertex->GetV0CosineOfPointingAngle()>kMinPointAngle2) {
4515 //Bo: pvertex->SetESDindexes(track0->GetESDtrack()->GetID(),track1->GetESDtrack()->GetID());
4516 pvertex->SetIndex(0,track0->GetESDtrack()->GetID());//Bo: consistency 0 for neg
4517 pvertex->SetIndex(1,track1->GetESDtrack()->GetID());//Bo: consistency 1 for pos
4519 // AliV0vertex vertexjuri(*track0,*track1);
4520 // vertexjuri.SetESDindexes(track0->fESDtrack->GetID(),track1->fESDtrack->GetID());
4521 // event->AddV0(&vertexjuri);
4522 pvertex->SetStatus(100);
4524 pvertex->SetOnFlyStatus(kTRUE);
4525 pvertex->ChangeMassHypothesis(kK0Short);
4526 event->AddV0(pvertex);
4532 // delete temporary arrays
4535 delete[] minPointAngle;
4547 //------------------------------------------------------------------------
4548 void AliITStrackerMI::RefitV02(AliESDEvent *event)
4551 //try to refit V0s in the third path of the reconstruction
4553 TTreeSRedirector &cstream = *fDebugStreamer;
4555 Int_t nv0s = event->GetNumberOfV0s();
4556 Float_t primvertex[3]={GetX(),GetY(),GetZ()};
4558 for (Int_t iv0 = 0; iv0<nv0s;iv0++){
4559 AliV0 * v0mi = (AliV0*)event->GetV0(iv0);
4560 if (!v0mi) continue;
4561 Int_t itrack0 = v0mi->GetIndex(0);
4562 Int_t itrack1 = v0mi->GetIndex(1);
4563 AliESDtrack *esd0 = event->GetTrack(itrack0);
4564 AliESDtrack *esd1 = event->GetTrack(itrack1);
4565 if (!esd0||!esd1) continue;
4566 AliITStrackMI tpc0(*esd0);
4567 AliITStrackMI tpc1(*esd1);
4568 Double_t x,y,z; v0mi->GetXYZ(x,y,z); //I.B.
4569 Double_t alpha =TMath::ATan2(y,x); //I.B.
4570 if (v0mi->GetRr()>85){
4571 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4572 v0temp.SetParamN(tpc0);
4573 v0temp.SetParamP(tpc1);
4574 v0temp.Update(primvertex);
4575 if (kFALSE) cstream<<"Refit"<<
4577 "V0refit.="<<&v0temp<<
4581 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4582 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4583 v0mi->SetParamN(tpc0);
4584 v0mi->SetParamP(tpc1);
4585 v0mi->Update(primvertex);
4590 if (v0mi->GetRr()>35){
4591 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4592 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4593 if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4594 v0temp.SetParamN(tpc0);
4595 v0temp.SetParamP(tpc1);
4596 v0temp.Update(primvertex);
4597 if (kFALSE) cstream<<"Refit"<<
4599 "V0refit.="<<&v0temp<<
4603 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4604 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4605 v0mi->SetParamN(tpc0);
4606 v0mi->SetParamP(tpc1);
4607 v0mi->Update(primvertex);
4612 CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
4613 CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
4614 // if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
4615 if (RefitAt(v0mi->GetRr(),&tpc0, v0mi->GetClusters(0)) && RefitAt(v0mi->GetRr(),&tpc1, v0mi->GetClusters(1))){
4616 v0temp.SetParamN(tpc0);
4617 v0temp.SetParamP(tpc1);
4618 v0temp.Update(primvertex);
4619 if (kFALSE) cstream<<"Refit"<<
4621 "V0refit.="<<&v0temp<<
4625 //Bo: if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4626 if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
4627 v0mi->SetParamN(tpc0);
4628 v0mi->SetParamP(tpc1);
4629 v0mi->Update(primvertex);
4634 //------------------------------------------------------------------------
4635 void AliITStrackerMI::BuildMaterialLUT(TString material) {
4636 //--------------------------------------------------------------------
4637 // Fill a look-up table with mean material
4638 //--------------------------------------------------------------------
4642 Double_t point1[3],point2[3];
4643 Double_t phi,cosphi,sinphi,z;
4644 // 0-5 layers, 6 pipe, 7-8 shields
4645 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
4646 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
4648 Int_t ifirst=0,ilast=0;
4649 if(material.Contains("Pipe")) {
4651 } else if(material.Contains("Shields")) {
4653 } else if(material.Contains("Layers")) {
4656 Error("BuildMaterialLUT","Wrong layer name\n");
4659 for(Int_t imat=ifirst; imat<=ilast; imat++) {
4660 Double_t param[5]={0.,0.,0.,0.,0.};
4661 for (Int_t i=0; i<n; i++) {
4662 phi = 2.*TMath::Pi()*gRandom->Rndm();
4663 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
4664 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
4665 point1[0] = rmin[imat]*cosphi;
4666 point1[1] = rmin[imat]*sinphi;
4668 point2[0] = rmax[imat]*cosphi;
4669 point2[1] = rmax[imat]*sinphi;
4671 AliTracker::MeanMaterialBudget(point1,point2,mparam);
4672 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
4674 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
4676 fxOverX0Layer[imat] = param[1];
4677 fxTimesRhoLayer[imat] = param[0]*param[4];
4678 } else if(imat==6) {
4679 fxOverX0Pipe = param[1];
4680 fxTimesRhoPipe = param[0]*param[4];
4681 } else if(imat==7) {
4682 fxOverX0Shield[0] = param[1];
4683 fxTimesRhoShield[0] = param[0]*param[4];
4684 } else if(imat==8) {
4685 fxOverX0Shield[1] = param[1];
4686 fxTimesRhoShield[1] = param[0]*param[4];
4690 printf("%s\n",material.Data());
4691 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
4692 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
4693 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
4694 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
4695 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
4696 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
4697 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
4698 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
4699 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
4703 //------------------------------------------------------------------------
4704 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
4705 TString direction) {
4706 //-------------------------------------------------------------------
4707 // Propagate beyond beam pipe and correct for material
4708 // (material budget in different ways according to fUseTGeo value)
4709 //-------------------------------------------------------------------
4711 // Define budget mode:
4712 // 0: material from AliITSRecoParam (hard coded)
4713 // 1: material from TGeo (on the fly)
4714 // 2: material from lut
4715 // 3: material from TGeo (same for all hypotheses)
4728 if(fTrackingPhase.Contains("Clusters2Tracks"))
4729 { mode=3; } else { mode=1; }
4732 if(fTrackingPhase.Contains("Clusters2Tracks"))
4733 { mode=3; } else { mode=2; }
4739 if(fTrackingPhase.Contains("Default")) mode=0;
4741 Int_t index=fCurrentEsdTrack;
4743 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4744 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4746 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4748 Double_t xOverX0,x0,lengthTimesMeanDensity;
4749 Bool_t anglecorr=kTRUE;
4753 xOverX0 = AliITSRecoParam::GetdPipe();
4754 x0 = AliITSRecoParam::GetX0Be();
4755 lengthTimesMeanDensity = xOverX0*x0;
4758 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4762 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4763 xOverX0 = fxOverX0Pipe;
4764 lengthTimesMeanDensity = fxTimesRhoPipe;
4767 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4768 if(fxOverX0PipeTrks[index]<0) {
4769 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4770 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4771 (1.-t->GetSnp()*t->GetSnp()));
4772 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4773 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4776 xOverX0 = fxOverX0PipeTrks[index];
4777 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4781 lengthTimesMeanDensity *= dir;
4783 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4784 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4788 //------------------------------------------------------------------------
4789 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4791 TString direction) {
4792 //-------------------------------------------------------------------
4793 // Propagate beyond SPD or SDD shield and correct for material
4794 // (material budget in different ways according to fUseTGeo value)
4795 //-------------------------------------------------------------------
4797 // Define budget mode:
4798 // 0: material from AliITSRecoParam (hard coded)
4799 // 1: material from TGeo (on the fly)
4800 // 2: material from lut
4801 // 3: material from TGeo (same for all hypotheses)
4814 if(fTrackingPhase.Contains("Clusters2Tracks"))
4815 { mode=3; } else { mode=1; }
4818 if(fTrackingPhase.Contains("Clusters2Tracks"))
4819 { mode=3; } else { mode=2; }
4825 if(fTrackingPhase.Contains("Default")) mode=0;
4827 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4829 Int_t shieldindex=0;
4830 if (shield.Contains("SDD")) { // SDDouter
4831 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4833 } else if (shield.Contains("SPD")) { // SPDouter
4834 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4837 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4841 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4843 Int_t index=2*fCurrentEsdTrack+shieldindex;
4845 Double_t xOverX0,x0,lengthTimesMeanDensity;
4846 Bool_t anglecorr=kTRUE;
4850 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4851 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4852 lengthTimesMeanDensity = xOverX0*x0;
4855 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4859 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4860 xOverX0 = fxOverX0Shield[shieldindex];
4861 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4864 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4865 if(fxOverX0ShieldTrks[index]<0) {
4866 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4867 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4868 (1.-t->GetSnp()*t->GetSnp()));
4869 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4870 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4873 xOverX0 = fxOverX0ShieldTrks[index];
4874 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4878 lengthTimesMeanDensity *= dir;
4880 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4881 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4885 //------------------------------------------------------------------------
4886 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4888 Double_t oldGlobXYZ[3],
4889 TString direction) {
4890 //-------------------------------------------------------------------
4891 // Propagate beyond layer and correct for material
4892 // (material budget in different ways according to fUseTGeo value)
4893 //-------------------------------------------------------------------
4895 // Define budget mode:
4896 // 0: material from AliITSRecoParam (hard coded)
4897 // 1: material from TGeo (on the fly)
4898 // 2: material from lut
4899 // 3: material from TGeo (same for all hypotheses)
4912 if(fTrackingPhase.Contains("Clusters2Tracks"))
4913 { mode=3; } else { mode=1; }
4916 if(fTrackingPhase.Contains("Clusters2Tracks"))
4917 { mode=3; } else { mode=2; }
4923 if(fTrackingPhase.Contains("Default")) mode=0;
4925 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4927 Double_t r=fgLayers[layerindex].GetR();
4928 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4930 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4932 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4934 Int_t index=6*fCurrentEsdTrack+layerindex;
4936 // Bring the track beyond the material
4937 if (!t->AliExternalTrackParam::PropagateTo(xToGo,GetBz())) return 0;
4938 Double_t globXYZ[3];
4939 if (!t->GetXYZ(globXYZ)) return 0;
4941 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4943 Bool_t anglecorr=kTRUE;
4947 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4948 lengthTimesMeanDensity = xOverX0*x0;
4951 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4952 if(mparam[1]>900000) return 0;
4954 lengthTimesMeanDensity=mparam[0]*mparam[4];
4958 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4959 xOverX0 = fxOverX0Layer[layerindex];
4960 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4963 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4964 if(fxOverX0LayerTrks[index]<0) {
4965 AliTracker::MeanMaterialBudget(oldGlobXYZ,globXYZ,mparam);
4966 if(mparam[1]>900000) return 0;
4967 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4968 (1.-t->GetSnp()*t->GetSnp()));
4969 xOverX0=mparam[1]/angle;
4970 lengthTimesMeanDensity=mparam[0]*mparam[4]/angle;
4971 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0);
4972 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity);
4974 xOverX0 = fxOverX0LayerTrks[index];
4975 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4979 lengthTimesMeanDensity *= dir;
4981 if (!t->CorrectForMeanMaterial(xOverX0,lengthTimesMeanDensity,anglecorr)) return 0;
4985 //------------------------------------------------------------------------
4986 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4987 //-----------------------------------------------------------------
4988 // Initialize LUT for storing material for each prolonged track
4989 //-----------------------------------------------------------------
4990 fxOverX0PipeTrks = new Float_t[ntracks];
4991 fxTimesRhoPipeTrks = new Float_t[ntracks];
4992 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4993 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4994 fxOverX0LayerTrks = new Float_t[ntracks*6];
4995 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4997 for(Int_t i=0; i<ntracks; i++) {
4998 fxOverX0PipeTrks[i] = -1.;
4999 fxTimesRhoPipeTrks[i] = -1.;
5001 for(Int_t j=0; j<ntracks*2; j++) {
5002 fxOverX0ShieldTrks[j] = -1.;
5003 fxTimesRhoShieldTrks[j] = -1.;
5005 for(Int_t k=0; k<ntracks*6; k++) {
5006 fxOverX0LayerTrks[k] = -1.;
5007 fxTimesRhoLayerTrks[k] = -1.;
5014 //------------------------------------------------------------------------
5015 void AliITStrackerMI::DeleteTrksMaterialLUT() {
5016 //-----------------------------------------------------------------
5017 // Delete LUT for storing material for each prolonged track
5018 //-----------------------------------------------------------------
5019 if(fxOverX0PipeTrks) {
5020 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
5022 if(fxOverX0ShieldTrks) {
5023 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
5026 if(fxOverX0LayerTrks) {
5027 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
5029 if(fxTimesRhoPipeTrks) {
5030 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
5032 if(fxTimesRhoShieldTrks) {
5033 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
5035 if(fxTimesRhoLayerTrks) {
5036 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
5040 //------------------------------------------------------------------------
5041 Int_t AliITStrackerMI::CheckSkipLayer(AliITStrackMI *track,
5042 Int_t ilayer,Int_t idet) const {
5043 //-----------------------------------------------------------------
5044 // This method is used to decide whether to allow a prolongation
5045 // without clusters, because we want to skip the layer.
5046 // In this case the return value is > 0:
5047 // return 1: the user requested to skip a layer
5048 // return 2: track outside z acceptance of SSD/SDD and will cross both SPD
5049 //-----------------------------------------------------------------
5051 if (AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) return 1;
5053 if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
5054 // check if track will cross SPD outer layer
5055 Double_t phiAtSPD2,zAtSPD2;
5056 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
5057 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
5063 //------------------------------------------------------------------------
5064 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
5065 Int_t ilayer,Int_t idet,
5066 Double_t dz,Double_t dy,
5067 Bool_t noClusters) const {
5068 //-----------------------------------------------------------------
5069 // This method is used to decide whether to allow a prolongation
5070 // without clusters, because there is a dead zone in the road.
5071 // In this case the return value is > 0:
5072 // return 1: dead zone at z=0,+-7cm in SPD
5073 // return 2: all road is "bad" (dead or noisy) from the OCDB
5074 // return 3: something "bad" (dead or noisy) from the OCDB
5075 //-----------------------------------------------------------------
5077 // check dead zones at z=0,+-7cm in the SPD
5078 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
5079 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
5080 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
5081 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
5082 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
5083 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
5084 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
5085 for (Int_t i=0; i<3; i++)
5086 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
5087 AliDebug(2,Form("crack SPD %d",ilayer));
5092 // check bad zones from OCDB
5093 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
5095 if (idet<0) return 0;
5097 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
5100 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
5101 if (ilayer==0 || ilayer==1) { // ---------- SPD
5103 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
5105 detSizeFactorX *= 2.;
5106 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
5109 AliITSsegmentation *segm = (AliITSsegmentation*)fDetTypeRec->GetSegmentationModel(detType);
5110 if (detType==2) segm->SetLayer(ilayer+1);
5111 Float_t detSizeX = detSizeFactorX*segm->Dx();
5112 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
5114 // check if the road overlaps with bad chips
5116 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
5117 Float_t zlocmin = zloc-dz;
5118 Float_t zlocmax = zloc+dz;
5119 Float_t xlocmin = xloc-dy;
5120 Float_t xlocmax = xloc+dy;
5121 Int_t chipsInRoad[100];
5123 // check if road goes out of detector
5124 Bool_t touchNeighbourDet=kFALSE;
5125 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.5*detSizeX; touchNeighbourDet=kTRUE;}
5126 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.5*detSizeX; touchNeighbourDet=kTRUE;}
5127 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.5*detSizeZ; touchNeighbourDet=kTRUE;}
5128 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.5*detSizeZ; touchNeighbourDet=kTRUE;}
5129 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));
5131 // check if this detector is bad
5133 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
5134 if(!touchNeighbourDet) {
5135 return 2; // all detectors in road are bad
5137 return 3; // at least one is bad
5141 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
5142 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
5143 if (!nChipsInRoad) return 0;
5145 Bool_t anyBad=kFALSE,anyGood=kFALSE;
5146 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
5147 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
5148 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
5149 if (det.IsChipBad(chipsInRoad[iCh])) {
5157 if(!touchNeighbourDet) {
5158 AliDebug(2,"all bad in road");
5159 return 2; // all chips in road are bad
5161 return 3; // at least a bad chip in road
5166 AliDebug(2,"at least a bad in road");
5167 return 3; // at least a bad chip in road
5171 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
5172 || ilayer==4 || ilayer==5 // SSD
5173 || !noClusters) return 0;
5175 // There are no clusters in road: check if there is at least
5176 // a bad SPD pixel or SDD anode
5178 Int_t idetInITS=idet;
5179 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
5181 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
5182 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
5185 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
5189 //------------------------------------------------------------------------
5190 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
5191 AliITStrackMI *track,
5192 Float_t &xloc,Float_t &zloc) const {
5193 //-----------------------------------------------------------------
5194 // Gives position of track in local module ref. frame
5195 //-----------------------------------------------------------------
5200 if(idet<0) return kFALSE;
5202 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
5204 Int_t lad = Int_t(idet/ndet) + 1;
5206 Int_t det = idet - (lad-1)*ndet + 1;
5208 Double_t xyzGlob[3],xyzLoc[3];
5210 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
5211 // take into account the misalignment: xyz at real detector plane
5212 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
5214 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
5216 xloc = (Float_t)xyzLoc[0];
5217 zloc = (Float_t)xyzLoc[2];
5221 //------------------------------------------------------------------------
5222 Bool_t AliITStrackerMI::IsOKForPlaneEff(AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
5224 // Method to be optimized further:
5225 // Aim: decide whether a track can be used for PlaneEff evaluation
5226 // the decision is taken based on the track quality at the layer under study
5227 // no information on the clusters on this layer has to be used
5228 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
5229 // the cut is done on number of sigmas from the boundaries
5231 // Input: Actual track, layer [0,5] under study
5233 // Return: kTRUE if this is a good track
5235 // it will apply a pre-selection to obtain good quality tracks.
5236 // Here also you will have the possibility to put a control on the
5237 // impact point of the track on the basic block, in order to exclude border regions
5238 // this will be done by calling a proper method of the AliITSPlaneEff class.
5240 // input: AliITStrackMI* track, ilayer= layer number [0,5]
5241 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
5243 Int_t index[AliITSgeomTGeo::kNLayers];
5245 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
5247 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
5248 index[k]=clusters[k];
5252 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
5253 AliITSlayer &layer=fgLayers[ilayer];
5254 Double_t r=layer.GetR();
5255 AliITStrackMI tmp(*track);
5257 // require a minimal number of cluster in other layers and eventually clusters in closest layers
5259 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) {
5260 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
5261 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
5262 if (tmp.GetClIndex(lay)>0) ncl++;
5264 Bool_t nextout = kFALSE;
5265 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
5266 else nextout = ((tmp.GetClIndex(ilayer+1)>0)? kTRUE : kFALSE );
5267 Bool_t nextin = kFALSE;
5268 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
5269 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
5270 if(ncl<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
5272 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
5273 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
5274 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
5275 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
5279 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
5280 Int_t idet=layer.FindDetectorIndex(phi,z);
5281 if(idet<0) { AliInfo(Form("cannot find detector"));
5284 // here check if it has good Chi Square.
5286 //propagate to the intersection with the detector plane
5287 const AliITSdetector &det=layer.GetDetector(idet);
5288 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
5292 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
5293 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5294 if(key>fPlaneEff->Nblock()) return kFALSE;
5295 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
5296 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
5298 // DEFINITION OF SEARCH ROAD FOR accepting a track
5300 //For the time being they are hard-wired, later on from AliITSRecoParam
5301 // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
5302 // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
5305 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
5306 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
5307 // done for RecPoints
5309 // exclude tracks at boundary between detectors
5310 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
5311 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
5312 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
5313 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
5314 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
5316 if ( (locx-dx < blockXmn+boundaryWidth) ||
5317 (locx+dx > blockXmx-boundaryWidth) ||
5318 (locz-dz < blockZmn+boundaryWidth) ||
5319 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
5322 //------------------------------------------------------------------------
5323 void AliITStrackerMI::UseTrackForPlaneEff(AliITStrackMI* track, Int_t ilayer) {
5325 // This Method has to be optimized! For the time-being it uses the same criteria
5326 // as those used in the search of extra clusters for overlapping modules.
5328 // Method Purpose: estabilish whether a track has produced a recpoint or not
5329 // in the layer under study (For Plane efficiency)
5331 // inputs: AliITStrackMI* track (pointer to a usable track)
5333 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
5334 // traversed by this very track. In details:
5335 // - if a cluster can be associated to the track then call
5336 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
5337 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
5340 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
5341 AliITSlayer &layer=fgLayers[ilayer];
5342 Double_t r=layer.GetR();
5343 AliITStrackMI tmp(*track);
5347 if (!tmp.GetPhiZat(r,phi,z)) return;
5348 Int_t idet=layer.FindDetectorIndex(phi,z);
5350 if(idet<0) { AliInfo(Form("cannot find detector"));
5354 //propagate to the intersection with the detector plane
5355 const AliITSdetector &det=layer.GetDetector(idet);
5356 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
5360 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
5362 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
5363 TMath::Sqrt(tmp.GetSigmaZ2() +
5364 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5365 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5366 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
5367 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
5368 TMath::Sqrt(tmp.GetSigmaY2() +
5369 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5370 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5371 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
5373 // road in global (rphi,z) [i.e. in tracking ref. system]
5374 Double_t zmin = tmp.GetZ() - dz;
5375 Double_t zmax = tmp.GetZ() + dz;
5376 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
5377 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
5379 // select clusters in road
5380 layer.SelectClusters(zmin,zmax,ymin,ymax);
5382 // Define criteria for track-cluster association
5383 Double_t msz = tmp.GetSigmaZ2() +
5384 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5385 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5386 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
5387 Double_t msy = tmp.GetSigmaY2() +
5388 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5389 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5390 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
5391 if (tmp.GetConstrain()) {
5392 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
5393 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
5395 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
5396 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
5398 msz = 1./msz; // 1/RoadZ^2
5399 msy = 1./msy; // 1/RoadY^2
5402 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
5404 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
5405 //Double_t tolerance=0.2;
5406 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
5407 idetc = cl->GetDetectorIndex();
5408 if(idet!=idetc) continue;
5409 //Int_t ilay = cl->GetLayer();
5411 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
5412 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
5414 Double_t chi2=tmp.GetPredictedChi2(cl);
5415 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
5419 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
5421 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
5422 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5423 if(key>fPlaneEff->Nblock()) return;
5424 Bool_t found=kFALSE;
5427 while ((cl=layer.GetNextCluster(clidx))!=0) {
5428 idetc = cl->GetDetectorIndex();
5429 if(idet!=idetc) continue;
5430 // here real control to see whether the cluster can be associated to the track.
5431 // cluster not associated to track
5432 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
5433 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
5434 // calculate track-clusters chi2
5435 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
5436 // in particular, the error associated to the cluster
5437 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
5439 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
5441 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
5442 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
5443 // track->SetExtraModule(ilayer,idetExtra);
5445 if(!fPlaneEff->UpDatePlaneEff(found,key))
5446 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
5447 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
5448 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
5449 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
5450 Int_t cltype[2]={-999,-999};
5454 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
5455 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
5458 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
5459 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
5460 cltype[0]=layer.GetCluster(ci)->GetNy();
5461 cltype[1]=layer.GetCluster(ci)->GetNz();
5463 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
5464 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
5465 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
5466 // It is computed properly by calling the method
5467 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
5469 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
5470 //if (tmp.PropagateTo(x,0.,0.)) {
5471 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
5472 AliCluster c(*layer.GetCluster(ci));
5473 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
5474 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
5475 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
5476 clu[2]=TMath::Sqrt(c.GetSigmaY2());
5477 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
5480 fPlaneEff->FillHistos(key,found,tr,clu,cltype);