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] = 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 Info("ReadBadFromDetTypeRec",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(!(rpcont->IsSPDActive() || rpcont->IsSDDActive() || rpcont->IsSSDActive())){
369 AliError("ITS is not in a known running configuration: SPD, SDD and SSD are not active");
372 Int_t i=0,j=0,ndet=0;
374 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
375 ndet=fgLayers[i].GetNdetectors();
376 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
377 for (; j<jmax; j++) {
378 // if (!cTree->GetEvent(j)) continue;
379 clusters = rpcont->UncheckedGetClusters(j);
380 if(!clusters)continue;
381 Int_t ncl=clusters->GetEntriesFast();
382 SignDeltas(clusters,GetZ());
385 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
386 detector=c->GetDetectorIndex();
388 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
390 Int_t retval = fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
392 AliWarning(Form("Too many clusters on layer %d!",i));
397 // add dead zone "virtual" cluster in SPD, if there is a cluster within
398 // zwindow cm from the dead zone
399 // This method assumes that fSPDdetzcentre is ordered from -z to +z
400 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
401 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
402 Int_t lab[4] = {0,0,0,detector};
403 Int_t info[3] = {0,0,i};
404 Float_t q = 0.; // this identifies virtual clusters
405 Float_t hit[5] = {xdead,
407 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
408 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
410 Bool_t local = kTRUE;
411 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
412 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
413 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
414 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
415 hit[1] = fSPDdetzcentre[1]-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[2]-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[3]-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));
431 } // "virtual" clusters in SPD
435 fgLayers[i].ResetRoad(); //road defined by the cluster density
436 fgLayers[i].SortClusters();
439 // check whether we have to skip some layers
440 SetForceSkippingOfLayer();
444 //------------------------------------------------------------------------
445 void AliITStrackerMI::UnloadClusters() {
446 //--------------------------------------------------------------------
447 //This function unloads ITS clusters
448 //--------------------------------------------------------------------
449 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
451 //------------------------------------------------------------------------
452 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
453 //--------------------------------------------------------------------
454 // Publishes all pointers to clusters known to the tracker into the
455 // passed object array.
456 // The ownership is not transfered - the caller is not expected to delete
458 //--------------------------------------------------------------------
460 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
461 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
462 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
469 //------------------------------------------------------------------------
470 Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
471 //--------------------------------------------------------------------
472 // Correction for the material between the TPC and the ITS
473 //--------------------------------------------------------------------
474 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
475 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
476 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
477 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
478 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
479 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
480 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
481 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
483 printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
489 //------------------------------------------------------------------------
490 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
491 //--------------------------------------------------------------------
492 // This functions reconstructs ITS tracks
493 // The clusters must be already loaded !
494 //--------------------------------------------------------------------
496 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
498 fTrackingPhase="Clusters2Tracks";
500 TObjArray itsTracks(15000);
502 fEsd = event; // store pointer to the esd
504 // temporary (for cosmics)
505 if(event->GetVertex()) {
506 TString title = event->GetVertex()->GetTitle();
507 if(title.Contains("cosmics")) {
508 Double_t xyz[3]={GetX(),GetY(),GetZ()};
509 Double_t exyz[3]={0.1,0.1,0.1};
515 {/* Read ESD tracks */
516 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
517 Int_t nentr=event->GetNumberOfTracks();
519 // Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
521 AliESDtrack *esd=event->GetTrack(nentr);
522 // ---- for debugging:
523 //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); }
525 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
526 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
527 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
528 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
529 AliITStrackMI *t = new AliITStrackMI(*esd);
530 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
531 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
534 // look at the ESD mass hypothesys !
535 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
537 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
539 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
540 //track - can be V0 according to TPC
542 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
546 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
550 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
554 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
559 t->SetReconstructed(kFALSE);
560 itsTracks.AddLast(t);
561 fOriginal.AddLast(t);
563 } /* End Read ESD tracks */
567 Int_t nentr=itsTracks.GetEntriesFast();
568 fTrackHypothesys.Expand(nentr);
569 fBestHypothesys.Expand(nentr);
570 MakeCoefficients(nentr);
571 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
573 // THE TWO TRACKING PASSES
574 for (fPass=0; fPass<2; fPass++) {
575 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
576 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
577 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
578 if (t==0) continue; //this track has been already tracked
579 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
580 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
581 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
582 if (fConstraint[fPass]) {
583 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
584 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
587 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
588 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
590 ResetTrackToFollow(*t);
593 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
596 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
598 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
599 if (!besttrack) continue;
600 besttrack->SetLabel(tpcLabel);
601 // besttrack->CookdEdx();
603 besttrack->SetFakeRatio(1.);
604 CookLabel(besttrack,0.); //For comparison only
605 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
607 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
609 t->SetReconstructed(kTRUE);
611 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
613 GetBestHypothesysMIP(itsTracks);
614 } // end loop on the two tracking passes
616 if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
617 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
622 Int_t entries = fTrackHypothesys.GetEntriesFast();
623 for (Int_t ientry=0; ientry<entries; ientry++) {
624 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
625 if (array) array->Delete();
626 delete fTrackHypothesys.RemoveAt(ientry);
629 fTrackHypothesys.Delete();
630 entries = fBestHypothesys.GetEntriesFast();
631 for (Int_t ientry=0; ientry<entries; ientry++) {
632 TObjArray * array =(TObjArray*)fBestHypothesys.UncheckedAt(ientry);
633 if (array) array->Delete();
634 delete fBestHypothesys.RemoveAt(ientry);
636 fBestHypothesys.Delete();
638 delete [] fCoefficients;
640 DeleteTrksMaterialLUT();
642 AliInfo(Form("Number of prolonged tracks: %d out of %d ESD tracks",ntrk,noesd));
644 fTrackingPhase="Default";
648 //------------------------------------------------------------------------
649 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
650 //--------------------------------------------------------------------
651 // This functions propagates reconstructed ITS tracks back
652 // The clusters must be loaded !
653 //--------------------------------------------------------------------
654 fTrackingPhase="PropagateBack";
655 Int_t nentr=event->GetNumberOfTracks();
656 // Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
659 for (Int_t i=0; i<nentr; i++) {
660 AliESDtrack *esd=event->GetTrack(i);
662 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
663 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
665 AliITStrackMI *t = new AliITStrackMI(*esd);
667 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
669 ResetTrackToFollow(*t);
672 // propagate to vertex [SR, GSI 17.02.2003]
673 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
674 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
675 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
676 fTrackToFollow.StartTimeIntegral();
677 // from vertex to outside pipe
678 CorrectForPipeMaterial(&fTrackToFollow,"outward");
680 // Start time integral and add distance from current position to vertex
681 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
682 fTrackToFollow.GetXYZ(xyzTrk);
684 for (Int_t icoord=0; icoord<3; icoord++) {
685 Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
688 fTrackToFollow.StartTimeIntegral();
689 fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
691 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
692 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
693 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
697 fTrackToFollow.SetLabel(t->GetLabel());
698 //fTrackToFollow.CookdEdx();
699 CookLabel(&fTrackToFollow,0.); //For comparison only
700 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
701 //UseClusters(&fTrackToFollow);
707 AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
709 fTrackingPhase="Default";
713 //------------------------------------------------------------------------
714 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
715 //--------------------------------------------------------------------
716 // This functions refits ITS tracks using the
717 // "inward propagated" TPC tracks
718 // The clusters must be loaded !
719 //--------------------------------------------------------------------
720 fTrackingPhase="RefitInward";
722 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
724 Int_t nentr=event->GetNumberOfTracks();
725 // Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
728 for (Int_t i=0; i<nentr; i++) {
729 AliESDtrack *esd=event->GetTrack(i);
731 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
732 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
733 if (esd->GetStatus()&AliESDtrack::kTPCout)
734 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
736 AliITStrackMI *t = new AliITStrackMI(*esd);
738 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
739 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
744 ResetTrackToFollow(*t);
745 fTrackToFollow.ResetClusters();
747 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
748 fTrackToFollow.ResetCovariance(10.);
751 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
752 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
754 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
755 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
756 AliDebug(2," refit OK");
757 fTrackToFollow.SetLabel(t->GetLabel());
758 // fTrackToFollow.CookdEdx();
759 CookdEdx(&fTrackToFollow);
761 CookLabel(&fTrackToFollow,0.0); //For comparison only
764 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
765 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
766 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
767 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
768 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
769 Double_t r[3]={0.,0.,0.};
771 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
778 AliInfo(Form("Number of refitted tracks: %d out of %d ESD tracks",ntrk,nentr));
780 fTrackingPhase="Default";
784 //------------------------------------------------------------------------
785 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
786 //--------------------------------------------------------------------
787 // Return pointer to a given cluster
788 //--------------------------------------------------------------------
789 Int_t l=(index & 0xf0000000) >> 28;
790 Int_t c=(index & 0x0fffffff) >> 00;
791 return fgLayers[l].GetCluster(c);
793 //------------------------------------------------------------------------
794 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
795 //--------------------------------------------------------------------
796 // Get track space point with index i
797 //--------------------------------------------------------------------
799 Int_t l=(index & 0xf0000000) >> 28;
800 Int_t c=(index & 0x0fffffff) >> 00;
801 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
802 Int_t idet = cl->GetDetectorIndex();
806 cl->GetGlobalXYZ(xyz);
807 cl->GetGlobalCov(cov);
809 p.SetCharge(cl->GetQ());
810 p.SetDriftTime(cl->GetDriftTime());
811 p.SetChargeRatio(cl->GetChargeRatio());
812 p.SetClusterType(cl->GetClusterType());
813 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
816 iLayer = AliGeomManager::kSPD1;
819 iLayer = AliGeomManager::kSPD2;
822 iLayer = AliGeomManager::kSDD1;
825 iLayer = AliGeomManager::kSDD2;
828 iLayer = AliGeomManager::kSSD1;
831 iLayer = AliGeomManager::kSSD2;
834 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
837 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
838 p.SetVolumeID((UShort_t)volid);
841 //------------------------------------------------------------------------
842 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
843 AliTrackPoint& p, const AliESDtrack *t) {
844 //--------------------------------------------------------------------
845 // Get track space point with index i
846 // (assign error estimated during the tracking)
847 //--------------------------------------------------------------------
849 Int_t l=(index & 0xf0000000) >> 28;
850 Int_t c=(index & 0x0fffffff) >> 00;
851 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
852 Int_t idet = cl->GetDetectorIndex();
854 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
856 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
858 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
859 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
860 Double_t alpha = t->GetAlpha();
861 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
862 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe+cl->GetX(),GetBz()));
863 phi += alpha-det.GetPhi();
864 Float_t tgphi = TMath::Tan(phi);
866 Float_t tgl = t->GetTgl(); // tgl about const along track
867 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
869 Float_t errtrky,errtrkz,covyz;
870 Bool_t addMisalErr=kFALSE;
871 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
875 cl->GetGlobalXYZ(xyz);
876 // cl->GetGlobalCov(cov);
877 Float_t pos[3] = {0.,0.,0.};
878 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
879 tmpcl.GetGlobalCov(cov);
882 p.SetCharge(cl->GetQ());
883 p.SetDriftTime(cl->GetDriftTime());
884 p.SetChargeRatio(cl->GetChargeRatio());
885 p.SetClusterType(cl->GetClusterType());
887 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
890 iLayer = AliGeomManager::kSPD1;
893 iLayer = AliGeomManager::kSPD2;
896 iLayer = AliGeomManager::kSDD1;
899 iLayer = AliGeomManager::kSDD2;
902 iLayer = AliGeomManager::kSSD1;
905 iLayer = AliGeomManager::kSSD2;
908 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
911 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
913 p.SetVolumeID((UShort_t)volid);
916 //------------------------------------------------------------------------
917 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
919 //--------------------------------------------------------------------
920 // Follow prolongation tree
921 //--------------------------------------------------------------------
923 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
924 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
927 AliESDtrack * esd = otrack->GetESDtrack();
928 if (esd->GetV0Index(0)>0) {
929 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
930 // mapping of ESD track is different as ITS track in Containers
931 // Need something more stable
932 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
933 for (Int_t i=0;i<3;i++){
934 Int_t index = esd->GetV0Index(i);
936 AliESDv0 * vertex = fEsd->GetV0(index);
937 if (vertex->GetStatus()<0) continue; // rejected V0
939 if (esd->GetSign()>0) {
940 vertex->SetIndex(0,esdindex);
942 vertex->SetIndex(1,esdindex);
946 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
948 bestarray = new TObjArray(5);
949 bestarray->SetOwner();
950 fBestHypothesys.AddAt(bestarray,esdindex);
954 //setup tree of the prolongations
956 static AliITStrackMI tracks[7][100];
957 AliITStrackMI *currenttrack;
958 static AliITStrackMI currenttrack1;
959 static AliITStrackMI currenttrack2;
960 static AliITStrackMI backuptrack;
962 Int_t nindexes[7][100];
963 Float_t normalizedchi2[100];
964 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
965 otrack->SetNSkipped(0);
966 new (&(tracks[6][0])) AliITStrackMI(*otrack);
968 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
969 Int_t modstatus = 1; // found
973 // follow prolongations
974 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
975 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
978 AliITSlayer &layer=fgLayers[ilayer];
979 Double_t r = layer.GetR();
985 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
987 if (ntracks[ilayer]>=100) break;
988 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
989 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
990 if (ntracks[ilayer]>15+ilayer){
991 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
992 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
995 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
997 // material between SSD and SDD, SDD and SPD
999 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
1001 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
1005 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
1006 Int_t idet=layer.FindDetectorIndex(phi,z);
1008 Double_t trackGlobXYZ1[3];
1009 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1011 // Get the budget to the primary vertex for the current track being prolonged
1012 Double_t budgetToPrimVertex = GetEffectiveThickness();
1014 // check if we allow a prolongation without point
1015 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1017 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1018 // propagate to the layer radius
1019 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1020 if(!vtrack->Propagate(xToGo)) continue;
1021 // apply correction for material of the current layer
1022 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1023 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1024 vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1025 vtrack->SetClIndex(ilayer,-1);
1026 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1027 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1028 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1030 if(constrain && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1035 // track outside layer acceptance in z
1036 if (idet<0) continue;
1038 //propagate to the intersection with the detector plane
1039 const AliITSdetector &det=layer.GetDetector(idet);
1040 new(¤ttrack2) AliITStrackMI(currenttrack1);
1041 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1042 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1043 currenttrack1.SetDetectorIndex(idet);
1044 currenttrack2.SetDetectorIndex(idet);
1045 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1048 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1050 // road in global (rphi,z) [i.e. in tracking ref. system]
1051 Double_t zmin,zmax,ymin,ymax;
1052 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1054 // select clusters in road
1055 layer.SelectClusters(zmin,zmax,ymin,ymax);
1056 //********************
1058 // Define criteria for track-cluster association
1059 Double_t msz = currenttrack1.GetSigmaZ2() +
1060 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1061 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1062 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1063 Double_t msy = currenttrack1.GetSigmaY2() +
1064 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1065 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1066 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1068 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1069 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1071 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1072 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1074 msz = 1./msz; // 1/RoadZ^2
1075 msy = 1./msy; // 1/RoadY^2
1079 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1081 const AliITSRecPoint *cl=0;
1083 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1084 Bool_t deadzoneSPD=kFALSE;
1085 currenttrack = ¤ttrack1;
1087 // check if the road contains a dead zone
1088 Bool_t noClusters = kFALSE;
1089 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1090 if (noClusters) AliDebug(2,"no clusters in road");
1091 Double_t dz=0.5*(zmax-zmin);
1092 Double_t dy=0.5*(ymax-ymin);
1093 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1094 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1095 // create a prolongation without clusters (check also if there are no clusters in the road)
1098 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1099 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1100 updatetrack->SetClIndex(ilayer,-1);
1102 modstatus = 5; // no cls in road
1103 } else if (dead==1) {
1104 modstatus = 7; // holes in z in SPD
1105 } else if (dead==2 || dead==3 || dead==4) {
1106 modstatus = 2; // dead from OCDB
1108 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1109 // apply correction for material of the current layer
1110 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1111 if (constrain) { // apply vertex constrain
1112 updatetrack->SetConstrain(constrain);
1113 Bool_t isPrim = kTRUE;
1114 if (ilayer<4) { // check that it's close to the vertex
1115 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1116 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1117 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1118 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1119 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1121 if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1123 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1125 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1126 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1128 } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1129 updatetrack->SetDeadZoneProbability(ilayer,1.);
1130 } else if (dead==4) { // at least a single dead channel from OCDB
1131 updatetrack->SetDeadZoneProbability(ilayer,0.);
1138 // loop over clusters in the road
1139 while ((cl=layer.GetNextCluster(clidx))!=0) {
1140 if (ntracks[ilayer]>95) break; //space for skipped clusters
1141 Bool_t changedet =kFALSE;
1142 if (TMath::Abs(cl->GetQ())<1.e-13 && deadzoneSPD==kTRUE) continue;
1143 Int_t idetc=cl->GetDetectorIndex();
1145 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1146 // take into account misalignment (bring track to real detector plane)
1147 Double_t xTrOrig = currenttrack->GetX();
1148 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1149 // a first cut on track-cluster distance
1150 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1151 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1152 { // cluster not associated to track
1153 AliDebug(2,"not associated");
1154 // MvL: added here as well
1155 // bring track back to ideal detector plane
1156 currenttrack->Propagate(xTrOrig);
1159 // bring track back to ideal detector plane
1160 if (!currenttrack->Propagate(xTrOrig)) continue;
1161 } else { // have to move track to cluster's detector
1162 const AliITSdetector &detc=layer.GetDetector(idetc);
1163 // a first cut on track-cluster distance
1165 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1166 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1167 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1168 continue; // cluster not associated to track
1170 new (&backuptrack) AliITStrackMI(currenttrack2);
1172 currenttrack =¤ttrack2;
1173 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1174 new (currenttrack) AliITStrackMI(backuptrack);
1178 currenttrack->SetDetectorIndex(idetc);
1179 // Get again the budget to the primary vertex
1180 // for the current track being prolonged, if had to change detector
1181 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1184 // calculate track-clusters chi2
1185 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1187 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1188 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1189 if (TMath::Abs(cl->GetQ())<1.e-13) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1190 if (ntracks[ilayer]>=100) continue;
1191 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1192 updatetrack->SetClIndex(ilayer,-1);
1193 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1195 if (TMath::Abs(cl->GetQ())>1.e-13) { // real cluster
1196 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1197 AliDebug(2,"update failed");
1200 updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1201 modstatus = 1; // found
1202 } else { // virtual cluster in dead zone
1203 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1204 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1205 modstatus = 7; // holes in z in SPD
1209 Float_t xlocnewdet,zlocnewdet;
1210 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1211 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1214 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1216 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1218 // apply correction for material of the current layer
1219 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1221 if (constrain) { // apply vertex constrain
1222 updatetrack->SetConstrain(constrain);
1223 Bool_t isPrim = kTRUE;
1224 if (ilayer<4) { // check that it's close to the vertex
1225 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1226 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1227 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1228 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1229 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1231 if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1232 } //apply vertex constrain
1234 } // create new hypothesis
1236 AliDebug(2,"chi2 too large");
1239 } // loop over possible prolongations
1241 // allow one prolongation without clusters
1242 if (constrain && itrack<=1 && TMath::Abs(currenttrack1.GetNSkipped())<1.e-13 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1243 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1244 // apply correction for material of the current layer
1245 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1246 vtrack->SetClIndex(ilayer,-1);
1247 modstatus = 3; // skipped
1248 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1249 if(AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1250 vtrack->IncrementNSkipped();
1255 } // loop over tracks in layer ilayer+1
1257 //loop over track candidates for the current layer
1263 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1264 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1265 if (normalizedchi2[itrack] <
1266 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1270 if (constrain) { // constrain
1271 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1273 } else { // !constrain
1274 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1279 // sort tracks by increasing normalized chi2
1280 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1281 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1282 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1283 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1284 } // end loop over layers
1288 // Now select tracks to be kept
1290 Int_t max = constrain ? 20 : 5;
1292 // tracks that reach layer 0 (SPD inner)
1293 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1294 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1295 if (track.GetNumberOfClusters()<2) continue;
1296 if (!constrain && track.GetNormChi2(0) >
1297 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1300 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1303 // tracks that reach layer 1 (SPD outer)
1304 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1305 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1306 if (track.GetNumberOfClusters()<4) continue;
1307 if (!constrain && track.GetNormChi2(1) >
1308 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1309 if (constrain) track.IncrementNSkipped();
1311 track.SetD(0,track.GetD(GetX(),GetY()));
1312 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1313 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1314 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1317 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1320 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1322 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1323 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1324 if (track.GetNumberOfClusters()<3) continue;
1325 if (!constrain && track.GetNormChi2(2) >
1326 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1327 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1329 track.SetD(0,track.GetD(GetX(),GetY()));
1330 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1331 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1332 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1335 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1341 // register best track of each layer - important for V0 finder
1343 for (Int_t ilayer=0;ilayer<5;ilayer++){
1344 if (ntracks[ilayer]==0) continue;
1345 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1346 if (track.GetNumberOfClusters()<1) continue;
1347 CookLabel(&track,0);
1348 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1352 // update TPC V0 information
1354 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1355 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1356 for (Int_t i=0;i<3;i++){
1357 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1358 if (index==0) break;
1359 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1360 if (vertex->GetStatus()<0) continue; // rejected V0
1362 if (otrack->GetSign()>0) {
1363 vertex->SetIndex(0,esdindex);
1366 vertex->SetIndex(1,esdindex);
1368 //find nearest layer with track info
1369 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1370 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1371 Int_t nearest = nearestold;
1372 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1373 if (ntracks[nearest]==0){
1378 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1379 if (nearestold<5&&nearest<5){
1380 Bool_t accept = track.GetNormChi2(nearest)<10;
1382 if (track.GetSign()>0) {
1383 vertex->SetParamP(track);
1384 vertex->Update(fprimvertex);
1385 //vertex->SetIndex(0,track.fESDtrack->GetID());
1386 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1388 vertex->SetParamN(track);
1389 vertex->Update(fprimvertex);
1390 //vertex->SetIndex(1,track.fESDtrack->GetID());
1391 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1393 vertex->SetStatus(vertex->GetStatus()+1);
1395 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1402 //------------------------------------------------------------------------
1403 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1405 //--------------------------------------------------------------------
1408 return fgLayers[layer];
1410 //------------------------------------------------------------------------
1411 AliITStrackerMI::AliITSlayer::AliITSlayer():
1441 //--------------------------------------------------------------------
1442 //default AliITSlayer constructor
1443 //--------------------------------------------------------------------
1444 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1445 fClusterWeight[i]=0;
1446 fClusterTracks[0][i]=-1;
1447 fClusterTracks[1][i]=-1;
1448 fClusterTracks[2][i]=-1;
1449 fClusterTracks[3][i]=-1;
1452 //------------------------------------------------------------------------
1453 AliITStrackerMI::AliITSlayer::
1454 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1483 //--------------------------------------------------------------------
1484 //main AliITSlayer constructor
1485 //--------------------------------------------------------------------
1486 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1487 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1489 //------------------------------------------------------------------------
1490 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1492 fPhiOffset(layer.fPhiOffset),
1493 fNladders(layer.fNladders),
1494 fZOffset(layer.fZOffset),
1495 fNdetectors(layer.fNdetectors),
1496 fDetectors(layer.fDetectors),
1501 fClustersCs(layer.fClustersCs),
1502 fClusterIndexCs(layer.fClusterIndexCs),
1506 fCurrentSlice(layer.fCurrentSlice),
1514 fAccepted(layer.fAccepted),
1516 fMaxSigmaClY(layer.fMaxSigmaClY),
1517 fMaxSigmaClZ(layer.fMaxSigmaClZ),
1518 fNMaxSigmaCl(layer.fNMaxSigmaCl)
1522 //------------------------------------------------------------------------
1523 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1524 //--------------------------------------------------------------------
1525 // AliITSlayer destructor
1526 //--------------------------------------------------------------------
1527 delete [] fDetectors;
1528 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1529 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1530 fClusterWeight[i]=0;
1531 fClusterTracks[0][i]=-1;
1532 fClusterTracks[1][i]=-1;
1533 fClusterTracks[2][i]=-1;
1534 fClusterTracks[3][i]=-1;
1537 //------------------------------------------------------------------------
1538 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1539 //--------------------------------------------------------------------
1540 // This function removes loaded clusters
1541 //--------------------------------------------------------------------
1542 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1543 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1544 fClusterWeight[i]=0;
1545 fClusterTracks[0][i]=-1;
1546 fClusterTracks[1][i]=-1;
1547 fClusterTracks[2][i]=-1;
1548 fClusterTracks[3][i]=-1;
1554 //------------------------------------------------------------------------
1555 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1556 //--------------------------------------------------------------------
1557 // This function reset weights of the clusters
1558 //--------------------------------------------------------------------
1559 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1560 fClusterWeight[i]=0;
1561 fClusterTracks[0][i]=-1;
1562 fClusterTracks[1][i]=-1;
1563 fClusterTracks[2][i]=-1;
1564 fClusterTracks[3][i]=-1;
1566 for (Int_t i=0; i<fN;i++) {
1567 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1568 if (cl&&cl->IsUsed()) cl->Use();
1572 //------------------------------------------------------------------------
1573 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1574 //--------------------------------------------------------------------
1575 // This function calculates the road defined by the cluster density
1576 //--------------------------------------------------------------------
1578 for (Int_t i=0; i<fN; i++) {
1579 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1581 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1583 //------------------------------------------------------------------------
1584 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1585 //--------------------------------------------------------------------
1586 //This function adds a cluster to this layer
1587 //--------------------------------------------------------------------
1588 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1594 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1596 Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
1597 Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2());
1598 if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
1599 if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
1600 if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
1601 if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
1604 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1605 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1606 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1607 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1611 //------------------------------------------------------------------------
1612 void AliITStrackerMI::AliITSlayer::SortClusters()
1617 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1618 Float_t *z = new Float_t[fN];
1619 Int_t * index = new Int_t[fN];
1621 fMaxSigmaClY=0.; //AD
1622 fMaxSigmaClZ=0.; //AD
1624 for (Int_t i=0;i<fN;i++){
1625 z[i] = fClusters[i]->GetZ();
1626 // save largest errors in y and z for this layer
1627 fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
1628 fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
1630 TMath::Sort(fN,z,index,kFALSE);
1631 for (Int_t i=0;i<fN;i++){
1632 clusters[i] = fClusters[index[i]];
1635 for (Int_t i=0;i<fN;i++){
1636 fClusters[i] = clusters[i];
1637 fZ[i] = fClusters[i]->GetZ();
1638 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1639 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1640 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1650 for (Int_t i=0;i<fN;i++){
1651 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1652 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1653 fClusterIndex[i] = i;
1657 fDy5 = (fYB[1]-fYB[0])/5.;
1658 fDy10 = (fYB[1]-fYB[0])/10.;
1659 fDy20 = (fYB[1]-fYB[0])/20.;
1660 for (Int_t i=0;i<6;i++) fN5[i] =0;
1661 for (Int_t i=0;i<11;i++) fN10[i]=0;
1662 for (Int_t i=0;i<21;i++) fN20[i]=0;
1664 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;}
1665 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;}
1666 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;}
1669 for (Int_t i=0;i<fN;i++)
1670 for (Int_t irot=-1;irot<=1;irot++){
1671 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1673 for (Int_t slice=0; slice<6;slice++){
1674 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1675 fClusters5[slice][fN5[slice]] = fClusters[i];
1676 fY5[slice][fN5[slice]] = curY;
1677 fZ5[slice][fN5[slice]] = fZ[i];
1678 fClusterIndex5[slice][fN5[slice]]=i;
1683 for (Int_t slice=0; slice<11;slice++){
1684 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1685 fClusters10[slice][fN10[slice]] = fClusters[i];
1686 fY10[slice][fN10[slice]] = curY;
1687 fZ10[slice][fN10[slice]] = fZ[i];
1688 fClusterIndex10[slice][fN10[slice]]=i;
1693 for (Int_t slice=0; slice<21;slice++){
1694 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1695 fClusters20[slice][fN20[slice]] = fClusters[i];
1696 fY20[slice][fN20[slice]] = curY;
1697 fZ20[slice][fN20[slice]] = fZ[i];
1698 fClusterIndex20[slice][fN20[slice]]=i;
1705 // consistency check
1707 for (Int_t i=0;i<fN-1;i++){
1713 for (Int_t slice=0;slice<21;slice++)
1714 for (Int_t i=0;i<fN20[slice]-1;i++){
1715 if (fZ20[slice][i]>fZ20[slice][i+1]){
1722 //------------------------------------------------------------------------
1723 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1724 //--------------------------------------------------------------------
1725 // This function returns the index of the nearest cluster
1726 //--------------------------------------------------------------------
1729 if (fCurrentSlice<0) {
1738 if (ncl==0) return 0;
1739 Int_t b=0, e=ncl-1, m=(b+e)/2;
1740 for (; b<e; m=(b+e)/2) {
1741 // if (z > fClusters[m]->GetZ()) b=m+1;
1742 if (z > zcl[m]) b=m+1;
1747 //------------------------------------------------------------------------
1748 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 {
1749 //--------------------------------------------------------------------
1750 // This function computes the rectangular road for this track
1751 //--------------------------------------------------------------------
1754 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1755 // take into account the misalignment: propagate track to misaligned detector plane
1756 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1758 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1759 TMath::Sqrt(track->GetSigmaZ2() +
1760 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1761 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1762 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1763 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1764 TMath::Sqrt(track->GetSigmaY2() +
1765 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1766 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1767 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1769 // track at boundary between detectors, enlarge road
1770 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1771 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1772 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1773 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1774 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1775 Float_t tgl = TMath::Abs(track->GetTgl());
1776 if (tgl > 1.) tgl=1.;
1777 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1778 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1779 Float_t snp = TMath::Abs(track->GetSnp());
1780 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1781 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1784 // add to the road a term (up to 2-3 mm) to deal with misalignments
1785 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1786 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1788 Double_t r = fgLayers[ilayer].GetR();
1789 zmin = track->GetZ() - dz;
1790 zmax = track->GetZ() + dz;
1791 ymin = track->GetY() + r*det.GetPhi() - dy;
1792 ymax = track->GetY() + r*det.GetPhi() + dy;
1794 // bring track back to idead detector plane
1795 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1799 //------------------------------------------------------------------------
1800 void AliITStrackerMI::AliITSlayer::
1801 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1802 //--------------------------------------------------------------------
1803 // This function sets the "window"
1804 //--------------------------------------------------------------------
1806 Double_t circle=2*TMath::Pi()*fR;
1812 // enlarge road in y by maximum cluster error on this layer (3 sigma)
1813 fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
1814 fYmax += fNMaxSigmaCl*fMaxSigmaClY;
1815 fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
1816 fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
1818 Float_t ymiddle = (fYmin+fYmax)*0.5;
1819 if (ymiddle<fYB[0]) {
1820 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1821 } else if (ymiddle>fYB[1]) {
1822 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1828 fClustersCs = fClusters;
1829 fClusterIndexCs = fClusterIndex;
1835 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1836 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1837 if (slice<0) slice=0;
1838 if (slice>20) slice=20;
1839 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1841 fCurrentSlice=slice;
1842 fClustersCs = fClusters20[fCurrentSlice];
1843 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1844 fYcs = fY20[fCurrentSlice];
1845 fZcs = fZ20[fCurrentSlice];
1846 fNcs = fN20[fCurrentSlice];
1851 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1852 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1853 if (slice<0) slice=0;
1854 if (slice>10) slice=10;
1855 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1857 fCurrentSlice=slice;
1858 fClustersCs = fClusters10[fCurrentSlice];
1859 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1860 fYcs = fY10[fCurrentSlice];
1861 fZcs = fZ10[fCurrentSlice];
1862 fNcs = fN10[fCurrentSlice];
1867 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1868 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1869 if (slice<0) slice=0;
1870 if (slice>5) slice=5;
1871 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1873 fCurrentSlice=slice;
1874 fClustersCs = fClusters5[fCurrentSlice];
1875 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1876 fYcs = fY5[fCurrentSlice];
1877 fZcs = fZ5[fCurrentSlice];
1878 fNcs = fN5[fCurrentSlice];
1882 fI = FindClusterIndex(fZmin);
1883 fImax = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
1889 //------------------------------------------------------------------------
1890 Int_t AliITStrackerMI::AliITSlayer::
1891 FindDetectorIndex(Double_t phi, Double_t z) const {
1892 //--------------------------------------------------------------------
1893 //This function finds the detector crossed by the track
1894 //--------------------------------------------------------------------
1896 if (fZOffset<0) // old geometry
1897 dphi = -(phi-fPhiOffset);
1898 else // new geometry
1899 dphi = phi-fPhiOffset;
1902 if (dphi < 0) dphi += 2*TMath::Pi();
1903 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1904 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1905 if (np>=fNladders) np-=fNladders;
1906 if (np<0) np+=fNladders;
1909 Double_t dz=fZOffset-z;
1910 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1911 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1912 if (nz>=fNdetectors || nz<0) {
1913 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1917 // ad hoc correction for 3rd ladder of SDD inner layer,
1918 // which is reversed (rotated by pi around local y)
1919 // this correction is OK only from AliITSv11Hybrid onwards
1920 if (GetR()>12. && GetR()<20.) { // SDD inner
1921 if(np==2) { // 3rd ladder
1922 Double_t posMod252[3];
1923 AliITSgeomTGeo::GetTranslation(252,posMod252);
1924 // check the Z coordinate of Mod 252: if negative
1925 // (old SDD geometry in AliITSv11Hybrid)
1926 // the swap of numeration whould be applied
1927 if(posMod252[2]<0.){
1928 nz = (fNdetectors-1) - nz;
1932 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1935 return np*fNdetectors + nz;
1937 //------------------------------------------------------------------------
1938 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1940 //--------------------------------------------------------------------
1941 // This function returns clusters within the "window"
1942 //--------------------------------------------------------------------
1944 if (fCurrentSlice<0) {
1945 Double_t rpi2 = 2.*fR*TMath::Pi();
1946 for (Int_t i=fI; i<fImax; i++) {
1949 if (fYmax<y) y -= rpi2;
1950 if (fYmin>y) y += rpi2;
1951 if (y<fYmin) continue;
1952 if (y>fYmax) continue;
1954 // skip clusters that are in "extended" road but they
1955 // 3sigma error does not touch the original road
1956 if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
1957 if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
1959 if (TMath::Abs(fClusters[i]->GetQ())<1.e-13 && fSkip==2) continue;
1962 return fClusters[i];
1965 for (Int_t i=fI; i<fImax; i++) {
1966 if (fYcs[i]<fYmin) continue;
1967 if (fYcs[i]>fYmax) continue;
1968 if (TMath::Abs(fClustersCs[i]->GetQ())<1.e-13 && fSkip==2) continue;
1969 ci=fClusterIndexCs[i];
1971 return fClustersCs[i];
1976 //------------------------------------------------------------------------
1977 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1979 //--------------------------------------------------------------------
1980 // This function returns the layer thickness at this point (units X0)
1981 //--------------------------------------------------------------------
1983 x0=AliITSRecoParam::GetX0Air();
1984 if (43<fR&&fR<45) { //SSD2
1987 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1988 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1989 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1990 for (Int_t i=0; i<12; i++) {
1991 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1992 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1996 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1997 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2001 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2002 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2005 if (37<fR&&fR<41) { //SSD1
2008 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2009 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2010 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2011 for (Int_t i=0; i<11; i++) {
2012 if (TMath::Abs(z-3.9*i)<0.15) {
2013 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2017 if (TMath::Abs(z+3.9*i)<0.15) {
2018 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2022 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2023 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2026 if (13<fR&&fR<26) { //SDD
2029 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2031 if (TMath::Abs(y-1.80)<0.55) {
2033 for (Int_t j=0; j<20; j++) {
2034 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2035 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2038 if (TMath::Abs(y+1.80)<0.55) {
2040 for (Int_t j=0; j<20; j++) {
2041 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2042 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2046 for (Int_t i=0; i<4; i++) {
2047 if (TMath::Abs(z-7.3*i)<0.60) {
2049 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2052 if (TMath::Abs(z+7.3*i)<0.60) {
2054 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2059 if (6<fR&&fR<8) { //SPD2
2060 Double_t dd=0.0063; x0=21.5;
2062 if (TMath::Abs(y-3.08)>0.5) d+=dd;
2063 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2065 if (3<fR&&fR<5) { //SPD1
2066 Double_t dd=0.0063; x0=21.5;
2068 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2069 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2074 //------------------------------------------------------------------------
2075 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2077 fRmisal(det.fRmisal),
2079 fSinPhi(det.fSinPhi),
2080 fCosPhi(det.fCosPhi),
2086 fNChips(det.fNChips),
2087 fChipIsBad(det.fChipIsBad)
2091 //------------------------------------------------------------------------
2092 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2093 const AliITSDetTypeRec *detTypeRec)
2095 //--------------------------------------------------------------------
2096 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2097 //--------------------------------------------------------------------
2099 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2100 // while in the tracker they start from 0 for each layer
2101 for(Int_t il=0; il<ilayer; il++)
2102 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2105 if (ilayer==0 || ilayer==1) { // ---------- SPD
2107 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2109 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2112 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2116 // Get calibration from AliITSDetTypeRec
2117 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2118 calib->SetModuleIndex(idet);
2119 AliITSCalibration *calibSPDdead = 0;
2120 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2121 if (calib->IsBad() ||
2122 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2125 // printf("lay %d bad %d\n",ilayer,idet);
2128 // Get segmentation from AliITSDetTypeRec
2129 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2131 // Read info about bad chips
2132 fNChips = segm->GetMaximumChipIndex()+1;
2133 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2134 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2135 fChipIsBad = new Bool_t[fNChips];
2136 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2137 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2138 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2139 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2144 //------------------------------------------------------------------------
2145 Double_t AliITStrackerMI::GetEffectiveThickness()
2147 //--------------------------------------------------------------------
2148 // Returns the thickness between the current layer and the vertex (units X0)
2149 //--------------------------------------------------------------------
2152 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2153 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2154 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2158 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2159 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2163 Double_t xn=fgLayers[fI].GetR();
2164 for (Int_t i=0; i<fI; i++) {
2165 Double_t xi=fgLayers[i].GetR();
2166 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2172 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2173 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2176 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2177 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2181 //------------------------------------------------------------------------
2182 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2183 //-------------------------------------------------------------------
2184 // This function returns number of clusters within the "window"
2185 //--------------------------------------------------------------------
2187 for (Int_t i=fI; i<fN; i++) {
2188 const AliITSRecPoint *c=fClusters[i];
2189 if (c->GetZ() > fZmax) break;
2190 if (c->IsUsed()) continue;
2191 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2192 Double_t y=fR*det.GetPhi() + c->GetY();
2194 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2195 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2197 if (y<fYmin) continue;
2198 if (y>fYmax) continue;
2203 //------------------------------------------------------------------------
2204 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2205 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2207 //--------------------------------------------------------------------
2208 // This function refits the track "track" at the position "x" using
2209 // the clusters from "clusters"
2210 // If "extra"==kTRUE,
2211 // the clusters from overlapped modules get attached to "track"
2212 // If "planeff"==kTRUE,
2213 // special approach for plane efficiency evaluation is applyed
2214 //--------------------------------------------------------------------
2216 Int_t index[AliITSgeomTGeo::kNLayers];
2218 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2219 Int_t nc=clusters->GetNumberOfClusters();
2220 for (k=0; k<nc; k++) {
2221 Int_t idx=clusters->GetClusterIndex(k);
2222 Int_t ilayer=(idx&0xf0000000)>>28;
2226 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2228 //------------------------------------------------------------------------
2229 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2230 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2232 //--------------------------------------------------------------------
2233 // This function refits the track "track" at the position "x" using
2234 // the clusters from array
2235 // If "extra"==kTRUE,
2236 // the clusters from overlapped modules get attached to "track"
2237 // If "planeff"==kTRUE,
2238 // special approach for plane efficiency evaluation is applyed
2239 //--------------------------------------------------------------------
2240 Int_t index[AliITSgeomTGeo::kNLayers];
2242 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2244 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2245 index[k]=clusters[k];
2248 // special for cosmics and TPC prolonged tracks:
2249 // propagate to the innermost of:
2250 // - innermost layer crossed by the track
2251 // - innermost layer where a cluster was associated to the track
2252 static AliITSRecoParam *repa = NULL;
2254 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
2256 repa = AliITSRecoParam::GetHighFluxParam();
2257 AliWarning("Using default AliITSRecoParam class");
2260 Int_t evsp=repa->GetEventSpecie();
2262 if(track->GetESDtrack()) trStatus=track->GetStatus();
2263 Int_t innermostlayer=0;
2264 if((evsp&AliRecoParam::kCosmic) || (trStatus&AliESDtrack::kTPCin)) {
2266 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2267 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2268 if( (drphi < (fgLayers[innermostlayer].GetR()+1.)) ||
2269 index[innermostlayer] >= 0 ) break;
2272 AliDebug(2,Form(" drphi %f innermost %d",drphi,innermostlayer));
2275 Int_t modstatus=1; // found
2277 Int_t from, to, step;
2278 if (xx > track->GetX()) {
2279 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2282 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2285 TString dir = (step>0 ? "outward" : "inward");
2287 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2288 AliITSlayer &layer=fgLayers[ilayer];
2289 Double_t r=layer.GetR();
2291 if (step<0 && xx>r) break;
2293 // material between SSD and SDD, SDD and SPD
2294 Double_t hI=ilayer-0.5*step;
2295 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2296 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2297 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2298 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2301 Double_t oldGlobXYZ[3];
2302 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2304 // continue if we are already beyond this layer
2305 Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2306 if(step>0 && oldGlobR > r) continue; // going outward
2307 if(step<0 && oldGlobR < r) continue; // going inward
2310 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2312 Int_t idet=layer.FindDetectorIndex(phi,z);
2314 // check if we allow a prolongation without point for large-eta tracks
2315 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2317 modstatus = 4; // out in z
2318 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2319 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2322 // apply correction for material of the current layer
2323 // add time if going outward
2324 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2328 if (idet<0) return kFALSE;
2331 const AliITSdetector &det=layer.GetDetector(idet);
2332 // only for ITS-SA tracks refit
2333 if (ilayer>1 && fTrackingPhase.Contains("RefitInward") && !(track->GetStatus()&AliESDtrack::kTPCin)) track->SetCheckInvariant(kFALSE);
2335 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2337 track->SetDetectorIndex(idet);
2338 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2340 Double_t dz,zmin,zmax,dy,ymin,ymax;
2342 const AliITSRecPoint *clAcc=0;
2343 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2345 Int_t idx=index[ilayer];
2346 if (idx>=0) { // cluster in this layer
2347 modstatus = 6; // no refit
2348 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2350 if (idet != cl->GetDetectorIndex()) {
2351 idet=cl->GetDetectorIndex();
2352 const AliITSdetector &detc=layer.GetDetector(idet);
2353 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2354 track->SetDetectorIndex(idet);
2355 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2357 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2358 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2362 modstatus = 1; // found
2367 } else { // no cluster in this layer
2369 modstatus = 3; // skipped
2370 // Plane Eff determination:
2371 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2372 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2373 UseTrackForPlaneEff(track,ilayer);
2376 modstatus = 5; // no cls in road
2378 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2379 dz = 0.5*(zmax-zmin);
2380 dy = 0.5*(ymax-ymin);
2381 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2382 if (dead==1) modstatus = 7; // holes in z in SPD
2383 if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2388 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2389 track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2391 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2394 if (extra) { // search for extra clusters in overlapped modules
2395 AliITStrackV2 tmp(*track);
2396 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2397 layer.SelectClusters(zmin,zmax,ymin,ymax);
2399 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2401 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2402 Double_t tolerance=0.1;
2403 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2404 // only clusters in another module! (overlaps)
2405 idetExtra = clExtra->GetDetectorIndex();
2406 if (idet == idetExtra) continue;
2408 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2410 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2411 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2412 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2413 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2415 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2416 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2419 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2420 track->SetExtraModule(ilayer,idetExtra);
2422 } // end search for extra clusters in overlapped modules
2424 // Correct for material of the current layer
2426 // add time if going outward
2427 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2428 track->SetCheckInvariant(kTRUE);
2429 } // end loop on layers
2431 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2435 //------------------------------------------------------------------------
2436 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2439 // calculate normalized chi2
2440 // return NormalizedChi2(track,0);
2443 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2444 // track->fdEdxMismatch=0;
2445 Float_t dedxmismatch =0;
2446 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2448 for (Int_t i = 0;i<6;i++){
2449 if (track->GetClIndex(i)>=0){
2450 Float_t cerry, cerrz;
2451 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2453 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2456 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2457 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2458 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2460 cchi2+=(0.5-ratio)*10.;
2461 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2462 dedxmismatch+=(0.5-ratio)*10.;
2466 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2467 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2468 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2469 if (i<2) chi2+=2*cl->GetDeltaProbability();
2475 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2476 track->SetdEdxMismatch(dedxmismatch);
2480 for (Int_t i = 0;i<4;i++){
2481 if (track->GetClIndex(i)>=0){
2482 Float_t cerry, cerrz;
2483 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2484 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2487 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2488 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2492 for (Int_t i = 4;i<6;i++){
2493 if (track->GetClIndex(i)>=0){
2494 Float_t cerry, cerrz;
2495 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2496 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2499 Float_t cerryb, cerrzb;
2500 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2501 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2504 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2505 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2510 if (track->GetESDtrack()->GetTPCsignal()>85){
2511 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2513 chi2+=(0.5-ratio)*5.;
2516 chi2+=(ratio-2.0)*3;
2520 Double_t match = TMath::Sqrt(track->GetChi22());
2521 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2522 if (!track->GetConstrain()) {
2523 if (track->GetNumberOfClusters()>2) {
2524 match/=track->GetNumberOfClusters()-2.;
2529 if (match<0) match=0;
2531 // penalty factor for missing points (NDeadZone>0), but no penalty
2532 // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2533 // or there is a dead from OCDB)
2534 Float_t deadzonefactor = 0.;
2535 if (track->GetNDeadZone()>0.) {
2536 Int_t sumDeadZoneProbability=0;
2537 for(Int_t ilay=0;ilay<6;ilay++) {
2538 if(track->GetDeadZoneProbability(ilay)>0.) sumDeadZoneProbability++;
2540 Int_t nDeadZoneWithProbNot1=(Int_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2541 if(nDeadZoneWithProbNot1>0) {
2542 Float_t deadZoneProbability = track->GetNDeadZone()-(Float_t)sumDeadZoneProbability;
2543 AliDebug(2,Form("nDeadZone %f sumDZProbability %d nDZWithProbNot1 %d deadZoneProb %f\n",track->GetNDeadZone(),sumDeadZoneProbability,nDeadZoneWithProbNot1,deadZoneProbability));
2544 deadZoneProbability /= (Float_t)nDeadZoneWithProbNot1;
2546 deadZoneProbability = TMath::Min(deadZoneProbability,one);
2547 deadzonefactor = 3.*(1.1-deadZoneProbability);
2551 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2552 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2553 1./(1.+track->GetNSkipped()));
2554 AliDebug(2,Form("match %f deadzonefactor %f chi2 %f sum %f skipped %f\n",match,deadzonefactor,chi2,sum,track->GetNSkipped()));
2555 AliDebug(2,Form("NormChi2 %f cls %d\n",normchi2,track->GetNumberOfClusters()));
2558 //------------------------------------------------------------------------
2559 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2562 // return matching chi2 between two tracks
2563 Double_t largeChi2=1000.;
2565 AliITStrackMI track3(*track2);
2566 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2568 vec(0,0)=track1->GetY() - track3.GetY();
2569 vec(1,0)=track1->GetZ() - track3.GetZ();
2570 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2571 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2572 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2575 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2576 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2577 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2578 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2579 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2581 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2582 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2583 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2584 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2586 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2587 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2588 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2590 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2591 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2593 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2596 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2597 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2600 //------------------------------------------------------------------------
2601 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2604 // return probability that given point (characterized by z position and error)
2605 // is in SPD dead zone
2606 // This method assumes that fSPDdetzcentre is ordered from -z to +z
2608 Double_t probability = 0.;
2609 Double_t nearestz = 0.,distz=0.;
2610 Int_t nearestzone = -1;
2611 Double_t mindistz = 1000.;
2613 // find closest dead zone
2614 for (Int_t i=0; i<3; i++) {
2615 distz=TMath::Abs(zpos-0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]));
2616 if (distz<mindistz) {
2618 nearestz=0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]);
2623 // too far from dead zone
2624 if (TMath::Abs(zpos-nearestz)>0.25+3.*zerr) return probability;
2627 Double_t zmin, zmax;
2628 if (nearestzone==0) { // dead zone at z = -7
2629 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2630 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2631 } else if (nearestzone==1) { // dead zone at z = 0
2632 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2633 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2634 } else if (nearestzone==2) { // dead zone at z = +7
2635 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2636 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2641 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2643 probability = 0.5*( AliMathBase::ErfFast((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2644 AliMathBase::ErfFast((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2645 AliDebug(2,Form("zpos %f +- %f nearestzone %d zmin zmax %f %f prob %f\n",zpos,zerr,nearestzone,zmin,zmax,probability));
2648 //------------------------------------------------------------------------
2649 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2652 // calculate normalized chi2
2654 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2656 for (Int_t i = 0;i<6;i++){
2657 if (TMath::Abs(track->GetDy(i))>0){
2658 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2659 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2662 else{chi2[i]=10000;}
2665 TMath::Sort(6,chi2,index,kFALSE);
2666 Float_t max = float(ncl)*fac-1.;
2667 Float_t sumchi=0, sumweight=0;
2668 for (Int_t i=0;i<max+1;i++){
2669 Float_t weight = (i<max)?1.:(max+1.-i);
2670 sumchi+=weight*chi2[index[i]];
2673 Double_t normchi2 = sumchi/sumweight;
2676 //------------------------------------------------------------------------
2677 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2680 // calculate normalized chi2
2681 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2684 for (Int_t i=0;i<6;i++){
2685 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2686 Double_t sy1 = forwardtrack->GetSigmaY(i);
2687 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2688 Double_t sy2 = backtrack->GetSigmaY(i);
2689 Double_t sz2 = backtrack->GetSigmaZ(i);
2690 if (i<2){ sy2=1000.;sz2=1000;}
2692 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2693 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2695 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2696 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2698 res+= nz0*nz0+ny0*ny0;
2701 if (npoints>1) return
2702 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2703 //2*forwardtrack->fNUsed+
2704 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2705 1./(1.+forwardtrack->GetNSkipped()));
2708 //------------------------------------------------------------------------
2709 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2710 //--------------------------------------------------------------------
2711 // Return pointer to a given cluster
2712 //--------------------------------------------------------------------
2713 Int_t l=(index & 0xf0000000) >> 28;
2714 Int_t c=(index & 0x0fffffff) >> 00;
2715 return fgLayers[l].GetWeight(c);
2717 //------------------------------------------------------------------------
2718 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2720 //---------------------------------------------
2721 // register track to the list
2723 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2726 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2727 Int_t index = track->GetClusterIndex(icluster);
2728 Int_t l=(index & 0xf0000000) >> 28;
2729 Int_t c=(index & 0x0fffffff) >> 00;
2730 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2731 for (Int_t itrack=0;itrack<4;itrack++){
2732 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2733 fgLayers[l].SetClusterTracks(itrack,c,id);
2739 //------------------------------------------------------------------------
2740 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2742 //---------------------------------------------
2743 // unregister track from the list
2744 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2745 Int_t index = track->GetClusterIndex(icluster);
2746 Int_t l=(index & 0xf0000000) >> 28;
2747 Int_t c=(index & 0x0fffffff) >> 00;
2748 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2749 for (Int_t itrack=0;itrack<4;itrack++){
2750 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2751 fgLayers[l].SetClusterTracks(itrack,c,-1);
2756 //------------------------------------------------------------------------
2757 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2759 //-------------------------------------------------------------
2760 //get number of shared clusters
2761 //-------------------------------------------------------------
2763 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2764 // mean number of clusters
2765 Float_t *ny = GetNy(id), *nz = GetNz(id);
2768 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2769 Int_t index = track->GetClusterIndex(icluster);
2770 Int_t l=(index & 0xf0000000) >> 28;
2771 Int_t c=(index & 0x0fffffff) >> 00;
2772 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2773 // if (ny[l]<1.e-13){
2774 // printf("problem\n");
2776 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2780 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2781 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2782 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2784 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2787 deltan = (cl->GetNz()-nz[l]);
2789 if (deltan>2.0) continue; // extended - highly probable shared cluster
2790 weight = 2./TMath::Max(3.+deltan,2.);
2792 for (Int_t itrack=0;itrack<4;itrack++){
2793 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2795 clist[l] = (AliITSRecPoint*)GetCluster(index);
2801 track->SetNUsed(shared);
2804 //------------------------------------------------------------------------
2805 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2808 // find first shared track
2810 // mean number of clusters
2811 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2813 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2814 Int_t sharedtrack=100000;
2815 Int_t tracks[24],trackindex=0;
2816 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2818 for (Int_t icluster=0;icluster<6;icluster++){
2819 if (clusterlist[icluster]<0) continue;
2820 Int_t index = clusterlist[icluster];
2821 Int_t l=(index & 0xf0000000) >> 28;
2822 Int_t c=(index & 0x0fffffff) >> 00;
2823 // if (ny[l]<1.e-13){
2824 // printf("problem\n");
2826 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2827 //if (l>3) continue;
2828 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2831 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2832 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2833 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2835 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2838 deltan = (cl->GetNz()-nz[l]);
2840 if (deltan>2.0) continue; // extended - highly probable shared cluster
2842 for (Int_t itrack=3;itrack>=0;itrack--){
2843 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2844 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2845 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2850 if (trackindex==0) return -1;
2852 sharedtrack = tracks[0];
2854 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2857 Int_t tracks2[24], cluster[24];
2858 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2861 for (Int_t i=0;i<trackindex;i++){
2862 if (tracks[i]<0) continue;
2863 tracks2[index] = tracks[i];
2865 for (Int_t j=i+1;j<trackindex;j++){
2866 if (tracks[j]<0) continue;
2867 if (tracks[j]==tracks[i]){
2875 for (Int_t i=0;i<index;i++){
2876 if (cluster[index]>max) {
2877 sharedtrack=tracks2[index];
2884 if (sharedtrack>=100000) return -1;
2886 // make list of overlaps
2888 for (Int_t icluster=0;icluster<6;icluster++){
2889 if (clusterlist[icluster]<0) continue;
2890 Int_t index = clusterlist[icluster];
2891 Int_t l=(index & 0xf0000000) >> 28;
2892 Int_t c=(index & 0x0fffffff) >> 00;
2893 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2894 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2896 if (cl->GetNy()>2) continue;
2897 if (cl->GetNz()>2) continue;
2900 if (cl->GetNy()>3) continue;
2901 if (cl->GetNz()>3) continue;
2904 for (Int_t itrack=3;itrack>=0;itrack--){
2905 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2906 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2914 //------------------------------------------------------------------------
2915 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2917 // try to find track hypothesys without conflicts
2918 // with minimal chi2;
2919 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2920 Int_t entries1 = arr1->GetEntriesFast();
2921 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2922 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2923 Int_t entries2 = arr2->GetEntriesFast();
2924 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2926 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2927 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2928 if (track10->Pt()>0.5+track20->Pt()) return track10;
2930 for (Int_t itrack=0;itrack<entries1;itrack++){
2931 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2932 UnRegisterClusterTracks(track,trackID1);
2935 for (Int_t itrack=0;itrack<entries2;itrack++){
2936 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2937 UnRegisterClusterTracks(track,trackID2);
2941 Float_t maxconflicts=6;
2942 Double_t maxchi2 =1000.;
2944 // get weight of hypothesys - using best hypothesy
2947 Int_t list1[6],list2[6];
2948 AliITSRecPoint *clist1[6], *clist2[6] ;
2949 RegisterClusterTracks(track10,trackID1);
2950 RegisterClusterTracks(track20,trackID2);
2951 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2952 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2953 UnRegisterClusterTracks(track10,trackID1);
2954 UnRegisterClusterTracks(track20,trackID2);
2957 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2958 Float_t nerry[6],nerrz[6];
2959 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2960 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2961 for (Int_t i=0;i<6;i++){
2962 if ( (erry1[i]>0) && (erry2[i]>0)) {
2963 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2964 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2966 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2967 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2969 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2970 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2971 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2974 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2975 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2976 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2984 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2985 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2986 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2987 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2989 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2990 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2991 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2993 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2994 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2995 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2998 Double_t sumw = w1+w2;
3002 w1 = (d2+0.5)/(d1+d2+1.);
3003 w2 = (d1+0.5)/(d1+d2+1.);
3005 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
3006 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
3008 // get pair of "best" hypothesys
3010 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
3011 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
3013 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
3014 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
3015 //if (track1->fFakeRatio>0) continue;
3016 RegisterClusterTracks(track1,trackID1);
3017 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
3018 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
3020 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
3021 //if (track2->fFakeRatio>0) continue;
3023 RegisterClusterTracks(track2,trackID2);
3024 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
3025 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
3026 UnRegisterClusterTracks(track2,trackID2);
3028 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
3029 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
3030 if (nskipped>0.5) continue;
3032 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
3033 if (conflict1+1<cconflict1) continue;
3034 if (conflict2+1<cconflict2) continue;
3038 for (Int_t i=0;i<6;i++){
3040 Float_t c1 =0.; // conflict coeficients
3042 if (clist1[i]&&clist2[i]){
3045 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
3048 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
3050 c1 = 2./TMath::Max(3.+deltan,2.);
3051 c2 = 2./TMath::Max(3.+deltan,2.);
3057 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
3060 deltan = (clist1[i]->GetNz()-nz1[i]);
3062 c1 = 2./TMath::Max(3.+deltan,2.);
3069 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
3072 deltan = (clist2[i]->GetNz()-nz2[i]);
3074 c2 = 2./TMath::Max(3.+deltan,2.);
3080 if (TMath::Abs(track1->GetDy(i))>0.) {
3081 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
3082 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
3083 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
3084 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
3086 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
3089 if (TMath::Abs(track2->GetDy(i))>0.) {
3090 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
3091 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
3092 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
3093 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3096 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3098 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3099 if (chi21>0) sum+=w1;
3100 if (chi22>0) sum+=w2;
3103 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3104 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3105 Double_t normchi2 = 2*conflict+sumchi2/sum;
3106 if ( normchi2 <maxchi2 ){
3109 maxconflicts = conflict;
3113 UnRegisterClusterTracks(track1,trackID1);
3116 // if (maxconflicts<4 && maxchi2<th0){
3117 if (maxchi2<th0*2.){
3118 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3119 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3120 track1->SetChi2MIP(5,maxconflicts);
3121 track1->SetChi2MIP(6,maxchi2);
3122 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3123 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3124 track1->SetChi2MIP(8,index1);
3125 fBestTrackIndex[trackID1] =index1;
3126 UpdateESDtrack(track1, AliESDtrack::kITSin);
3128 else if (track10->GetChi2MIP(0)<th1){
3129 track10->SetChi2MIP(5,maxconflicts);
3130 track10->SetChi2MIP(6,maxchi2);
3131 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3132 UpdateESDtrack(track10,AliESDtrack::kITSin);
3135 for (Int_t itrack=0;itrack<entries1;itrack++){
3136 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3137 UnRegisterClusterTracks(track,trackID1);
3140 for (Int_t itrack=0;itrack<entries2;itrack++){
3141 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3142 UnRegisterClusterTracks(track,trackID2);
3145 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3146 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3147 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3148 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3149 RegisterClusterTracks(track10,trackID1);
3151 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3152 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3153 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3154 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3155 RegisterClusterTracks(track20,trackID2);
3160 //------------------------------------------------------------------------
3161 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3162 //--------------------------------------------------------------------
3163 // This function marks clusters assigned to the track
3164 //--------------------------------------------------------------------
3165 AliTracker::UseClusters(t,from);
3167 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3168 //if (c->GetQ()>2) c->Use();
3169 if (c->GetSigmaZ2()>0.1) c->Use();
3170 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3171 //if (c->GetQ()>2) c->Use();
3172 if (c->GetSigmaZ2()>0.1) c->Use();
3175 //------------------------------------------------------------------------
3176 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3178 //------------------------------------------------------------------
3179 // add track to the list of hypothesys
3180 //------------------------------------------------------------------
3182 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3183 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3185 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3187 array = new TObjArray(10);
3188 fTrackHypothesys.AddAt(array,esdindex);
3190 array->AddLast(track);
3192 //------------------------------------------------------------------------
3193 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3195 //-------------------------------------------------------------------
3196 // compress array of track hypothesys
3197 // keep only maxsize best hypothesys
3198 //-------------------------------------------------------------------
3199 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3200 if (! (fTrackHypothesys.At(esdindex)) ) return;
3201 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3202 Int_t entries = array->GetEntriesFast();
3204 //- find preliminary besttrack as a reference
3205 Float_t minchi2=10000;
3207 AliITStrackMI * besttrack=0;
3208 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3209 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3210 if (!track) continue;
3211 Float_t chi2 = NormalizedChi2(track,0);
3213 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3214 track->SetLabel(tpcLabel);
3216 track->SetFakeRatio(1.);
3217 CookLabel(track,0.); //For comparison only
3219 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3220 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3221 if (track->GetNumberOfClusters()<maxn) continue;
3222 maxn = track->GetNumberOfClusters();
3229 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3230 delete array->RemoveAt(itrack);
3234 if (!besttrack) return;
3237 //take errors of best track as a reference
3238 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3239 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3240 for (Int_t j=0;j<6;j++) {
3241 if (besttrack->GetClIndex(j)>=0){
3242 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3243 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3244 ny[j] = besttrack->GetNy(j);
3245 nz[j] = besttrack->GetNz(j);
3249 // calculate normalized chi2
3251 Float_t * chi2 = new Float_t[entries];
3252 Int_t * index = new Int_t[entries];
3253 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3254 for (Int_t itrack=0;itrack<entries;itrack++){
3255 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3257 AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3258 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3259 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3260 chi2[itrack] = track->GetChi2MIP(0);
3262 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3263 delete array->RemoveAt(itrack);
3269 TMath::Sort(entries,chi2,index,kFALSE);
3270 besttrack = (AliITStrackMI*)array->At(index[0]);
3271 if(besttrack) AliDebug(2,Form("ncls best track %d\n",besttrack->GetNumberOfClusters()));
3272 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3273 for (Int_t j=0;j<6;j++){
3274 if (besttrack->GetClIndex(j)>=0){
3275 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3276 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3277 ny[j] = besttrack->GetNy(j);
3278 nz[j] = besttrack->GetNz(j);
3283 // calculate one more time with updated normalized errors
3284 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3285 for (Int_t itrack=0;itrack<entries;itrack++){
3286 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3288 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3289 AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3290 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3291 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3294 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3295 delete array->RemoveAt(itrack);
3300 entries = array->GetEntriesFast();
3304 TObjArray * newarray = new TObjArray();
3305 TMath::Sort(entries,chi2,index,kFALSE);
3306 besttrack = (AliITStrackMI*)array->At(index[0]);
3308 AliDebug(2,Form("ncls best track %d %f %f\n",besttrack->GetNumberOfClusters(),besttrack->GetChi2MIP(0),chi2[index[0]]));
3310 for (Int_t j=0;j<6;j++){
3311 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3312 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3313 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3314 ny[j] = besttrack->GetNy(j);
3315 nz[j] = besttrack->GetNz(j);
3318 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3319 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3320 Float_t minn = besttrack->GetNumberOfClusters()-3;
3322 for (Int_t i=0;i<entries;i++){
3323 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3324 if (!track) continue;
3325 if (accepted>maxcut) break;
3326 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3327 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3328 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3329 delete array->RemoveAt(index[i]);
3333 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3334 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3335 if (!shortbest) accepted++;
3337 newarray->AddLast(array->RemoveAt(index[i]));
3338 for (Int_t j=0;j<6;j++){
3340 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3341 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3342 ny[j] = track->GetNy(j);
3343 nz[j] = track->GetNz(j);
3348 delete array->RemoveAt(index[i]);
3352 delete fTrackHypothesys.RemoveAt(esdindex);
3353 fTrackHypothesys.AddAt(newarray,esdindex);
3357 delete fTrackHypothesys.RemoveAt(esdindex);
3363 //------------------------------------------------------------------------
3364 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3366 //-------------------------------------------------------------
3367 // try to find best hypothesy
3368 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3369 //-------------------------------------------------------------
3370 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3371 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3372 if (!array) return 0;
3373 Int_t entries = array->GetEntriesFast();
3374 if (!entries) return 0;
3375 Float_t minchi2 = 100000;
3376 AliITStrackMI * besttrack=0;
3378 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3379 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3380 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3381 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3383 for (Int_t i=0;i<entries;i++){
3384 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3385 if (!track) continue;
3386 Float_t sigmarfi,sigmaz;
3387 GetDCASigma(track,sigmarfi,sigmaz);
3388 track->SetDnorm(0,sigmarfi);
3389 track->SetDnorm(1,sigmaz);
3391 track->SetChi2MIP(1,1000000);
3392 track->SetChi2MIP(2,1000000);
3393 track->SetChi2MIP(3,1000000);
3396 backtrack = new(backtrack) AliITStrackMI(*track);
3397 if (track->GetConstrain()) {
3398 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3399 if (AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
3400 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3402 backtrack->ResetCovariance(10.);
3404 backtrack->ResetCovariance(10.);
3406 backtrack->ResetClusters();
3408 Double_t x = original->GetX();
3409 if (!RefitAt(x,backtrack,track)) continue;
3411 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3412 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3413 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3414 track->SetChi22(GetMatchingChi2(backtrack,original));
3416 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3417 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3418 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3421 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3423 //forward track - without constraint
3424 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3425 forwardtrack->ResetClusters();
3427 RefitAt(x,forwardtrack,track);
3428 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3429 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3430 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3432 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3433 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3434 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3435 forwardtrack->SetD(0,track->GetD(0));
3436 forwardtrack->SetD(1,track->GetD(1));
3439 AliITSRecPoint* clist[6];
3440 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3441 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3444 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3445 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3446 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3447 track->SetChi2MIP(3,1000);
3450 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3452 for (Int_t ichi=0;ichi<5;ichi++){
3453 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3455 if (chi2 < minchi2){
3456 //besttrack = new AliITStrackMI(*forwardtrack);
3458 besttrack->SetLabel(track->GetLabel());
3459 besttrack->SetFakeRatio(track->GetFakeRatio());
3461 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3462 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3463 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3467 delete forwardtrack;
3469 for (Int_t i=0;i<entries;i++){
3470 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3472 if (!track) continue;
3474 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3475 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3476 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3477 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3478 delete array->RemoveAt(i);
3488 SortTrackHypothesys(esdindex,checkmax,1);
3490 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3491 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3492 besttrack = (AliITStrackMI*)array->At(0);
3493 if (!besttrack) return 0;
3494 besttrack->SetChi2MIP(8,0);
3495 fBestTrackIndex[esdindex]=0;
3496 entries = array->GetEntriesFast();
3497 AliITStrackMI *longtrack =0;
3499 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3500 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3501 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3502 if (!track->GetConstrain()) continue;
3503 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3504 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3505 if (track->GetChi2MIP(0)>4.) continue;
3506 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3509 //if (longtrack) besttrack=longtrack;
3512 AliITSRecPoint * clist[6];
3513 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3514 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3515 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3516 RegisterClusterTracks(besttrack,esdindex);
3523 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3524 if (sharedtrack>=0){
3526 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3528 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3534 if (shared>2.5) return 0;
3535 if (shared>1.0) return besttrack;
3537 // Don't sign clusters if not gold track
3539 if (!besttrack->IsGoldPrimary()) return besttrack;
3540 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3542 if (fConstraint[fPass]){
3546 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3547 for (Int_t i=0;i<6;i++){
3548 Int_t index = besttrack->GetClIndex(i);
3549 if (index<0) continue;
3550 Int_t ilayer = (index & 0xf0000000) >> 28;
3551 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3552 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3554 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3555 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3556 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3557 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3558 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3559 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3561 Bool_t cansign = kTRUE;
3562 for (Int_t itrack=0;itrack<entries; itrack++){
3563 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3564 if (!track) continue;
3565 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3566 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3572 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3573 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3574 if (!c->IsUsed()) c->Use();
3580 //------------------------------------------------------------------------
3581 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3584 // get "best" hypothesys
3587 Int_t nentries = itsTracks.GetEntriesFast();
3588 for (Int_t i=0;i<nentries;i++){
3589 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3590 if (!track) continue;
3591 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3592 if (!array) continue;
3593 if (array->GetEntriesFast()<=0) continue;
3595 AliITStrackMI* longtrack=0;
3597 Float_t maxchi2=1000;
3598 for (Int_t j=0;j<array->GetEntriesFast();j++){
3599 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3600 if (!trackHyp) continue;
3601 if (trackHyp->GetGoldV0()) {
3602 longtrack = trackHyp; //gold V0 track taken
3605 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3606 Float_t chi2 = trackHyp->GetChi2MIP(0);
3608 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3610 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3612 if (chi2 > maxchi2) continue;
3613 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3620 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3621 if (!longtrack) {longtrack = besttrack;}
3622 else besttrack= longtrack;
3626 AliITSRecPoint * clist[6];
3627 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3629 track->SetNUsed(shared);
3630 track->SetNSkipped(besttrack->GetNSkipped());
3631 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3633 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3637 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3638 //if (sharedtrack==-1) sharedtrack=0;
3639 if (sharedtrack>=0) {
3640 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3643 if (besttrack&&fAfterV0) {
3644 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3646 if (besttrack&&fConstraint[fPass])
3647 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3648 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3649 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3650 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3656 //------------------------------------------------------------------------
3657 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3658 //--------------------------------------------------------------------
3659 //This function "cooks" a track label. If label<0, this track is fake.
3660 //--------------------------------------------------------------------
3663 if (track->GetESDtrack()){
3664 tpcLabel = track->GetESDtrack()->GetTPCLabel();
3665 ULong_t trStatus=track->GetESDtrack()->GetStatus();
3666 if(!(trStatus&AliESDtrack::kTPCin)) tpcLabel=track->GetLabel(); // for ITSsa tracks
3668 track->SetChi2MIP(9,0);
3670 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3671 Int_t cindex = track->GetClusterIndex(i);
3672 Int_t l=(cindex & 0xf0000000) >> 28;
3673 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3675 for (Int_t ind=0;ind<3;ind++){
3676 if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
3677 //AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3679 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3682 Int_t nclusters = track->GetNumberOfClusters();
3683 if (nclusters > 0) //PH Some tracks don't have any cluster
3684 track->SetFakeRatio(double(nwrong)/double(nclusters));
3685 if (tpcLabel>0 && track->GetFakeRatio()>wrong) {
3686 track->SetLabel(-tpcLabel);
3688 track->SetLabel(tpcLabel);
3690 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3693 //------------------------------------------------------------------------
3694 void AliITStrackerMI::CookdEdx(AliITStrackMI* track){
3696 // Fill the dE/dx in this track
3698 track->SetChi2MIP(9,0);
3699 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3700 Int_t cindex = track->GetClusterIndex(i);
3701 Int_t l=(cindex & 0xf0000000) >> 28;
3702 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3703 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3705 for (Int_t ind=0;ind<3;ind++){
3706 if (cl->GetLabel(ind)==lab) isWrong=0;
3708 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3712 track->CookdEdx(low,up);
3714 //------------------------------------------------------------------------
3715 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3717 // Create some arrays
3719 if (fCoefficients) delete []fCoefficients;
3720 fCoefficients = new Float_t[ntracks*48];
3721 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3723 //------------------------------------------------------------------------
3724 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3727 // Compute predicted chi2
3729 // Take into account the mis-alignment (bring track to cluster plane)
3730 Double_t xTrOrig=track->GetX();
3731 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3732 Float_t erry,errz,covyz;
3733 Float_t theta = track->GetTgl();
3734 Float_t phi = track->GetSnp();
3735 phi *= TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3736 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
3737 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()));
3738 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()));
3739 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
3740 // Bring the track back to detector plane in ideal geometry
3741 // [mis-alignment will be accounted for in UpdateMI()]
3742 if (!track->Propagate(xTrOrig)) return 1000.;
3744 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3745 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3747 chi2+=0.5*TMath::Min(delta/2,2.);
3748 chi2+=2.*cluster->GetDeltaProbability();
3751 track->SetNy(layer,ny);
3752 track->SetNz(layer,nz);
3753 track->SetSigmaY(layer,erry);
3754 track->SetSigmaZ(layer, errz);
3755 track->SetSigmaYZ(layer,covyz);
3756 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3757 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3761 //------------------------------------------------------------------------
3762 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3767 Int_t layer = (index & 0xf0000000) >> 28;
3768 track->SetClIndex(layer, index);
3769 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3770 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3771 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3772 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3776 if (TMath::Abs(cl->GetQ())<1.e-13) return 0; // ingore the "virtual" clusters
3779 // Take into account the mis-alignment (bring track to cluster plane)
3780 Double_t xTrOrig=track->GetX();
3781 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3782 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3783 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3784 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3786 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3789 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3790 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3791 c.SetSigmaYZ(track->GetSigmaYZ(layer));
3794 Int_t updated = track->UpdateMI(&c,chi2,index);
3795 // Bring the track back to detector plane in ideal geometry
3796 if (!track->Propagate(xTrOrig)) return 0;
3798 if(!updated) AliDebug(2,"update failed");
3802 //------------------------------------------------------------------------
3803 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3806 //DCA sigmas parameterization
3807 //to be paramterized using external parameters in future
3810 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3811 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3813 //------------------------------------------------------------------------
3814 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3817 // Clusters from delta electrons?
3819 Int_t entries = clusterArray->GetEntriesFast();
3820 if (entries<4) return;
3821 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3822 Int_t layer = cluster->GetLayer();
3823 if (layer>1) return;
3825 Int_t ncandidates=0;
3826 Float_t r = (layer>0)? 7:4;
3828 for (Int_t i=0;i<entries;i++){
3829 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3830 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3831 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3832 index[ncandidates] = i; //candidate to belong to delta electron track
3834 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3835 cl0->SetDeltaProbability(1);
3841 for (Int_t i=0;i<ncandidates;i++){
3842 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3843 if (cl0->GetDeltaProbability()>0.8) continue;
3846 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3847 sumy=sumz=sumy2=sumyz=sumw=0.0;
3848 for (Int_t j=0;j<ncandidates;j++){
3850 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3852 Float_t dz = cl0->GetZ()-cl1->GetZ();
3853 Float_t dy = cl0->GetY()-cl1->GetY();
3854 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3855 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3856 y[ncl] = cl1->GetY();
3857 z[ncl] = cl1->GetZ();
3858 sumy+= y[ncl]*weight;
3859 sumz+= z[ncl]*weight;
3860 sumy2+=y[ncl]*y[ncl]*weight;
3861 sumyz+=y[ncl]*z[ncl]*weight;
3866 if (ncl<4) continue;
3867 Float_t det = sumw*sumy2 - sumy*sumy;
3869 if (TMath::Abs(det)>0.01){
3870 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3871 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3872 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3875 Float_t z0 = sumyz/sumy;
3876 delta = TMath::Abs(cl0->GetZ()-z0);
3879 cl0->SetDeltaProbability(1-20.*delta);
3883 //------------------------------------------------------------------------
3884 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3889 track->UpdateESDtrack(flags);
3890 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3891 if (oldtrack) delete oldtrack;
3892 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3893 // if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3894 // printf("Problem\n");
3897 //------------------------------------------------------------------------
3898 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3900 // Get nearest upper layer close to the point xr.
3901 // rough approximation
3903 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3904 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3906 for (Int_t i=0;i<6;i++){
3907 if (radius<kRadiuses[i]){
3914 //------------------------------------------------------------------------
3915 void AliITStrackerMI::BuildMaterialLUT(TString material) {
3916 //--------------------------------------------------------------------
3917 // Fill a look-up table with mean material
3918 //--------------------------------------------------------------------
3922 Double_t point1[3],point2[3];
3923 Double_t phi,cosphi,sinphi,z;
3924 // 0-5 layers, 6 pipe, 7-8 shields
3925 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
3926 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
3928 Int_t ifirst=0,ilast=0;
3929 if(material.Contains("Pipe")) {
3931 } else if(material.Contains("Shields")) {
3933 } else if(material.Contains("Layers")) {
3936 Error("BuildMaterialLUT","Wrong layer name\n");
3939 for(Int_t imat=ifirst; imat<=ilast; imat++) {
3940 Double_t param[5]={0.,0.,0.,0.,0.};
3941 for (Int_t i=0; i<n; i++) {
3942 phi = 2.*TMath::Pi()*gRandom->Rndm();
3943 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
3944 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
3945 point1[0] = rmin[imat]*cosphi;
3946 point1[1] = rmin[imat]*sinphi;
3948 point2[0] = rmax[imat]*cosphi;
3949 point2[1] = rmax[imat]*sinphi;
3951 AliTracker::MeanMaterialBudget(point1,point2,mparam);
3952 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
3954 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
3956 fxOverX0Layer[imat] = param[1];
3957 fxTimesRhoLayer[imat] = param[0]*param[4];
3958 } else if(imat==6) {
3959 fxOverX0Pipe = param[1];
3960 fxTimesRhoPipe = param[0]*param[4];
3961 } else if(imat==7) {
3962 fxOverX0Shield[0] = param[1];
3963 fxTimesRhoShield[0] = param[0]*param[4];
3964 } else if(imat==8) {
3965 fxOverX0Shield[1] = param[1];
3966 fxTimesRhoShield[1] = param[0]*param[4];
3970 printf("%s\n",material.Data());
3971 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
3972 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
3973 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
3974 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
3975 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
3976 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
3977 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
3978 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
3979 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
3983 //------------------------------------------------------------------------
3984 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
3985 TString direction) {
3986 //-------------------------------------------------------------------
3987 // Propagate beyond beam pipe and correct for material
3988 // (material budget in different ways according to fUseTGeo value)
3989 // Add time if going outward (PropagateTo or PropagateToTGeo)
3990 //-------------------------------------------------------------------
3992 // Define budget mode:
3993 // 0: material from AliITSRecoParam (hard coded)
3994 // 1: material from TGeo in one step (on the fly)
3995 // 2: material from lut
3996 // 3: material from TGeo in one step (same for all hypotheses)
4009 if(fTrackingPhase.Contains("Clusters2Tracks"))
4010 { mode=3; } else { mode=1; }
4013 if(fTrackingPhase.Contains("Clusters2Tracks"))
4014 { mode=3; } else { mode=2; }
4020 if(fTrackingPhase.Contains("Default")) mode=0;
4022 Int_t index=fCurrentEsdTrack;
4024 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4025 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4027 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4029 Double_t xOverX0,x0,lengthTimesMeanDensity;
4033 xOverX0 = AliITSRecoParam::GetdPipe();
4034 x0 = AliITSRecoParam::GetX0Be();
4035 lengthTimesMeanDensity = xOverX0*x0;
4036 lengthTimesMeanDensity *= dir;
4037 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4040 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4043 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4044 xOverX0 = fxOverX0Pipe;
4045 lengthTimesMeanDensity = fxTimesRhoPipe;
4046 lengthTimesMeanDensity *= dir;
4047 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4050 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4051 if(fxOverX0PipeTrks[index]<0) {
4052 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4053 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4054 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4055 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4056 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4059 xOverX0 = fxOverX0PipeTrks[index];
4060 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4061 lengthTimesMeanDensity *= dir;
4062 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4068 //------------------------------------------------------------------------
4069 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4071 TString direction) {
4072 //-------------------------------------------------------------------
4073 // Propagate beyond SPD or SDD shield and correct for material
4074 // (material budget in different ways according to fUseTGeo value)
4075 // Add time if going outward (PropagateTo or PropagateToTGeo)
4076 //-------------------------------------------------------------------
4078 // Define budget mode:
4079 // 0: material from AliITSRecoParam (hard coded)
4080 // 1: material from TGeo in steps of X cm (on the fly)
4081 // X = AliITSRecoParam::GetStepSizeTGeo()
4082 // 2: material from lut
4083 // 3: material from TGeo in one step (same for all hypotheses)
4096 if(fTrackingPhase.Contains("Clusters2Tracks"))
4097 { mode=3; } else { mode=1; }
4100 if(fTrackingPhase.Contains("Clusters2Tracks"))
4101 { mode=3; } else { mode=2; }
4107 if(fTrackingPhase.Contains("Default")) mode=0;
4109 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4111 Int_t shieldindex=0;
4112 if (shield.Contains("SDD")) { // SDDouter
4113 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4115 } else if (shield.Contains("SPD")) { // SPDouter
4116 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4119 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4123 // do nothing if we are already beyond the shield
4124 Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4125 if(dir<0 && rTrack > rToGo) return 1; // going outward
4126 if(dir>0 && rTrack < rToGo) return 1; // going inward
4130 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4132 Int_t index=2*fCurrentEsdTrack+shieldindex;
4134 Double_t xOverX0,x0,lengthTimesMeanDensity;
4139 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4140 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4141 lengthTimesMeanDensity = xOverX0*x0;
4142 lengthTimesMeanDensity *= dir;
4143 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4146 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4147 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4150 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4151 xOverX0 = fxOverX0Shield[shieldindex];
4152 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4153 lengthTimesMeanDensity *= dir;
4154 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4157 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4158 if(fxOverX0ShieldTrks[index]<0) {
4159 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4160 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4161 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4162 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4163 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4166 xOverX0 = fxOverX0ShieldTrks[index];
4167 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4168 lengthTimesMeanDensity *= dir;
4169 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4175 //------------------------------------------------------------------------
4176 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4178 Double_t oldGlobXYZ[3],
4179 TString direction) {
4180 //-------------------------------------------------------------------
4181 // Propagate beyond layer 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 stepsof 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 Double_t r=fgLayers[layerindex].GetR();
4220 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4222 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4224 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4226 Int_t index=6*fCurrentEsdTrack+layerindex;
4229 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4232 // back before material (no correction)
4234 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4235 if (!t->GetLocalXat(rOld,xOld)) return 0;
4236 if (!t->Propagate(xOld)) return 0;
4240 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4241 lengthTimesMeanDensity = xOverX0*x0;
4242 lengthTimesMeanDensity *= dir;
4243 // Bring the track beyond the material
4244 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4247 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4248 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4251 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4252 xOverX0 = fxOverX0Layer[layerindex];
4253 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4254 lengthTimesMeanDensity *= dir;
4255 // Bring the track beyond the material
4256 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4259 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4260 if(fxOverX0LayerTrks[index]<0) {
4261 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4262 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4263 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4264 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4265 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4266 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4269 xOverX0 = fxOverX0LayerTrks[index];
4270 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4271 lengthTimesMeanDensity *= dir;
4272 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4279 //------------------------------------------------------------------------
4280 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4281 //-----------------------------------------------------------------
4282 // Initialize LUT for storing material for each prolonged track
4283 //-----------------------------------------------------------------
4284 fxOverX0PipeTrks = new Float_t[ntracks];
4285 fxTimesRhoPipeTrks = new Float_t[ntracks];
4286 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4287 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4288 fxOverX0LayerTrks = new Float_t[ntracks*6];
4289 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4291 for(Int_t i=0; i<ntracks; i++) {
4292 fxOverX0PipeTrks[i] = -1.;
4293 fxTimesRhoPipeTrks[i] = -1.;
4295 for(Int_t j=0; j<ntracks*2; j++) {
4296 fxOverX0ShieldTrks[j] = -1.;
4297 fxTimesRhoShieldTrks[j] = -1.;
4299 for(Int_t k=0; k<ntracks*6; k++) {
4300 fxOverX0LayerTrks[k] = -1.;
4301 fxTimesRhoLayerTrks[k] = -1.;
4308 //------------------------------------------------------------------------
4309 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4310 //-----------------------------------------------------------------
4311 // Delete LUT for storing material for each prolonged track
4312 //-----------------------------------------------------------------
4313 if(fxOverX0PipeTrks) {
4314 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4316 if(fxOverX0ShieldTrks) {
4317 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4320 if(fxOverX0LayerTrks) {
4321 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4323 if(fxTimesRhoPipeTrks) {
4324 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4326 if(fxTimesRhoShieldTrks) {
4327 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4329 if(fxTimesRhoLayerTrks) {
4330 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4334 //------------------------------------------------------------------------
4335 void AliITStrackerMI::SetForceSkippingOfLayer() {
4336 //-----------------------------------------------------------------
4337 // Check if we are forced to skip layers
4338 // either we set to skip them in RecoParam
4339 // or they were off during data-taking
4340 //-----------------------------------------------------------------
4342 const AliEventInfo *eventInfo = GetEventInfo();
4344 for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
4345 fForceSkippingOfLayer[l] = 0;
4347 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
4351 AliITSReconstructor::GetRecoParam()->GetSkipSubdetsNotInTriggerCluster()) {
4352 AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
4354 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
4355 } else if(l==2 || l==3) {
4356 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1;
4358 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
4364 //------------------------------------------------------------------------
4365 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4366 Int_t ilayer,Int_t idet) const {
4367 //-----------------------------------------------------------------
4368 // This method is used to decide whether to allow a prolongation
4369 // without clusters, because we want to skip the layer.
4370 // In this case the return value is > 0:
4371 // return 1: the user requested to skip a layer
4372 // return 2: track outside z acceptance
4373 //-----------------------------------------------------------------
4375 if (ForceSkippingOfLayer(ilayer)) return 1;
4377 Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
4379 if (idet<0 && // out in z
4380 ilayer>innerLayCanSkip &&
4381 AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4382 // check if track will cross SPD outer layer
4383 Double_t phiAtSPD2,zAtSPD2;
4384 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4385 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4387 return 2; // always allow skipping, changed on 05.11.2009
4392 //------------------------------------------------------------------------
4393 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4394 Int_t ilayer,Int_t idet,
4395 Double_t dz,Double_t dy,
4396 Bool_t noClusters) const {
4397 //-----------------------------------------------------------------
4398 // This method is used to decide whether to allow a prolongation
4399 // without clusters, because there is a dead zone in the road.
4400 // In this case the return value is > 0:
4401 // return 1: dead zone at z=0,+-7cm in SPD
4402 // This method assumes that fSPDdetzcentre is ordered from -z to +z
4403 // return 2: all road is "bad" (dead or noisy) from the OCDB
4404 // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4405 // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4406 //-----------------------------------------------------------------
4408 // check dead zones at z=0,+-7cm in the SPD
4409 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4410 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4411 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4412 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4413 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4414 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4415 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4416 for (Int_t i=0; i<3; i++)
4417 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4418 AliDebug(2,Form("crack SPD %d track z %f %f %f %f\n",ilayer,track->GetZ(),dz,zmaxdead[i],zmindead[i]));
4419 if (GetSPDDeadZoneProbability(track->GetZ(),TMath::Sqrt(track->GetSigmaZ2()))>0.1) return 1;
4423 // check bad zones from OCDB
4424 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4426 if (idet<0) return 0;
4428 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4431 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4432 if (ilayer==0 || ilayer==1) { // ---------- SPD
4434 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4436 detSizeFactorX *= 2.;
4437 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4440 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4441 if (detType==2) segm->SetLayer(ilayer+1);
4442 Float_t detSizeX = detSizeFactorX*segm->Dx();
4443 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4445 // check if the road overlaps with bad chips
4447 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
4448 Float_t zlocmin = zloc-dz;
4449 Float_t zlocmax = zloc+dz;
4450 Float_t xlocmin = xloc-dy;
4451 Float_t xlocmax = xloc+dy;
4452 Int_t chipsInRoad[100];
4454 // check if road goes out of detector
4455 Bool_t touchNeighbourDet=kFALSE;
4456 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4457 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4458 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4459 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4460 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));
4462 // check if this detector is bad
4464 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4465 if(!touchNeighbourDet) {
4466 return 2; // all detectors in road are bad
4468 return 3; // at least one is bad
4472 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4473 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4474 if (!nChipsInRoad) return 0;
4476 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4477 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4478 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4479 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4480 if (det.IsChipBad(chipsInRoad[iCh])) {
4488 if(!touchNeighbourDet) {
4489 AliDebug(2,"all bad in road");
4490 return 2; // all chips in road are bad
4492 return 3; // at least a bad chip in road
4497 AliDebug(2,"at least a bad in road");
4498 return 3; // at least a bad chip in road
4502 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4503 || !noClusters) return 0;
4505 // There are no clusters in road: check if there is at least
4506 // a bad SPD pixel or SDD anode or SSD strips on both sides
4508 Int_t idetInITS=idet;
4509 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4511 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4512 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4515 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4519 //------------------------------------------------------------------------
4520 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4521 const AliITStrackMI *track,
4522 Float_t &xloc,Float_t &zloc) const {
4523 //-----------------------------------------------------------------
4524 // Gives position of track in local module ref. frame
4525 //-----------------------------------------------------------------
4530 if(idet<0) return kTRUE; // track out of z acceptance of layer
4532 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4534 Int_t lad = Int_t(idet/ndet) + 1;
4536 Int_t det = idet - (lad-1)*ndet + 1;
4538 Double_t xyzGlob[3],xyzLoc[3];
4540 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4541 // take into account the misalignment: xyz at real detector plane
4542 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4544 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4546 xloc = (Float_t)xyzLoc[0];
4547 zloc = (Float_t)xyzLoc[2];
4551 //------------------------------------------------------------------------
4552 //------------------------------------------------------------------------
4553 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
4555 // Method to be optimized further:
4556 // Aim: decide whether a track can be used for PlaneEff evaluation
4557 // the decision is taken based on the track quality at the layer under study
4558 // no information on the clusters on this layer has to be used
4559 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4560 // the cut is done on number of sigmas from the boundaries
4562 // Input: Actual track, layer [0,5] under study
4564 // Return: kTRUE if this is a good track
4566 // it will apply a pre-selection to obtain good quality tracks.
4567 // Here also you will have the possibility to put a control on the
4568 // impact point of the track on the basic block, in order to exclude border regions
4569 // this will be done by calling a proper method of the AliITSPlaneEff class.
4571 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4572 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4574 Int_t index[AliITSgeomTGeo::kNLayers];
4576 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4578 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4579 index[k]=clusters[k];
4583 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4584 AliITSlayer &layer=fgLayers[ilayer];
4585 Double_t r=layer.GetR();
4586 AliITStrackMI tmp(*track);
4588 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4589 Int_t ncl_out=0; Int_t ncl_in=0;
4590 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) { // count n. of cluster in outermost layers
4591 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4592 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4593 // if (tmp.GetClIndex(lay)>=0) ncl_out++;
4594 if(index[lay]>=0)ncl_out++;
4596 for(Int_t lay=ilayer-1; lay>=0;lay--) { // count n. of cluster in innermost layers
4597 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4598 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4599 if (index[lay]>=0) ncl_in++;
4601 Int_t ncl=ncl_out+ncl_in;
4602 Bool_t nextout = kFALSE;
4603 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4604 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4605 Bool_t nextin = kFALSE;
4606 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4607 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4608 // maximum number of missing clusters allowed in outermost layers
4609 if(ncl_out<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersOutPlaneEff())
4611 // maximum number of missing clusters allowed (both in innermost and in outermost layers)
4612 if(ncl<AliITSgeomTGeo::kNLayers-1-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
4614 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
4615 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
4616 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
4617 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
4621 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4622 Int_t idet=layer.FindDetectorIndex(phi,z);
4623 if(idet<0) { AliInfo(Form("cannot find detector"));
4626 // here check if it has good Chi Square.
4628 //propagate to the intersection with the detector plane
4629 const AliITSdetector &det=layer.GetDetector(idet);
4630 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4634 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
4635 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4636 if(key>fPlaneEff->Nblock()) return kFALSE;
4637 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4638 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4640 // DEFINITION OF SEARCH ROAD FOR accepting a track
4642 Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXFromBoundaryPlaneEff();
4643 Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZFromBoundaryPlaneEff();
4644 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4645 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4646 // done for RecPoints
4648 // exclude tracks at boundary between detectors
4649 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
4650 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4651 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
4652 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
4653 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
4654 if ( (locx-dx < blockXmn+boundaryWidth) ||
4655 (locx+dx > blockXmx-boundaryWidth) ||
4656 (locz-dz < blockZmn+boundaryWidth) ||
4657 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
4660 //------------------------------------------------------------------------
4661 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
4663 // This Method has to be optimized! For the time-being it uses the same criteria
4664 // as those used in the search of extra clusters for overlapping modules.
4666 // Method Purpose: estabilish whether a track has produced a recpoint or not
4667 // in the layer under study (For Plane efficiency)
4669 // inputs: AliITStrackMI* track (pointer to a usable track)
4671 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
4672 // traversed by this very track. In details:
4673 // - if a cluster can be associated to the track then call
4674 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
4675 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
4678 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
4679 AliITSlayer &layer=fgLayers[ilayer];
4680 Double_t r=layer.GetR();
4681 AliITStrackMI tmp(*track);
4685 if (!tmp.GetPhiZat(r,phi,z)) return;
4686 Int_t idet=layer.FindDetectorIndex(phi,z);
4688 if(idet<0) { AliInfo(Form("cannot find detector"));
4692 //propagate to the intersection with the detector plane
4693 const AliITSdetector &det=layer.GetDetector(idet);
4694 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
4698 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
4700 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
4701 TMath::Sqrt(tmp.GetSigmaZ2() +
4702 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4703 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4704 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
4705 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
4706 TMath::Sqrt(tmp.GetSigmaY2() +
4707 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4708 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4709 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
4711 // road in global (rphi,z) [i.e. in tracking ref. system]
4712 Double_t zmin = tmp.GetZ() - dz;
4713 Double_t zmax = tmp.GetZ() + dz;
4714 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
4715 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
4717 // select clusters in road
4718 layer.SelectClusters(zmin,zmax,ymin,ymax);
4720 // Define criteria for track-cluster association
4721 Double_t msz = tmp.GetSigmaZ2() +
4722 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4723 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4724 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
4725 Double_t msy = tmp.GetSigmaY2() +
4726 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4727 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4728 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
4729 if (tmp.GetConstrain()) {
4730 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
4731 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
4733 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
4734 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
4736 msz = 1./msz; // 1/RoadZ^2
4737 msy = 1./msy; // 1/RoadY^2
4740 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
4742 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
4743 //Double_t tolerance=0.2;
4744 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
4745 idetc = cl->GetDetectorIndex();
4746 if(idet!=idetc) continue;
4747 //Int_t ilay = cl->GetLayer();
4749 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
4750 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
4752 Double_t chi2=tmp.GetPredictedChi2(cl);
4753 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
4757 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
4759 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
4760 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4761 if(key>fPlaneEff->Nblock()) return;
4762 Bool_t found=kFALSE;
4765 while ((cl=layer.GetNextCluster(clidx))!=0) {
4766 idetc = cl->GetDetectorIndex();
4767 if(idet!=idetc) continue;
4768 // here real control to see whether the cluster can be associated to the track.
4769 // cluster not associated to track
4770 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
4771 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
4772 // calculate track-clusters chi2
4773 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
4774 // in particular, the error associated to the cluster
4775 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
4777 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
4779 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
4780 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
4781 // track->SetExtraModule(ilayer,idetExtra);
4783 if(!fPlaneEff->UpDatePlaneEff(found,key))
4784 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
4785 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
4786 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
4787 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
4788 Int_t cltype[2]={-999,-999};
4791 Float_t AngleModTrack[3]={99999.,99999.,99999.}; // angles (phi, z and "absolute angle") between the track and the mormal to the module (see below)
4795 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4796 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4799 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
4800 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
4801 cltype[0]=layer.GetCluster(ci)->GetNy();
4802 cltype[1]=layer.GetCluster(ci)->GetNz();
4804 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
4805 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
4806 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
4807 // It is computed properly by calling the method
4808 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4810 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
4811 //if (tmp.PropagateTo(x,0.,0.)) {
4812 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
4813 AliCluster c(*layer.GetCluster(ci));
4814 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
4815 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
4816 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
4817 clu[2]=TMath::Sqrt(c.GetSigmaY2());
4818 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
4821 // Compute the angles between the track and the module
4822 // compute the angle "in phi direction", i.e. the angle in the transverse plane
4823 // between the normal to the module and the projection (in the transverse plane) of the
4825 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
4826 Float_t tgl = tmp.GetTgl();
4827 Float_t phitr = tmp.GetSnp();
4828 phitr = TMath::ASin(phitr);
4829 Int_t volId = AliGeomManager::LayerToVolUIDSafe(ilayer+1 ,idet );
4831 Double_t tra[3]; AliGeomManager::GetOrigTranslation(volId,tra);
4832 Double_t rot[9]; AliGeomManager::GetOrigRotation(volId,rot);
4834 alpha = tmp.GetAlpha();
4835 Double_t phiglob = alpha+phitr;
4837 p[0] = TMath::Cos(phiglob);
4838 p[1] = TMath::Sin(phiglob);
4840 TVector3 pvec(p[0],p[1],p[2]);
4841 TVector3 normvec(rot[1],rot[4],rot[7]);
4842 Double_t angle = pvec.Angle(normvec);
4844 if(angle>0.5*TMath::Pi()) angle = (TMath::Pi()-angle);
4845 angle *= 180./TMath::Pi();
4848 TVector3 pt(p[0],p[1],0);
4849 TVector3 normt(rot[1],rot[4],0);
4850 Double_t anglet = pt.Angle(normt);
4852 Double_t phiPt = TMath::ATan2(p[1],p[0]);
4853 if(phiPt<0)phiPt+=2.*TMath::Pi();
4854 Double_t phiNorm = TMath::ATan2(rot[4],rot[1]);
4855 if(phiNorm<0) phiNorm+=2.*TMath::Pi();
4856 if(anglet>0.5*TMath::Pi()) anglet = (TMath::Pi()-anglet);
4857 if(phiNorm>phiPt) anglet*=-1.;// pt-->normt clockwise: anglet>0
4858 if((phiNorm-phiPt)>TMath::Pi()) anglet*=-1.;
4859 anglet *= 180./TMath::Pi();
4861 AngleModTrack[2]=(Float_t) angle;
4862 AngleModTrack[0]=(Float_t) anglet;
4863 // now the "angle in z" (much easier, i.e. the angle between the z axis and the track momentum + 90)
4864 AngleModTrack[1]=TMath::ACos(tgl/TMath::Sqrt(tgl*tgl+1.));
4865 AngleModTrack[1]-=TMath::Pi()/2.; // range of angle is -pi/2 , pi/2
4866 AngleModTrack[1]*=180./TMath::Pi(); // in degree
4868 fPlaneEff->FillHistos(key,found,tr,clu,cltype,AngleModTrack);