1 /**************************************************************************
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 //-------------------------------------------------------------------------
18 // Implementation of the ITS tracker class
19 // It reads AliITSRecPoint clusters and creates AliITStrackMI tracks
20 // and fills with them the ESD
21 // Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch
22 // Current support and development:
23 // Andrea Dainese, andrea.dainese@lnl.infn.it
24 // dE/dx analysis by: Boris Batyunya, JINR, Boris.Batiounia@cern.ch
25 // Params moved to AliITSRecoParam by: Andrea Dainese, INFN
26 // Material budget from TGeo by: Ludovic Gaudichet & Andrea Dainese, INFN
27 //-------------------------------------------------------------------------
31 #include <TDatabasePDG.h>
34 #include <TTreeStream.h>
37 #include "AliITSPlaneEff.h"
38 #include "AliITSCalibrationSPD.h"
39 #include "AliITSCalibrationSDD.h"
40 #include "AliITSCalibrationSSD.h"
41 #include "AliCDBEntry.h"
42 #include "AliCDBManager.h"
43 #include "AliAlignObj.h"
44 #include "AliTrackPointArray.h"
45 #include "AliESDVertex.h"
46 #include "AliESDEvent.h"
47 #include "AliESDtrack.h"
50 #include "AliITSChannelStatus.h"
51 #include "AliITSDetTypeRec.h"
52 #include "AliITSRecPoint.h"
53 #include "AliITSRecPointContainer.h"
54 #include "AliITSgeomTGeo.h"
55 #include "AliITSReconstructor.h"
56 #include "AliITSClusterParam.h"
57 #include "AliITSsegmentation.h"
58 #include "AliITSCalibration.h"
59 #include "AliITSPlaneEffSPD.h"
60 #include "AliITSPlaneEffSDD.h"
61 #include "AliITSPlaneEffSSD.h"
62 #include "AliITSV0Finder.h"
63 #include "AliITStrackerMI.h"
65 ClassImp(AliITStrackerMI)
67 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
69 AliITStrackerMI::AliITStrackerMI():AliTracker(),
79 fLastLayerToTrackTo(0),
82 fTrackingPhase("Default"),
88 fxTimesRhoPipeTrks(0),
89 fxOverX0ShieldTrks(0),
90 fxTimesRhoShieldTrks(0),
92 fxTimesRhoLayerTrks(0),
99 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
100 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
101 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
103 //------------------------------------------------------------------------
104 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
105 fI(AliITSgeomTGeo::GetNLayers()),
114 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
117 fTrackingPhase("Default"),
123 fxTimesRhoPipeTrks(0),
124 fxOverX0ShieldTrks(0),
125 fxTimesRhoShieldTrks(0),
126 fxOverX0LayerTrks(0),
127 fxTimesRhoLayerTrks(0),
129 fITSChannelStatus(0),
132 //--------------------------------------------------------------------
133 //This is the AliITStrackerMI constructor
134 //--------------------------------------------------------------------
136 AliWarning("\"geom\" is actually a dummy argument !");
142 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
143 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
144 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
146 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
147 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
148 Double_t poff=TMath::ATan2(y,x);
150 Double_t r=TMath::Sqrt(x*x + y*y);
152 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
153 r += TMath::Sqrt(x*x + y*y);
154 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
155 r += TMath::Sqrt(x*x + y*y);
156 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
157 r += TMath::Sqrt(x*x + y*y);
160 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
162 for (Int_t j=1; j<nlad+1; j++) {
163 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
164 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
165 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
167 Double_t txyz[3]={0.};
168 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
169 m.LocalToMaster(txyz,xyz);
170 r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
171 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
173 if (phi<0) phi+=TMath::TwoPi();
174 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
176 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
177 new(&det) AliITSdetector(r,phi);
178 // compute the real radius (with misalignment)
179 TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
181 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
182 mmisal.LocalToMaster(txyz,xyz);
183 Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
184 det.SetRmisal(rmisal);
186 } // end loop on detectors
187 } // end loop on ladders
188 fForceSkippingOfLayer[i] = 0;
189 } // end loop on layers
192 fI=AliITSgeomTGeo::GetNLayers();
195 fConstraint[0]=1; fConstraint[1]=0;
197 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
198 AliITSReconstructor::GetRecoParam()->GetYVdef(),
199 AliITSReconstructor::GetRecoParam()->GetZVdef()};
200 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
201 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
202 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
203 SetVertex(xyzVtx,ersVtx);
205 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
206 for (Int_t i=0;i<100000;i++){
207 fBestTrackIndex[i]=0;
210 // store positions of centre of SPD modules (in z)
212 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
213 fSPDdetzcentre[0] = tr[2];
214 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
215 fSPDdetzcentre[1] = tr[2];
216 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
217 fSPDdetzcentre[2] = tr[2];
218 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
219 fSPDdetzcentre[3] = tr[2];
221 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
222 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
223 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
227 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
228 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
230 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
232 // only for plane efficiency evaluation
233 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
234 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
235 Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
236 if(!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)==1)
237 AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
238 if (iplane<2) fPlaneEff = new AliITSPlaneEffSPD();
239 else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
240 else fPlaneEff = new AliITSPlaneEffSSD();
241 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
242 if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
243 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
246 //------------------------------------------------------------------------
247 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
249 fBestTrack(tracker.fBestTrack),
250 fTrackToFollow(tracker.fTrackToFollow),
251 fTrackHypothesys(tracker.fTrackHypothesys),
252 fBestHypothesys(tracker.fBestHypothesys),
253 fOriginal(tracker.fOriginal),
254 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
255 fPass(tracker.fPass),
256 fAfterV0(tracker.fAfterV0),
257 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
258 fCoefficients(tracker.fCoefficients),
260 fTrackingPhase(tracker.fTrackingPhase),
261 fUseTGeo(tracker.fUseTGeo),
262 fNtracks(tracker.fNtracks),
263 fxOverX0Pipe(tracker.fxOverX0Pipe),
264 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
266 fxTimesRhoPipeTrks(0),
267 fxOverX0ShieldTrks(0),
268 fxTimesRhoShieldTrks(0),
269 fxOverX0LayerTrks(0),
270 fxTimesRhoLayerTrks(0),
271 fDebugStreamer(tracker.fDebugStreamer),
272 fITSChannelStatus(tracker.fITSChannelStatus),
273 fkDetTypeRec(tracker.fkDetTypeRec),
274 fPlaneEff(tracker.fPlaneEff) {
278 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
281 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
282 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
285 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
286 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
289 //------------------------------------------------------------------------
290 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
291 //Assignment operator
292 this->~AliITStrackerMI();
293 new(this) AliITStrackerMI(tracker);
296 //------------------------------------------------------------------------
297 AliITStrackerMI::~AliITStrackerMI()
302 if (fCoefficients) delete [] fCoefficients;
303 DeleteTrksMaterialLUT();
304 if (fDebugStreamer) {
305 //fDebugStreamer->Close();
306 delete fDebugStreamer;
308 if(fITSChannelStatus) delete fITSChannelStatus;
309 if(fPlaneEff) delete fPlaneEff;
311 //------------------------------------------------------------------------
312 void AliITStrackerMI::ReadBadFromDetTypeRec() {
313 //--------------------------------------------------------------------
314 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
316 //--------------------------------------------------------------------
318 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
320 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
322 if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
325 if(fITSChannelStatus) delete fITSChannelStatus;
326 fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
328 // ITS detectors and chips
329 Int_t i=0,j=0,k=0,ndet=0;
330 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
331 Int_t nBadDetsPerLayer=0;
332 ndet=AliITSgeomTGeo::GetNDetectors(i);
333 for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
334 for (k=1; k<ndet+1; k++) {
335 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
336 det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fkDetTypeRec);
337 if(det.IsBad()) {nBadDetsPerLayer++;}
338 } // end loop on detectors
339 } // end loop on ladders
340 Info("ReadBadFromDetTypeRec",Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
341 } // end loop on layers
345 //------------------------------------------------------------------------
346 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
347 //--------------------------------------------------------------------
348 //This function loads ITS clusters
349 //--------------------------------------------------------------------
351 TClonesArray *clusters = NULL;
352 AliITSRecPointContainer* rpcont=AliITSRecPointContainer::Instance();
353 clusters=rpcont->FetchClusters(0,cTree);
354 if(!(rpcont->IsSPDActive() || rpcont->IsSDDActive() || rpcont->IsSSDActive())){
355 AliError("ITS is not in a known running configuration: SPD, SDD and SSD are not active");
358 Int_t i=0,j=0,ndet=0;
360 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
361 ndet=fgLayers[i].GetNdetectors();
362 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
363 for (; j<jmax; j++) {
364 // if (!cTree->GetEvent(j)) continue;
365 clusters = rpcont->UncheckedGetClusters(j);
366 if(!clusters)continue;
367 Int_t ncl=clusters->GetEntriesFast();
368 SignDeltas(clusters,GetZ());
371 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
372 detector=c->GetDetectorIndex();
374 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
376 Int_t retval = fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
378 AliWarning(Form("Too many clusters on layer %d!",i));
383 // add dead zone "virtual" cluster in SPD, if there is a cluster within
384 // zwindow cm from the dead zone
385 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
386 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
387 Int_t lab[4] = {0,0,0,detector};
388 Int_t info[3] = {0,0,i};
389 Float_t q = 0.; // this identifies virtual clusters
390 Float_t hit[5] = {xdead,
392 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
393 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
395 Bool_t local = kTRUE;
396 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
397 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
398 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
399 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
400 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
401 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
402 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
403 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
404 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
405 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
406 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
407 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
408 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
409 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
410 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
411 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
412 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
413 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
414 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
416 } // "virtual" clusters in SPD
420 fgLayers[i].ResetRoad(); //road defined by the cluster density
421 fgLayers[i].SortClusters();
424 // check whether we have to skip some layers
425 SetForceSkippingOfLayer();
429 //------------------------------------------------------------------------
430 void AliITStrackerMI::UnloadClusters() {
431 //--------------------------------------------------------------------
432 //This function unloads ITS clusters
433 //--------------------------------------------------------------------
434 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
436 //------------------------------------------------------------------------
437 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
438 //--------------------------------------------------------------------
439 // Publishes all pointers to clusters known to the tracker into the
440 // passed object array.
441 // The ownership is not transfered - the caller is not expected to delete
443 //--------------------------------------------------------------------
445 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
446 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
447 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
454 //------------------------------------------------------------------------
455 Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
456 //--------------------------------------------------------------------
457 // Correction for the material between the TPC and the ITS
458 //--------------------------------------------------------------------
459 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
460 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
461 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
462 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
463 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
464 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
465 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
466 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
468 printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
474 //------------------------------------------------------------------------
475 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
476 //--------------------------------------------------------------------
477 // This functions reconstructs ITS tracks
478 // The clusters must be already loaded !
479 //--------------------------------------------------------------------
481 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
483 fTrackingPhase="Clusters2Tracks";
485 TObjArray itsTracks(15000);
487 fEsd = event; // store pointer to the esd
489 // temporary (for cosmics)
490 if(event->GetVertex()) {
491 TString title = event->GetVertex()->GetTitle();
492 if(title.Contains("cosmics")) {
493 Double_t xyz[3]={GetX(),GetY(),GetZ()};
494 Double_t exyz[3]={0.1,0.1,0.1};
500 {/* Read ESD tracks */
501 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
502 Int_t nentr=event->GetNumberOfTracks();
504 // Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
506 AliESDtrack *esd=event->GetTrack(nentr);
507 // ---- for debugging:
508 //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); }
510 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
511 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
512 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
513 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
516 t=new AliITStrackMI(*esd);
517 } catch (const Char_t *msg) {
518 //Warning("Clusters2Tracks",msg);
522 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
523 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
526 // look at the ESD mass hypothesys !
527 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
529 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
531 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
532 //track - can be V0 according to TPC
534 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
538 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
542 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
546 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
551 t->SetReconstructed(kFALSE);
552 itsTracks.AddLast(t);
553 fOriginal.AddLast(t);
555 } /* End Read ESD tracks */
559 Int_t nentr=itsTracks.GetEntriesFast();
560 fTrackHypothesys.Expand(nentr);
561 fBestHypothesys.Expand(nentr);
562 MakeCoefficients(nentr);
563 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
565 // THE TWO TRACKING PASSES
566 for (fPass=0; fPass<2; fPass++) {
567 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
568 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
569 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
570 if (t==0) continue; //this track has been already tracked
571 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
572 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
573 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
574 if (fConstraint[fPass]) {
575 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
576 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
579 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
580 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
582 ResetTrackToFollow(*t);
585 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
588 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
590 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
591 if (!besttrack) continue;
592 besttrack->SetLabel(tpcLabel);
593 // besttrack->CookdEdx();
595 besttrack->SetFakeRatio(1.);
596 CookLabel(besttrack,0.); //For comparison only
597 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
599 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
601 t->SetReconstructed(kTRUE);
603 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
605 GetBestHypothesysMIP(itsTracks);
606 } // end loop on the two tracking passes
608 if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
609 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
614 Int_t entries = fTrackHypothesys.GetEntriesFast();
615 for (Int_t ientry=0; ientry<entries; ientry++) {
616 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
617 if (array) array->Delete();
618 delete fTrackHypothesys.RemoveAt(ientry);
621 fTrackHypothesys.Delete();
622 fBestHypothesys.Delete();
624 delete [] fCoefficients;
626 DeleteTrksMaterialLUT();
628 AliInfo(Form("Number of prolonged tracks: %d out of %d ESD tracks",ntrk,noesd));
630 fTrackingPhase="Default";
634 //------------------------------------------------------------------------
635 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
636 //--------------------------------------------------------------------
637 // This functions propagates reconstructed ITS tracks back
638 // The clusters must be loaded !
639 //--------------------------------------------------------------------
640 fTrackingPhase="PropagateBack";
641 Int_t nentr=event->GetNumberOfTracks();
642 // Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
645 for (Int_t i=0; i<nentr; i++) {
646 AliESDtrack *esd=event->GetTrack(i);
648 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
649 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
653 t=new AliITStrackMI(*esd);
654 } catch (const Char_t *msg) {
655 //Warning("PropagateBack",msg);
659 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
661 ResetTrackToFollow(*t);
664 // propagate to vertex [SR, GSI 17.02.2003]
665 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
666 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
667 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
668 fTrackToFollow.StartTimeIntegral();
669 // from vertex to outside pipe
670 CorrectForPipeMaterial(&fTrackToFollow,"outward");
672 // Start time integral and add distance from current position to vertex
673 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
674 fTrackToFollow.GetXYZ(xyzTrk);
676 for (Int_t icoord=0; icoord<3; icoord++) {
677 Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
680 fTrackToFollow.StartTimeIntegral();
681 fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
683 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
684 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
685 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
689 fTrackToFollow.SetLabel(t->GetLabel());
690 //fTrackToFollow.CookdEdx();
691 CookLabel(&fTrackToFollow,0.); //For comparison only
692 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
693 //UseClusters(&fTrackToFollow);
699 AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
701 fTrackingPhase="Default";
705 //------------------------------------------------------------------------
706 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
707 //--------------------------------------------------------------------
708 // This functions refits ITS tracks using the
709 // "inward propagated" TPC tracks
710 // The clusters must be loaded !
711 //--------------------------------------------------------------------
712 fTrackingPhase="RefitInward";
714 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
716 Int_t nentr=event->GetNumberOfTracks();
717 // Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
720 for (Int_t i=0; i<nentr; i++) {
721 AliESDtrack *esd=event->GetTrack(i);
723 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
724 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
725 if (esd->GetStatus()&AliESDtrack::kTPCout)
726 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
730 t=new AliITStrackMI(*esd);
731 } catch (const Char_t *msg) {
732 //Warning("RefitInward",msg);
736 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
737 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
742 ResetTrackToFollow(*t);
743 fTrackToFollow.ResetClusters();
745 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
746 fTrackToFollow.ResetCovariance(10.);
749 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
750 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
752 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
753 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
754 AliDebug(2," refit OK");
755 fTrackToFollow.SetLabel(t->GetLabel());
756 // fTrackToFollow.CookdEdx();
757 CookdEdx(&fTrackToFollow);
759 CookLabel(&fTrackToFollow,0.0); //For comparison only
762 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
763 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
764 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
765 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
766 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
767 Double_t r[3]={0.,0.,0.};
769 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
776 AliInfo(Form("Number of refitted tracks: %d out of %d ESD tracks",ntrk,nentr));
778 fTrackingPhase="Default";
782 //------------------------------------------------------------------------
783 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
784 //--------------------------------------------------------------------
785 // Return pointer to a given cluster
786 //--------------------------------------------------------------------
787 Int_t l=(index & 0xf0000000) >> 28;
788 Int_t c=(index & 0x0fffffff) >> 00;
789 return fgLayers[l].GetCluster(c);
791 //------------------------------------------------------------------------
792 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
793 //--------------------------------------------------------------------
794 // Get track space point with index i
795 //--------------------------------------------------------------------
797 Int_t l=(index & 0xf0000000) >> 28;
798 Int_t c=(index & 0x0fffffff) >> 00;
799 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
800 Int_t idet = cl->GetDetectorIndex();
804 cl->GetGlobalXYZ(xyz);
805 cl->GetGlobalCov(cov);
807 p.SetCharge(cl->GetQ());
808 p.SetDriftTime(cl->GetDriftTime());
809 p.SetChargeRatio(cl->GetChargeRatio());
810 p.SetClusterType(cl->GetClusterType());
811 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
814 iLayer = AliGeomManager::kSPD1;
817 iLayer = AliGeomManager::kSPD2;
820 iLayer = AliGeomManager::kSDD1;
823 iLayer = AliGeomManager::kSDD2;
826 iLayer = AliGeomManager::kSSD1;
829 iLayer = AliGeomManager::kSSD2;
832 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
835 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
836 p.SetVolumeID((UShort_t)volid);
839 //------------------------------------------------------------------------
840 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
841 AliTrackPoint& p, const AliESDtrack *t) {
842 //--------------------------------------------------------------------
843 // Get track space point with index i
844 // (assign error estimated during the tracking)
845 //--------------------------------------------------------------------
847 Int_t l=(index & 0xf0000000) >> 28;
848 Int_t c=(index & 0x0fffffff) >> 00;
849 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
850 Int_t idet = cl->GetDetectorIndex();
852 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
854 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
856 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
857 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
858 Double_t alpha = t->GetAlpha();
859 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
860 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,GetBz()));
861 phi += alpha-det.GetPhi();
862 Float_t tgphi = TMath::Tan(phi);
864 Float_t tgl = t->GetTgl(); // tgl about const along track
865 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
867 Float_t errtrky,errtrkz,covyz;
868 Bool_t addMisalErr=kFALSE;
869 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
873 cl->GetGlobalXYZ(xyz);
874 // cl->GetGlobalCov(cov);
875 Float_t pos[3] = {0.,0.,0.};
876 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
877 tmpcl.GetGlobalCov(cov);
880 p.SetCharge(cl->GetQ());
881 p.SetDriftTime(cl->GetDriftTime());
882 p.SetChargeRatio(cl->GetChargeRatio());
883 p.SetClusterType(cl->GetClusterType());
885 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
888 iLayer = AliGeomManager::kSPD1;
891 iLayer = AliGeomManager::kSPD2;
894 iLayer = AliGeomManager::kSDD1;
897 iLayer = AliGeomManager::kSDD2;
900 iLayer = AliGeomManager::kSSD1;
903 iLayer = AliGeomManager::kSSD2;
906 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
909 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
911 p.SetVolumeID((UShort_t)volid);
914 //------------------------------------------------------------------------
915 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
917 //--------------------------------------------------------------------
918 // Follow prolongation tree
919 //--------------------------------------------------------------------
921 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
922 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
925 AliESDtrack * esd = otrack->GetESDtrack();
926 if (esd->GetV0Index(0)>0) {
927 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
928 // mapping of ESD track is different as ITS track in Containers
929 // Need something more stable
930 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
931 for (Int_t i=0;i<3;i++){
932 Int_t index = esd->GetV0Index(i);
934 AliESDv0 * vertex = fEsd->GetV0(index);
935 if (vertex->GetStatus()<0) continue; // rejected V0
937 if (esd->GetSign()>0) {
938 vertex->SetIndex(0,esdindex);
940 vertex->SetIndex(1,esdindex);
944 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
946 bestarray = new TObjArray(5);
947 fBestHypothesys.AddAt(bestarray,esdindex);
951 //setup tree of the prolongations
953 static AliITStrackMI tracks[7][100];
954 AliITStrackMI *currenttrack;
955 static AliITStrackMI currenttrack1;
956 static AliITStrackMI currenttrack2;
957 static AliITStrackMI backuptrack;
959 Int_t nindexes[7][100];
960 Float_t normalizedchi2[100];
961 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
962 otrack->SetNSkipped(0);
963 new (&(tracks[6][0])) AliITStrackMI(*otrack);
965 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
966 Int_t modstatus = 1; // found
970 // follow prolongations
971 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
972 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
975 AliITSlayer &layer=fgLayers[ilayer];
976 Double_t r = layer.GetR();
982 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
984 if (ntracks[ilayer]>=100) break;
985 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
986 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
987 if (ntracks[ilayer]>15+ilayer){
988 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
989 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
992 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
994 // material between SSD and SDD, SDD and SPD
996 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
998 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
1002 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
1003 Int_t idet=layer.FindDetectorIndex(phi,z);
1005 Double_t trackGlobXYZ1[3];
1006 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1008 // Get the budget to the primary vertex for the current track being prolonged
1009 Double_t budgetToPrimVertex = GetEffectiveThickness();
1011 // check if we allow a prolongation without point
1012 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1014 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1015 // propagate to the layer radius
1016 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1017 if(!vtrack->Propagate(xToGo)) continue;
1018 // apply correction for material of the current layer
1019 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1020 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1021 vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1022 vtrack->SetClIndex(ilayer,-1);
1023 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1024 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1025 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1027 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1032 // track outside layer acceptance in z
1033 if (idet<0) continue;
1035 //propagate to the intersection with the detector plane
1036 const AliITSdetector &det=layer.GetDetector(idet);
1037 new(¤ttrack2) AliITStrackMI(currenttrack1);
1038 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1039 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1040 currenttrack1.SetDetectorIndex(idet);
1041 currenttrack2.SetDetectorIndex(idet);
1042 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1045 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1047 // road in global (rphi,z) [i.e. in tracking ref. system]
1048 Double_t zmin,zmax,ymin,ymax;
1049 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1051 // select clusters in road
1052 layer.SelectClusters(zmin,zmax,ymin,ymax);
1053 //********************
1055 // Define criteria for track-cluster association
1056 Double_t msz = currenttrack1.GetSigmaZ2() +
1057 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1058 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1059 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1060 Double_t msy = currenttrack1.GetSigmaY2() +
1061 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1062 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1063 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1065 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1066 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1068 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1069 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1071 msz = 1./msz; // 1/RoadZ^2
1072 msy = 1./msy; // 1/RoadY^2
1076 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1078 const AliITSRecPoint *cl=0;
1080 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1081 Bool_t deadzoneSPD=kFALSE;
1082 currenttrack = ¤ttrack1;
1084 // check if the road contains a dead zone
1085 Bool_t noClusters = kFALSE;
1086 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1087 if (noClusters) AliDebug(2,"no clusters in road");
1088 Double_t dz=0.5*(zmax-zmin);
1089 Double_t dy=0.5*(ymax-ymin);
1090 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1091 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1092 // create a prolongation without clusters (check also if there are no clusters in the road)
1095 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1096 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1097 updatetrack->SetClIndex(ilayer,-1);
1099 modstatus = 5; // no cls in road
1100 } else if (dead==1) {
1101 modstatus = 7; // holes in z in SPD
1102 } else if (dead==2 || dead==3 || dead==4) {
1103 modstatus = 2; // dead from OCDB
1105 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1106 // apply correction for material of the current layer
1107 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1108 if (constrain) { // apply vertex constrain
1109 updatetrack->SetConstrain(constrain);
1110 Bool_t isPrim = kTRUE;
1111 if (ilayer<4) { // check that it's close to the vertex
1112 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1113 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1114 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1115 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1116 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1118 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1120 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1122 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1123 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1125 } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1126 updatetrack->SetDeadZoneProbability(ilayer,1.);
1127 } else if (dead==4) { // at least a single dead channel from OCDB
1128 updatetrack->SetDeadZoneProbability(ilayer,0.);
1135 // loop over clusters in the road
1136 while ((cl=layer.GetNextCluster(clidx))!=0) {
1137 if (ntracks[ilayer]>95) break; //space for skipped clusters
1138 Bool_t changedet =kFALSE;
1139 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
1140 Int_t idetc=cl->GetDetectorIndex();
1142 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1143 // take into account misalignment (bring track to real detector plane)
1144 Double_t xTrOrig = currenttrack->GetX();
1145 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1146 // a first cut on track-cluster distance
1147 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1148 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1149 { // cluster not associated to track
1150 AliDebug(2,"not associated");
1153 // bring track back to ideal detector plane
1154 if (!currenttrack->Propagate(xTrOrig)) continue;
1155 } else { // have to move track to cluster's detector
1156 const AliITSdetector &detc=layer.GetDetector(idetc);
1157 // a first cut on track-cluster distance
1159 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1160 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1161 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1162 continue; // cluster not associated to track
1164 new (&backuptrack) AliITStrackMI(currenttrack2);
1166 currenttrack =¤ttrack2;
1167 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1168 new (currenttrack) AliITStrackMI(backuptrack);
1172 currenttrack->SetDetectorIndex(idetc);
1173 // Get again the budget to the primary vertex
1174 // for the current track being prolonged, if had to change detector
1175 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1178 // calculate track-clusters chi2
1179 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1181 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1182 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1183 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1184 if (ntracks[ilayer]>=100) continue;
1185 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1186 updatetrack->SetClIndex(ilayer,-1);
1187 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1189 if (cl->GetQ()!=0) { // real cluster
1190 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1191 AliDebug(2,"update failed");
1194 updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1195 modstatus = 1; // found
1196 } else { // virtual cluster in dead zone
1197 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1198 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1199 modstatus = 7; // holes in z in SPD
1203 Float_t xlocnewdet,zlocnewdet;
1204 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1205 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1208 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1210 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1212 // apply correction for material of the current layer
1213 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1215 if (constrain) { // apply vertex constrain
1216 updatetrack->SetConstrain(constrain);
1217 Bool_t isPrim = kTRUE;
1218 if (ilayer<4) { // check that it's close to the vertex
1219 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1220 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1221 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1222 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1223 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1225 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1226 } //apply vertex constrain
1228 } // create new hypothesis
1230 AliDebug(2,"chi2 too large");
1233 } // loop over possible prolongations
1235 // allow one prolongation without clusters
1236 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1237 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1238 // apply correction for material of the current layer
1239 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1240 vtrack->SetClIndex(ilayer,-1);
1241 modstatus = 3; // skipped
1242 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1243 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1244 vtrack->IncrementNSkipped();
1249 } // loop over tracks in layer ilayer+1
1251 //loop over track candidates for the current layer
1257 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1258 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1259 if (normalizedchi2[itrack] <
1260 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1264 if (constrain) { // constrain
1265 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1267 } else { // !constrain
1268 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1273 // sort tracks by increasing normalized chi2
1274 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1275 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1276 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1277 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1278 } // end loop over layers
1282 // Now select tracks to be kept
1284 Int_t max = constrain ? 20 : 5;
1286 // tracks that reach layer 0 (SPD inner)
1287 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1288 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1289 if (track.GetNumberOfClusters()<2) continue;
1290 if (!constrain && track.GetNormChi2(0) >
1291 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1294 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1297 // tracks that reach layer 1 (SPD outer)
1298 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1299 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1300 if (track.GetNumberOfClusters()<4) continue;
1301 if (!constrain && track.GetNormChi2(1) >
1302 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1303 if (constrain) track.IncrementNSkipped();
1305 track.SetD(0,track.GetD(GetX(),GetY()));
1306 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1307 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1308 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1311 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1314 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1316 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1317 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1318 if (track.GetNumberOfClusters()<3) continue;
1319 if (!constrain && track.GetNormChi2(2) >
1320 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1321 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1323 track.SetD(0,track.GetD(GetX(),GetY()));
1324 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1325 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1326 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1329 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1335 // register best track of each layer - important for V0 finder
1337 for (Int_t ilayer=0;ilayer<5;ilayer++){
1338 if (ntracks[ilayer]==0) continue;
1339 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1340 if (track.GetNumberOfClusters()<1) continue;
1341 CookLabel(&track,0);
1342 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1346 // update TPC V0 information
1348 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1349 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1350 for (Int_t i=0;i<3;i++){
1351 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1352 if (index==0) break;
1353 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1354 if (vertex->GetStatus()<0) continue; // rejected V0
1356 if (otrack->GetSign()>0) {
1357 vertex->SetIndex(0,esdindex);
1360 vertex->SetIndex(1,esdindex);
1362 //find nearest layer with track info
1363 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1364 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1365 Int_t nearest = nearestold;
1366 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1367 if (ntracks[nearest]==0){
1372 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1373 if (nearestold<5&&nearest<5){
1374 Bool_t accept = track.GetNormChi2(nearest)<10;
1376 if (track.GetSign()>0) {
1377 vertex->SetParamP(track);
1378 vertex->Update(fprimvertex);
1379 //vertex->SetIndex(0,track.fESDtrack->GetID());
1380 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1382 vertex->SetParamN(track);
1383 vertex->Update(fprimvertex);
1384 //vertex->SetIndex(1,track.fESDtrack->GetID());
1385 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1387 vertex->SetStatus(vertex->GetStatus()+1);
1389 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1396 //------------------------------------------------------------------------
1397 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1399 //--------------------------------------------------------------------
1402 return fgLayers[layer];
1404 //------------------------------------------------------------------------
1405 AliITStrackerMI::AliITSlayer::AliITSlayer():
1435 //--------------------------------------------------------------------
1436 //default AliITSlayer constructor
1437 //--------------------------------------------------------------------
1438 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1439 fClusterWeight[i]=0;
1440 fClusterTracks[0][i]=-1;
1441 fClusterTracks[1][i]=-1;
1442 fClusterTracks[2][i]=-1;
1443 fClusterTracks[3][i]=-1;
1446 //------------------------------------------------------------------------
1447 AliITStrackerMI::AliITSlayer::
1448 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1477 //--------------------------------------------------------------------
1478 //main AliITSlayer constructor
1479 //--------------------------------------------------------------------
1480 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1481 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1483 //------------------------------------------------------------------------
1484 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1486 fPhiOffset(layer.fPhiOffset),
1487 fNladders(layer.fNladders),
1488 fZOffset(layer.fZOffset),
1489 fNdetectors(layer.fNdetectors),
1490 fDetectors(layer.fDetectors),
1495 fClustersCs(layer.fClustersCs),
1496 fClusterIndexCs(layer.fClusterIndexCs),
1500 fCurrentSlice(layer.fCurrentSlice),
1508 fAccepted(layer.fAccepted),
1510 fMaxSigmaClY(layer.fMaxSigmaClY),
1511 fMaxSigmaClZ(layer.fMaxSigmaClZ),
1512 fNMaxSigmaCl(layer.fNMaxSigmaCl)
1516 //------------------------------------------------------------------------
1517 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1518 //--------------------------------------------------------------------
1519 // AliITSlayer destructor
1520 //--------------------------------------------------------------------
1521 delete [] fDetectors;
1522 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1523 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1524 fClusterWeight[i]=0;
1525 fClusterTracks[0][i]=-1;
1526 fClusterTracks[1][i]=-1;
1527 fClusterTracks[2][i]=-1;
1528 fClusterTracks[3][i]=-1;
1531 //------------------------------------------------------------------------
1532 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1533 //--------------------------------------------------------------------
1534 // This function removes loaded clusters
1535 //--------------------------------------------------------------------
1536 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1537 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1538 fClusterWeight[i]=0;
1539 fClusterTracks[0][i]=-1;
1540 fClusterTracks[1][i]=-1;
1541 fClusterTracks[2][i]=-1;
1542 fClusterTracks[3][i]=-1;
1548 //------------------------------------------------------------------------
1549 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1550 //--------------------------------------------------------------------
1551 // This function reset weights of the clusters
1552 //--------------------------------------------------------------------
1553 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1554 fClusterWeight[i]=0;
1555 fClusterTracks[0][i]=-1;
1556 fClusterTracks[1][i]=-1;
1557 fClusterTracks[2][i]=-1;
1558 fClusterTracks[3][i]=-1;
1560 for (Int_t i=0; i<fN;i++) {
1561 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1562 if (cl&&cl->IsUsed()) cl->Use();
1566 //------------------------------------------------------------------------
1567 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1568 //--------------------------------------------------------------------
1569 // This function calculates the road defined by the cluster density
1570 //--------------------------------------------------------------------
1572 for (Int_t i=0; i<fN; i++) {
1573 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1575 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1577 //------------------------------------------------------------------------
1578 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1579 //--------------------------------------------------------------------
1580 //This function adds a cluster to this layer
1581 //--------------------------------------------------------------------
1582 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1588 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1590 Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
1591 Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2());
1592 if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
1593 if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
1594 if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
1595 if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
1598 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1599 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1600 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1601 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1605 //------------------------------------------------------------------------
1606 void AliITStrackerMI::AliITSlayer::SortClusters()
1611 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1612 Float_t *z = new Float_t[fN];
1613 Int_t * index = new Int_t[fN];
1615 fMaxSigmaClY=0.; //AD
1616 fMaxSigmaClZ=0.; //AD
1618 for (Int_t i=0;i<fN;i++){
1619 z[i] = fClusters[i]->GetZ();
1620 // save largest errors in y and z for this layer
1621 fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
1622 fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
1624 TMath::Sort(fN,z,index,kFALSE);
1625 for (Int_t i=0;i<fN;i++){
1626 clusters[i] = fClusters[index[i]];
1629 for (Int_t i=0;i<fN;i++){
1630 fClusters[i] = clusters[i];
1631 fZ[i] = fClusters[i]->GetZ();
1632 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1633 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1634 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1644 for (Int_t i=0;i<fN;i++){
1645 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1646 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1647 fClusterIndex[i] = i;
1651 fDy5 = (fYB[1]-fYB[0])/5.;
1652 fDy10 = (fYB[1]-fYB[0])/10.;
1653 fDy20 = (fYB[1]-fYB[0])/20.;
1654 for (Int_t i=0;i<6;i++) fN5[i] =0;
1655 for (Int_t i=0;i<11;i++) fN10[i]=0;
1656 for (Int_t i=0;i<21;i++) fN20[i]=0;
1658 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;}
1659 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;}
1660 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;}
1663 for (Int_t i=0;i<fN;i++)
1664 for (Int_t irot=-1;irot<=1;irot++){
1665 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1667 for (Int_t slice=0; slice<6;slice++){
1668 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1669 fClusters5[slice][fN5[slice]] = fClusters[i];
1670 fY5[slice][fN5[slice]] = curY;
1671 fZ5[slice][fN5[slice]] = fZ[i];
1672 fClusterIndex5[slice][fN5[slice]]=i;
1677 for (Int_t slice=0; slice<11;slice++){
1678 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1679 fClusters10[slice][fN10[slice]] = fClusters[i];
1680 fY10[slice][fN10[slice]] = curY;
1681 fZ10[slice][fN10[slice]] = fZ[i];
1682 fClusterIndex10[slice][fN10[slice]]=i;
1687 for (Int_t slice=0; slice<21;slice++){
1688 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1689 fClusters20[slice][fN20[slice]] = fClusters[i];
1690 fY20[slice][fN20[slice]] = curY;
1691 fZ20[slice][fN20[slice]] = fZ[i];
1692 fClusterIndex20[slice][fN20[slice]]=i;
1699 // consistency check
1701 for (Int_t i=0;i<fN-1;i++){
1707 for (Int_t slice=0;slice<21;slice++)
1708 for (Int_t i=0;i<fN20[slice]-1;i++){
1709 if (fZ20[slice][i]>fZ20[slice][i+1]){
1716 //------------------------------------------------------------------------
1717 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1718 //--------------------------------------------------------------------
1719 // This function returns the index of the nearest cluster
1720 //--------------------------------------------------------------------
1723 if (fCurrentSlice<0) {
1732 if (ncl==0) return 0;
1733 Int_t b=0, e=ncl-1, m=(b+e)/2;
1734 for (; b<e; m=(b+e)/2) {
1735 // if (z > fClusters[m]->GetZ()) b=m+1;
1736 if (z > zcl[m]) b=m+1;
1741 //------------------------------------------------------------------------
1742 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 {
1743 //--------------------------------------------------------------------
1744 // This function computes the rectangular road for this track
1745 //--------------------------------------------------------------------
1748 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1749 // take into account the misalignment: propagate track to misaligned detector plane
1750 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1752 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1753 TMath::Sqrt(track->GetSigmaZ2() +
1754 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1755 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1756 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1757 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1758 TMath::Sqrt(track->GetSigmaY2() +
1759 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1760 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1761 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1763 // track at boundary between detectors, enlarge road
1764 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1765 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1766 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1767 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1768 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1769 Float_t tgl = TMath::Abs(track->GetTgl());
1770 if (tgl > 1.) tgl=1.;
1771 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1772 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1773 Float_t snp = TMath::Abs(track->GetSnp());
1774 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1775 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1778 // add to the road a term (up to 2-3 mm) to deal with misalignments
1779 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1780 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1782 Double_t r = fgLayers[ilayer].GetR();
1783 zmin = track->GetZ() - dz;
1784 zmax = track->GetZ() + dz;
1785 ymin = track->GetY() + r*det.GetPhi() - dy;
1786 ymax = track->GetY() + r*det.GetPhi() + dy;
1788 // bring track back to idead detector plane
1789 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1793 //------------------------------------------------------------------------
1794 void AliITStrackerMI::AliITSlayer::
1795 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1796 //--------------------------------------------------------------------
1797 // This function sets the "window"
1798 //--------------------------------------------------------------------
1800 Double_t circle=2*TMath::Pi()*fR;
1806 // enlarge road in y by maximum cluster error on this layer (3 sigma)
1807 fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
1808 fYmax += fNMaxSigmaCl*fMaxSigmaClY;
1809 fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
1810 fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
1812 Float_t ymiddle = (fYmin+fYmax)*0.5;
1813 if (ymiddle<fYB[0]) {
1814 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1815 } else if (ymiddle>fYB[1]) {
1816 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1822 fClustersCs = fClusters;
1823 fClusterIndexCs = fClusterIndex;
1829 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1830 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1831 if (slice<0) slice=0;
1832 if (slice>20) slice=20;
1833 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1835 fCurrentSlice=slice;
1836 fClustersCs = fClusters20[fCurrentSlice];
1837 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1838 fYcs = fY20[fCurrentSlice];
1839 fZcs = fZ20[fCurrentSlice];
1840 fNcs = fN20[fCurrentSlice];
1845 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1846 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1847 if (slice<0) slice=0;
1848 if (slice>10) slice=10;
1849 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1851 fCurrentSlice=slice;
1852 fClustersCs = fClusters10[fCurrentSlice];
1853 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1854 fYcs = fY10[fCurrentSlice];
1855 fZcs = fZ10[fCurrentSlice];
1856 fNcs = fN10[fCurrentSlice];
1861 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1862 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1863 if (slice<0) slice=0;
1864 if (slice>5) slice=5;
1865 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1867 fCurrentSlice=slice;
1868 fClustersCs = fClusters5[fCurrentSlice];
1869 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1870 fYcs = fY5[fCurrentSlice];
1871 fZcs = fZ5[fCurrentSlice];
1872 fNcs = fN5[fCurrentSlice];
1876 fI = FindClusterIndex(fZmin);
1877 fImax = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
1883 //------------------------------------------------------------------------
1884 Int_t AliITStrackerMI::AliITSlayer::
1885 FindDetectorIndex(Double_t phi, Double_t z) const {
1886 //--------------------------------------------------------------------
1887 //This function finds the detector crossed by the track
1888 //--------------------------------------------------------------------
1890 if (fZOffset<0) // old geometry
1891 dphi = -(phi-fPhiOffset);
1892 else // new geometry
1893 dphi = phi-fPhiOffset;
1896 if (dphi < 0) dphi += 2*TMath::Pi();
1897 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1898 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1899 if (np>=fNladders) np-=fNladders;
1900 if (np<0) np+=fNladders;
1903 Double_t dz=fZOffset-z;
1904 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1905 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1906 if (nz>=fNdetectors) return -1;
1907 if (nz<0) return -1;
1909 // ad hoc correction for 3rd ladder of SDD inner layer,
1910 // which is reversed (rotated by pi around local y)
1911 // this correction is OK only from AliITSv11Hybrid onwards
1912 if (GetR()>12. && GetR()<20.) { // SDD inner
1913 if(np==2) { // 3rd ladder
1914 Double_t posMod252[3];
1915 AliITSgeomTGeo::GetTranslation(252,posMod252);
1916 // check the Z coordinate of Mod 252: if negative
1917 // (old SDD geometry in AliITSv11Hybrid)
1918 // the swap of numeration whould be applied
1919 if(posMod252[2]<0.){
1920 nz = (fNdetectors-1) - nz;
1924 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1927 return np*fNdetectors + nz;
1929 //------------------------------------------------------------------------
1930 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1932 //--------------------------------------------------------------------
1933 // This function returns clusters within the "window"
1934 //--------------------------------------------------------------------
1936 if (fCurrentSlice<0) {
1937 Double_t rpi2 = 2.*fR*TMath::Pi();
1938 for (Int_t i=fI; i<fImax; i++) {
1941 if (fYmax<y) y -= rpi2;
1942 if (fYmin>y) y += rpi2;
1943 if (y<fYmin) continue;
1944 if (y>fYmax) continue;
1946 // skip clusters that are in "extended" road but they
1947 // 3sigma error does not touch the original road
1948 if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
1949 if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
1951 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1954 return fClusters[i];
1957 for (Int_t i=fI; i<fImax; i++) {
1958 if (fYcs[i]<fYmin) continue;
1959 if (fYcs[i]>fYmax) continue;
1960 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1961 ci=fClusterIndexCs[i];
1963 return fClustersCs[i];
1968 //------------------------------------------------------------------------
1969 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1971 //--------------------------------------------------------------------
1972 // This function returns the layer thickness at this point (units X0)
1973 //--------------------------------------------------------------------
1975 x0=AliITSRecoParam::GetX0Air();
1976 if (43<fR&&fR<45) { //SSD2
1979 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1980 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1981 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1982 for (Int_t i=0; i<12; i++) {
1983 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1984 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1988 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1989 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1993 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1994 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1997 if (37<fR&&fR<41) { //SSD1
2000 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2001 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2002 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2003 for (Int_t i=0; i<11; i++) {
2004 if (TMath::Abs(z-3.9*i)<0.15) {
2005 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2009 if (TMath::Abs(z+3.9*i)<0.15) {
2010 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2014 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2015 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2018 if (13<fR&&fR<26) { //SDD
2021 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2023 if (TMath::Abs(y-1.80)<0.55) {
2025 for (Int_t j=0; j<20; j++) {
2026 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2027 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2030 if (TMath::Abs(y+1.80)<0.55) {
2032 for (Int_t j=0; j<20; j++) {
2033 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2034 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2038 for (Int_t i=0; i<4; i++) {
2039 if (TMath::Abs(z-7.3*i)<0.60) {
2041 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2044 if (TMath::Abs(z+7.3*i)<0.60) {
2046 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2051 if (6<fR&&fR<8) { //SPD2
2052 Double_t dd=0.0063; x0=21.5;
2054 if (TMath::Abs(y-3.08)>0.5) d+=dd;
2055 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2057 if (3<fR&&fR<5) { //SPD1
2058 Double_t dd=0.0063; x0=21.5;
2060 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2061 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2066 //------------------------------------------------------------------------
2067 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2069 fRmisal(det.fRmisal),
2071 fSinPhi(det.fSinPhi),
2072 fCosPhi(det.fCosPhi),
2078 fNChips(det.fNChips),
2079 fChipIsBad(det.fChipIsBad)
2083 //------------------------------------------------------------------------
2084 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2085 const AliITSDetTypeRec *detTypeRec)
2087 //--------------------------------------------------------------------
2088 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2089 //--------------------------------------------------------------------
2091 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2092 // while in the tracker they start from 0 for each layer
2093 for(Int_t il=0; il<ilayer; il++)
2094 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2097 if (ilayer==0 || ilayer==1) { // ---------- SPD
2099 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2101 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2104 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2108 // Get calibration from AliITSDetTypeRec
2109 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2110 calib->SetModuleIndex(idet);
2111 AliITSCalibration *calibSPDdead = 0;
2112 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2113 if (calib->IsBad() ||
2114 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2117 // printf("lay %d bad %d\n",ilayer,idet);
2120 // Get segmentation from AliITSDetTypeRec
2121 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2123 // Read info about bad chips
2124 fNChips = segm->GetMaximumChipIndex()+1;
2125 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2126 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2127 fChipIsBad = new Bool_t[fNChips];
2128 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2129 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2130 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2131 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2136 //------------------------------------------------------------------------
2137 Double_t AliITStrackerMI::GetEffectiveThickness()
2139 //--------------------------------------------------------------------
2140 // Returns the thickness between the current layer and the vertex (units X0)
2141 //--------------------------------------------------------------------
2144 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2145 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2146 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2150 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2151 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2155 Double_t xn=fgLayers[fI].GetR();
2156 for (Int_t i=0; i<fI; i++) {
2157 Double_t xi=fgLayers[i].GetR();
2158 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2164 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2165 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2168 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2169 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2173 //------------------------------------------------------------------------
2174 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2175 //-------------------------------------------------------------------
2176 // This function returns number of clusters within the "window"
2177 //--------------------------------------------------------------------
2179 for (Int_t i=fI; i<fN; i++) {
2180 const AliITSRecPoint *c=fClusters[i];
2181 if (c->GetZ() > fZmax) break;
2182 if (c->IsUsed()) continue;
2183 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2184 Double_t y=fR*det.GetPhi() + c->GetY();
2186 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2187 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2189 if (y<fYmin) continue;
2190 if (y>fYmax) continue;
2195 //------------------------------------------------------------------------
2196 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2197 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2199 //--------------------------------------------------------------------
2200 // This function refits the track "track" at the position "x" using
2201 // the clusters from "clusters"
2202 // If "extra"==kTRUE,
2203 // the clusters from overlapped modules get attached to "track"
2204 // If "planeff"==kTRUE,
2205 // special approach for plane efficiency evaluation is applyed
2206 //--------------------------------------------------------------------
2208 Int_t index[AliITSgeomTGeo::kNLayers];
2210 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2211 Int_t nc=clusters->GetNumberOfClusters();
2212 for (k=0; k<nc; k++) {
2213 Int_t idx=clusters->GetClusterIndex(k);
2214 Int_t ilayer=(idx&0xf0000000)>>28;
2218 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2220 //------------------------------------------------------------------------
2221 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2222 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2224 //--------------------------------------------------------------------
2225 // This function refits the track "track" at the position "x" using
2226 // the clusters from array
2227 // If "extra"==kTRUE,
2228 // the clusters from overlapped modules get attached to "track"
2229 // If "planeff"==kTRUE,
2230 // special approach for plane efficiency evaluation is applyed
2231 //--------------------------------------------------------------------
2232 Int_t index[AliITSgeomTGeo::kNLayers];
2234 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2236 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2237 index[k]=clusters[k];
2240 // special for cosmics: check which the innermost layer crossed
2242 Int_t innermostlayer=5;
2243 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2244 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2245 if(drphi < fgLayers[innermostlayer].GetR()) break;
2247 AliDebug(2,Form(" drphi %f innermost %d",drphi,innermostlayer));
2249 Int_t modstatus=1; // found
2251 Int_t from, to, step;
2252 if (xx > track->GetX()) {
2253 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2256 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2259 TString dir = (step>0 ? "outward" : "inward");
2261 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2262 AliITSlayer &layer=fgLayers[ilayer];
2263 Double_t r=layer.GetR();
2265 if (step<0 && xx>r) break;
2267 // material between SSD and SDD, SDD and SPD
2268 Double_t hI=ilayer-0.5*step;
2269 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2270 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2271 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2272 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2275 Double_t oldGlobXYZ[3];
2276 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2278 // continue if we are already beyond this layer
2279 Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2280 if(step>0 && oldGlobR > r) continue; // going outward
2281 if(step<0 && oldGlobR < r) continue; // going inward
2284 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2286 Int_t idet=layer.FindDetectorIndex(phi,z);
2288 // check if we allow a prolongation without point for large-eta tracks
2289 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2291 modstatus = 4; // out in z
2292 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2293 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2296 // apply correction for material of the current layer
2297 // add time if going outward
2298 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2302 if (idet<0) return kFALSE;
2305 const AliITSdetector &det=layer.GetDetector(idet);
2306 // only for ITS-SA tracks refit
2307 if (ilayer>1 && fTrackingPhase.Contains("RefitInward") && !(track->GetStatus()&AliESDtrack::kTPCin)) track->SetCheckInvariant(kFALSE);
2309 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2311 track->SetDetectorIndex(idet);
2312 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2314 Double_t dz,zmin,zmax,dy,ymin,ymax;
2316 const AliITSRecPoint *clAcc=0;
2317 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2319 Int_t idx=index[ilayer];
2320 if (idx>=0) { // cluster in this layer
2321 modstatus = 6; // no refit
2322 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2324 if (idet != cl->GetDetectorIndex()) {
2325 idet=cl->GetDetectorIndex();
2326 const AliITSdetector &detc=layer.GetDetector(idet);
2327 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2328 track->SetDetectorIndex(idet);
2329 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2331 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2332 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2336 modstatus = 1; // found
2341 } else { // no cluster in this layer
2343 modstatus = 3; // skipped
2344 // Plane Eff determination:
2345 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2346 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2347 UseTrackForPlaneEff(track,ilayer);
2350 modstatus = 5; // no cls in road
2352 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2353 dz = 0.5*(zmax-zmin);
2354 dy = 0.5*(ymax-ymin);
2355 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2356 if (dead==1) modstatus = 7; // holes in z in SPD
2357 if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2362 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2363 track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2365 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2368 if (extra) { // search for extra clusters in overlapped modules
2369 AliITStrackV2 tmp(*track);
2370 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2371 layer.SelectClusters(zmin,zmax,ymin,ymax);
2373 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2375 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2376 Double_t tolerance=0.1;
2377 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2378 // only clusters in another module! (overlaps)
2379 idetExtra = clExtra->GetDetectorIndex();
2380 if (idet == idetExtra) continue;
2382 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2384 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2385 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2386 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2387 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2389 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2390 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2393 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2394 track->SetExtraModule(ilayer,idetExtra);
2396 } // end search for extra clusters in overlapped modules
2398 // Correct for material of the current layer
2400 // add time if going outward
2401 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2402 track->SetCheckInvariant(kTRUE);
2403 } // end loop on layers
2405 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2409 //------------------------------------------------------------------------
2410 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2413 // calculate normalized chi2
2414 // return NormalizedChi2(track,0);
2417 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2418 // track->fdEdxMismatch=0;
2419 Float_t dedxmismatch =0;
2420 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2422 for (Int_t i = 0;i<6;i++){
2423 if (track->GetClIndex(i)>=0){
2424 Float_t cerry, cerrz;
2425 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2427 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2430 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2431 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2432 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2434 cchi2+=(0.5-ratio)*10.;
2435 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2436 dedxmismatch+=(0.5-ratio)*10.;
2440 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2441 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2442 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2443 if (i<2) chi2+=2*cl->GetDeltaProbability();
2449 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2450 track->SetdEdxMismatch(dedxmismatch);
2454 for (Int_t i = 0;i<4;i++){
2455 if (track->GetClIndex(i)>=0){
2456 Float_t cerry, cerrz;
2457 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2458 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2461 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2462 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2466 for (Int_t i = 4;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];}
2470 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2473 Float_t cerryb, cerrzb;
2474 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2475 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2478 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2479 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2484 if (track->GetESDtrack()->GetTPCsignal()>85){
2485 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2487 chi2+=(0.5-ratio)*5.;
2490 chi2+=(ratio-2.0)*3;
2494 Double_t match = TMath::Sqrt(track->GetChi22());
2495 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2496 if (!track->GetConstrain()) {
2497 if (track->GetNumberOfClusters()>2) {
2498 match/=track->GetNumberOfClusters()-2.;
2503 if (match<0) match=0;
2505 // penalty factor for missing points (NDeadZone>0), but no penalty
2506 // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2507 // or there is a dead from OCDB)
2508 Float_t deadzonefactor = 0.;
2509 if (track->GetNDeadZone()>0.) {
2510 Float_t sumDeadZoneProbability=0;
2511 for(Int_t ilay=0;ilay<6;ilay++) sumDeadZoneProbability+=track->GetDeadZoneProbability(ilay);
2512 Float_t nDeadZoneWithProbNot1=(Float_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2513 if(nDeadZoneWithProbNot1>0.) {
2514 Float_t deadZoneProbability = sumDeadZoneProbability - (Float_t)((Int_t)sumDeadZoneProbability);
2515 deadZoneProbability /= nDeadZoneWithProbNot1;
2516 deadzonefactor = 3.*(1.1-deadZoneProbability);
2520 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2521 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2522 1./(1.+track->GetNSkipped()));
2526 //------------------------------------------------------------------------
2527 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2530 // return matching chi2 between two tracks
2531 Double_t largeChi2=1000.;
2533 AliITStrackMI track3(*track2);
2534 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2536 vec(0,0)=track1->GetY() - track3.GetY();
2537 vec(1,0)=track1->GetZ() - track3.GetZ();
2538 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2539 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2540 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2543 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2544 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2545 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2546 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2547 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2549 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2550 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2551 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2552 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2554 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2555 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2556 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2558 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2559 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2561 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2564 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2565 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2568 //------------------------------------------------------------------------
2569 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2572 // return probability that given point (characterized by z position and error)
2573 // is in SPD dead zone
2575 Double_t probability = 0.;
2576 Double_t absz = TMath::Abs(zpos);
2577 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2578 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2579 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2580 Double_t zmin, zmax;
2581 if (zpos<-6.) { // dead zone at z = -7
2582 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2583 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2584 } else if (zpos>6.) { // dead zone at z = +7
2585 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2586 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2587 } else if (absz<2.) { // dead zone at z = 0
2588 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2589 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2594 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2596 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2597 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2600 //------------------------------------------------------------------------
2601 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2604 // calculate normalized chi2
2606 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2608 for (Int_t i = 0;i<6;i++){
2609 if (TMath::Abs(track->GetDy(i))>0){
2610 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2611 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2614 else{chi2[i]=10000;}
2617 TMath::Sort(6,chi2,index,kFALSE);
2618 Float_t max = float(ncl)*fac-1.;
2619 Float_t sumchi=0, sumweight=0;
2620 for (Int_t i=0;i<max+1;i++){
2621 Float_t weight = (i<max)?1.:(max+1.-i);
2622 sumchi+=weight*chi2[index[i]];
2625 Double_t normchi2 = sumchi/sumweight;
2628 //------------------------------------------------------------------------
2629 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2632 // calculate normalized chi2
2633 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2636 for (Int_t i=0;i<6;i++){
2637 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2638 Double_t sy1 = forwardtrack->GetSigmaY(i);
2639 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2640 Double_t sy2 = backtrack->GetSigmaY(i);
2641 Double_t sz2 = backtrack->GetSigmaZ(i);
2642 if (i<2){ sy2=1000.;sz2=1000;}
2644 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2645 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2647 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2648 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2650 res+= nz0*nz0+ny0*ny0;
2653 if (npoints>1) return
2654 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2655 //2*forwardtrack->fNUsed+
2656 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2657 1./(1.+forwardtrack->GetNSkipped()));
2660 //------------------------------------------------------------------------
2661 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2662 //--------------------------------------------------------------------
2663 // Return pointer to a given cluster
2664 //--------------------------------------------------------------------
2665 Int_t l=(index & 0xf0000000) >> 28;
2666 Int_t c=(index & 0x0fffffff) >> 00;
2667 return fgLayers[l].GetWeight(c);
2669 //------------------------------------------------------------------------
2670 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2672 //---------------------------------------------
2673 // register track to the list
2675 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2678 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2679 Int_t index = track->GetClusterIndex(icluster);
2680 Int_t l=(index & 0xf0000000) >> 28;
2681 Int_t c=(index & 0x0fffffff) >> 00;
2682 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2683 for (Int_t itrack=0;itrack<4;itrack++){
2684 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2685 fgLayers[l].SetClusterTracks(itrack,c,id);
2691 //------------------------------------------------------------------------
2692 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2694 //---------------------------------------------
2695 // unregister track from the list
2696 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2697 Int_t index = track->GetClusterIndex(icluster);
2698 Int_t l=(index & 0xf0000000) >> 28;
2699 Int_t c=(index & 0x0fffffff) >> 00;
2700 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2701 for (Int_t itrack=0;itrack<4;itrack++){
2702 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2703 fgLayers[l].SetClusterTracks(itrack,c,-1);
2708 //------------------------------------------------------------------------
2709 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2711 //-------------------------------------------------------------
2712 //get number of shared clusters
2713 //-------------------------------------------------------------
2715 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2716 // mean number of clusters
2717 Float_t *ny = GetNy(id), *nz = GetNz(id);
2720 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2721 Int_t index = track->GetClusterIndex(icluster);
2722 Int_t l=(index & 0xf0000000) >> 28;
2723 Int_t c=(index & 0x0fffffff) >> 00;
2724 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2726 printf("problem\n");
2728 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2732 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2733 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2734 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2736 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2739 deltan = (cl->GetNz()-nz[l]);
2741 if (deltan>2.0) continue; // extended - highly probable shared cluster
2742 weight = 2./TMath::Max(3.+deltan,2.);
2744 for (Int_t itrack=0;itrack<4;itrack++){
2745 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2747 clist[l] = (AliITSRecPoint*)GetCluster(index);
2753 track->SetNUsed(shared);
2756 //------------------------------------------------------------------------
2757 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2760 // find first shared track
2762 // mean number of clusters
2763 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2765 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2766 Int_t sharedtrack=100000;
2767 Int_t tracks[24],trackindex=0;
2768 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2770 for (Int_t icluster=0;icluster<6;icluster++){
2771 if (clusterlist[icluster]<0) continue;
2772 Int_t index = clusterlist[icluster];
2773 Int_t l=(index & 0xf0000000) >> 28;
2774 Int_t c=(index & 0x0fffffff) >> 00;
2776 printf("problem\n");
2778 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2779 //if (l>3) continue;
2780 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2783 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2784 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2785 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2787 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2790 deltan = (cl->GetNz()-nz[l]);
2792 if (deltan>2.0) continue; // extended - highly probable shared cluster
2794 for (Int_t itrack=3;itrack>=0;itrack--){
2795 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2796 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2797 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2802 if (trackindex==0) return -1;
2804 sharedtrack = tracks[0];
2806 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2809 Int_t tracks2[24], cluster[24];
2810 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2813 for (Int_t i=0;i<trackindex;i++){
2814 if (tracks[i]<0) continue;
2815 tracks2[index] = tracks[i];
2817 for (Int_t j=i+1;j<trackindex;j++){
2818 if (tracks[j]<0) continue;
2819 if (tracks[j]==tracks[i]){
2827 for (Int_t i=0;i<index;i++){
2828 if (cluster[index]>max) {
2829 sharedtrack=tracks2[index];
2836 if (sharedtrack>=100000) return -1;
2838 // make list of overlaps
2840 for (Int_t icluster=0;icluster<6;icluster++){
2841 if (clusterlist[icluster]<0) continue;
2842 Int_t index = clusterlist[icluster];
2843 Int_t l=(index & 0xf0000000) >> 28;
2844 Int_t c=(index & 0x0fffffff) >> 00;
2845 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2846 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2848 if (cl->GetNy()>2) continue;
2849 if (cl->GetNz()>2) continue;
2852 if (cl->GetNy()>3) continue;
2853 if (cl->GetNz()>3) continue;
2856 for (Int_t itrack=3;itrack>=0;itrack--){
2857 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2858 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2866 //------------------------------------------------------------------------
2867 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2869 // try to find track hypothesys without conflicts
2870 // with minimal chi2;
2871 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2872 Int_t entries1 = arr1->GetEntriesFast();
2873 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2874 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2875 Int_t entries2 = arr2->GetEntriesFast();
2876 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2878 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2879 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2880 if (track10->Pt()>0.5+track20->Pt()) return track10;
2882 for (Int_t itrack=0;itrack<entries1;itrack++){
2883 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2884 UnRegisterClusterTracks(track,trackID1);
2887 for (Int_t itrack=0;itrack<entries2;itrack++){
2888 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2889 UnRegisterClusterTracks(track,trackID2);
2893 Float_t maxconflicts=6;
2894 Double_t maxchi2 =1000.;
2896 // get weight of hypothesys - using best hypothesy
2899 Int_t list1[6],list2[6];
2900 AliITSRecPoint *clist1[6], *clist2[6] ;
2901 RegisterClusterTracks(track10,trackID1);
2902 RegisterClusterTracks(track20,trackID2);
2903 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2904 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2905 UnRegisterClusterTracks(track10,trackID1);
2906 UnRegisterClusterTracks(track20,trackID2);
2909 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2910 Float_t nerry[6],nerrz[6];
2911 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2912 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2913 for (Int_t i=0;i<6;i++){
2914 if ( (erry1[i]>0) && (erry2[i]>0)) {
2915 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2916 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2918 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2919 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2921 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2922 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2923 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2926 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2927 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2928 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2936 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2937 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2938 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2939 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2941 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2942 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2943 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2945 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2946 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2947 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2950 Double_t sumw = w1+w2;
2954 w1 = (d2+0.5)/(d1+d2+1.);
2955 w2 = (d1+0.5)/(d1+d2+1.);
2957 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2958 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2960 // get pair of "best" hypothesys
2962 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2963 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2965 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2966 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2967 //if (track1->fFakeRatio>0) continue;
2968 RegisterClusterTracks(track1,trackID1);
2969 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2970 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2972 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2973 //if (track2->fFakeRatio>0) continue;
2975 RegisterClusterTracks(track2,trackID2);
2976 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2977 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2978 UnRegisterClusterTracks(track2,trackID2);
2980 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2981 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2982 if (nskipped>0.5) continue;
2984 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2985 if (conflict1+1<cconflict1) continue;
2986 if (conflict2+1<cconflict2) continue;
2990 for (Int_t i=0;i<6;i++){
2992 Float_t c1 =0.; // conflict coeficients
2994 if (clist1[i]&&clist2[i]){
2997 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
3000 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
3002 c1 = 2./TMath::Max(3.+deltan,2.);
3003 c2 = 2./TMath::Max(3.+deltan,2.);
3009 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
3012 deltan = (clist1[i]->GetNz()-nz1[i]);
3014 c1 = 2./TMath::Max(3.+deltan,2.);
3021 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
3024 deltan = (clist2[i]->GetNz()-nz2[i]);
3026 c2 = 2./TMath::Max(3.+deltan,2.);
3032 if (TMath::Abs(track1->GetDy(i))>0.) {
3033 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
3034 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
3035 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
3036 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
3038 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
3041 if (TMath::Abs(track2->GetDy(i))>0.) {
3042 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
3043 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
3044 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
3045 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3048 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3050 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3051 if (chi21>0) sum+=w1;
3052 if (chi22>0) sum+=w2;
3055 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3056 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3057 Double_t normchi2 = 2*conflict+sumchi2/sum;
3058 if ( normchi2 <maxchi2 ){
3061 maxconflicts = conflict;
3065 UnRegisterClusterTracks(track1,trackID1);
3068 // if (maxconflicts<4 && maxchi2<th0){
3069 if (maxchi2<th0*2.){
3070 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3071 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3072 track1->SetChi2MIP(5,maxconflicts);
3073 track1->SetChi2MIP(6,maxchi2);
3074 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3075 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3076 track1->SetChi2MIP(8,index1);
3077 fBestTrackIndex[trackID1] =index1;
3078 UpdateESDtrack(track1, AliESDtrack::kITSin);
3080 else if (track10->GetChi2MIP(0)<th1){
3081 track10->SetChi2MIP(5,maxconflicts);
3082 track10->SetChi2MIP(6,maxchi2);
3083 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3084 UpdateESDtrack(track10,AliESDtrack::kITSin);
3087 for (Int_t itrack=0;itrack<entries1;itrack++){
3088 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3089 UnRegisterClusterTracks(track,trackID1);
3092 for (Int_t itrack=0;itrack<entries2;itrack++){
3093 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3094 UnRegisterClusterTracks(track,trackID2);
3097 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3098 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3099 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3100 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3101 RegisterClusterTracks(track10,trackID1);
3103 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3104 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3105 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3106 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3107 RegisterClusterTracks(track20,trackID2);
3112 //------------------------------------------------------------------------
3113 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3114 //--------------------------------------------------------------------
3115 // This function marks clusters assigned to the track
3116 //--------------------------------------------------------------------
3117 AliTracker::UseClusters(t,from);
3119 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3120 //if (c->GetQ()>2) c->Use();
3121 if (c->GetSigmaZ2()>0.1) c->Use();
3122 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3123 //if (c->GetQ()>2) c->Use();
3124 if (c->GetSigmaZ2()>0.1) c->Use();
3127 //------------------------------------------------------------------------
3128 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3130 //------------------------------------------------------------------
3131 // add track to the list of hypothesys
3132 //------------------------------------------------------------------
3134 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3135 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3137 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3139 array = new TObjArray(10);
3140 fTrackHypothesys.AddAt(array,esdindex);
3142 array->AddLast(track);
3144 //------------------------------------------------------------------------
3145 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3147 //-------------------------------------------------------------------
3148 // compress array of track hypothesys
3149 // keep only maxsize best hypothesys
3150 //-------------------------------------------------------------------
3151 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3152 if (! (fTrackHypothesys.At(esdindex)) ) return;
3153 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3154 Int_t entries = array->GetEntriesFast();
3156 //- find preliminary besttrack as a reference
3157 Float_t minchi2=10000;
3159 AliITStrackMI * besttrack=0;
3160 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3161 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3162 if (!track) continue;
3163 Float_t chi2 = NormalizedChi2(track,0);
3165 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3166 track->SetLabel(tpcLabel);
3168 track->SetFakeRatio(1.);
3169 CookLabel(track,0.); //For comparison only
3171 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3172 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3173 if (track->GetNumberOfClusters()<maxn) continue;
3174 maxn = track->GetNumberOfClusters();
3181 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3182 delete array->RemoveAt(itrack);
3186 if (!besttrack) return;
3189 //take errors of best track as a reference
3190 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3191 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3192 for (Int_t j=0;j<6;j++) {
3193 if (besttrack->GetClIndex(j)>=0){
3194 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3195 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3196 ny[j] = besttrack->GetNy(j);
3197 nz[j] = besttrack->GetNz(j);
3201 // calculate normalized chi2
3203 Float_t * chi2 = new Float_t[entries];
3204 Int_t * index = new Int_t[entries];
3205 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3206 for (Int_t itrack=0;itrack<entries;itrack++){
3207 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3209 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3210 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3211 chi2[itrack] = track->GetChi2MIP(0);
3213 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3214 delete array->RemoveAt(itrack);
3220 TMath::Sort(entries,chi2,index,kFALSE);
3221 besttrack = (AliITStrackMI*)array->At(index[0]);
3222 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3223 for (Int_t j=0;j<6;j++){
3224 if (besttrack->GetClIndex(j)>=0){
3225 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3226 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3227 ny[j] = besttrack->GetNy(j);
3228 nz[j] = besttrack->GetNz(j);
3233 // calculate one more time with updated normalized errors
3234 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3235 for (Int_t itrack=0;itrack<entries;itrack++){
3236 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3238 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3239 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3240 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3243 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3244 delete array->RemoveAt(itrack);
3249 entries = array->GetEntriesFast();
3253 TObjArray * newarray = new TObjArray();
3254 TMath::Sort(entries,chi2,index,kFALSE);
3255 besttrack = (AliITStrackMI*)array->At(index[0]);
3258 for (Int_t j=0;j<6;j++){
3259 if (besttrack->GetNz(j)>0&&besttrack->GetNy(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);
3266 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3267 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3268 Float_t minn = besttrack->GetNumberOfClusters()-3;
3270 for (Int_t i=0;i<entries;i++){
3271 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3272 if (!track) continue;
3273 if (accepted>maxcut) break;
3274 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3275 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3276 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3277 delete array->RemoveAt(index[i]);
3281 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3282 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3283 if (!shortbest) accepted++;
3285 newarray->AddLast(array->RemoveAt(index[i]));
3286 for (Int_t j=0;j<6;j++){
3288 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3289 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3290 ny[j] = track->GetNy(j);
3291 nz[j] = track->GetNz(j);
3296 delete array->RemoveAt(index[i]);
3300 delete fTrackHypothesys.RemoveAt(esdindex);
3301 fTrackHypothesys.AddAt(newarray,esdindex);
3305 delete fTrackHypothesys.RemoveAt(esdindex);
3311 //------------------------------------------------------------------------
3312 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3314 //-------------------------------------------------------------
3315 // try to find best hypothesy
3316 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3317 //-------------------------------------------------------------
3318 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3319 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3320 if (!array) return 0;
3321 Int_t entries = array->GetEntriesFast();
3322 if (!entries) return 0;
3323 Float_t minchi2 = 100000;
3324 AliITStrackMI * besttrack=0;
3326 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3327 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3328 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3329 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3331 for (Int_t i=0;i<entries;i++){
3332 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3333 if (!track) continue;
3334 Float_t sigmarfi,sigmaz;
3335 GetDCASigma(track,sigmarfi,sigmaz);
3336 track->SetDnorm(0,sigmarfi);
3337 track->SetDnorm(1,sigmaz);
3339 track->SetChi2MIP(1,1000000);
3340 track->SetChi2MIP(2,1000000);
3341 track->SetChi2MIP(3,1000000);
3344 backtrack = new(backtrack) AliITStrackMI(*track);
3345 if (track->GetConstrain()) {
3346 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3347 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3348 backtrack->ResetCovariance(10.);
3350 backtrack->ResetCovariance(10.);
3352 backtrack->ResetClusters();
3354 Double_t x = original->GetX();
3355 if (!RefitAt(x,backtrack,track)) continue;
3357 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3358 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3359 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3360 track->SetChi22(GetMatchingChi2(backtrack,original));
3362 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3363 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3364 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3367 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3369 //forward track - without constraint
3370 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3371 forwardtrack->ResetClusters();
3373 RefitAt(x,forwardtrack,track);
3374 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3375 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3376 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3378 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3379 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3380 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3381 forwardtrack->SetD(0,track->GetD(0));
3382 forwardtrack->SetD(1,track->GetD(1));
3385 AliITSRecPoint* clist[6];
3386 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3387 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3390 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3391 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3392 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3393 track->SetChi2MIP(3,1000);
3396 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3398 for (Int_t ichi=0;ichi<5;ichi++){
3399 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3401 if (chi2 < minchi2){
3402 //besttrack = new AliITStrackMI(*forwardtrack);
3404 besttrack->SetLabel(track->GetLabel());
3405 besttrack->SetFakeRatio(track->GetFakeRatio());
3407 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3408 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3409 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3413 delete forwardtrack;
3415 for (Int_t i=0;i<entries;i++){
3416 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3418 if (!track) continue;
3420 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3421 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3422 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3423 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3424 delete array->RemoveAt(i);
3434 SortTrackHypothesys(esdindex,checkmax,1);
3436 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3437 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3438 besttrack = (AliITStrackMI*)array->At(0);
3439 if (!besttrack) return 0;
3440 besttrack->SetChi2MIP(8,0);
3441 fBestTrackIndex[esdindex]=0;
3442 entries = array->GetEntriesFast();
3443 AliITStrackMI *longtrack =0;
3445 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3446 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3447 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3448 if (!track->GetConstrain()) continue;
3449 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3450 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3451 if (track->GetChi2MIP(0)>4.) continue;
3452 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3455 //if (longtrack) besttrack=longtrack;
3458 AliITSRecPoint * clist[6];
3459 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3460 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3461 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3462 RegisterClusterTracks(besttrack,esdindex);
3469 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3470 if (sharedtrack>=0){
3472 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3474 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3480 if (shared>2.5) return 0;
3481 if (shared>1.0) return besttrack;
3483 // Don't sign clusters if not gold track
3485 if (!besttrack->IsGoldPrimary()) return besttrack;
3486 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3488 if (fConstraint[fPass]){
3492 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3493 for (Int_t i=0;i<6;i++){
3494 Int_t index = besttrack->GetClIndex(i);
3495 if (index<0) continue;
3496 Int_t ilayer = (index & 0xf0000000) >> 28;
3497 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3498 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3500 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3501 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3502 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3503 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3504 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3505 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3507 Bool_t cansign = kTRUE;
3508 for (Int_t itrack=0;itrack<entries; itrack++){
3509 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3510 if (!track) continue;
3511 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3512 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3518 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3519 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3520 if (!c->IsUsed()) c->Use();
3526 //------------------------------------------------------------------------
3527 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3530 // get "best" hypothesys
3533 Int_t nentries = itsTracks.GetEntriesFast();
3534 for (Int_t i=0;i<nentries;i++){
3535 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3536 if (!track) continue;
3537 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3538 if (!array) continue;
3539 if (array->GetEntriesFast()<=0) continue;
3541 AliITStrackMI* longtrack=0;
3543 Float_t maxchi2=1000;
3544 for (Int_t j=0;j<array->GetEntriesFast();j++){
3545 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3546 if (!trackHyp) continue;
3547 if (trackHyp->GetGoldV0()) {
3548 longtrack = trackHyp; //gold V0 track taken
3551 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3552 Float_t chi2 = trackHyp->GetChi2MIP(0);
3554 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3556 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3558 if (chi2 > maxchi2) continue;
3559 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3566 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3567 if (!longtrack) {longtrack = besttrack;}
3568 else besttrack= longtrack;
3572 AliITSRecPoint * clist[6];
3573 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3575 track->SetNUsed(shared);
3576 track->SetNSkipped(besttrack->GetNSkipped());
3577 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3579 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3583 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3584 //if (sharedtrack==-1) sharedtrack=0;
3585 if (sharedtrack>=0) {
3586 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3589 if (besttrack&&fAfterV0) {
3590 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3592 if (besttrack&&fConstraint[fPass])
3593 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3594 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3595 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3596 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3602 //------------------------------------------------------------------------
3603 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3604 //--------------------------------------------------------------------
3605 //This function "cooks" a track label. If label<0, this track is fake.
3606 //--------------------------------------------------------------------
3609 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3611 track->SetChi2MIP(9,0);
3613 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3614 Int_t cindex = track->GetClusterIndex(i);
3615 Int_t l=(cindex & 0xf0000000) >> 28;
3616 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3618 for (Int_t ind=0;ind<3;ind++){
3620 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3621 AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3623 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3626 Int_t nclusters = track->GetNumberOfClusters();
3627 if (nclusters > 0) //PH Some tracks don't have any cluster
3628 track->SetFakeRatio(double(nwrong)/double(nclusters));
3630 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3632 track->SetLabel(tpcLabel);
3634 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3637 //------------------------------------------------------------------------
3638 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3641 track->SetChi2MIP(9,0);
3642 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3643 Int_t cindex = track->GetClusterIndex(i);
3644 Int_t l=(cindex & 0xf0000000) >> 28;
3645 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3646 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3648 for (Int_t ind=0;ind<3;ind++){
3649 if (cl->GetLabel(ind)==lab) isWrong=0;
3651 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3655 track->CookdEdx(low,up);
3657 //------------------------------------------------------------------------
3658 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3660 // Create some arrays
3662 if (fCoefficients) delete []fCoefficients;
3663 fCoefficients = new Float_t[ntracks*48];
3664 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3666 //------------------------------------------------------------------------
3667 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3670 // Compute predicted chi2
3672 Float_t erry,errz,covyz;
3673 Float_t theta = track->GetTgl();
3674 Float_t phi = track->GetSnp();
3675 phi = TMath::Abs(phi)*TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3676 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
3677 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()));
3678 // Take into account the mis-alignment (bring track to cluster plane)
3679 Double_t xTrOrig=track->GetX();
3680 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3681 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()));
3682 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
3683 // Bring the track back to detector plane in ideal geometry
3684 // [mis-alignment will be accounted for in UpdateMI()]
3685 if (!track->Propagate(xTrOrig)) return 1000.;
3687 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3688 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3690 chi2+=0.5*TMath::Min(delta/2,2.);
3691 chi2+=2.*cluster->GetDeltaProbability();
3694 track->SetNy(layer,ny);
3695 track->SetNz(layer,nz);
3696 track->SetSigmaY(layer,erry);
3697 track->SetSigmaZ(layer, errz);
3698 track->SetSigmaYZ(layer,covyz);
3699 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3700 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3704 //------------------------------------------------------------------------
3705 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3710 Int_t layer = (index & 0xf0000000) >> 28;
3711 track->SetClIndex(layer, index);
3712 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3713 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3714 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3715 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3719 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3722 // Take into account the mis-alignment (bring track to cluster plane)
3723 Double_t xTrOrig=track->GetX();
3724 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3725 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3726 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3727 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3729 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3732 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3733 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3734 c.SetSigmaYZ(track->GetSigmaYZ(layer));
3737 Int_t updated = track->UpdateMI(&c,chi2,index);
3738 // Bring the track back to detector plane in ideal geometry
3739 if (!track->Propagate(xTrOrig)) return 0;
3741 if(!updated) AliDebug(2,"update failed");
3745 //------------------------------------------------------------------------
3746 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3749 //DCA sigmas parameterization
3750 //to be paramterized using external parameters in future
3753 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3754 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3756 //------------------------------------------------------------------------
3757 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3760 // Clusters from delta electrons?
3762 Int_t entries = clusterArray->GetEntriesFast();
3763 if (entries<4) return;
3764 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3765 Int_t layer = cluster->GetLayer();
3766 if (layer>1) return;
3768 Int_t ncandidates=0;
3769 Float_t r = (layer>0)? 7:4;
3771 for (Int_t i=0;i<entries;i++){
3772 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3773 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3774 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3775 index[ncandidates] = i; //candidate to belong to delta electron track
3777 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3778 cl0->SetDeltaProbability(1);
3784 for (Int_t i=0;i<ncandidates;i++){
3785 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3786 if (cl0->GetDeltaProbability()>0.8) continue;
3789 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3790 sumy=sumz=sumy2=sumyz=sumw=0.0;
3791 for (Int_t j=0;j<ncandidates;j++){
3793 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3795 Float_t dz = cl0->GetZ()-cl1->GetZ();
3796 Float_t dy = cl0->GetY()-cl1->GetY();
3797 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3798 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3799 y[ncl] = cl1->GetY();
3800 z[ncl] = cl1->GetZ();
3801 sumy+= y[ncl]*weight;
3802 sumz+= z[ncl]*weight;
3803 sumy2+=y[ncl]*y[ncl]*weight;
3804 sumyz+=y[ncl]*z[ncl]*weight;
3809 if (ncl<4) continue;
3810 Float_t det = sumw*sumy2 - sumy*sumy;
3812 if (TMath::Abs(det)>0.01){
3813 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3814 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3815 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3818 Float_t z0 = sumyz/sumy;
3819 delta = TMath::Abs(cl0->GetZ()-z0);
3822 cl0->SetDeltaProbability(1-20.*delta);
3826 //------------------------------------------------------------------------
3827 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3832 track->UpdateESDtrack(flags);
3833 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3834 if (oldtrack) delete oldtrack;
3835 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3836 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3837 printf("Problem\n");
3840 //------------------------------------------------------------------------
3841 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3843 // Get nearest upper layer close to the point xr.
3844 // rough approximation
3846 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3847 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3849 for (Int_t i=0;i<6;i++){
3850 if (radius<kRadiuses[i]){
3857 //------------------------------------------------------------------------
3858 void AliITStrackerMI::BuildMaterialLUT(TString material) {
3859 //--------------------------------------------------------------------
3860 // Fill a look-up table with mean material
3861 //--------------------------------------------------------------------
3865 Double_t point1[3],point2[3];
3866 Double_t phi,cosphi,sinphi,z;
3867 // 0-5 layers, 6 pipe, 7-8 shields
3868 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
3869 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
3871 Int_t ifirst=0,ilast=0;
3872 if(material.Contains("Pipe")) {
3874 } else if(material.Contains("Shields")) {
3876 } else if(material.Contains("Layers")) {
3879 Error("BuildMaterialLUT","Wrong layer name\n");
3882 for(Int_t imat=ifirst; imat<=ilast; imat++) {
3883 Double_t param[5]={0.,0.,0.,0.,0.};
3884 for (Int_t i=0; i<n; i++) {
3885 phi = 2.*TMath::Pi()*gRandom->Rndm();
3886 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
3887 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
3888 point1[0] = rmin[imat]*cosphi;
3889 point1[1] = rmin[imat]*sinphi;
3891 point2[0] = rmax[imat]*cosphi;
3892 point2[1] = rmax[imat]*sinphi;
3894 AliTracker::MeanMaterialBudget(point1,point2,mparam);
3895 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
3897 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
3899 fxOverX0Layer[imat] = param[1];
3900 fxTimesRhoLayer[imat] = param[0]*param[4];
3901 } else if(imat==6) {
3902 fxOverX0Pipe = param[1];
3903 fxTimesRhoPipe = param[0]*param[4];
3904 } else if(imat==7) {
3905 fxOverX0Shield[0] = param[1];
3906 fxTimesRhoShield[0] = param[0]*param[4];
3907 } else if(imat==8) {
3908 fxOverX0Shield[1] = param[1];
3909 fxTimesRhoShield[1] = param[0]*param[4];
3913 printf("%s\n",material.Data());
3914 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
3915 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
3916 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
3917 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
3918 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
3919 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
3920 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
3921 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
3922 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
3926 //------------------------------------------------------------------------
3927 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
3928 TString direction) {
3929 //-------------------------------------------------------------------
3930 // Propagate beyond beam pipe and correct for material
3931 // (material budget in different ways according to fUseTGeo value)
3932 // Add time if going outward (PropagateTo or PropagateToTGeo)
3933 //-------------------------------------------------------------------
3935 // Define budget mode:
3936 // 0: material from AliITSRecoParam (hard coded)
3937 // 1: material from TGeo in one step (on the fly)
3938 // 2: material from lut
3939 // 3: material from TGeo in one step (same for all hypotheses)
3952 if(fTrackingPhase.Contains("Clusters2Tracks"))
3953 { mode=3; } else { mode=1; }
3956 if(fTrackingPhase.Contains("Clusters2Tracks"))
3957 { mode=3; } else { mode=2; }
3963 if(fTrackingPhase.Contains("Default")) mode=0;
3965 Int_t index=fCurrentEsdTrack;
3967 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
3968 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
3970 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
3972 Double_t xOverX0,x0,lengthTimesMeanDensity;
3976 xOverX0 = AliITSRecoParam::GetdPipe();
3977 x0 = AliITSRecoParam::GetX0Be();
3978 lengthTimesMeanDensity = xOverX0*x0;
3979 lengthTimesMeanDensity *= dir;
3980 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3983 if (!t->PropagateToTGeo(xToGo,1)) return 0;
3986 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
3987 xOverX0 = fxOverX0Pipe;
3988 lengthTimesMeanDensity = fxTimesRhoPipe;
3989 lengthTimesMeanDensity *= dir;
3990 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3993 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
3994 if(fxOverX0PipeTrks[index]<0) {
3995 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
3996 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
3997 ((1.-t->GetSnp())*(1.+t->GetSnp())));
3998 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
3999 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4002 xOverX0 = fxOverX0PipeTrks[index];
4003 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4004 lengthTimesMeanDensity *= dir;
4005 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4011 //------------------------------------------------------------------------
4012 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4014 TString direction) {
4015 //-------------------------------------------------------------------
4016 // Propagate beyond SPD or SDD shield and correct for material
4017 // (material budget in different ways according to fUseTGeo value)
4018 // Add time if going outward (PropagateTo or PropagateToTGeo)
4019 //-------------------------------------------------------------------
4021 // Define budget mode:
4022 // 0: material from AliITSRecoParam (hard coded)
4023 // 1: material from TGeo in steps of X cm (on the fly)
4024 // X = AliITSRecoParam::GetStepSizeTGeo()
4025 // 2: material from lut
4026 // 3: material from TGeo in one step (same for all hypotheses)
4039 if(fTrackingPhase.Contains("Clusters2Tracks"))
4040 { mode=3; } else { mode=1; }
4043 if(fTrackingPhase.Contains("Clusters2Tracks"))
4044 { mode=3; } else { mode=2; }
4050 if(fTrackingPhase.Contains("Default")) mode=0;
4052 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4054 Int_t shieldindex=0;
4055 if (shield.Contains("SDD")) { // SDDouter
4056 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4058 } else if (shield.Contains("SPD")) { // SPDouter
4059 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4062 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4066 // do nothing if we are already beyond the shield
4067 Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4068 if(dir<0 && rTrack > rToGo) return 1; // going outward
4069 if(dir>0 && rTrack < rToGo) return 1; // going inward
4073 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4075 Int_t index=2*fCurrentEsdTrack+shieldindex;
4077 Double_t xOverX0,x0,lengthTimesMeanDensity;
4082 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4083 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4084 lengthTimesMeanDensity = xOverX0*x0;
4085 lengthTimesMeanDensity *= dir;
4086 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4089 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4090 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4093 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4094 xOverX0 = fxOverX0Shield[shieldindex];
4095 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4096 lengthTimesMeanDensity *= dir;
4097 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4100 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4101 if(fxOverX0ShieldTrks[index]<0) {
4102 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4103 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4104 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4105 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4106 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4109 xOverX0 = fxOverX0ShieldTrks[index];
4110 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4111 lengthTimesMeanDensity *= dir;
4112 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4118 //------------------------------------------------------------------------
4119 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4121 Double_t oldGlobXYZ[3],
4122 TString direction) {
4123 //-------------------------------------------------------------------
4124 // Propagate beyond layer and correct for material
4125 // (material budget in different ways according to fUseTGeo value)
4126 // Add time if going outward (PropagateTo or PropagateToTGeo)
4127 //-------------------------------------------------------------------
4129 // Define budget mode:
4130 // 0: material from AliITSRecoParam (hard coded)
4131 // 1: material from TGeo in stepsof X cm (on the fly)
4132 // X = AliITSRecoParam::GetStepSizeTGeo()
4133 // 2: material from lut
4134 // 3: material from TGeo in one step (same for all hypotheses)
4147 if(fTrackingPhase.Contains("Clusters2Tracks"))
4148 { mode=3; } else { mode=1; }
4151 if(fTrackingPhase.Contains("Clusters2Tracks"))
4152 { mode=3; } else { mode=2; }
4158 if(fTrackingPhase.Contains("Default")) mode=0;
4160 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4162 Double_t r=fgLayers[layerindex].GetR();
4163 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4165 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4167 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4169 Int_t index=6*fCurrentEsdTrack+layerindex;
4172 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4175 // back before material (no correction)
4177 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4178 if (!t->GetLocalXat(rOld,xOld)) return 0;
4179 if (!t->Propagate(xOld)) return 0;
4183 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4184 lengthTimesMeanDensity = xOverX0*x0;
4185 lengthTimesMeanDensity *= dir;
4186 // Bring the track beyond the material
4187 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4190 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4191 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4194 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4195 xOverX0 = fxOverX0Layer[layerindex];
4196 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4197 lengthTimesMeanDensity *= dir;
4198 // Bring the track beyond the material
4199 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4202 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4203 if(fxOverX0LayerTrks[index]<0) {
4204 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4205 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4206 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4207 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4208 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4209 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4212 xOverX0 = fxOverX0LayerTrks[index];
4213 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4214 lengthTimesMeanDensity *= dir;
4215 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4222 //------------------------------------------------------------------------
4223 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4224 //-----------------------------------------------------------------
4225 // Initialize LUT for storing material for each prolonged track
4226 //-----------------------------------------------------------------
4227 fxOverX0PipeTrks = new Float_t[ntracks];
4228 fxTimesRhoPipeTrks = new Float_t[ntracks];
4229 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4230 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4231 fxOverX0LayerTrks = new Float_t[ntracks*6];
4232 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4234 for(Int_t i=0; i<ntracks; i++) {
4235 fxOverX0PipeTrks[i] = -1.;
4236 fxTimesRhoPipeTrks[i] = -1.;
4238 for(Int_t j=0; j<ntracks*2; j++) {
4239 fxOverX0ShieldTrks[j] = -1.;
4240 fxTimesRhoShieldTrks[j] = -1.;
4242 for(Int_t k=0; k<ntracks*6; k++) {
4243 fxOverX0LayerTrks[k] = -1.;
4244 fxTimesRhoLayerTrks[k] = -1.;
4251 //------------------------------------------------------------------------
4252 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4253 //-----------------------------------------------------------------
4254 // Delete LUT for storing material for each prolonged track
4255 //-----------------------------------------------------------------
4256 if(fxOverX0PipeTrks) {
4257 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4259 if(fxOverX0ShieldTrks) {
4260 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4263 if(fxOverX0LayerTrks) {
4264 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4266 if(fxTimesRhoPipeTrks) {
4267 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4269 if(fxTimesRhoShieldTrks) {
4270 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4272 if(fxTimesRhoLayerTrks) {
4273 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4277 //------------------------------------------------------------------------
4278 void AliITStrackerMI::SetForceSkippingOfLayer() {
4279 //-----------------------------------------------------------------
4280 // Check if we are forced to skip layers
4281 // either we set to skip them in RecoParam
4282 // or they were off during data-taking
4283 //-----------------------------------------------------------------
4285 const AliEventInfo *eventInfo = GetEventInfo();
4287 for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
4288 fForceSkippingOfLayer[l] = 0;
4290 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
4294 AliITSReconstructor::GetRecoParam()->GetSkipSubdetsNotInTriggerCluster()) {
4295 AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
4297 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
4298 } else if(l==2 || l==3) {
4299 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1;
4301 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
4307 //------------------------------------------------------------------------
4308 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4309 Int_t ilayer,Int_t idet) const {
4310 //-----------------------------------------------------------------
4311 // This method is used to decide whether to allow a prolongation
4312 // without clusters, because we want to skip the layer.
4313 // In this case the return value is > 0:
4314 // return 1: the user requested to skip a layer
4315 // return 2: track outside z acceptance
4316 //-----------------------------------------------------------------
4318 if (ForceSkippingOfLayer(ilayer)) return 1;
4320 Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
4322 if (idet<0 && // out in z
4323 ilayer>innerLayCanSkip &&
4324 AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4325 // check if track will cross SPD outer layer
4326 Double_t phiAtSPD2,zAtSPD2;
4327 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4328 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4330 return 2; // always allow skipping, changed on 05.11.2009
4335 //------------------------------------------------------------------------
4336 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4337 Int_t ilayer,Int_t idet,
4338 Double_t dz,Double_t dy,
4339 Bool_t noClusters) const {
4340 //-----------------------------------------------------------------
4341 // This method is used to decide whether to allow a prolongation
4342 // without clusters, because there is a dead zone in the road.
4343 // In this case the return value is > 0:
4344 // return 1: dead zone at z=0,+-7cm in SPD
4345 // return 2: all road is "bad" (dead or noisy) from the OCDB
4346 // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4347 // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4348 //-----------------------------------------------------------------
4350 // check dead zones at z=0,+-7cm in the SPD
4351 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4352 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4353 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4354 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4355 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4356 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4357 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4358 for (Int_t i=0; i<3; i++)
4359 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4360 AliDebug(2,Form("crack SPD %d",ilayer));
4365 // check bad zones from OCDB
4366 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4368 if (idet<0) return 0;
4370 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4373 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4374 if (ilayer==0 || ilayer==1) { // ---------- SPD
4376 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4378 detSizeFactorX *= 2.;
4379 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4382 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4383 if (detType==2) segm->SetLayer(ilayer+1);
4384 Float_t detSizeX = detSizeFactorX*segm->Dx();
4385 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4387 // check if the road overlaps with bad chips
4389 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
4390 Float_t zlocmin = zloc-dz;
4391 Float_t zlocmax = zloc+dz;
4392 Float_t xlocmin = xloc-dy;
4393 Float_t xlocmax = xloc+dy;
4394 Int_t chipsInRoad[100];
4396 // check if road goes out of detector
4397 Bool_t touchNeighbourDet=kFALSE;
4398 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4399 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4400 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4401 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4402 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));
4404 // check if this detector is bad
4406 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4407 if(!touchNeighbourDet) {
4408 return 2; // all detectors in road are bad
4410 return 3; // at least one is bad
4414 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4415 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4416 if (!nChipsInRoad) return 0;
4418 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4419 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4420 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4421 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4422 if (det.IsChipBad(chipsInRoad[iCh])) {
4430 if(!touchNeighbourDet) {
4431 AliDebug(2,"all bad in road");
4432 return 2; // all chips in road are bad
4434 return 3; // at least a bad chip in road
4439 AliDebug(2,"at least a bad in road");
4440 return 3; // at least a bad chip in road
4444 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4445 || !noClusters) return 0;
4447 // There are no clusters in road: check if there is at least
4448 // a bad SPD pixel or SDD anode or SSD strips on both sides
4450 Int_t idetInITS=idet;
4451 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4453 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4454 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4457 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4461 //------------------------------------------------------------------------
4462 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4463 const AliITStrackMI *track,
4464 Float_t &xloc,Float_t &zloc) const {
4465 //-----------------------------------------------------------------
4466 // Gives position of track in local module ref. frame
4467 //-----------------------------------------------------------------
4472 if(idet<0) return kTRUE; // track out of z acceptance of layer
4474 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4476 Int_t lad = Int_t(idet/ndet) + 1;
4478 Int_t det = idet - (lad-1)*ndet + 1;
4480 Double_t xyzGlob[3],xyzLoc[3];
4482 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4483 // take into account the misalignment: xyz at real detector plane
4484 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4486 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4488 xloc = (Float_t)xyzLoc[0];
4489 zloc = (Float_t)xyzLoc[2];
4493 //------------------------------------------------------------------------
4494 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
4496 // Method to be optimized further:
4497 // Aim: decide whether a track can be used for PlaneEff evaluation
4498 // the decision is taken based on the track quality at the layer under study
4499 // no information on the clusters on this layer has to be used
4500 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4501 // the cut is done on number of sigmas from the boundaries
4503 // Input: Actual track, layer [0,5] under study
4505 // Return: kTRUE if this is a good track
4507 // it will apply a pre-selection to obtain good quality tracks.
4508 // Here also you will have the possibility to put a control on the
4509 // impact point of the track on the basic block, in order to exclude border regions
4510 // this will be done by calling a proper method of the AliITSPlaneEff class.
4512 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4513 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4515 Int_t index[AliITSgeomTGeo::kNLayers];
4517 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4519 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4520 index[k]=clusters[k];
4524 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4525 AliITSlayer &layer=fgLayers[ilayer];
4526 Double_t r=layer.GetR();
4527 AliITStrackMI tmp(*track);
4529 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4531 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) {
4532 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4533 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4534 if (tmp.GetClIndex(lay)>=0) ncl++;
4536 Bool_t nextout = kFALSE;
4537 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4538 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4539 Bool_t nextin = kFALSE;
4540 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4541 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4542 if(ncl<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
4544 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
4545 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
4546 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
4547 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
4551 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4552 Int_t idet=layer.FindDetectorIndex(phi,z);
4553 if(idet<0) { AliInfo(Form("cannot find detector"));
4556 // here check if it has good Chi Square.
4558 //propagate to the intersection with the detector plane
4559 const AliITSdetector &det=layer.GetDetector(idet);
4560 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4564 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
4565 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4566 if(key>fPlaneEff->Nblock()) return kFALSE;
4567 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4568 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4570 // DEFINITION OF SEARCH ROAD FOR accepting a track
4572 //For the time being they are hard-wired, later on from AliITSRecoParam
4573 // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
4574 // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
4577 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4578 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4579 // done for RecPoints
4581 // exclude tracks at boundary between detectors
4582 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
4583 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4584 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
4585 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
4586 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
4588 if ( (locx-dx < blockXmn+boundaryWidth) ||
4589 (locx+dx > blockXmx-boundaryWidth) ||
4590 (locz-dz < blockZmn+boundaryWidth) ||
4591 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
4594 //------------------------------------------------------------------------
4595 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
4597 // This Method has to be optimized! For the time-being it uses the same criteria
4598 // as those used in the search of extra clusters for overlapping modules.
4600 // Method Purpose: estabilish whether a track has produced a recpoint or not
4601 // in the layer under study (For Plane efficiency)
4603 // inputs: AliITStrackMI* track (pointer to a usable track)
4605 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
4606 // traversed by this very track. In details:
4607 // - if a cluster can be associated to the track then call
4608 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
4609 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
4612 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
4613 AliITSlayer &layer=fgLayers[ilayer];
4614 Double_t r=layer.GetR();
4615 AliITStrackMI tmp(*track);
4619 if (!tmp.GetPhiZat(r,phi,z)) return;
4620 Int_t idet=layer.FindDetectorIndex(phi,z);
4622 if(idet<0) { AliInfo(Form("cannot find detector"));
4626 //propagate to the intersection with the detector plane
4627 const AliITSdetector &det=layer.GetDetector(idet);
4628 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
4632 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
4634 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
4635 TMath::Sqrt(tmp.GetSigmaZ2() +
4636 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4637 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4638 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
4639 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
4640 TMath::Sqrt(tmp.GetSigmaY2() +
4641 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4642 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4643 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
4645 // road in global (rphi,z) [i.e. in tracking ref. system]
4646 Double_t zmin = tmp.GetZ() - dz;
4647 Double_t zmax = tmp.GetZ() + dz;
4648 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
4649 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
4651 // select clusters in road
4652 layer.SelectClusters(zmin,zmax,ymin,ymax);
4654 // Define criteria for track-cluster association
4655 Double_t msz = tmp.GetSigmaZ2() +
4656 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4657 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4658 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
4659 Double_t msy = tmp.GetSigmaY2() +
4660 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4661 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4662 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
4663 if (tmp.GetConstrain()) {
4664 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
4665 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
4667 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
4668 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
4670 msz = 1./msz; // 1/RoadZ^2
4671 msy = 1./msy; // 1/RoadY^2
4674 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
4676 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
4677 //Double_t tolerance=0.2;
4678 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
4679 idetc = cl->GetDetectorIndex();
4680 if(idet!=idetc) continue;
4681 //Int_t ilay = cl->GetLayer();
4683 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
4684 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
4686 Double_t chi2=tmp.GetPredictedChi2(cl);
4687 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
4691 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
4693 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
4694 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4695 if(key>fPlaneEff->Nblock()) return;
4696 Bool_t found=kFALSE;
4699 while ((cl=layer.GetNextCluster(clidx))!=0) {
4700 idetc = cl->GetDetectorIndex();
4701 if(idet!=idetc) continue;
4702 // here real control to see whether the cluster can be associated to the track.
4703 // cluster not associated to track
4704 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
4705 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
4706 // calculate track-clusters chi2
4707 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
4708 // in particular, the error associated to the cluster
4709 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
4711 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
4713 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
4714 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
4715 // track->SetExtraModule(ilayer,idetExtra);
4717 if(!fPlaneEff->UpDatePlaneEff(found,key))
4718 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
4719 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
4720 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
4721 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
4722 Int_t cltype[2]={-999,-999};
4726 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4727 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4730 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
4731 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
4732 cltype[0]=layer.GetCluster(ci)->GetNy();
4733 cltype[1]=layer.GetCluster(ci)->GetNz();
4735 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
4736 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
4737 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
4738 // It is computed properly by calling the method
4739 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4741 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
4742 //if (tmp.PropagateTo(x,0.,0.)) {
4743 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
4744 AliCluster c(*layer.GetCluster(ci));
4745 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
4746 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
4747 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
4748 clu[2]=TMath::Sqrt(c.GetSigmaY2());
4749 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
4752 fPlaneEff->FillHistos(key,found,tr,clu,cltype);