1 /**************************************************************************
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 //-------------------------------------------------------------------------
18 // Implementation of the ITS tracker class
19 // It reads AliITSRecPoint clusters and creates AliITStrackMI tracks
20 // and fills with them the ESD
21 // Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch
22 // Current support and development:
23 // Andrea Dainese, andrea.dainese@lnl.infn.it
24 // dE/dx analysis by: Boris Batyunya, JINR, Boris.Batiounia@cern.ch
25 // Params moved to AliITSRecoParam by: Andrea Dainese, INFN
26 // Material budget from TGeo by: Ludovic Gaudichet & Andrea Dainese, INFN
27 //-------------------------------------------------------------------------
31 #include <TDatabasePDG.h>
34 #include <TTreeStream.h>
37 #include "AliGeomManager.h"
38 #include "AliITSPlaneEff.h"
39 #include "AliTrackPointArray.h"
40 #include "AliESDEvent.h"
41 #include "AliESDtrack.h"
43 #include "AliITSChannelStatus.h"
44 #include "AliITSDetTypeRec.h"
45 #include "AliITSRecPoint.h"
46 #include "AliITSRecPointContainer.h"
47 #include "AliITSgeomTGeo.h"
48 #include "AliITSReconstructor.h"
49 #include "AliITSClusterParam.h"
50 #include "AliITSsegmentation.h"
51 #include "AliITSCalibration.h"
52 #include "AliITSPlaneEffSPD.h"
53 #include "AliITSPlaneEffSDD.h"
54 #include "AliITSPlaneEffSSD.h"
55 #include "AliITSV0Finder.h"
56 #include "AliITStrackerMI.h"
57 #include "AliMathBase.h"
59 ClassImp(AliITStrackerMI)
61 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
63 AliITStrackerMI::AliITStrackerMI():AliTracker(),
73 fLastLayerToTrackTo(0),
76 fTrackingPhase("Default"),
82 fxTimesRhoPipeTrks(0),
83 fxOverX0ShieldTrks(0),
84 fxTimesRhoShieldTrks(0),
86 fxTimesRhoLayerTrks(0),
93 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
94 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
95 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
98 //------------------------------------------------------------------------
99 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
100 fI(AliITSgeomTGeo::GetNLayers()),
109 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
112 fTrackingPhase("Default"),
118 fxTimesRhoPipeTrks(0),
119 fxOverX0ShieldTrks(0),
120 fxTimesRhoShieldTrks(0),
121 fxOverX0LayerTrks(0),
122 fxTimesRhoLayerTrks(0),
124 fITSChannelStatus(0),
127 //--------------------------------------------------------------------
128 //This is the AliITStrackerMI constructor
129 //--------------------------------------------------------------------
131 AliWarning("\"geom\" is actually a dummy argument !");
134 fOriginal.SetOwner();
138 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
139 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
140 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
142 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
143 AliITSgeomTGeo::GetTranslation(i,1,1,xyz);
144 Double_t poff=TMath::ATan2(y,x);
147 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
148 Double_t r=TMath::Sqrt(x*x + y*y);
150 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
151 r += TMath::Sqrt(x*x + y*y);
152 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
153 r += TMath::Sqrt(x*x + y*y);
154 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
155 r += TMath::Sqrt(x*x + y*y);
158 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
160 for (Int_t j=1; j<nlad+1; j++) {
161 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
162 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
163 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
165 Double_t txyz[3]={0.};
166 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
167 m.LocalToMaster(txyz,xyz);
168 r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
169 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
171 if (phi<0) phi+=TMath::TwoPi();
172 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
174 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
175 new(&det) AliITSdetector(r,phi);
176 // compute the real radius (with misalignment)
177 TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
179 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
180 mmisal.LocalToMaster(txyz,xyz);
181 Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
182 det.SetRmisal(rmisal);
184 } // end loop on detectors
185 } // end loop on ladders
186 fForceSkippingOfLayer[i] = 0;
187 } // end loop on layers
190 fI=AliITSgeomTGeo::GetNLayers();
193 fConstraint[0]=1; fConstraint[1]=0;
195 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
196 AliITSReconstructor::GetRecoParam()->GetYVdef(),
197 AliITSReconstructor::GetRecoParam()->GetZVdef()};
198 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
199 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
200 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
201 SetVertex(xyzVtx,ersVtx);
203 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
204 for (Int_t i=0;i<100000;i++){
205 fBestTrackIndex[i]=0;
208 // store positions of centre of SPD modules (in z)
209 // The convetion is that fSPDdetzcentre is ordered from -z to +z
211 if (tr[2]<0) { // old geom (up to v5asymmPPR)
212 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
213 fSPDdetzcentre[0] = tr[2];
214 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
215 fSPDdetzcentre[1] = tr[2];
216 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
217 fSPDdetzcentre[2] = tr[2];
218 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
219 fSPDdetzcentre[3] = tr[2];
220 } else { // new geom (from v11Hybrid)
221 AliITSgeomTGeo::GetTranslation(1,1,4,tr);
222 fSPDdetzcentre[0] = tr[2];
223 AliITSgeomTGeo::GetTranslation(1,1,3,tr);
224 fSPDdetzcentre[1] = tr[2];
225 AliITSgeomTGeo::GetTranslation(1,1,2,tr);
226 fSPDdetzcentre[2] = tr[2];
227 AliITSgeomTGeo::GetTranslation(1,1,1,tr);
228 fSPDdetzcentre[3] = tr[2];
231 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
232 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
233 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
237 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
238 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
240 if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0)
241 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
243 // only for plane efficiency evaluation
244 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
245 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
246 Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
247 if(!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)==1)
248 AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
249 if (iplane<2) fPlaneEff = new AliITSPlaneEffSPD();
250 else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
251 else fPlaneEff = new AliITSPlaneEffSSD();
252 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
253 if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
254 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
257 //------------------------------------------------------------------------
258 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
260 fBestTrack(tracker.fBestTrack),
261 fTrackToFollow(tracker.fTrackToFollow),
262 fTrackHypothesys(tracker.fTrackHypothesys),
263 fBestHypothesys(tracker.fBestHypothesys),
264 fOriginal(tracker.fOriginal),
265 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
266 fPass(tracker.fPass),
267 fAfterV0(tracker.fAfterV0),
268 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
269 fCoefficients(tracker.fCoefficients),
271 fTrackingPhase(tracker.fTrackingPhase),
272 fUseTGeo(tracker.fUseTGeo),
273 fNtracks(tracker.fNtracks),
274 fxOverX0Pipe(tracker.fxOverX0Pipe),
275 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
277 fxTimesRhoPipeTrks(0),
278 fxOverX0ShieldTrks(0),
279 fxTimesRhoShieldTrks(0),
280 fxOverX0LayerTrks(0),
281 fxTimesRhoLayerTrks(0),
282 fDebugStreamer(tracker.fDebugStreamer),
283 fITSChannelStatus(tracker.fITSChannelStatus),
284 fkDetTypeRec(tracker.fkDetTypeRec),
285 fPlaneEff(tracker.fPlaneEff) {
287 fOriginal.SetOwner();
290 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
293 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
294 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
297 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
298 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
301 //------------------------------------------------------------------------
302 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
303 //Assignment operator
304 this->~AliITStrackerMI();
305 new(this) AliITStrackerMI(tracker);
308 //------------------------------------------------------------------------
309 AliITStrackerMI::~AliITStrackerMI()
314 if (fCoefficients) delete [] fCoefficients;
315 DeleteTrksMaterialLUT();
316 if (fDebugStreamer) {
317 //fDebugStreamer->Close();
318 delete fDebugStreamer;
320 if(fITSChannelStatus) delete fITSChannelStatus;
321 if(fPlaneEff) delete fPlaneEff;
323 //------------------------------------------------------------------------
324 void AliITStrackerMI::ReadBadFromDetTypeRec() {
325 //--------------------------------------------------------------------
326 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
328 //--------------------------------------------------------------------
330 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
332 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
334 if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
337 if(fITSChannelStatus) delete fITSChannelStatus;
338 fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
340 // ITS detectors and chips
341 Int_t i=0,j=0,k=0,ndet=0;
342 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
343 Int_t nBadDetsPerLayer=0;
344 ndet=AliITSgeomTGeo::GetNDetectors(i);
345 for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
346 for (k=1; k<ndet+1; k++) {
347 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
348 det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fkDetTypeRec);
349 if(det.IsBad()) {nBadDetsPerLayer++;}
350 } // end loop on detectors
351 } // end loop on ladders
352 Info("ReadBadFromDetTypeRec",Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
353 } // end loop on layers
357 //------------------------------------------------------------------------
358 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
359 //--------------------------------------------------------------------
360 //This function loads ITS clusters
361 //--------------------------------------------------------------------
363 TClonesArray *clusters = NULL;
364 AliITSRecPointContainer* rpcont=AliITSRecPointContainer::Instance();
365 clusters=rpcont->FetchClusters(0,cTree);
366 if(!(rpcont->IsSPDActive() || rpcont->IsSDDActive() || rpcont->IsSSDActive())){
367 AliError("ITS is not in a known running configuration: SPD, SDD and SSD are not active");
370 Int_t i=0,j=0,ndet=0;
372 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
373 ndet=fgLayers[i].GetNdetectors();
374 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
375 for (; j<jmax; j++) {
376 // if (!cTree->GetEvent(j)) continue;
377 clusters = rpcont->UncheckedGetClusters(j);
378 if(!clusters)continue;
379 Int_t ncl=clusters->GetEntriesFast();
380 SignDeltas(clusters,GetZ());
383 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
384 detector=c->GetDetectorIndex();
386 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
388 Int_t retval = fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
390 AliWarning(Form("Too many clusters on layer %d!",i));
395 // add dead zone "virtual" cluster in SPD, if there is a cluster within
396 // zwindow cm from the dead zone
397 // This method assumes that fSPDdetzcentre is ordered from -z to +z
398 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
399 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
400 Int_t lab[4] = {0,0,0,detector};
401 Int_t info[3] = {0,0,i};
402 Float_t q = 0.; // this identifies virtual clusters
403 Float_t hit[5] = {xdead,
405 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
406 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
408 Bool_t local = kTRUE;
409 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
410 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
411 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
412 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
413 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
414 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
415 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
416 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
417 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
418 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
419 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
420 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
421 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
422 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
423 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
424 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
425 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
426 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
427 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
429 } // "virtual" clusters in SPD
433 fgLayers[i].ResetRoad(); //road defined by the cluster density
434 fgLayers[i].SortClusters();
437 // check whether we have to skip some layers
438 SetForceSkippingOfLayer();
442 //------------------------------------------------------------------------
443 void AliITStrackerMI::UnloadClusters() {
444 //--------------------------------------------------------------------
445 //This function unloads ITS clusters
446 //--------------------------------------------------------------------
447 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
449 //------------------------------------------------------------------------
450 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
451 //--------------------------------------------------------------------
452 // Publishes all pointers to clusters known to the tracker into the
453 // passed object array.
454 // The ownership is not transfered - the caller is not expected to delete
456 //--------------------------------------------------------------------
458 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
459 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
460 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
467 //------------------------------------------------------------------------
468 Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
469 //--------------------------------------------------------------------
470 // Correction for the material between the TPC and the ITS
471 //--------------------------------------------------------------------
472 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
473 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
474 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
475 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
476 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
477 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
478 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
479 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
481 printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
487 //------------------------------------------------------------------------
488 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
489 //--------------------------------------------------------------------
490 // This functions reconstructs ITS tracks
491 // The clusters must be already loaded !
492 //--------------------------------------------------------------------
494 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
496 fTrackingPhase="Clusters2Tracks";
498 TObjArray itsTracks(15000);
500 fEsd = event; // store pointer to the esd
502 // temporary (for cosmics)
503 if(event->GetVertex()) {
504 TString title = event->GetVertex()->GetTitle();
505 if(title.Contains("cosmics")) {
506 Double_t xyz[3]={GetX(),GetY(),GetZ()};
507 Double_t exyz[3]={0.1,0.1,0.1};
513 {/* Read ESD tracks */
514 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
515 Int_t nentr=event->GetNumberOfTracks();
517 // Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
519 AliESDtrack *esd=event->GetTrack(nentr);
520 // ---- for debugging:
521 //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); }
523 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
524 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
525 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
526 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
529 t=new AliITStrackMI(*esd);
530 } catch (const Char_t *msg) {
531 //Warning("Clusters2Tracks",msg);
535 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
536 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
539 // look at the ESD mass hypothesys !
540 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
542 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
544 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
545 //track - can be V0 according to TPC
547 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
551 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
555 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
559 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
564 t->SetReconstructed(kFALSE);
565 itsTracks.AddLast(t);
566 fOriginal.AddLast(t);
568 } /* End Read ESD tracks */
572 Int_t nentr=itsTracks.GetEntriesFast();
573 fTrackHypothesys.Expand(nentr);
574 fBestHypothesys.Expand(nentr);
575 MakeCoefficients(nentr);
576 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
578 // THE TWO TRACKING PASSES
579 for (fPass=0; fPass<2; fPass++) {
580 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
581 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
582 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
583 if (t==0) continue; //this track has been already tracked
584 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
585 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
586 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
587 if (fConstraint[fPass]) {
588 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
589 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
592 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
593 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
595 ResetTrackToFollow(*t);
598 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
601 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
603 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
604 if (!besttrack) continue;
605 besttrack->SetLabel(tpcLabel);
606 // besttrack->CookdEdx();
608 besttrack->SetFakeRatio(1.);
609 CookLabel(besttrack,0.); //For comparison only
610 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
612 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
614 t->SetReconstructed(kTRUE);
616 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
618 GetBestHypothesysMIP(itsTracks);
619 } // end loop on the two tracking passes
621 if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
622 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
627 Int_t entries = fTrackHypothesys.GetEntriesFast();
628 for (Int_t ientry=0; ientry<entries; ientry++) {
629 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
630 if (array) array->Delete();
631 delete fTrackHypothesys.RemoveAt(ientry);
634 fTrackHypothesys.Delete();
635 entries = fBestHypothesys.GetEntriesFast();
636 for (Int_t ientry=0; ientry<entries; ientry++) {
637 TObjArray * array =(TObjArray*)fBestHypothesys.UncheckedAt(ientry);
638 if (array) array->Delete();
639 delete fBestHypothesys.RemoveAt(ientry);
641 fBestHypothesys.Delete();
643 delete [] fCoefficients;
645 DeleteTrksMaterialLUT();
647 AliInfo(Form("Number of prolonged tracks: %d out of %d ESD tracks",ntrk,noesd));
649 fTrackingPhase="Default";
653 //------------------------------------------------------------------------
654 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
655 //--------------------------------------------------------------------
656 // This functions propagates reconstructed ITS tracks back
657 // The clusters must be loaded !
658 //--------------------------------------------------------------------
659 fTrackingPhase="PropagateBack";
660 Int_t nentr=event->GetNumberOfTracks();
661 // Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
664 for (Int_t i=0; i<nentr; i++) {
665 AliESDtrack *esd=event->GetTrack(i);
667 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
668 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
672 t=new AliITStrackMI(*esd);
673 } catch (const Char_t *msg) {
674 //Warning("PropagateBack",msg);
678 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
680 ResetTrackToFollow(*t);
683 // propagate to vertex [SR, GSI 17.02.2003]
684 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
685 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
686 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
687 fTrackToFollow.StartTimeIntegral();
688 // from vertex to outside pipe
689 CorrectForPipeMaterial(&fTrackToFollow,"outward");
691 // Start time integral and add distance from current position to vertex
692 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
693 fTrackToFollow.GetXYZ(xyzTrk);
695 for (Int_t icoord=0; icoord<3; icoord++) {
696 Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
699 fTrackToFollow.StartTimeIntegral();
700 fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
702 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
703 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
704 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
708 fTrackToFollow.SetLabel(t->GetLabel());
709 //fTrackToFollow.CookdEdx();
710 CookLabel(&fTrackToFollow,0.); //For comparison only
711 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
712 //UseClusters(&fTrackToFollow);
718 AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
720 fTrackingPhase="Default";
724 //------------------------------------------------------------------------
725 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
726 //--------------------------------------------------------------------
727 // This functions refits ITS tracks using the
728 // "inward propagated" TPC tracks
729 // The clusters must be loaded !
730 //--------------------------------------------------------------------
731 fTrackingPhase="RefitInward";
733 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
735 Int_t nentr=event->GetNumberOfTracks();
736 // Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
739 for (Int_t i=0; i<nentr; i++) {
740 AliESDtrack *esd=event->GetTrack(i);
742 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
743 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
744 if (esd->GetStatus()&AliESDtrack::kTPCout)
745 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
749 t=new AliITStrackMI(*esd);
750 } catch (const Char_t *msg) {
751 //Warning("RefitInward",msg);
755 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
756 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
761 ResetTrackToFollow(*t);
762 fTrackToFollow.ResetClusters();
764 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
765 fTrackToFollow.ResetCovariance(10.);
768 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
769 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
771 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
772 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
773 AliDebug(2," refit OK");
774 fTrackToFollow.SetLabel(t->GetLabel());
775 // fTrackToFollow.CookdEdx();
776 CookdEdx(&fTrackToFollow);
778 CookLabel(&fTrackToFollow,0.0); //For comparison only
781 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
782 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
783 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
784 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
785 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
786 Double_t r[3]={0.,0.,0.};
788 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
795 AliInfo(Form("Number of refitted tracks: %d out of %d ESD tracks",ntrk,nentr));
797 fTrackingPhase="Default";
801 //------------------------------------------------------------------------
802 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
803 //--------------------------------------------------------------------
804 // Return pointer to a given cluster
805 //--------------------------------------------------------------------
806 Int_t l=(index & 0xf0000000) >> 28;
807 Int_t c=(index & 0x0fffffff) >> 00;
808 return fgLayers[l].GetCluster(c);
810 //------------------------------------------------------------------------
811 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
812 //--------------------------------------------------------------------
813 // Get track space point with index i
814 //--------------------------------------------------------------------
816 Int_t l=(index & 0xf0000000) >> 28;
817 Int_t c=(index & 0x0fffffff) >> 00;
818 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
819 Int_t idet = cl->GetDetectorIndex();
823 cl->GetGlobalXYZ(xyz);
824 cl->GetGlobalCov(cov);
826 p.SetCharge(cl->GetQ());
827 p.SetDriftTime(cl->GetDriftTime());
828 p.SetChargeRatio(cl->GetChargeRatio());
829 p.SetClusterType(cl->GetClusterType());
830 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
833 iLayer = AliGeomManager::kSPD1;
836 iLayer = AliGeomManager::kSPD2;
839 iLayer = AliGeomManager::kSDD1;
842 iLayer = AliGeomManager::kSDD2;
845 iLayer = AliGeomManager::kSSD1;
848 iLayer = AliGeomManager::kSSD2;
851 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
854 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
855 p.SetVolumeID((UShort_t)volid);
858 //------------------------------------------------------------------------
859 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
860 AliTrackPoint& p, const AliESDtrack *t) {
861 //--------------------------------------------------------------------
862 // Get track space point with index i
863 // (assign error estimated during the tracking)
864 //--------------------------------------------------------------------
866 Int_t l=(index & 0xf0000000) >> 28;
867 Int_t c=(index & 0x0fffffff) >> 00;
868 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
869 Int_t idet = cl->GetDetectorIndex();
871 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
873 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
875 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
876 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
877 Double_t alpha = t->GetAlpha();
878 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
879 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,GetBz()));
880 phi += alpha-det.GetPhi();
881 Float_t tgphi = TMath::Tan(phi);
883 Float_t tgl = t->GetTgl(); // tgl about const along track
884 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
886 Float_t errtrky,errtrkz,covyz;
887 Bool_t addMisalErr=kFALSE;
888 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
892 cl->GetGlobalXYZ(xyz);
893 // cl->GetGlobalCov(cov);
894 Float_t pos[3] = {0.,0.,0.};
895 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
896 tmpcl.GetGlobalCov(cov);
899 p.SetCharge(cl->GetQ());
900 p.SetDriftTime(cl->GetDriftTime());
901 p.SetChargeRatio(cl->GetChargeRatio());
902 p.SetClusterType(cl->GetClusterType());
904 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
907 iLayer = AliGeomManager::kSPD1;
910 iLayer = AliGeomManager::kSPD2;
913 iLayer = AliGeomManager::kSDD1;
916 iLayer = AliGeomManager::kSDD2;
919 iLayer = AliGeomManager::kSSD1;
922 iLayer = AliGeomManager::kSSD2;
925 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
928 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
930 p.SetVolumeID((UShort_t)volid);
933 //------------------------------------------------------------------------
934 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
936 //--------------------------------------------------------------------
937 // Follow prolongation tree
938 //--------------------------------------------------------------------
940 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
941 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
944 AliESDtrack * esd = otrack->GetESDtrack();
945 if (esd->GetV0Index(0)>0) {
946 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
947 // mapping of ESD track is different as ITS track in Containers
948 // Need something more stable
949 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
950 for (Int_t i=0;i<3;i++){
951 Int_t index = esd->GetV0Index(i);
953 AliESDv0 * vertex = fEsd->GetV0(index);
954 if (vertex->GetStatus()<0) continue; // rejected V0
956 if (esd->GetSign()>0) {
957 vertex->SetIndex(0,esdindex);
959 vertex->SetIndex(1,esdindex);
963 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
965 bestarray = new TObjArray(5);
966 bestarray->SetOwner();
967 fBestHypothesys.AddAt(bestarray,esdindex);
971 //setup tree of the prolongations
973 static AliITStrackMI tracks[7][100];
974 AliITStrackMI *currenttrack;
975 static AliITStrackMI currenttrack1;
976 static AliITStrackMI currenttrack2;
977 static AliITStrackMI backuptrack;
979 Int_t nindexes[7][100];
980 Float_t normalizedchi2[100];
981 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
982 otrack->SetNSkipped(0);
983 new (&(tracks[6][0])) AliITStrackMI(*otrack);
985 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
986 Int_t modstatus = 1; // found
990 // follow prolongations
991 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
992 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
995 AliITSlayer &layer=fgLayers[ilayer];
996 Double_t r = layer.GetR();
1002 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
1004 if (ntracks[ilayer]>=100) break;
1005 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
1006 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
1007 if (ntracks[ilayer]>15+ilayer){
1008 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
1009 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
1012 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
1014 // material between SSD and SDD, SDD and SPD
1016 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
1018 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
1022 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
1023 Int_t idet=layer.FindDetectorIndex(phi,z);
1025 Double_t trackGlobXYZ1[3];
1026 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1028 // Get the budget to the primary vertex for the current track being prolonged
1029 Double_t budgetToPrimVertex = GetEffectiveThickness();
1031 // check if we allow a prolongation without point
1032 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1034 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1035 // propagate to the layer radius
1036 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1037 if(!vtrack->Propagate(xToGo)) continue;
1038 // apply correction for material of the current layer
1039 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1040 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1041 vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1042 vtrack->SetClIndex(ilayer,-1);
1043 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1044 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1045 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1047 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1052 // track outside layer acceptance in z
1053 if (idet<0) continue;
1055 //propagate to the intersection with the detector plane
1056 const AliITSdetector &det=layer.GetDetector(idet);
1057 new(¤ttrack2) AliITStrackMI(currenttrack1);
1058 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1059 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1060 currenttrack1.SetDetectorIndex(idet);
1061 currenttrack2.SetDetectorIndex(idet);
1062 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1065 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1067 // road in global (rphi,z) [i.e. in tracking ref. system]
1068 Double_t zmin,zmax,ymin,ymax;
1069 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1071 // select clusters in road
1072 layer.SelectClusters(zmin,zmax,ymin,ymax);
1073 //********************
1075 // Define criteria for track-cluster association
1076 Double_t msz = currenttrack1.GetSigmaZ2() +
1077 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1078 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1079 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1080 Double_t msy = currenttrack1.GetSigmaY2() +
1081 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1082 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1083 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1085 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1086 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1088 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1089 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1091 msz = 1./msz; // 1/RoadZ^2
1092 msy = 1./msy; // 1/RoadY^2
1096 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1098 const AliITSRecPoint *cl=0;
1100 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1101 Bool_t deadzoneSPD=kFALSE;
1102 currenttrack = ¤ttrack1;
1104 // check if the road contains a dead zone
1105 Bool_t noClusters = kFALSE;
1106 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1107 if (noClusters) AliDebug(2,"no clusters in road");
1108 Double_t dz=0.5*(zmax-zmin);
1109 Double_t dy=0.5*(ymax-ymin);
1110 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1111 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1112 // create a prolongation without clusters (check also if there are no clusters in the road)
1115 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1116 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1117 updatetrack->SetClIndex(ilayer,-1);
1119 modstatus = 5; // no cls in road
1120 } else if (dead==1) {
1121 modstatus = 7; // holes in z in SPD
1122 } else if (dead==2 || dead==3 || dead==4) {
1123 modstatus = 2; // dead from OCDB
1125 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1126 // apply correction for material of the current layer
1127 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1128 if (constrain) { // apply vertex constrain
1129 updatetrack->SetConstrain(constrain);
1130 Bool_t isPrim = kTRUE;
1131 if (ilayer<4) { // check that it's close to the vertex
1132 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1133 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1134 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1135 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1136 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1138 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1140 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1142 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1143 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1145 } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1146 updatetrack->SetDeadZoneProbability(ilayer,1.);
1147 } else if (dead==4) { // at least a single dead channel from OCDB
1148 updatetrack->SetDeadZoneProbability(ilayer,0.);
1155 // loop over clusters in the road
1156 while ((cl=layer.GetNextCluster(clidx))!=0) {
1157 if (ntracks[ilayer]>95) break; //space for skipped clusters
1158 Bool_t changedet =kFALSE;
1159 if (TMath::Abs(cl->GetQ())<1.e-13 && deadzoneSPD==kTRUE) continue;
1160 Int_t idetc=cl->GetDetectorIndex();
1162 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1163 // take into account misalignment (bring track to real detector plane)
1164 Double_t xTrOrig = currenttrack->GetX();
1165 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1166 // a first cut on track-cluster distance
1167 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1168 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1169 { // cluster not associated to track
1170 AliDebug(2,"not associated");
1173 // bring track back to ideal detector plane
1174 if (!currenttrack->Propagate(xTrOrig)) continue;
1175 } else { // have to move track to cluster's detector
1176 const AliITSdetector &detc=layer.GetDetector(idetc);
1177 // a first cut on track-cluster distance
1179 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1180 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1181 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1182 continue; // cluster not associated to track
1184 new (&backuptrack) AliITStrackMI(currenttrack2);
1186 currenttrack =¤ttrack2;
1187 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1188 new (currenttrack) AliITStrackMI(backuptrack);
1192 currenttrack->SetDetectorIndex(idetc);
1193 // Get again the budget to the primary vertex
1194 // for the current track being prolonged, if had to change detector
1195 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1198 // calculate track-clusters chi2
1199 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1201 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1202 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1203 if (TMath::Abs(cl->GetQ())<1.e-13) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1204 if (ntracks[ilayer]>=100) continue;
1205 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1206 updatetrack->SetClIndex(ilayer,-1);
1207 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1209 if (TMath::Abs(cl->GetQ())>1.e-13) { // real cluster
1210 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1211 AliDebug(2,"update failed");
1214 updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1215 modstatus = 1; // found
1216 } else { // virtual cluster in dead zone
1217 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1218 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1219 modstatus = 7; // holes in z in SPD
1223 Float_t xlocnewdet,zlocnewdet;
1224 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1225 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1228 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1230 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1232 // apply correction for material of the current layer
1233 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1235 if (constrain) { // apply vertex constrain
1236 updatetrack->SetConstrain(constrain);
1237 Bool_t isPrim = kTRUE;
1238 if (ilayer<4) { // check that it's close to the vertex
1239 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1240 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1241 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1242 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1243 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1245 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1246 } //apply vertex constrain
1248 } // create new hypothesis
1250 AliDebug(2,"chi2 too large");
1253 } // loop over possible prolongations
1255 // allow one prolongation without clusters
1256 if (constrain && itrack<=1 && TMath::Abs(currenttrack1.GetNSkipped())<1.e-13 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1257 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1258 // apply correction for material of the current layer
1259 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1260 vtrack->SetClIndex(ilayer,-1);
1261 modstatus = 3; // skipped
1262 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1263 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1264 vtrack->IncrementNSkipped();
1269 } // loop over tracks in layer ilayer+1
1271 //loop over track candidates for the current layer
1277 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1278 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1279 if (normalizedchi2[itrack] <
1280 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1284 if (constrain) { // constrain
1285 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1287 } else { // !constrain
1288 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1293 // sort tracks by increasing normalized chi2
1294 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1295 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1296 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1297 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1298 } // end loop over layers
1302 // Now select tracks to be kept
1304 Int_t max = constrain ? 20 : 5;
1306 // tracks that reach layer 0 (SPD inner)
1307 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1308 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1309 if (track.GetNumberOfClusters()<2) continue;
1310 if (!constrain && track.GetNormChi2(0) >
1311 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1314 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1317 // tracks that reach layer 1 (SPD outer)
1318 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1319 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1320 if (track.GetNumberOfClusters()<4) continue;
1321 if (!constrain && track.GetNormChi2(1) >
1322 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1323 if (constrain) track.IncrementNSkipped();
1325 track.SetD(0,track.GetD(GetX(),GetY()));
1326 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1327 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1328 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1331 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1334 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1336 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1337 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1338 if (track.GetNumberOfClusters()<3) continue;
1339 if (!constrain && track.GetNormChi2(2) >
1340 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1341 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1343 track.SetD(0,track.GetD(GetX(),GetY()));
1344 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1345 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1346 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1349 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1355 // register best track of each layer - important for V0 finder
1357 for (Int_t ilayer=0;ilayer<5;ilayer++){
1358 if (ntracks[ilayer]==0) continue;
1359 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1360 if (track.GetNumberOfClusters()<1) continue;
1361 CookLabel(&track,0);
1362 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1366 // update TPC V0 information
1368 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1369 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1370 for (Int_t i=0;i<3;i++){
1371 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1372 if (index==0) break;
1373 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1374 if (vertex->GetStatus()<0) continue; // rejected V0
1376 if (otrack->GetSign()>0) {
1377 vertex->SetIndex(0,esdindex);
1380 vertex->SetIndex(1,esdindex);
1382 //find nearest layer with track info
1383 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1384 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1385 Int_t nearest = nearestold;
1386 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1387 if (ntracks[nearest]==0){
1392 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1393 if (nearestold<5&&nearest<5){
1394 Bool_t accept = track.GetNormChi2(nearest)<10;
1396 if (track.GetSign()>0) {
1397 vertex->SetParamP(track);
1398 vertex->Update(fprimvertex);
1399 //vertex->SetIndex(0,track.fESDtrack->GetID());
1400 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1402 vertex->SetParamN(track);
1403 vertex->Update(fprimvertex);
1404 //vertex->SetIndex(1,track.fESDtrack->GetID());
1405 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1407 vertex->SetStatus(vertex->GetStatus()+1);
1409 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1416 //------------------------------------------------------------------------
1417 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1419 //--------------------------------------------------------------------
1422 return fgLayers[layer];
1424 //------------------------------------------------------------------------
1425 AliITStrackerMI::AliITSlayer::AliITSlayer():
1455 //--------------------------------------------------------------------
1456 //default AliITSlayer constructor
1457 //--------------------------------------------------------------------
1458 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1459 fClusterWeight[i]=0;
1460 fClusterTracks[0][i]=-1;
1461 fClusterTracks[1][i]=-1;
1462 fClusterTracks[2][i]=-1;
1463 fClusterTracks[3][i]=-1;
1466 //------------------------------------------------------------------------
1467 AliITStrackerMI::AliITSlayer::
1468 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1497 //--------------------------------------------------------------------
1498 //main AliITSlayer constructor
1499 //--------------------------------------------------------------------
1500 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1501 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1503 //------------------------------------------------------------------------
1504 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1506 fPhiOffset(layer.fPhiOffset),
1507 fNladders(layer.fNladders),
1508 fZOffset(layer.fZOffset),
1509 fNdetectors(layer.fNdetectors),
1510 fDetectors(layer.fDetectors),
1515 fClustersCs(layer.fClustersCs),
1516 fClusterIndexCs(layer.fClusterIndexCs),
1520 fCurrentSlice(layer.fCurrentSlice),
1528 fAccepted(layer.fAccepted),
1530 fMaxSigmaClY(layer.fMaxSigmaClY),
1531 fMaxSigmaClZ(layer.fMaxSigmaClZ),
1532 fNMaxSigmaCl(layer.fNMaxSigmaCl)
1536 //------------------------------------------------------------------------
1537 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1538 //--------------------------------------------------------------------
1539 // AliITSlayer destructor
1540 //--------------------------------------------------------------------
1541 delete [] fDetectors;
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;
1551 //------------------------------------------------------------------------
1552 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1553 //--------------------------------------------------------------------
1554 // This function removes loaded clusters
1555 //--------------------------------------------------------------------
1556 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1557 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1558 fClusterWeight[i]=0;
1559 fClusterTracks[0][i]=-1;
1560 fClusterTracks[1][i]=-1;
1561 fClusterTracks[2][i]=-1;
1562 fClusterTracks[3][i]=-1;
1568 //------------------------------------------------------------------------
1569 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1570 //--------------------------------------------------------------------
1571 // This function reset weights of the clusters
1572 //--------------------------------------------------------------------
1573 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1574 fClusterWeight[i]=0;
1575 fClusterTracks[0][i]=-1;
1576 fClusterTracks[1][i]=-1;
1577 fClusterTracks[2][i]=-1;
1578 fClusterTracks[3][i]=-1;
1580 for (Int_t i=0; i<fN;i++) {
1581 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1582 if (cl&&cl->IsUsed()) cl->Use();
1586 //------------------------------------------------------------------------
1587 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1588 //--------------------------------------------------------------------
1589 // This function calculates the road defined by the cluster density
1590 //--------------------------------------------------------------------
1592 for (Int_t i=0; i<fN; i++) {
1593 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1595 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1597 //------------------------------------------------------------------------
1598 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1599 //--------------------------------------------------------------------
1600 //This function adds a cluster to this layer
1601 //--------------------------------------------------------------------
1602 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1608 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1610 Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
1611 Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2());
1612 if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
1613 if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
1614 if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
1615 if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
1618 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1619 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1620 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1621 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1625 //------------------------------------------------------------------------
1626 void AliITStrackerMI::AliITSlayer::SortClusters()
1631 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1632 Float_t *z = new Float_t[fN];
1633 Int_t * index = new Int_t[fN];
1635 fMaxSigmaClY=0.; //AD
1636 fMaxSigmaClZ=0.; //AD
1638 for (Int_t i=0;i<fN;i++){
1639 z[i] = fClusters[i]->GetZ();
1640 // save largest errors in y and z for this layer
1641 fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
1642 fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
1644 TMath::Sort(fN,z,index,kFALSE);
1645 for (Int_t i=0;i<fN;i++){
1646 clusters[i] = fClusters[index[i]];
1649 for (Int_t i=0;i<fN;i++){
1650 fClusters[i] = clusters[i];
1651 fZ[i] = fClusters[i]->GetZ();
1652 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1653 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1654 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1664 for (Int_t i=0;i<fN;i++){
1665 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1666 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1667 fClusterIndex[i] = i;
1671 fDy5 = (fYB[1]-fYB[0])/5.;
1672 fDy10 = (fYB[1]-fYB[0])/10.;
1673 fDy20 = (fYB[1]-fYB[0])/20.;
1674 for (Int_t i=0;i<6;i++) fN5[i] =0;
1675 for (Int_t i=0;i<11;i++) fN10[i]=0;
1676 for (Int_t i=0;i<21;i++) fN20[i]=0;
1678 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;}
1679 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;}
1680 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;}
1683 for (Int_t i=0;i<fN;i++)
1684 for (Int_t irot=-1;irot<=1;irot++){
1685 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1687 for (Int_t slice=0; slice<6;slice++){
1688 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1689 fClusters5[slice][fN5[slice]] = fClusters[i];
1690 fY5[slice][fN5[slice]] = curY;
1691 fZ5[slice][fN5[slice]] = fZ[i];
1692 fClusterIndex5[slice][fN5[slice]]=i;
1697 for (Int_t slice=0; slice<11;slice++){
1698 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1699 fClusters10[slice][fN10[slice]] = fClusters[i];
1700 fY10[slice][fN10[slice]] = curY;
1701 fZ10[slice][fN10[slice]] = fZ[i];
1702 fClusterIndex10[slice][fN10[slice]]=i;
1707 for (Int_t slice=0; slice<21;slice++){
1708 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1709 fClusters20[slice][fN20[slice]] = fClusters[i];
1710 fY20[slice][fN20[slice]] = curY;
1711 fZ20[slice][fN20[slice]] = fZ[i];
1712 fClusterIndex20[slice][fN20[slice]]=i;
1719 // consistency check
1721 for (Int_t i=0;i<fN-1;i++){
1727 for (Int_t slice=0;slice<21;slice++)
1728 for (Int_t i=0;i<fN20[slice]-1;i++){
1729 if (fZ20[slice][i]>fZ20[slice][i+1]){
1736 //------------------------------------------------------------------------
1737 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1738 //--------------------------------------------------------------------
1739 // This function returns the index of the nearest cluster
1740 //--------------------------------------------------------------------
1743 if (fCurrentSlice<0) {
1752 if (ncl==0) return 0;
1753 Int_t b=0, e=ncl-1, m=(b+e)/2;
1754 for (; b<e; m=(b+e)/2) {
1755 // if (z > fClusters[m]->GetZ()) b=m+1;
1756 if (z > zcl[m]) b=m+1;
1761 //------------------------------------------------------------------------
1762 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 {
1763 //--------------------------------------------------------------------
1764 // This function computes the rectangular road for this track
1765 //--------------------------------------------------------------------
1768 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1769 // take into account the misalignment: propagate track to misaligned detector plane
1770 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1772 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1773 TMath::Sqrt(track->GetSigmaZ2() +
1774 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1775 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1776 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1777 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1778 TMath::Sqrt(track->GetSigmaY2() +
1779 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1780 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1781 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1783 // track at boundary between detectors, enlarge road
1784 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1785 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1786 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1787 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1788 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1789 Float_t tgl = TMath::Abs(track->GetTgl());
1790 if (tgl > 1.) tgl=1.;
1791 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1792 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1793 Float_t snp = TMath::Abs(track->GetSnp());
1794 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1795 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1798 // add to the road a term (up to 2-3 mm) to deal with misalignments
1799 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1800 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1802 Double_t r = fgLayers[ilayer].GetR();
1803 zmin = track->GetZ() - dz;
1804 zmax = track->GetZ() + dz;
1805 ymin = track->GetY() + r*det.GetPhi() - dy;
1806 ymax = track->GetY() + r*det.GetPhi() + dy;
1808 // bring track back to idead detector plane
1809 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1813 //------------------------------------------------------------------------
1814 void AliITStrackerMI::AliITSlayer::
1815 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1816 //--------------------------------------------------------------------
1817 // This function sets the "window"
1818 //--------------------------------------------------------------------
1820 Double_t circle=2*TMath::Pi()*fR;
1826 // enlarge road in y by maximum cluster error on this layer (3 sigma)
1827 fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
1828 fYmax += fNMaxSigmaCl*fMaxSigmaClY;
1829 fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
1830 fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
1832 Float_t ymiddle = (fYmin+fYmax)*0.5;
1833 if (ymiddle<fYB[0]) {
1834 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1835 } else if (ymiddle>fYB[1]) {
1836 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1842 fClustersCs = fClusters;
1843 fClusterIndexCs = fClusterIndex;
1849 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1850 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1851 if (slice<0) slice=0;
1852 if (slice>20) slice=20;
1853 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1855 fCurrentSlice=slice;
1856 fClustersCs = fClusters20[fCurrentSlice];
1857 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1858 fYcs = fY20[fCurrentSlice];
1859 fZcs = fZ20[fCurrentSlice];
1860 fNcs = fN20[fCurrentSlice];
1865 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1866 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1867 if (slice<0) slice=0;
1868 if (slice>10) slice=10;
1869 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1871 fCurrentSlice=slice;
1872 fClustersCs = fClusters10[fCurrentSlice];
1873 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1874 fYcs = fY10[fCurrentSlice];
1875 fZcs = fZ10[fCurrentSlice];
1876 fNcs = fN10[fCurrentSlice];
1881 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1882 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1883 if (slice<0) slice=0;
1884 if (slice>5) slice=5;
1885 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1887 fCurrentSlice=slice;
1888 fClustersCs = fClusters5[fCurrentSlice];
1889 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1890 fYcs = fY5[fCurrentSlice];
1891 fZcs = fZ5[fCurrentSlice];
1892 fNcs = fN5[fCurrentSlice];
1896 fI = FindClusterIndex(fZmin);
1897 fImax = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
1903 //------------------------------------------------------------------------
1904 Int_t AliITStrackerMI::AliITSlayer::
1905 FindDetectorIndex(Double_t phi, Double_t z) const {
1906 //--------------------------------------------------------------------
1907 //This function finds the detector crossed by the track
1908 //--------------------------------------------------------------------
1910 if (fZOffset<0) // old geometry
1911 dphi = -(phi-fPhiOffset);
1912 else // new geometry
1913 dphi = phi-fPhiOffset;
1916 if (dphi < 0) dphi += 2*TMath::Pi();
1917 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1918 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1919 if (np>=fNladders) np-=fNladders;
1920 if (np<0) np+=fNladders;
1923 Double_t dz=fZOffset-z;
1924 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1925 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1926 if (nz>=fNdetectors || nz<0) {
1927 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1931 // ad hoc correction for 3rd ladder of SDD inner layer,
1932 // which is reversed (rotated by pi around local y)
1933 // this correction is OK only from AliITSv11Hybrid onwards
1934 if (GetR()>12. && GetR()<20.) { // SDD inner
1935 if(np==2) { // 3rd ladder
1936 Double_t posMod252[3];
1937 AliITSgeomTGeo::GetTranslation(252,posMod252);
1938 // check the Z coordinate of Mod 252: if negative
1939 // (old SDD geometry in AliITSv11Hybrid)
1940 // the swap of numeration whould be applied
1941 if(posMod252[2]<0.){
1942 nz = (fNdetectors-1) - nz;
1946 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1949 return np*fNdetectors + nz;
1951 //------------------------------------------------------------------------
1952 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1954 //--------------------------------------------------------------------
1955 // This function returns clusters within the "window"
1956 //--------------------------------------------------------------------
1958 if (fCurrentSlice<0) {
1959 Double_t rpi2 = 2.*fR*TMath::Pi();
1960 for (Int_t i=fI; i<fImax; i++) {
1963 if (fYmax<y) y -= rpi2;
1964 if (fYmin>y) y += rpi2;
1965 if (y<fYmin) continue;
1966 if (y>fYmax) continue;
1968 // skip clusters that are in "extended" road but they
1969 // 3sigma error does not touch the original road
1970 if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
1971 if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
1973 if (TMath::Abs(fClusters[i]->GetQ())<1.e-13 && fSkip==2) continue;
1976 return fClusters[i];
1979 for (Int_t i=fI; i<fImax; i++) {
1980 if (fYcs[i]<fYmin) continue;
1981 if (fYcs[i]>fYmax) continue;
1982 if (TMath::Abs(fClustersCs[i]->GetQ())<1.e-13 && fSkip==2) continue;
1983 ci=fClusterIndexCs[i];
1985 return fClustersCs[i];
1990 //------------------------------------------------------------------------
1991 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1993 //--------------------------------------------------------------------
1994 // This function returns the layer thickness at this point (units X0)
1995 //--------------------------------------------------------------------
1997 x0=AliITSRecoParam::GetX0Air();
1998 if (43<fR&&fR<45) { //SSD2
2001 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2002 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2003 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2004 for (Int_t i=0; i<12; i++) {
2005 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
2006 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2010 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
2011 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2015 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2016 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2019 if (37<fR&&fR<41) { //SSD1
2022 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2023 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2024 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2025 for (Int_t i=0; i<11; i++) {
2026 if (TMath::Abs(z-3.9*i)<0.15) {
2027 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2031 if (TMath::Abs(z+3.9*i)<0.15) {
2032 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2036 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2037 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2040 if (13<fR&&fR<26) { //SDD
2043 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2045 if (TMath::Abs(y-1.80)<0.55) {
2047 for (Int_t j=0; j<20; j++) {
2048 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2049 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2052 if (TMath::Abs(y+1.80)<0.55) {
2054 for (Int_t j=0; j<20; j++) {
2055 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2056 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2060 for (Int_t i=0; i<4; i++) {
2061 if (TMath::Abs(z-7.3*i)<0.60) {
2063 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2066 if (TMath::Abs(z+7.3*i)<0.60) {
2068 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2073 if (6<fR&&fR<8) { //SPD2
2074 Double_t dd=0.0063; x0=21.5;
2076 if (TMath::Abs(y-3.08)>0.5) d+=dd;
2077 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2079 if (3<fR&&fR<5) { //SPD1
2080 Double_t dd=0.0063; x0=21.5;
2082 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2083 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2088 //------------------------------------------------------------------------
2089 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2091 fRmisal(det.fRmisal),
2093 fSinPhi(det.fSinPhi),
2094 fCosPhi(det.fCosPhi),
2100 fNChips(det.fNChips),
2101 fChipIsBad(det.fChipIsBad)
2105 //------------------------------------------------------------------------
2106 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2107 const AliITSDetTypeRec *detTypeRec)
2109 //--------------------------------------------------------------------
2110 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2111 //--------------------------------------------------------------------
2113 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2114 // while in the tracker they start from 0 for each layer
2115 for(Int_t il=0; il<ilayer; il++)
2116 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2119 if (ilayer==0 || ilayer==1) { // ---------- SPD
2121 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2123 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2126 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2130 // Get calibration from AliITSDetTypeRec
2131 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2132 calib->SetModuleIndex(idet);
2133 AliITSCalibration *calibSPDdead = 0;
2134 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2135 if (calib->IsBad() ||
2136 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2139 // printf("lay %d bad %d\n",ilayer,idet);
2142 // Get segmentation from AliITSDetTypeRec
2143 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2145 // Read info about bad chips
2146 fNChips = segm->GetMaximumChipIndex()+1;
2147 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2148 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2149 fChipIsBad = new Bool_t[fNChips];
2150 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2151 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2152 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2153 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2158 //------------------------------------------------------------------------
2159 Double_t AliITStrackerMI::GetEffectiveThickness()
2161 //--------------------------------------------------------------------
2162 // Returns the thickness between the current layer and the vertex (units X0)
2163 //--------------------------------------------------------------------
2166 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2167 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2168 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2172 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2173 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2177 Double_t xn=fgLayers[fI].GetR();
2178 for (Int_t i=0; i<fI; i++) {
2179 Double_t xi=fgLayers[i].GetR();
2180 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2186 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2187 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2190 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2191 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2195 //------------------------------------------------------------------------
2196 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2197 //-------------------------------------------------------------------
2198 // This function returns number of clusters within the "window"
2199 //--------------------------------------------------------------------
2201 for (Int_t i=fI; i<fN; i++) {
2202 const AliITSRecPoint *c=fClusters[i];
2203 if (c->GetZ() > fZmax) break;
2204 if (c->IsUsed()) continue;
2205 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2206 Double_t y=fR*det.GetPhi() + c->GetY();
2208 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2209 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2211 if (y<fYmin) continue;
2212 if (y>fYmax) continue;
2217 //------------------------------------------------------------------------
2218 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2219 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2221 //--------------------------------------------------------------------
2222 // This function refits the track "track" at the position "x" using
2223 // the clusters from "clusters"
2224 // If "extra"==kTRUE,
2225 // the clusters from overlapped modules get attached to "track"
2226 // If "planeff"==kTRUE,
2227 // special approach for plane efficiency evaluation is applyed
2228 //--------------------------------------------------------------------
2230 Int_t index[AliITSgeomTGeo::kNLayers];
2232 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2233 Int_t nc=clusters->GetNumberOfClusters();
2234 for (k=0; k<nc; k++) {
2235 Int_t idx=clusters->GetClusterIndex(k);
2236 Int_t ilayer=(idx&0xf0000000)>>28;
2240 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2242 //------------------------------------------------------------------------
2243 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2244 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2246 //--------------------------------------------------------------------
2247 // This function refits the track "track" at the position "x" using
2248 // the clusters from array
2249 // If "extra"==kTRUE,
2250 // the clusters from overlapped modules get attached to "track"
2251 // If "planeff"==kTRUE,
2252 // special approach for plane efficiency evaluation is applyed
2253 //--------------------------------------------------------------------
2254 Int_t index[AliITSgeomTGeo::kNLayers];
2256 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2258 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2259 index[k]=clusters[k];
2262 // special for cosmics and TPC prolonged tracks:
2263 // propagate to the innermost of:
2264 // - innermost layer crossed by the track
2265 // - innermost layer where a cluster was associated to the track
2266 static AliITSRecoParam *repa = NULL;
2268 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
2270 repa = AliITSRecoParam::GetHighFluxParam();
2271 AliWarning("Using default AliITSRecoParam class");
2274 Int_t evsp=repa->GetEventSpecie();
2276 if(track->GetESDtrack()) trStatus=track->GetStatus();
2277 Int_t innermostlayer=0;
2278 if((evsp&AliRecoParam::kCosmic) || (trStatus&AliESDtrack::kTPCin)) {
2280 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2281 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2282 if( (drphi < (fgLayers[innermostlayer].GetR()+1.)) ||
2283 index[innermostlayer] >= 0 ) break;
2286 AliDebug(2,Form(" drphi %f innermost %d",drphi,innermostlayer));
2289 Int_t modstatus=1; // found
2291 Int_t from, to, step;
2292 if (xx > track->GetX()) {
2293 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2296 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2299 TString dir = (step>0 ? "outward" : "inward");
2301 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2302 AliITSlayer &layer=fgLayers[ilayer];
2303 Double_t r=layer.GetR();
2305 if (step<0 && xx>r) break;
2307 // material between SSD and SDD, SDD and SPD
2308 Double_t hI=ilayer-0.5*step;
2309 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2310 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2311 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2312 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2315 Double_t oldGlobXYZ[3];
2316 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2318 // continue if we are already beyond this layer
2319 Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2320 if(step>0 && oldGlobR > r) continue; // going outward
2321 if(step<0 && oldGlobR < r) continue; // going inward
2324 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2326 Int_t idet=layer.FindDetectorIndex(phi,z);
2328 // check if we allow a prolongation without point for large-eta tracks
2329 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2331 modstatus = 4; // out in z
2332 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2333 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2336 // apply correction for material of the current layer
2337 // add time if going outward
2338 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2342 if (idet<0) return kFALSE;
2345 const AliITSdetector &det=layer.GetDetector(idet);
2346 // only for ITS-SA tracks refit
2347 if (ilayer>1 && fTrackingPhase.Contains("RefitInward") && !(track->GetStatus()&AliESDtrack::kTPCin)) track->SetCheckInvariant(kFALSE);
2349 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2351 track->SetDetectorIndex(idet);
2352 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2354 Double_t dz,zmin,zmax,dy,ymin,ymax;
2356 const AliITSRecPoint *clAcc=0;
2357 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2359 Int_t idx=index[ilayer];
2360 if (idx>=0) { // cluster in this layer
2361 modstatus = 6; // no refit
2362 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2364 if (idet != cl->GetDetectorIndex()) {
2365 idet=cl->GetDetectorIndex();
2366 const AliITSdetector &detc=layer.GetDetector(idet);
2367 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2368 track->SetDetectorIndex(idet);
2369 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2371 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2372 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2376 modstatus = 1; // found
2381 } else { // no cluster in this layer
2383 modstatus = 3; // skipped
2384 // Plane Eff determination:
2385 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2386 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2387 UseTrackForPlaneEff(track,ilayer);
2390 modstatus = 5; // no cls in road
2392 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2393 dz = 0.5*(zmax-zmin);
2394 dy = 0.5*(ymax-ymin);
2395 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2396 if (dead==1) modstatus = 7; // holes in z in SPD
2397 if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2402 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2403 track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2405 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2408 if (extra) { // search for extra clusters in overlapped modules
2409 AliITStrackV2 tmp(*track);
2410 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2411 layer.SelectClusters(zmin,zmax,ymin,ymax);
2413 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2415 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2416 Double_t tolerance=0.1;
2417 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2418 // only clusters in another module! (overlaps)
2419 idetExtra = clExtra->GetDetectorIndex();
2420 if (idet == idetExtra) continue;
2422 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2424 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2425 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2426 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2427 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2429 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2430 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2433 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2434 track->SetExtraModule(ilayer,idetExtra);
2436 } // end search for extra clusters in overlapped modules
2438 // Correct for material of the current layer
2440 // add time if going outward
2441 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2442 track->SetCheckInvariant(kTRUE);
2443 } // end loop on layers
2445 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2449 //------------------------------------------------------------------------
2450 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2453 // calculate normalized chi2
2454 // return NormalizedChi2(track,0);
2457 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2458 // track->fdEdxMismatch=0;
2459 Float_t dedxmismatch =0;
2460 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2462 for (Int_t i = 0;i<6;i++){
2463 if (track->GetClIndex(i)>=0){
2464 Float_t cerry, cerrz;
2465 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2467 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2470 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2471 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2472 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2474 cchi2+=(0.5-ratio)*10.;
2475 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2476 dedxmismatch+=(0.5-ratio)*10.;
2480 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2481 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2482 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2483 if (i<2) chi2+=2*cl->GetDeltaProbability();
2489 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2490 track->SetdEdxMismatch(dedxmismatch);
2494 for (Int_t i = 0;i<4;i++){
2495 if (track->GetClIndex(i)>=0){
2496 Float_t cerry, cerrz;
2497 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2498 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2501 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2502 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2506 for (Int_t i = 4;i<6;i++){
2507 if (track->GetClIndex(i)>=0){
2508 Float_t cerry, cerrz;
2509 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2510 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2513 Float_t cerryb, cerrzb;
2514 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2515 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2518 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2519 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2524 if (track->GetESDtrack()->GetTPCsignal()>85){
2525 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2527 chi2+=(0.5-ratio)*5.;
2530 chi2+=(ratio-2.0)*3;
2534 Double_t match = TMath::Sqrt(track->GetChi22());
2535 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2536 if (!track->GetConstrain()) {
2537 if (track->GetNumberOfClusters()>2) {
2538 match/=track->GetNumberOfClusters()-2.;
2543 if (match<0) match=0;
2545 // penalty factor for missing points (NDeadZone>0), but no penalty
2546 // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2547 // or there is a dead from OCDB)
2548 Float_t deadzonefactor = 0.;
2549 if (track->GetNDeadZone()>0.) {
2550 Int_t sumDeadZoneProbability=0;
2551 for(Int_t ilay=0;ilay<6;ilay++) {
2552 if(track->GetDeadZoneProbability(ilay)>0.) sumDeadZoneProbability++;
2554 Int_t nDeadZoneWithProbNot1=(Int_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2555 if(nDeadZoneWithProbNot1>0) {
2556 Float_t deadZoneProbability = track->GetNDeadZone()-(Float_t)sumDeadZoneProbability;
2557 AliDebug(2,Form("nDeadZone %f sumDZProbability %d nDZWithProbNot1 %d deadZoneProb %f\n",track->GetNDeadZone(),sumDeadZoneProbability,nDeadZoneWithProbNot1,deadZoneProbability));
2558 deadZoneProbability /= (Float_t)nDeadZoneWithProbNot1;
2560 deadZoneProbability = TMath::Min(deadZoneProbability,one);
2561 deadzonefactor = 3.*(1.1-deadZoneProbability);
2565 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2566 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2567 1./(1.+track->GetNSkipped()));
2568 AliDebug(2,Form("match %f deadzonefactor %f chi2 %f sum %f skipped %f\n",match,deadzonefactor,chi2,sum,track->GetNSkipped()));
2569 AliDebug(2,Form("NormChi2 %f cls %d\n",normchi2,track->GetNumberOfClusters()));
2572 //------------------------------------------------------------------------
2573 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2576 // return matching chi2 between two tracks
2577 Double_t largeChi2=1000.;
2579 AliITStrackMI track3(*track2);
2580 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2582 vec(0,0)=track1->GetY() - track3.GetY();
2583 vec(1,0)=track1->GetZ() - track3.GetZ();
2584 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2585 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2586 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2589 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2590 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2591 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2592 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2593 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2595 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2596 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2597 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2598 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2600 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2601 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2602 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2604 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2605 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2607 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2610 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2611 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2614 //------------------------------------------------------------------------
2615 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2618 // return probability that given point (characterized by z position and error)
2619 // is in SPD dead zone
2620 // This method assumes that fSPDdetzcentre is ordered from -z to +z
2622 Double_t probability = 0.;
2623 Double_t nearestz = 0.,distz=0.;
2624 Int_t nearestzone = -1;
2625 Double_t mindistz = 1000.;
2627 // find closest dead zone
2628 for (Int_t i=0; i<3; i++) {
2629 distz=TMath::Abs(zpos-0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]));
2630 if (distz<mindistz) {
2632 nearestz=0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]);
2637 // too far from dead zone
2638 if (TMath::Abs(zpos-nearestz)>0.25+3.*zerr) return probability;
2641 Double_t zmin, zmax;
2642 if (nearestzone==0) { // dead zone at z = -7
2643 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2644 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2645 } else if (nearestzone==1) { // dead zone at z = 0
2646 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2647 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2648 } else if (nearestzone==2) { // dead zone at z = +7
2649 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2650 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2655 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2657 probability = 0.5*( AliMathBase::ErfFast((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2658 AliMathBase::ErfFast((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2659 AliDebug(2,Form("zpos %f +- %f nearestzone %d zmin zmax %f %f prob %f\n",zpos,zerr,nearestzone,zmin,zmax,probability));
2662 //------------------------------------------------------------------------
2663 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2666 // calculate normalized chi2
2668 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2670 for (Int_t i = 0;i<6;i++){
2671 if (TMath::Abs(track->GetDy(i))>0){
2672 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2673 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2676 else{chi2[i]=10000;}
2679 TMath::Sort(6,chi2,index,kFALSE);
2680 Float_t max = float(ncl)*fac-1.;
2681 Float_t sumchi=0, sumweight=0;
2682 for (Int_t i=0;i<max+1;i++){
2683 Float_t weight = (i<max)?1.:(max+1.-i);
2684 sumchi+=weight*chi2[index[i]];
2687 Double_t normchi2 = sumchi/sumweight;
2690 //------------------------------------------------------------------------
2691 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2694 // calculate normalized chi2
2695 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2698 for (Int_t i=0;i<6;i++){
2699 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2700 Double_t sy1 = forwardtrack->GetSigmaY(i);
2701 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2702 Double_t sy2 = backtrack->GetSigmaY(i);
2703 Double_t sz2 = backtrack->GetSigmaZ(i);
2704 if (i<2){ sy2=1000.;sz2=1000;}
2706 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2707 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2709 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2710 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2712 res+= nz0*nz0+ny0*ny0;
2715 if (npoints>1) return
2716 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2717 //2*forwardtrack->fNUsed+
2718 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2719 1./(1.+forwardtrack->GetNSkipped()));
2722 //------------------------------------------------------------------------
2723 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2724 //--------------------------------------------------------------------
2725 // Return pointer to a given cluster
2726 //--------------------------------------------------------------------
2727 Int_t l=(index & 0xf0000000) >> 28;
2728 Int_t c=(index & 0x0fffffff) >> 00;
2729 return fgLayers[l].GetWeight(c);
2731 //------------------------------------------------------------------------
2732 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2734 //---------------------------------------------
2735 // register track to the list
2737 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2740 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2741 Int_t index = track->GetClusterIndex(icluster);
2742 Int_t l=(index & 0xf0000000) >> 28;
2743 Int_t c=(index & 0x0fffffff) >> 00;
2744 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2745 for (Int_t itrack=0;itrack<4;itrack++){
2746 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2747 fgLayers[l].SetClusterTracks(itrack,c,id);
2753 //------------------------------------------------------------------------
2754 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2756 //---------------------------------------------
2757 // unregister track from the list
2758 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2759 Int_t index = track->GetClusterIndex(icluster);
2760 Int_t l=(index & 0xf0000000) >> 28;
2761 Int_t c=(index & 0x0fffffff) >> 00;
2762 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2763 for (Int_t itrack=0;itrack<4;itrack++){
2764 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2765 fgLayers[l].SetClusterTracks(itrack,c,-1);
2770 //------------------------------------------------------------------------
2771 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2773 //-------------------------------------------------------------
2774 //get number of shared clusters
2775 //-------------------------------------------------------------
2777 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2778 // mean number of clusters
2779 Float_t *ny = GetNy(id), *nz = GetNz(id);
2782 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2783 Int_t index = track->GetClusterIndex(icluster);
2784 Int_t l=(index & 0xf0000000) >> 28;
2785 Int_t c=(index & 0x0fffffff) >> 00;
2786 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2787 // if (ny[l]<1.e-13){
2788 // printf("problem\n");
2790 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2794 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2795 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2796 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2798 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2801 deltan = (cl->GetNz()-nz[l]);
2803 if (deltan>2.0) continue; // extended - highly probable shared cluster
2804 weight = 2./TMath::Max(3.+deltan,2.);
2806 for (Int_t itrack=0;itrack<4;itrack++){
2807 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2809 clist[l] = (AliITSRecPoint*)GetCluster(index);
2815 track->SetNUsed(shared);
2818 //------------------------------------------------------------------------
2819 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2822 // find first shared track
2824 // mean number of clusters
2825 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2827 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2828 Int_t sharedtrack=100000;
2829 Int_t tracks[24],trackindex=0;
2830 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2832 for (Int_t icluster=0;icluster<6;icluster++){
2833 if (clusterlist[icluster]<0) continue;
2834 Int_t index = clusterlist[icluster];
2835 Int_t l=(index & 0xf0000000) >> 28;
2836 Int_t c=(index & 0x0fffffff) >> 00;
2837 // if (ny[l]<1.e-13){
2838 // printf("problem\n");
2840 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2841 //if (l>3) continue;
2842 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2845 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2846 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2847 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2849 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2852 deltan = (cl->GetNz()-nz[l]);
2854 if (deltan>2.0) continue; // extended - highly probable shared cluster
2856 for (Int_t itrack=3;itrack>=0;itrack--){
2857 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2858 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2859 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2864 if (trackindex==0) return -1;
2866 sharedtrack = tracks[0];
2868 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2871 Int_t tracks2[24], cluster[24];
2872 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2875 for (Int_t i=0;i<trackindex;i++){
2876 if (tracks[i]<0) continue;
2877 tracks2[index] = tracks[i];
2879 for (Int_t j=i+1;j<trackindex;j++){
2880 if (tracks[j]<0) continue;
2881 if (tracks[j]==tracks[i]){
2889 for (Int_t i=0;i<index;i++){
2890 if (cluster[index]>max) {
2891 sharedtrack=tracks2[index];
2898 if (sharedtrack>=100000) return -1;
2900 // make list of overlaps
2902 for (Int_t icluster=0;icluster<6;icluster++){
2903 if (clusterlist[icluster]<0) continue;
2904 Int_t index = clusterlist[icluster];
2905 Int_t l=(index & 0xf0000000) >> 28;
2906 Int_t c=(index & 0x0fffffff) >> 00;
2907 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2908 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2910 if (cl->GetNy()>2) continue;
2911 if (cl->GetNz()>2) continue;
2914 if (cl->GetNy()>3) continue;
2915 if (cl->GetNz()>3) continue;
2918 for (Int_t itrack=3;itrack>=0;itrack--){
2919 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2920 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2928 //------------------------------------------------------------------------
2929 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2931 // try to find track hypothesys without conflicts
2932 // with minimal chi2;
2933 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2934 Int_t entries1 = arr1->GetEntriesFast();
2935 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2936 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2937 Int_t entries2 = arr2->GetEntriesFast();
2938 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2940 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2941 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2942 if (track10->Pt()>0.5+track20->Pt()) return track10;
2944 for (Int_t itrack=0;itrack<entries1;itrack++){
2945 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2946 UnRegisterClusterTracks(track,trackID1);
2949 for (Int_t itrack=0;itrack<entries2;itrack++){
2950 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2951 UnRegisterClusterTracks(track,trackID2);
2955 Float_t maxconflicts=6;
2956 Double_t maxchi2 =1000.;
2958 // get weight of hypothesys - using best hypothesy
2961 Int_t list1[6],list2[6];
2962 AliITSRecPoint *clist1[6], *clist2[6] ;
2963 RegisterClusterTracks(track10,trackID1);
2964 RegisterClusterTracks(track20,trackID2);
2965 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2966 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2967 UnRegisterClusterTracks(track10,trackID1);
2968 UnRegisterClusterTracks(track20,trackID2);
2971 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2972 Float_t nerry[6],nerrz[6];
2973 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2974 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2975 for (Int_t i=0;i<6;i++){
2976 if ( (erry1[i]>0) && (erry2[i]>0)) {
2977 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2978 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2980 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2981 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2983 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2984 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2985 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2988 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2989 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2990 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2998 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2999 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
3000 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
3001 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
3003 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
3004 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
3005 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
3007 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
3008 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
3009 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
3012 Double_t sumw = w1+w2;
3016 w1 = (d2+0.5)/(d1+d2+1.);
3017 w2 = (d1+0.5)/(d1+d2+1.);
3019 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
3020 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
3022 // get pair of "best" hypothesys
3024 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
3025 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
3027 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
3028 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
3029 //if (track1->fFakeRatio>0) continue;
3030 RegisterClusterTracks(track1,trackID1);
3031 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
3032 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
3034 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
3035 //if (track2->fFakeRatio>0) continue;
3037 RegisterClusterTracks(track2,trackID2);
3038 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
3039 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
3040 UnRegisterClusterTracks(track2,trackID2);
3042 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
3043 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
3044 if (nskipped>0.5) continue;
3046 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
3047 if (conflict1+1<cconflict1) continue;
3048 if (conflict2+1<cconflict2) continue;
3052 for (Int_t i=0;i<6;i++){
3054 Float_t c1 =0.; // conflict coeficients
3056 if (clist1[i]&&clist2[i]){
3059 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
3062 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
3064 c1 = 2./TMath::Max(3.+deltan,2.);
3065 c2 = 2./TMath::Max(3.+deltan,2.);
3071 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
3074 deltan = (clist1[i]->GetNz()-nz1[i]);
3076 c1 = 2./TMath::Max(3.+deltan,2.);
3083 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
3086 deltan = (clist2[i]->GetNz()-nz2[i]);
3088 c2 = 2./TMath::Max(3.+deltan,2.);
3094 if (TMath::Abs(track1->GetDy(i))>0.) {
3095 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
3096 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
3097 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
3098 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
3100 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
3103 if (TMath::Abs(track2->GetDy(i))>0.) {
3104 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
3105 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
3106 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
3107 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3110 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3112 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3113 if (chi21>0) sum+=w1;
3114 if (chi22>0) sum+=w2;
3117 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3118 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3119 Double_t normchi2 = 2*conflict+sumchi2/sum;
3120 if ( normchi2 <maxchi2 ){
3123 maxconflicts = conflict;
3127 UnRegisterClusterTracks(track1,trackID1);
3130 // if (maxconflicts<4 && maxchi2<th0){
3131 if (maxchi2<th0*2.){
3132 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3133 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3134 track1->SetChi2MIP(5,maxconflicts);
3135 track1->SetChi2MIP(6,maxchi2);
3136 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3137 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3138 track1->SetChi2MIP(8,index1);
3139 fBestTrackIndex[trackID1] =index1;
3140 UpdateESDtrack(track1, AliESDtrack::kITSin);
3142 else if (track10->GetChi2MIP(0)<th1){
3143 track10->SetChi2MIP(5,maxconflicts);
3144 track10->SetChi2MIP(6,maxchi2);
3145 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3146 UpdateESDtrack(track10,AliESDtrack::kITSin);
3149 for (Int_t itrack=0;itrack<entries1;itrack++){
3150 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3151 UnRegisterClusterTracks(track,trackID1);
3154 for (Int_t itrack=0;itrack<entries2;itrack++){
3155 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3156 UnRegisterClusterTracks(track,trackID2);
3159 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3160 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3161 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3162 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3163 RegisterClusterTracks(track10,trackID1);
3165 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3166 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3167 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3168 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3169 RegisterClusterTracks(track20,trackID2);
3174 //------------------------------------------------------------------------
3175 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3176 //--------------------------------------------------------------------
3177 // This function marks clusters assigned to the track
3178 //--------------------------------------------------------------------
3179 AliTracker::UseClusters(t,from);
3181 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3182 //if (c->GetQ()>2) c->Use();
3183 if (c->GetSigmaZ2()>0.1) c->Use();
3184 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3185 //if (c->GetQ()>2) c->Use();
3186 if (c->GetSigmaZ2()>0.1) c->Use();
3189 //------------------------------------------------------------------------
3190 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3192 //------------------------------------------------------------------
3193 // add track to the list of hypothesys
3194 //------------------------------------------------------------------
3196 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3197 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3199 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3201 array = new TObjArray(10);
3202 fTrackHypothesys.AddAt(array,esdindex);
3204 array->AddLast(track);
3206 //------------------------------------------------------------------------
3207 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3209 //-------------------------------------------------------------------
3210 // compress array of track hypothesys
3211 // keep only maxsize best hypothesys
3212 //-------------------------------------------------------------------
3213 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3214 if (! (fTrackHypothesys.At(esdindex)) ) return;
3215 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3216 Int_t entries = array->GetEntriesFast();
3218 //- find preliminary besttrack as a reference
3219 Float_t minchi2=10000;
3221 AliITStrackMI * besttrack=0;
3222 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3223 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3224 if (!track) continue;
3225 Float_t chi2 = NormalizedChi2(track,0);
3227 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3228 track->SetLabel(tpcLabel);
3230 track->SetFakeRatio(1.);
3231 CookLabel(track,0.); //For comparison only
3233 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3234 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3235 if (track->GetNumberOfClusters()<maxn) continue;
3236 maxn = track->GetNumberOfClusters();
3243 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3244 delete array->RemoveAt(itrack);
3248 if (!besttrack) return;
3251 //take errors of best track as a reference
3252 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3253 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3254 for (Int_t j=0;j<6;j++) {
3255 if (besttrack->GetClIndex(j)>=0){
3256 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3257 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3258 ny[j] = besttrack->GetNy(j);
3259 nz[j] = besttrack->GetNz(j);
3263 // calculate normalized chi2
3265 Float_t * chi2 = new Float_t[entries];
3266 Int_t * index = new Int_t[entries];
3267 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3268 for (Int_t itrack=0;itrack<entries;itrack++){
3269 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3271 AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3272 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3273 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3274 chi2[itrack] = track->GetChi2MIP(0);
3276 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3277 delete array->RemoveAt(itrack);
3283 TMath::Sort(entries,chi2,index,kFALSE);
3284 besttrack = (AliITStrackMI*)array->At(index[0]);
3285 if(besttrack) AliDebug(2,Form("ncls best track %d\n",besttrack->GetNumberOfClusters()));
3286 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3287 for (Int_t j=0;j<6;j++){
3288 if (besttrack->GetClIndex(j)>=0){
3289 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3290 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3291 ny[j] = besttrack->GetNy(j);
3292 nz[j] = besttrack->GetNz(j);
3297 // calculate one more time with updated normalized errors
3298 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3299 for (Int_t itrack=0;itrack<entries;itrack++){
3300 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3302 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3303 AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3304 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3305 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3308 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3309 delete array->RemoveAt(itrack);
3314 entries = array->GetEntriesFast();
3318 TObjArray * newarray = new TObjArray();
3319 TMath::Sort(entries,chi2,index,kFALSE);
3320 besttrack = (AliITStrackMI*)array->At(index[0]);
3322 AliDebug(2,Form("ncls best track %d %f %f\n",besttrack->GetNumberOfClusters(),besttrack->GetChi2MIP(0),chi2[index[0]]));
3324 for (Int_t j=0;j<6;j++){
3325 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3326 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3327 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3328 ny[j] = besttrack->GetNy(j);
3329 nz[j] = besttrack->GetNz(j);
3332 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3333 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3334 Float_t minn = besttrack->GetNumberOfClusters()-3;
3336 for (Int_t i=0;i<entries;i++){
3337 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3338 if (!track) continue;
3339 if (accepted>maxcut) break;
3340 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3341 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3342 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3343 delete array->RemoveAt(index[i]);
3347 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3348 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3349 if (!shortbest) accepted++;
3351 newarray->AddLast(array->RemoveAt(index[i]));
3352 for (Int_t j=0;j<6;j++){
3354 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3355 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3356 ny[j] = track->GetNy(j);
3357 nz[j] = track->GetNz(j);
3362 delete array->RemoveAt(index[i]);
3366 delete fTrackHypothesys.RemoveAt(esdindex);
3367 fTrackHypothesys.AddAt(newarray,esdindex);
3371 delete fTrackHypothesys.RemoveAt(esdindex);
3377 //------------------------------------------------------------------------
3378 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3380 //-------------------------------------------------------------
3381 // try to find best hypothesy
3382 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3383 //-------------------------------------------------------------
3384 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3385 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3386 if (!array) return 0;
3387 Int_t entries = array->GetEntriesFast();
3388 if (!entries) return 0;
3389 Float_t minchi2 = 100000;
3390 AliITStrackMI * besttrack=0;
3392 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3393 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3394 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3395 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3397 for (Int_t i=0;i<entries;i++){
3398 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3399 if (!track) continue;
3400 Float_t sigmarfi,sigmaz;
3401 GetDCASigma(track,sigmarfi,sigmaz);
3402 track->SetDnorm(0,sigmarfi);
3403 track->SetDnorm(1,sigmaz);
3405 track->SetChi2MIP(1,1000000);
3406 track->SetChi2MIP(2,1000000);
3407 track->SetChi2MIP(3,1000000);
3410 backtrack = new(backtrack) AliITStrackMI(*track);
3411 if (track->GetConstrain()) {
3412 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3413 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3414 backtrack->ResetCovariance(10.);
3416 backtrack->ResetCovariance(10.);
3418 backtrack->ResetClusters();
3420 Double_t x = original->GetX();
3421 if (!RefitAt(x,backtrack,track)) continue;
3423 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3424 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3425 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3426 track->SetChi22(GetMatchingChi2(backtrack,original));
3428 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3429 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3430 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3433 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3435 //forward track - without constraint
3436 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3437 forwardtrack->ResetClusters();
3439 RefitAt(x,forwardtrack,track);
3440 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3441 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3442 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3444 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3445 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3446 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3447 forwardtrack->SetD(0,track->GetD(0));
3448 forwardtrack->SetD(1,track->GetD(1));
3451 AliITSRecPoint* clist[6];
3452 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3453 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3456 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3457 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3458 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3459 track->SetChi2MIP(3,1000);
3462 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3464 for (Int_t ichi=0;ichi<5;ichi++){
3465 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3467 if (chi2 < minchi2){
3468 //besttrack = new AliITStrackMI(*forwardtrack);
3470 besttrack->SetLabel(track->GetLabel());
3471 besttrack->SetFakeRatio(track->GetFakeRatio());
3473 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3474 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3475 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3479 delete forwardtrack;
3481 for (Int_t i=0;i<entries;i++){
3482 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3484 if (!track) continue;
3486 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3487 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3488 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3489 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3490 delete array->RemoveAt(i);
3500 SortTrackHypothesys(esdindex,checkmax,1);
3502 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3503 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3504 besttrack = (AliITStrackMI*)array->At(0);
3505 if (!besttrack) return 0;
3506 besttrack->SetChi2MIP(8,0);
3507 fBestTrackIndex[esdindex]=0;
3508 entries = array->GetEntriesFast();
3509 AliITStrackMI *longtrack =0;
3511 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3512 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3513 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3514 if (!track->GetConstrain()) continue;
3515 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3516 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3517 if (track->GetChi2MIP(0)>4.) continue;
3518 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3521 //if (longtrack) besttrack=longtrack;
3524 AliITSRecPoint * clist[6];
3525 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3526 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3527 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3528 RegisterClusterTracks(besttrack,esdindex);
3535 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3536 if (sharedtrack>=0){
3538 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3540 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3546 if (shared>2.5) return 0;
3547 if (shared>1.0) return besttrack;
3549 // Don't sign clusters if not gold track
3551 if (!besttrack->IsGoldPrimary()) return besttrack;
3552 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3554 if (fConstraint[fPass]){
3558 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3559 for (Int_t i=0;i<6;i++){
3560 Int_t index = besttrack->GetClIndex(i);
3561 if (index<0) continue;
3562 Int_t ilayer = (index & 0xf0000000) >> 28;
3563 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3564 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3566 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3567 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3568 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3569 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3570 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3571 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3573 Bool_t cansign = kTRUE;
3574 for (Int_t itrack=0;itrack<entries; itrack++){
3575 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3576 if (!track) continue;
3577 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3578 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3584 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3585 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3586 if (!c->IsUsed()) c->Use();
3592 //------------------------------------------------------------------------
3593 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3596 // get "best" hypothesys
3599 Int_t nentries = itsTracks.GetEntriesFast();
3600 for (Int_t i=0;i<nentries;i++){
3601 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3602 if (!track) continue;
3603 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3604 if (!array) continue;
3605 if (array->GetEntriesFast()<=0) continue;
3607 AliITStrackMI* longtrack=0;
3609 Float_t maxchi2=1000;
3610 for (Int_t j=0;j<array->GetEntriesFast();j++){
3611 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3612 if (!trackHyp) continue;
3613 if (trackHyp->GetGoldV0()) {
3614 longtrack = trackHyp; //gold V0 track taken
3617 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3618 Float_t chi2 = trackHyp->GetChi2MIP(0);
3620 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3622 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3624 if (chi2 > maxchi2) continue;
3625 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3632 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3633 if (!longtrack) {longtrack = besttrack;}
3634 else besttrack= longtrack;
3638 AliITSRecPoint * clist[6];
3639 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3641 track->SetNUsed(shared);
3642 track->SetNSkipped(besttrack->GetNSkipped());
3643 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3645 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3649 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3650 //if (sharedtrack==-1) sharedtrack=0;
3651 if (sharedtrack>=0) {
3652 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3655 if (besttrack&&fAfterV0) {
3656 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3658 if (besttrack&&fConstraint[fPass])
3659 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3660 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3661 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3662 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3668 //------------------------------------------------------------------------
3669 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3670 //--------------------------------------------------------------------
3671 //This function "cooks" a track label. If label<0, this track is fake.
3672 //--------------------------------------------------------------------
3675 if (track->GetESDtrack()){
3676 tpcLabel = track->GetESDtrack()->GetTPCLabel();
3677 ULong_t trStatus=track->GetESDtrack()->GetStatus();
3678 if(!(trStatus&AliESDtrack::kTPCin)) tpcLabel=track->GetLabel(); // for ITSsa tracks
3680 track->SetChi2MIP(9,0);
3682 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3683 Int_t cindex = track->GetClusterIndex(i);
3684 Int_t l=(cindex & 0xf0000000) >> 28;
3685 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3687 for (Int_t ind=0;ind<3;ind++){
3688 if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
3689 //AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3691 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3694 Int_t nclusters = track->GetNumberOfClusters();
3695 if (nclusters > 0) //PH Some tracks don't have any cluster
3696 track->SetFakeRatio(double(nwrong)/double(nclusters));
3697 if (tpcLabel>0 && track->GetFakeRatio()>wrong) {
3698 track->SetLabel(-tpcLabel);
3700 track->SetLabel(tpcLabel);
3702 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3705 //------------------------------------------------------------------------
3706 void AliITStrackerMI::CookdEdx(AliITStrackMI* track){
3708 // Fill the dE/dx in this track
3710 track->SetChi2MIP(9,0);
3711 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3712 Int_t cindex = track->GetClusterIndex(i);
3713 Int_t l=(cindex & 0xf0000000) >> 28;
3714 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3715 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3717 for (Int_t ind=0;ind<3;ind++){
3718 if (cl->GetLabel(ind)==lab) isWrong=0;
3720 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3724 track->CookdEdx(low,up);
3726 //------------------------------------------------------------------------
3727 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3729 // Create some arrays
3731 if (fCoefficients) delete []fCoefficients;
3732 fCoefficients = new Float_t[ntracks*48];
3733 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3735 //------------------------------------------------------------------------
3736 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3739 // Compute predicted chi2
3741 Float_t erry,errz,covyz;
3742 Float_t theta = track->GetTgl();
3743 Float_t phi = track->GetSnp();
3744 phi = TMath::Abs(phi)*TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3745 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
3746 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()));
3747 // Take into account the mis-alignment (bring track to cluster plane)
3748 Double_t xTrOrig=track->GetX();
3749 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3750 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()));
3751 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
3752 // Bring the track back to detector plane in ideal geometry
3753 // [mis-alignment will be accounted for in UpdateMI()]
3754 if (!track->Propagate(xTrOrig)) return 1000.;
3756 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3757 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3759 chi2+=0.5*TMath::Min(delta/2,2.);
3760 chi2+=2.*cluster->GetDeltaProbability();
3763 track->SetNy(layer,ny);
3764 track->SetNz(layer,nz);
3765 track->SetSigmaY(layer,erry);
3766 track->SetSigmaZ(layer, errz);
3767 track->SetSigmaYZ(layer,covyz);
3768 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3769 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3773 //------------------------------------------------------------------------
3774 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3779 Int_t layer = (index & 0xf0000000) >> 28;
3780 track->SetClIndex(layer, index);
3781 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3782 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3783 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3784 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3788 if (TMath::Abs(cl->GetQ())<1.e-13) return 0; // ingore the "virtual" clusters
3791 // Take into account the mis-alignment (bring track to cluster plane)
3792 Double_t xTrOrig=track->GetX();
3793 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3794 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3795 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3796 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3798 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3801 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3802 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3803 c.SetSigmaYZ(track->GetSigmaYZ(layer));
3806 Int_t updated = track->UpdateMI(&c,chi2,index);
3807 // Bring the track back to detector plane in ideal geometry
3808 if (!track->Propagate(xTrOrig)) return 0;
3810 if(!updated) AliDebug(2,"update failed");
3814 //------------------------------------------------------------------------
3815 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3818 //DCA sigmas parameterization
3819 //to be paramterized using external parameters in future
3822 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3823 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3825 //------------------------------------------------------------------------
3826 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3829 // Clusters from delta electrons?
3831 Int_t entries = clusterArray->GetEntriesFast();
3832 if (entries<4) return;
3833 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3834 Int_t layer = cluster->GetLayer();
3835 if (layer>1) return;
3837 Int_t ncandidates=0;
3838 Float_t r = (layer>0)? 7:4;
3840 for (Int_t i=0;i<entries;i++){
3841 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3842 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3843 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3844 index[ncandidates] = i; //candidate to belong to delta electron track
3846 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3847 cl0->SetDeltaProbability(1);
3853 for (Int_t i=0;i<ncandidates;i++){
3854 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3855 if (cl0->GetDeltaProbability()>0.8) continue;
3858 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3859 sumy=sumz=sumy2=sumyz=sumw=0.0;
3860 for (Int_t j=0;j<ncandidates;j++){
3862 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3864 Float_t dz = cl0->GetZ()-cl1->GetZ();
3865 Float_t dy = cl0->GetY()-cl1->GetY();
3866 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3867 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3868 y[ncl] = cl1->GetY();
3869 z[ncl] = cl1->GetZ();
3870 sumy+= y[ncl]*weight;
3871 sumz+= z[ncl]*weight;
3872 sumy2+=y[ncl]*y[ncl]*weight;
3873 sumyz+=y[ncl]*z[ncl]*weight;
3878 if (ncl<4) continue;
3879 Float_t det = sumw*sumy2 - sumy*sumy;
3881 if (TMath::Abs(det)>0.01){
3882 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3883 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3884 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3887 Float_t z0 = sumyz/sumy;
3888 delta = TMath::Abs(cl0->GetZ()-z0);
3891 cl0->SetDeltaProbability(1-20.*delta);
3895 //------------------------------------------------------------------------
3896 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3901 track->UpdateESDtrack(flags);
3902 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3903 if (oldtrack) delete oldtrack;
3904 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3905 // if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3906 // printf("Problem\n");
3909 //------------------------------------------------------------------------
3910 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3912 // Get nearest upper layer close to the point xr.
3913 // rough approximation
3915 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3916 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3918 for (Int_t i=0;i<6;i++){
3919 if (radius<kRadiuses[i]){
3926 //------------------------------------------------------------------------
3927 void AliITStrackerMI::BuildMaterialLUT(TString material) {
3928 //--------------------------------------------------------------------
3929 // Fill a look-up table with mean material
3930 //--------------------------------------------------------------------
3934 Double_t point1[3],point2[3];
3935 Double_t phi,cosphi,sinphi,z;
3936 // 0-5 layers, 6 pipe, 7-8 shields
3937 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
3938 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
3940 Int_t ifirst=0,ilast=0;
3941 if(material.Contains("Pipe")) {
3943 } else if(material.Contains("Shields")) {
3945 } else if(material.Contains("Layers")) {
3948 Error("BuildMaterialLUT","Wrong layer name\n");
3951 for(Int_t imat=ifirst; imat<=ilast; imat++) {
3952 Double_t param[5]={0.,0.,0.,0.,0.};
3953 for (Int_t i=0; i<n; i++) {
3954 phi = 2.*TMath::Pi()*gRandom->Rndm();
3955 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
3956 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
3957 point1[0] = rmin[imat]*cosphi;
3958 point1[1] = rmin[imat]*sinphi;
3960 point2[0] = rmax[imat]*cosphi;
3961 point2[1] = rmax[imat]*sinphi;
3963 AliTracker::MeanMaterialBudget(point1,point2,mparam);
3964 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
3966 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
3968 fxOverX0Layer[imat] = param[1];
3969 fxTimesRhoLayer[imat] = param[0]*param[4];
3970 } else if(imat==6) {
3971 fxOverX0Pipe = param[1];
3972 fxTimesRhoPipe = param[0]*param[4];
3973 } else if(imat==7) {
3974 fxOverX0Shield[0] = param[1];
3975 fxTimesRhoShield[0] = param[0]*param[4];
3976 } else if(imat==8) {
3977 fxOverX0Shield[1] = param[1];
3978 fxTimesRhoShield[1] = param[0]*param[4];
3982 printf("%s\n",material.Data());
3983 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
3984 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
3985 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
3986 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
3987 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
3988 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
3989 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
3990 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
3991 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
3995 //------------------------------------------------------------------------
3996 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
3997 TString direction) {
3998 //-------------------------------------------------------------------
3999 // Propagate beyond beam pipe and correct for material
4000 // (material budget in different ways according to fUseTGeo value)
4001 // Add time if going outward (PropagateTo or PropagateToTGeo)
4002 //-------------------------------------------------------------------
4004 // Define budget mode:
4005 // 0: material from AliITSRecoParam (hard coded)
4006 // 1: material from TGeo in one step (on the fly)
4007 // 2: material from lut
4008 // 3: material from TGeo in one step (same for all hypotheses)
4021 if(fTrackingPhase.Contains("Clusters2Tracks"))
4022 { mode=3; } else { mode=1; }
4025 if(fTrackingPhase.Contains("Clusters2Tracks"))
4026 { mode=3; } else { mode=2; }
4032 if(fTrackingPhase.Contains("Default")) mode=0;
4034 Int_t index=fCurrentEsdTrack;
4036 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4037 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4039 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4041 Double_t xOverX0,x0,lengthTimesMeanDensity;
4045 xOverX0 = AliITSRecoParam::GetdPipe();
4046 x0 = AliITSRecoParam::GetX0Be();
4047 lengthTimesMeanDensity = xOverX0*x0;
4048 lengthTimesMeanDensity *= dir;
4049 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4052 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4055 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4056 xOverX0 = fxOverX0Pipe;
4057 lengthTimesMeanDensity = fxTimesRhoPipe;
4058 lengthTimesMeanDensity *= dir;
4059 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4062 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4063 if(fxOverX0PipeTrks[index]<0) {
4064 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4065 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4066 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4067 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4068 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4071 xOverX0 = fxOverX0PipeTrks[index];
4072 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4073 lengthTimesMeanDensity *= dir;
4074 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4080 //------------------------------------------------------------------------
4081 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4083 TString direction) {
4084 //-------------------------------------------------------------------
4085 // Propagate beyond SPD or SDD shield and correct for material
4086 // (material budget in different ways according to fUseTGeo value)
4087 // Add time if going outward (PropagateTo or PropagateToTGeo)
4088 //-------------------------------------------------------------------
4090 // Define budget mode:
4091 // 0: material from AliITSRecoParam (hard coded)
4092 // 1: material from TGeo in steps of X cm (on the fly)
4093 // X = AliITSRecoParam::GetStepSizeTGeo()
4094 // 2: material from lut
4095 // 3: material from TGeo in one step (same for all hypotheses)
4108 if(fTrackingPhase.Contains("Clusters2Tracks"))
4109 { mode=3; } else { mode=1; }
4112 if(fTrackingPhase.Contains("Clusters2Tracks"))
4113 { mode=3; } else { mode=2; }
4119 if(fTrackingPhase.Contains("Default")) mode=0;
4121 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4123 Int_t shieldindex=0;
4124 if (shield.Contains("SDD")) { // SDDouter
4125 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4127 } else if (shield.Contains("SPD")) { // SPDouter
4128 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4131 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4135 // do nothing if we are already beyond the shield
4136 Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4137 if(dir<0 && rTrack > rToGo) return 1; // going outward
4138 if(dir>0 && rTrack < rToGo) return 1; // going inward
4142 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4144 Int_t index=2*fCurrentEsdTrack+shieldindex;
4146 Double_t xOverX0,x0,lengthTimesMeanDensity;
4151 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4152 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4153 lengthTimesMeanDensity = xOverX0*x0;
4154 lengthTimesMeanDensity *= dir;
4155 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4158 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4159 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4162 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4163 xOverX0 = fxOverX0Shield[shieldindex];
4164 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4165 lengthTimesMeanDensity *= dir;
4166 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4169 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4170 if(fxOverX0ShieldTrks[index]<0) {
4171 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4172 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4173 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4174 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4175 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4178 xOverX0 = fxOverX0ShieldTrks[index];
4179 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4180 lengthTimesMeanDensity *= dir;
4181 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4187 //------------------------------------------------------------------------
4188 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4190 Double_t oldGlobXYZ[3],
4191 TString direction) {
4192 //-------------------------------------------------------------------
4193 // Propagate beyond layer and correct for material
4194 // (material budget in different ways according to fUseTGeo value)
4195 // Add time if going outward (PropagateTo or PropagateToTGeo)
4196 //-------------------------------------------------------------------
4198 // Define budget mode:
4199 // 0: material from AliITSRecoParam (hard coded)
4200 // 1: material from TGeo in stepsof X cm (on the fly)
4201 // X = AliITSRecoParam::GetStepSizeTGeo()
4202 // 2: material from lut
4203 // 3: material from TGeo in one step (same for all hypotheses)
4216 if(fTrackingPhase.Contains("Clusters2Tracks"))
4217 { mode=3; } else { mode=1; }
4220 if(fTrackingPhase.Contains("Clusters2Tracks"))
4221 { mode=3; } else { mode=2; }
4227 if(fTrackingPhase.Contains("Default")) mode=0;
4229 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4231 Double_t r=fgLayers[layerindex].GetR();
4232 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4234 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4236 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4238 Int_t index=6*fCurrentEsdTrack+layerindex;
4241 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4244 // back before material (no correction)
4246 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4247 if (!t->GetLocalXat(rOld,xOld)) return 0;
4248 if (!t->Propagate(xOld)) return 0;
4252 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4253 lengthTimesMeanDensity = xOverX0*x0;
4254 lengthTimesMeanDensity *= dir;
4255 // Bring the track beyond the material
4256 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4259 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4260 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4263 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4264 xOverX0 = fxOverX0Layer[layerindex];
4265 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4266 lengthTimesMeanDensity *= dir;
4267 // Bring the track beyond the material
4268 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4271 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4272 if(fxOverX0LayerTrks[index]<0) {
4273 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4274 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4275 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4276 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4277 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4278 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4281 xOverX0 = fxOverX0LayerTrks[index];
4282 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4283 lengthTimesMeanDensity *= dir;
4284 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4291 //------------------------------------------------------------------------
4292 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4293 //-----------------------------------------------------------------
4294 // Initialize LUT for storing material for each prolonged track
4295 //-----------------------------------------------------------------
4296 fxOverX0PipeTrks = new Float_t[ntracks];
4297 fxTimesRhoPipeTrks = new Float_t[ntracks];
4298 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4299 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4300 fxOverX0LayerTrks = new Float_t[ntracks*6];
4301 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4303 for(Int_t i=0; i<ntracks; i++) {
4304 fxOverX0PipeTrks[i] = -1.;
4305 fxTimesRhoPipeTrks[i] = -1.;
4307 for(Int_t j=0; j<ntracks*2; j++) {
4308 fxOverX0ShieldTrks[j] = -1.;
4309 fxTimesRhoShieldTrks[j] = -1.;
4311 for(Int_t k=0; k<ntracks*6; k++) {
4312 fxOverX0LayerTrks[k] = -1.;
4313 fxTimesRhoLayerTrks[k] = -1.;
4320 //------------------------------------------------------------------------
4321 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4322 //-----------------------------------------------------------------
4323 // Delete LUT for storing material for each prolonged track
4324 //-----------------------------------------------------------------
4325 if(fxOverX0PipeTrks) {
4326 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4328 if(fxOverX0ShieldTrks) {
4329 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4332 if(fxOverX0LayerTrks) {
4333 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4335 if(fxTimesRhoPipeTrks) {
4336 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4338 if(fxTimesRhoShieldTrks) {
4339 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4341 if(fxTimesRhoLayerTrks) {
4342 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4346 //------------------------------------------------------------------------
4347 void AliITStrackerMI::SetForceSkippingOfLayer() {
4348 //-----------------------------------------------------------------
4349 // Check if we are forced to skip layers
4350 // either we set to skip them in RecoParam
4351 // or they were off during data-taking
4352 //-----------------------------------------------------------------
4354 const AliEventInfo *eventInfo = GetEventInfo();
4356 for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
4357 fForceSkippingOfLayer[l] = 0;
4359 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
4363 AliITSReconstructor::GetRecoParam()->GetSkipSubdetsNotInTriggerCluster()) {
4364 AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
4366 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
4367 } else if(l==2 || l==3) {
4368 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1;
4370 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
4376 //------------------------------------------------------------------------
4377 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4378 Int_t ilayer,Int_t idet) const {
4379 //-----------------------------------------------------------------
4380 // This method is used to decide whether to allow a prolongation
4381 // without clusters, because we want to skip the layer.
4382 // In this case the return value is > 0:
4383 // return 1: the user requested to skip a layer
4384 // return 2: track outside z acceptance
4385 //-----------------------------------------------------------------
4387 if (ForceSkippingOfLayer(ilayer)) return 1;
4389 Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
4391 if (idet<0 && // out in z
4392 ilayer>innerLayCanSkip &&
4393 AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4394 // check if track will cross SPD outer layer
4395 Double_t phiAtSPD2,zAtSPD2;
4396 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4397 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4399 return 2; // always allow skipping, changed on 05.11.2009
4404 //------------------------------------------------------------------------
4405 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4406 Int_t ilayer,Int_t idet,
4407 Double_t dz,Double_t dy,
4408 Bool_t noClusters) const {
4409 //-----------------------------------------------------------------
4410 // This method is used to decide whether to allow a prolongation
4411 // without clusters, because there is a dead zone in the road.
4412 // In this case the return value is > 0:
4413 // return 1: dead zone at z=0,+-7cm in SPD
4414 // This method assumes that fSPDdetzcentre is ordered from -z to +z
4415 // return 2: all road is "bad" (dead or noisy) from the OCDB
4416 // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4417 // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4418 //-----------------------------------------------------------------
4420 // check dead zones at z=0,+-7cm in the SPD
4421 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4422 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4423 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4424 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4425 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4426 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4427 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4428 for (Int_t i=0; i<3; i++)
4429 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4430 AliDebug(2,Form("crack SPD %d track z %f %f %f %f\n",ilayer,track->GetZ(),dz,zmaxdead[i],zmindead[i]));
4431 if (GetSPDDeadZoneProbability(track->GetZ(),TMath::Sqrt(track->GetSigmaZ2()))>0.1) return 1;
4435 // check bad zones from OCDB
4436 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4438 if (idet<0) return 0;
4440 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4443 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4444 if (ilayer==0 || ilayer==1) { // ---------- SPD
4446 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4448 detSizeFactorX *= 2.;
4449 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4452 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4453 if (detType==2) segm->SetLayer(ilayer+1);
4454 Float_t detSizeX = detSizeFactorX*segm->Dx();
4455 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4457 // check if the road overlaps with bad chips
4459 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
4460 Float_t zlocmin = zloc-dz;
4461 Float_t zlocmax = zloc+dz;
4462 Float_t xlocmin = xloc-dy;
4463 Float_t xlocmax = xloc+dy;
4464 Int_t chipsInRoad[100];
4466 // check if road goes out of detector
4467 Bool_t touchNeighbourDet=kFALSE;
4468 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4469 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4470 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4471 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4472 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));
4474 // check if this detector is bad
4476 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4477 if(!touchNeighbourDet) {
4478 return 2; // all detectors in road are bad
4480 return 3; // at least one is bad
4484 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4485 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4486 if (!nChipsInRoad) return 0;
4488 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4489 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4490 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4491 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4492 if (det.IsChipBad(chipsInRoad[iCh])) {
4500 if(!touchNeighbourDet) {
4501 AliDebug(2,"all bad in road");
4502 return 2; // all chips in road are bad
4504 return 3; // at least a bad chip in road
4509 AliDebug(2,"at least a bad in road");
4510 return 3; // at least a bad chip in road
4514 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4515 || !noClusters) return 0;
4517 // There are no clusters in road: check if there is at least
4518 // a bad SPD pixel or SDD anode or SSD strips on both sides
4520 Int_t idetInITS=idet;
4521 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4523 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4524 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4527 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4531 //------------------------------------------------------------------------
4532 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4533 const AliITStrackMI *track,
4534 Float_t &xloc,Float_t &zloc) const {
4535 //-----------------------------------------------------------------
4536 // Gives position of track in local module ref. frame
4537 //-----------------------------------------------------------------
4542 if(idet<0) return kTRUE; // track out of z acceptance of layer
4544 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4546 Int_t lad = Int_t(idet/ndet) + 1;
4548 Int_t det = idet - (lad-1)*ndet + 1;
4550 Double_t xyzGlob[3],xyzLoc[3];
4552 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4553 // take into account the misalignment: xyz at real detector plane
4554 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4556 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4558 xloc = (Float_t)xyzLoc[0];
4559 zloc = (Float_t)xyzLoc[2];
4563 //------------------------------------------------------------------------
4564 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
4566 // Method to be optimized further:
4567 // Aim: decide whether a track can be used for PlaneEff evaluation
4568 // the decision is taken based on the track quality at the layer under study
4569 // no information on the clusters on this layer has to be used
4570 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4571 // the cut is done on number of sigmas from the boundaries
4573 // Input: Actual track, layer [0,5] under study
4575 // Return: kTRUE if this is a good track
4577 // it will apply a pre-selection to obtain good quality tracks.
4578 // Here also you will have the possibility to put a control on the
4579 // impact point of the track on the basic block, in order to exclude border regions
4580 // this will be done by calling a proper method of the AliITSPlaneEff class.
4582 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4583 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4585 Int_t index[AliITSgeomTGeo::kNLayers];
4587 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4589 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4590 index[k]=clusters[k];
4594 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4595 AliITSlayer &layer=fgLayers[ilayer];
4596 Double_t r=layer.GetR();
4597 AliITStrackMI tmp(*track);
4599 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4600 Int_t ncl_out=0; Int_t ncl_in=0;
4601 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) { // count n. of cluster in outermost layers
4602 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4603 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4604 if (tmp.GetClIndex(lay)>=0) ncl_out++;
4606 for(Int_t lay=ilayer-1; lay>=0;lay--) { // count n. of cluster in innermost layers
4607 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4608 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4609 if (tmp.GetClIndex(lay)>=0) ncl_in++;
4611 Int_t ncl=ncl_out+ncl_out;
4612 Bool_t nextout = kFALSE;
4613 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4614 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4615 Bool_t nextin = kFALSE;
4616 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4617 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4618 // maximum number of missing clusters allowed in outermost layers
4619 if(ncl_out<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersOutPlaneEff())
4621 // maximum number of missing clusters allowed (both in innermost and in outermost layers)
4622 if(ncl<AliITSgeomTGeo::kNLayers-1-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
4624 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
4625 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
4626 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
4627 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
4631 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4632 Int_t idet=layer.FindDetectorIndex(phi,z);
4633 if(idet<0) { AliInfo(Form("cannot find detector"));
4636 // here check if it has good Chi Square.
4638 //propagate to the intersection with the detector plane
4639 const AliITSdetector &det=layer.GetDetector(idet);
4640 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4644 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
4645 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4646 if(key>fPlaneEff->Nblock()) return kFALSE;
4647 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4648 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4650 // DEFINITION OF SEARCH ROAD FOR accepting a track
4652 //For the time being they are hard-wired, later on from AliITSRecoParam
4653 Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXFromBoundaryPlaneEff();
4654 Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZFromBoundaryPlaneEff();
4655 // Double_t nsigz=4;
4656 // Double_t nsigx=4;
4657 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4658 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4659 // done for RecPoints
4661 // exclude tracks at boundary between detectors
4662 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
4663 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4664 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
4665 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
4666 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
4668 if ( (locx-dx < blockXmn+boundaryWidth) ||
4669 (locx+dx > blockXmx-boundaryWidth) ||
4670 (locz-dz < blockZmn+boundaryWidth) ||
4671 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
4674 //------------------------------------------------------------------------
4675 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
4677 // This Method has to be optimized! For the time-being it uses the same criteria
4678 // as those used in the search of extra clusters for overlapping modules.
4680 // Method Purpose: estabilish whether a track has produced a recpoint or not
4681 // in the layer under study (For Plane efficiency)
4683 // inputs: AliITStrackMI* track (pointer to a usable track)
4685 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
4686 // traversed by this very track. In details:
4687 // - if a cluster can be associated to the track then call
4688 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
4689 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
4692 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
4693 AliITSlayer &layer=fgLayers[ilayer];
4694 Double_t r=layer.GetR();
4695 AliITStrackMI tmp(*track);
4699 if (!tmp.GetPhiZat(r,phi,z)) return;
4700 Int_t idet=layer.FindDetectorIndex(phi,z);
4702 if(idet<0) { AliInfo(Form("cannot find detector"));
4706 //propagate to the intersection with the detector plane
4707 const AliITSdetector &det=layer.GetDetector(idet);
4708 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
4712 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
4714 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
4715 TMath::Sqrt(tmp.GetSigmaZ2() +
4716 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4717 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4718 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
4719 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
4720 TMath::Sqrt(tmp.GetSigmaY2() +
4721 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4722 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4723 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
4725 // road in global (rphi,z) [i.e. in tracking ref. system]
4726 Double_t zmin = tmp.GetZ() - dz;
4727 Double_t zmax = tmp.GetZ() + dz;
4728 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
4729 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
4731 // select clusters in road
4732 layer.SelectClusters(zmin,zmax,ymin,ymax);
4734 // Define criteria for track-cluster association
4735 Double_t msz = tmp.GetSigmaZ2() +
4736 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4737 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4738 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
4739 Double_t msy = tmp.GetSigmaY2() +
4740 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4741 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4742 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
4743 if (tmp.GetConstrain()) {
4744 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
4745 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
4747 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
4748 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
4750 msz = 1./msz; // 1/RoadZ^2
4751 msy = 1./msy; // 1/RoadY^2
4754 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
4756 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
4757 //Double_t tolerance=0.2;
4758 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
4759 idetc = cl->GetDetectorIndex();
4760 if(idet!=idetc) continue;
4761 //Int_t ilay = cl->GetLayer();
4763 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
4764 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
4766 Double_t chi2=tmp.GetPredictedChi2(cl);
4767 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
4771 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
4773 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
4774 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4775 if(key>fPlaneEff->Nblock()) return;
4776 Bool_t found=kFALSE;
4779 while ((cl=layer.GetNextCluster(clidx))!=0) {
4780 idetc = cl->GetDetectorIndex();
4781 if(idet!=idetc) continue;
4782 // here real control to see whether the cluster can be associated to the track.
4783 // cluster not associated to track
4784 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
4785 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
4786 // calculate track-clusters chi2
4787 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
4788 // in particular, the error associated to the cluster
4789 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
4791 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
4793 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
4794 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
4795 // track->SetExtraModule(ilayer,idetExtra);
4797 if(!fPlaneEff->UpDatePlaneEff(found,key))
4798 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
4799 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
4800 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
4801 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
4802 Int_t cltype[2]={-999,-999};
4806 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4807 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4810 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
4811 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
4812 cltype[0]=layer.GetCluster(ci)->GetNy();
4813 cltype[1]=layer.GetCluster(ci)->GetNz();
4815 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
4816 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
4817 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
4818 // It is computed properly by calling the method
4819 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4821 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
4822 //if (tmp.PropagateTo(x,0.,0.)) {
4823 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
4824 AliCluster c(*layer.GetCluster(ci));
4825 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
4826 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
4827 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
4828 clu[2]=TMath::Sqrt(c.GetSigmaY2());
4829 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
4832 fPlaneEff->FillHistos(key,found,tr,clu,cltype);