1 /**************************************************************************
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 //-------------------------------------------------------------------------
18 // Implementation of the ITS tracker class
19 // It reads AliITSRecPoint clusters and creates AliITStrackMI tracks
20 // and fills with them the ESD
21 // Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch
22 // Current support and development:
23 // Andrea Dainese, andrea.dainese@lnl.infn.it
24 // dE/dx analysis by: Boris Batyunya, JINR, Boris.Batiounia@cern.ch
25 // Params moved to AliITSRecoParam by: Andrea Dainese, INFN
26 // Material budget from TGeo by: Ludovic Gaudichet & Andrea Dainese, INFN
27 //-------------------------------------------------------------------------
31 #include <TDatabasePDG.h>
34 #include <TTreeStream.h>
37 #include "AliGeomManager.h"
38 #include "AliITSPlaneEff.h"
39 #include "AliTrackPointArray.h"
40 #include "AliESDEvent.h"
41 #include "AliESDtrack.h"
43 #include "AliITSChannelStatus.h"
44 #include "AliITSDetTypeRec.h"
45 #include "AliITSRecPoint.h"
46 #include "AliITSRecPointContainer.h"
47 #include "AliITSgeomTGeo.h"
48 #include "AliITSReconstructor.h"
49 #include "AliITSClusterParam.h"
50 #include "AliITSsegmentation.h"
51 #include "AliITSCalibration.h"
52 #include "AliITSPlaneEffSPD.h"
53 #include "AliITSPlaneEffSDD.h"
54 #include "AliITSPlaneEffSSD.h"
55 #include "AliITSV0Finder.h"
56 #include "AliITStrackerMI.h"
57 #include "AliMathBase.h"
59 ClassImp(AliITStrackerMI)
61 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
63 AliITStrackerMI::AliITStrackerMI():AliTracker(),
73 fLastLayerToTrackTo(0),
76 fTrackingPhase("Default"),
82 fxTimesRhoPipeTrks(0),
83 fxOverX0ShieldTrks(0),
84 fxTimesRhoShieldTrks(0),
86 fxTimesRhoLayerTrks(0),
93 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
94 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
95 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
98 //------------------------------------------------------------------------
99 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
100 fI(AliITSgeomTGeo::GetNLayers()),
109 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
112 fTrackingPhase("Default"),
118 fxTimesRhoPipeTrks(0),
119 fxOverX0ShieldTrks(0),
120 fxTimesRhoShieldTrks(0),
121 fxOverX0LayerTrks(0),
122 fxTimesRhoLayerTrks(0),
124 fITSChannelStatus(0),
127 //--------------------------------------------------------------------
128 //This is the AliITStrackerMI constructor
129 //--------------------------------------------------------------------
131 AliWarning("\"geom\" is actually a dummy argument !");
134 fOriginal.SetOwner();
138 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
139 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
140 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
142 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
143 AliITSgeomTGeo::GetTranslation(i,1,1,xyz);
144 Double_t poff=TMath::ATan2(y,x);
147 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
148 Double_t r=TMath::Sqrt(x*x + y*y);
150 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
151 r += TMath::Sqrt(x*x + y*y);
152 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
153 r += TMath::Sqrt(x*x + y*y);
154 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
155 r += TMath::Sqrt(x*x + y*y);
158 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
160 for (Int_t j=1; j<nlad+1; j++) {
161 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
162 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
163 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
165 Double_t txyz[3]={0.};
166 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
167 m.LocalToMaster(txyz,xyz);
168 r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
169 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
171 if (phi<0) phi+=TMath::TwoPi();
172 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
174 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
175 new(&det) AliITSdetector(r,phi);
176 // compute the real radius (with misalignment)
177 TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
179 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
180 mmisal.LocalToMaster(txyz,xyz);
181 Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
182 det.SetRmisal(rmisal);
184 } // end loop on detectors
185 } // end loop on ladders
186 fForceSkippingOfLayer[i] = 0;
187 } // end loop on layers
190 fI=AliITSgeomTGeo::GetNLayers();
193 fConstraint[0]=1; fConstraint[1]=0;
195 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
196 AliITSReconstructor::GetRecoParam()->GetYVdef(),
197 AliITSReconstructor::GetRecoParam()->GetZVdef()};
198 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
199 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
200 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
201 SetVertex(xyzVtx,ersVtx);
203 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
204 for (Int_t i=0;i<100000;i++){
205 fBestTrackIndex[i]=0;
208 // store positions of centre of SPD modules (in z)
209 // The convetion is that fSPDdetzcentre is ordered from -z to +z
211 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
212 if (tr[2]<0) { // old geom (up to v5asymmPPR)
213 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
214 fSPDdetzcentre[0] = tr[2];
215 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
216 fSPDdetzcentre[1] = tr[2];
217 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
218 fSPDdetzcentre[2] = tr[2];
219 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
220 fSPDdetzcentre[3] = tr[2];
221 } else { // new geom (from v11Hybrid)
222 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
223 fSPDdetzcentre[0] = tr[2];
224 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
225 fSPDdetzcentre[1] = tr[2];
226 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
227 fSPDdetzcentre[2] = tr[2];
228 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
229 fSPDdetzcentre[3] = tr[2];
232 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
233 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
234 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
238 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
239 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
241 if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0)
242 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
244 // only for plane efficiency evaluation
245 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
246 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
247 Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
248 if(!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)==1)
249 AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
250 if (iplane<2) fPlaneEff = new AliITSPlaneEffSPD();
251 else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
252 else fPlaneEff = new AliITSPlaneEffSSD();
253 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
254 if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
255 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
258 //------------------------------------------------------------------------
259 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
261 fBestTrack(tracker.fBestTrack),
262 fTrackToFollow(tracker.fTrackToFollow),
263 fTrackHypothesys(tracker.fTrackHypothesys),
264 fBestHypothesys(tracker.fBestHypothesys),
265 fOriginal(tracker.fOriginal),
266 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
267 fPass(tracker.fPass),
268 fAfterV0(tracker.fAfterV0),
269 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
270 fCoefficients(tracker.fCoefficients),
272 fTrackingPhase(tracker.fTrackingPhase),
273 fUseTGeo(tracker.fUseTGeo),
274 fNtracks(tracker.fNtracks),
275 fxOverX0Pipe(tracker.fxOverX0Pipe),
276 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
278 fxTimesRhoPipeTrks(0),
279 fxOverX0ShieldTrks(0),
280 fxTimesRhoShieldTrks(0),
281 fxOverX0LayerTrks(0),
282 fxTimesRhoLayerTrks(0),
283 fDebugStreamer(tracker.fDebugStreamer),
284 fITSChannelStatus(tracker.fITSChannelStatus),
285 fkDetTypeRec(tracker.fkDetTypeRec),
286 fPlaneEff(tracker.fPlaneEff) {
288 fOriginal.SetOwner();
291 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
294 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
295 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
298 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
299 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
302 //------------------------------------------------------------------------
303 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
304 //Assignment operator
305 this->~AliITStrackerMI();
306 new(this) AliITStrackerMI(tracker);
309 //------------------------------------------------------------------------
310 AliITStrackerMI::~AliITStrackerMI()
315 if (fCoefficients) delete [] fCoefficients;
316 DeleteTrksMaterialLUT();
317 if (fDebugStreamer) {
318 //fDebugStreamer->Close();
319 delete fDebugStreamer;
321 if(fITSChannelStatus) delete fITSChannelStatus;
322 if(fPlaneEff) delete fPlaneEff;
324 //------------------------------------------------------------------------
325 void AliITStrackerMI::ReadBadFromDetTypeRec() {
326 //--------------------------------------------------------------------
327 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
329 //--------------------------------------------------------------------
331 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
333 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
335 if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
338 if(fITSChannelStatus) delete fITSChannelStatus;
339 fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
341 // ITS detectors and chips
342 Int_t i=0,j=0,k=0,ndet=0;
343 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
344 Int_t nBadDetsPerLayer=0;
345 ndet=AliITSgeomTGeo::GetNDetectors(i);
346 for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
347 for (k=1; k<ndet+1; k++) {
348 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
349 det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fkDetTypeRec);
350 if(det.IsBad()) {nBadDetsPerLayer++;}
351 } // end loop on detectors
352 } // end loop on ladders
353 Info("ReadBadFromDetTypeRec",Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
354 } // end loop on layers
358 //------------------------------------------------------------------------
359 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
360 //--------------------------------------------------------------------
361 //This function loads ITS clusters
362 //--------------------------------------------------------------------
364 TClonesArray *clusters = NULL;
365 AliITSRecPointContainer* rpcont=AliITSRecPointContainer::Instance();
366 clusters=rpcont->FetchClusters(0,cTree);
367 if(!(rpcont->IsSPDActive() || rpcont->IsSDDActive() || rpcont->IsSSDActive())){
368 AliError("ITS is not in a known running configuration: SPD, SDD and SSD are not active");
371 Int_t i=0,j=0,ndet=0;
373 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
374 ndet=fgLayers[i].GetNdetectors();
375 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
376 for (; j<jmax; j++) {
377 // if (!cTree->GetEvent(j)) continue;
378 clusters = rpcont->UncheckedGetClusters(j);
379 if(!clusters)continue;
380 Int_t ncl=clusters->GetEntriesFast();
381 SignDeltas(clusters,GetZ());
384 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
385 detector=c->GetDetectorIndex();
387 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
389 Int_t retval = fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
391 AliWarning(Form("Too many clusters on layer %d!",i));
396 // add dead zone "virtual" cluster in SPD, if there is a cluster within
397 // zwindow cm from the dead zone
398 // This method assumes that fSPDdetzcentre is ordered from -z to +z
399 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
400 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
401 Int_t lab[4] = {0,0,0,detector};
402 Int_t info[3] = {0,0,i};
403 Float_t q = 0.; // this identifies virtual clusters
404 Float_t hit[5] = {xdead,
406 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
407 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
409 Bool_t local = kTRUE;
410 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
411 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
412 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
413 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
414 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
415 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
416 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
417 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
418 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
419 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
420 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
421 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
422 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
423 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
424 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
425 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
426 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
427 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
428 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
430 } // "virtual" clusters in SPD
434 fgLayers[i].ResetRoad(); //road defined by the cluster density
435 fgLayers[i].SortClusters();
438 // check whether we have to skip some layers
439 SetForceSkippingOfLayer();
443 //------------------------------------------------------------------------
444 void AliITStrackerMI::UnloadClusters() {
445 //--------------------------------------------------------------------
446 //This function unloads ITS clusters
447 //--------------------------------------------------------------------
448 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
450 //------------------------------------------------------------------------
451 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
452 //--------------------------------------------------------------------
453 // Publishes all pointers to clusters known to the tracker into the
454 // passed object array.
455 // The ownership is not transfered - the caller is not expected to delete
457 //--------------------------------------------------------------------
459 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
460 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
461 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
468 //------------------------------------------------------------------------
469 Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
470 //--------------------------------------------------------------------
471 // Correction for the material between the TPC and the ITS
472 //--------------------------------------------------------------------
473 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
474 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
475 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
476 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
477 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
478 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
479 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
480 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
482 printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
488 //------------------------------------------------------------------------
489 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
490 //--------------------------------------------------------------------
491 // This functions reconstructs ITS tracks
492 // The clusters must be already loaded !
493 //--------------------------------------------------------------------
495 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
497 fTrackingPhase="Clusters2Tracks";
499 TObjArray itsTracks(15000);
501 fEsd = event; // store pointer to the esd
503 // temporary (for cosmics)
504 if(event->GetVertex()) {
505 TString title = event->GetVertex()->GetTitle();
506 if(title.Contains("cosmics")) {
507 Double_t xyz[3]={GetX(),GetY(),GetZ()};
508 Double_t exyz[3]={0.1,0.1,0.1};
514 {/* Read ESD tracks */
515 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
516 Int_t nentr=event->GetNumberOfTracks();
518 // Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
520 AliESDtrack *esd=event->GetTrack(nentr);
521 // ---- for debugging:
522 //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); }
524 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
525 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
526 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
527 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
530 t=new AliITStrackMI(*esd);
531 } catch (const Char_t *msg) {
532 //Warning("Clusters2Tracks",msg);
536 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
537 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
540 // look at the ESD mass hypothesys !
541 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
543 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
545 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
546 //track - can be V0 according to TPC
548 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
552 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
556 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
560 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
565 t->SetReconstructed(kFALSE);
566 itsTracks.AddLast(t);
567 fOriginal.AddLast(t);
569 } /* End Read ESD tracks */
573 Int_t nentr=itsTracks.GetEntriesFast();
574 fTrackHypothesys.Expand(nentr);
575 fBestHypothesys.Expand(nentr);
576 MakeCoefficients(nentr);
577 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
579 // THE TWO TRACKING PASSES
580 for (fPass=0; fPass<2; fPass++) {
581 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
582 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
583 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
584 if (t==0) continue; //this track has been already tracked
585 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
586 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
587 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
588 if (fConstraint[fPass]) {
589 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
590 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
593 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
594 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
596 ResetTrackToFollow(*t);
599 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
602 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
604 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
605 if (!besttrack) continue;
606 besttrack->SetLabel(tpcLabel);
607 // besttrack->CookdEdx();
609 besttrack->SetFakeRatio(1.);
610 CookLabel(besttrack,0.); //For comparison only
611 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
613 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
615 t->SetReconstructed(kTRUE);
617 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
619 GetBestHypothesysMIP(itsTracks);
620 } // end loop on the two tracking passes
622 if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
623 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
628 Int_t entries = fTrackHypothesys.GetEntriesFast();
629 for (Int_t ientry=0; ientry<entries; ientry++) {
630 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
631 if (array) array->Delete();
632 delete fTrackHypothesys.RemoveAt(ientry);
635 fTrackHypothesys.Delete();
636 entries = fBestHypothesys.GetEntriesFast();
637 for (Int_t ientry=0; ientry<entries; ientry++) {
638 TObjArray * array =(TObjArray*)fBestHypothesys.UncheckedAt(ientry);
639 if (array) array->Delete();
640 delete fBestHypothesys.RemoveAt(ientry);
642 fBestHypothesys.Delete();
644 delete [] fCoefficients;
646 DeleteTrksMaterialLUT();
648 AliInfo(Form("Number of prolonged tracks: %d out of %d ESD tracks",ntrk,noesd));
650 fTrackingPhase="Default";
654 //------------------------------------------------------------------------
655 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
656 //--------------------------------------------------------------------
657 // This functions propagates reconstructed ITS tracks back
658 // The clusters must be loaded !
659 //--------------------------------------------------------------------
660 fTrackingPhase="PropagateBack";
661 Int_t nentr=event->GetNumberOfTracks();
662 // Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
665 for (Int_t i=0; i<nentr; i++) {
666 AliESDtrack *esd=event->GetTrack(i);
668 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
669 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
673 t=new AliITStrackMI(*esd);
674 } catch (const Char_t *msg) {
675 //Warning("PropagateBack",msg);
679 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
681 ResetTrackToFollow(*t);
684 // propagate to vertex [SR, GSI 17.02.2003]
685 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
686 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
687 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
688 fTrackToFollow.StartTimeIntegral();
689 // from vertex to outside pipe
690 CorrectForPipeMaterial(&fTrackToFollow,"outward");
692 // Start time integral and add distance from current position to vertex
693 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
694 fTrackToFollow.GetXYZ(xyzTrk);
696 for (Int_t icoord=0; icoord<3; icoord++) {
697 Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
700 fTrackToFollow.StartTimeIntegral();
701 fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
703 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
704 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
705 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
709 fTrackToFollow.SetLabel(t->GetLabel());
710 //fTrackToFollow.CookdEdx();
711 CookLabel(&fTrackToFollow,0.); //For comparison only
712 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
713 //UseClusters(&fTrackToFollow);
719 AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
721 fTrackingPhase="Default";
725 //------------------------------------------------------------------------
726 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
727 //--------------------------------------------------------------------
728 // This functions refits ITS tracks using the
729 // "inward propagated" TPC tracks
730 // The clusters must be loaded !
731 //--------------------------------------------------------------------
732 fTrackingPhase="RefitInward";
734 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
736 Int_t nentr=event->GetNumberOfTracks();
737 // Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
740 for (Int_t i=0; i<nentr; i++) {
741 AliESDtrack *esd=event->GetTrack(i);
743 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
744 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
745 if (esd->GetStatus()&AliESDtrack::kTPCout)
746 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
750 t=new AliITStrackMI(*esd);
751 } catch (const Char_t *msg) {
752 //Warning("RefitInward",msg);
756 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
757 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
762 ResetTrackToFollow(*t);
763 fTrackToFollow.ResetClusters();
765 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
766 fTrackToFollow.ResetCovariance(10.);
769 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
770 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
772 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
773 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
774 AliDebug(2," refit OK");
775 fTrackToFollow.SetLabel(t->GetLabel());
776 // fTrackToFollow.CookdEdx();
777 CookdEdx(&fTrackToFollow);
779 CookLabel(&fTrackToFollow,0.0); //For comparison only
782 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
783 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
784 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
785 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
786 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
787 Double_t r[3]={0.,0.,0.};
789 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
796 AliInfo(Form("Number of refitted tracks: %d out of %d ESD tracks",ntrk,nentr));
798 fTrackingPhase="Default";
802 //------------------------------------------------------------------------
803 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
804 //--------------------------------------------------------------------
805 // Return pointer to a given cluster
806 //--------------------------------------------------------------------
807 Int_t l=(index & 0xf0000000) >> 28;
808 Int_t c=(index & 0x0fffffff) >> 00;
809 return fgLayers[l].GetCluster(c);
811 //------------------------------------------------------------------------
812 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
813 //--------------------------------------------------------------------
814 // Get track space point with index i
815 //--------------------------------------------------------------------
817 Int_t l=(index & 0xf0000000) >> 28;
818 Int_t c=(index & 0x0fffffff) >> 00;
819 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
820 Int_t idet = cl->GetDetectorIndex();
824 cl->GetGlobalXYZ(xyz);
825 cl->GetGlobalCov(cov);
827 p.SetCharge(cl->GetQ());
828 p.SetDriftTime(cl->GetDriftTime());
829 p.SetChargeRatio(cl->GetChargeRatio());
830 p.SetClusterType(cl->GetClusterType());
831 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
834 iLayer = AliGeomManager::kSPD1;
837 iLayer = AliGeomManager::kSPD2;
840 iLayer = AliGeomManager::kSDD1;
843 iLayer = AliGeomManager::kSDD2;
846 iLayer = AliGeomManager::kSSD1;
849 iLayer = AliGeomManager::kSSD2;
852 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
855 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
856 p.SetVolumeID((UShort_t)volid);
859 //------------------------------------------------------------------------
860 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
861 AliTrackPoint& p, const AliESDtrack *t) {
862 //--------------------------------------------------------------------
863 // Get track space point with index i
864 // (assign error estimated during the tracking)
865 //--------------------------------------------------------------------
867 Int_t l=(index & 0xf0000000) >> 28;
868 Int_t c=(index & 0x0fffffff) >> 00;
869 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
870 Int_t idet = cl->GetDetectorIndex();
872 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
874 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
876 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
877 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
878 Double_t alpha = t->GetAlpha();
879 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
880 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe+cl->GetX(),GetBz()));
881 phi += alpha-det.GetPhi();
882 Float_t tgphi = TMath::Tan(phi);
884 Float_t tgl = t->GetTgl(); // tgl about const along track
885 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
887 Float_t errtrky,errtrkz,covyz;
888 Bool_t addMisalErr=kFALSE;
889 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
893 cl->GetGlobalXYZ(xyz);
894 // cl->GetGlobalCov(cov);
895 Float_t pos[3] = {0.,0.,0.};
896 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
897 tmpcl.GetGlobalCov(cov);
900 p.SetCharge(cl->GetQ());
901 p.SetDriftTime(cl->GetDriftTime());
902 p.SetChargeRatio(cl->GetChargeRatio());
903 p.SetClusterType(cl->GetClusterType());
905 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
908 iLayer = AliGeomManager::kSPD1;
911 iLayer = AliGeomManager::kSPD2;
914 iLayer = AliGeomManager::kSDD1;
917 iLayer = AliGeomManager::kSDD2;
920 iLayer = AliGeomManager::kSSD1;
923 iLayer = AliGeomManager::kSSD2;
926 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
929 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
931 p.SetVolumeID((UShort_t)volid);
934 //------------------------------------------------------------------------
935 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
937 //--------------------------------------------------------------------
938 // Follow prolongation tree
939 //--------------------------------------------------------------------
941 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
942 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
945 AliESDtrack * esd = otrack->GetESDtrack();
946 if (esd->GetV0Index(0)>0) {
947 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
948 // mapping of ESD track is different as ITS track in Containers
949 // Need something more stable
950 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
951 for (Int_t i=0;i<3;i++){
952 Int_t index = esd->GetV0Index(i);
954 AliESDv0 * vertex = fEsd->GetV0(index);
955 if (vertex->GetStatus()<0) continue; // rejected V0
957 if (esd->GetSign()>0) {
958 vertex->SetIndex(0,esdindex);
960 vertex->SetIndex(1,esdindex);
964 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
966 bestarray = new TObjArray(5);
967 bestarray->SetOwner();
968 fBestHypothesys.AddAt(bestarray,esdindex);
972 //setup tree of the prolongations
974 static AliITStrackMI tracks[7][100];
975 AliITStrackMI *currenttrack;
976 static AliITStrackMI currenttrack1;
977 static AliITStrackMI currenttrack2;
978 static AliITStrackMI backuptrack;
980 Int_t nindexes[7][100];
981 Float_t normalizedchi2[100];
982 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
983 otrack->SetNSkipped(0);
984 new (&(tracks[6][0])) AliITStrackMI(*otrack);
986 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
987 Int_t modstatus = 1; // found
991 // follow prolongations
992 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
993 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
996 AliITSlayer &layer=fgLayers[ilayer];
997 Double_t r = layer.GetR();
1003 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
1005 if (ntracks[ilayer]>=100) break;
1006 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
1007 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
1008 if (ntracks[ilayer]>15+ilayer){
1009 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
1010 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
1013 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
1015 // material between SSD and SDD, SDD and SPD
1017 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
1019 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
1023 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
1024 Int_t idet=layer.FindDetectorIndex(phi,z);
1026 Double_t trackGlobXYZ1[3];
1027 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1029 // Get the budget to the primary vertex for the current track being prolonged
1030 Double_t budgetToPrimVertex = GetEffectiveThickness();
1032 // check if we allow a prolongation without point
1033 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1035 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1036 // propagate to the layer radius
1037 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1038 if(!vtrack->Propagate(xToGo)) continue;
1039 // apply correction for material of the current layer
1040 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1041 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1042 vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1043 vtrack->SetClIndex(ilayer,-1);
1044 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1045 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1046 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1048 if(constrain && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1053 // track outside layer acceptance in z
1054 if (idet<0) continue;
1056 //propagate to the intersection with the detector plane
1057 const AliITSdetector &det=layer.GetDetector(idet);
1058 new(¤ttrack2) AliITStrackMI(currenttrack1);
1059 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1060 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1061 currenttrack1.SetDetectorIndex(idet);
1062 currenttrack2.SetDetectorIndex(idet);
1063 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1066 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1068 // road in global (rphi,z) [i.e. in tracking ref. system]
1069 Double_t zmin,zmax,ymin,ymax;
1070 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1072 // select clusters in road
1073 layer.SelectClusters(zmin,zmax,ymin,ymax);
1074 //********************
1076 // Define criteria for track-cluster association
1077 Double_t msz = currenttrack1.GetSigmaZ2() +
1078 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1079 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1080 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1081 Double_t msy = currenttrack1.GetSigmaY2() +
1082 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1083 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1084 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1086 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1087 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1089 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1090 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1092 msz = 1./msz; // 1/RoadZ^2
1093 msy = 1./msy; // 1/RoadY^2
1097 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1099 const AliITSRecPoint *cl=0;
1101 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1102 Bool_t deadzoneSPD=kFALSE;
1103 currenttrack = ¤ttrack1;
1105 // check if the road contains a dead zone
1106 Bool_t noClusters = kFALSE;
1107 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1108 if (noClusters) AliDebug(2,"no clusters in road");
1109 Double_t dz=0.5*(zmax-zmin);
1110 Double_t dy=0.5*(ymax-ymin);
1111 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1112 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1113 // create a prolongation without clusters (check also if there are no clusters in the road)
1116 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1117 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1118 updatetrack->SetClIndex(ilayer,-1);
1120 modstatus = 5; // no cls in road
1121 } else if (dead==1) {
1122 modstatus = 7; // holes in z in SPD
1123 } else if (dead==2 || dead==3 || dead==4) {
1124 modstatus = 2; // dead from OCDB
1126 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1127 // apply correction for material of the current layer
1128 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1129 if (constrain) { // apply vertex constrain
1130 updatetrack->SetConstrain(constrain);
1131 Bool_t isPrim = kTRUE;
1132 if (ilayer<4) { // check that it's close to the vertex
1133 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1134 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1135 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1136 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1137 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1139 if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1141 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1143 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1144 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1146 } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1147 updatetrack->SetDeadZoneProbability(ilayer,1.);
1148 } else if (dead==4) { // at least a single dead channel from OCDB
1149 updatetrack->SetDeadZoneProbability(ilayer,0.);
1156 // loop over clusters in the road
1157 while ((cl=layer.GetNextCluster(clidx))!=0) {
1158 if (ntracks[ilayer]>95) break; //space for skipped clusters
1159 Bool_t changedet =kFALSE;
1160 if (TMath::Abs(cl->GetQ())<1.e-13 && deadzoneSPD==kTRUE) continue;
1161 Int_t idetc=cl->GetDetectorIndex();
1163 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1164 // take into account misalignment (bring track to real detector plane)
1165 Double_t xTrOrig = currenttrack->GetX();
1166 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1167 // a first cut on track-cluster distance
1168 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1169 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1170 { // cluster not associated to track
1171 AliDebug(2,"not associated");
1172 // MvL: added here as well
1173 // bring track back to ideal detector plane
1174 currenttrack->Propagate(xTrOrig);
1177 // bring track back to ideal detector plane
1178 if (!currenttrack->Propagate(xTrOrig)) continue;
1179 } else { // have to move track to cluster's detector
1180 const AliITSdetector &detc=layer.GetDetector(idetc);
1181 // a first cut on track-cluster distance
1183 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1184 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1185 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1186 continue; // cluster not associated to track
1188 new (&backuptrack) AliITStrackMI(currenttrack2);
1190 currenttrack =¤ttrack2;
1191 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1192 new (currenttrack) AliITStrackMI(backuptrack);
1196 currenttrack->SetDetectorIndex(idetc);
1197 // Get again the budget to the primary vertex
1198 // for the current track being prolonged, if had to change detector
1199 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1202 // calculate track-clusters chi2
1203 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1205 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1206 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1207 if (TMath::Abs(cl->GetQ())<1.e-13) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1208 if (ntracks[ilayer]>=100) continue;
1209 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1210 updatetrack->SetClIndex(ilayer,-1);
1211 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1213 if (TMath::Abs(cl->GetQ())>1.e-13) { // real cluster
1214 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1215 AliDebug(2,"update failed");
1218 updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1219 modstatus = 1; // found
1220 } else { // virtual cluster in dead zone
1221 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1222 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1223 modstatus = 7; // holes in z in SPD
1227 Float_t xlocnewdet,zlocnewdet;
1228 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1229 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1232 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1234 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1236 // apply correction for material of the current layer
1237 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1239 if (constrain) { // apply vertex constrain
1240 updatetrack->SetConstrain(constrain);
1241 Bool_t isPrim = kTRUE;
1242 if (ilayer<4) { // check that it's close to the vertex
1243 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1244 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1245 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1246 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1247 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1249 if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1250 } //apply vertex constrain
1252 } // create new hypothesis
1254 AliDebug(2,"chi2 too large");
1257 } // loop over possible prolongations
1259 // allow one prolongation without clusters
1260 if (constrain && itrack<=1 && TMath::Abs(currenttrack1.GetNSkipped())<1.e-13 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1261 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1262 // apply correction for material of the current layer
1263 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1264 vtrack->SetClIndex(ilayer,-1);
1265 modstatus = 3; // skipped
1266 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1267 if(AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1268 vtrack->IncrementNSkipped();
1273 } // loop over tracks in layer ilayer+1
1275 //loop over track candidates for the current layer
1281 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1282 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1283 if (normalizedchi2[itrack] <
1284 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1288 if (constrain) { // constrain
1289 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1291 } else { // !constrain
1292 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1297 // sort tracks by increasing normalized chi2
1298 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1299 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1300 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1301 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1302 } // end loop over layers
1306 // Now select tracks to be kept
1308 Int_t max = constrain ? 20 : 5;
1310 // tracks that reach layer 0 (SPD inner)
1311 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1312 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1313 if (track.GetNumberOfClusters()<2) continue;
1314 if (!constrain && track.GetNormChi2(0) >
1315 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1318 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1321 // tracks that reach layer 1 (SPD outer)
1322 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1323 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1324 if (track.GetNumberOfClusters()<4) continue;
1325 if (!constrain && track.GetNormChi2(1) >
1326 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1327 if (constrain) track.IncrementNSkipped();
1329 track.SetD(0,track.GetD(GetX(),GetY()));
1330 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1331 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1332 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1335 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1338 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1340 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1341 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1342 if (track.GetNumberOfClusters()<3) continue;
1343 if (!constrain && track.GetNormChi2(2) >
1344 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1345 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1347 track.SetD(0,track.GetD(GetX(),GetY()));
1348 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1349 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1350 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1353 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1359 // register best track of each layer - important for V0 finder
1361 for (Int_t ilayer=0;ilayer<5;ilayer++){
1362 if (ntracks[ilayer]==0) continue;
1363 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1364 if (track.GetNumberOfClusters()<1) continue;
1365 CookLabel(&track,0);
1366 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1370 // update TPC V0 information
1372 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1373 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1374 for (Int_t i=0;i<3;i++){
1375 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1376 if (index==0) break;
1377 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1378 if (vertex->GetStatus()<0) continue; // rejected V0
1380 if (otrack->GetSign()>0) {
1381 vertex->SetIndex(0,esdindex);
1384 vertex->SetIndex(1,esdindex);
1386 //find nearest layer with track info
1387 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1388 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1389 Int_t nearest = nearestold;
1390 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1391 if (ntracks[nearest]==0){
1396 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1397 if (nearestold<5&&nearest<5){
1398 Bool_t accept = track.GetNormChi2(nearest)<10;
1400 if (track.GetSign()>0) {
1401 vertex->SetParamP(track);
1402 vertex->Update(fprimvertex);
1403 //vertex->SetIndex(0,track.fESDtrack->GetID());
1404 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1406 vertex->SetParamN(track);
1407 vertex->Update(fprimvertex);
1408 //vertex->SetIndex(1,track.fESDtrack->GetID());
1409 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1411 vertex->SetStatus(vertex->GetStatus()+1);
1413 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1420 //------------------------------------------------------------------------
1421 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1423 //--------------------------------------------------------------------
1426 return fgLayers[layer];
1428 //------------------------------------------------------------------------
1429 AliITStrackerMI::AliITSlayer::AliITSlayer():
1459 //--------------------------------------------------------------------
1460 //default AliITSlayer constructor
1461 //--------------------------------------------------------------------
1462 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1463 fClusterWeight[i]=0;
1464 fClusterTracks[0][i]=-1;
1465 fClusterTracks[1][i]=-1;
1466 fClusterTracks[2][i]=-1;
1467 fClusterTracks[3][i]=-1;
1470 //------------------------------------------------------------------------
1471 AliITStrackerMI::AliITSlayer::
1472 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1501 //--------------------------------------------------------------------
1502 //main AliITSlayer constructor
1503 //--------------------------------------------------------------------
1504 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1505 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1507 //------------------------------------------------------------------------
1508 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1510 fPhiOffset(layer.fPhiOffset),
1511 fNladders(layer.fNladders),
1512 fZOffset(layer.fZOffset),
1513 fNdetectors(layer.fNdetectors),
1514 fDetectors(layer.fDetectors),
1519 fClustersCs(layer.fClustersCs),
1520 fClusterIndexCs(layer.fClusterIndexCs),
1524 fCurrentSlice(layer.fCurrentSlice),
1532 fAccepted(layer.fAccepted),
1534 fMaxSigmaClY(layer.fMaxSigmaClY),
1535 fMaxSigmaClZ(layer.fMaxSigmaClZ),
1536 fNMaxSigmaCl(layer.fNMaxSigmaCl)
1540 //------------------------------------------------------------------------
1541 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1542 //--------------------------------------------------------------------
1543 // AliITSlayer destructor
1544 //--------------------------------------------------------------------
1545 delete [] fDetectors;
1546 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1547 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1548 fClusterWeight[i]=0;
1549 fClusterTracks[0][i]=-1;
1550 fClusterTracks[1][i]=-1;
1551 fClusterTracks[2][i]=-1;
1552 fClusterTracks[3][i]=-1;
1555 //------------------------------------------------------------------------
1556 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1557 //--------------------------------------------------------------------
1558 // This function removes loaded clusters
1559 //--------------------------------------------------------------------
1560 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1561 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1562 fClusterWeight[i]=0;
1563 fClusterTracks[0][i]=-1;
1564 fClusterTracks[1][i]=-1;
1565 fClusterTracks[2][i]=-1;
1566 fClusterTracks[3][i]=-1;
1572 //------------------------------------------------------------------------
1573 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1574 //--------------------------------------------------------------------
1575 // This function reset weights of the clusters
1576 //--------------------------------------------------------------------
1577 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1578 fClusterWeight[i]=0;
1579 fClusterTracks[0][i]=-1;
1580 fClusterTracks[1][i]=-1;
1581 fClusterTracks[2][i]=-1;
1582 fClusterTracks[3][i]=-1;
1584 for (Int_t i=0; i<fN;i++) {
1585 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1586 if (cl&&cl->IsUsed()) cl->Use();
1590 //------------------------------------------------------------------------
1591 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1592 //--------------------------------------------------------------------
1593 // This function calculates the road defined by the cluster density
1594 //--------------------------------------------------------------------
1596 for (Int_t i=0; i<fN; i++) {
1597 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1599 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1601 //------------------------------------------------------------------------
1602 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1603 //--------------------------------------------------------------------
1604 //This function adds a cluster to this layer
1605 //--------------------------------------------------------------------
1606 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1612 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1614 Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
1615 Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2());
1616 if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
1617 if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
1618 if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
1619 if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
1622 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1623 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1624 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1625 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1629 //------------------------------------------------------------------------
1630 void AliITStrackerMI::AliITSlayer::SortClusters()
1635 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1636 Float_t *z = new Float_t[fN];
1637 Int_t * index = new Int_t[fN];
1639 fMaxSigmaClY=0.; //AD
1640 fMaxSigmaClZ=0.; //AD
1642 for (Int_t i=0;i<fN;i++){
1643 z[i] = fClusters[i]->GetZ();
1644 // save largest errors in y and z for this layer
1645 fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
1646 fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
1648 TMath::Sort(fN,z,index,kFALSE);
1649 for (Int_t i=0;i<fN;i++){
1650 clusters[i] = fClusters[index[i]];
1653 for (Int_t i=0;i<fN;i++){
1654 fClusters[i] = clusters[i];
1655 fZ[i] = fClusters[i]->GetZ();
1656 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1657 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1658 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1668 for (Int_t i=0;i<fN;i++){
1669 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1670 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1671 fClusterIndex[i] = i;
1675 fDy5 = (fYB[1]-fYB[0])/5.;
1676 fDy10 = (fYB[1]-fYB[0])/10.;
1677 fDy20 = (fYB[1]-fYB[0])/20.;
1678 for (Int_t i=0;i<6;i++) fN5[i] =0;
1679 for (Int_t i=0;i<11;i++) fN10[i]=0;
1680 for (Int_t i=0;i<21;i++) fN20[i]=0;
1682 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;}
1683 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;}
1684 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;}
1687 for (Int_t i=0;i<fN;i++)
1688 for (Int_t irot=-1;irot<=1;irot++){
1689 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1691 for (Int_t slice=0; slice<6;slice++){
1692 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1693 fClusters5[slice][fN5[slice]] = fClusters[i];
1694 fY5[slice][fN5[slice]] = curY;
1695 fZ5[slice][fN5[slice]] = fZ[i];
1696 fClusterIndex5[slice][fN5[slice]]=i;
1701 for (Int_t slice=0; slice<11;slice++){
1702 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1703 fClusters10[slice][fN10[slice]] = fClusters[i];
1704 fY10[slice][fN10[slice]] = curY;
1705 fZ10[slice][fN10[slice]] = fZ[i];
1706 fClusterIndex10[slice][fN10[slice]]=i;
1711 for (Int_t slice=0; slice<21;slice++){
1712 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1713 fClusters20[slice][fN20[slice]] = fClusters[i];
1714 fY20[slice][fN20[slice]] = curY;
1715 fZ20[slice][fN20[slice]] = fZ[i];
1716 fClusterIndex20[slice][fN20[slice]]=i;
1723 // consistency check
1725 for (Int_t i=0;i<fN-1;i++){
1731 for (Int_t slice=0;slice<21;slice++)
1732 for (Int_t i=0;i<fN20[slice]-1;i++){
1733 if (fZ20[slice][i]>fZ20[slice][i+1]){
1740 //------------------------------------------------------------------------
1741 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1742 //--------------------------------------------------------------------
1743 // This function returns the index of the nearest cluster
1744 //--------------------------------------------------------------------
1747 if (fCurrentSlice<0) {
1756 if (ncl==0) return 0;
1757 Int_t b=0, e=ncl-1, m=(b+e)/2;
1758 for (; b<e; m=(b+e)/2) {
1759 // if (z > fClusters[m]->GetZ()) b=m+1;
1760 if (z > zcl[m]) b=m+1;
1765 //------------------------------------------------------------------------
1766 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 {
1767 //--------------------------------------------------------------------
1768 // This function computes the rectangular road for this track
1769 //--------------------------------------------------------------------
1772 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1773 // take into account the misalignment: propagate track to misaligned detector plane
1774 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1776 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1777 TMath::Sqrt(track->GetSigmaZ2() +
1778 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1779 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1780 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1781 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1782 TMath::Sqrt(track->GetSigmaY2() +
1783 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1784 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1785 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1787 // track at boundary between detectors, enlarge road
1788 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1789 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1790 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1791 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1792 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1793 Float_t tgl = TMath::Abs(track->GetTgl());
1794 if (tgl > 1.) tgl=1.;
1795 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1796 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1797 Float_t snp = TMath::Abs(track->GetSnp());
1798 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1799 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1802 // add to the road a term (up to 2-3 mm) to deal with misalignments
1803 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1804 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1806 Double_t r = fgLayers[ilayer].GetR();
1807 zmin = track->GetZ() - dz;
1808 zmax = track->GetZ() + dz;
1809 ymin = track->GetY() + r*det.GetPhi() - dy;
1810 ymax = track->GetY() + r*det.GetPhi() + dy;
1812 // bring track back to idead detector plane
1813 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1817 //------------------------------------------------------------------------
1818 void AliITStrackerMI::AliITSlayer::
1819 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1820 //--------------------------------------------------------------------
1821 // This function sets the "window"
1822 //--------------------------------------------------------------------
1824 Double_t circle=2*TMath::Pi()*fR;
1830 // enlarge road in y by maximum cluster error on this layer (3 sigma)
1831 fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
1832 fYmax += fNMaxSigmaCl*fMaxSigmaClY;
1833 fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
1834 fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
1836 Float_t ymiddle = (fYmin+fYmax)*0.5;
1837 if (ymiddle<fYB[0]) {
1838 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1839 } else if (ymiddle>fYB[1]) {
1840 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1846 fClustersCs = fClusters;
1847 fClusterIndexCs = fClusterIndex;
1853 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1854 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1855 if (slice<0) slice=0;
1856 if (slice>20) slice=20;
1857 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1859 fCurrentSlice=slice;
1860 fClustersCs = fClusters20[fCurrentSlice];
1861 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1862 fYcs = fY20[fCurrentSlice];
1863 fZcs = fZ20[fCurrentSlice];
1864 fNcs = fN20[fCurrentSlice];
1869 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1870 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1871 if (slice<0) slice=0;
1872 if (slice>10) slice=10;
1873 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1875 fCurrentSlice=slice;
1876 fClustersCs = fClusters10[fCurrentSlice];
1877 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1878 fYcs = fY10[fCurrentSlice];
1879 fZcs = fZ10[fCurrentSlice];
1880 fNcs = fN10[fCurrentSlice];
1885 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1886 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1887 if (slice<0) slice=0;
1888 if (slice>5) slice=5;
1889 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1891 fCurrentSlice=slice;
1892 fClustersCs = fClusters5[fCurrentSlice];
1893 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1894 fYcs = fY5[fCurrentSlice];
1895 fZcs = fZ5[fCurrentSlice];
1896 fNcs = fN5[fCurrentSlice];
1900 fI = FindClusterIndex(fZmin);
1901 fImax = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
1907 //------------------------------------------------------------------------
1908 Int_t AliITStrackerMI::AliITSlayer::
1909 FindDetectorIndex(Double_t phi, Double_t z) const {
1910 //--------------------------------------------------------------------
1911 //This function finds the detector crossed by the track
1912 //--------------------------------------------------------------------
1914 if (fZOffset<0) // old geometry
1915 dphi = -(phi-fPhiOffset);
1916 else // new geometry
1917 dphi = phi-fPhiOffset;
1920 if (dphi < 0) dphi += 2*TMath::Pi();
1921 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1922 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1923 if (np>=fNladders) np-=fNladders;
1924 if (np<0) np+=fNladders;
1927 Double_t dz=fZOffset-z;
1928 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1929 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1930 if (nz>=fNdetectors || nz<0) {
1931 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1935 // ad hoc correction for 3rd ladder of SDD inner layer,
1936 // which is reversed (rotated by pi around local y)
1937 // this correction is OK only from AliITSv11Hybrid onwards
1938 if (GetR()>12. && GetR()<20.) { // SDD inner
1939 if(np==2) { // 3rd ladder
1940 Double_t posMod252[3];
1941 AliITSgeomTGeo::GetTranslation(252,posMod252);
1942 // check the Z coordinate of Mod 252: if negative
1943 // (old SDD geometry in AliITSv11Hybrid)
1944 // the swap of numeration whould be applied
1945 if(posMod252[2]<0.){
1946 nz = (fNdetectors-1) - nz;
1950 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1953 return np*fNdetectors + nz;
1955 //------------------------------------------------------------------------
1956 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1958 //--------------------------------------------------------------------
1959 // This function returns clusters within the "window"
1960 //--------------------------------------------------------------------
1962 if (fCurrentSlice<0) {
1963 Double_t rpi2 = 2.*fR*TMath::Pi();
1964 for (Int_t i=fI; i<fImax; i++) {
1967 if (fYmax<y) y -= rpi2;
1968 if (fYmin>y) y += rpi2;
1969 if (y<fYmin) continue;
1970 if (y>fYmax) continue;
1972 // skip clusters that are in "extended" road but they
1973 // 3sigma error does not touch the original road
1974 if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
1975 if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
1977 if (TMath::Abs(fClusters[i]->GetQ())<1.e-13 && fSkip==2) continue;
1980 return fClusters[i];
1983 for (Int_t i=fI; i<fImax; i++) {
1984 if (fYcs[i]<fYmin) continue;
1985 if (fYcs[i]>fYmax) continue;
1986 if (TMath::Abs(fClustersCs[i]->GetQ())<1.e-13 && fSkip==2) continue;
1987 ci=fClusterIndexCs[i];
1989 return fClustersCs[i];
1994 //------------------------------------------------------------------------
1995 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1997 //--------------------------------------------------------------------
1998 // This function returns the layer thickness at this point (units X0)
1999 //--------------------------------------------------------------------
2001 x0=AliITSRecoParam::GetX0Air();
2002 if (43<fR&&fR<45) { //SSD2
2005 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2006 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2007 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2008 for (Int_t i=0; i<12; i++) {
2009 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
2010 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2014 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
2015 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2019 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2020 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2023 if (37<fR&&fR<41) { //SSD1
2026 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2027 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2028 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2029 for (Int_t i=0; i<11; i++) {
2030 if (TMath::Abs(z-3.9*i)<0.15) {
2031 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2035 if (TMath::Abs(z+3.9*i)<0.15) {
2036 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2040 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2041 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2044 if (13<fR&&fR<26) { //SDD
2047 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2049 if (TMath::Abs(y-1.80)<0.55) {
2051 for (Int_t j=0; j<20; j++) {
2052 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2053 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2056 if (TMath::Abs(y+1.80)<0.55) {
2058 for (Int_t j=0; j<20; j++) {
2059 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2060 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2064 for (Int_t i=0; i<4; i++) {
2065 if (TMath::Abs(z-7.3*i)<0.60) {
2067 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2070 if (TMath::Abs(z+7.3*i)<0.60) {
2072 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2077 if (6<fR&&fR<8) { //SPD2
2078 Double_t dd=0.0063; x0=21.5;
2080 if (TMath::Abs(y-3.08)>0.5) d+=dd;
2081 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2083 if (3<fR&&fR<5) { //SPD1
2084 Double_t dd=0.0063; x0=21.5;
2086 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2087 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2092 //------------------------------------------------------------------------
2093 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2095 fRmisal(det.fRmisal),
2097 fSinPhi(det.fSinPhi),
2098 fCosPhi(det.fCosPhi),
2104 fNChips(det.fNChips),
2105 fChipIsBad(det.fChipIsBad)
2109 //------------------------------------------------------------------------
2110 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2111 const AliITSDetTypeRec *detTypeRec)
2113 //--------------------------------------------------------------------
2114 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2115 //--------------------------------------------------------------------
2117 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2118 // while in the tracker they start from 0 for each layer
2119 for(Int_t il=0; il<ilayer; il++)
2120 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2123 if (ilayer==0 || ilayer==1) { // ---------- SPD
2125 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2127 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2130 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2134 // Get calibration from AliITSDetTypeRec
2135 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2136 calib->SetModuleIndex(idet);
2137 AliITSCalibration *calibSPDdead = 0;
2138 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2139 if (calib->IsBad() ||
2140 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2143 // printf("lay %d bad %d\n",ilayer,idet);
2146 // Get segmentation from AliITSDetTypeRec
2147 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2149 // Read info about bad chips
2150 fNChips = segm->GetMaximumChipIndex()+1;
2151 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2152 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2153 fChipIsBad = new Bool_t[fNChips];
2154 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2155 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2156 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2157 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2162 //------------------------------------------------------------------------
2163 Double_t AliITStrackerMI::GetEffectiveThickness()
2165 //--------------------------------------------------------------------
2166 // Returns the thickness between the current layer and the vertex (units X0)
2167 //--------------------------------------------------------------------
2170 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2171 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2172 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2176 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2177 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2181 Double_t xn=fgLayers[fI].GetR();
2182 for (Int_t i=0; i<fI; i++) {
2183 Double_t xi=fgLayers[i].GetR();
2184 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2190 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2191 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2194 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2195 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2199 //------------------------------------------------------------------------
2200 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2201 //-------------------------------------------------------------------
2202 // This function returns number of clusters within the "window"
2203 //--------------------------------------------------------------------
2205 for (Int_t i=fI; i<fN; i++) {
2206 const AliITSRecPoint *c=fClusters[i];
2207 if (c->GetZ() > fZmax) break;
2208 if (c->IsUsed()) continue;
2209 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2210 Double_t y=fR*det.GetPhi() + c->GetY();
2212 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2213 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2215 if (y<fYmin) continue;
2216 if (y>fYmax) continue;
2221 //------------------------------------------------------------------------
2222 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2223 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2225 //--------------------------------------------------------------------
2226 // This function refits the track "track" at the position "x" using
2227 // the clusters from "clusters"
2228 // If "extra"==kTRUE,
2229 // the clusters from overlapped modules get attached to "track"
2230 // If "planeff"==kTRUE,
2231 // special approach for plane efficiency evaluation is applyed
2232 //--------------------------------------------------------------------
2234 Int_t index[AliITSgeomTGeo::kNLayers];
2236 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2237 Int_t nc=clusters->GetNumberOfClusters();
2238 for (k=0; k<nc; k++) {
2239 Int_t idx=clusters->GetClusterIndex(k);
2240 Int_t ilayer=(idx&0xf0000000)>>28;
2244 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2246 //------------------------------------------------------------------------
2247 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2248 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2250 //--------------------------------------------------------------------
2251 // This function refits the track "track" at the position "x" using
2252 // the clusters from array
2253 // If "extra"==kTRUE,
2254 // the clusters from overlapped modules get attached to "track"
2255 // If "planeff"==kTRUE,
2256 // special approach for plane efficiency evaluation is applyed
2257 //--------------------------------------------------------------------
2258 Int_t index[AliITSgeomTGeo::kNLayers];
2260 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2262 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2263 index[k]=clusters[k];
2266 // special for cosmics and TPC prolonged tracks:
2267 // propagate to the innermost of:
2268 // - innermost layer crossed by the track
2269 // - innermost layer where a cluster was associated to the track
2270 static AliITSRecoParam *repa = NULL;
2272 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
2274 repa = AliITSRecoParam::GetHighFluxParam();
2275 AliWarning("Using default AliITSRecoParam class");
2278 Int_t evsp=repa->GetEventSpecie();
2280 if(track->GetESDtrack()) trStatus=track->GetStatus();
2281 Int_t innermostlayer=0;
2282 if((evsp&AliRecoParam::kCosmic) || (trStatus&AliESDtrack::kTPCin)) {
2284 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2285 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2286 if( (drphi < (fgLayers[innermostlayer].GetR()+1.)) ||
2287 index[innermostlayer] >= 0 ) break;
2290 AliDebug(2,Form(" drphi %f innermost %d",drphi,innermostlayer));
2293 Int_t modstatus=1; // found
2295 Int_t from, to, step;
2296 if (xx > track->GetX()) {
2297 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2300 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2303 TString dir = (step>0 ? "outward" : "inward");
2305 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2306 AliITSlayer &layer=fgLayers[ilayer];
2307 Double_t r=layer.GetR();
2309 if (step<0 && xx>r) break;
2311 // material between SSD and SDD, SDD and SPD
2312 Double_t hI=ilayer-0.5*step;
2313 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2314 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2315 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2316 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2319 Double_t oldGlobXYZ[3];
2320 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2322 // continue if we are already beyond this layer
2323 Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2324 if(step>0 && oldGlobR > r) continue; // going outward
2325 if(step<0 && oldGlobR < r) continue; // going inward
2328 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2330 Int_t idet=layer.FindDetectorIndex(phi,z);
2332 // check if we allow a prolongation without point for large-eta tracks
2333 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2335 modstatus = 4; // out in z
2336 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2337 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2340 // apply correction for material of the current layer
2341 // add time if going outward
2342 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2346 if (idet<0) return kFALSE;
2349 const AliITSdetector &det=layer.GetDetector(idet);
2350 // only for ITS-SA tracks refit
2351 if (ilayer>1 && fTrackingPhase.Contains("RefitInward") && !(track->GetStatus()&AliESDtrack::kTPCin)) track->SetCheckInvariant(kFALSE);
2353 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2355 track->SetDetectorIndex(idet);
2356 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2358 Double_t dz,zmin,zmax,dy,ymin,ymax;
2360 const AliITSRecPoint *clAcc=0;
2361 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2363 Int_t idx=index[ilayer];
2364 if (idx>=0) { // cluster in this layer
2365 modstatus = 6; // no refit
2366 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2368 if (idet != cl->GetDetectorIndex()) {
2369 idet=cl->GetDetectorIndex();
2370 const AliITSdetector &detc=layer.GetDetector(idet);
2371 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2372 track->SetDetectorIndex(idet);
2373 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2375 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2376 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2380 modstatus = 1; // found
2385 } else { // no cluster in this layer
2387 modstatus = 3; // skipped
2388 // Plane Eff determination:
2389 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2390 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2391 UseTrackForPlaneEff(track,ilayer);
2394 modstatus = 5; // no cls in road
2396 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2397 dz = 0.5*(zmax-zmin);
2398 dy = 0.5*(ymax-ymin);
2399 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2400 if (dead==1) modstatus = 7; // holes in z in SPD
2401 if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2406 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2407 track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2409 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2412 if (extra) { // search for extra clusters in overlapped modules
2413 AliITStrackV2 tmp(*track);
2414 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2415 layer.SelectClusters(zmin,zmax,ymin,ymax);
2417 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2419 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2420 Double_t tolerance=0.1;
2421 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2422 // only clusters in another module! (overlaps)
2423 idetExtra = clExtra->GetDetectorIndex();
2424 if (idet == idetExtra) continue;
2426 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2428 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2429 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2430 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2431 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2433 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2434 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2437 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2438 track->SetExtraModule(ilayer,idetExtra);
2440 } // end search for extra clusters in overlapped modules
2442 // Correct for material of the current layer
2444 // add time if going outward
2445 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2446 track->SetCheckInvariant(kTRUE);
2447 } // end loop on layers
2449 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2453 //------------------------------------------------------------------------
2454 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2457 // calculate normalized chi2
2458 // return NormalizedChi2(track,0);
2461 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2462 // track->fdEdxMismatch=0;
2463 Float_t dedxmismatch =0;
2464 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2466 for (Int_t i = 0;i<6;i++){
2467 if (track->GetClIndex(i)>=0){
2468 Float_t cerry, cerrz;
2469 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2471 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2474 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2475 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2476 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2478 cchi2+=(0.5-ratio)*10.;
2479 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2480 dedxmismatch+=(0.5-ratio)*10.;
2484 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2485 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2486 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2487 if (i<2) chi2+=2*cl->GetDeltaProbability();
2493 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2494 track->SetdEdxMismatch(dedxmismatch);
2498 for (Int_t i = 0;i<4;i++){
2499 if (track->GetClIndex(i)>=0){
2500 Float_t cerry, cerrz;
2501 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2502 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2505 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2506 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2510 for (Int_t i = 4;i<6;i++){
2511 if (track->GetClIndex(i)>=0){
2512 Float_t cerry, cerrz;
2513 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2514 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2517 Float_t cerryb, cerrzb;
2518 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2519 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2522 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2523 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2528 if (track->GetESDtrack()->GetTPCsignal()>85){
2529 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2531 chi2+=(0.5-ratio)*5.;
2534 chi2+=(ratio-2.0)*3;
2538 Double_t match = TMath::Sqrt(track->GetChi22());
2539 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2540 if (!track->GetConstrain()) {
2541 if (track->GetNumberOfClusters()>2) {
2542 match/=track->GetNumberOfClusters()-2.;
2547 if (match<0) match=0;
2549 // penalty factor for missing points (NDeadZone>0), but no penalty
2550 // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2551 // or there is a dead from OCDB)
2552 Float_t deadzonefactor = 0.;
2553 if (track->GetNDeadZone()>0.) {
2554 Int_t sumDeadZoneProbability=0;
2555 for(Int_t ilay=0;ilay<6;ilay++) {
2556 if(track->GetDeadZoneProbability(ilay)>0.) sumDeadZoneProbability++;
2558 Int_t nDeadZoneWithProbNot1=(Int_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2559 if(nDeadZoneWithProbNot1>0) {
2560 Float_t deadZoneProbability = track->GetNDeadZone()-(Float_t)sumDeadZoneProbability;
2561 AliDebug(2,Form("nDeadZone %f sumDZProbability %d nDZWithProbNot1 %d deadZoneProb %f\n",track->GetNDeadZone(),sumDeadZoneProbability,nDeadZoneWithProbNot1,deadZoneProbability));
2562 deadZoneProbability /= (Float_t)nDeadZoneWithProbNot1;
2564 deadZoneProbability = TMath::Min(deadZoneProbability,one);
2565 deadzonefactor = 3.*(1.1-deadZoneProbability);
2569 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2570 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2571 1./(1.+track->GetNSkipped()));
2572 AliDebug(2,Form("match %f deadzonefactor %f chi2 %f sum %f skipped %f\n",match,deadzonefactor,chi2,sum,track->GetNSkipped()));
2573 AliDebug(2,Form("NormChi2 %f cls %d\n",normchi2,track->GetNumberOfClusters()));
2576 //------------------------------------------------------------------------
2577 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2580 // return matching chi2 between two tracks
2581 Double_t largeChi2=1000.;
2583 AliITStrackMI track3(*track2);
2584 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2586 vec(0,0)=track1->GetY() - track3.GetY();
2587 vec(1,0)=track1->GetZ() - track3.GetZ();
2588 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2589 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2590 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2593 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2594 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2595 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2596 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2597 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2599 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2600 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2601 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2602 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2604 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2605 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2606 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2608 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2609 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2611 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2614 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2615 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2618 //------------------------------------------------------------------------
2619 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2622 // return probability that given point (characterized by z position and error)
2623 // is in SPD dead zone
2624 // This method assumes that fSPDdetzcentre is ordered from -z to +z
2626 Double_t probability = 0.;
2627 Double_t nearestz = 0.,distz=0.;
2628 Int_t nearestzone = -1;
2629 Double_t mindistz = 1000.;
2631 // find closest dead zone
2632 for (Int_t i=0; i<3; i++) {
2633 distz=TMath::Abs(zpos-0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]));
2634 if (distz<mindistz) {
2636 nearestz=0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]);
2641 // too far from dead zone
2642 if (TMath::Abs(zpos-nearestz)>0.25+3.*zerr) return probability;
2645 Double_t zmin, zmax;
2646 if (nearestzone==0) { // dead zone at z = -7
2647 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2648 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2649 } else if (nearestzone==1) { // dead zone at z = 0
2650 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2651 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2652 } else if (nearestzone==2) { // dead zone at z = +7
2653 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2654 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2659 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2661 probability = 0.5*( AliMathBase::ErfFast((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2662 AliMathBase::ErfFast((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2663 AliDebug(2,Form("zpos %f +- %f nearestzone %d zmin zmax %f %f prob %f\n",zpos,zerr,nearestzone,zmin,zmax,probability));
2666 //------------------------------------------------------------------------
2667 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2670 // calculate normalized chi2
2672 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2674 for (Int_t i = 0;i<6;i++){
2675 if (TMath::Abs(track->GetDy(i))>0){
2676 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2677 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2680 else{chi2[i]=10000;}
2683 TMath::Sort(6,chi2,index,kFALSE);
2684 Float_t max = float(ncl)*fac-1.;
2685 Float_t sumchi=0, sumweight=0;
2686 for (Int_t i=0;i<max+1;i++){
2687 Float_t weight = (i<max)?1.:(max+1.-i);
2688 sumchi+=weight*chi2[index[i]];
2691 Double_t normchi2 = sumchi/sumweight;
2694 //------------------------------------------------------------------------
2695 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2698 // calculate normalized chi2
2699 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2702 for (Int_t i=0;i<6;i++){
2703 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2704 Double_t sy1 = forwardtrack->GetSigmaY(i);
2705 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2706 Double_t sy2 = backtrack->GetSigmaY(i);
2707 Double_t sz2 = backtrack->GetSigmaZ(i);
2708 if (i<2){ sy2=1000.;sz2=1000;}
2710 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2711 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2713 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2714 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2716 res+= nz0*nz0+ny0*ny0;
2719 if (npoints>1) return
2720 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2721 //2*forwardtrack->fNUsed+
2722 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2723 1./(1.+forwardtrack->GetNSkipped()));
2726 //------------------------------------------------------------------------
2727 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2728 //--------------------------------------------------------------------
2729 // Return pointer to a given cluster
2730 //--------------------------------------------------------------------
2731 Int_t l=(index & 0xf0000000) >> 28;
2732 Int_t c=(index & 0x0fffffff) >> 00;
2733 return fgLayers[l].GetWeight(c);
2735 //------------------------------------------------------------------------
2736 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2738 //---------------------------------------------
2739 // register track to the list
2741 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2744 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2745 Int_t index = track->GetClusterIndex(icluster);
2746 Int_t l=(index & 0xf0000000) >> 28;
2747 Int_t c=(index & 0x0fffffff) >> 00;
2748 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2749 for (Int_t itrack=0;itrack<4;itrack++){
2750 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2751 fgLayers[l].SetClusterTracks(itrack,c,id);
2757 //------------------------------------------------------------------------
2758 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2760 //---------------------------------------------
2761 // unregister track from the list
2762 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2763 Int_t index = track->GetClusterIndex(icluster);
2764 Int_t l=(index & 0xf0000000) >> 28;
2765 Int_t c=(index & 0x0fffffff) >> 00;
2766 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2767 for (Int_t itrack=0;itrack<4;itrack++){
2768 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2769 fgLayers[l].SetClusterTracks(itrack,c,-1);
2774 //------------------------------------------------------------------------
2775 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2777 //-------------------------------------------------------------
2778 //get number of shared clusters
2779 //-------------------------------------------------------------
2781 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2782 // mean number of clusters
2783 Float_t *ny = GetNy(id), *nz = GetNz(id);
2786 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2787 Int_t index = track->GetClusterIndex(icluster);
2788 Int_t l=(index & 0xf0000000) >> 28;
2789 Int_t c=(index & 0x0fffffff) >> 00;
2790 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2791 // if (ny[l]<1.e-13){
2792 // printf("problem\n");
2794 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2798 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2799 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2800 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2802 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2805 deltan = (cl->GetNz()-nz[l]);
2807 if (deltan>2.0) continue; // extended - highly probable shared cluster
2808 weight = 2./TMath::Max(3.+deltan,2.);
2810 for (Int_t itrack=0;itrack<4;itrack++){
2811 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2813 clist[l] = (AliITSRecPoint*)GetCluster(index);
2819 track->SetNUsed(shared);
2822 //------------------------------------------------------------------------
2823 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2826 // find first shared track
2828 // mean number of clusters
2829 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2831 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2832 Int_t sharedtrack=100000;
2833 Int_t tracks[24],trackindex=0;
2834 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2836 for (Int_t icluster=0;icluster<6;icluster++){
2837 if (clusterlist[icluster]<0) continue;
2838 Int_t index = clusterlist[icluster];
2839 Int_t l=(index & 0xf0000000) >> 28;
2840 Int_t c=(index & 0x0fffffff) >> 00;
2841 // if (ny[l]<1.e-13){
2842 // printf("problem\n");
2844 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2845 //if (l>3) continue;
2846 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2849 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2850 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2851 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2853 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2856 deltan = (cl->GetNz()-nz[l]);
2858 if (deltan>2.0) continue; // extended - highly probable shared cluster
2860 for (Int_t itrack=3;itrack>=0;itrack--){
2861 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2862 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2863 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2868 if (trackindex==0) return -1;
2870 sharedtrack = tracks[0];
2872 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2875 Int_t tracks2[24], cluster[24];
2876 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2879 for (Int_t i=0;i<trackindex;i++){
2880 if (tracks[i]<0) continue;
2881 tracks2[index] = tracks[i];
2883 for (Int_t j=i+1;j<trackindex;j++){
2884 if (tracks[j]<0) continue;
2885 if (tracks[j]==tracks[i]){
2893 for (Int_t i=0;i<index;i++){
2894 if (cluster[index]>max) {
2895 sharedtrack=tracks2[index];
2902 if (sharedtrack>=100000) return -1;
2904 // make list of overlaps
2906 for (Int_t icluster=0;icluster<6;icluster++){
2907 if (clusterlist[icluster]<0) continue;
2908 Int_t index = clusterlist[icluster];
2909 Int_t l=(index & 0xf0000000) >> 28;
2910 Int_t c=(index & 0x0fffffff) >> 00;
2911 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2912 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2914 if (cl->GetNy()>2) continue;
2915 if (cl->GetNz()>2) continue;
2918 if (cl->GetNy()>3) continue;
2919 if (cl->GetNz()>3) continue;
2922 for (Int_t itrack=3;itrack>=0;itrack--){
2923 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2924 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2932 //------------------------------------------------------------------------
2933 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2935 // try to find track hypothesys without conflicts
2936 // with minimal chi2;
2937 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2938 Int_t entries1 = arr1->GetEntriesFast();
2939 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2940 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2941 Int_t entries2 = arr2->GetEntriesFast();
2942 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2944 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2945 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2946 if (track10->Pt()>0.5+track20->Pt()) return track10;
2948 for (Int_t itrack=0;itrack<entries1;itrack++){
2949 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2950 UnRegisterClusterTracks(track,trackID1);
2953 for (Int_t itrack=0;itrack<entries2;itrack++){
2954 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2955 UnRegisterClusterTracks(track,trackID2);
2959 Float_t maxconflicts=6;
2960 Double_t maxchi2 =1000.;
2962 // get weight of hypothesys - using best hypothesy
2965 Int_t list1[6],list2[6];
2966 AliITSRecPoint *clist1[6], *clist2[6] ;
2967 RegisterClusterTracks(track10,trackID1);
2968 RegisterClusterTracks(track20,trackID2);
2969 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2970 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2971 UnRegisterClusterTracks(track10,trackID1);
2972 UnRegisterClusterTracks(track20,trackID2);
2975 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2976 Float_t nerry[6],nerrz[6];
2977 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2978 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2979 for (Int_t i=0;i<6;i++){
2980 if ( (erry1[i]>0) && (erry2[i]>0)) {
2981 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2982 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2984 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2985 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2987 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2988 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2989 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2992 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2993 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2994 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
3002 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
3003 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
3004 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
3005 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
3007 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
3008 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
3009 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
3011 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
3012 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
3013 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
3016 Double_t sumw = w1+w2;
3020 w1 = (d2+0.5)/(d1+d2+1.);
3021 w2 = (d1+0.5)/(d1+d2+1.);
3023 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
3024 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
3026 // get pair of "best" hypothesys
3028 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
3029 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
3031 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
3032 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
3033 //if (track1->fFakeRatio>0) continue;
3034 RegisterClusterTracks(track1,trackID1);
3035 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
3036 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
3038 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
3039 //if (track2->fFakeRatio>0) continue;
3041 RegisterClusterTracks(track2,trackID2);
3042 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
3043 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
3044 UnRegisterClusterTracks(track2,trackID2);
3046 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
3047 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
3048 if (nskipped>0.5) continue;
3050 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
3051 if (conflict1+1<cconflict1) continue;
3052 if (conflict2+1<cconflict2) continue;
3056 for (Int_t i=0;i<6;i++){
3058 Float_t c1 =0.; // conflict coeficients
3060 if (clist1[i]&&clist2[i]){
3063 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
3066 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
3068 c1 = 2./TMath::Max(3.+deltan,2.);
3069 c2 = 2./TMath::Max(3.+deltan,2.);
3075 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
3078 deltan = (clist1[i]->GetNz()-nz1[i]);
3080 c1 = 2./TMath::Max(3.+deltan,2.);
3087 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
3090 deltan = (clist2[i]->GetNz()-nz2[i]);
3092 c2 = 2./TMath::Max(3.+deltan,2.);
3098 if (TMath::Abs(track1->GetDy(i))>0.) {
3099 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
3100 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
3101 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
3102 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
3104 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
3107 if (TMath::Abs(track2->GetDy(i))>0.) {
3108 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
3109 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
3110 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
3111 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3114 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3116 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3117 if (chi21>0) sum+=w1;
3118 if (chi22>0) sum+=w2;
3121 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3122 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3123 Double_t normchi2 = 2*conflict+sumchi2/sum;
3124 if ( normchi2 <maxchi2 ){
3127 maxconflicts = conflict;
3131 UnRegisterClusterTracks(track1,trackID1);
3134 // if (maxconflicts<4 && maxchi2<th0){
3135 if (maxchi2<th0*2.){
3136 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3137 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3138 track1->SetChi2MIP(5,maxconflicts);
3139 track1->SetChi2MIP(6,maxchi2);
3140 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3141 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3142 track1->SetChi2MIP(8,index1);
3143 fBestTrackIndex[trackID1] =index1;
3144 UpdateESDtrack(track1, AliESDtrack::kITSin);
3146 else if (track10->GetChi2MIP(0)<th1){
3147 track10->SetChi2MIP(5,maxconflicts);
3148 track10->SetChi2MIP(6,maxchi2);
3149 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3150 UpdateESDtrack(track10,AliESDtrack::kITSin);
3153 for (Int_t itrack=0;itrack<entries1;itrack++){
3154 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3155 UnRegisterClusterTracks(track,trackID1);
3158 for (Int_t itrack=0;itrack<entries2;itrack++){
3159 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3160 UnRegisterClusterTracks(track,trackID2);
3163 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3164 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3165 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3166 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3167 RegisterClusterTracks(track10,trackID1);
3169 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3170 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3171 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3172 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3173 RegisterClusterTracks(track20,trackID2);
3178 //------------------------------------------------------------------------
3179 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3180 //--------------------------------------------------------------------
3181 // This function marks clusters assigned to the track
3182 //--------------------------------------------------------------------
3183 AliTracker::UseClusters(t,from);
3185 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3186 //if (c->GetQ()>2) c->Use();
3187 if (c->GetSigmaZ2()>0.1) c->Use();
3188 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3189 //if (c->GetQ()>2) c->Use();
3190 if (c->GetSigmaZ2()>0.1) c->Use();
3193 //------------------------------------------------------------------------
3194 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3196 //------------------------------------------------------------------
3197 // add track to the list of hypothesys
3198 //------------------------------------------------------------------
3200 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3201 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3203 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3205 array = new TObjArray(10);
3206 fTrackHypothesys.AddAt(array,esdindex);
3208 array->AddLast(track);
3210 //------------------------------------------------------------------------
3211 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3213 //-------------------------------------------------------------------
3214 // compress array of track hypothesys
3215 // keep only maxsize best hypothesys
3216 //-------------------------------------------------------------------
3217 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3218 if (! (fTrackHypothesys.At(esdindex)) ) return;
3219 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3220 Int_t entries = array->GetEntriesFast();
3222 //- find preliminary besttrack as a reference
3223 Float_t minchi2=10000;
3225 AliITStrackMI * besttrack=0;
3226 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3227 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3228 if (!track) continue;
3229 Float_t chi2 = NormalizedChi2(track,0);
3231 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3232 track->SetLabel(tpcLabel);
3234 track->SetFakeRatio(1.);
3235 CookLabel(track,0.); //For comparison only
3237 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3238 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3239 if (track->GetNumberOfClusters()<maxn) continue;
3240 maxn = track->GetNumberOfClusters();
3247 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3248 delete array->RemoveAt(itrack);
3252 if (!besttrack) return;
3255 //take errors of best track as a reference
3256 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3257 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3258 for (Int_t j=0;j<6;j++) {
3259 if (besttrack->GetClIndex(j)>=0){
3260 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3261 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3262 ny[j] = besttrack->GetNy(j);
3263 nz[j] = besttrack->GetNz(j);
3267 // calculate normalized chi2
3269 Float_t * chi2 = new Float_t[entries];
3270 Int_t * index = new Int_t[entries];
3271 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3272 for (Int_t itrack=0;itrack<entries;itrack++){
3273 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3275 AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3276 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3277 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3278 chi2[itrack] = track->GetChi2MIP(0);
3280 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3281 delete array->RemoveAt(itrack);
3287 TMath::Sort(entries,chi2,index,kFALSE);
3288 besttrack = (AliITStrackMI*)array->At(index[0]);
3289 if(besttrack) AliDebug(2,Form("ncls best track %d\n",besttrack->GetNumberOfClusters()));
3290 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3291 for (Int_t j=0;j<6;j++){
3292 if (besttrack->GetClIndex(j)>=0){
3293 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3294 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3295 ny[j] = besttrack->GetNy(j);
3296 nz[j] = besttrack->GetNz(j);
3301 // calculate one more time with updated normalized errors
3302 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3303 for (Int_t itrack=0;itrack<entries;itrack++){
3304 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3306 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3307 AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3308 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3309 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3312 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3313 delete array->RemoveAt(itrack);
3318 entries = array->GetEntriesFast();
3322 TObjArray * newarray = new TObjArray();
3323 TMath::Sort(entries,chi2,index,kFALSE);
3324 besttrack = (AliITStrackMI*)array->At(index[0]);
3326 AliDebug(2,Form("ncls best track %d %f %f\n",besttrack->GetNumberOfClusters(),besttrack->GetChi2MIP(0),chi2[index[0]]));
3328 for (Int_t j=0;j<6;j++){
3329 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3330 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3331 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3332 ny[j] = besttrack->GetNy(j);
3333 nz[j] = besttrack->GetNz(j);
3336 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3337 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3338 Float_t minn = besttrack->GetNumberOfClusters()-3;
3340 for (Int_t i=0;i<entries;i++){
3341 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3342 if (!track) continue;
3343 if (accepted>maxcut) break;
3344 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3345 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3346 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3347 delete array->RemoveAt(index[i]);
3351 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3352 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3353 if (!shortbest) accepted++;
3355 newarray->AddLast(array->RemoveAt(index[i]));
3356 for (Int_t j=0;j<6;j++){
3358 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3359 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3360 ny[j] = track->GetNy(j);
3361 nz[j] = track->GetNz(j);
3366 delete array->RemoveAt(index[i]);
3370 delete fTrackHypothesys.RemoveAt(esdindex);
3371 fTrackHypothesys.AddAt(newarray,esdindex);
3375 delete fTrackHypothesys.RemoveAt(esdindex);
3381 //------------------------------------------------------------------------
3382 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3384 //-------------------------------------------------------------
3385 // try to find best hypothesy
3386 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3387 //-------------------------------------------------------------
3388 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3389 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3390 if (!array) return 0;
3391 Int_t entries = array->GetEntriesFast();
3392 if (!entries) return 0;
3393 Float_t minchi2 = 100000;
3394 AliITStrackMI * besttrack=0;
3396 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3397 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3398 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3399 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3401 for (Int_t i=0;i<entries;i++){
3402 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3403 if (!track) continue;
3404 Float_t sigmarfi,sigmaz;
3405 GetDCASigma(track,sigmarfi,sigmaz);
3406 track->SetDnorm(0,sigmarfi);
3407 track->SetDnorm(1,sigmaz);
3409 track->SetChi2MIP(1,1000000);
3410 track->SetChi2MIP(2,1000000);
3411 track->SetChi2MIP(3,1000000);
3414 backtrack = new(backtrack) AliITStrackMI(*track);
3415 if (track->GetConstrain()) {
3416 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3417 if (AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
3418 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3420 backtrack->ResetCovariance(10.);
3422 backtrack->ResetCovariance(10.);
3424 backtrack->ResetClusters();
3426 Double_t x = original->GetX();
3427 if (!RefitAt(x,backtrack,track)) continue;
3429 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3430 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3431 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3432 track->SetChi22(GetMatchingChi2(backtrack,original));
3434 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3435 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3436 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3439 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3441 //forward track - without constraint
3442 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3443 forwardtrack->ResetClusters();
3445 RefitAt(x,forwardtrack,track);
3446 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3447 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3448 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3450 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3451 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3452 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3453 forwardtrack->SetD(0,track->GetD(0));
3454 forwardtrack->SetD(1,track->GetD(1));
3457 AliITSRecPoint* clist[6];
3458 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3459 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3462 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3463 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3464 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3465 track->SetChi2MIP(3,1000);
3468 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3470 for (Int_t ichi=0;ichi<5;ichi++){
3471 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3473 if (chi2 < minchi2){
3474 //besttrack = new AliITStrackMI(*forwardtrack);
3476 besttrack->SetLabel(track->GetLabel());
3477 besttrack->SetFakeRatio(track->GetFakeRatio());
3479 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3480 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3481 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3485 delete forwardtrack;
3487 for (Int_t i=0;i<entries;i++){
3488 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3490 if (!track) continue;
3492 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3493 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3494 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3495 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3496 delete array->RemoveAt(i);
3506 SortTrackHypothesys(esdindex,checkmax,1);
3508 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3509 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3510 besttrack = (AliITStrackMI*)array->At(0);
3511 if (!besttrack) return 0;
3512 besttrack->SetChi2MIP(8,0);
3513 fBestTrackIndex[esdindex]=0;
3514 entries = array->GetEntriesFast();
3515 AliITStrackMI *longtrack =0;
3517 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3518 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3519 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3520 if (!track->GetConstrain()) continue;
3521 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3522 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3523 if (track->GetChi2MIP(0)>4.) continue;
3524 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3527 //if (longtrack) besttrack=longtrack;
3530 AliITSRecPoint * clist[6];
3531 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3532 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3533 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3534 RegisterClusterTracks(besttrack,esdindex);
3541 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3542 if (sharedtrack>=0){
3544 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3546 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3552 if (shared>2.5) return 0;
3553 if (shared>1.0) return besttrack;
3555 // Don't sign clusters if not gold track
3557 if (!besttrack->IsGoldPrimary()) return besttrack;
3558 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3560 if (fConstraint[fPass]){
3564 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3565 for (Int_t i=0;i<6;i++){
3566 Int_t index = besttrack->GetClIndex(i);
3567 if (index<0) continue;
3568 Int_t ilayer = (index & 0xf0000000) >> 28;
3569 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3570 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3572 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3573 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3574 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3575 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3576 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3577 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3579 Bool_t cansign = kTRUE;
3580 for (Int_t itrack=0;itrack<entries; itrack++){
3581 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3582 if (!track) continue;
3583 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3584 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3590 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3591 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3592 if (!c->IsUsed()) c->Use();
3598 //------------------------------------------------------------------------
3599 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3602 // get "best" hypothesys
3605 Int_t nentries = itsTracks.GetEntriesFast();
3606 for (Int_t i=0;i<nentries;i++){
3607 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3608 if (!track) continue;
3609 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3610 if (!array) continue;
3611 if (array->GetEntriesFast()<=0) continue;
3613 AliITStrackMI* longtrack=0;
3615 Float_t maxchi2=1000;
3616 for (Int_t j=0;j<array->GetEntriesFast();j++){
3617 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3618 if (!trackHyp) continue;
3619 if (trackHyp->GetGoldV0()) {
3620 longtrack = trackHyp; //gold V0 track taken
3623 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3624 Float_t chi2 = trackHyp->GetChi2MIP(0);
3626 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3628 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3630 if (chi2 > maxchi2) continue;
3631 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3638 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3639 if (!longtrack) {longtrack = besttrack;}
3640 else besttrack= longtrack;
3644 AliITSRecPoint * clist[6];
3645 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3647 track->SetNUsed(shared);
3648 track->SetNSkipped(besttrack->GetNSkipped());
3649 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3651 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3655 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3656 //if (sharedtrack==-1) sharedtrack=0;
3657 if (sharedtrack>=0) {
3658 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3661 if (besttrack&&fAfterV0) {
3662 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3664 if (besttrack&&fConstraint[fPass])
3665 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3666 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3667 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3668 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3674 //------------------------------------------------------------------------
3675 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3676 //--------------------------------------------------------------------
3677 //This function "cooks" a track label. If label<0, this track is fake.
3678 //--------------------------------------------------------------------
3681 if (track->GetESDtrack()){
3682 tpcLabel = track->GetESDtrack()->GetTPCLabel();
3683 ULong_t trStatus=track->GetESDtrack()->GetStatus();
3684 if(!(trStatus&AliESDtrack::kTPCin)) tpcLabel=track->GetLabel(); // for ITSsa tracks
3686 track->SetChi2MIP(9,0);
3688 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3689 Int_t cindex = track->GetClusterIndex(i);
3690 Int_t l=(cindex & 0xf0000000) >> 28;
3691 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3693 for (Int_t ind=0;ind<3;ind++){
3694 if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
3695 //AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3697 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3700 Int_t nclusters = track->GetNumberOfClusters();
3701 if (nclusters > 0) //PH Some tracks don't have any cluster
3702 track->SetFakeRatio(double(nwrong)/double(nclusters));
3703 if (tpcLabel>0 && track->GetFakeRatio()>wrong) {
3704 track->SetLabel(-tpcLabel);
3706 track->SetLabel(tpcLabel);
3708 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3711 //------------------------------------------------------------------------
3712 void AliITStrackerMI::CookdEdx(AliITStrackMI* track){
3714 // Fill the dE/dx in this track
3716 track->SetChi2MIP(9,0);
3717 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3718 Int_t cindex = track->GetClusterIndex(i);
3719 Int_t l=(cindex & 0xf0000000) >> 28;
3720 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3721 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3723 for (Int_t ind=0;ind<3;ind++){
3724 if (cl->GetLabel(ind)==lab) isWrong=0;
3726 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3730 track->CookdEdx(low,up);
3732 //------------------------------------------------------------------------
3733 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3735 // Create some arrays
3737 if (fCoefficients) delete []fCoefficients;
3738 fCoefficients = new Float_t[ntracks*48];
3739 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3741 //------------------------------------------------------------------------
3742 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3745 // Compute predicted chi2
3747 // Take into account the mis-alignment (bring track to cluster plane)
3748 Double_t xTrOrig=track->GetX();
3749 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3750 Float_t erry,errz,covyz;
3751 Float_t theta = track->GetTgl();
3752 Float_t phi = track->GetSnp();
3753 phi *= TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3754 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
3755 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()));
3756 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()));
3757 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
3758 // Bring the track back to detector plane in ideal geometry
3759 // [mis-alignment will be accounted for in UpdateMI()]
3760 if (!track->Propagate(xTrOrig)) return 1000.;
3762 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3763 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3765 chi2+=0.5*TMath::Min(delta/2,2.);
3766 chi2+=2.*cluster->GetDeltaProbability();
3769 track->SetNy(layer,ny);
3770 track->SetNz(layer,nz);
3771 track->SetSigmaY(layer,erry);
3772 track->SetSigmaZ(layer, errz);
3773 track->SetSigmaYZ(layer,covyz);
3774 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3775 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3779 //------------------------------------------------------------------------
3780 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3785 Int_t layer = (index & 0xf0000000) >> 28;
3786 track->SetClIndex(layer, index);
3787 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3788 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3789 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3790 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3794 if (TMath::Abs(cl->GetQ())<1.e-13) return 0; // ingore the "virtual" clusters
3797 // Take into account the mis-alignment (bring track to cluster plane)
3798 Double_t xTrOrig=track->GetX();
3799 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3800 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3801 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3802 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3804 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3807 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3808 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3809 c.SetSigmaYZ(track->GetSigmaYZ(layer));
3812 Int_t updated = track->UpdateMI(&c,chi2,index);
3813 // Bring the track back to detector plane in ideal geometry
3814 if (!track->Propagate(xTrOrig)) return 0;
3816 if(!updated) AliDebug(2,"update failed");
3820 //------------------------------------------------------------------------
3821 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3824 //DCA sigmas parameterization
3825 //to be paramterized using external parameters in future
3828 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3829 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3831 //------------------------------------------------------------------------
3832 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3835 // Clusters from delta electrons?
3837 Int_t entries = clusterArray->GetEntriesFast();
3838 if (entries<4) return;
3839 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3840 Int_t layer = cluster->GetLayer();
3841 if (layer>1) return;
3843 Int_t ncandidates=0;
3844 Float_t r = (layer>0)? 7:4;
3846 for (Int_t i=0;i<entries;i++){
3847 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3848 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3849 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3850 index[ncandidates] = i; //candidate to belong to delta electron track
3852 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3853 cl0->SetDeltaProbability(1);
3859 for (Int_t i=0;i<ncandidates;i++){
3860 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3861 if (cl0->GetDeltaProbability()>0.8) continue;
3864 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3865 sumy=sumz=sumy2=sumyz=sumw=0.0;
3866 for (Int_t j=0;j<ncandidates;j++){
3868 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3870 Float_t dz = cl0->GetZ()-cl1->GetZ();
3871 Float_t dy = cl0->GetY()-cl1->GetY();
3872 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3873 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3874 y[ncl] = cl1->GetY();
3875 z[ncl] = cl1->GetZ();
3876 sumy+= y[ncl]*weight;
3877 sumz+= z[ncl]*weight;
3878 sumy2+=y[ncl]*y[ncl]*weight;
3879 sumyz+=y[ncl]*z[ncl]*weight;
3884 if (ncl<4) continue;
3885 Float_t det = sumw*sumy2 - sumy*sumy;
3887 if (TMath::Abs(det)>0.01){
3888 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3889 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3890 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3893 Float_t z0 = sumyz/sumy;
3894 delta = TMath::Abs(cl0->GetZ()-z0);
3897 cl0->SetDeltaProbability(1-20.*delta);
3901 //------------------------------------------------------------------------
3902 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3907 track->UpdateESDtrack(flags);
3908 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3909 if (oldtrack) delete oldtrack;
3910 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3911 // if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3912 // printf("Problem\n");
3915 //------------------------------------------------------------------------
3916 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3918 // Get nearest upper layer close to the point xr.
3919 // rough approximation
3921 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3922 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3924 for (Int_t i=0;i<6;i++){
3925 if (radius<kRadiuses[i]){
3932 //------------------------------------------------------------------------
3933 void AliITStrackerMI::BuildMaterialLUT(TString material) {
3934 //--------------------------------------------------------------------
3935 // Fill a look-up table with mean material
3936 //--------------------------------------------------------------------
3940 Double_t point1[3],point2[3];
3941 Double_t phi,cosphi,sinphi,z;
3942 // 0-5 layers, 6 pipe, 7-8 shields
3943 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
3944 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
3946 Int_t ifirst=0,ilast=0;
3947 if(material.Contains("Pipe")) {
3949 } else if(material.Contains("Shields")) {
3951 } else if(material.Contains("Layers")) {
3954 Error("BuildMaterialLUT","Wrong layer name\n");
3957 for(Int_t imat=ifirst; imat<=ilast; imat++) {
3958 Double_t param[5]={0.,0.,0.,0.,0.};
3959 for (Int_t i=0; i<n; i++) {
3960 phi = 2.*TMath::Pi()*gRandom->Rndm();
3961 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
3962 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
3963 point1[0] = rmin[imat]*cosphi;
3964 point1[1] = rmin[imat]*sinphi;
3966 point2[0] = rmax[imat]*cosphi;
3967 point2[1] = rmax[imat]*sinphi;
3969 AliTracker::MeanMaterialBudget(point1,point2,mparam);
3970 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
3972 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
3974 fxOverX0Layer[imat] = param[1];
3975 fxTimesRhoLayer[imat] = param[0]*param[4];
3976 } else if(imat==6) {
3977 fxOverX0Pipe = param[1];
3978 fxTimesRhoPipe = param[0]*param[4];
3979 } else if(imat==7) {
3980 fxOverX0Shield[0] = param[1];
3981 fxTimesRhoShield[0] = param[0]*param[4];
3982 } else if(imat==8) {
3983 fxOverX0Shield[1] = param[1];
3984 fxTimesRhoShield[1] = param[0]*param[4];
3988 printf("%s\n",material.Data());
3989 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
3990 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
3991 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
3992 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
3993 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
3994 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
3995 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
3996 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
3997 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
4001 //------------------------------------------------------------------------
4002 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
4003 TString direction) {
4004 //-------------------------------------------------------------------
4005 // Propagate beyond beam pipe and correct for material
4006 // (material budget in different ways according to fUseTGeo value)
4007 // Add time if going outward (PropagateTo or PropagateToTGeo)
4008 //-------------------------------------------------------------------
4010 // Define budget mode:
4011 // 0: material from AliITSRecoParam (hard coded)
4012 // 1: material from TGeo in one step (on the fly)
4013 // 2: material from lut
4014 // 3: material from TGeo in one step (same for all hypotheses)
4027 if(fTrackingPhase.Contains("Clusters2Tracks"))
4028 { mode=3; } else { mode=1; }
4031 if(fTrackingPhase.Contains("Clusters2Tracks"))
4032 { mode=3; } else { mode=2; }
4038 if(fTrackingPhase.Contains("Default")) mode=0;
4040 Int_t index=fCurrentEsdTrack;
4042 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4043 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4045 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4047 Double_t xOverX0,x0,lengthTimesMeanDensity;
4051 xOverX0 = AliITSRecoParam::GetdPipe();
4052 x0 = AliITSRecoParam::GetX0Be();
4053 lengthTimesMeanDensity = xOverX0*x0;
4054 lengthTimesMeanDensity *= dir;
4055 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4058 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4061 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4062 xOverX0 = fxOverX0Pipe;
4063 lengthTimesMeanDensity = fxTimesRhoPipe;
4064 lengthTimesMeanDensity *= dir;
4065 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4068 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4069 if(fxOverX0PipeTrks[index]<0) {
4070 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4071 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4072 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4073 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4074 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4077 xOverX0 = fxOverX0PipeTrks[index];
4078 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4079 lengthTimesMeanDensity *= dir;
4080 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4086 //------------------------------------------------------------------------
4087 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4089 TString direction) {
4090 //-------------------------------------------------------------------
4091 // Propagate beyond SPD or SDD shield and correct for material
4092 // (material budget in different ways according to fUseTGeo value)
4093 // Add time if going outward (PropagateTo or PropagateToTGeo)
4094 //-------------------------------------------------------------------
4096 // Define budget mode:
4097 // 0: material from AliITSRecoParam (hard coded)
4098 // 1: material from TGeo in steps of X cm (on the fly)
4099 // X = AliITSRecoParam::GetStepSizeTGeo()
4100 // 2: material from lut
4101 // 3: material from TGeo in one step (same for all hypotheses)
4114 if(fTrackingPhase.Contains("Clusters2Tracks"))
4115 { mode=3; } else { mode=1; }
4118 if(fTrackingPhase.Contains("Clusters2Tracks"))
4119 { mode=3; } else { mode=2; }
4125 if(fTrackingPhase.Contains("Default")) mode=0;
4127 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4129 Int_t shieldindex=0;
4130 if (shield.Contains("SDD")) { // SDDouter
4131 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4133 } else if (shield.Contains("SPD")) { // SPDouter
4134 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4137 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4141 // do nothing if we are already beyond the shield
4142 Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4143 if(dir<0 && rTrack > rToGo) return 1; // going outward
4144 if(dir>0 && rTrack < rToGo) return 1; // going inward
4148 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4150 Int_t index=2*fCurrentEsdTrack+shieldindex;
4152 Double_t xOverX0,x0,lengthTimesMeanDensity;
4157 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4158 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4159 lengthTimesMeanDensity = xOverX0*x0;
4160 lengthTimesMeanDensity *= dir;
4161 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4164 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4165 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4168 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4169 xOverX0 = fxOverX0Shield[shieldindex];
4170 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4171 lengthTimesMeanDensity *= dir;
4172 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4175 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4176 if(fxOverX0ShieldTrks[index]<0) {
4177 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4178 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4179 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4180 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4181 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4184 xOverX0 = fxOverX0ShieldTrks[index];
4185 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4186 lengthTimesMeanDensity *= dir;
4187 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4193 //------------------------------------------------------------------------
4194 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4196 Double_t oldGlobXYZ[3],
4197 TString direction) {
4198 //-------------------------------------------------------------------
4199 // Propagate beyond layer and correct for material
4200 // (material budget in different ways according to fUseTGeo value)
4201 // Add time if going outward (PropagateTo or PropagateToTGeo)
4202 //-------------------------------------------------------------------
4204 // Define budget mode:
4205 // 0: material from AliITSRecoParam (hard coded)
4206 // 1: material from TGeo in stepsof X cm (on the fly)
4207 // X = AliITSRecoParam::GetStepSizeTGeo()
4208 // 2: material from lut
4209 // 3: material from TGeo in one step (same for all hypotheses)
4222 if(fTrackingPhase.Contains("Clusters2Tracks"))
4223 { mode=3; } else { mode=1; }
4226 if(fTrackingPhase.Contains("Clusters2Tracks"))
4227 { mode=3; } else { mode=2; }
4233 if(fTrackingPhase.Contains("Default")) mode=0;
4235 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4237 Double_t r=fgLayers[layerindex].GetR();
4238 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4240 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4242 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4244 Int_t index=6*fCurrentEsdTrack+layerindex;
4247 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4250 // back before material (no correction)
4252 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4253 if (!t->GetLocalXat(rOld,xOld)) return 0;
4254 if (!t->Propagate(xOld)) return 0;
4258 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4259 lengthTimesMeanDensity = xOverX0*x0;
4260 lengthTimesMeanDensity *= dir;
4261 // Bring the track beyond the material
4262 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4265 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4266 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4269 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4270 xOverX0 = fxOverX0Layer[layerindex];
4271 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4272 lengthTimesMeanDensity *= dir;
4273 // Bring the track beyond the material
4274 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4277 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4278 if(fxOverX0LayerTrks[index]<0) {
4279 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4280 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4281 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4282 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4283 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4284 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4287 xOverX0 = fxOverX0LayerTrks[index];
4288 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4289 lengthTimesMeanDensity *= dir;
4290 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4297 //------------------------------------------------------------------------
4298 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4299 //-----------------------------------------------------------------
4300 // Initialize LUT for storing material for each prolonged track
4301 //-----------------------------------------------------------------
4302 fxOverX0PipeTrks = new Float_t[ntracks];
4303 fxTimesRhoPipeTrks = new Float_t[ntracks];
4304 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4305 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4306 fxOverX0LayerTrks = new Float_t[ntracks*6];
4307 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4309 for(Int_t i=0; i<ntracks; i++) {
4310 fxOverX0PipeTrks[i] = -1.;
4311 fxTimesRhoPipeTrks[i] = -1.;
4313 for(Int_t j=0; j<ntracks*2; j++) {
4314 fxOverX0ShieldTrks[j] = -1.;
4315 fxTimesRhoShieldTrks[j] = -1.;
4317 for(Int_t k=0; k<ntracks*6; k++) {
4318 fxOverX0LayerTrks[k] = -1.;
4319 fxTimesRhoLayerTrks[k] = -1.;
4326 //------------------------------------------------------------------------
4327 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4328 //-----------------------------------------------------------------
4329 // Delete LUT for storing material for each prolonged track
4330 //-----------------------------------------------------------------
4331 if(fxOverX0PipeTrks) {
4332 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4334 if(fxOverX0ShieldTrks) {
4335 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4338 if(fxOverX0LayerTrks) {
4339 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4341 if(fxTimesRhoPipeTrks) {
4342 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4344 if(fxTimesRhoShieldTrks) {
4345 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4347 if(fxTimesRhoLayerTrks) {
4348 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4352 //------------------------------------------------------------------------
4353 void AliITStrackerMI::SetForceSkippingOfLayer() {
4354 //-----------------------------------------------------------------
4355 // Check if we are forced to skip layers
4356 // either we set to skip them in RecoParam
4357 // or they were off during data-taking
4358 //-----------------------------------------------------------------
4360 const AliEventInfo *eventInfo = GetEventInfo();
4362 for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
4363 fForceSkippingOfLayer[l] = 0;
4365 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
4369 AliITSReconstructor::GetRecoParam()->GetSkipSubdetsNotInTriggerCluster()) {
4370 AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
4372 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
4373 } else if(l==2 || l==3) {
4374 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1;
4376 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
4382 //------------------------------------------------------------------------
4383 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4384 Int_t ilayer,Int_t idet) const {
4385 //-----------------------------------------------------------------
4386 // This method is used to decide whether to allow a prolongation
4387 // without clusters, because we want to skip the layer.
4388 // In this case the return value is > 0:
4389 // return 1: the user requested to skip a layer
4390 // return 2: track outside z acceptance
4391 //-----------------------------------------------------------------
4393 if (ForceSkippingOfLayer(ilayer)) return 1;
4395 Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
4397 if (idet<0 && // out in z
4398 ilayer>innerLayCanSkip &&
4399 AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4400 // check if track will cross SPD outer layer
4401 Double_t phiAtSPD2,zAtSPD2;
4402 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4403 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4405 return 2; // always allow skipping, changed on 05.11.2009
4410 //------------------------------------------------------------------------
4411 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4412 Int_t ilayer,Int_t idet,
4413 Double_t dz,Double_t dy,
4414 Bool_t noClusters) const {
4415 //-----------------------------------------------------------------
4416 // This method is used to decide whether to allow a prolongation
4417 // without clusters, because there is a dead zone in the road.
4418 // In this case the return value is > 0:
4419 // return 1: dead zone at z=0,+-7cm in SPD
4420 // This method assumes that fSPDdetzcentre is ordered from -z to +z
4421 // return 2: all road is "bad" (dead or noisy) from the OCDB
4422 // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4423 // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4424 //-----------------------------------------------------------------
4426 // check dead zones at z=0,+-7cm in the SPD
4427 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4428 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4429 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4430 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4431 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4432 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4433 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4434 for (Int_t i=0; i<3; i++)
4435 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4436 AliDebug(2,Form("crack SPD %d track z %f %f %f %f\n",ilayer,track->GetZ(),dz,zmaxdead[i],zmindead[i]));
4437 if (GetSPDDeadZoneProbability(track->GetZ(),TMath::Sqrt(track->GetSigmaZ2()))>0.1) return 1;
4441 // check bad zones from OCDB
4442 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4444 if (idet<0) return 0;
4446 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4449 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4450 if (ilayer==0 || ilayer==1) { // ---------- SPD
4452 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4454 detSizeFactorX *= 2.;
4455 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4458 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4459 if (detType==2) segm->SetLayer(ilayer+1);
4460 Float_t detSizeX = detSizeFactorX*segm->Dx();
4461 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4463 // check if the road overlaps with bad chips
4465 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
4466 Float_t zlocmin = zloc-dz;
4467 Float_t zlocmax = zloc+dz;
4468 Float_t xlocmin = xloc-dy;
4469 Float_t xlocmax = xloc+dy;
4470 Int_t chipsInRoad[100];
4472 // check if road goes out of detector
4473 Bool_t touchNeighbourDet=kFALSE;
4474 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4475 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4476 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4477 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4478 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));
4480 // check if this detector is bad
4482 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4483 if(!touchNeighbourDet) {
4484 return 2; // all detectors in road are bad
4486 return 3; // at least one is bad
4490 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4491 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4492 if (!nChipsInRoad) return 0;
4494 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4495 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4496 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4497 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4498 if (det.IsChipBad(chipsInRoad[iCh])) {
4506 if(!touchNeighbourDet) {
4507 AliDebug(2,"all bad in road");
4508 return 2; // all chips in road are bad
4510 return 3; // at least a bad chip in road
4515 AliDebug(2,"at least a bad in road");
4516 return 3; // at least a bad chip in road
4520 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4521 || !noClusters) return 0;
4523 // There are no clusters in road: check if there is at least
4524 // a bad SPD pixel or SDD anode or SSD strips on both sides
4526 Int_t idetInITS=idet;
4527 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4529 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4530 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4533 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4537 //------------------------------------------------------------------------
4538 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4539 const AliITStrackMI *track,
4540 Float_t &xloc,Float_t &zloc) const {
4541 //-----------------------------------------------------------------
4542 // Gives position of track in local module ref. frame
4543 //-----------------------------------------------------------------
4548 if(idet<0) return kTRUE; // track out of z acceptance of layer
4550 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4552 Int_t lad = Int_t(idet/ndet) + 1;
4554 Int_t det = idet - (lad-1)*ndet + 1;
4556 Double_t xyzGlob[3],xyzLoc[3];
4558 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4559 // take into account the misalignment: xyz at real detector plane
4560 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4562 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4564 xloc = (Float_t)xyzLoc[0];
4565 zloc = (Float_t)xyzLoc[2];
4569 //------------------------------------------------------------------------
4570 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
4572 // Method to be optimized further:
4573 // Aim: decide whether a track can be used for PlaneEff evaluation
4574 // the decision is taken based on the track quality at the layer under study
4575 // no information on the clusters on this layer has to be used
4576 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4577 // the cut is done on number of sigmas from the boundaries
4579 // Input: Actual track, layer [0,5] under study
4581 // Return: kTRUE if this is a good track
4583 // it will apply a pre-selection to obtain good quality tracks.
4584 // Here also you will have the possibility to put a control on the
4585 // impact point of the track on the basic block, in order to exclude border regions
4586 // this will be done by calling a proper method of the AliITSPlaneEff class.
4588 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4589 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4591 Int_t index[AliITSgeomTGeo::kNLayers];
4593 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4595 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4596 index[k]=clusters[k];
4600 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4601 AliITSlayer &layer=fgLayers[ilayer];
4602 Double_t r=layer.GetR();
4603 AliITStrackMI tmp(*track);
4605 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4606 Int_t ncl_out=0; Int_t ncl_in=0;
4607 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) { // count n. of cluster in outermost layers
4608 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4609 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4610 if (tmp.GetClIndex(lay)>=0) ncl_out++;
4612 for(Int_t lay=ilayer-1; lay>=0;lay--) { // count n. of cluster in innermost layers
4613 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4614 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4615 if (tmp.GetClIndex(lay)>=0) ncl_in++;
4617 Int_t ncl=ncl_out+ncl_in;
4618 Bool_t nextout = kFALSE;
4619 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4620 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4621 Bool_t nextin = kFALSE;
4622 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4623 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4624 // maximum number of missing clusters allowed in outermost layers
4625 if(ncl_out<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersOutPlaneEff())
4627 // maximum number of missing clusters allowed (both in innermost and in outermost layers)
4628 if(ncl<AliITSgeomTGeo::kNLayers-1-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
4630 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
4631 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
4632 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
4633 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
4637 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4638 Int_t idet=layer.FindDetectorIndex(phi,z);
4639 if(idet<0) { AliInfo(Form("cannot find detector"));
4642 // here check if it has good Chi Square.
4644 //propagate to the intersection with the detector plane
4645 const AliITSdetector &det=layer.GetDetector(idet);
4646 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4650 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
4651 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4652 if(key>fPlaneEff->Nblock()) return kFALSE;
4653 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4654 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4656 // DEFINITION OF SEARCH ROAD FOR accepting a track
4658 //For the time being they are hard-wired, later on from AliITSRecoParam
4659 Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXFromBoundaryPlaneEff();
4660 Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZFromBoundaryPlaneEff();
4661 // Double_t nsigz=4;
4662 // Double_t nsigx=4;
4663 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4664 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4665 // done for RecPoints
4667 // exclude tracks at boundary between detectors
4668 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
4669 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4670 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
4671 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
4672 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
4674 if ( (locx-dx < blockXmn+boundaryWidth) ||
4675 (locx+dx > blockXmx-boundaryWidth) ||
4676 (locz-dz < blockZmn+boundaryWidth) ||
4677 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
4680 //------------------------------------------------------------------------
4681 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
4683 // This Method has to be optimized! For the time-being it uses the same criteria
4684 // as those used in the search of extra clusters for overlapping modules.
4686 // Method Purpose: estabilish whether a track has produced a recpoint or not
4687 // in the layer under study (For Plane efficiency)
4689 // inputs: AliITStrackMI* track (pointer to a usable track)
4691 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
4692 // traversed by this very track. In details:
4693 // - if a cluster can be associated to the track then call
4694 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
4695 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
4698 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
4699 AliITSlayer &layer=fgLayers[ilayer];
4700 Double_t r=layer.GetR();
4701 AliITStrackMI tmp(*track);
4705 if (!tmp.GetPhiZat(r,phi,z)) return;
4706 Int_t idet=layer.FindDetectorIndex(phi,z);
4708 if(idet<0) { AliInfo(Form("cannot find detector"));
4712 //propagate to the intersection with the detector plane
4713 const AliITSdetector &det=layer.GetDetector(idet);
4714 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
4718 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
4720 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
4721 TMath::Sqrt(tmp.GetSigmaZ2() +
4722 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4723 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4724 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
4725 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
4726 TMath::Sqrt(tmp.GetSigmaY2() +
4727 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4728 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4729 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
4731 // road in global (rphi,z) [i.e. in tracking ref. system]
4732 Double_t zmin = tmp.GetZ() - dz;
4733 Double_t zmax = tmp.GetZ() + dz;
4734 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
4735 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
4737 // select clusters in road
4738 layer.SelectClusters(zmin,zmax,ymin,ymax);
4740 // Define criteria for track-cluster association
4741 Double_t msz = tmp.GetSigmaZ2() +
4742 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4743 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4744 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
4745 Double_t msy = tmp.GetSigmaY2() +
4746 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4747 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4748 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
4749 if (tmp.GetConstrain()) {
4750 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
4751 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
4753 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
4754 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
4756 msz = 1./msz; // 1/RoadZ^2
4757 msy = 1./msy; // 1/RoadY^2
4760 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
4762 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
4763 //Double_t tolerance=0.2;
4764 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
4765 idetc = cl->GetDetectorIndex();
4766 if(idet!=idetc) continue;
4767 //Int_t ilay = cl->GetLayer();
4769 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
4770 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
4772 Double_t chi2=tmp.GetPredictedChi2(cl);
4773 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
4777 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
4779 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
4780 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4781 if(key>fPlaneEff->Nblock()) return;
4782 Bool_t found=kFALSE;
4785 while ((cl=layer.GetNextCluster(clidx))!=0) {
4786 idetc = cl->GetDetectorIndex();
4787 if(idet!=idetc) continue;
4788 // here real control to see whether the cluster can be associated to the track.
4789 // cluster not associated to track
4790 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
4791 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
4792 // calculate track-clusters chi2
4793 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
4794 // in particular, the error associated to the cluster
4795 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
4797 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
4799 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
4800 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
4801 // track->SetExtraModule(ilayer,idetExtra);
4803 if(!fPlaneEff->UpDatePlaneEff(found,key))
4804 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
4805 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
4806 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
4807 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
4808 Int_t cltype[2]={-999,-999};
4812 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4813 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4816 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
4817 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
4818 cltype[0]=layer.GetCluster(ci)->GetNy();
4819 cltype[1]=layer.GetCluster(ci)->GetNz();
4821 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
4822 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
4823 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
4824 // It is computed properly by calling the method
4825 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4827 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
4828 //if (tmp.PropagateTo(x,0.,0.)) {
4829 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
4830 AliCluster c(*layer.GetCluster(ci));
4831 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
4832 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
4833 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
4834 clu[2]=TMath::Sqrt(c.GetSigmaY2());
4835 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
4838 fPlaneEff->FillHistos(key,found,tr,clu,cltype);