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>
39 #include "AliGeomManager.h"
40 #include "AliITSPlaneEff.h"
41 #include "AliTrackPointArray.h"
42 #include "AliESDEvent.h"
43 #include "AliESDV0Params.h"
44 #include "AliESDtrack.h"
46 #include "AliITSChannelStatus.h"
47 #include "AliITSDetTypeRec.h"
48 #include "AliITSRecPoint.h"
49 #include "AliITSRecPointContainer.h"
50 #include "AliITSgeomTGeo.h"
51 #include "AliITSReconstructor.h"
52 #include "AliITSClusterParam.h"
53 #include "AliITSsegmentation.h"
54 #include "AliITSCalibration.h"
55 #include "AliITSPlaneEffSPD.h"
56 #include "AliITSPlaneEffSDD.h"
57 #include "AliITSPlaneEffSSD.h"
58 #include "AliITSV0Finder.h"
59 #include "AliITStrackerMI.h"
60 #include "AliMathBase.h"
63 ClassImp(AliITStrackerMI)
65 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
67 AliITStrackerMI::AliITStrackerMI():AliTracker(),
77 fLastLayerToTrackTo(0),
80 fTrackingPhase("Default"),
84 fSelectBestMIP03(kFALSE),
85 fUseImproveKalman(kFALSE),
89 fxTimesRhoPipeTrks(0),
90 fxOverX0ShieldTrks(0),
91 fxTimesRhoShieldTrks(0),
93 fxTimesRhoLayerTrks(0),
98 fSPDChipIntPlaneEff(0),
102 //Default constructor
104 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
106 fxOverX0Shield[i]=-1.;
107 fxTimesRhoShield[i]=-1.;
110 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
111 fOriginal.SetOwner();
112 for(i=0;i<AliITSgeomTGeo::kNLayers;i++)fForceSkippingOfLayer[i]=0;
113 for(i=0;i<100000;i++)fBestTrackIndex[i]=0;
114 fITSPid=new AliITSPIDResponse();
117 //------------------------------------------------------------------------
118 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
119 fI(AliITSgeomTGeo::GetNLayers()),
128 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
131 fTrackingPhase("Default"),
135 fSelectBestMIP03(kFALSE),
136 fUseImproveKalman(kFALSE),
140 fxTimesRhoPipeTrks(0),
141 fxOverX0ShieldTrks(0),
142 fxTimesRhoShieldTrks(0),
143 fxOverX0LayerTrks(0),
144 fxTimesRhoLayerTrks(0),
146 fITSChannelStatus(0),
149 fSPDChipIntPlaneEff(0),
151 //--------------------------------------------------------------------
152 //This is the AliITStrackerMI constructor
153 //--------------------------------------------------------------------
155 AliWarning("\"geom\" is actually a dummy argument !");
158 fOriginal.SetOwner();
162 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
163 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
164 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
166 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
167 AliITSgeomTGeo::GetTranslation(i,1,1,xyz);
168 Double_t poff=TMath::ATan2(y,x);
171 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
172 Double_t r=TMath::Sqrt(x*x + y*y);
174 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
175 r += TMath::Sqrt(x*x + y*y);
176 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
177 r += TMath::Sqrt(x*x + y*y);
178 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
179 r += TMath::Sqrt(x*x + y*y);
182 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
184 for (Int_t j=1; j<nlad+1; j++) {
185 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
186 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
187 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
189 Double_t txyz[3]={0.};
190 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
191 m.LocalToMaster(txyz,xyz);
192 r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
193 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
195 if (phi<0) phi+=TMath::TwoPi();
196 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
198 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
199 new(&det) AliITSdetector(r,phi);
200 // compute the real radius (with misalignment)
201 TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
203 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
204 mmisal.LocalToMaster(txyz,xyz);
205 Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
206 det.SetRmisal(rmisal);
208 } // end loop on detectors
209 } // end loop on ladders
210 fForceSkippingOfLayer[i-1] = 0;
211 } // end loop on layers
214 fI=AliITSgeomTGeo::GetNLayers();
217 fConstraint[0]=1; fConstraint[1]=0;
219 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
220 AliITSReconstructor::GetRecoParam()->GetYVdef(),
221 AliITSReconstructor::GetRecoParam()->GetZVdef()};
222 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
223 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
224 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
225 SetVertex(xyzVtx,ersVtx);
227 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
228 for (Int_t i=0;i<100000;i++){
229 fBestTrackIndex[i]=0;
232 // store positions of centre of SPD modules (in z)
233 // The convetion is that fSPDdetzcentre is ordered from -z to +z
235 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
236 if (tr[2]<0) { // old geom (up to v5asymmPPR)
237 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
238 fSPDdetzcentre[0] = tr[2];
239 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
240 fSPDdetzcentre[1] = tr[2];
241 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
242 fSPDdetzcentre[2] = tr[2];
243 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
244 fSPDdetzcentre[3] = tr[2];
245 } else { // new geom (from v11Hybrid)
246 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
247 fSPDdetzcentre[0] = tr[2];
248 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
249 fSPDdetzcentre[1] = tr[2];
250 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
251 fSPDdetzcentre[2] = tr[2];
252 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
253 fSPDdetzcentre[3] = tr[2];
256 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
257 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
258 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
262 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
263 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
265 if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0)
266 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
268 // only for plane efficiency evaluation
269 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
270 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
271 Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
272 if(!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)==1)
273 AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
275 fPlaneEff = new AliITSPlaneEffSPD();
276 fSPDChipIntPlaneEff = new Bool_t[AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip];
277 for (UInt_t i=0; i<AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip; i++) fSPDChipIntPlaneEff[i]=kFALSE;
279 else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
280 else fPlaneEff = new AliITSPlaneEffSSD();
281 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
282 if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
283 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
287 fSelectBestMIP03 = kFALSE;//AliITSReconstructor::GetRecoParam()->GetSelectBestMIP03();
288 fFlagFakes = AliITSReconstructor::GetRecoParam()->GetFlagFakes();
289 fUseImproveKalman = AliITSReconstructor::GetRecoParam()->GetUseImproveKalman();
291 fITSPid=new AliITSPIDResponse();
294 //------------------------------------------------------------------------
295 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
297 fBestTrack(tracker.fBestTrack),
298 fTrackToFollow(tracker.fTrackToFollow),
299 fTrackHypothesys(tracker.fTrackHypothesys),
300 fBestHypothesys(tracker.fBestHypothesys),
301 fOriginal(tracker.fOriginal),
302 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
303 fPass(tracker.fPass),
304 fAfterV0(tracker.fAfterV0),
305 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
306 fCoefficients(tracker.fCoefficients),
308 fTrackingPhase(tracker.fTrackingPhase),
309 fUseTGeo(tracker.fUseTGeo),
310 fNtracks(tracker.fNtracks),
311 fFlagFakes(tracker.fFlagFakes),
312 fSelectBestMIP03(tracker.fSelectBestMIP03),
313 fxOverX0Pipe(tracker.fxOverX0Pipe),
314 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
316 fxTimesRhoPipeTrks(0),
317 fxOverX0ShieldTrks(0),
318 fxTimesRhoShieldTrks(0),
319 fxOverX0LayerTrks(0),
320 fxTimesRhoLayerTrks(0),
321 fDebugStreamer(tracker.fDebugStreamer),
322 fITSChannelStatus(tracker.fITSChannelStatus),
323 fkDetTypeRec(tracker.fkDetTypeRec),
324 fPlaneEff(tracker.fPlaneEff) {
326 fOriginal.SetOwner();
329 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
332 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
333 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
336 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
337 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
341 //------------------------------------------------------------------------
342 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
343 //Assignment operator
344 this->~AliITStrackerMI();
345 new(this) AliITStrackerMI(tracker);
349 //------------------------------------------------------------------------
350 AliITStrackerMI::~AliITStrackerMI()
355 if (fCoefficients) delete [] fCoefficients;
356 DeleteTrksMaterialLUT();
357 if (fDebugStreamer) {
358 //fDebugStreamer->Close();
359 delete fDebugStreamer;
361 if(fITSChannelStatus) delete fITSChannelStatus;
362 if(fPlaneEff) delete fPlaneEff;
363 if(fITSPid) delete fITSPid;
364 if (fSPDChipIntPlaneEff) delete [] fSPDChipIntPlaneEff;
367 //------------------------------------------------------------------------
368 void AliITStrackerMI::ReadBadFromDetTypeRec() {
369 //--------------------------------------------------------------------
370 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
372 //--------------------------------------------------------------------
374 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
376 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
378 if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
381 if(fITSChannelStatus) delete fITSChannelStatus;
382 fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
384 // ITS detectors and chips
385 Int_t i=0,j=0,k=0,ndet=0;
386 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
387 Int_t nBadDetsPerLayer=0;
388 ndet=AliITSgeomTGeo::GetNDetectors(i);
389 for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
390 for (k=1; k<ndet+1; k++) {
391 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
392 det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fkDetTypeRec);
393 if(det.IsBad()) {nBadDetsPerLayer++;}
394 } // end loop on detectors
395 } // end loop on ladders
396 AliInfo(Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
397 } // end loop on layers
401 //------------------------------------------------------------------------
402 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
403 //--------------------------------------------------------------------
404 //This function loads ITS clusters
405 //--------------------------------------------------------------------
407 TClonesArray *clusters = NULL;
408 AliITSRecPointContainer* rpcont=AliITSRecPointContainer::Instance();
409 clusters=rpcont->FetchClusters(0,cTree);
410 if(!clusters) return 1;
412 if(!(rpcont->IsSPDActive() || rpcont->IsSDDActive() || rpcont->IsSSDActive())){
413 AliError("ITS is not in a known running configuration: SPD, SDD and SSD are not active");
416 Int_t i=0,j=0,ndet=0;
418 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
419 ndet=fgLayers[i].GetNdetectors();
420 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
421 for (; j<jmax; j++) {
422 // if (!cTree->GetEvent(j)) continue;
423 clusters = rpcont->UncheckedGetClusters(j);
424 if(!clusters)continue;
425 Int_t ncl=clusters->GetEntriesFast();
426 SignDeltas(clusters,GetZ());
429 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
430 detector=c->GetDetectorIndex();
432 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
434 Int_t retval = fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
436 AliWarning(Form("Too many clusters on layer %d!",i));
441 // add dead zone "virtual" cluster in SPD, if there is a cluster within
442 // zwindow cm from the dead zone
443 // This method assumes that fSPDdetzcentre is ordered from -z to +z
444 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
445 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
446 Int_t lab[4] = {0,0,0,detector};
447 Int_t info[3] = {0,0,i};
448 Float_t q = 0.; // this identifies virtual clusters
449 Float_t hit[6] = {xdead,
451 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
452 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
455 Bool_t local = kTRUE;
456 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
457 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
458 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
459 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
460 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
461 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
462 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
463 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
464 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
465 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
466 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
467 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
468 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
469 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
470 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
471 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
472 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
473 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
474 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
476 } // "virtual" clusters in SPD
480 fgLayers[i].ResetRoad(); //road defined by the cluster density
481 fgLayers[i].SortClusters();
484 // check whether we have to skip some layers
485 SetForceSkippingOfLayer();
489 //------------------------------------------------------------------------
490 void AliITStrackerMI::UnloadClusters() {
491 //--------------------------------------------------------------------
492 //This function unloads ITS clusters
493 //--------------------------------------------------------------------
494 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
496 //------------------------------------------------------------------------
497 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
498 //--------------------------------------------------------------------
499 // Publishes all pointers to clusters known to the tracker into the
500 // passed object array.
501 // The ownership is not transfered - the caller is not expected to delete
503 //--------------------------------------------------------------------
505 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
506 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
507 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
514 //------------------------------------------------------------------------
515 Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
516 //--------------------------------------------------------------------
517 // Correction for the material between the TPC and the ITS
518 //--------------------------------------------------------------------
519 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
520 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
521 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
522 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
523 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
524 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
525 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
526 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
528 printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
534 //------------------------------------------------------------------------
535 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
536 //--------------------------------------------------------------------
537 // This functions reconstructs ITS tracks
538 // The clusters must be already loaded !
539 //--------------------------------------------------------------------
541 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
543 fTrackingPhase="Clusters2Tracks";
546 fSelectBestMIP03 = kFALSE;//AliITSReconstructor::GetRecoParam()->GetSelectBestMIP03();
547 fFlagFakes = AliITSReconstructor::GetRecoParam()->GetFlagFakes();
548 fUseImproveKalman = AliITSReconstructor::GetRecoParam()->GetUseImproveKalman();
550 TObjArray itsTracks(15000);
552 fEsd = event; // store pointer to the esd
554 // temporary (for cosmics)
555 if(event->GetVertex()) {
556 TString title = event->GetVertex()->GetTitle();
557 if(title.Contains("cosmics")) {
558 Double_t xyz[3]={GetX(),GetY(),GetZ()};
559 Double_t exyz[3]={0.1,0.1,0.1};
565 {/* Read ESD tracks */
566 Int_t nentr=event->GetNumberOfTracks();
568 // Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
570 AliESDtrack *esd=event->GetTrack(nentr);
571 // ---- for debugging:
572 //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); }
574 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
575 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
576 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
577 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
578 AliITStrackMI *t = new AliITStrackMI(*esd);
579 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
580 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
583 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
585 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
586 //track - can be V0 according to TPC
588 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
592 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
596 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
600 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
605 t->SetReconstructed(kFALSE);
606 itsTracks.AddLast(t);
607 fOriginal.AddLast(t);
609 } /* End Read ESD tracks */
613 Int_t nentr=itsTracks.GetEntriesFast();
614 fTrackHypothesys.Expand(nentr);
615 fBestHypothesys.Expand(nentr);
616 MakeCoefficients(nentr);
617 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
619 // THE TWO TRACKING PASSES
620 for (fPass=0; fPass<2; fPass++) {
621 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
622 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
623 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
624 if (t==0) continue; //this track has been already tracked
625 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
626 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
627 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
628 if (fConstraint[fPass]) {
629 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
630 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
633 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
634 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
636 ResetTrackToFollow(*t);
639 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
642 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
644 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
645 if (!besttrack) continue;
646 besttrack->SetLabel(tpcLabel);
647 // besttrack->CookdEdx();
649 besttrack->SetFakeRatio(1.);
650 CookLabel(besttrack,0.); //For comparison only
651 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
652 t->SetWinner(besttrack);
654 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
656 t->SetReconstructed(kTRUE);
658 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
660 GetBestHypothesysMIP(itsTracks);
661 } // end loop on the two tracking passes
663 if (fFlagFakes) FlagFakes(itsTracks);
665 if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
666 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
671 Int_t entries = fTrackHypothesys.GetEntriesFast();
672 for (Int_t ientry=0; ientry<entries; ientry++) {
673 TObjArray * array =(TObjArray*)fTrackHypothesys.At(ientry);
674 if (array) array->Delete();
675 delete fTrackHypothesys.RemoveAt(ientry);
678 fTrackHypothesys.Delete();
679 entries = fBestHypothesys.GetEntriesFast();
680 for (Int_t ientry=0; ientry<entries; ientry++) {
681 TObjArray * array =(TObjArray*)fBestHypothesys.At(ientry);
682 if (array) array->Delete();
683 delete fBestHypothesys.RemoveAt(ientry);
685 fBestHypothesys.Delete();
687 delete [] fCoefficients;
689 DeleteTrksMaterialLUT();
691 AliInfo(Form("Number of prolonged tracks: %d out of %d ESD tracks",ntrk,noesd));
693 fTrackingPhase="Default";
697 //------------------------------------------------------------------------
698 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
699 //--------------------------------------------------------------------
700 // This functions propagates reconstructed ITS tracks back
701 // The clusters must be loaded !
702 //--------------------------------------------------------------------
703 fTrackingPhase="PropagateBack";
704 Int_t nentr=event->GetNumberOfTracks();
705 // Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
706 double bz0 = GetBz();
707 const double kWatchStep=10.; // for larger steps watch arc vs segment difference
710 for (Int_t i=0; i<nentr; i++) {
711 AliESDtrack *esd=event->GetTrack(i);
713 // Start time integral and add distance from current position to vertex
714 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
715 AliITStrackMI t(*esd);
716 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
720 double dxs = xyzTrk[0] - xyzVtx[0];
721 double dys = xyzTrk[1] - xyzVtx[1];
722 double dzs = xyzTrk[2] - xyzVtx[2];
723 // RS: for large segment steps d use approximation of cicrular arc s by
724 // s = 2R*asin(d/2R) = d/p asin(p) \approx d/p (p + 1/6 p^3) = d (1+1/6 p^2)
725 // where R is the track radius, p = d/2R = 2C*d (C is the abs curvature)
726 // Hence s^2/d^2 = (1+1/6 p^2)^2
727 dst2 = dxs*dxs + dys*dys;
728 if (dst2 > kWatchStep*kWatchStep) { // correct circular part for arc/segment factor
729 double crv = TMath::Abs(esd->GetC(bz0));
730 double fcarc = 1.+crv*crv*dst2/6.;
735 t.StartTimeIntegral();
736 t.AddTimeStep(TMath::Sqrt(dst2));
738 // transfer the time integral to ESD track
739 esd->SetStatus(AliESDtrack::kTIME);
740 Double_t times[10];t.GetIntegratedTimes(times); esd->SetIntegratedTimes(times);
741 esd->SetIntegratedLength(t.GetIntegratedLength());
743 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
745 t.SetExpQ(TMath::Max(0.8*t.GetESDtrack()->GetTPCsignal(),30.));
746 ResetTrackToFollow(t);
748 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
749 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,&t)) {
750 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) continue;
751 // fTrackToFollow.SetLabel(t.GetLabel()); // why do we neet this
752 //fTrackToFollow.CookdEdx();
753 CookLabel(&fTrackToFollow,0.); //For comparison only // why do we need this?
754 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
755 //UseClusters(&fTrackToFollow);
760 AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
762 fTrackingPhase="Default";
766 //------------------------------------------------------------------------
767 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
768 //--------------------------------------------------------------------
769 // This functions refits ITS tracks using the
770 // "inward propagated" TPC tracks
771 // The clusters must be loaded !
772 //--------------------------------------------------------------------
773 fTrackingPhase="RefitInward";
775 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
777 Bool_t doExtra=AliITSReconstructor::GetRecoParam()->GetSearchForExtraClusters();
778 if(!doExtra) AliDebug(2,"Do not search for extra clusters");
780 Int_t nentr=event->GetNumberOfTracks();
781 // Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
783 // only for PlaneEff and in case of SPD (for FO studies)
784 if( AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
785 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0 &&
786 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()<2) {
787 for (UInt_t i=0; i<AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip; i++) fSPDChipIntPlaneEff[i]=kFALSE;
791 for (Int_t i=0; i<nentr; i++) {
792 AliESDtrack *esd=event->GetTrack(i);
794 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
795 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
796 if (esd->GetStatus()&AliESDtrack::kTPCout)
797 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
799 AliITStrackMI *t = new AliITStrackMI(*esd);
801 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
802 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
807 ResetTrackToFollow(*t);
808 fTrackToFollow.ResetClusters();
810 // ITS standalone tracks
811 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) {
812 fTrackToFollow.ResetCovariance(10.);
813 // protection for loopers that can have parameters screwed up
814 if(TMath::Abs(fTrackToFollow.GetY())>1000. ||
815 TMath::Abs(fTrackToFollow.GetZ())>1000.) {
822 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
823 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
825 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
826 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,doExtra,pe)) {
827 AliDebug(2," refit OK");
828 fTrackToFollow.SetLabel(t->GetLabel());
829 // fTrackToFollow.CookdEdx();
830 CookdEdx(&fTrackToFollow);
832 CookLabel(&fTrackToFollow,0.0); //For comparison only // RS why do we need this?
835 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
836 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
837 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
838 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
839 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
840 Double_t r[3]={0.,0.,0.};
842 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
849 AliInfo(Form("Number of refitted tracks: %d out of %d ESD tracks",ntrk,nentr));
851 fTrackingPhase="Default";
855 //------------------------------------------------------------------------
856 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
857 //--------------------------------------------------------------------
858 // Return pointer to a given cluster
859 //--------------------------------------------------------------------
860 Int_t l=(index & 0xf0000000) >> 28;
861 Int_t c=(index & 0x0fffffff) >> 00;
862 return fgLayers[l].GetCluster(c);
864 //------------------------------------------------------------------------
865 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
866 //--------------------------------------------------------------------
867 // Get track space point with index i
868 //--------------------------------------------------------------------
870 Int_t l=(index & 0xf0000000) >> 28;
871 Int_t c=(index & 0x0fffffff) >> 00;
872 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
873 Int_t idet = cl->GetDetectorIndex();
877 cl->GetGlobalXYZ(xyz);
878 cl->GetGlobalCov(cov);
880 p.SetCharge(cl->GetQ());
881 p.SetDriftTime(cl->GetDriftTime());
882 p.SetChargeRatio(cl->GetChargeRatio());
883 p.SetClusterType(cl->GetClusterType());
884 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
887 iLayer = AliGeomManager::kSPD1;
890 iLayer = AliGeomManager::kSPD2;
893 iLayer = AliGeomManager::kSDD1;
896 iLayer = AliGeomManager::kSDD2;
899 iLayer = AliGeomManager::kSSD1;
902 iLayer = AliGeomManager::kSSD2;
905 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
908 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
909 p.SetVolumeID((UShort_t)volid);
912 //------------------------------------------------------------------------
913 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
914 AliTrackPoint& p, const AliESDtrack *t) {
915 //--------------------------------------------------------------------
916 // Get track space point with index i
917 // (assign error estimated during the tracking)
918 //--------------------------------------------------------------------
920 Int_t l=(index & 0xf0000000) >> 28;
921 Int_t c=(index & 0x0fffffff) >> 00;
922 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
923 Int_t idet = cl->GetDetectorIndex();
925 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
927 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
929 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
930 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
931 Double_t alpha = t->GetAlpha();
932 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
933 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe+cl->GetX(),GetBz()));
934 phi += alpha-det.GetPhi();
935 Float_t tgphi = TMath::Tan(phi);
937 Float_t tgl = t->GetTgl(); // tgl about const along track
938 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
940 Float_t errtrky,errtrkz,covyz;
941 Bool_t addMisalErr=kFALSE;
942 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
946 cl->GetGlobalXYZ(xyz);
947 // cl->GetGlobalCov(cov);
948 Float_t pos[3] = {0.,0.,0.};
949 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
950 tmpcl.GetGlobalCov(cov);
953 p.SetCharge(cl->GetQ());
954 p.SetDriftTime(cl->GetDriftTime());
955 p.SetChargeRatio(cl->GetChargeRatio());
956 p.SetClusterType(cl->GetClusterType());
958 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
961 iLayer = AliGeomManager::kSPD1;
964 iLayer = AliGeomManager::kSPD2;
967 iLayer = AliGeomManager::kSDD1;
970 iLayer = AliGeomManager::kSDD2;
973 iLayer = AliGeomManager::kSSD1;
976 iLayer = AliGeomManager::kSSD2;
979 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
982 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
984 p.SetVolumeID((UShort_t)volid);
987 //------------------------------------------------------------------------
988 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
990 //--------------------------------------------------------------------
991 // Follow prolongation tree
992 //--------------------------------------------------------------------
994 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
995 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
998 AliESDtrack * esd = otrack->GetESDtrack();
999 if (esd->GetV0Index(0)>0) {
1000 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
1001 // mapping of ESD track is different as ITS track in Containers
1002 // Need something more stable
1003 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
1004 for (Int_t i=0;i<3;i++){
1005 Int_t index = esd->GetV0Index(i);
1006 if (index==0) break;
1007 AliESDv0 * vertex = fEsd->GetV0(index);
1008 if (vertex->GetStatus()<0) continue; // rejected V0
1010 if (esd->GetSign()>0) {
1011 vertex->SetIndex(0,esdindex);
1013 vertex->SetIndex(1,esdindex);
1017 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
1019 bestarray = new TObjArray(5);
1020 bestarray->SetOwner();
1021 fBestHypothesys.AddAt(bestarray,esdindex);
1025 //setup tree of the prolongations
1027 const int kMaxTr = 100; //RS
1028 static AliITStrackMI tracks[7][kMaxTr];
1029 AliITStrackMI *currenttrack;
1030 static AliITStrackMI currenttrack1;
1031 static AliITStrackMI currenttrack2;
1032 static AliITStrackMI backuptrack;
1034 Int_t nindexes[7][kMaxTr];
1035 Float_t normalizedchi2[kMaxTr];
1036 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
1037 otrack->SetNSkipped(0);
1038 new (&(tracks[6][0])) AliITStrackMI(*otrack);
1040 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
1041 Int_t modstatus = 1; // found
1045 // follow prolongations
1046 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
1047 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
1050 AliITSlayer &layer=fgLayers[ilayer];
1051 Double_t r = layer.GetR();
1057 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
1058 // printf("LR %d Tr:%d NSeeds: %d\n",ilayer,itrack,ntracks[ilayer+1]);
1060 if (ntracks[ilayer]>=kMaxTr) break;
1061 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
1062 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
1063 if (ntracks[ilayer]>15+ilayer){
1064 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
1065 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
1068 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
1070 // material between SSD and SDD, SDD and SPD
1072 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
1074 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
1078 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
1079 Int_t idet=layer.FindDetectorIndex(phi,z);
1081 Double_t trackGlobXYZ1[3];
1082 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1084 // Get the budget to the primary vertex for the current track being prolonged
1085 Double_t budgetToPrimVertex = 0;
1086 double xMSLrs[9],x2X0MSLrs[9]; // needed for ImproveKalman
1089 if (fUseImproveKalman) nMSLrs = GetEffectiveThicknessLbyL(xMSLrs,x2X0MSLrs);
1090 else budgetToPrimVertex = GetEffectiveThickness();
1092 // check if we allow a prolongation without point
1093 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1095 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1096 // propagate to the layer radius
1097 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1098 if(!vtrack->Propagate(xToGo)) continue;
1099 // apply correction for material of the current layer
1100 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1101 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1102 vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1103 vtrack->SetClIndex(ilayer,-1);
1104 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1105 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1106 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1108 if(constrain && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
1110 vtrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) :
1111 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1117 // track outside layer acceptance in z
1118 if (idet<0) continue;
1120 //propagate to the intersection with the detector plane
1121 const AliITSdetector &det=layer.GetDetector(idet);
1122 new(¤ttrack2) AliITStrackMI(currenttrack1);
1123 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1124 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1125 currenttrack1.SetDetectorIndex(idet);
1126 currenttrack2.SetDetectorIndex(idet);
1127 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1130 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1132 // road in global (rphi,z) [i.e. in tracking ref. system]
1133 Double_t zmin,zmax,ymin,ymax;
1134 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1136 // select clusters in road
1137 layer.SelectClusters(zmin,zmax,ymin,ymax);
1138 //********************
1140 // Define criteria for track-cluster association
1141 Double_t msz = currenttrack1.GetSigmaZ2() +
1142 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1143 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1144 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1145 Double_t msy = currenttrack1.GetSigmaY2() +
1146 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1147 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1148 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1150 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1151 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1153 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1154 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1156 msz = 1./msz; // 1/RoadZ^2
1157 msy = 1./msy; // 1/RoadY^2
1161 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1163 const AliITSRecPoint *cl=0;
1165 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1166 Bool_t deadzoneSPD=kFALSE;
1167 currenttrack = ¤ttrack1;
1169 // check if the road contains a dead zone
1170 Bool_t noClusters = kFALSE;
1171 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1172 if (noClusters) AliDebug(2,"no clusters in road");
1173 Double_t dz=0.5*(zmax-zmin);
1174 Double_t dy=0.5*(ymax-ymin);
1175 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1176 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1177 // create a prolongation without clusters (check also if there are no clusters in the road)
1180 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1181 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1182 updatetrack->SetClIndex(ilayer,-1);
1184 modstatus = 5; // no cls in road
1185 } else if (dead==1) {
1186 modstatus = 7; // holes in z in SPD
1187 } else if (dead==2 || dead==3 || dead==4) {
1188 modstatus = 2; // dead from OCDB
1190 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1191 // apply correction for material of the current layer
1192 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1193 if (constrain) { // apply vertex constrain
1194 updatetrack->SetConstrain(constrain);
1195 Bool_t isPrim = kTRUE;
1196 if (ilayer<4) { // check that it's close to the vertex
1197 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1198 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1199 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1200 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1201 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1203 if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
1205 updatetrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) :
1206 updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1209 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1211 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1212 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1214 } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1215 updatetrack->SetDeadZoneProbability(ilayer,1.);
1216 } else if (dead==4) { // at least a single dead channel from OCDB
1217 updatetrack->SetDeadZoneProbability(ilayer,0.);
1224 // loop over clusters in the road
1225 while ((cl=layer.GetNextCluster(clidx))!=0) {
1226 if (ntracks[ilayer]>int(0.95*kMaxTr)) break; //space for skipped clusters
1227 Bool_t changedet =kFALSE;
1228 if (TMath::Abs(cl->GetQ())<1.e-13 && deadzoneSPD==kTRUE) continue;
1229 Int_t idetc=cl->GetDetectorIndex();
1231 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1232 // take into account misalignment (bring track to real detector plane)
1233 Double_t xTrOrig = currenttrack->GetX();
1234 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1235 // a first cut on track-cluster distance
1236 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1237 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1238 { // cluster not associated to track
1239 AliDebug(2,"not associated");
1240 // MvL: added here as well
1241 // bring track back to ideal detector plane
1242 currenttrack->Propagate(xTrOrig);
1245 // bring track back to ideal detector plane
1246 if (!currenttrack->Propagate(xTrOrig)) continue;
1247 } else { // have to move track to cluster's detector
1248 const AliITSdetector &detc=layer.GetDetector(idetc);
1249 // a first cut on track-cluster distance
1251 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1252 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1253 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1254 continue; // cluster not associated to track
1256 new (&backuptrack) AliITStrackMI(currenttrack2);
1258 currenttrack =¤ttrack2;
1259 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1260 new (currenttrack) AliITStrackMI(backuptrack);
1264 currenttrack->SetDetectorIndex(idetc);
1265 // Get again the budget to the primary vertex
1266 // for the current track being prolonged, if had to change detector
1267 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1270 // calculate track-clusters chi2
1271 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1273 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1274 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1275 if (TMath::Abs(cl->GetQ())<1.e-13) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1276 if (ntracks[ilayer]>=kMaxTr) continue;
1277 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1278 updatetrack->SetClIndex(ilayer,-1);
1279 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1281 if (TMath::Abs(cl->GetQ())>1.e-13) { // real cluster
1282 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1283 AliDebug(2,"update failed");
1286 updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1287 modstatus = 1; // found
1288 } else { // virtual cluster in dead zone
1289 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1290 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1291 modstatus = 7; // holes in z in SPD
1295 Float_t xlocnewdet,zlocnewdet;
1296 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1297 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1300 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1302 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1304 // apply correction for material of the current layer
1305 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1307 if (constrain) { // apply vertex constrain
1308 updatetrack->SetConstrain(constrain);
1309 Bool_t isPrim = kTRUE;
1310 if (ilayer<4) { // check that it's close to the vertex
1311 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1312 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1313 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1314 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1315 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1317 if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
1319 updatetrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) :
1320 updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1322 } //apply vertex constrain
1324 } // create new hypothesis
1326 AliDebug(2,"chi2 too large");
1329 } // loop over possible prolongations
1331 // allow one prolongation without clusters
1332 if (constrain && itrack<=1 && TMath::Abs(currenttrack1.GetNSkipped())<1.e-13 && deadzoneSPD==kFALSE && ntracks[ilayer]<kMaxTr) {
1333 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1334 // apply correction for material of the current layer
1335 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1336 vtrack->SetClIndex(ilayer,-1);
1337 modstatus = 3; // skipped
1338 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1339 if(AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
1341 vtrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) :
1342 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1344 vtrack->IncrementNSkipped();
1349 } // loop over tracks in layer ilayer+1
1351 //loop over track candidates for the current layer
1357 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1358 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1359 if (normalizedchi2[itrack] <
1360 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1364 if (constrain) { // constrain
1365 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1367 } else { // !constrain
1368 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1373 // sort tracks by increasing normalized chi2
1374 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1375 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1376 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1377 // if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1378 if (ntracks[ilayer]>int(kMaxTr*0.9)) ntracks[ilayer]=int(kMaxTr*0.9);
1379 } // end loop over layers
1383 // Now select tracks to be kept
1385 Int_t max = constrain ? 20 : 5;
1387 // tracks that reach layer 0 (SPD inner)
1388 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1389 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1390 if (track.GetNumberOfClusters()<2) continue;
1391 if (!constrain && track.GetNormChi2(0) >
1392 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1395 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1398 // tracks that reach layer 1 (SPD outer)
1399 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1400 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1401 if (track.GetNumberOfClusters()<4) continue;
1402 if (!constrain && track.GetNormChi2(1) >
1403 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1404 if (constrain) track.IncrementNSkipped();
1406 track.SetD(0,track.GetD(GetX(),GetY()));
1407 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1408 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1409 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1412 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1415 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1417 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1418 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1419 if (track.GetNumberOfClusters()<3) continue;
1420 if (track.GetNormChi2(2) >
1421 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1422 track.SetD(0,track.GetD(GetX(),GetY()));
1423 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1424 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1425 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1427 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1433 // register best track of each layer - important for V0 finder
1435 for (Int_t ilayer=0;ilayer<5;ilayer++){
1436 if (ntracks[ilayer]==0) continue;
1437 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1438 if (track.GetNumberOfClusters()<1) continue;
1439 CookLabel(&track,0);
1440 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1444 // update TPC V0 information
1446 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1447 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1448 for (Int_t i=0;i<3;i++){
1449 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1450 if (index==0) break;
1451 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1452 if (vertex->GetStatus()<0) continue; // rejected V0
1454 if (otrack->GetSign()>0) {
1455 vertex->SetIndex(0,esdindex);
1458 vertex->SetIndex(1,esdindex);
1460 //find nearest layer with track info
1461 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1462 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1463 Int_t nearest = nearestold;
1464 for (Int_t ilayer =nearest;ilayer<7;ilayer++){
1465 if (ntracks[nearest]==0){
1470 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1471 if (nearestold<5&&nearest<5){
1472 Bool_t accept = track.GetNormChi2(nearest)<10;
1474 if (track.GetSign()>0) {
1475 vertex->SetParamP(track);
1476 vertex->Update(fprimvertex);
1477 //vertex->SetIndex(0,track.fESDtrack->GetID());
1478 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1480 vertex->SetParamN(track);
1481 vertex->Update(fprimvertex);
1482 //vertex->SetIndex(1,track.fESDtrack->GetID());
1483 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1485 vertex->SetStatus(vertex->GetStatus()+1);
1487 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1494 //------------------------------------------------------------------------
1495 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1497 //--------------------------------------------------------------------
1500 return fgLayers[layer];
1502 //------------------------------------------------------------------------
1503 AliITStrackerMI::AliITSlayer::AliITSlayer():
1533 //--------------------------------------------------------------------
1534 //default AliITSlayer constructor
1535 //--------------------------------------------------------------------
1536 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1537 fClusterWeight[i]=0;
1538 fClusterTracks[0][i]=-1;
1539 fClusterTracks[1][i]=-1;
1540 fClusterTracks[2][i]=-1;
1541 fClusterTracks[3][i]=-1;
1548 for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer5; j++) {
1549 for (Int_t j1=0; j1<6; j1++) {
1550 fClusters5[j1][j]=0;
1551 fClusterIndex5[j1][j]=-1;
1560 for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer10; j++) {
1561 for (Int_t j1=0; j1<11; j1++) {
1562 fClusters10[j1][j]=0;
1563 fClusterIndex10[j1][j]=-1;
1572 for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer20; j++) {
1573 for (Int_t j1=0; j1<21; j1++) {
1574 fClusters20[j1][j]=0;
1575 fClusterIndex20[j1][j]=-1;
1583 for(Int_t i=0;i<AliITSRecoParam::kMaxClusterPerLayer;i++){
1588 //------------------------------------------------------------------------
1589 AliITStrackerMI::AliITSlayer::
1590 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1619 //--------------------------------------------------------------------
1620 //main AliITSlayer constructor
1621 //--------------------------------------------------------------------
1622 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1623 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1625 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1626 fClusterWeight[i]=0;
1627 fClusterTracks[0][i]=-1;
1628 fClusterTracks[1][i]=-1;
1629 fClusterTracks[2][i]=-1;
1630 fClusterTracks[3][i]=-1;
1638 for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer5; j++) {
1639 for (Int_t j1=0; j1<6; j1++) {
1640 fClusters5[j1][j]=0;
1641 fClusterIndex5[j1][j]=-1;
1650 for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer10; j++) {
1651 for (Int_t j1=0; j1<11; j1++) {
1652 fClusters10[j1][j]=0;
1653 fClusterIndex10[j1][j]=-1;
1662 for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer20; j++) {
1663 for (Int_t j1=0; j1<21; j1++) {
1664 fClusters20[j1][j]=0;
1665 fClusterIndex20[j1][j]=-1;
1673 for(Int_t i=0;i<AliITSRecoParam::kMaxClusterPerLayer;i++){
1679 //------------------------------------------------------------------------
1680 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1682 fPhiOffset(layer.fPhiOffset),
1683 fNladders(layer.fNladders),
1684 fZOffset(layer.fZOffset),
1685 fNdetectors(layer.fNdetectors),
1686 fDetectors(layer.fDetectors),
1691 fClustersCs(layer.fClustersCs),
1692 fClusterIndexCs(layer.fClusterIndexCs),
1696 fCurrentSlice(layer.fCurrentSlice),
1704 fAccepted(layer.fAccepted),
1706 fMaxSigmaClY(layer.fMaxSigmaClY),
1707 fMaxSigmaClZ(layer.fMaxSigmaClZ),
1708 fNMaxSigmaCl(layer.fNMaxSigmaCl)
1713 //------------------------------------------------------------------------
1714 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1715 //--------------------------------------------------------------------
1716 // AliITSlayer destructor
1717 //--------------------------------------------------------------------
1718 delete [] fDetectors;
1719 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1720 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1721 fClusterWeight[i]=0;
1722 fClusterTracks[0][i]=-1;
1723 fClusterTracks[1][i]=-1;
1724 fClusterTracks[2][i]=-1;
1725 fClusterTracks[3][i]=-1;
1728 //------------------------------------------------------------------------
1729 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1730 //--------------------------------------------------------------------
1731 // This function removes loaded clusters
1732 //--------------------------------------------------------------------
1733 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1734 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1735 fClusterWeight[i]=0;
1736 fClusterTracks[0][i]=-1;
1737 fClusterTracks[1][i]=-1;
1738 fClusterTracks[2][i]=-1;
1739 fClusterTracks[3][i]=-1;
1745 //------------------------------------------------------------------------
1746 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1747 //--------------------------------------------------------------------
1748 // This function reset weights of the clusters
1749 //--------------------------------------------------------------------
1750 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1751 fClusterWeight[i]=0;
1752 fClusterTracks[0][i]=-1;
1753 fClusterTracks[1][i]=-1;
1754 fClusterTracks[2][i]=-1;
1755 fClusterTracks[3][i]=-1;
1757 for (Int_t i=0; i<fN;i++) {
1758 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1759 if (cl&&cl->IsUsed()) cl->Use();
1763 //------------------------------------------------------------------------
1764 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1765 //--------------------------------------------------------------------
1766 // This function calculates the road defined by the cluster density
1767 //--------------------------------------------------------------------
1769 for (Int_t i=0; i<fN; i++) {
1770 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1772 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1774 //------------------------------------------------------------------------
1775 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1776 //--------------------------------------------------------------------
1777 //This function adds a cluster to this layer
1778 //--------------------------------------------------------------------
1779 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1785 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1787 Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
1788 Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2());
1789 if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
1790 if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
1791 if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
1792 if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
1795 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1796 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1797 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1798 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1802 //------------------------------------------------------------------------
1803 void AliITStrackerMI::AliITSlayer::SortClusters()
1808 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1809 Float_t *z = new Float_t[fN];
1810 Int_t * index = new Int_t[fN];
1812 fMaxSigmaClY=0.; //AD
1813 fMaxSigmaClZ=0.; //AD
1815 for (Int_t i=0;i<fN;i++){
1816 z[i] = fClusters[i]->GetZ();
1817 // save largest errors in y and z for this layer
1818 fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
1819 fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
1821 TMath::Sort(fN,z,index,kFALSE);
1822 for (Int_t i=0;i<fN;i++){
1823 clusters[i] = fClusters[index[i]];
1826 for (Int_t i=0;i<fN;i++){
1827 fClusters[i] = clusters[i];
1828 fZ[i] = fClusters[i]->GetZ();
1829 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1830 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1831 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1841 for (Int_t i=0;i<fN;i++){
1842 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1843 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1844 fClusterIndex[i] = i;
1848 fDy5 = (fYB[1]-fYB[0])/5.;
1849 fDy10 = (fYB[1]-fYB[0])/10.;
1850 fDy20 = (fYB[1]-fYB[0])/20.;
1851 for (Int_t i=0;i<6;i++) fN5[i] =0;
1852 for (Int_t i=0;i<11;i++) fN10[i]=0;
1853 for (Int_t i=0;i<21;i++) fN20[i]=0;
1855 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;}
1856 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;}
1857 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;}
1860 for (Int_t i=0;i<fN;i++)
1861 for (Int_t irot=-1;irot<=1;irot++){
1862 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1864 for (Int_t slice=0; slice<6;slice++){
1865 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1866 fClusters5[slice][fN5[slice]] = fClusters[i];
1867 fY5[slice][fN5[slice]] = curY;
1868 fZ5[slice][fN5[slice]] = fZ[i];
1869 fClusterIndex5[slice][fN5[slice]]=i;
1874 for (Int_t slice=0; slice<11;slice++){
1875 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1876 fClusters10[slice][fN10[slice]] = fClusters[i];
1877 fY10[slice][fN10[slice]] = curY;
1878 fZ10[slice][fN10[slice]] = fZ[i];
1879 fClusterIndex10[slice][fN10[slice]]=i;
1884 for (Int_t slice=0; slice<21;slice++){
1885 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1886 fClusters20[slice][fN20[slice]] = fClusters[i];
1887 fY20[slice][fN20[slice]] = curY;
1888 fZ20[slice][fN20[slice]] = fZ[i];
1889 fClusterIndex20[slice][fN20[slice]]=i;
1896 // consistency check
1898 for (Int_t i=0;i<fN-1;i++){
1904 for (Int_t slice=0;slice<21;slice++)
1905 for (Int_t i=0;i<fN20[slice]-1;i++){
1906 if (fZ20[slice][i]>fZ20[slice][i+1]){
1913 //------------------------------------------------------------------------
1914 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1915 //--------------------------------------------------------------------
1916 // This function returns the index of the nearest cluster
1917 //--------------------------------------------------------------------
1920 if (fCurrentSlice<0) {
1929 if (ncl==0) return 0;
1930 Int_t b=0, e=ncl-1, m=(b+e)/2;
1931 for (; b<e; m=(b+e)/2) {
1932 // if (z > fClusters[m]->GetZ()) b=m+1;
1933 if (z > zcl[m]) b=m+1;
1938 //------------------------------------------------------------------------
1939 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 {
1940 //--------------------------------------------------------------------
1941 // This function computes the rectangular road for this track
1942 //--------------------------------------------------------------------
1945 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1946 // take into account the misalignment: propagate track to misaligned detector plane
1947 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1949 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1950 TMath::Sqrt(track->GetSigmaZ2() +
1951 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1952 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1953 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1954 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1955 TMath::Sqrt(track->GetSigmaY2() +
1956 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1957 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1958 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1960 // track at boundary between detectors, enlarge road
1961 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1962 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1963 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1964 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1965 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1966 Float_t tgl = TMath::Abs(track->GetTgl());
1967 if (tgl > 1.) tgl=1.;
1968 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1969 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1970 Float_t snp = TMath::Abs(track->GetSnp());
1971 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1972 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1975 // add to the road a term (up to 2-3 mm) to deal with misalignments
1976 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1977 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1979 Double_t r = fgLayers[ilayer].GetR();
1980 zmin = track->GetZ() - dz;
1981 zmax = track->GetZ() + dz;
1982 ymin = track->GetY() + r*det.GetPhi() - dy;
1983 ymax = track->GetY() + r*det.GetPhi() + dy;
1985 // bring track back to idead detector plane
1986 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1990 //------------------------------------------------------------------------
1991 void AliITStrackerMI::AliITSlayer::
1992 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1993 //--------------------------------------------------------------------
1994 // This function sets the "window"
1995 //--------------------------------------------------------------------
1997 Double_t circle=2*TMath::Pi()*fR;
2003 // enlarge road in y by maximum cluster error on this layer (3 sigma)
2004 fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
2005 fYmax += fNMaxSigmaCl*fMaxSigmaClY;
2006 fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
2007 fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
2009 Float_t ymiddle = (fYmin+fYmax)*0.5;
2010 if (ymiddle<fYB[0]) {
2011 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
2012 } else if (ymiddle>fYB[1]) {
2013 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
2019 fClustersCs = fClusters;
2020 fClusterIndexCs = fClusterIndex;
2026 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
2027 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
2028 if (slice<0) slice=0;
2029 if (slice>20) slice=20;
2030 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
2032 fCurrentSlice=slice;
2033 fClustersCs = fClusters20[fCurrentSlice];
2034 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
2035 fYcs = fY20[fCurrentSlice];
2036 fZcs = fZ20[fCurrentSlice];
2037 fNcs = fN20[fCurrentSlice];
2042 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
2043 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
2044 if (slice<0) slice=0;
2045 if (slice>10) slice=10;
2046 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
2048 fCurrentSlice=slice;
2049 fClustersCs = fClusters10[fCurrentSlice];
2050 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
2051 fYcs = fY10[fCurrentSlice];
2052 fZcs = fZ10[fCurrentSlice];
2053 fNcs = fN10[fCurrentSlice];
2058 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
2059 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
2060 if (slice<0) slice=0;
2061 if (slice>5) slice=5;
2062 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
2064 fCurrentSlice=slice;
2065 fClustersCs = fClusters5[fCurrentSlice];
2066 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
2067 fYcs = fY5[fCurrentSlice];
2068 fZcs = fZ5[fCurrentSlice];
2069 fNcs = fN5[fCurrentSlice];
2073 fI = FindClusterIndex(fZmin);
2074 fImax = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
2080 //------------------------------------------------------------------------
2081 Int_t AliITStrackerMI::AliITSlayer::
2082 FindDetectorIndex(Double_t phi, Double_t z) const {
2083 //--------------------------------------------------------------------
2084 //This function finds the detector crossed by the track
2085 //--------------------------------------------------------------------
2087 if (fZOffset<0) // old geometry
2088 dphi = -(phi-fPhiOffset);
2089 else // new geometry
2090 dphi = phi-fPhiOffset;
2093 if (dphi < 0) dphi += 2*TMath::Pi();
2094 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
2095 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
2096 if (np>=fNladders) np-=fNladders;
2097 if (np<0) np+=fNladders;
2100 Double_t dz=fZOffset-z;
2101 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
2102 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
2103 if (nz>=fNdetectors || nz<0) {
2104 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
2108 // ad hoc correction for 3rd ladder of SDD inner layer,
2109 // which is reversed (rotated by pi around local y)
2110 // this correction is OK only from AliITSv11Hybrid onwards
2111 if (GetR()>12. && GetR()<20.) { // SDD inner
2112 if(np==2) { // 3rd ladder
2113 Double_t posMod252[3];
2114 AliITSgeomTGeo::GetTranslation(252,posMod252);
2115 // check the Z coordinate of Mod 252: if negative
2116 // (old SDD geometry in AliITSv11Hybrid)
2117 // the swap of numeration whould be applied
2118 if(posMod252[2]<0.){
2119 nz = (fNdetectors-1) - nz;
2123 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
2126 return np*fNdetectors + nz;
2128 //------------------------------------------------------------------------
2129 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
2131 //--------------------------------------------------------------------
2132 // This function returns clusters within the "window"
2133 //--------------------------------------------------------------------
2135 if (fCurrentSlice<0) {
2136 Double_t rpi2 = 2.*fR*TMath::Pi();
2137 for (Int_t i=fI; i<fImax; i++) {
2140 if (fYmax<y) y -= rpi2;
2141 if (fYmin>y) y += rpi2;
2142 if (y<fYmin) continue;
2143 if (y>fYmax) continue;
2145 // skip clusters that are in "extended" road but they
2146 // 3sigma error does not touch the original road
2147 if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
2148 if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
2150 if (TMath::Abs(fClusters[i]->GetQ())<1.e-13 && fSkip==2) continue;
2153 return fClusters[i];
2156 for (Int_t i=fI; i<fImax; i++) {
2157 if (fYcs[i]<fYmin) continue;
2158 if (fYcs[i]>fYmax) continue;
2159 if (TMath::Abs(fClustersCs[i]->GetQ())<1.e-13 && fSkip==2) continue;
2160 ci=fClusterIndexCs[i];
2162 return fClustersCs[i];
2167 //------------------------------------------------------------------------
2168 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
2170 //--------------------------------------------------------------------
2171 // This function returns the layer thickness at this point (units X0)
2172 //--------------------------------------------------------------------
2174 x0=AliITSRecoParam::GetX0Air();
2175 if (43<fR&&fR<45) { //SSD2
2178 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2179 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2180 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2181 for (Int_t i=0; i<12; i++) {
2182 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
2183 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2187 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
2188 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2192 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2193 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2196 if (37<fR&&fR<41) { //SSD1
2199 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2200 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2201 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2202 for (Int_t i=0; i<11; i++) {
2203 if (TMath::Abs(z-3.9*i)<0.15) {
2204 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2208 if (TMath::Abs(z+3.9*i)<0.15) {
2209 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2213 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2214 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2217 if (13<fR&&fR<26) { //SDD
2220 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2222 if (TMath::Abs(y-1.80)<0.55) {
2224 for (Int_t j=0; j<20; j++) {
2225 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2226 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2229 if (TMath::Abs(y+1.80)<0.55) {
2231 for (Int_t j=0; j<20; j++) {
2232 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2233 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2237 for (Int_t i=0; i<4; i++) {
2238 if (TMath::Abs(z-7.3*i)<0.60) {
2240 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2243 if (TMath::Abs(z+7.3*i)<0.60) {
2245 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2250 if (6<fR&&fR<8) { //SPD2
2251 Double_t dd=0.0063; x0=21.5;
2253 if (TMath::Abs(y-3.08)>0.5) d+=dd;
2254 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2256 if (3<fR&&fR<5) { //SPD1
2257 Double_t dd=0.0063; x0=21.5;
2259 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2260 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2265 //------------------------------------------------------------------------
2266 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2268 fRmisal(det.fRmisal),
2270 fSinPhi(det.fSinPhi),
2271 fCosPhi(det.fCosPhi),
2277 fNChips(det.fNChips),
2278 fChipIsBad(det.fChipIsBad)
2282 //------------------------------------------------------------------------
2283 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2284 const AliITSDetTypeRec *detTypeRec)
2286 //--------------------------------------------------------------------
2287 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2288 //--------------------------------------------------------------------
2290 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2291 // while in the tracker they start from 0 for each layer
2292 for(Int_t il=0; il<ilayer; il++)
2293 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2296 if (ilayer==0 || ilayer==1) { // ---------- SPD
2298 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2300 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2303 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2307 // Get calibration from AliITSDetTypeRec
2308 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2309 calib->SetModuleIndex(idet);
2310 AliITSCalibration *calibSPDdead = 0;
2311 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2312 if (calib->IsBad() ||
2313 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2316 // printf("lay %d bad %d\n",ilayer,idet);
2319 // Get segmentation from AliITSDetTypeRec
2320 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2322 // Read info about bad chips
2323 fNChips = segm->GetMaximumChipIndex()+1;
2324 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2325 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2326 fChipIsBad = new Bool_t[fNChips];
2327 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2328 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2329 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2330 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2335 //------------------------------------------------------------------------
2336 Double_t AliITStrackerMI::GetEffectiveThickness()
2338 //--------------------------------------------------------------------
2339 // Returns the thickness between the current layer and the vertex (units X0)
2340 //--------------------------------------------------------------------
2343 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2344 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2345 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2349 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2350 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2354 Double_t xn=fgLayers[fI].GetR();
2355 for (Int_t i=0; i<fI; i++) {
2356 Double_t xi=fgLayers[i].GetR();
2357 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2363 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2364 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2367 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2368 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2373 //------------------------------------------------------------------------
2374 Int_t AliITStrackerMI::GetEffectiveThicknessLbyL(Double_t* xMS, Double_t* x2x0MS)
2376 //--------------------------------------------------------------------
2377 // Returns the array of layers between the current layer and the vertex
2378 //--------------------------------------------------------------------
2381 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2382 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2383 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2388 for (int il=fI;il--;) {
2391 x2x0MS[nl] = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2392 xMS[nl++] = AliITSRecoParam::GetrInsideShield(1);
2395 x2x0MS[nl] = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2396 xMS[nl++] = AliITSRecoParam::GetrInsideShield(0);
2399 x2x0MS[nl] = (fUseTGeo==0 ? fgLayers[il].GetThickness(0,0,x0) : fxOverX0Layer[il]);
2400 xMS[nl++] = fgLayers[il].GetR();
2405 x2x0MS[nl] = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2406 xMS[nl++] = AliITSRecoParam::GetrPipe();
2412 //------------------------------------------------------------------------
2413 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2414 //-------------------------------------------------------------------
2415 // This function returns number of clusters within the "window"
2416 //--------------------------------------------------------------------
2418 for (Int_t i=fI; i<fN; i++) {
2419 const AliITSRecPoint *c=fClusters[i];
2420 if (c->GetZ() > fZmax) break;
2421 if (c->IsUsed()) continue;
2422 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2423 Double_t y=fR*det.GetPhi() + c->GetY();
2425 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2426 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2428 if (y<fYmin) continue;
2429 if (y>fYmax) continue;
2434 //------------------------------------------------------------------------
2435 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2436 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2438 //--------------------------------------------------------------------
2439 // This function refits the track "track" at the position "x" using
2440 // the clusters from "clusters"
2441 // If "extra"==kTRUE,
2442 // the clusters from overlapped modules get attached to "track"
2443 // If "planeff"==kTRUE,
2444 // special approach for plane efficiency evaluation is applyed
2445 //--------------------------------------------------------------------
2447 Int_t index[AliITSgeomTGeo::kNLayers];
2449 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2450 Int_t nc=clusters->GetNumberOfClusters();
2451 for (k=0; k<nc; k++) {
2452 Int_t idx=clusters->GetClusterIndex(k);
2453 Int_t ilayer=(idx&0xf0000000)>>28;
2457 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2459 //------------------------------------------------------------------------
2460 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2461 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2463 //--------------------------------------------------------------------
2464 // This function refits the track "track" at the position "x" using
2465 // the clusters from array
2466 // If "extra"==kTRUE,
2467 // the clusters from overlapped modules get attached to "track"
2468 // If "planeff"==kTRUE,
2469 // special approach for plane efficiency evaluation is applyed
2470 //--------------------------------------------------------------------
2471 Int_t index[AliITSgeomTGeo::kNLayers];
2473 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2475 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2476 index[k]=clusters[k];
2479 // special for cosmics and TPC prolonged tracks:
2480 // propagate to the innermost of:
2481 // - innermost layer crossed by the track
2482 // - innermost layer where a cluster was associated to the track
2483 static AliITSRecoParam *repa = NULL;
2485 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
2487 repa = AliITSRecoParam::GetHighFluxParam();
2488 AliWarning("Using default AliITSRecoParam class");
2491 Int_t evsp=repa->GetEventSpecie();
2493 if(track->GetESDtrack()) trStatus=track->GetStatus();
2494 Int_t innermostlayer=0;
2495 if((evsp&AliRecoParam::kCosmic) || (trStatus&AliESDtrack::kTPCin)) {
2497 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2498 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2499 if( (drphi < (fgLayers[innermostlayer].GetR()+1.)) ||
2500 index[innermostlayer] >= 0 ) break;
2503 AliDebug(2,Form(" drphi %f innermost %d",drphi,innermostlayer));
2506 Int_t modstatus=1; // found
2508 Int_t from, to, step;
2509 if (xx > track->GetX()) {
2510 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2513 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2516 TString dir = (step>0 ? "outward" : "inward");
2518 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2519 AliITSlayer &layer=fgLayers[ilayer];
2520 Double_t r=layer.GetR();
2522 if (step<0 && xx>r) break;
2524 // material between SSD and SDD, SDD and SPD
2525 Double_t hI=ilayer-0.5*step;
2526 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2527 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2528 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2529 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2532 Double_t oldGlobXYZ[3];
2533 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2535 // continue if we are already beyond this layer
2536 Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2537 if(step>0 && oldGlobR > r) continue; // going outward
2538 if(step<0 && oldGlobR < r) continue; // going inward
2541 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2543 Int_t idet=layer.FindDetectorIndex(phi,z);
2545 // check if we allow a prolongation without point for large-eta tracks
2546 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2548 modstatus = 4; // out in z
2549 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2550 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2553 // apply correction for material of the current layer
2554 // add time if going outward
2555 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2559 if (idet<0) return kFALSE;
2562 const AliITSdetector &det=layer.GetDetector(idet);
2563 // only for ITS-SA tracks refit
2564 if (ilayer>1 && fTrackingPhase.Contains("RefitInward") && !(track->GetStatus()&AliESDtrack::kTPCin)) track->SetCheckInvariant(kFALSE);
2566 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2568 track->SetDetectorIndex(idet);
2569 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2571 Double_t dz,zmin,zmax,dy,ymin,ymax;
2573 const AliITSRecPoint *clAcc=0;
2574 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2576 Int_t idx=index[ilayer];
2577 if (idx>=0) { // cluster in this layer
2578 modstatus = 6; // no refit
2579 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2581 if (idet != cl->GetDetectorIndex()) {
2582 idet=cl->GetDetectorIndex();
2583 const AliITSdetector &detc=layer.GetDetector(idet);
2584 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2585 track->SetDetectorIndex(idet);
2586 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2588 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2589 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2593 modstatus = 1; // found
2598 } else { // no cluster in this layer
2600 modstatus = 3; // skipped
2601 // Plane Eff determination:
2602 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2603 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2604 UseTrackForPlaneEff(track,ilayer);
2607 modstatus = 5; // no cls in road
2609 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2610 dz = 0.5*(zmax-zmin);
2611 dy = 0.5*(ymax-ymin);
2612 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2613 if (dead==1) modstatus = 7; // holes in z in SPD
2614 if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2619 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2620 track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2622 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2625 if (extra && clAcc) { // search for extra clusters in overlapped modules
2626 AliITStrackV2 tmp(*track);
2627 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2628 layer.SelectClusters(zmin,zmax,ymin,ymax);
2630 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2632 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2633 Double_t tolerance=0.1;
2634 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2635 // only clusters in another module! (overlaps)
2636 idetExtra = clExtra->GetDetectorIndex();
2637 if (idet == idetExtra) continue;
2639 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2641 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2642 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2643 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2644 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2646 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2647 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2650 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2651 track->SetExtraModule(ilayer,idetExtra);
2653 } // end search for extra clusters in overlapped modules
2655 // Correct for material of the current layer
2657 // add time if going outward
2658 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2659 track->SetCheckInvariant(kTRUE);
2660 } // end loop on layers
2662 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2666 //------------------------------------------------------------------------
2667 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2670 // calculate normalized chi2
2671 // return NormalizedChi2(track,0);
2674 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2675 // track->fdEdxMismatch=0;
2676 Float_t dedxmismatch =0;
2677 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2679 for (Int_t i = 0;i<6;i++){
2680 if (track->GetClIndex(i)>=0){
2681 Float_t cerry, cerrz;
2682 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2684 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2687 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2688 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2689 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2691 cchi2+=(0.5-ratio)*10.;
2692 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2693 dedxmismatch+=(0.5-ratio)*10.;
2697 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2698 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2699 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2700 if (i<2) chi2+=2*cl->GetDeltaProbability();
2706 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2707 track->SetdEdxMismatch(dedxmismatch);
2711 for (Int_t i = 0;i<4;i++){
2712 if (track->GetClIndex(i)>=0){
2713 Float_t cerry, cerrz;
2714 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2715 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2718 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2719 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2723 for (Int_t i = 4;i<6;i++){
2724 if (track->GetClIndex(i)>=0){
2725 Float_t cerry, cerrz;
2726 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2727 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2730 Float_t cerryb, cerrzb;
2731 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2732 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2735 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2736 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2741 if (track->GetESDtrack()->GetTPCsignal()>85){
2742 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2744 chi2+=(0.5-ratio)*5.;
2747 chi2+=(ratio-2.0)*3;
2751 Double_t match = TMath::Sqrt(track->GetChi22());
2752 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2753 if (!track->GetConstrain()) {
2754 if (track->GetNumberOfClusters()>2) {
2755 match/=track->GetNumberOfClusters()-2.;
2760 if (match<0) match=0;
2762 // penalty factor for missing points (NDeadZone>0), but no penalty
2763 // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2764 // or there is a dead from OCDB)
2765 Float_t deadzonefactor = 0.;
2766 if (track->GetNDeadZone()>0.) {
2767 Int_t sumDeadZoneProbability=0;
2768 for(Int_t ilay=0;ilay<6;ilay++) {
2769 if(track->GetDeadZoneProbability(ilay)>0.) sumDeadZoneProbability++;
2771 Int_t nDeadZoneWithProbNot1=(Int_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2772 if(nDeadZoneWithProbNot1>0) {
2773 Float_t deadZoneProbability = track->GetNDeadZone()-(Float_t)sumDeadZoneProbability;
2774 AliDebug(2,Form("nDeadZone %f sumDZProbability %d nDZWithProbNot1 %d deadZoneProb %f\n",track->GetNDeadZone(),sumDeadZoneProbability,nDeadZoneWithProbNot1,deadZoneProbability));
2775 deadZoneProbability /= (Float_t)nDeadZoneWithProbNot1;
2777 deadZoneProbability = TMath::Min(deadZoneProbability,one);
2778 deadzonefactor = 3.*(1.1-deadZoneProbability);
2782 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2783 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2784 1./(1.+track->GetNSkipped()));
2785 AliDebug(2,Form("match %f deadzonefactor %f chi2 %f sum %f skipped %f\n",match,deadzonefactor,chi2,sum,track->GetNSkipped()));
2786 AliDebug(2,Form("NormChi2 %f cls %d\n",normchi2,track->GetNumberOfClusters()));
2789 //------------------------------------------------------------------------
2790 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2793 // return matching chi2 between two tracks
2794 Double_t largeChi2=1000.;
2796 AliITStrackMI track3(*track2);
2797 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2799 vec(0,0)=track1->GetY() - track3.GetY();
2800 vec(1,0)=track1->GetZ() - track3.GetZ();
2801 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2802 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2803 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2806 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2807 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2808 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2809 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2810 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2812 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2813 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2814 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2815 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2817 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2818 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2819 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2821 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2822 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2824 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2827 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2828 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2831 //------------------------------------------------------------------------
2832 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2835 // return probability that given point (characterized by z position and error)
2836 // is in SPD dead zone
2837 // This method assumes that fSPDdetzcentre is ordered from -z to +z
2839 Double_t probability = 0.;
2840 Double_t nearestz = 0.,distz=0.;
2841 Int_t nearestzone = -1;
2842 Double_t mindistz = 1000.;
2844 // find closest dead zone
2845 for (Int_t i=0; i<3; i++) {
2846 distz=TMath::Abs(zpos-0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]));
2847 if (distz<mindistz) {
2849 nearestz=0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]);
2854 // too far from dead zone
2855 if (TMath::Abs(zpos-nearestz)>0.25+3.*zerr) return probability;
2858 Double_t zmin, zmax;
2859 if (nearestzone==0) { // dead zone at z = -7
2860 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2861 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2862 } else if (nearestzone==1) { // dead zone at z = 0
2863 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2864 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2865 } else if (nearestzone==2) { // dead zone at z = +7
2866 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2867 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2872 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2874 probability = 0.5*( AliMathBase::ErfFast((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2875 AliMathBase::ErfFast((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2876 AliDebug(2,Form("zpos %f +- %f nearestzone %d zmin zmax %f %f prob %f\n",zpos,zerr,nearestzone,zmin,zmax,probability));
2879 //------------------------------------------------------------------------
2880 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2883 // calculate normalized chi2
2885 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2887 for (Int_t i = 0;i<6;i++){
2888 if (TMath::Abs(track->GetDy(i))>0){
2889 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2890 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2893 else{chi2[i]=10000;}
2896 TMath::Sort(6,chi2,index,kFALSE);
2897 Float_t max = float(ncl)*fac-1.;
2898 Float_t sumchi=0, sumweight=0;
2899 for (Int_t i=0;i<max+1;i++){
2900 Float_t weight = (i<max)?1.:(max+1.-i);
2901 sumchi+=weight*chi2[index[i]];
2904 Double_t normchi2 = sumchi/sumweight;
2907 //------------------------------------------------------------------------
2908 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2911 // calculate normalized chi2
2912 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2915 for (Int_t i=0;i<6;i++){
2916 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2917 Double_t sy1 = forwardtrack->GetSigmaY(i);
2918 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2919 Double_t sy2 = backtrack->GetSigmaY(i);
2920 Double_t sz2 = backtrack->GetSigmaZ(i);
2921 if (i<2){ sy2=1000.;sz2=1000;}
2923 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2924 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2926 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2927 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2929 res+= nz0*nz0+ny0*ny0;
2932 if (npoints>1) return
2933 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2934 //2*forwardtrack->fNUsed+
2935 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2936 1./(1.+forwardtrack->GetNSkipped()));
2939 //------------------------------------------------------------------------
2940 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2941 //--------------------------------------------------------------------
2942 // Return pointer to a given cluster
2943 //--------------------------------------------------------------------
2944 Int_t l=(index & 0xf0000000) >> 28;
2945 Int_t c=(index & 0x0fffffff) >> 00;
2946 return fgLayers[l].GetWeight(c);
2948 //------------------------------------------------------------------------
2949 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2951 //---------------------------------------------
2952 // register track to the list
2954 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2957 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2958 Int_t index = track->GetClusterIndex(icluster);
2959 Int_t l=(index & 0xf0000000) >> 28;
2960 Int_t c=(index & 0x0fffffff) >> 00;
2961 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2962 for (Int_t itrack=0;itrack<4;itrack++){
2963 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2964 fgLayers[l].SetClusterTracks(itrack,c,id);
2970 //------------------------------------------------------------------------
2971 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2973 //---------------------------------------------
2974 // unregister track from the list
2975 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2976 Int_t index = track->GetClusterIndex(icluster);
2977 Int_t l=(index & 0xf0000000) >> 28;
2978 Int_t c=(index & 0x0fffffff) >> 00;
2979 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2980 for (Int_t itrack=0;itrack<4;itrack++){
2981 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2982 fgLayers[l].SetClusterTracks(itrack,c,-1);
2987 //------------------------------------------------------------------------
2988 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2990 //-------------------------------------------------------------
2991 //get number of shared clusters
2992 //-------------------------------------------------------------
2994 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2995 // mean number of clusters
2996 Float_t *ny = GetNy(id), *nz = GetNz(id);
2999 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
3000 Int_t index = track->GetClusterIndex(icluster);
3001 Int_t l=(index & 0xf0000000) >> 28;
3002 Int_t c=(index & 0x0fffffff) >> 00;
3003 if (c>fgLayers[l].GetNumberOfClusters()) continue;
3004 // if (ny[l]<1.e-13){
3005 // printf("problem\n");
3007 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
3011 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
3012 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
3013 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
3015 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
3018 deltan = (cl->GetNz()-nz[l]);
3020 if (deltan>2.0) continue; // extended - highly probable shared cluster
3021 weight = 2./TMath::Max(3.+deltan,2.);
3023 for (Int_t itrack=0;itrack<4;itrack++){
3024 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
3026 clist[l] = (AliITSRecPoint*)GetCluster(index);
3027 track->SetSharedWeight(l,weight);
3033 track->SetNUsed(shared);
3036 //------------------------------------------------------------------------
3037 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
3040 // find first shared track
3042 // mean number of clusters
3043 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
3045 for (Int_t i=0;i<6;i++) overlist[i]=-1;
3046 Int_t sharedtrack=100000;
3047 Int_t tracks[24],trackindex=0;
3048 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
3050 for (Int_t icluster=0;icluster<6;icluster++){
3051 if (clusterlist[icluster]<0) continue;
3052 Int_t index = clusterlist[icluster];
3053 Int_t l=(index & 0xf0000000) >> 28;
3054 Int_t c=(index & 0x0fffffff) >> 00;
3055 // if (ny[l]<1.e-13){
3056 // printf("problem\n");
3058 if (c>fgLayers[l].GetNumberOfClusters()) continue;
3059 //if (l>3) continue;
3060 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
3063 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
3064 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
3065 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
3067 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
3070 deltan = (cl->GetNz()-nz[l]);
3072 if (deltan>2.0) continue; // extended - highly probable shared cluster
3074 for (Int_t itrack=3;itrack>=0;itrack--){
3075 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
3076 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
3077 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
3082 if (trackindex==0) return -1;
3084 sharedtrack = tracks[0];
3086 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
3089 Int_t tracks2[24], cluster[24];
3090 for (Int_t i=0;i<24;i++){ tracks2[i]=-1; cluster[i]=0;}
3093 for (Int_t i=0;i<trackindex;i++){
3094 if (tracks[i]<0) continue;
3095 tracks2[index] = tracks[i];
3097 for (Int_t j=i+1;j<trackindex;j++){
3098 if (tracks[j]<0) continue;
3099 if (tracks[j]==tracks[i]){
3107 for (Int_t i=0;i<index;i++){
3108 if (cluster[index]>max) {
3109 sharedtrack=tracks2[index];
3116 if (sharedtrack>=100000) return -1;
3118 // make list of overlaps
3120 for (Int_t icluster=0;icluster<6;icluster++){
3121 if (clusterlist[icluster]<0) continue;
3122 Int_t index = clusterlist[icluster];
3123 Int_t l=(index & 0xf0000000) >> 28;
3124 Int_t c=(index & 0x0fffffff) >> 00;
3125 if (c>fgLayers[l].GetNumberOfClusters()) continue;
3126 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
3128 if (cl->GetNy()>2) continue;
3129 if (cl->GetNz()>2) continue;
3132 if (cl->GetNy()>3) continue;
3133 if (cl->GetNz()>3) continue;
3136 for (Int_t itrack=3;itrack>=0;itrack--){
3137 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
3138 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
3146 //------------------------------------------------------------------------
3147 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1,AliITStrackMI* original){
3149 // try to find track hypothesys without conflicts
3150 // with minimal chi2;
3151 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
3152 Int_t entries1 = arr1->GetEntriesFast();
3153 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
3154 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
3155 Int_t entries2 = arr2->GetEntriesFast();
3156 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
3158 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
3159 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
3160 if (track10->Pt()>0.5+track20->Pt()) return track10;
3162 for (Int_t itrack=0;itrack<entries1;itrack++){
3163 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3164 UnRegisterClusterTracks(track,trackID1);
3167 for (Int_t itrack=0;itrack<entries2;itrack++){
3168 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3169 UnRegisterClusterTracks(track,trackID2);
3173 Float_t maxconflicts=6;
3174 Double_t maxchi2 =1000.;
3176 // get weight of hypothesys - using best hypothesy
3179 Int_t list1[6],list2[6];
3180 AliITSRecPoint *clist1[6], *clist2[6] ;
3181 RegisterClusterTracks(track10,trackID1);
3182 RegisterClusterTracks(track20,trackID2);
3183 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
3184 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
3185 UnRegisterClusterTracks(track10,trackID1);
3186 UnRegisterClusterTracks(track20,trackID2);
3189 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
3190 Float_t nerry[6],nerrz[6];
3191 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
3192 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
3193 for (Int_t i=0;i<6;i++){
3194 if ( (erry1[i]>0) && (erry2[i]>0)) {
3195 nerry[i] = TMath::Min(erry1[i],erry2[i]);
3196 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
3198 nerry[i] = TMath::Max(erry1[i],erry2[i]);
3199 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
3201 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
3202 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
3203 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
3206 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
3207 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
3208 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
3216 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
3217 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
3218 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
3219 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
3221 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
3222 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
3223 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
3225 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
3226 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
3227 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
3230 Double_t sumw = w1+w2;
3234 w1 = (d2+0.5)/(d1+d2+1.);
3235 w2 = (d1+0.5)/(d1+d2+1.);
3237 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
3238 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
3240 // get pair of "best" hypothesys
3242 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
3243 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
3245 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
3246 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
3247 //if (track1->fFakeRatio>0) continue;
3248 RegisterClusterTracks(track1,trackID1);
3249 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
3250 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
3252 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
3253 //if (track2->fFakeRatio>0) continue;
3255 RegisterClusterTracks(track2,trackID2);
3256 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
3257 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
3258 UnRegisterClusterTracks(track2,trackID2);
3260 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
3261 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
3262 if (nskipped>0.5) continue;
3264 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
3265 if (conflict1+1<cconflict1) continue;
3266 if (conflict2+1<cconflict2) continue;
3270 for (Int_t i=0;i<6;i++){
3272 Float_t c1 =0.; // conflict coeficients
3274 if (clist1[i]&&clist2[i]){
3277 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
3280 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
3282 c1 = 2./TMath::Max(3.+deltan,2.);
3283 c2 = 2./TMath::Max(3.+deltan,2.);
3289 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
3292 deltan = (clist1[i]->GetNz()-nz1[i]);
3294 c1 = 2./TMath::Max(3.+deltan,2.);
3301 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
3304 deltan = (clist2[i]->GetNz()-nz2[i]);
3306 c2 = 2./TMath::Max(3.+deltan,2.);
3312 if (TMath::Abs(track1->GetDy(i))>0.) {
3313 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
3314 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
3315 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
3316 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
3318 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
3321 if (TMath::Abs(track2->GetDy(i))>0.) {
3322 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
3323 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
3324 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
3325 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3328 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3330 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3331 if (chi21>0) sum+=w1;
3332 if (chi22>0) sum+=w2;
3335 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3336 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3337 Double_t normchi2 = 2*conflict+sumchi2/sum;
3338 if ( normchi2 <maxchi2 ){
3341 maxconflicts = conflict;
3345 UnRegisterClusterTracks(track1,trackID1);
3348 // if (maxconflicts<4 && maxchi2<th0){
3349 if (maxchi2<th0*2.){
3350 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3351 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3352 track1->SetChi2MIP(5,maxconflicts);
3353 track1->SetChi2MIP(6,maxchi2);
3354 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3355 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3356 track1->SetChi2MIP(8,index1);
3357 fBestTrackIndex[trackID1] =index1;
3358 UpdateESDtrack(track1, AliESDtrack::kITSin);
3359 original->SetWinner(track1);
3361 else if (track10->GetChi2MIP(0)<th1){
3362 track10->SetChi2MIP(5,maxconflicts);
3363 track10->SetChi2MIP(6,maxchi2);
3364 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3365 UpdateESDtrack(track10,AliESDtrack::kITSin);
3366 original->SetWinner(track10);
3369 for (Int_t itrack=0;itrack<entries1;itrack++){
3370 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3371 UnRegisterClusterTracks(track,trackID1);
3374 for (Int_t itrack=0;itrack<entries2;itrack++){
3375 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3376 UnRegisterClusterTracks(track,trackID2);
3379 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3380 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3381 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3382 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3383 RegisterClusterTracks(track10,trackID1);
3385 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3386 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3387 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3388 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3389 RegisterClusterTracks(track20,trackID2);
3394 //------------------------------------------------------------------------
3395 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3396 //--------------------------------------------------------------------
3397 // This function marks clusters assigned to the track
3398 //--------------------------------------------------------------------
3399 AliTracker::UseClusters(t,from);
3401 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3402 //if (c->GetQ()>2) c->Use();
3403 if (c->GetSigmaZ2()>0.1) c->Use();
3404 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3405 //if (c->GetQ()>2) c->Use();
3406 if (c->GetSigmaZ2()>0.1) c->Use();
3409 //------------------------------------------------------------------------
3410 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3412 //------------------------------------------------------------------
3413 // add track to the list of hypothesys
3414 //------------------------------------------------------------------
3417 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3419 array = new TObjArray(10);
3420 fTrackHypothesys.AddAtAndExpand(array,esdindex);
3422 array->AddLast(track);
3424 //------------------------------------------------------------------------
3425 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3427 //-------------------------------------------------------------------
3428 // compress array of track hypothesys
3429 // keep only maxsize best hypothesys
3430 //-------------------------------------------------------------------
3431 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3432 if (! (fTrackHypothesys.At(esdindex)) ) return;
3433 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3434 Int_t entries = array->GetEntriesFast();
3436 //- find preliminary besttrack as a reference
3437 Float_t minchi2=10000;
3439 AliITStrackMI * besttrack=0;
3441 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3442 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3443 if (!track) continue;
3444 Float_t chi2 = NormalizedChi2(track,0);
3446 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3447 track->SetLabel(tpcLabel);
3449 track->SetFakeRatio(1.);
3450 CookLabel(track,0.); //For comparison only
3452 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3453 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3454 if (track->GetNumberOfClusters()<maxn) continue;
3455 maxn = track->GetNumberOfClusters();
3456 // if (fSelectBestMIP03 && track->GetChi2MIP(3)>0) chi2 *= track->GetChi2MIP(3); // RS
3463 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3464 delete array->RemoveAt(itrack);
3468 if (!besttrack) return;
3471 //take errors of best track as a reference
3472 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3473 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3474 for (Int_t j=0;j<6;j++) {
3475 if (besttrack->GetClIndex(j)>=0){
3476 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3477 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3478 ny[j] = besttrack->GetNy(j);
3479 nz[j] = besttrack->GetNz(j);
3483 // calculate normalized chi2
3485 Float_t * chi2 = new Float_t[entries];
3486 Int_t * index = new Int_t[entries];
3487 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3488 for (Int_t itrack=0;itrack<entries;itrack++){
3489 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3491 AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3492 double chi2t = GetNormalizedChi2(track, mode);
3493 track->SetChi2MIP(0,chi2t);
3494 if (chi2t<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)) {
3495 if (fSelectBestMIP03 && track->GetChi2MIP(3)>0) chi2t *= track->GetChi2MIP(3); // RS
3496 chi2[itrack] = chi2t;
3499 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3500 delete array->RemoveAt(itrack);
3506 TMath::Sort(entries,chi2,index,kFALSE);
3507 besttrack = (AliITStrackMI*)array->At(index[0]);
3508 if(besttrack) AliDebug(2,Form("ncls best track %d\n",besttrack->GetNumberOfClusters()));
3509 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3510 for (Int_t j=0;j<6;j++){
3511 if (besttrack->GetClIndex(j)>=0){
3512 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3513 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3514 ny[j] = besttrack->GetNy(j);
3515 nz[j] = besttrack->GetNz(j);
3520 // calculate one more time with updated normalized errors
3521 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3522 for (Int_t itrack=0;itrack<entries;itrack++){
3523 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3525 double chi2t = GetNormalizedChi2(track, mode);
3526 track->SetChi2MIP(0,chi2t);
3527 AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3528 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)) {
3529 if (fSelectBestMIP03 && track->GetChi2MIP(3)>0) chi2t *= track->GetChi2MIP(3); // RS
3530 chi2[itrack] = chi2t; //-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3533 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3534 delete array->RemoveAt(itrack);
3539 entries = array->GetEntriesFast();
3543 TObjArray * newarray = new TObjArray();
3544 TMath::Sort(entries,chi2,index,kFALSE);
3545 besttrack = (AliITStrackMI*)array->At(index[0]);
3547 AliDebug(2,Form("ncls best track %d %f %f\n",besttrack->GetNumberOfClusters(),besttrack->GetChi2MIP(0),chi2[index[0]]));
3549 for (Int_t j=0;j<6;j++){
3550 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3551 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3552 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3553 ny[j] = besttrack->GetNy(j);
3554 nz[j] = besttrack->GetNz(j);
3557 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3558 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3559 Float_t minn = besttrack->GetNumberOfClusters()-3;
3561 for (Int_t i=0;i<entries;i++){
3562 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3563 if (!track) continue;
3564 if (accepted>maxcut) break;
3565 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3566 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3567 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3568 delete array->RemoveAt(index[i]);
3572 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3573 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3574 if (!shortbest) accepted++;
3576 newarray->AddLast(array->RemoveAt(index[i]));
3577 for (Int_t j=0;j<6;j++){
3579 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3580 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3581 ny[j] = track->GetNy(j);
3582 nz[j] = track->GetNz(j);
3587 delete array->RemoveAt(index[i]);
3591 delete fTrackHypothesys.RemoveAt(esdindex);
3592 fTrackHypothesys.AddAt(newarray,esdindex);
3596 delete fTrackHypothesys.RemoveAt(esdindex);
3602 //------------------------------------------------------------------------
3603 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3605 //-------------------------------------------------------------
3606 // try to find best hypothesy
3607 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3608 // RS: optionally changing this to product of Chi2MIP(0)*Chi2MIP(3) == (chi2*chi2_interpolated)
3609 //-------------------------------------------------------------
3610 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3611 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3612 if (!array) return 0;
3613 Int_t entries = array->GetEntriesFast();
3614 if (!entries) return 0;
3615 Float_t minchi2 = 100000;
3616 AliITStrackMI * besttrack=0;
3618 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3619 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3620 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3621 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3623 for (Int_t i=0;i<entries;i++){
3624 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3625 if (!track) continue;
3626 Float_t sigmarfi,sigmaz;
3627 GetDCASigma(track,sigmarfi,sigmaz);
3628 track->SetDnorm(0,sigmarfi);
3629 track->SetDnorm(1,sigmaz);
3631 track->SetChi2MIP(1,1000000);
3632 track->SetChi2MIP(2,1000000);
3633 track->SetChi2MIP(3,1000000);
3636 backtrack = new(backtrack) AliITStrackMI(*track);
3637 if (track->GetConstrain()) {
3638 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3639 if (AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
3640 if (fUseImproveKalman) {if (!backtrack->ImproveKalman(xyzVtx,ersVtx,0,0,0)) continue;}
3641 else {if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;}
3643 backtrack->ResetCovariance(10.);
3645 backtrack->ResetCovariance(10.);
3647 backtrack->ResetClusters();
3649 Double_t x = original->GetX();
3650 if (!RefitAt(x,backtrack,track)) continue;
3652 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3653 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3654 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3655 track->SetChi22(GetMatchingChi2(backtrack,original));
3657 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3658 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3659 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3662 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3664 //forward track - without constraint
3665 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3666 forwardtrack->ResetClusters();
3668 if (!RefitAt(x,forwardtrack,track) && fSelectBestMIP03) continue; // w/o fwd track MIP03 is meaningless
3669 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3670 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3671 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3673 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3674 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3675 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3676 forwardtrack->SetD(0,track->GetD(0));
3677 forwardtrack->SetD(1,track->GetD(1));
3680 AliITSRecPoint* clist[6];
3681 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3682 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3685 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3686 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3687 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3688 track->SetChi2MIP(3,1000);
3691 Double_t chi2 = track->GetChi2MIP(0); // +track->GetNUsed(); //RS
3692 if (fSelectBestMIP03) chi2 *= track->GetChi2MIP(3);
3693 else chi2 += track->GetNUsed();
3695 for (Int_t ichi=0;ichi<5;ichi++){
3696 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3698 if (chi2 < minchi2){
3699 //besttrack = new AliITStrackMI(*forwardtrack);
3701 besttrack->SetLabel(track->GetLabel());
3702 besttrack->SetFakeRatio(track->GetFakeRatio());
3704 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3705 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3706 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3710 delete forwardtrack;
3712 if (!besttrack) return 0;
3715 for (Int_t i=0;i<entries;i++){
3716 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3718 if (!track) continue;
3720 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3721 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)
3722 // RS: don't apply this cut when fSelectBestMIP03 is on
3723 || (!fSelectBestMIP03 && (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.))
3725 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3726 delete array->RemoveAt(i);
3736 SortTrackHypothesys(esdindex,checkmax,1);
3738 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3739 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3740 besttrack = (AliITStrackMI*)array->At(0);
3741 if (!besttrack) return 0;
3742 besttrack->SetChi2MIP(8,0);
3743 fBestTrackIndex[esdindex]=0;
3744 entries = array->GetEntriesFast();
3745 AliITStrackMI *longtrack =0;
3747 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3748 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3749 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3750 if (!track->GetConstrain()) continue;
3751 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3752 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3753 if (track->GetChi2MIP(0)>4.) continue;
3754 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3757 //if (longtrack) besttrack=longtrack;
3759 // RS do shared cluster analysis here only if the new sharing analysis is not requested
3760 //RRR if (fFlagFakes) return besttrack;
3763 AliITSRecPoint * clist[6];
3764 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3765 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3766 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3767 RegisterClusterTracks(besttrack,esdindex);
3774 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3775 if (sharedtrack>=0){
3777 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5,original);
3779 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3785 if (shared>2.5) return 0;
3786 if (shared>1.0) return besttrack;
3788 // Don't sign clusters if not gold track
3790 if (!besttrack->IsGoldPrimary()) return besttrack;
3791 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3793 if (fConstraint[fPass]){
3797 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3798 for (Int_t i=0;i<6;i++){
3799 Int_t index = besttrack->GetClIndex(i);
3800 if (index<0) continue;
3801 Int_t ilayer = (index & 0xf0000000) >> 28;
3802 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3803 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3805 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3806 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3807 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3808 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3809 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3810 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3812 Bool_t cansign = kTRUE;
3813 for (Int_t itrack=0;itrack<entries; itrack++){
3814 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3815 if (!track) continue;
3816 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3817 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3823 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3824 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3825 if (!c->IsUsed()) c->Use();
3831 //------------------------------------------------------------------------
3832 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3835 // get "best" hypothesys
3838 Int_t nentries = itsTracks.GetEntriesFast();
3839 for (Int_t i=0;i<nentries;i++){
3840 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3841 if (!track) continue;
3842 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3843 if (!array) continue;
3844 if (array->GetEntriesFast()<=0) continue;
3846 AliITStrackMI* longtrack=0;
3848 Float_t maxchi2=1000;
3849 for (Int_t j=0;j<array->GetEntriesFast();j++){
3850 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3851 if (!trackHyp) continue;
3852 if (trackHyp->GetGoldV0()) {
3853 longtrack = trackHyp; //gold V0 track taken
3856 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3857 Float_t chi2 = trackHyp->GetChi2MIP(0);
3858 if (fSelectBestMIP03) chi2 *= trackHyp->GetChi2MIP(3);
3859 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = chi2; //trackHyp->GetChi2MIP(0);
3861 if (fAfterV0){ // ??? RS
3862 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3864 if (chi2 > maxchi2) continue;
3865 minn = trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3866 if (fSelectBestMIP03) minn++; // allow next to longest to win
3873 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3874 if (!longtrack) {longtrack = besttrack;}
3875 else besttrack= longtrack;
3879 AliITSRecPoint * clist[6];
3880 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3882 track->SetNUsed(shared);
3883 track->SetNSkipped(besttrack->GetNSkipped());
3884 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3886 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3890 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3891 //if (sharedtrack==-1) sharedtrack=0;
3892 if (sharedtrack>=0) {
3893 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5,track);
3896 if (besttrack&&fAfterV0) {
3897 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3898 track->SetWinner(besttrack);
3901 if (fConstraint[fPass]) {
3902 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3903 track->SetWinner(besttrack);
3905 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3906 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3907 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3914 //------------------------------------------------------------------------
3915 void AliITStrackerMI::FlagFakes(const TObjArray &itsTracks)
3918 // RS: flag those tracks which are suxpected to have fake clusters
3920 const double kThreshPt = 0.5;
3921 AliRefArray *refArr[6];
3923 for (int i=0;i<6;i++) {
3924 int ncl = fgLayers[i].GetNumberOfClusters();
3925 refArr[i] = new AliRefArray(ncl,TMath::Min(ncl,1000));
3927 Int_t nentries = itsTracks.GetEntriesFast();
3929 // fill cluster->track associations
3930 for (Int_t itr=0;itr<nentries;itr++){
3931 AliITStrackMI* track = (AliITStrackMI*)itsTracks.UncheckedAt(itr);
3932 if (!track) continue;
3933 AliITStrackMI* trackITS = track->GetWinner();
3934 if (!trackITS) continue;
3935 for (int il=trackITS->GetNumberOfClusters();il--;) {
3936 int idx = trackITS->GetClusterIndex(il);
3937 Int_t l=(idx & 0xf0000000) >> 28, c=(idx & 0x0fffffff) >> 00;
3938 // if (c>fgLayers[l].GetNumberOfClusters()) continue;
3939 refArr[l]->AddReference(c, itr);
3943 const UInt_t kMaxRef = 100;
3944 UInt_t crefs[kMaxRef];
3946 // process tracks with shared clusters
3947 for (int itr=0;itr<nentries;itr++){
3948 AliITStrackMI* track0 = (AliITStrackMI*)itsTracks.UncheckedAt(itr);
3949 AliITStrackMI* trackH0 = track0->GetWinner();
3950 if (!trackH0) continue;
3951 AliESDtrack* esd0 = track0->GetESDtrack();
3953 for (int il=0;il<trackH0->GetNumberOfClusters();il++) {
3954 int idx = trackH0->GetClusterIndex(il);
3955 Int_t l=(idx & 0xf0000000) >> 28, c=(idx & 0x0fffffff) >> 00;
3956 ncrefs = refArr[l]->GetReferences(c,crefs,kMaxRef);
3957 if (ncrefs<2) continue; // there will be always self-reference, for sharing needs at least 2
3958 esd0->SetITSSharedFlag(l);
3959 for (int ir=ncrefs;ir--;) {
3960 if (int(crefs[ir]) <= itr) continue; // ==:selfreference, <: the same pair will be checked with >
3961 AliITStrackMI* track1 = (AliITStrackMI*)itsTracks.UncheckedAt(crefs[ir]);
3962 AliITStrackMI* trackH1 = track1->GetWinner();
3963 AliESDtrack* esd1 = track1->GetESDtrack();
3964 esd1->SetITSSharedFlag(l);
3966 double pt0 = trackH0->Pt(), pt1 = trackH1->Pt(), res = 0.;
3967 if (pt0>kThreshPt && pt0-pt1>0.2+0.2*(pt0-kThreshPt) ) res = -100;
3968 else if (pt1>kThreshPt && pt1-pt0>0.2+0.2*(pt1-kThreshPt) ) res = 100;
3970 // select the one with smallest chi2's product
3971 res += trackH0->GetChi2MIP(0)*trackH0->GetChi2MIP(3);
3972 res -= trackH1->GetChi2MIP(0)*trackH1->GetChi2MIP(3);
3974 if (res<0) esd1->SetITSFakeFlag(); // esd0 is winner
3975 else esd0->SetITSFakeFlag(); // esd1 is winner
3982 for (int i=6;i--;) delete refArr[i];
3987 //------------------------------------------------------------------------
3988 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3989 //--------------------------------------------------------------------
3990 //This function "cooks" a track label. If label<0, this track is fake.
3991 //--------------------------------------------------------------------
3992 const int kMaxLbPerCl = 3;
3993 int lbID[36],lbStat[36];
3994 Int_t nLab=0, nCl = track->GetNumberOfClusters();
3996 // track->SetLabel(-1);
3997 // track->SetFakeRatio(0);
3999 for (Int_t i=0;i<nCl;i++) { // fill all labels
4000 Int_t cindex = track->GetClusterIndex(i);
4001 // Int_t l=(cindex & 0xf0000000) >> 28;
4002 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
4004 for (int imc=0;imc<kMaxLbPerCl;imc++) { // labels within single cluster
4005 int trLb = cl->GetLabel(imc);
4007 // search this mc track in already accounted ones
4009 for (iLab=0;iLab<nLab;iLab++) if (lbID[iLab]==trLb) break;
4010 if (iLab<nLab) lbStat[iLab]++;
4015 } // loop over given cluster's labels
4016 } // loop over clusters
4018 if (nLab<1) return; // no labels at all
4021 if (track->GetESDtrack() && track->GetESDtrack()->IsOn(AliESDtrack::kTPCin)){
4022 tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
4025 // find majority label
4027 int maxLab=0,tpcLabID=-1;
4028 for (int ilb=nLab;ilb--;) {
4029 int st = lbStat[ilb];
4030 if (lbStat[maxLab]<st) maxLab = ilb;
4031 if (lbID[ilb] == tpcLabel) tpcLabID = ilb;
4033 // if there is an equal choice, prefer ITS label consistent with TPC label
4034 if (tpcLabel>0 && (tpcLabID!=maxLab) && lbStat[maxLab]==lbStat[tpcLabID]) maxLab=tpcLabID;
4036 track->SetFakeRatio(1.-float(lbStat[maxLab])/nCl);
4037 track->SetLabel( lbStat[maxLab]>=nCl-wrong ? lbID[maxLab] : -lbID[maxLab]);
4043 //------------------------------------------------------------------------
4044 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
4045 //--------------------------------------------------------------------
4046 //This function "cooks" a track label. If label<0, this track is fake.
4047 //--------------------------------------------------------------------
4050 if (track->GetESDtrack()){
4051 tpcLabel = track->GetESDtrack()->GetTPCLabel();
4052 ULong_t trStatus=track->GetESDtrack()->GetStatus();
4053 if(!(trStatus&AliESDtrack::kTPCin)) tpcLabel=track->GetLabel(); // for ITSsa tracks
4055 track->SetChi2MIP(9,0);
4057 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
4058 Int_t cindex = track->GetClusterIndex(i);
4059 Int_t l=(cindex & 0xf0000000) >> 28;
4060 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
4062 for (Int_t ind=0;ind<3;ind++){
4063 if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
4064 //AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
4066 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
4069 Int_t nclusters = track->GetNumberOfClusters();
4070 if (nclusters > 0) //PH Some tracks don't have any cluster
4071 track->SetFakeRatio(double(nwrong)/double(nclusters));
4072 if (tpcLabel>0 && track->GetFakeRatio()>wrong) {
4073 track->SetLabel(-tpcLabel);
4075 track->SetLabel(tpcLabel);
4077 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
4081 //------------------------------------------------------------------------
4082 void AliITStrackerMI::CookdEdx(AliITStrackMI* track){
4084 // Fill the dE/dx in this track
4086 track->SetChi2MIP(9,0);
4087 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
4088 Int_t cindex = track->GetClusterIndex(i);
4089 Int_t l=(cindex & 0xf0000000) >> 28;
4090 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
4091 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
4093 for (Int_t ind=0;ind<3;ind++){
4094 if (cl->GetLabel(ind)==lab) isWrong=0;
4096 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
4100 track->CookdEdx(low,up);
4102 //------------------------------------------------------------------------
4103 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
4105 // Create some arrays
4107 if (fCoefficients) delete []fCoefficients;
4108 fCoefficients = new Float_t[ntracks*48];
4109 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
4111 //------------------------------------------------------------------------
4112 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4115 // Compute predicted chi2
4117 // Take into account the mis-alignment (bring track to cluster plane)
4118 Double_t xTrOrig=track->GetX();
4119 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
4120 Float_t erry,errz,covyz;
4121 Float_t theta = track->GetTgl();
4122 Float_t phi = track->GetSnp();
4123 phi *= TMath::Sqrt(1./((1.-phi)*(1.+phi)));
4124 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
4125 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()));
4126 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()));
4127 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
4128 // Bring the track back to detector plane in ideal geometry
4129 // [mis-alignment will be accounted for in UpdateMI()]
4130 if (!track->Propagate(xTrOrig)) return 1000.;
4132 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
4133 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
4135 chi2+=0.5*TMath::Min(delta/2,2.);
4136 chi2+=2.*cluster->GetDeltaProbability();
4139 track->SetNy(layer,ny);
4140 track->SetNz(layer,nz);
4141 track->SetSigmaY(layer,erry);
4142 track->SetSigmaZ(layer, errz);
4143 track->SetSigmaYZ(layer,covyz);
4144 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
4145 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
4149 //------------------------------------------------------------------------
4150 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
4155 Int_t layer = (index & 0xf0000000) >> 28;
4156 track->SetClIndex(layer, index);
4157 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
4158 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
4159 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
4160 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
4164 if (TMath::Abs(cl->GetQ())<1.e-13) return 0; // ingore the "virtual" clusters
4167 // Take into account the mis-alignment (bring track to cluster plane)
4168 Double_t xTrOrig=track->GetX();
4169 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
4170 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
4171 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
4172 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
4174 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
4177 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
4178 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
4179 c.SetSigmaYZ(track->GetSigmaYZ(layer));
4182 Int_t updated = track->UpdateMI(&c,chi2,index);
4183 // Bring the track back to detector plane in ideal geometry
4184 if (!track->Propagate(xTrOrig)) return 0;
4186 if(!updated) AliDebug(2,"update failed");
4190 //------------------------------------------------------------------------
4191 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
4194 //DCA sigmas parameterization
4195 //to be paramterized using external parameters in future
4198 Double_t curv=track->GetC();
4199 sigmarfi = 0.0040+1.4 *TMath::Abs(curv)+332.*curv*curv;
4200 sigmaz = 0.0110+4.37*TMath::Abs(curv);
4202 //------------------------------------------------------------------------
4203 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
4206 // Clusters from delta electrons?
4208 Int_t entries = clusterArray->GetEntriesFast();
4209 if (entries<4) return;
4210 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
4211 Int_t layer = cluster->GetLayer();
4212 if (layer>1) return;
4214 Int_t ncandidates=0;
4215 Float_t r = (layer>0)? 7:4;
4217 for (Int_t i=0;i<entries;i++){
4218 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
4219 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
4220 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
4221 index[ncandidates] = i; //candidate to belong to delta electron track
4223 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
4224 cl0->SetDeltaProbability(1);
4230 for (Int_t i=0;i<ncandidates;i++){
4231 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
4232 if (cl0->GetDeltaProbability()>0.8) continue;
4235 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
4236 sumy=sumz=sumy2=sumyz=sumw=0.0;
4237 for (Int_t j=0;j<ncandidates;j++){
4239 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
4241 Float_t dz = cl0->GetZ()-cl1->GetZ();
4242 Float_t dy = cl0->GetY()-cl1->GetY();
4243 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
4244 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
4245 y[ncl] = cl1->GetY();
4246 z[ncl] = cl1->GetZ();
4247 sumy+= y[ncl]*weight;
4248 sumz+= z[ncl]*weight;
4249 sumy2+=y[ncl]*y[ncl]*weight;
4250 sumyz+=y[ncl]*z[ncl]*weight;
4255 if (ncl<4) continue;
4256 Float_t det = sumw*sumy2 - sumy*sumy;
4258 if (TMath::Abs(det)>0.01){
4259 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
4260 Float_t k = (sumyz*sumw - sumy*sumz)/det;
4261 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
4264 Float_t z0 = sumyz/sumy;
4265 delta = TMath::Abs(cl0->GetZ()-z0);
4268 cl0->SetDeltaProbability(1-20.*delta);
4272 //------------------------------------------------------------------------
4273 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
4278 track->UpdateESDtrack(flags);
4279 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
4280 if (oldtrack) delete oldtrack;
4281 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
4282 // if (TMath::Abs(track->GetDnorm(1))<0.000000001){
4283 // printf("Problem\n");
4286 //------------------------------------------------------------------------
4287 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
4289 // Get nearest upper layer close to the point xr.
4290 // rough approximation
4292 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
4293 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
4295 for (Int_t i=0;i<6;i++){
4296 if (radius<kRadiuses[i]){
4303 //------------------------------------------------------------------------
4304 void AliITStrackerMI::BuildMaterialLUT(TString material) {
4305 //--------------------------------------------------------------------
4306 // Fill a look-up table with mean material
4307 //--------------------------------------------------------------------
4311 Double_t point1[3],point2[3];
4312 Double_t phi,cosphi,sinphi,z;
4313 // 0-5 layers, 6 pipe, 7-8 shields
4314 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
4315 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
4317 Int_t ifirst=0,ilast=0;
4318 if(material.Contains("Pipe")) {
4320 } else if(material.Contains("Shields")) {
4322 } else if(material.Contains("Layers")) {
4325 Error("BuildMaterialLUT","Wrong layer name\n");
4327 const double kAngEps = 1e-4; // tiny slope to avoid tracks strictly normal to Z axis
4328 for(Int_t imat=ifirst; imat<=ilast; imat++) {
4329 Double_t param[5]={0.,0.,0.,0.,0.};
4330 for (Int_t i=0; i<n; i++) {
4331 phi = 2.*TMath::Pi()*gRandom->Rndm();
4332 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
4333 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
4334 point1[0] = rmin[imat]*cosphi;
4335 point1[1] = rmin[imat]*sinphi;
4337 point2[0] = rmax[imat]*cosphi;
4338 point2[1] = rmax[imat]*sinphi;
4339 point2[2] = z+(rmax[imat]-rmin[imat])*kAngEps;
4340 AliTracker::MeanMaterialBudget(point1,point2,mparam);
4341 if (mparam[1]>999) {n--; continue;} // skip anomalous values in failed propagation
4342 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
4344 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
4346 fxOverX0Layer[imat] = param[1];
4347 fxTimesRhoLayer[imat] = param[0]*param[4];
4348 } else if(imat==6) {
4349 fxOverX0Pipe = param[1];
4350 fxTimesRhoPipe = param[0]*param[4];
4351 } else if(imat==7) {
4352 fxOverX0Shield[0] = param[1];
4353 fxTimesRhoShield[0] = param[0]*param[4];
4354 } else if(imat==8) {
4355 fxOverX0Shield[1] = param[1];
4356 fxTimesRhoShield[1] = param[0]*param[4];
4360 printf("%s\n",material.Data());
4361 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
4362 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
4363 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
4364 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
4365 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
4366 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
4367 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
4368 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
4369 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
4373 //------------------------------------------------------------------------
4374 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
4375 TString direction) {
4376 //-------------------------------------------------------------------
4377 // Propagate beyond beam pipe and correct for material
4378 // (material budget in different ways according to fUseTGeo value)
4379 // Add time if going outward (PropagateTo or PropagateToTGeo)
4380 //-------------------------------------------------------------------
4382 // Define budget mode:
4383 // 0: material from AliITSRecoParam (hard coded)
4384 // 1: material from TGeo in one step (on the fly)
4385 // 2: material from lut
4386 // 3: material from TGeo in one step (same for all hypotheses)
4399 if(fTrackingPhase.Contains("Clusters2Tracks"))
4400 { mode=3; } else { mode=1; }
4403 if(fTrackingPhase.Contains("Clusters2Tracks"))
4404 { mode=3; } else { mode=2; }
4410 if(fTrackingPhase.Contains("Default")) mode=0;
4412 Int_t index=fCurrentEsdTrack;
4414 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4415 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4417 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4419 Double_t xOverX0,x0,lengthTimesMeanDensity;
4423 xOverX0 = AliITSRecoParam::GetdPipe();
4424 x0 = AliITSRecoParam::GetX0Be();
4425 lengthTimesMeanDensity = xOverX0*x0;
4426 lengthTimesMeanDensity *= dir;
4427 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4430 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4433 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4434 xOverX0 = fxOverX0Pipe;
4435 lengthTimesMeanDensity = fxTimesRhoPipe;
4436 lengthTimesMeanDensity *= dir;
4437 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4440 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4441 if(fxOverX0PipeTrks[index]<0) {
4442 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4443 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4444 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4445 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4446 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4449 xOverX0 = fxOverX0PipeTrks[index];
4450 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4451 lengthTimesMeanDensity *= dir;
4452 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4458 //------------------------------------------------------------------------
4459 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4461 TString direction) {
4462 //-------------------------------------------------------------------
4463 // Propagate beyond SPD or SDD shield and correct for material
4464 // (material budget in different ways according to fUseTGeo value)
4465 // Add time if going outward (PropagateTo or PropagateToTGeo)
4466 //-------------------------------------------------------------------
4468 // Define budget mode:
4469 // 0: material from AliITSRecoParam (hard coded)
4470 // 1: material from TGeo in steps of X cm (on the fly)
4471 // X = AliITSRecoParam::GetStepSizeTGeo()
4472 // 2: material from lut
4473 // 3: material from TGeo in one step (same for all hypotheses)
4486 if(fTrackingPhase.Contains("Clusters2Tracks"))
4487 { mode=3; } else { mode=1; }
4490 if(fTrackingPhase.Contains("Clusters2Tracks"))
4491 { mode=3; } else { mode=2; }
4497 if(fTrackingPhase.Contains("Default")) mode=0;
4499 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4501 Int_t shieldindex=0;
4502 if (shield.Contains("SDD")) { // SDDouter
4503 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4505 } else if (shield.Contains("SPD")) { // SPDouter
4506 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4509 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4513 // do nothing if we are already beyond the shield
4514 Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4515 if(dir<0 && rTrack > rToGo) return 1; // going outward
4516 if(dir>0 && rTrack < rToGo) return 1; // going inward
4520 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4522 Int_t index=2*fCurrentEsdTrack+shieldindex;
4524 Double_t xOverX0,x0,lengthTimesMeanDensity;
4529 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4530 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4531 lengthTimesMeanDensity = xOverX0*x0;
4532 lengthTimesMeanDensity *= dir;
4533 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4536 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4537 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4540 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4541 xOverX0 = fxOverX0Shield[shieldindex];
4542 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4543 lengthTimesMeanDensity *= dir;
4544 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4547 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4548 if(fxOverX0ShieldTrks[index]<0) {
4549 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4550 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4551 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4552 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4553 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4556 xOverX0 = fxOverX0ShieldTrks[index];
4557 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4558 lengthTimesMeanDensity *= dir;
4559 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4565 //------------------------------------------------------------------------
4566 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4568 Double_t oldGlobXYZ[3],
4569 TString direction) {
4570 //-------------------------------------------------------------------
4571 // Propagate beyond layer and correct for material
4572 // (material budget in different ways according to fUseTGeo value)
4573 // Add time if going outward (PropagateTo or PropagateToTGeo)
4574 //-------------------------------------------------------------------
4576 // Define budget mode:
4577 // 0: material from AliITSRecoParam (hard coded)
4578 // 1: material from TGeo in stepsof X cm (on the fly)
4579 // X = AliITSRecoParam::GetStepSizeTGeo()
4580 // 2: material from lut
4581 // 3: material from TGeo in one step (same for all hypotheses)
4594 if(fTrackingPhase.Contains("Clusters2Tracks"))
4595 { mode=3; } else { mode=1; }
4598 if(fTrackingPhase.Contains("Clusters2Tracks"))
4599 { mode=3; } else { mode=2; }
4605 if(fTrackingPhase.Contains("Default")) mode=0;
4607 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4609 Double_t r=fgLayers[layerindex].GetR();
4610 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4612 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4614 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4616 Int_t index=6*fCurrentEsdTrack+layerindex;
4619 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4622 // back before material (no correction)
4624 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4625 if (!t->GetLocalXat(rOld,xOld)) return 0;
4626 if (!t->Propagate(xOld)) return 0;
4630 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4631 lengthTimesMeanDensity = xOverX0*x0;
4632 lengthTimesMeanDensity *= dir;
4633 // Bring the track beyond the material
4634 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4637 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4638 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4641 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4642 xOverX0 = fxOverX0Layer[layerindex];
4643 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4644 lengthTimesMeanDensity *= dir;
4645 // Bring the track beyond the material
4646 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4649 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4650 if(fxOverX0LayerTrks[index]<0) {
4651 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4652 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4653 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4654 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4655 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4656 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4659 xOverX0 = fxOverX0LayerTrks[index];
4660 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4661 lengthTimesMeanDensity *= dir;
4662 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4669 //------------------------------------------------------------------------
4670 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4671 //-----------------------------------------------------------------
4672 // Initialize LUT for storing material for each prolonged track
4673 //-----------------------------------------------------------------
4674 fxOverX0PipeTrks = new Float_t[ntracks];
4675 fxTimesRhoPipeTrks = new Float_t[ntracks];
4676 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4677 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4678 fxOverX0LayerTrks = new Float_t[ntracks*6];
4679 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4681 for(Int_t i=0; i<ntracks; i++) {
4682 fxOverX0PipeTrks[i] = -1.;
4683 fxTimesRhoPipeTrks[i] = -1.;
4685 for(Int_t j=0; j<ntracks*2; j++) {
4686 fxOverX0ShieldTrks[j] = -1.;
4687 fxTimesRhoShieldTrks[j] = -1.;
4689 for(Int_t k=0; k<ntracks*6; k++) {
4690 fxOverX0LayerTrks[k] = -1.;
4691 fxTimesRhoLayerTrks[k] = -1.;
4698 //------------------------------------------------------------------------
4699 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4700 //-----------------------------------------------------------------
4701 // Delete LUT for storing material for each prolonged track
4702 //-----------------------------------------------------------------
4703 if(fxOverX0PipeTrks) {
4704 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4706 if(fxOverX0ShieldTrks) {
4707 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4710 if(fxOverX0LayerTrks) {
4711 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4713 if(fxTimesRhoPipeTrks) {
4714 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4716 if(fxTimesRhoShieldTrks) {
4717 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4719 if(fxTimesRhoLayerTrks) {
4720 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4724 //------------------------------------------------------------------------
4725 void AliITStrackerMI::SetForceSkippingOfLayer() {
4726 //-----------------------------------------------------------------
4727 // Check if we are forced to skip layers
4728 // either we set to skip them in RecoParam
4729 // or they were off during data-taking
4730 //-----------------------------------------------------------------
4732 const AliEventInfo *eventInfo = GetEventInfo();
4734 for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
4735 fForceSkippingOfLayer[l] = 0;
4737 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
4741 AliITSReconstructor::GetRecoParam()->GetSkipSubdetsNotInTriggerCluster()) {
4742 AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
4744 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
4745 } else if(l==2 || l==3) {
4746 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1;
4748 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
4754 //------------------------------------------------------------------------
4755 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4756 Int_t ilayer,Int_t idet) const {
4757 //-----------------------------------------------------------------
4758 // This method is used to decide whether to allow a prolongation
4759 // without clusters, because we want to skip the layer.
4760 // In this case the return value is > 0:
4761 // return 1: the user requested to skip a layer
4762 // return 2: track outside z acceptance
4763 //-----------------------------------------------------------------
4765 if (ForceSkippingOfLayer(ilayer)) return 1;
4767 Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
4769 if (idet<0 && // out in z
4770 ilayer>innerLayCanSkip &&
4771 AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4772 // check if track will cross SPD outer layer
4773 Double_t phiAtSPD2,zAtSPD2;
4774 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4775 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4777 return 2; // always allow skipping, changed on 05.11.2009
4782 //------------------------------------------------------------------------
4783 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4784 Int_t ilayer,Int_t idet,
4785 Double_t dz,Double_t dy,
4786 Bool_t noClusters) const {
4787 //-----------------------------------------------------------------
4788 // This method is used to decide whether to allow a prolongation
4789 // without clusters, because there is a dead zone in the road.
4790 // In this case the return value is > 0:
4791 // return 1: dead zone at z=0,+-7cm in SPD
4792 // This method assumes that fSPDdetzcentre is ordered from -z to +z
4793 // return 2: all road is "bad" (dead or noisy) from the OCDB
4794 // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4795 // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4796 //-----------------------------------------------------------------
4798 // check dead zones at z=0,+-7cm in the SPD
4799 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4800 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4801 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4802 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4803 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4804 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4805 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4806 for (Int_t i=0; i<3; i++)
4807 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4808 AliDebug(2,Form("crack SPD %d track z %f %f %f %f\n",ilayer,track->GetZ(),dz,zmaxdead[i],zmindead[i]));
4809 if (GetSPDDeadZoneProbability(track->GetZ(),TMath::Sqrt(track->GetSigmaZ2()))>0.1) return 1;
4813 // check bad zones from OCDB
4814 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4816 if (idet<0) return 0;
4818 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4821 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4822 if (ilayer==0 || ilayer==1) { // ---------- SPD
4824 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4826 detSizeFactorX *= 2.;
4827 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4830 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4831 if (detType==2) segm->SetLayer(ilayer+1);
4832 Float_t detSizeX = detSizeFactorX*segm->Dx();
4833 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4835 // check if the road overlaps with bad chips
4837 if(!(LocalModuleCoord(ilayer,idet,track,xloc,zloc)))return 0;
4838 Float_t zlocmin = zloc-dz;
4839 Float_t zlocmax = zloc+dz;
4840 Float_t xlocmin = xloc-dy;
4841 Float_t xlocmax = xloc+dy;
4842 Int_t chipsInRoad[100];
4844 // check if road goes out of detector
4845 Bool_t touchNeighbourDet=kFALSE;
4846 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4847 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4848 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4849 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4850 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));
4852 // check if this detector is bad
4854 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4855 if(!touchNeighbourDet) {
4856 return 2; // all detectors in road are bad
4858 return 3; // at least one is bad
4862 if(zlocmin>zlocmax)return 0;
4863 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4864 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4865 if (!nChipsInRoad) return 0;
4867 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4868 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4869 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4870 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4871 if (det.IsChipBad(chipsInRoad[iCh])) {
4879 if(!touchNeighbourDet) {
4880 AliDebug(2,"all bad in road");
4881 return 2; // all chips in road are bad
4883 return 3; // at least a bad chip in road
4888 AliDebug(2,"at least a bad in road");
4889 return 3; // at least a bad chip in road
4893 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4894 || !noClusters) return 0;
4896 // There are no clusters in road: check if there is at least
4897 // a bad SPD pixel or SDD anode or SSD strips on both sides
4899 Int_t idetInITS=idet;
4900 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4902 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4903 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4906 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4910 //------------------------------------------------------------------------
4911 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4912 const AliITStrackMI *track,
4913 Float_t &xloc,Float_t &zloc) const {
4914 //-----------------------------------------------------------------
4915 // Gives position of track in local module ref. frame
4916 //-----------------------------------------------------------------
4921 if(idet<0) return kTRUE; // track out of z acceptance of layer
4923 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4925 Int_t lad = Int_t(idet/ndet) + 1;
4927 Int_t det = idet - (lad-1)*ndet + 1;
4929 Double_t xyzGlob[3],xyzLoc[3];
4931 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4932 // take into account the misalignment: xyz at real detector plane
4933 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4935 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4937 xloc = (Float_t)xyzLoc[0];
4938 zloc = (Float_t)xyzLoc[2];
4942 //------------------------------------------------------------------------
4943 //------------------------------------------------------------------------
4944 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer){
4946 // Method to be optimized further:
4947 // Aim: decide whether a track can be used for PlaneEff evaluation
4948 // the decision is taken based on the track quality at the layer under study
4949 // no information on the clusters on this layer has to be used
4950 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4951 // the cut is done on number of sigmas from the boundaries
4953 // Input: Actual track, layer [0,5] under study
4955 // Return: kTRUE if this is a good track
4957 // it will apply a pre-selection to obtain good quality tracks.
4958 // Here also you will have the possibility to put a control on the
4959 // impact point of the track on the basic block, in order to exclude border regions
4960 // this will be done by calling a proper method of the AliITSPlaneEff class.
4962 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4963 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4965 Int_t index[AliITSgeomTGeo::kNLayers];
4967 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4969 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4970 index[k]=clusters[k];
4974 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4975 AliITSlayer &layer=fgLayers[ilayer];
4976 Double_t r=layer.GetR();
4977 AliITStrackMI tmp(*track);
4979 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4980 Int_t nclout=0; Int_t nclin=0;
4981 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) { // count n. of cluster in outermost layers
4982 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4983 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4984 // if (tmp.GetClIndex(lay)>=0) nclout++;
4985 if(index[lay]>=0)nclout++;
4987 for(Int_t lay=ilayer-1; lay>=0;lay--) { // count n. of cluster in innermost layers
4988 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4989 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4990 if (index[lay]>=0) nclin++;
4992 Int_t ncl=nclout+nclin;
4993 Bool_t nextout = kFALSE;
4994 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4995 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4996 Bool_t nextin = kFALSE;
4997 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4998 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4999 // maximum number of missing clusters allowed in outermost layers
5000 if(nclout<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersOutPlaneEff())
5002 // maximum number of missing clusters allowed (both in innermost and in outermost layers)
5003 if(ncl<AliITSgeomTGeo::kNLayers-1-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
5005 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
5006 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
5007 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
5008 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
5012 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
5013 Int_t idet=layer.FindDetectorIndex(phi,z);
5014 if(idet<0) { AliInfo(Form("cannot find detector"));
5017 // here check if it has good Chi Square.
5019 //propagate to the intersection with the detector plane
5020 const AliITSdetector &det=layer.GetDetector(idet);
5021 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
5025 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
5026 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5027 if(key>fPlaneEff->Nblock()) return kFALSE;
5028 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
5029 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
5031 // DEFINITION OF SEARCH ROAD FOR accepting a track
5033 Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXFromBoundaryPlaneEff();
5034 Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZFromBoundaryPlaneEff();
5035 Double_t distx=AliITSReconstructor::GetRecoParam()->GetDistXFromBoundaryPlaneEff();
5036 Double_t distz=AliITSReconstructor::GetRecoParam()->GetDistZFromBoundaryPlaneEff();
5037 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()) + distx;
5038 // those are precisions in the tracking reference system
5039 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()) + distz;
5040 // Use it also for the module reference system, as it is done for RecPoints
5042 if(AliITSReconstructor::GetRecoParam()->GetSwitchOnMaxDistNSigFrmBndPlaneEff()){
5043 if(nsigx*TMath::Sqrt(tmp.GetSigmaY2())<=distx) dx -= nsigx*TMath::Sqrt(tmp.GetSigmaY2());
5046 if(nsigz*TMath::Sqrt(tmp.GetSigmaZ2())<=distz) dz -= nsigz*TMath::Sqrt(tmp.GetSigmaZ2());
5050 // exclude tracks at boundary between detectors
5051 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
5052 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
5053 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
5054 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
5055 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
5056 if ( (locx-dx < blockXmn+boundaryWidth) ||
5057 (locx+dx > blockXmx-boundaryWidth) ||
5058 (locz-dz < blockZmn+boundaryWidth) ||
5059 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
5062 const AliESDEvent *myesd = ((AliESDtrack*)tmp.GetESDtrack())->GetESDEvent();
5064 if (CorrectForPipeMaterial(&tmp,"inward")) {
5065 const AliESDVertex* vtx = myesd->GetVertex();
5066 if(!vtx) return kFALSE;
5067 Double_t ddz[2],cov[3];
5069 if(!tmp.PropagateToDCA(vtx,AliTracker::GetBz(),maxD,ddz,cov)) return kFALSE;
5070 if(TMath::Abs(ddz[0])>=AliITSReconstructor::GetRecoParam()->GetDCACutPlaneEff()) return kFALSE;
5072 Double_t covar[6]; vtx->GetCovMatrix(covar);
5073 Double_t p[2]={tmp.GetParameter()[0]-ddz[0],tmp.GetParameter()[1]-ddz[1]};
5074 Double_t c[3]={covar[2],0.,covar[5]};
5075 Double_t chi2= ((AliESDtrack*)tmp.GetESDtrack())->GetPredictedChi2(p,c);
5076 if (chi2>AliITSReconstructor::GetRecoParam()->GetVertexChi2CutPlaneEff()) return kFALSE; // Use this to cut on chi^2
5078 } else return kFALSE;
5084 //------------------------------------------------------------------------
5085 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
5087 // This Method has to be optimized! For the time-being it uses the same criteria
5088 // as those used in the search of extra clusters for overlapping modules.
5090 // Method Purpose: estabilish whether a track has produced a recpoint or not
5091 // in the layer under study (For Plane efficiency)
5093 // inputs: AliITStrackMI* track (pointer to a usable track)
5095 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
5096 // traversed by this very track. In details:
5097 // - if a cluster can be associated to the track then call
5098 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
5099 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
5102 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
5103 AliITSlayer &layer=fgLayers[ilayer];
5104 Double_t r=layer.GetR();
5105 AliITStrackMI tmp(*track);
5109 if (!tmp.GetPhiZat(r,phi,z)) return;
5110 Int_t idet=layer.FindDetectorIndex(phi,z);
5112 if(idet<0) { AliInfo(Form("cannot find detector"));
5116 //propagate to the intersection with the detector plane
5117 const AliITSdetector &det=layer.GetDetector(idet);
5118 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
5122 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
5124 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
5125 TMath::Sqrt(tmp.GetSigmaZ2() +
5126 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5127 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5128 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
5129 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
5130 TMath::Sqrt(tmp.GetSigmaY2() +
5131 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5132 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5133 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
5135 // road in global (rphi,z) [i.e. in tracking ref. system]
5136 Double_t zmin = tmp.GetZ() - dz;
5137 Double_t zmax = tmp.GetZ() + dz;
5138 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
5139 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
5141 // select clusters in road
5142 layer.SelectClusters(zmin,zmax,ymin,ymax);
5144 // Define criteria for track-cluster association
5145 Double_t msz = tmp.GetSigmaZ2() +
5146 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5147 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
5148 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
5149 Double_t msy = tmp.GetSigmaY2() +
5150 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5151 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
5152 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
5153 if (tmp.GetConstrain()) {
5154 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
5155 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
5157 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
5158 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
5161 if(AliITSReconstructor::GetRecoParam()->GetSwitchOffStdSearchClusPlaneEff()){
5162 Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXSearchClusterPlaneEff();
5163 Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZSearchClusterPlaneEff();
5164 Double_t distx=AliITSReconstructor::GetRecoParam()->GetDistXSearchClusterPlaneEff();
5165 Double_t distz=AliITSReconstructor::GetRecoParam()->GetDistZSearchClusterPlaneEff();
5166 msy = nsigx*TMath::Sqrt(tmp.GetSigmaY2()) + distx;
5167 msz = nsigz*TMath::Sqrt(tmp.GetSigmaZ2()) + distz;
5169 if(AliITSReconstructor::GetRecoParam()->GetSwitchOnMaxDistNSigSrhClusPlaneEff()){
5170 if(nsigx*TMath::Sqrt(tmp.GetSigmaY2())<=distx) msy -= nsigx*TMath::Sqrt(tmp.GetSigmaY2());
5173 if(nsigz*TMath::Sqrt(tmp.GetSigmaZ2())<=distz) msz -= nsigz*TMath::Sqrt(tmp.GetSigmaZ2());
5182 if(msz==0 || msy==0){AliWarning("UseTrackForPlaneEff: null search frame"); return;}
5184 msz = 1./msz; // 1/RoadZ^2
5185 msy = 1./msy; // 1/RoadY^2
5187 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
5189 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
5190 //Double_t tolerance=0.2;
5191 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
5192 idetc = cl->GetDetectorIndex();
5193 if(idet!=idetc) continue;
5194 //Int_t ilay = cl->GetLayer();
5196 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
5197 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
5199 Double_t chi2=tmp.GetPredictedChi2(cl);
5200 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
5204 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
5206 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
5207 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
5208 if(key>fPlaneEff->Nblock()) return;
5209 Bool_t found=kFALSE;
5212 while ((cl=layer.GetNextCluster(clidx))!=0) {
5213 idetc = cl->GetDetectorIndex();
5214 if(idet!=idetc) continue;
5215 // here real control to see whether the cluster can be associated to the track.
5216 // cluster not associated to track
5217 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
5218 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
5219 // calculate track-clusters chi2
5220 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
5221 // in particular, the error associated to the cluster
5222 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
5224 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
5226 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
5227 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
5228 // track->SetExtraModule(ilayer,idetExtra);
5230 if(!fPlaneEff->UpDatePlaneEff(found,key))
5231 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
5233 // this for FO efficiency studies (only for SPD) //
5234 UInt_t keyFO=999999;
5235 Bool_t foundFO=kFALSE;
5236 if(ilayer<2){ //ONLY SPD layers for FastOr studies
5237 TBits mapFO = fkDetTypeRec->GetFastOrFiredMap();
5238 Int_t phase = (fEsd->GetBunchCrossNumber())%4;
5239 if(!fSPDChipIntPlaneEff[key]){
5240 AliITSPlaneEffSPD spd;
5241 keyFO = spd.SwitchChipKeyNumbering(key);
5242 if(mapFO.TestBitNumber(keyFO))foundFO=kTRUE;
5243 keyFO = key + (AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip)*(phase+1);
5244 if(keyFO<AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip) {
5245 AliWarning(Form("UseTrackForPlaneEff: too small keyF0 (= %d), setting it to 999999",keyFO));
5248 if(!fPlaneEff->UpDatePlaneEff(foundFO,keyFO))
5249 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for FastOR for key=%d",keyFO));
5255 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
5256 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
5257 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
5258 Int_t cltype[2]={-999,-999};
5261 Float_t angleModTrack[3]={99999.,99999.,99999.}; // angles (phi, z and "absolute angle") between the track and the mormal to the module (see below)
5265 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
5266 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
5269 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
5270 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
5271 cltype[0]=layer.GetCluster(ci)->GetNy();
5272 cltype[1]=layer.GetCluster(ci)->GetNz();
5274 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
5275 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
5276 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
5277 // It is computed properly by calling the method
5278 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
5280 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
5281 //if (tmp.PropagateTo(x,0.,0.)) {
5282 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
5283 AliCluster c(*layer.GetCluster(ci));
5284 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
5285 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
5286 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
5287 clu[2]=TMath::Sqrt(c.GetSigmaY2());
5288 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
5291 // Compute the angles between the track and the module
5292 // compute the angle "in phi direction", i.e. the angle in the transverse plane
5293 // between the normal to the module and the projection (in the transverse plane) of the
5295 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
5296 Float_t tgl = tmp.GetTgl();
5297 Float_t phitr = tmp.GetSnp();
5298 phitr = TMath::ASin(phitr);
5299 Int_t volId = AliGeomManager::LayerToVolUIDSafe(ilayer+1 ,idet );
5301 Double_t tra[3]; AliGeomManager::GetOrigTranslation(volId,tra);
5302 Double_t rot[9]; AliGeomManager::GetOrigRotation(volId,rot);
5304 alpha = tmp.GetAlpha();
5305 Double_t phiglob = alpha+phitr;
5307 p[0] = TMath::Cos(phiglob);
5308 p[1] = TMath::Sin(phiglob);
5310 TVector3 pvec(p[0],p[1],p[2]);
5311 TVector3 normvec(rot[1],rot[4],rot[7]);
5312 Double_t angle = pvec.Angle(normvec);
5314 if(angle>0.5*TMath::Pi()) angle = (TMath::Pi()-angle);
5315 angle *= 180./TMath::Pi();
5318 TVector3 pt(p[0],p[1],0);
5319 TVector3 normt(rot[1],rot[4],0);
5320 Double_t anglet = pt.Angle(normt);
5322 Double_t phiPt = TMath::ATan2(p[1],p[0]);
5323 if(phiPt<0)phiPt+=2.*TMath::Pi();
5324 Double_t phiNorm = TMath::ATan2(rot[4],rot[1]);
5325 if(phiNorm<0) phiNorm+=2.*TMath::Pi();
5326 if(anglet>0.5*TMath::Pi()) anglet = (TMath::Pi()-anglet);
5327 if(phiNorm>phiPt) anglet*=-1.;// pt-->normt clockwise: anglet>0
5328 if((phiNorm-phiPt)>TMath::Pi()) anglet*=-1.;
5329 anglet *= 180./TMath::Pi();
5331 angleModTrack[2]=(Float_t) angle;
5332 angleModTrack[0]=(Float_t) anglet;
5333 // now the "angle in z" (much easier, i.e. the angle between the z axis and the track momentum + 90)
5334 angleModTrack[1]=TMath::ACos(tgl/TMath::Sqrt(tgl*tgl+1.));
5335 angleModTrack[1]-=TMath::Pi()/2.; // range of angle is -pi/2 , pi/2
5336 angleModTrack[1]*=180./TMath::Pi(); // in degree
5338 fPlaneEff->FillHistos(key,found,tr,clu,cltype,angleModTrack);
5340 // For FO efficiency studies of SPD
5341 if(ilayer<2 && !fSPDChipIntPlaneEff[key]) fPlaneEff->FillHistos(keyFO,foundFO,tr,clu,cltype,angleModTrack);
5343 if(ilayer<2) fSPDChipIntPlaneEff[key]=kTRUE;
5347 Int_t AliITStrackerMI::FindClusterOfTrack(int label, int lr, int* store) const //RS
5349 // find the MC cluster for the label
5350 return fgLayers[lr].FindClusterForLabel(label,store);
5354 Int_t AliITStrackerMI::GetPattern(const AliITStrackMI* track, char* patt)
5356 // creates pattarn of hits marking fake/corrects by f/c. Used for debugging (RS)
5357 strncpy(patt,"......",6);
5359 if (track->GetESDtrack()) tpcLabel = track->GetESDtrack()->GetTPCLabel();
5362 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
5363 Int_t cindex = track->GetClusterIndex(i);
5364 Int_t l=(cindex & 0xf0000000) >> 28;
5365 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
5367 for (Int_t ind=0;ind<3;ind++) if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
5368 patt[l] = isWrong ? 'f':'c';
5374 //------------------------------------------------------------------------
5375 Int_t AliITStrackerMI::AliITSlayer::FindClusterForLabel(Int_t label, Int_t *store) const
5377 //--------------------------------------------------------------------
5380 for (int ic=0;ic<fN;ic++) {
5381 const AliITSRecPoint *cl = GetCluster(ic);
5382 for (int i=0;i<3;i++) if (cl->GetLabel(i)==label) {
5384 if (store) store[nfound] = ic;