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>
38 #include "AliGeomManager.h"
39 #include "AliITSPlaneEff.h"
40 #include "AliTrackPointArray.h"
41 #include "AliESDEvent.h"
42 #include "AliESDtrack.h"
44 #include "AliITSChannelStatus.h"
45 #include "AliITSDetTypeRec.h"
46 #include "AliITSRecPoint.h"
47 #include "AliITSRecPointContainer.h"
48 #include "AliITSgeomTGeo.h"
49 #include "AliITSReconstructor.h"
50 #include "AliITSClusterParam.h"
51 #include "AliITSsegmentation.h"
52 #include "AliITSCalibration.h"
53 #include "AliITSPlaneEffSPD.h"
54 #include "AliITSPlaneEffSDD.h"
55 #include "AliITSPlaneEffSSD.h"
56 #include "AliITSV0Finder.h"
57 #include "AliITStrackerMI.h"
58 #include "AliMathBase.h"
60 ClassImp(AliITStrackerMI)
62 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
64 AliITStrackerMI::AliITStrackerMI():AliTracker(),
74 fLastLayerToTrackTo(0),
77 fTrackingPhase("Default"),
83 fxTimesRhoPipeTrks(0),
84 fxOverX0ShieldTrks(0),
85 fxTimesRhoShieldTrks(0),
87 fxTimesRhoLayerTrks(0),
94 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
95 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
96 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
99 //------------------------------------------------------------------------
100 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
101 fI(AliITSgeomTGeo::GetNLayers()),
110 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
113 fTrackingPhase("Default"),
119 fxTimesRhoPipeTrks(0),
120 fxOverX0ShieldTrks(0),
121 fxTimesRhoShieldTrks(0),
122 fxOverX0LayerTrks(0),
123 fxTimesRhoLayerTrks(0),
125 fITSChannelStatus(0),
128 //--------------------------------------------------------------------
129 //This is the AliITStrackerMI constructor
130 //--------------------------------------------------------------------
132 AliWarning("\"geom\" is actually a dummy argument !");
135 fOriginal.SetOwner();
139 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
140 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
141 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
143 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
144 AliITSgeomTGeo::GetTranslation(i,1,1,xyz);
145 Double_t poff=TMath::ATan2(y,x);
148 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
149 Double_t r=TMath::Sqrt(x*x + y*y);
151 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
152 r += TMath::Sqrt(x*x + y*y);
153 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
154 r += TMath::Sqrt(x*x + y*y);
155 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
156 r += TMath::Sqrt(x*x + y*y);
159 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
161 for (Int_t j=1; j<nlad+1; j++) {
162 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
163 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
164 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
166 Double_t txyz[3]={0.};
167 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
168 m.LocalToMaster(txyz,xyz);
169 r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
170 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
172 if (phi<0) phi+=TMath::TwoPi();
173 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
175 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
176 new(&det) AliITSdetector(r,phi);
177 // compute the real radius (with misalignment)
178 TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
180 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
181 mmisal.LocalToMaster(txyz,xyz);
182 Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
183 det.SetRmisal(rmisal);
185 } // end loop on detectors
186 } // end loop on ladders
187 fForceSkippingOfLayer[i-1] = 0;
188 } // end loop on layers
191 fI=AliITSgeomTGeo::GetNLayers();
194 fConstraint[0]=1; fConstraint[1]=0;
196 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
197 AliITSReconstructor::GetRecoParam()->GetYVdef(),
198 AliITSReconstructor::GetRecoParam()->GetZVdef()};
199 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
200 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
201 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
202 SetVertex(xyzVtx,ersVtx);
204 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
205 for (Int_t i=0;i<100000;i++){
206 fBestTrackIndex[i]=0;
209 // store positions of centre of SPD modules (in z)
210 // The convetion is that fSPDdetzcentre is ordered from -z to +z
212 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
213 if (tr[2]<0) { // old geom (up to v5asymmPPR)
214 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
215 fSPDdetzcentre[0] = tr[2];
216 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
217 fSPDdetzcentre[1] = tr[2];
218 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
219 fSPDdetzcentre[2] = tr[2];
220 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
221 fSPDdetzcentre[3] = tr[2];
222 } else { // new geom (from v11Hybrid)
223 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
224 fSPDdetzcentre[0] = tr[2];
225 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
226 fSPDdetzcentre[1] = tr[2];
227 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
228 fSPDdetzcentre[2] = tr[2];
229 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
230 fSPDdetzcentre[3] = tr[2];
233 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
234 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
235 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
239 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
240 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
242 if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0)
243 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
245 // only for plane efficiency evaluation
246 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
247 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
248 Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
249 if(!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)==1)
250 AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
251 if (iplane<2) fPlaneEff = new AliITSPlaneEffSPD();
252 else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
253 else fPlaneEff = new AliITSPlaneEffSSD();
254 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
255 if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
256 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
259 //------------------------------------------------------------------------
260 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
262 fBestTrack(tracker.fBestTrack),
263 fTrackToFollow(tracker.fTrackToFollow),
264 fTrackHypothesys(tracker.fTrackHypothesys),
265 fBestHypothesys(tracker.fBestHypothesys),
266 fOriginal(tracker.fOriginal),
267 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
268 fPass(tracker.fPass),
269 fAfterV0(tracker.fAfterV0),
270 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
271 fCoefficients(tracker.fCoefficients),
273 fTrackingPhase(tracker.fTrackingPhase),
274 fUseTGeo(tracker.fUseTGeo),
275 fNtracks(tracker.fNtracks),
276 fxOverX0Pipe(tracker.fxOverX0Pipe),
277 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
279 fxTimesRhoPipeTrks(0),
280 fxOverX0ShieldTrks(0),
281 fxTimesRhoShieldTrks(0),
282 fxOverX0LayerTrks(0),
283 fxTimesRhoLayerTrks(0),
284 fDebugStreamer(tracker.fDebugStreamer),
285 fITSChannelStatus(tracker.fITSChannelStatus),
286 fkDetTypeRec(tracker.fkDetTypeRec),
287 fPlaneEff(tracker.fPlaneEff) {
289 fOriginal.SetOwner();
292 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
295 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
296 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
299 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
300 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
303 //------------------------------------------------------------------------
304 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
305 //Assignment operator
306 this->~AliITStrackerMI();
307 new(this) AliITStrackerMI(tracker);
310 //------------------------------------------------------------------------
311 AliITStrackerMI::~AliITStrackerMI()
316 if (fCoefficients) delete [] fCoefficients;
317 DeleteTrksMaterialLUT();
318 if (fDebugStreamer) {
319 //fDebugStreamer->Close();
320 delete fDebugStreamer;
322 if(fITSChannelStatus) delete fITSChannelStatus;
323 if(fPlaneEff) delete fPlaneEff;
325 //------------------------------------------------------------------------
326 void AliITStrackerMI::ReadBadFromDetTypeRec() {
327 //--------------------------------------------------------------------
328 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
330 //--------------------------------------------------------------------
332 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
334 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
336 if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
339 if(fITSChannelStatus) delete fITSChannelStatus;
340 fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
342 // ITS detectors and chips
343 Int_t i=0,j=0,k=0,ndet=0;
344 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
345 Int_t nBadDetsPerLayer=0;
346 ndet=AliITSgeomTGeo::GetNDetectors(i);
347 for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
348 for (k=1; k<ndet+1; k++) {
349 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
350 det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fkDetTypeRec);
351 if(det.IsBad()) {nBadDetsPerLayer++;}
352 } // end loop on detectors
353 } // end loop on ladders
354 AliInfo(Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
355 } // end loop on layers
359 //------------------------------------------------------------------------
360 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
361 //--------------------------------------------------------------------
362 //This function loads ITS clusters
363 //--------------------------------------------------------------------
365 TClonesArray *clusters = NULL;
366 AliITSRecPointContainer* rpcont=AliITSRecPointContainer::Instance();
367 clusters=rpcont->FetchClusters(0,cTree);
368 if(!clusters) return 1;
370 if(!(rpcont->IsSPDActive() || rpcont->IsSDDActive() || rpcont->IsSSDActive())){
371 AliError("ITS is not in a known running configuration: SPD, SDD and SSD are not active");
374 Int_t i=0,j=0,ndet=0;
376 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
377 ndet=fgLayers[i].GetNdetectors();
378 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
379 for (; j<jmax; j++) {
380 // if (!cTree->GetEvent(j)) continue;
381 clusters = rpcont->UncheckedGetClusters(j);
382 if(!clusters)continue;
383 Int_t ncl=clusters->GetEntriesFast();
384 SignDeltas(clusters,GetZ());
387 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
388 detector=c->GetDetectorIndex();
390 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
392 Int_t retval = fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
394 AliWarning(Form("Too many clusters on layer %d!",i));
399 // add dead zone "virtual" cluster in SPD, if there is a cluster within
400 // zwindow cm from the dead zone
401 // This method assumes that fSPDdetzcentre is ordered from -z to +z
402 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
403 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
404 Int_t lab[4] = {0,0,0,detector};
405 Int_t info[3] = {0,0,i};
406 Float_t q = 0.; // this identifies virtual clusters
407 Float_t hit[6] = {xdead,
409 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
410 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
413 Bool_t local = kTRUE;
414 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
415 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
416 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
417 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
418 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
419 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
420 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
421 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
422 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
423 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
424 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
425 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
426 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
427 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
428 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
429 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
430 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
431 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
432 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
434 } // "virtual" clusters in SPD
438 fgLayers[i].ResetRoad(); //road defined by the cluster density
439 fgLayers[i].SortClusters();
442 // check whether we have to skip some layers
443 SetForceSkippingOfLayer();
447 //------------------------------------------------------------------------
448 void AliITStrackerMI::UnloadClusters() {
449 //--------------------------------------------------------------------
450 //This function unloads ITS clusters
451 //--------------------------------------------------------------------
452 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
454 //------------------------------------------------------------------------
455 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
456 //--------------------------------------------------------------------
457 // Publishes all pointers to clusters known to the tracker into the
458 // passed object array.
459 // The ownership is not transfered - the caller is not expected to delete
461 //--------------------------------------------------------------------
463 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
464 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
465 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
472 //------------------------------------------------------------------------
473 Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
474 //--------------------------------------------------------------------
475 // Correction for the material between the TPC and the ITS
476 //--------------------------------------------------------------------
477 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
478 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
479 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
480 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
481 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
482 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
483 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
484 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
486 printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
492 //------------------------------------------------------------------------
493 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
494 //--------------------------------------------------------------------
495 // This functions reconstructs ITS tracks
496 // The clusters must be already loaded !
497 //--------------------------------------------------------------------
499 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
501 fTrackingPhase="Clusters2Tracks";
503 TObjArray itsTracks(15000);
505 fEsd = event; // store pointer to the esd
507 // temporary (for cosmics)
508 if(event->GetVertex()) {
509 TString title = event->GetVertex()->GetTitle();
510 if(title.Contains("cosmics")) {
511 Double_t xyz[3]={GetX(),GetY(),GetZ()};
512 Double_t exyz[3]={0.1,0.1,0.1};
518 {/* Read ESD tracks */
519 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
520 Int_t nentr=event->GetNumberOfTracks();
522 // Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
524 AliESDtrack *esd=event->GetTrack(nentr);
525 // ---- for debugging:
526 //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); }
528 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
529 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
530 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
531 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
532 AliITStrackMI *t = new AliITStrackMI(*esd);
533 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
534 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
537 // look at the ESD mass hypothesys !
538 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
540 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
542 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
543 //track - can be V0 according to TPC
545 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
549 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
553 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
557 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
562 t->SetReconstructed(kFALSE);
563 itsTracks.AddLast(t);
564 fOriginal.AddLast(t);
566 } /* End Read ESD tracks */
570 Int_t nentr=itsTracks.GetEntriesFast();
571 fTrackHypothesys.Expand(nentr);
572 fBestHypothesys.Expand(nentr);
573 MakeCoefficients(nentr);
574 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
576 // THE TWO TRACKING PASSES
577 for (fPass=0; fPass<2; fPass++) {
578 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
579 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
580 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
581 if (t==0) continue; //this track has been already tracked
582 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
583 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
584 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
585 if (fConstraint[fPass]) {
586 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
587 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
590 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
591 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
593 ResetTrackToFollow(*t);
596 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
599 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
601 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
602 if (!besttrack) continue;
603 besttrack->SetLabel(tpcLabel);
604 // besttrack->CookdEdx();
606 besttrack->SetFakeRatio(1.);
607 CookLabel(besttrack,0.); //For comparison only
608 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
610 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
612 t->SetReconstructed(kTRUE);
614 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
616 GetBestHypothesysMIP(itsTracks);
617 } // end loop on the two tracking passes
619 if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
620 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
625 Int_t entries = fTrackHypothesys.GetEntriesFast();
626 for (Int_t ientry=0; ientry<entries; ientry++) {
627 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
628 if (array) array->Delete();
629 delete fTrackHypothesys.RemoveAt(ientry);
632 fTrackHypothesys.Delete();
633 entries = fBestHypothesys.GetEntriesFast();
634 for (Int_t ientry=0; ientry<entries; ientry++) {
635 TObjArray * array =(TObjArray*)fBestHypothesys.UncheckedAt(ientry);
636 if (array) array->Delete();
637 delete fBestHypothesys.RemoveAt(ientry);
639 fBestHypothesys.Delete();
641 delete [] fCoefficients;
643 DeleteTrksMaterialLUT();
645 AliInfo(Form("Number of prolonged tracks: %d out of %d ESD tracks",ntrk,noesd));
647 fTrackingPhase="Default";
651 //------------------------------------------------------------------------
652 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
653 //--------------------------------------------------------------------
654 // This functions propagates reconstructed ITS tracks back
655 // The clusters must be loaded !
656 //--------------------------------------------------------------------
657 fTrackingPhase="PropagateBack";
658 Int_t nentr=event->GetNumberOfTracks();
659 // Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
662 for (Int_t i=0; i<nentr; i++) {
663 AliESDtrack *esd=event->GetTrack(i);
665 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
666 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
668 AliITStrackMI *t = new AliITStrackMI(*esd);
670 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
672 ResetTrackToFollow(*t);
675 // propagate to vertex [SR, GSI 17.02.2003]
676 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
677 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
678 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
679 fTrackToFollow.StartTimeIntegral();
680 // from vertex to outside pipe
681 CorrectForPipeMaterial(&fTrackToFollow,"outward");
683 // Start time integral and add distance from current position to vertex
684 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
685 fTrackToFollow.GetXYZ(xyzTrk);
687 for (Int_t icoord=0; icoord<3; icoord++) {
688 Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
691 fTrackToFollow.StartTimeIntegral();
692 fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
694 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
695 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
696 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
700 fTrackToFollow.SetLabel(t->GetLabel());
701 //fTrackToFollow.CookdEdx();
702 CookLabel(&fTrackToFollow,0.); //For comparison only
703 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
704 //UseClusters(&fTrackToFollow);
710 AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
712 fTrackingPhase="Default";
716 //------------------------------------------------------------------------
717 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
718 //--------------------------------------------------------------------
719 // This functions refits ITS tracks using the
720 // "inward propagated" TPC tracks
721 // The clusters must be loaded !
722 //--------------------------------------------------------------------
723 fTrackingPhase="RefitInward";
725 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
727 Bool_t doExtra=AliITSReconstructor::GetRecoParam()->GetSearchForExtraClusters();
728 if(!doExtra) AliDebug(2,"Do not search for extra clusters");
730 Int_t nentr=event->GetNumberOfTracks();
731 // Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
734 for (Int_t i=0; i<nentr; i++) {
735 AliESDtrack *esd=event->GetTrack(i);
737 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
738 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
739 if (esd->GetStatus()&AliESDtrack::kTPCout)
740 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
742 AliITStrackMI *t = new AliITStrackMI(*esd);
744 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
745 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
750 ResetTrackToFollow(*t);
751 fTrackToFollow.ResetClusters();
753 // ITS standalone tracks
754 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) {
755 fTrackToFollow.ResetCovariance(10.);
756 // protection for loopers that can have parameters screwed up
757 if(TMath::Abs(fTrackToFollow.GetY())>1000. ||
758 TMath::Abs(fTrackToFollow.GetZ())>1000.) {
765 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
766 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
768 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
769 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,doExtra,pe)) {
770 AliDebug(2," refit OK");
771 fTrackToFollow.SetLabel(t->GetLabel());
772 // fTrackToFollow.CookdEdx();
773 CookdEdx(&fTrackToFollow);
775 CookLabel(&fTrackToFollow,0.0); //For comparison only
778 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
779 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
780 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
781 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
782 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
783 Double_t r[3]={0.,0.,0.};
785 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
792 AliInfo(Form("Number of refitted tracks: %d out of %d ESD tracks",ntrk,nentr));
794 fTrackingPhase="Default";
798 //------------------------------------------------------------------------
799 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
800 //--------------------------------------------------------------------
801 // Return pointer to a given cluster
802 //--------------------------------------------------------------------
803 Int_t l=(index & 0xf0000000) >> 28;
804 Int_t c=(index & 0x0fffffff) >> 00;
805 return fgLayers[l].GetCluster(c);
807 //------------------------------------------------------------------------
808 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
809 //--------------------------------------------------------------------
810 // Get track space point with index i
811 //--------------------------------------------------------------------
813 Int_t l=(index & 0xf0000000) >> 28;
814 Int_t c=(index & 0x0fffffff) >> 00;
815 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
816 Int_t idet = cl->GetDetectorIndex();
820 cl->GetGlobalXYZ(xyz);
821 cl->GetGlobalCov(cov);
823 p.SetCharge(cl->GetQ());
824 p.SetDriftTime(cl->GetDriftTime());
825 p.SetChargeRatio(cl->GetChargeRatio());
826 p.SetClusterType(cl->GetClusterType());
827 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
830 iLayer = AliGeomManager::kSPD1;
833 iLayer = AliGeomManager::kSPD2;
836 iLayer = AliGeomManager::kSDD1;
839 iLayer = AliGeomManager::kSDD2;
842 iLayer = AliGeomManager::kSSD1;
845 iLayer = AliGeomManager::kSSD2;
848 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
851 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
852 p.SetVolumeID((UShort_t)volid);
855 //------------------------------------------------------------------------
856 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
857 AliTrackPoint& p, const AliESDtrack *t) {
858 //--------------------------------------------------------------------
859 // Get track space point with index i
860 // (assign error estimated during the tracking)
861 //--------------------------------------------------------------------
863 Int_t l=(index & 0xf0000000) >> 28;
864 Int_t c=(index & 0x0fffffff) >> 00;
865 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
866 Int_t idet = cl->GetDetectorIndex();
868 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
870 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
872 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
873 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
874 Double_t alpha = t->GetAlpha();
875 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
876 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe+cl->GetX(),GetBz()));
877 phi += alpha-det.GetPhi();
878 Float_t tgphi = TMath::Tan(phi);
880 Float_t tgl = t->GetTgl(); // tgl about const along track
881 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
883 Float_t errtrky,errtrkz,covyz;
884 Bool_t addMisalErr=kFALSE;
885 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
889 cl->GetGlobalXYZ(xyz);
890 // cl->GetGlobalCov(cov);
891 Float_t pos[3] = {0.,0.,0.};
892 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
893 tmpcl.GetGlobalCov(cov);
896 p.SetCharge(cl->GetQ());
897 p.SetDriftTime(cl->GetDriftTime());
898 p.SetChargeRatio(cl->GetChargeRatio());
899 p.SetClusterType(cl->GetClusterType());
901 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
904 iLayer = AliGeomManager::kSPD1;
907 iLayer = AliGeomManager::kSPD2;
910 iLayer = AliGeomManager::kSDD1;
913 iLayer = AliGeomManager::kSDD2;
916 iLayer = AliGeomManager::kSSD1;
919 iLayer = AliGeomManager::kSSD2;
922 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
925 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
927 p.SetVolumeID((UShort_t)volid);
930 //------------------------------------------------------------------------
931 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
933 //--------------------------------------------------------------------
934 // Follow prolongation tree
935 //--------------------------------------------------------------------
937 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
938 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
941 AliESDtrack * esd = otrack->GetESDtrack();
942 if (esd->GetV0Index(0)>0) {
943 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
944 // mapping of ESD track is different as ITS track in Containers
945 // Need something more stable
946 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
947 for (Int_t i=0;i<3;i++){
948 Int_t index = esd->GetV0Index(i);
950 AliESDv0 * vertex = fEsd->GetV0(index);
951 if (vertex->GetStatus()<0) continue; // rejected V0
953 if (esd->GetSign()>0) {
954 vertex->SetIndex(0,esdindex);
956 vertex->SetIndex(1,esdindex);
960 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
962 bestarray = new TObjArray(5);
963 bestarray->SetOwner();
964 fBestHypothesys.AddAt(bestarray,esdindex);
968 //setup tree of the prolongations
970 static AliITStrackMI tracks[7][100];
971 AliITStrackMI *currenttrack;
972 static AliITStrackMI currenttrack1;
973 static AliITStrackMI currenttrack2;
974 static AliITStrackMI backuptrack;
976 Int_t nindexes[7][100];
977 Float_t normalizedchi2[100];
978 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
979 otrack->SetNSkipped(0);
980 new (&(tracks[6][0])) AliITStrackMI(*otrack);
982 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
983 Int_t modstatus = 1; // found
987 // follow prolongations
988 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
989 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
992 AliITSlayer &layer=fgLayers[ilayer];
993 Double_t r = layer.GetR();
999 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
1001 if (ntracks[ilayer]>=100) break;
1002 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
1003 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
1004 if (ntracks[ilayer]>15+ilayer){
1005 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
1006 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
1009 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
1011 // material between SSD and SDD, SDD and SPD
1013 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
1015 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
1019 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
1020 Int_t idet=layer.FindDetectorIndex(phi,z);
1022 Double_t trackGlobXYZ1[3];
1023 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1025 // Get the budget to the primary vertex for the current track being prolonged
1026 Double_t budgetToPrimVertex = GetEffectiveThickness();
1028 // check if we allow a prolongation without point
1029 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1031 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1032 // propagate to the layer radius
1033 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1034 if(!vtrack->Propagate(xToGo)) continue;
1035 // apply correction for material of the current layer
1036 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1037 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1038 vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1039 vtrack->SetClIndex(ilayer,-1);
1040 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1041 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1042 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1044 if(constrain && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1049 // track outside layer acceptance in z
1050 if (idet<0) continue;
1052 //propagate to the intersection with the detector plane
1053 const AliITSdetector &det=layer.GetDetector(idet);
1054 new(¤ttrack2) AliITStrackMI(currenttrack1);
1055 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1056 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1057 currenttrack1.SetDetectorIndex(idet);
1058 currenttrack2.SetDetectorIndex(idet);
1059 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1062 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1064 // road in global (rphi,z) [i.e. in tracking ref. system]
1065 Double_t zmin,zmax,ymin,ymax;
1066 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1068 // select clusters in road
1069 layer.SelectClusters(zmin,zmax,ymin,ymax);
1070 //********************
1072 // Define criteria for track-cluster association
1073 Double_t msz = currenttrack1.GetSigmaZ2() +
1074 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1075 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1076 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1077 Double_t msy = currenttrack1.GetSigmaY2() +
1078 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1079 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1080 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1082 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1083 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1085 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1086 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1088 msz = 1./msz; // 1/RoadZ^2
1089 msy = 1./msy; // 1/RoadY^2
1093 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1095 const AliITSRecPoint *cl=0;
1097 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1098 Bool_t deadzoneSPD=kFALSE;
1099 currenttrack = ¤ttrack1;
1101 // check if the road contains a dead zone
1102 Bool_t noClusters = kFALSE;
1103 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1104 if (noClusters) AliDebug(2,"no clusters in road");
1105 Double_t dz=0.5*(zmax-zmin);
1106 Double_t dy=0.5*(ymax-ymin);
1107 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1108 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1109 // create a prolongation without clusters (check also if there are no clusters in the road)
1112 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1113 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1114 updatetrack->SetClIndex(ilayer,-1);
1116 modstatus = 5; // no cls in road
1117 } else if (dead==1) {
1118 modstatus = 7; // holes in z in SPD
1119 } else if (dead==2 || dead==3 || dead==4) {
1120 modstatus = 2; // dead from OCDB
1122 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1123 // apply correction for material of the current layer
1124 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1125 if (constrain) { // apply vertex constrain
1126 updatetrack->SetConstrain(constrain);
1127 Bool_t isPrim = kTRUE;
1128 if (ilayer<4) { // check that it's close to the vertex
1129 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1130 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1131 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1132 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1133 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1135 if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1137 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1139 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1140 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1142 } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1143 updatetrack->SetDeadZoneProbability(ilayer,1.);
1144 } else if (dead==4) { // at least a single dead channel from OCDB
1145 updatetrack->SetDeadZoneProbability(ilayer,0.);
1152 // loop over clusters in the road
1153 while ((cl=layer.GetNextCluster(clidx))!=0) {
1154 if (ntracks[ilayer]>95) break; //space for skipped clusters
1155 Bool_t changedet =kFALSE;
1156 if (TMath::Abs(cl->GetQ())<1.e-13 && deadzoneSPD==kTRUE) continue;
1157 Int_t idetc=cl->GetDetectorIndex();
1159 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1160 // take into account misalignment (bring track to real detector plane)
1161 Double_t xTrOrig = currenttrack->GetX();
1162 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1163 // a first cut on track-cluster distance
1164 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1165 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1166 { // cluster not associated to track
1167 AliDebug(2,"not associated");
1168 // MvL: added here as well
1169 // bring track back to ideal detector plane
1170 currenttrack->Propagate(xTrOrig);
1173 // bring track back to ideal detector plane
1174 if (!currenttrack->Propagate(xTrOrig)) continue;
1175 } else { // have to move track to cluster's detector
1176 const AliITSdetector &detc=layer.GetDetector(idetc);
1177 // a first cut on track-cluster distance
1179 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1180 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1181 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1182 continue; // cluster not associated to track
1184 new (&backuptrack) AliITStrackMI(currenttrack2);
1186 currenttrack =¤ttrack2;
1187 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1188 new (currenttrack) AliITStrackMI(backuptrack);
1192 currenttrack->SetDetectorIndex(idetc);
1193 // Get again the budget to the primary vertex
1194 // for the current track being prolonged, if had to change detector
1195 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1198 // calculate track-clusters chi2
1199 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1201 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1202 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1203 if (TMath::Abs(cl->GetQ())<1.e-13) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1204 if (ntracks[ilayer]>=100) continue;
1205 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1206 updatetrack->SetClIndex(ilayer,-1);
1207 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1209 if (TMath::Abs(cl->GetQ())>1.e-13) { // real cluster
1210 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1211 AliDebug(2,"update failed");
1214 updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1215 modstatus = 1; // found
1216 } else { // virtual cluster in dead zone
1217 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1218 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1219 modstatus = 7; // holes in z in SPD
1223 Float_t xlocnewdet,zlocnewdet;
1224 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1225 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1228 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1230 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1232 // apply correction for material of the current layer
1233 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1235 if (constrain) { // apply vertex constrain
1236 updatetrack->SetConstrain(constrain);
1237 Bool_t isPrim = kTRUE;
1238 if (ilayer<4) { // check that it's close to the vertex
1239 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1240 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1241 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1242 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1243 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1245 if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1246 } //apply vertex constrain
1248 } // create new hypothesis
1250 AliDebug(2,"chi2 too large");
1253 } // loop over possible prolongations
1255 // allow one prolongation without clusters
1256 if (constrain && itrack<=1 && TMath::Abs(currenttrack1.GetNSkipped())<1.e-13 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1257 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1258 // apply correction for material of the current layer
1259 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1260 vtrack->SetClIndex(ilayer,-1);
1261 modstatus = 3; // skipped
1262 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1263 if(AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1264 vtrack->IncrementNSkipped();
1269 } // loop over tracks in layer ilayer+1
1271 //loop over track candidates for the current layer
1277 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1278 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1279 if (normalizedchi2[itrack] <
1280 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1284 if (constrain) { // constrain
1285 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1287 } else { // !constrain
1288 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1293 // sort tracks by increasing normalized chi2
1294 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1295 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1296 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1297 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1298 } // end loop over layers
1302 // Now select tracks to be kept
1304 Int_t max = constrain ? 20 : 5;
1306 // tracks that reach layer 0 (SPD inner)
1307 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1308 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1309 if (track.GetNumberOfClusters()<2) continue;
1310 if (!constrain && track.GetNormChi2(0) >
1311 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1314 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1317 // tracks that reach layer 1 (SPD outer)
1318 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1319 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1320 if (track.GetNumberOfClusters()<4) continue;
1321 if (!constrain && track.GetNormChi2(1) >
1322 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1323 if (constrain) track.IncrementNSkipped();
1325 track.SetD(0,track.GetD(GetX(),GetY()));
1326 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1327 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1328 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1331 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1334 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1336 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1337 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1338 if (track.GetNumberOfClusters()<3) continue;
1339 if (track.GetNormChi2(2) >
1340 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1341 track.SetD(0,track.GetD(GetX(),GetY()));
1342 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1343 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1344 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1346 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1352 // register best track of each layer - important for V0 finder
1354 for (Int_t ilayer=0;ilayer<5;ilayer++){
1355 if (ntracks[ilayer]==0) continue;
1356 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1357 if (track.GetNumberOfClusters()<1) continue;
1358 CookLabel(&track,0);
1359 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1363 // update TPC V0 information
1365 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1366 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1367 for (Int_t i=0;i<3;i++){
1368 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1369 if (index==0) break;
1370 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1371 if (vertex->GetStatus()<0) continue; // rejected V0
1373 if (otrack->GetSign()>0) {
1374 vertex->SetIndex(0,esdindex);
1377 vertex->SetIndex(1,esdindex);
1379 //find nearest layer with track info
1380 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1381 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1382 Int_t nearest = nearestold;
1383 for (Int_t ilayer =nearest;ilayer<7;ilayer++){
1384 if (ntracks[nearest]==0){
1389 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1390 if (nearestold<5&&nearest<5){
1391 Bool_t accept = track.GetNormChi2(nearest)<10;
1393 if (track.GetSign()>0) {
1394 vertex->SetParamP(track);
1395 vertex->Update(fprimvertex);
1396 //vertex->SetIndex(0,track.fESDtrack->GetID());
1397 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1399 vertex->SetParamN(track);
1400 vertex->Update(fprimvertex);
1401 //vertex->SetIndex(1,track.fESDtrack->GetID());
1402 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1404 vertex->SetStatus(vertex->GetStatus()+1);
1406 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1413 //------------------------------------------------------------------------
1414 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1416 //--------------------------------------------------------------------
1419 return fgLayers[layer];
1421 //------------------------------------------------------------------------
1422 AliITStrackerMI::AliITSlayer::AliITSlayer():
1452 //--------------------------------------------------------------------
1453 //default AliITSlayer constructor
1454 //--------------------------------------------------------------------
1455 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1456 fClusterWeight[i]=0;
1457 fClusterTracks[0][i]=-1;
1458 fClusterTracks[1][i]=-1;
1459 fClusterTracks[2][i]=-1;
1460 fClusterTracks[3][i]=-1;
1467 for (Int_t j=0; j<AliITSRecoParam::fgkMaxClusterPerLayer5; j++) {
1468 for (Int_t j1=0; j1<6; j1++) {
1469 fClusters5[j1][j]=0;
1470 fClusterIndex5[j1][j]=-1;
1479 for (Int_t j=0; j<AliITSRecoParam::fgkMaxClusterPerLayer10; j++) {
1480 for (Int_t j1=0; j1<11; j1++) {
1481 fClusters10[j1][j]=0;
1482 fClusterIndex10[j1][j]=-1;
1491 for (Int_t j=0; j<AliITSRecoParam::fgkMaxClusterPerLayer20; j++) {
1492 for (Int_t j1=0; j1<21; j1++) {
1493 fClusters20[j1][j]=0;
1494 fClusterIndex20[j1][j]=-1;
1505 //------------------------------------------------------------------------
1506 AliITStrackerMI::AliITSlayer::
1507 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1536 //--------------------------------------------------------------------
1537 //main AliITSlayer constructor
1538 //--------------------------------------------------------------------
1539 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1540 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1542 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1543 fClusterWeight[i]=0;
1544 fClusterTracks[0][i]=-1;
1545 fClusterTracks[1][i]=-1;
1546 fClusterTracks[2][i]=-1;
1547 fClusterTracks[3][i]=-1;
1555 for (Int_t j=0; j<AliITSRecoParam::fgkMaxClusterPerLayer5; j++) {
1556 for (Int_t j1=0; j1<6; j1++) {
1557 fClusters5[j1][j]=0;
1558 fClusterIndex5[j1][j]=-1;
1567 for (Int_t j=0; j<AliITSRecoParam::fgkMaxClusterPerLayer10; j++) {
1568 for (Int_t j1=0; j1<11; j1++) {
1569 fClusters10[j1][j]=0;
1570 fClusterIndex10[j1][j]=-1;
1579 for (Int_t j=0; j<AliITSRecoParam::fgkMaxClusterPerLayer20; j++) {
1580 for (Int_t j1=0; j1<21; j1++) {
1581 fClusters20[j1][j]=0;
1582 fClusterIndex20[j1][j]=-1;
1592 //------------------------------------------------------------------------
1593 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1595 fPhiOffset(layer.fPhiOffset),
1596 fNladders(layer.fNladders),
1597 fZOffset(layer.fZOffset),
1598 fNdetectors(layer.fNdetectors),
1599 fDetectors(layer.fDetectors),
1604 fClustersCs(layer.fClustersCs),
1605 fClusterIndexCs(layer.fClusterIndexCs),
1609 fCurrentSlice(layer.fCurrentSlice),
1617 fAccepted(layer.fAccepted),
1619 fMaxSigmaClY(layer.fMaxSigmaClY),
1620 fMaxSigmaClZ(layer.fMaxSigmaClZ),
1621 fNMaxSigmaCl(layer.fNMaxSigmaCl)
1625 //------------------------------------------------------------------------
1626 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1627 //--------------------------------------------------------------------
1628 // AliITSlayer destructor
1629 //--------------------------------------------------------------------
1630 delete [] fDetectors;
1631 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1632 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1633 fClusterWeight[i]=0;
1634 fClusterTracks[0][i]=-1;
1635 fClusterTracks[1][i]=-1;
1636 fClusterTracks[2][i]=-1;
1637 fClusterTracks[3][i]=-1;
1640 //------------------------------------------------------------------------
1641 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1642 //--------------------------------------------------------------------
1643 // This function removes loaded clusters
1644 //--------------------------------------------------------------------
1645 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1646 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1647 fClusterWeight[i]=0;
1648 fClusterTracks[0][i]=-1;
1649 fClusterTracks[1][i]=-1;
1650 fClusterTracks[2][i]=-1;
1651 fClusterTracks[3][i]=-1;
1657 //------------------------------------------------------------------------
1658 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1659 //--------------------------------------------------------------------
1660 // This function reset weights of the clusters
1661 //--------------------------------------------------------------------
1662 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1663 fClusterWeight[i]=0;
1664 fClusterTracks[0][i]=-1;
1665 fClusterTracks[1][i]=-1;
1666 fClusterTracks[2][i]=-1;
1667 fClusterTracks[3][i]=-1;
1669 for (Int_t i=0; i<fN;i++) {
1670 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1671 if (cl&&cl->IsUsed()) cl->Use();
1675 //------------------------------------------------------------------------
1676 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1677 //--------------------------------------------------------------------
1678 // This function calculates the road defined by the cluster density
1679 //--------------------------------------------------------------------
1681 for (Int_t i=0; i<fN; i++) {
1682 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1684 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1686 //------------------------------------------------------------------------
1687 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1688 //--------------------------------------------------------------------
1689 //This function adds a cluster to this layer
1690 //--------------------------------------------------------------------
1691 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1697 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1699 Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
1700 Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2());
1701 if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
1702 if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
1703 if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
1704 if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
1707 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1708 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1709 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1710 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1714 //------------------------------------------------------------------------
1715 void AliITStrackerMI::AliITSlayer::SortClusters()
1720 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1721 Float_t *z = new Float_t[fN];
1722 Int_t * index = new Int_t[fN];
1724 fMaxSigmaClY=0.; //AD
1725 fMaxSigmaClZ=0.; //AD
1727 for (Int_t i=0;i<fN;i++){
1728 z[i] = fClusters[i]->GetZ();
1729 // save largest errors in y and z for this layer
1730 fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
1731 fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
1733 TMath::Sort(fN,z,index,kFALSE);
1734 for (Int_t i=0;i<fN;i++){
1735 clusters[i] = fClusters[index[i]];
1738 for (Int_t i=0;i<fN;i++){
1739 fClusters[i] = clusters[i];
1740 fZ[i] = fClusters[i]->GetZ();
1741 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1742 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1743 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1753 for (Int_t i=0;i<fN;i++){
1754 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1755 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1756 fClusterIndex[i] = i;
1760 fDy5 = (fYB[1]-fYB[0])/5.;
1761 fDy10 = (fYB[1]-fYB[0])/10.;
1762 fDy20 = (fYB[1]-fYB[0])/20.;
1763 for (Int_t i=0;i<6;i++) fN5[i] =0;
1764 for (Int_t i=0;i<11;i++) fN10[i]=0;
1765 for (Int_t i=0;i<21;i++) fN20[i]=0;
1767 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;}
1768 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;}
1769 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;}
1772 for (Int_t i=0;i<fN;i++)
1773 for (Int_t irot=-1;irot<=1;irot++){
1774 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1776 for (Int_t slice=0; slice<6;slice++){
1777 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1778 fClusters5[slice][fN5[slice]] = fClusters[i];
1779 fY5[slice][fN5[slice]] = curY;
1780 fZ5[slice][fN5[slice]] = fZ[i];
1781 fClusterIndex5[slice][fN5[slice]]=i;
1786 for (Int_t slice=0; slice<11;slice++){
1787 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1788 fClusters10[slice][fN10[slice]] = fClusters[i];
1789 fY10[slice][fN10[slice]] = curY;
1790 fZ10[slice][fN10[slice]] = fZ[i];
1791 fClusterIndex10[slice][fN10[slice]]=i;
1796 for (Int_t slice=0; slice<21;slice++){
1797 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1798 fClusters20[slice][fN20[slice]] = fClusters[i];
1799 fY20[slice][fN20[slice]] = curY;
1800 fZ20[slice][fN20[slice]] = fZ[i];
1801 fClusterIndex20[slice][fN20[slice]]=i;
1808 // consistency check
1810 for (Int_t i=0;i<fN-1;i++){
1816 for (Int_t slice=0;slice<21;slice++)
1817 for (Int_t i=0;i<fN20[slice]-1;i++){
1818 if (fZ20[slice][i]>fZ20[slice][i+1]){
1825 //------------------------------------------------------------------------
1826 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1827 //--------------------------------------------------------------------
1828 // This function returns the index of the nearest cluster
1829 //--------------------------------------------------------------------
1832 if (fCurrentSlice<0) {
1841 if (ncl==0) return 0;
1842 Int_t b=0, e=ncl-1, m=(b+e)/2;
1843 for (; b<e; m=(b+e)/2) {
1844 // if (z > fClusters[m]->GetZ()) b=m+1;
1845 if (z > zcl[m]) b=m+1;
1850 //------------------------------------------------------------------------
1851 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 {
1852 //--------------------------------------------------------------------
1853 // This function computes the rectangular road for this track
1854 //--------------------------------------------------------------------
1857 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1858 // take into account the misalignment: propagate track to misaligned detector plane
1859 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1861 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1862 TMath::Sqrt(track->GetSigmaZ2() +
1863 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1864 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1865 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1866 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1867 TMath::Sqrt(track->GetSigmaY2() +
1868 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1869 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1870 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1872 // track at boundary between detectors, enlarge road
1873 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1874 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1875 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1876 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1877 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1878 Float_t tgl = TMath::Abs(track->GetTgl());
1879 if (tgl > 1.) tgl=1.;
1880 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1881 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1882 Float_t snp = TMath::Abs(track->GetSnp());
1883 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1884 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1887 // add to the road a term (up to 2-3 mm) to deal with misalignments
1888 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1889 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1891 Double_t r = fgLayers[ilayer].GetR();
1892 zmin = track->GetZ() - dz;
1893 zmax = track->GetZ() + dz;
1894 ymin = track->GetY() + r*det.GetPhi() - dy;
1895 ymax = track->GetY() + r*det.GetPhi() + dy;
1897 // bring track back to idead detector plane
1898 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1902 //------------------------------------------------------------------------
1903 void AliITStrackerMI::AliITSlayer::
1904 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1905 //--------------------------------------------------------------------
1906 // This function sets the "window"
1907 //--------------------------------------------------------------------
1909 Double_t circle=2*TMath::Pi()*fR;
1915 // enlarge road in y by maximum cluster error on this layer (3 sigma)
1916 fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
1917 fYmax += fNMaxSigmaCl*fMaxSigmaClY;
1918 fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
1919 fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
1921 Float_t ymiddle = (fYmin+fYmax)*0.5;
1922 if (ymiddle<fYB[0]) {
1923 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1924 } else if (ymiddle>fYB[1]) {
1925 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1931 fClustersCs = fClusters;
1932 fClusterIndexCs = fClusterIndex;
1938 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1939 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1940 if (slice<0) slice=0;
1941 if (slice>20) slice=20;
1942 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1944 fCurrentSlice=slice;
1945 fClustersCs = fClusters20[fCurrentSlice];
1946 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1947 fYcs = fY20[fCurrentSlice];
1948 fZcs = fZ20[fCurrentSlice];
1949 fNcs = fN20[fCurrentSlice];
1954 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1955 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1956 if (slice<0) slice=0;
1957 if (slice>10) slice=10;
1958 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1960 fCurrentSlice=slice;
1961 fClustersCs = fClusters10[fCurrentSlice];
1962 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1963 fYcs = fY10[fCurrentSlice];
1964 fZcs = fZ10[fCurrentSlice];
1965 fNcs = fN10[fCurrentSlice];
1970 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1971 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1972 if (slice<0) slice=0;
1973 if (slice>5) slice=5;
1974 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1976 fCurrentSlice=slice;
1977 fClustersCs = fClusters5[fCurrentSlice];
1978 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1979 fYcs = fY5[fCurrentSlice];
1980 fZcs = fZ5[fCurrentSlice];
1981 fNcs = fN5[fCurrentSlice];
1985 fI = FindClusterIndex(fZmin);
1986 fImax = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
1992 //------------------------------------------------------------------------
1993 Int_t AliITStrackerMI::AliITSlayer::
1994 FindDetectorIndex(Double_t phi, Double_t z) const {
1995 //--------------------------------------------------------------------
1996 //This function finds the detector crossed by the track
1997 //--------------------------------------------------------------------
1999 if (fZOffset<0) // old geometry
2000 dphi = -(phi-fPhiOffset);
2001 else // new geometry
2002 dphi = phi-fPhiOffset;
2005 if (dphi < 0) dphi += 2*TMath::Pi();
2006 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
2007 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
2008 if (np>=fNladders) np-=fNladders;
2009 if (np<0) np+=fNladders;
2012 Double_t dz=fZOffset-z;
2013 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
2014 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
2015 if (nz>=fNdetectors || nz<0) {
2016 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
2020 // ad hoc correction for 3rd ladder of SDD inner layer,
2021 // which is reversed (rotated by pi around local y)
2022 // this correction is OK only from AliITSv11Hybrid onwards
2023 if (GetR()>12. && GetR()<20.) { // SDD inner
2024 if(np==2) { // 3rd ladder
2025 Double_t posMod252[3];
2026 AliITSgeomTGeo::GetTranslation(252,posMod252);
2027 // check the Z coordinate of Mod 252: if negative
2028 // (old SDD geometry in AliITSv11Hybrid)
2029 // the swap of numeration whould be applied
2030 if(posMod252[2]<0.){
2031 nz = (fNdetectors-1) - nz;
2035 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
2038 return np*fNdetectors + nz;
2040 //------------------------------------------------------------------------
2041 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
2043 //--------------------------------------------------------------------
2044 // This function returns clusters within the "window"
2045 //--------------------------------------------------------------------
2047 if (fCurrentSlice<0) {
2048 Double_t rpi2 = 2.*fR*TMath::Pi();
2049 for (Int_t i=fI; i<fImax; i++) {
2052 if (fYmax<y) y -= rpi2;
2053 if (fYmin>y) y += rpi2;
2054 if (y<fYmin) continue;
2055 if (y>fYmax) continue;
2057 // skip clusters that are in "extended" road but they
2058 // 3sigma error does not touch the original road
2059 if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
2060 if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
2062 if (TMath::Abs(fClusters[i]->GetQ())<1.e-13 && fSkip==2) continue;
2065 return fClusters[i];
2068 for (Int_t i=fI; i<fImax; i++) {
2069 if (fYcs[i]<fYmin) continue;
2070 if (fYcs[i]>fYmax) continue;
2071 if (TMath::Abs(fClustersCs[i]->GetQ())<1.e-13 && fSkip==2) continue;
2072 ci=fClusterIndexCs[i];
2074 return fClustersCs[i];
2079 //------------------------------------------------------------------------
2080 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
2082 //--------------------------------------------------------------------
2083 // This function returns the layer thickness at this point (units X0)
2084 //--------------------------------------------------------------------
2086 x0=AliITSRecoParam::GetX0Air();
2087 if (43<fR&&fR<45) { //SSD2
2090 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2091 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2092 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2093 for (Int_t i=0; i<12; i++) {
2094 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
2095 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2099 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
2100 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2104 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2105 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2108 if (37<fR&&fR<41) { //SSD1
2111 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2112 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2113 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2114 for (Int_t i=0; i<11; i++) {
2115 if (TMath::Abs(z-3.9*i)<0.15) {
2116 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2120 if (TMath::Abs(z+3.9*i)<0.15) {
2121 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2125 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2126 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2129 if (13<fR&&fR<26) { //SDD
2132 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2134 if (TMath::Abs(y-1.80)<0.55) {
2136 for (Int_t j=0; j<20; j++) {
2137 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2138 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2141 if (TMath::Abs(y+1.80)<0.55) {
2143 for (Int_t j=0; j<20; j++) {
2144 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2145 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2149 for (Int_t i=0; i<4; i++) {
2150 if (TMath::Abs(z-7.3*i)<0.60) {
2152 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2155 if (TMath::Abs(z+7.3*i)<0.60) {
2157 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2162 if (6<fR&&fR<8) { //SPD2
2163 Double_t dd=0.0063; x0=21.5;
2165 if (TMath::Abs(y-3.08)>0.5) d+=dd;
2166 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2168 if (3<fR&&fR<5) { //SPD1
2169 Double_t dd=0.0063; x0=21.5;
2171 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2172 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2177 //------------------------------------------------------------------------
2178 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2180 fRmisal(det.fRmisal),
2182 fSinPhi(det.fSinPhi),
2183 fCosPhi(det.fCosPhi),
2189 fNChips(det.fNChips),
2190 fChipIsBad(det.fChipIsBad)
2194 //------------------------------------------------------------------------
2195 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2196 const AliITSDetTypeRec *detTypeRec)
2198 //--------------------------------------------------------------------
2199 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2200 //--------------------------------------------------------------------
2202 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2203 // while in the tracker they start from 0 for each layer
2204 for(Int_t il=0; il<ilayer; il++)
2205 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2208 if (ilayer==0 || ilayer==1) { // ---------- SPD
2210 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2212 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2215 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2219 // Get calibration from AliITSDetTypeRec
2220 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2221 calib->SetModuleIndex(idet);
2222 AliITSCalibration *calibSPDdead = 0;
2223 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2224 if (calib->IsBad() ||
2225 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2228 // printf("lay %d bad %d\n",ilayer,idet);
2231 // Get segmentation from AliITSDetTypeRec
2232 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2234 // Read info about bad chips
2235 fNChips = segm->GetMaximumChipIndex()+1;
2236 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2237 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2238 fChipIsBad = new Bool_t[fNChips];
2239 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2240 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2241 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2242 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2247 //------------------------------------------------------------------------
2248 Double_t AliITStrackerMI::GetEffectiveThickness()
2250 //--------------------------------------------------------------------
2251 // Returns the thickness between the current layer and the vertex (units X0)
2252 //--------------------------------------------------------------------
2255 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2256 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2257 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2261 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2262 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2266 Double_t xn=fgLayers[fI].GetR();
2267 for (Int_t i=0; i<fI; i++) {
2268 Double_t xi=fgLayers[i].GetR();
2269 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2275 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2276 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2279 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2280 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2284 //------------------------------------------------------------------------
2285 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2286 //-------------------------------------------------------------------
2287 // This function returns number of clusters within the "window"
2288 //--------------------------------------------------------------------
2290 for (Int_t i=fI; i<fN; i++) {
2291 const AliITSRecPoint *c=fClusters[i];
2292 if (c->GetZ() > fZmax) break;
2293 if (c->IsUsed()) continue;
2294 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2295 Double_t y=fR*det.GetPhi() + c->GetY();
2297 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2298 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2300 if (y<fYmin) continue;
2301 if (y>fYmax) continue;
2306 //------------------------------------------------------------------------
2307 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2308 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2310 //--------------------------------------------------------------------
2311 // This function refits the track "track" at the position "x" using
2312 // the clusters from "clusters"
2313 // If "extra"==kTRUE,
2314 // the clusters from overlapped modules get attached to "track"
2315 // If "planeff"==kTRUE,
2316 // special approach for plane efficiency evaluation is applyed
2317 //--------------------------------------------------------------------
2319 Int_t index[AliITSgeomTGeo::kNLayers];
2321 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2322 Int_t nc=clusters->GetNumberOfClusters();
2323 for (k=0; k<nc; k++) {
2324 Int_t idx=clusters->GetClusterIndex(k);
2325 Int_t ilayer=(idx&0xf0000000)>>28;
2329 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2331 //------------------------------------------------------------------------
2332 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2333 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2335 //--------------------------------------------------------------------
2336 // This function refits the track "track" at the position "x" using
2337 // the clusters from array
2338 // If "extra"==kTRUE,
2339 // the clusters from overlapped modules get attached to "track"
2340 // If "planeff"==kTRUE,
2341 // special approach for plane efficiency evaluation is applyed
2342 //--------------------------------------------------------------------
2343 Int_t index[AliITSgeomTGeo::kNLayers];
2345 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2347 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2348 index[k]=clusters[k];
2351 // special for cosmics and TPC prolonged tracks:
2352 // propagate to the innermost of:
2353 // - innermost layer crossed by the track
2354 // - innermost layer where a cluster was associated to the track
2355 static AliITSRecoParam *repa = NULL;
2357 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
2359 repa = AliITSRecoParam::GetHighFluxParam();
2360 AliWarning("Using default AliITSRecoParam class");
2363 Int_t evsp=repa->GetEventSpecie();
2365 if(track->GetESDtrack()) trStatus=track->GetStatus();
2366 Int_t innermostlayer=0;
2367 if((evsp&AliRecoParam::kCosmic) || (trStatus&AliESDtrack::kTPCin)) {
2369 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2370 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2371 if( (drphi < (fgLayers[innermostlayer].GetR()+1.)) ||
2372 index[innermostlayer] >= 0 ) break;
2375 AliDebug(2,Form(" drphi %f innermost %d",drphi,innermostlayer));
2378 Int_t modstatus=1; // found
2380 Int_t from, to, step;
2381 if (xx > track->GetX()) {
2382 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2385 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2388 TString dir = (step>0 ? "outward" : "inward");
2390 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2391 AliITSlayer &layer=fgLayers[ilayer];
2392 Double_t r=layer.GetR();
2394 if (step<0 && xx>r) break;
2396 // material between SSD and SDD, SDD and SPD
2397 Double_t hI=ilayer-0.5*step;
2398 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2399 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2400 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2401 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2404 Double_t oldGlobXYZ[3];
2405 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2407 // continue if we are already beyond this layer
2408 Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2409 if(step>0 && oldGlobR > r) continue; // going outward
2410 if(step<0 && oldGlobR < r) continue; // going inward
2413 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2415 Int_t idet=layer.FindDetectorIndex(phi,z);
2417 // check if we allow a prolongation without point for large-eta tracks
2418 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2420 modstatus = 4; // out in z
2421 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2422 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2425 // apply correction for material of the current layer
2426 // add time if going outward
2427 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2431 if (idet<0) return kFALSE;
2434 const AliITSdetector &det=layer.GetDetector(idet);
2435 // only for ITS-SA tracks refit
2436 if (ilayer>1 && fTrackingPhase.Contains("RefitInward") && !(track->GetStatus()&AliESDtrack::kTPCin)) track->SetCheckInvariant(kFALSE);
2438 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2440 track->SetDetectorIndex(idet);
2441 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2443 Double_t dz,zmin,zmax,dy,ymin,ymax;
2445 const AliITSRecPoint *clAcc=0;
2446 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2448 Int_t idx=index[ilayer];
2449 if (idx>=0) { // cluster in this layer
2450 modstatus = 6; // no refit
2451 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2453 if (idet != cl->GetDetectorIndex()) {
2454 idet=cl->GetDetectorIndex();
2455 const AliITSdetector &detc=layer.GetDetector(idet);
2456 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2457 track->SetDetectorIndex(idet);
2458 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2460 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2461 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2465 modstatus = 1; // found
2470 } else { // no cluster in this layer
2472 modstatus = 3; // skipped
2473 // Plane Eff determination:
2474 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2475 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2476 UseTrackForPlaneEff(track,ilayer);
2479 modstatus = 5; // no cls in road
2481 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2482 dz = 0.5*(zmax-zmin);
2483 dy = 0.5*(ymax-ymin);
2484 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2485 if (dead==1) modstatus = 7; // holes in z in SPD
2486 if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2491 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2492 track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2494 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2497 if (extra && clAcc) { // search for extra clusters in overlapped modules
2498 AliITStrackV2 tmp(*track);
2499 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2500 layer.SelectClusters(zmin,zmax,ymin,ymax);
2502 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2504 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2505 Double_t tolerance=0.1;
2506 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2507 // only clusters in another module! (overlaps)
2508 idetExtra = clExtra->GetDetectorIndex();
2509 if (idet == idetExtra) continue;
2511 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2513 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2514 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2515 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2516 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2518 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2519 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2522 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2523 track->SetExtraModule(ilayer,idetExtra);
2525 } // end search for extra clusters in overlapped modules
2527 // Correct for material of the current layer
2529 // add time if going outward
2530 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2531 track->SetCheckInvariant(kTRUE);
2532 } // end loop on layers
2534 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2538 //------------------------------------------------------------------------
2539 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2542 // calculate normalized chi2
2543 // return NormalizedChi2(track,0);
2546 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2547 // track->fdEdxMismatch=0;
2548 Float_t dedxmismatch =0;
2549 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2551 for (Int_t i = 0;i<6;i++){
2552 if (track->GetClIndex(i)>=0){
2553 Float_t cerry, cerrz;
2554 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2556 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2559 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2560 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2561 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2563 cchi2+=(0.5-ratio)*10.;
2564 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2565 dedxmismatch+=(0.5-ratio)*10.;
2569 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2570 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2571 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2572 if (i<2) chi2+=2*cl->GetDeltaProbability();
2578 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2579 track->SetdEdxMismatch(dedxmismatch);
2583 for (Int_t i = 0;i<4;i++){
2584 if (track->GetClIndex(i)>=0){
2585 Float_t cerry, cerrz;
2586 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2587 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2590 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2591 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2595 for (Int_t i = 4;i<6;i++){
2596 if (track->GetClIndex(i)>=0){
2597 Float_t cerry, cerrz;
2598 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2599 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2602 Float_t cerryb, cerrzb;
2603 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2604 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2607 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2608 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2613 if (track->GetESDtrack()->GetTPCsignal()>85){
2614 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2616 chi2+=(0.5-ratio)*5.;
2619 chi2+=(ratio-2.0)*3;
2623 Double_t match = TMath::Sqrt(track->GetChi22());
2624 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2625 if (!track->GetConstrain()) {
2626 if (track->GetNumberOfClusters()>2) {
2627 match/=track->GetNumberOfClusters()-2.;
2632 if (match<0) match=0;
2634 // penalty factor for missing points (NDeadZone>0), but no penalty
2635 // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2636 // or there is a dead from OCDB)
2637 Float_t deadzonefactor = 0.;
2638 if (track->GetNDeadZone()>0.) {
2639 Int_t sumDeadZoneProbability=0;
2640 for(Int_t ilay=0;ilay<6;ilay++) {
2641 if(track->GetDeadZoneProbability(ilay)>0.) sumDeadZoneProbability++;
2643 Int_t nDeadZoneWithProbNot1=(Int_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2644 if(nDeadZoneWithProbNot1>0) {
2645 Float_t deadZoneProbability = track->GetNDeadZone()-(Float_t)sumDeadZoneProbability;
2646 AliDebug(2,Form("nDeadZone %f sumDZProbability %d nDZWithProbNot1 %d deadZoneProb %f\n",track->GetNDeadZone(),sumDeadZoneProbability,nDeadZoneWithProbNot1,deadZoneProbability));
2647 deadZoneProbability /= (Float_t)nDeadZoneWithProbNot1;
2649 deadZoneProbability = TMath::Min(deadZoneProbability,one);
2650 deadzonefactor = 3.*(1.1-deadZoneProbability);
2654 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2655 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2656 1./(1.+track->GetNSkipped()));
2657 AliDebug(2,Form("match %f deadzonefactor %f chi2 %f sum %f skipped %f\n",match,deadzonefactor,chi2,sum,track->GetNSkipped()));
2658 AliDebug(2,Form("NormChi2 %f cls %d\n",normchi2,track->GetNumberOfClusters()));
2661 //------------------------------------------------------------------------
2662 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2665 // return matching chi2 between two tracks
2666 Double_t largeChi2=1000.;
2668 AliITStrackMI track3(*track2);
2669 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2671 vec(0,0)=track1->GetY() - track3.GetY();
2672 vec(1,0)=track1->GetZ() - track3.GetZ();
2673 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2674 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2675 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2678 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2679 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2680 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2681 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2682 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2684 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2685 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2686 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2687 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2689 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2690 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2691 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2693 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2694 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2696 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2699 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2700 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2703 //------------------------------------------------------------------------
2704 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2707 // return probability that given point (characterized by z position and error)
2708 // is in SPD dead zone
2709 // This method assumes that fSPDdetzcentre is ordered from -z to +z
2711 Double_t probability = 0.;
2712 Double_t nearestz = 0.,distz=0.;
2713 Int_t nearestzone = -1;
2714 Double_t mindistz = 1000.;
2716 // find closest dead zone
2717 for (Int_t i=0; i<3; i++) {
2718 distz=TMath::Abs(zpos-0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]));
2719 if (distz<mindistz) {
2721 nearestz=0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]);
2726 // too far from dead zone
2727 if (TMath::Abs(zpos-nearestz)>0.25+3.*zerr) return probability;
2730 Double_t zmin, zmax;
2731 if (nearestzone==0) { // dead zone at z = -7
2732 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2733 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2734 } else if (nearestzone==1) { // dead zone at z = 0
2735 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2736 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2737 } else if (nearestzone==2) { // dead zone at z = +7
2738 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2739 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2744 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2746 probability = 0.5*( AliMathBase::ErfFast((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2747 AliMathBase::ErfFast((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2748 AliDebug(2,Form("zpos %f +- %f nearestzone %d zmin zmax %f %f prob %f\n",zpos,zerr,nearestzone,zmin,zmax,probability));
2751 //------------------------------------------------------------------------
2752 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2755 // calculate normalized chi2
2757 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2759 for (Int_t i = 0;i<6;i++){
2760 if (TMath::Abs(track->GetDy(i))>0){
2761 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2762 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2765 else{chi2[i]=10000;}
2768 TMath::Sort(6,chi2,index,kFALSE);
2769 Float_t max = float(ncl)*fac-1.;
2770 Float_t sumchi=0, sumweight=0;
2771 for (Int_t i=0;i<max+1;i++){
2772 Float_t weight = (i<max)?1.:(max+1.-i);
2773 sumchi+=weight*chi2[index[i]];
2776 Double_t normchi2 = sumchi/sumweight;
2779 //------------------------------------------------------------------------
2780 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2783 // calculate normalized chi2
2784 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2787 for (Int_t i=0;i<6;i++){
2788 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2789 Double_t sy1 = forwardtrack->GetSigmaY(i);
2790 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2791 Double_t sy2 = backtrack->GetSigmaY(i);
2792 Double_t sz2 = backtrack->GetSigmaZ(i);
2793 if (i<2){ sy2=1000.;sz2=1000;}
2795 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2796 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2798 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2799 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2801 res+= nz0*nz0+ny0*ny0;
2804 if (npoints>1) return
2805 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2806 //2*forwardtrack->fNUsed+
2807 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2808 1./(1.+forwardtrack->GetNSkipped()));
2811 //------------------------------------------------------------------------
2812 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2813 //--------------------------------------------------------------------
2814 // Return pointer to a given cluster
2815 //--------------------------------------------------------------------
2816 Int_t l=(index & 0xf0000000) >> 28;
2817 Int_t c=(index & 0x0fffffff) >> 00;
2818 return fgLayers[l].GetWeight(c);
2820 //------------------------------------------------------------------------
2821 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2823 //---------------------------------------------
2824 // register track to the list
2826 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2829 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2830 Int_t index = track->GetClusterIndex(icluster);
2831 Int_t l=(index & 0xf0000000) >> 28;
2832 Int_t c=(index & 0x0fffffff) >> 00;
2833 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2834 for (Int_t itrack=0;itrack<4;itrack++){
2835 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2836 fgLayers[l].SetClusterTracks(itrack,c,id);
2842 //------------------------------------------------------------------------
2843 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2845 //---------------------------------------------
2846 // unregister track from the list
2847 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2848 Int_t index = track->GetClusterIndex(icluster);
2849 Int_t l=(index & 0xf0000000) >> 28;
2850 Int_t c=(index & 0x0fffffff) >> 00;
2851 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2852 for (Int_t itrack=0;itrack<4;itrack++){
2853 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2854 fgLayers[l].SetClusterTracks(itrack,c,-1);
2859 //------------------------------------------------------------------------
2860 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2862 //-------------------------------------------------------------
2863 //get number of shared clusters
2864 //-------------------------------------------------------------
2866 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2867 // mean number of clusters
2868 Float_t *ny = GetNy(id), *nz = GetNz(id);
2871 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2872 Int_t index = track->GetClusterIndex(icluster);
2873 Int_t l=(index & 0xf0000000) >> 28;
2874 Int_t c=(index & 0x0fffffff) >> 00;
2875 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2876 // if (ny[l]<1.e-13){
2877 // printf("problem\n");
2879 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2883 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2884 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2885 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2887 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2890 deltan = (cl->GetNz()-nz[l]);
2892 if (deltan>2.0) continue; // extended - highly probable shared cluster
2893 weight = 2./TMath::Max(3.+deltan,2.);
2895 for (Int_t itrack=0;itrack<4;itrack++){
2896 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2898 clist[l] = (AliITSRecPoint*)GetCluster(index);
2899 track->SetSharedWeight(l,weight);
2905 track->SetNUsed(shared);
2908 //------------------------------------------------------------------------
2909 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2912 // find first shared track
2914 // mean number of clusters
2915 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2917 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2918 Int_t sharedtrack=100000;
2919 Int_t tracks[24],trackindex=0;
2920 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2922 for (Int_t icluster=0;icluster<6;icluster++){
2923 if (clusterlist[icluster]<0) continue;
2924 Int_t index = clusterlist[icluster];
2925 Int_t l=(index & 0xf0000000) >> 28;
2926 Int_t c=(index & 0x0fffffff) >> 00;
2927 // if (ny[l]<1.e-13){
2928 // printf("problem\n");
2930 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2931 //if (l>3) continue;
2932 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2935 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2936 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2937 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2939 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2942 deltan = (cl->GetNz()-nz[l]);
2944 if (deltan>2.0) continue; // extended - highly probable shared cluster
2946 for (Int_t itrack=3;itrack>=0;itrack--){
2947 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2948 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2949 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2954 if (trackindex==0) return -1;
2956 sharedtrack = tracks[0];
2958 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2961 Int_t tracks2[24], cluster[24];
2962 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2965 for (Int_t i=0;i<trackindex;i++){
2966 if (tracks[i]<0) continue;
2967 tracks2[index] = tracks[i];
2969 for (Int_t j=i+1;j<trackindex;j++){
2970 if (tracks[j]<0) continue;
2971 if (tracks[j]==tracks[i]){
2979 for (Int_t i=0;i<index;i++){
2980 if (cluster[index]>max) {
2981 sharedtrack=tracks2[index];
2988 if (sharedtrack>=100000) return -1;
2990 // make list of overlaps
2992 for (Int_t icluster=0;icluster<6;icluster++){
2993 if (clusterlist[icluster]<0) continue;
2994 Int_t index = clusterlist[icluster];
2995 Int_t l=(index & 0xf0000000) >> 28;
2996 Int_t c=(index & 0x0fffffff) >> 00;
2997 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2998 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
3000 if (cl->GetNy()>2) continue;
3001 if (cl->GetNz()>2) continue;
3004 if (cl->GetNy()>3) continue;
3005 if (cl->GetNz()>3) continue;
3008 for (Int_t itrack=3;itrack>=0;itrack--){
3009 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
3010 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
3018 //------------------------------------------------------------------------
3019 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
3021 // try to find track hypothesys without conflicts
3022 // with minimal chi2;
3023 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
3024 Int_t entries1 = arr1->GetEntriesFast();
3025 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
3026 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
3027 Int_t entries2 = arr2->GetEntriesFast();
3028 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
3030 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
3031 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
3032 if (track10->Pt()>0.5+track20->Pt()) return track10;
3034 for (Int_t itrack=0;itrack<entries1;itrack++){
3035 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3036 UnRegisterClusterTracks(track,trackID1);
3039 for (Int_t itrack=0;itrack<entries2;itrack++){
3040 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3041 UnRegisterClusterTracks(track,trackID2);
3045 Float_t maxconflicts=6;
3046 Double_t maxchi2 =1000.;
3048 // get weight of hypothesys - using best hypothesy
3051 Int_t list1[6],list2[6];
3052 AliITSRecPoint *clist1[6], *clist2[6] ;
3053 RegisterClusterTracks(track10,trackID1);
3054 RegisterClusterTracks(track20,trackID2);
3055 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
3056 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
3057 UnRegisterClusterTracks(track10,trackID1);
3058 UnRegisterClusterTracks(track20,trackID2);
3061 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
3062 Float_t nerry[6],nerrz[6];
3063 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
3064 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
3065 for (Int_t i=0;i<6;i++){
3066 if ( (erry1[i]>0) && (erry2[i]>0)) {
3067 nerry[i] = TMath::Min(erry1[i],erry2[i]);
3068 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
3070 nerry[i] = TMath::Max(erry1[i],erry2[i]);
3071 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
3073 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
3074 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
3075 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
3078 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
3079 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
3080 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
3088 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
3089 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
3090 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
3091 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
3093 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
3094 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
3095 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
3097 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
3098 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
3099 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
3102 Double_t sumw = w1+w2;
3106 w1 = (d2+0.5)/(d1+d2+1.);
3107 w2 = (d1+0.5)/(d1+d2+1.);
3109 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
3110 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
3112 // get pair of "best" hypothesys
3114 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
3115 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
3117 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
3118 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
3119 //if (track1->fFakeRatio>0) continue;
3120 RegisterClusterTracks(track1,trackID1);
3121 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
3122 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
3124 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
3125 //if (track2->fFakeRatio>0) continue;
3127 RegisterClusterTracks(track2,trackID2);
3128 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
3129 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
3130 UnRegisterClusterTracks(track2,trackID2);
3132 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
3133 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
3134 if (nskipped>0.5) continue;
3136 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
3137 if (conflict1+1<cconflict1) continue;
3138 if (conflict2+1<cconflict2) continue;
3142 for (Int_t i=0;i<6;i++){
3144 Float_t c1 =0.; // conflict coeficients
3146 if (clist1[i]&&clist2[i]){
3149 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
3152 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
3154 c1 = 2./TMath::Max(3.+deltan,2.);
3155 c2 = 2./TMath::Max(3.+deltan,2.);
3161 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
3164 deltan = (clist1[i]->GetNz()-nz1[i]);
3166 c1 = 2./TMath::Max(3.+deltan,2.);
3173 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
3176 deltan = (clist2[i]->GetNz()-nz2[i]);
3178 c2 = 2./TMath::Max(3.+deltan,2.);
3184 if (TMath::Abs(track1->GetDy(i))>0.) {
3185 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
3186 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
3187 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
3188 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
3190 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
3193 if (TMath::Abs(track2->GetDy(i))>0.) {
3194 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
3195 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
3196 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
3197 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3200 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3202 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3203 if (chi21>0) sum+=w1;
3204 if (chi22>0) sum+=w2;
3207 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3208 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3209 Double_t normchi2 = 2*conflict+sumchi2/sum;
3210 if ( normchi2 <maxchi2 ){
3213 maxconflicts = conflict;
3217 UnRegisterClusterTracks(track1,trackID1);
3220 // if (maxconflicts<4 && maxchi2<th0){
3221 if (maxchi2<th0*2.){
3222 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3223 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3224 track1->SetChi2MIP(5,maxconflicts);
3225 track1->SetChi2MIP(6,maxchi2);
3226 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3227 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3228 track1->SetChi2MIP(8,index1);
3229 fBestTrackIndex[trackID1] =index1;
3230 UpdateESDtrack(track1, AliESDtrack::kITSin);
3232 else if (track10->GetChi2MIP(0)<th1){
3233 track10->SetChi2MIP(5,maxconflicts);
3234 track10->SetChi2MIP(6,maxchi2);
3235 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3236 UpdateESDtrack(track10,AliESDtrack::kITSin);
3239 for (Int_t itrack=0;itrack<entries1;itrack++){
3240 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3241 UnRegisterClusterTracks(track,trackID1);
3244 for (Int_t itrack=0;itrack<entries2;itrack++){
3245 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3246 UnRegisterClusterTracks(track,trackID2);
3249 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3250 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3251 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3252 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3253 RegisterClusterTracks(track10,trackID1);
3255 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3256 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3257 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3258 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3259 RegisterClusterTracks(track20,trackID2);
3264 //------------------------------------------------------------------------
3265 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3266 //--------------------------------------------------------------------
3267 // This function marks clusters assigned to the track
3268 //--------------------------------------------------------------------
3269 AliTracker::UseClusters(t,from);
3271 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3272 //if (c->GetQ()>2) c->Use();
3273 if (c->GetSigmaZ2()>0.1) c->Use();
3274 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3275 //if (c->GetQ()>2) c->Use();
3276 if (c->GetSigmaZ2()>0.1) c->Use();
3279 //------------------------------------------------------------------------
3280 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3282 //------------------------------------------------------------------
3283 // add track to the list of hypothesys
3284 //------------------------------------------------------------------
3286 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3287 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3289 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3291 array = new TObjArray(10);
3292 fTrackHypothesys.AddAt(array,esdindex);
3294 array->AddLast(track);
3296 //------------------------------------------------------------------------
3297 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3299 //-------------------------------------------------------------------
3300 // compress array of track hypothesys
3301 // keep only maxsize best hypothesys
3302 //-------------------------------------------------------------------
3303 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3304 if (! (fTrackHypothesys.At(esdindex)) ) return;
3305 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3306 Int_t entries = array->GetEntriesFast();
3308 //- find preliminary besttrack as a reference
3309 Float_t minchi2=10000;
3311 AliITStrackMI * besttrack=0;
3312 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3313 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3314 if (!track) continue;
3315 Float_t chi2 = NormalizedChi2(track,0);
3317 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3318 track->SetLabel(tpcLabel);
3320 track->SetFakeRatio(1.);
3321 CookLabel(track,0.); //For comparison only
3323 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3324 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3325 if (track->GetNumberOfClusters()<maxn) continue;
3326 maxn = track->GetNumberOfClusters();
3333 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3334 delete array->RemoveAt(itrack);
3338 if (!besttrack) return;
3341 //take errors of best track as a reference
3342 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3343 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3344 for (Int_t j=0;j<6;j++) {
3345 if (besttrack->GetClIndex(j)>=0){
3346 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3347 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3348 ny[j] = besttrack->GetNy(j);
3349 nz[j] = besttrack->GetNz(j);
3353 // calculate normalized chi2
3355 Float_t * chi2 = new Float_t[entries];
3356 Int_t * index = new Int_t[entries];
3357 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3358 for (Int_t itrack=0;itrack<entries;itrack++){
3359 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3361 AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3362 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3363 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3364 chi2[itrack] = track->GetChi2MIP(0);
3366 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3367 delete array->RemoveAt(itrack);
3373 TMath::Sort(entries,chi2,index,kFALSE);
3374 besttrack = (AliITStrackMI*)array->At(index[0]);
3375 if(besttrack) AliDebug(2,Form("ncls best track %d\n",besttrack->GetNumberOfClusters()));
3376 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3377 for (Int_t j=0;j<6;j++){
3378 if (besttrack->GetClIndex(j)>=0){
3379 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3380 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3381 ny[j] = besttrack->GetNy(j);
3382 nz[j] = besttrack->GetNz(j);
3387 // calculate one more time with updated normalized errors
3388 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3389 for (Int_t itrack=0;itrack<entries;itrack++){
3390 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3392 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3393 AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3394 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3395 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3398 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3399 delete array->RemoveAt(itrack);
3404 entries = array->GetEntriesFast();
3408 TObjArray * newarray = new TObjArray();
3409 TMath::Sort(entries,chi2,index,kFALSE);
3410 besttrack = (AliITStrackMI*)array->At(index[0]);
3412 AliDebug(2,Form("ncls best track %d %f %f\n",besttrack->GetNumberOfClusters(),besttrack->GetChi2MIP(0),chi2[index[0]]));
3414 for (Int_t j=0;j<6;j++){
3415 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3416 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3417 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3418 ny[j] = besttrack->GetNy(j);
3419 nz[j] = besttrack->GetNz(j);
3422 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3423 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3424 Float_t minn = besttrack->GetNumberOfClusters()-3;
3426 for (Int_t i=0;i<entries;i++){
3427 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3428 if (!track) continue;
3429 if (accepted>maxcut) break;
3430 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3431 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3432 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3433 delete array->RemoveAt(index[i]);
3437 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3438 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3439 if (!shortbest) accepted++;
3441 newarray->AddLast(array->RemoveAt(index[i]));
3442 for (Int_t j=0;j<6;j++){
3444 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3445 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3446 ny[j] = track->GetNy(j);
3447 nz[j] = track->GetNz(j);
3452 delete array->RemoveAt(index[i]);
3456 delete fTrackHypothesys.RemoveAt(esdindex);
3457 fTrackHypothesys.AddAt(newarray,esdindex);
3461 delete fTrackHypothesys.RemoveAt(esdindex);
3467 //------------------------------------------------------------------------
3468 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3470 //-------------------------------------------------------------
3471 // try to find best hypothesy
3472 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3473 //-------------------------------------------------------------
3474 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3475 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3476 if (!array) return 0;
3477 Int_t entries = array->GetEntriesFast();
3478 if (!entries) return 0;
3479 Float_t minchi2 = 100000;
3480 AliITStrackMI * besttrack=0;
3482 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3483 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3484 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3485 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3487 for (Int_t i=0;i<entries;i++){
3488 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3489 if (!track) continue;
3490 Float_t sigmarfi,sigmaz;
3491 GetDCASigma(track,sigmarfi,sigmaz);
3492 track->SetDnorm(0,sigmarfi);
3493 track->SetDnorm(1,sigmaz);
3495 track->SetChi2MIP(1,1000000);
3496 track->SetChi2MIP(2,1000000);
3497 track->SetChi2MIP(3,1000000);
3500 backtrack = new(backtrack) AliITStrackMI(*track);
3501 if (track->GetConstrain()) {
3502 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3503 if (AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
3504 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3506 backtrack->ResetCovariance(10.);
3508 backtrack->ResetCovariance(10.);
3510 backtrack->ResetClusters();
3512 Double_t x = original->GetX();
3513 if (!RefitAt(x,backtrack,track)) continue;
3515 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3516 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3517 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3518 track->SetChi22(GetMatchingChi2(backtrack,original));
3520 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3521 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3522 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3525 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3527 //forward track - without constraint
3528 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3529 forwardtrack->ResetClusters();
3531 RefitAt(x,forwardtrack,track);
3532 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3533 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3534 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3536 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3537 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3538 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3539 forwardtrack->SetD(0,track->GetD(0));
3540 forwardtrack->SetD(1,track->GetD(1));
3543 AliITSRecPoint* clist[6];
3544 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3545 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3548 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3549 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3550 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3551 track->SetChi2MIP(3,1000);
3554 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3556 for (Int_t ichi=0;ichi<5;ichi++){
3557 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3559 if (chi2 < minchi2){
3560 //besttrack = new AliITStrackMI(*forwardtrack);
3562 besttrack->SetLabel(track->GetLabel());
3563 besttrack->SetFakeRatio(track->GetFakeRatio());
3565 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3566 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3567 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3571 delete forwardtrack;
3573 if (!besttrack) return 0;
3576 for (Int_t i=0;i<entries;i++){
3577 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3579 if (!track) continue;
3581 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3582 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3583 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3584 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3585 delete array->RemoveAt(i);
3595 SortTrackHypothesys(esdindex,checkmax,1);
3597 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3598 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3599 besttrack = (AliITStrackMI*)array->At(0);
3600 if (!besttrack) return 0;
3601 besttrack->SetChi2MIP(8,0);
3602 fBestTrackIndex[esdindex]=0;
3603 entries = array->GetEntriesFast();
3604 AliITStrackMI *longtrack =0;
3606 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3607 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3608 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3609 if (!track->GetConstrain()) continue;
3610 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3611 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3612 if (track->GetChi2MIP(0)>4.) continue;
3613 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3616 //if (longtrack) besttrack=longtrack;
3619 AliITSRecPoint * clist[6];
3620 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3621 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3622 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3623 RegisterClusterTracks(besttrack,esdindex);
3630 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3631 if (sharedtrack>=0){
3633 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3635 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3641 if (shared>2.5) return 0;
3642 if (shared>1.0) return besttrack;
3644 // Don't sign clusters if not gold track
3646 if (!besttrack->IsGoldPrimary()) return besttrack;
3647 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3649 if (fConstraint[fPass]){
3653 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3654 for (Int_t i=0;i<6;i++){
3655 Int_t index = besttrack->GetClIndex(i);
3656 if (index<0) continue;
3657 Int_t ilayer = (index & 0xf0000000) >> 28;
3658 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3659 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3661 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3662 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3663 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3664 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3665 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3666 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3668 Bool_t cansign = kTRUE;
3669 for (Int_t itrack=0;itrack<entries; itrack++){
3670 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3671 if (!track) continue;
3672 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3673 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3679 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3680 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3681 if (!c->IsUsed()) c->Use();
3687 //------------------------------------------------------------------------
3688 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3691 // get "best" hypothesys
3694 Int_t nentries = itsTracks.GetEntriesFast();
3695 for (Int_t i=0;i<nentries;i++){
3696 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3697 if (!track) continue;
3698 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3699 if (!array) continue;
3700 if (array->GetEntriesFast()<=0) continue;
3702 AliITStrackMI* longtrack=0;
3704 Float_t maxchi2=1000;
3705 for (Int_t j=0;j<array->GetEntriesFast();j++){
3706 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3707 if (!trackHyp) continue;
3708 if (trackHyp->GetGoldV0()) {
3709 longtrack = trackHyp; //gold V0 track taken
3712 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3713 Float_t chi2 = trackHyp->GetChi2MIP(0);
3715 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3717 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3719 if (chi2 > maxchi2) continue;
3720 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3727 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3728 if (!longtrack) {longtrack = besttrack;}
3729 else besttrack= longtrack;
3733 AliITSRecPoint * clist[6];
3734 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3736 track->SetNUsed(shared);
3737 track->SetNSkipped(besttrack->GetNSkipped());
3738 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3740 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3744 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3745 //if (sharedtrack==-1) sharedtrack=0;
3746 if (sharedtrack>=0) {
3747 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3750 if (besttrack&&fAfterV0) {
3751 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3754 if (fConstraint[fPass]) UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3755 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3756 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3757 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3763 //------------------------------------------------------------------------
3764 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3765 //--------------------------------------------------------------------
3766 //This function "cooks" a track label. If label<0, this track is fake.
3767 //--------------------------------------------------------------------
3770 if (track->GetESDtrack()){
3771 tpcLabel = track->GetESDtrack()->GetTPCLabel();
3772 ULong_t trStatus=track->GetESDtrack()->GetStatus();
3773 if(!(trStatus&AliESDtrack::kTPCin)) tpcLabel=track->GetLabel(); // for ITSsa tracks
3775 track->SetChi2MIP(9,0);
3777 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3778 Int_t cindex = track->GetClusterIndex(i);
3779 Int_t l=(cindex & 0xf0000000) >> 28;
3780 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3782 for (Int_t ind=0;ind<3;ind++){
3783 if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
3784 //AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3786 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3789 Int_t nclusters = track->GetNumberOfClusters();
3790 if (nclusters > 0) //PH Some tracks don't have any cluster
3791 track->SetFakeRatio(double(nwrong)/double(nclusters));
3792 if (tpcLabel>0 && track->GetFakeRatio()>wrong) {
3793 track->SetLabel(-tpcLabel);
3795 track->SetLabel(tpcLabel);
3797 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3800 //------------------------------------------------------------------------
3801 void AliITStrackerMI::CookdEdx(AliITStrackMI* track){
3803 // Fill the dE/dx in this track
3805 track->SetChi2MIP(9,0);
3806 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3807 Int_t cindex = track->GetClusterIndex(i);
3808 Int_t l=(cindex & 0xf0000000) >> 28;
3809 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3810 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3812 for (Int_t ind=0;ind<3;ind++){
3813 if (cl->GetLabel(ind)==lab) isWrong=0;
3815 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3819 track->CookdEdx(low,up);
3821 //------------------------------------------------------------------------
3822 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3824 // Create some arrays
3826 if (fCoefficients) delete []fCoefficients;
3827 fCoefficients = new Float_t[ntracks*48];
3828 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3830 //------------------------------------------------------------------------
3831 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3834 // Compute predicted chi2
3836 // Take into account the mis-alignment (bring track to cluster plane)
3837 Double_t xTrOrig=track->GetX();
3838 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3839 Float_t erry,errz,covyz;
3840 Float_t theta = track->GetTgl();
3841 Float_t phi = track->GetSnp();
3842 phi *= TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3843 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
3844 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()));
3845 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()));
3846 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
3847 // Bring the track back to detector plane in ideal geometry
3848 // [mis-alignment will be accounted for in UpdateMI()]
3849 if (!track->Propagate(xTrOrig)) return 1000.;
3851 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3852 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3854 chi2+=0.5*TMath::Min(delta/2,2.);
3855 chi2+=2.*cluster->GetDeltaProbability();
3858 track->SetNy(layer,ny);
3859 track->SetNz(layer,nz);
3860 track->SetSigmaY(layer,erry);
3861 track->SetSigmaZ(layer, errz);
3862 track->SetSigmaYZ(layer,covyz);
3863 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3864 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3868 //------------------------------------------------------------------------
3869 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3874 Int_t layer = (index & 0xf0000000) >> 28;
3875 track->SetClIndex(layer, index);
3876 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3877 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3878 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3879 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3883 if (TMath::Abs(cl->GetQ())<1.e-13) return 0; // ingore the "virtual" clusters
3886 // Take into account the mis-alignment (bring track to cluster plane)
3887 Double_t xTrOrig=track->GetX();
3888 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3889 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3890 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3891 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3893 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3896 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3897 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3898 c.SetSigmaYZ(track->GetSigmaYZ(layer));
3901 Int_t updated = track->UpdateMI(&c,chi2,index);
3902 // Bring the track back to detector plane in ideal geometry
3903 if (!track->Propagate(xTrOrig)) return 0;
3905 if(!updated) AliDebug(2,"update failed");
3909 //------------------------------------------------------------------------
3910 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3913 //DCA sigmas parameterization
3914 //to be paramterized using external parameters in future
3917 Double_t curv=track->GetC();
3918 sigmarfi = 0.0040+1.4 *TMath::Abs(curv)+332.*curv*curv;
3919 sigmaz = 0.0110+4.37*TMath::Abs(curv);
3921 //------------------------------------------------------------------------
3922 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3925 // Clusters from delta electrons?
3927 Int_t entries = clusterArray->GetEntriesFast();
3928 if (entries<4) return;
3929 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3930 Int_t layer = cluster->GetLayer();
3931 if (layer>1) return;
3933 Int_t ncandidates=0;
3934 Float_t r = (layer>0)? 7:4;
3936 for (Int_t i=0;i<entries;i++){
3937 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3938 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3939 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3940 index[ncandidates] = i; //candidate to belong to delta electron track
3942 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3943 cl0->SetDeltaProbability(1);
3949 for (Int_t i=0;i<ncandidates;i++){
3950 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3951 if (cl0->GetDeltaProbability()>0.8) continue;
3954 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3955 sumy=sumz=sumy2=sumyz=sumw=0.0;
3956 for (Int_t j=0;j<ncandidates;j++){
3958 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3960 Float_t dz = cl0->GetZ()-cl1->GetZ();
3961 Float_t dy = cl0->GetY()-cl1->GetY();
3962 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3963 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3964 y[ncl] = cl1->GetY();
3965 z[ncl] = cl1->GetZ();
3966 sumy+= y[ncl]*weight;
3967 sumz+= z[ncl]*weight;
3968 sumy2+=y[ncl]*y[ncl]*weight;
3969 sumyz+=y[ncl]*z[ncl]*weight;
3974 if (ncl<4) continue;
3975 Float_t det = sumw*sumy2 - sumy*sumy;
3977 if (TMath::Abs(det)>0.01){
3978 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3979 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3980 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3983 Float_t z0 = sumyz/sumy;
3984 delta = TMath::Abs(cl0->GetZ()-z0);
3987 cl0->SetDeltaProbability(1-20.*delta);
3991 //------------------------------------------------------------------------
3992 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3997 track->UpdateESDtrack(flags);
3998 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3999 if (oldtrack) delete oldtrack;
4000 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
4001 // if (TMath::Abs(track->GetDnorm(1))<0.000000001){
4002 // printf("Problem\n");
4005 //------------------------------------------------------------------------
4006 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
4008 // Get nearest upper layer close to the point xr.
4009 // rough approximation
4011 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
4012 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
4014 for (Int_t i=0;i<6;i++){
4015 if (radius<kRadiuses[i]){
4022 //------------------------------------------------------------------------
4023 void AliITStrackerMI::BuildMaterialLUT(TString material) {
4024 //--------------------------------------------------------------------
4025 // Fill a look-up table with mean material
4026 //--------------------------------------------------------------------
4030 Double_t point1[3],point2[3];
4031 Double_t phi,cosphi,sinphi,z;
4032 // 0-5 layers, 6 pipe, 7-8 shields
4033 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
4034 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
4036 Int_t ifirst=0,ilast=0;
4037 if(material.Contains("Pipe")) {
4039 } else if(material.Contains("Shields")) {
4041 } else if(material.Contains("Layers")) {
4044 Error("BuildMaterialLUT","Wrong layer name\n");
4047 for(Int_t imat=ifirst; imat<=ilast; imat++) {
4048 Double_t param[5]={0.,0.,0.,0.,0.};
4049 for (Int_t i=0; i<n; i++) {
4050 phi = 2.*TMath::Pi()*gRandom->Rndm();
4051 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
4052 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
4053 point1[0] = rmin[imat]*cosphi;
4054 point1[1] = rmin[imat]*sinphi;
4056 point2[0] = rmax[imat]*cosphi;
4057 point2[1] = rmax[imat]*sinphi;
4059 AliTracker::MeanMaterialBudget(point1,point2,mparam);
4060 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
4062 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
4064 fxOverX0Layer[imat] = param[1];
4065 fxTimesRhoLayer[imat] = param[0]*param[4];
4066 } else if(imat==6) {
4067 fxOverX0Pipe = param[1];
4068 fxTimesRhoPipe = param[0]*param[4];
4069 } else if(imat==7) {
4070 fxOverX0Shield[0] = param[1];
4071 fxTimesRhoShield[0] = param[0]*param[4];
4072 } else if(imat==8) {
4073 fxOverX0Shield[1] = param[1];
4074 fxTimesRhoShield[1] = param[0]*param[4];
4078 printf("%s\n",material.Data());
4079 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
4080 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
4081 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
4082 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
4083 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
4084 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
4085 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
4086 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
4087 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
4091 //------------------------------------------------------------------------
4092 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
4093 TString direction) {
4094 //-------------------------------------------------------------------
4095 // Propagate beyond beam pipe and correct for material
4096 // (material budget in different ways according to fUseTGeo value)
4097 // Add time if going outward (PropagateTo or PropagateToTGeo)
4098 //-------------------------------------------------------------------
4100 // Define budget mode:
4101 // 0: material from AliITSRecoParam (hard coded)
4102 // 1: material from TGeo in one step (on the fly)
4103 // 2: material from lut
4104 // 3: material from TGeo in one step (same for all hypotheses)
4117 if(fTrackingPhase.Contains("Clusters2Tracks"))
4118 { mode=3; } else { mode=1; }
4121 if(fTrackingPhase.Contains("Clusters2Tracks"))
4122 { mode=3; } else { mode=2; }
4128 if(fTrackingPhase.Contains("Default")) mode=0;
4130 Int_t index=fCurrentEsdTrack;
4132 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4133 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4135 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4137 Double_t xOverX0,x0,lengthTimesMeanDensity;
4141 xOverX0 = AliITSRecoParam::GetdPipe();
4142 x0 = AliITSRecoParam::GetX0Be();
4143 lengthTimesMeanDensity = xOverX0*x0;
4144 lengthTimesMeanDensity *= dir;
4145 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4148 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4151 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4152 xOverX0 = fxOverX0Pipe;
4153 lengthTimesMeanDensity = fxTimesRhoPipe;
4154 lengthTimesMeanDensity *= dir;
4155 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4158 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4159 if(fxOverX0PipeTrks[index]<0) {
4160 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4161 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4162 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4163 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4164 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4167 xOverX0 = fxOverX0PipeTrks[index];
4168 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4169 lengthTimesMeanDensity *= dir;
4170 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4176 //------------------------------------------------------------------------
4177 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4179 TString direction) {
4180 //-------------------------------------------------------------------
4181 // Propagate beyond SPD or SDD shield and correct for material
4182 // (material budget in different ways according to fUseTGeo value)
4183 // Add time if going outward (PropagateTo or PropagateToTGeo)
4184 //-------------------------------------------------------------------
4186 // Define budget mode:
4187 // 0: material from AliITSRecoParam (hard coded)
4188 // 1: material from TGeo in steps of X cm (on the fly)
4189 // X = AliITSRecoParam::GetStepSizeTGeo()
4190 // 2: material from lut
4191 // 3: material from TGeo in one step (same for all hypotheses)
4204 if(fTrackingPhase.Contains("Clusters2Tracks"))
4205 { mode=3; } else { mode=1; }
4208 if(fTrackingPhase.Contains("Clusters2Tracks"))
4209 { mode=3; } else { mode=2; }
4215 if(fTrackingPhase.Contains("Default")) mode=0;
4217 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4219 Int_t shieldindex=0;
4220 if (shield.Contains("SDD")) { // SDDouter
4221 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4223 } else if (shield.Contains("SPD")) { // SPDouter
4224 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4227 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4231 // do nothing if we are already beyond the shield
4232 Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4233 if(dir<0 && rTrack > rToGo) return 1; // going outward
4234 if(dir>0 && rTrack < rToGo) return 1; // going inward
4238 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4240 Int_t index=2*fCurrentEsdTrack+shieldindex;
4242 Double_t xOverX0,x0,lengthTimesMeanDensity;
4247 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4248 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4249 lengthTimesMeanDensity = xOverX0*x0;
4250 lengthTimesMeanDensity *= dir;
4251 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4254 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4255 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4258 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4259 xOverX0 = fxOverX0Shield[shieldindex];
4260 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4261 lengthTimesMeanDensity *= dir;
4262 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4265 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4266 if(fxOverX0ShieldTrks[index]<0) {
4267 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4268 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4269 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4270 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4271 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4274 xOverX0 = fxOverX0ShieldTrks[index];
4275 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4276 lengthTimesMeanDensity *= dir;
4277 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4283 //------------------------------------------------------------------------
4284 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4286 Double_t oldGlobXYZ[3],
4287 TString direction) {
4288 //-------------------------------------------------------------------
4289 // Propagate beyond layer and correct for material
4290 // (material budget in different ways according to fUseTGeo value)
4291 // Add time if going outward (PropagateTo or PropagateToTGeo)
4292 //-------------------------------------------------------------------
4294 // Define budget mode:
4295 // 0: material from AliITSRecoParam (hard coded)
4296 // 1: material from TGeo in stepsof X cm (on the fly)
4297 // X = AliITSRecoParam::GetStepSizeTGeo()
4298 // 2: material from lut
4299 // 3: material from TGeo in one step (same for all hypotheses)
4312 if(fTrackingPhase.Contains("Clusters2Tracks"))
4313 { mode=3; } else { mode=1; }
4316 if(fTrackingPhase.Contains("Clusters2Tracks"))
4317 { mode=3; } else { mode=2; }
4323 if(fTrackingPhase.Contains("Default")) mode=0;
4325 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4327 Double_t r=fgLayers[layerindex].GetR();
4328 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4330 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4332 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4334 Int_t index=6*fCurrentEsdTrack+layerindex;
4337 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4340 // back before material (no correction)
4342 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4343 if (!t->GetLocalXat(rOld,xOld)) return 0;
4344 if (!t->Propagate(xOld)) return 0;
4348 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4349 lengthTimesMeanDensity = xOverX0*x0;
4350 lengthTimesMeanDensity *= dir;
4351 // Bring the track beyond the material
4352 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4355 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4356 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4359 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4360 xOverX0 = fxOverX0Layer[layerindex];
4361 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4362 lengthTimesMeanDensity *= dir;
4363 // Bring the track beyond the material
4364 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4367 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4368 if(fxOverX0LayerTrks[index]<0) {
4369 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4370 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4371 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4372 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4373 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4374 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4377 xOverX0 = fxOverX0LayerTrks[index];
4378 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4379 lengthTimesMeanDensity *= dir;
4380 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4387 //------------------------------------------------------------------------
4388 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4389 //-----------------------------------------------------------------
4390 // Initialize LUT for storing material for each prolonged track
4391 //-----------------------------------------------------------------
4392 fxOverX0PipeTrks = new Float_t[ntracks];
4393 fxTimesRhoPipeTrks = new Float_t[ntracks];
4394 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4395 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4396 fxOverX0LayerTrks = new Float_t[ntracks*6];
4397 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4399 for(Int_t i=0; i<ntracks; i++) {
4400 fxOverX0PipeTrks[i] = -1.;
4401 fxTimesRhoPipeTrks[i] = -1.;
4403 for(Int_t j=0; j<ntracks*2; j++) {
4404 fxOverX0ShieldTrks[j] = -1.;
4405 fxTimesRhoShieldTrks[j] = -1.;
4407 for(Int_t k=0; k<ntracks*6; k++) {
4408 fxOverX0LayerTrks[k] = -1.;
4409 fxTimesRhoLayerTrks[k] = -1.;
4416 //------------------------------------------------------------------------
4417 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4418 //-----------------------------------------------------------------
4419 // Delete LUT for storing material for each prolonged track
4420 //-----------------------------------------------------------------
4421 if(fxOverX0PipeTrks) {
4422 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4424 if(fxOverX0ShieldTrks) {
4425 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4428 if(fxOverX0LayerTrks) {
4429 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4431 if(fxTimesRhoPipeTrks) {
4432 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4434 if(fxTimesRhoShieldTrks) {
4435 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4437 if(fxTimesRhoLayerTrks) {
4438 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4442 //------------------------------------------------------------------------
4443 void AliITStrackerMI::SetForceSkippingOfLayer() {
4444 //-----------------------------------------------------------------
4445 // Check if we are forced to skip layers
4446 // either we set to skip them in RecoParam
4447 // or they were off during data-taking
4448 //-----------------------------------------------------------------
4450 const AliEventInfo *eventInfo = GetEventInfo();
4452 for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
4453 fForceSkippingOfLayer[l] = 0;
4455 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
4459 AliITSReconstructor::GetRecoParam()->GetSkipSubdetsNotInTriggerCluster()) {
4460 AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
4462 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
4463 } else if(l==2 || l==3) {
4464 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1;
4466 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
4472 //------------------------------------------------------------------------
4473 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4474 Int_t ilayer,Int_t idet) const {
4475 //-----------------------------------------------------------------
4476 // This method is used to decide whether to allow a prolongation
4477 // without clusters, because we want to skip the layer.
4478 // In this case the return value is > 0:
4479 // return 1: the user requested to skip a layer
4480 // return 2: track outside z acceptance
4481 //-----------------------------------------------------------------
4483 if (ForceSkippingOfLayer(ilayer)) return 1;
4485 Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
4487 if (idet<0 && // out in z
4488 ilayer>innerLayCanSkip &&
4489 AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4490 // check if track will cross SPD outer layer
4491 Double_t phiAtSPD2,zAtSPD2;
4492 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4493 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4495 return 2; // always allow skipping, changed on 05.11.2009
4500 //------------------------------------------------------------------------
4501 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4502 Int_t ilayer,Int_t idet,
4503 Double_t dz,Double_t dy,
4504 Bool_t noClusters) const {
4505 //-----------------------------------------------------------------
4506 // This method is used to decide whether to allow a prolongation
4507 // without clusters, because there is a dead zone in the road.
4508 // In this case the return value is > 0:
4509 // return 1: dead zone at z=0,+-7cm in SPD
4510 // This method assumes that fSPDdetzcentre is ordered from -z to +z
4511 // return 2: all road is "bad" (dead or noisy) from the OCDB
4512 // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4513 // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4514 //-----------------------------------------------------------------
4516 // check dead zones at z=0,+-7cm in the SPD
4517 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4518 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4519 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4520 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4521 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4522 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4523 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4524 for (Int_t i=0; i<3; i++)
4525 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4526 AliDebug(2,Form("crack SPD %d track z %f %f %f %f\n",ilayer,track->GetZ(),dz,zmaxdead[i],zmindead[i]));
4527 if (GetSPDDeadZoneProbability(track->GetZ(),TMath::Sqrt(track->GetSigmaZ2()))>0.1) return 1;
4531 // check bad zones from OCDB
4532 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4534 if (idet<0) return 0;
4536 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4539 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4540 if (ilayer==0 || ilayer==1) { // ---------- SPD
4542 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4544 detSizeFactorX *= 2.;
4545 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4548 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4549 if (detType==2) segm->SetLayer(ilayer+1);
4550 Float_t detSizeX = detSizeFactorX*segm->Dx();
4551 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4553 // check if the road overlaps with bad chips
4555 if(!(LocalModuleCoord(ilayer,idet,track,xloc,zloc)))return 0;
4556 Float_t zlocmin = zloc-dz;
4557 Float_t zlocmax = zloc+dz;
4558 Float_t xlocmin = xloc-dy;
4559 Float_t xlocmax = xloc+dy;
4560 Int_t chipsInRoad[100];
4562 // check if road goes out of detector
4563 Bool_t touchNeighbourDet=kFALSE;
4564 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4565 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4566 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4567 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4568 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));
4570 // check if this detector is bad
4572 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4573 if(!touchNeighbourDet) {
4574 return 2; // all detectors in road are bad
4576 return 3; // at least one is bad
4580 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4581 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4582 if (!nChipsInRoad) return 0;
4584 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4585 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4586 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4587 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4588 if (det.IsChipBad(chipsInRoad[iCh])) {
4596 if(!touchNeighbourDet) {
4597 AliDebug(2,"all bad in road");
4598 return 2; // all chips in road are bad
4600 return 3; // at least a bad chip in road
4605 AliDebug(2,"at least a bad in road");
4606 return 3; // at least a bad chip in road
4610 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4611 || !noClusters) return 0;
4613 // There are no clusters in road: check if there is at least
4614 // a bad SPD pixel or SDD anode or SSD strips on both sides
4616 Int_t idetInITS=idet;
4617 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4619 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4620 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4623 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4627 //------------------------------------------------------------------------
4628 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4629 const AliITStrackMI *track,
4630 Float_t &xloc,Float_t &zloc) const {
4631 //-----------------------------------------------------------------
4632 // Gives position of track in local module ref. frame
4633 //-----------------------------------------------------------------
4638 if(idet<0) return kTRUE; // track out of z acceptance of layer
4640 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4642 Int_t lad = Int_t(idet/ndet) + 1;
4644 Int_t det = idet - (lad-1)*ndet + 1;
4646 Double_t xyzGlob[3],xyzLoc[3];
4648 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4649 // take into account the misalignment: xyz at real detector plane
4650 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4652 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4654 xloc = (Float_t)xyzLoc[0];
4655 zloc = (Float_t)xyzLoc[2];
4659 //------------------------------------------------------------------------
4660 //------------------------------------------------------------------------
4661 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
4663 // Method to be optimized further:
4664 // Aim: decide whether a track can be used for PlaneEff evaluation
4665 // the decision is taken based on the track quality at the layer under study
4666 // no information on the clusters on this layer has to be used
4667 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4668 // the cut is done on number of sigmas from the boundaries
4670 // Input: Actual track, layer [0,5] under study
4672 // Return: kTRUE if this is a good track
4674 // it will apply a pre-selection to obtain good quality tracks.
4675 // Here also you will have the possibility to put a control on the
4676 // impact point of the track on the basic block, in order to exclude border regions
4677 // this will be done by calling a proper method of the AliITSPlaneEff class.
4679 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4680 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4682 Int_t index[AliITSgeomTGeo::kNLayers];
4684 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4686 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4687 index[k]=clusters[k];
4691 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4692 AliITSlayer &layer=fgLayers[ilayer];
4693 Double_t r=layer.GetR();
4694 AliITStrackMI tmp(*track);
4696 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4697 Int_t ncl_out=0; Int_t ncl_in=0;
4698 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) { // count n. of cluster in outermost layers
4699 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4700 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4701 // if (tmp.GetClIndex(lay)>=0) ncl_out++;
4702 if(index[lay]>=0)ncl_out++;
4704 for(Int_t lay=ilayer-1; lay>=0;lay--) { // count n. of cluster in innermost layers
4705 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4706 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4707 if (index[lay]>=0) ncl_in++;
4709 Int_t ncl=ncl_out+ncl_in;
4710 Bool_t nextout = kFALSE;
4711 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4712 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4713 Bool_t nextin = kFALSE;
4714 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4715 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4716 // maximum number of missing clusters allowed in outermost layers
4717 if(ncl_out<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersOutPlaneEff())
4719 // maximum number of missing clusters allowed (both in innermost and in outermost layers)
4720 if(ncl<AliITSgeomTGeo::kNLayers-1-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
4722 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
4723 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
4724 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
4725 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
4729 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4730 Int_t idet=layer.FindDetectorIndex(phi,z);
4731 if(idet<0) { AliInfo(Form("cannot find detector"));
4734 // here check if it has good Chi Square.
4736 //propagate to the intersection with the detector plane
4737 const AliITSdetector &det=layer.GetDetector(idet);
4738 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4742 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
4743 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4744 if(key>fPlaneEff->Nblock()) return kFALSE;
4745 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4746 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4748 // DEFINITION OF SEARCH ROAD FOR accepting a track
4750 Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXFromBoundaryPlaneEff();
4751 Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZFromBoundaryPlaneEff();
4752 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4753 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4754 // done for RecPoints
4756 // exclude tracks at boundary between detectors
4757 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
4758 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4759 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
4760 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
4761 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
4762 if ( (locx-dx < blockXmn+boundaryWidth) ||
4763 (locx+dx > blockXmx-boundaryWidth) ||
4764 (locz-dz < blockZmn+boundaryWidth) ||
4765 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
4768 //------------------------------------------------------------------------
4769 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
4771 // This Method has to be optimized! For the time-being it uses the same criteria
4772 // as those used in the search of extra clusters for overlapping modules.
4774 // Method Purpose: estabilish whether a track has produced a recpoint or not
4775 // in the layer under study (For Plane efficiency)
4777 // inputs: AliITStrackMI* track (pointer to a usable track)
4779 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
4780 // traversed by this very track. In details:
4781 // - if a cluster can be associated to the track then call
4782 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
4783 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
4786 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
4787 AliITSlayer &layer=fgLayers[ilayer];
4788 Double_t r=layer.GetR();
4789 AliITStrackMI tmp(*track);
4793 if (!tmp.GetPhiZat(r,phi,z)) return;
4794 Int_t idet=layer.FindDetectorIndex(phi,z);
4796 if(idet<0) { AliInfo(Form("cannot find detector"));
4800 //propagate to the intersection with the detector plane
4801 const AliITSdetector &det=layer.GetDetector(idet);
4802 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
4806 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
4808 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
4809 TMath::Sqrt(tmp.GetSigmaZ2() +
4810 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4811 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4812 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
4813 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
4814 TMath::Sqrt(tmp.GetSigmaY2() +
4815 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4816 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4817 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
4819 // road in global (rphi,z) [i.e. in tracking ref. system]
4820 Double_t zmin = tmp.GetZ() - dz;
4821 Double_t zmax = tmp.GetZ() + dz;
4822 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
4823 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
4825 // select clusters in road
4826 layer.SelectClusters(zmin,zmax,ymin,ymax);
4828 // Define criteria for track-cluster association
4829 Double_t msz = tmp.GetSigmaZ2() +
4830 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4831 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4832 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
4833 Double_t msy = tmp.GetSigmaY2() +
4834 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4835 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4836 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
4837 if (tmp.GetConstrain()) {
4838 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
4839 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
4841 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
4842 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
4844 msz = 1./msz; // 1/RoadZ^2
4845 msy = 1./msy; // 1/RoadY^2
4848 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
4850 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
4851 //Double_t tolerance=0.2;
4852 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
4853 idetc = cl->GetDetectorIndex();
4854 if(idet!=idetc) continue;
4855 //Int_t ilay = cl->GetLayer();
4857 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
4858 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
4860 Double_t chi2=tmp.GetPredictedChi2(cl);
4861 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
4865 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
4867 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
4868 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4869 if(key>fPlaneEff->Nblock()) return;
4870 Bool_t found=kFALSE;
4873 while ((cl=layer.GetNextCluster(clidx))!=0) {
4874 idetc = cl->GetDetectorIndex();
4875 if(idet!=idetc) continue;
4876 // here real control to see whether the cluster can be associated to the track.
4877 // cluster not associated to track
4878 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
4879 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
4880 // calculate track-clusters chi2
4881 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
4882 // in particular, the error associated to the cluster
4883 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
4885 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
4887 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
4888 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
4889 // track->SetExtraModule(ilayer,idetExtra);
4891 if(!fPlaneEff->UpDatePlaneEff(found,key))
4892 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
4893 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
4894 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
4895 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
4896 Int_t cltype[2]={-999,-999};
4899 Float_t AngleModTrack[3]={99999.,99999.,99999.}; // angles (phi, z and "absolute angle") between the track and the mormal to the module (see below)
4903 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4904 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4907 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
4908 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
4909 cltype[0]=layer.GetCluster(ci)->GetNy();
4910 cltype[1]=layer.GetCluster(ci)->GetNz();
4912 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
4913 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
4914 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
4915 // It is computed properly by calling the method
4916 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4918 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
4919 //if (tmp.PropagateTo(x,0.,0.)) {
4920 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
4921 AliCluster c(*layer.GetCluster(ci));
4922 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
4923 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
4924 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
4925 clu[2]=TMath::Sqrt(c.GetSigmaY2());
4926 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
4929 // Compute the angles between the track and the module
4930 // compute the angle "in phi direction", i.e. the angle in the transverse plane
4931 // between the normal to the module and the projection (in the transverse plane) of the
4933 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
4934 Float_t tgl = tmp.GetTgl();
4935 Float_t phitr = tmp.GetSnp();
4936 phitr = TMath::ASin(phitr);
4937 Int_t volId = AliGeomManager::LayerToVolUIDSafe(ilayer+1 ,idet );
4939 Double_t tra[3]; AliGeomManager::GetOrigTranslation(volId,tra);
4940 Double_t rot[9]; AliGeomManager::GetOrigRotation(volId,rot);
4942 alpha = tmp.GetAlpha();
4943 Double_t phiglob = alpha+phitr;
4945 p[0] = TMath::Cos(phiglob);
4946 p[1] = TMath::Sin(phiglob);
4948 TVector3 pvec(p[0],p[1],p[2]);
4949 TVector3 normvec(rot[1],rot[4],rot[7]);
4950 Double_t angle = pvec.Angle(normvec);
4952 if(angle>0.5*TMath::Pi()) angle = (TMath::Pi()-angle);
4953 angle *= 180./TMath::Pi();
4956 TVector3 pt(p[0],p[1],0);
4957 TVector3 normt(rot[1],rot[4],0);
4958 Double_t anglet = pt.Angle(normt);
4960 Double_t phiPt = TMath::ATan2(p[1],p[0]);
4961 if(phiPt<0)phiPt+=2.*TMath::Pi();
4962 Double_t phiNorm = TMath::ATan2(rot[4],rot[1]);
4963 if(phiNorm<0) phiNorm+=2.*TMath::Pi();
4964 if(anglet>0.5*TMath::Pi()) anglet = (TMath::Pi()-anglet);
4965 if(phiNorm>phiPt) anglet*=-1.;// pt-->normt clockwise: anglet>0
4966 if((phiNorm-phiPt)>TMath::Pi()) anglet*=-1.;
4967 anglet *= 180./TMath::Pi();
4969 AngleModTrack[2]=(Float_t) angle;
4970 AngleModTrack[0]=(Float_t) anglet;
4971 // now the "angle in z" (much easier, i.e. the angle between the z axis and the track momentum + 90)
4972 AngleModTrack[1]=TMath::ACos(tgl/TMath::Sqrt(tgl*tgl+1.));
4973 AngleModTrack[1]-=TMath::Pi()/2.; // range of angle is -pi/2 , pi/2
4974 AngleModTrack[1]*=180./TMath::Pi(); // in degree
4976 fPlaneEff->FillHistos(key,found,tr,clu,cltype,AngleModTrack);