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 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
242 // only for plane efficiency evaluation
243 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
244 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
245 Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
246 if(!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)==1)
247 AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
248 if (iplane<2) fPlaneEff = new AliITSPlaneEffSPD();
249 else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
250 else fPlaneEff = new AliITSPlaneEffSSD();
251 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
252 if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
253 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
256 //------------------------------------------------------------------------
257 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
259 fBestTrack(tracker.fBestTrack),
260 fTrackToFollow(tracker.fTrackToFollow),
261 fTrackHypothesys(tracker.fTrackHypothesys),
262 fBestHypothesys(tracker.fBestHypothesys),
263 fOriginal(tracker.fOriginal),
264 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
265 fPass(tracker.fPass),
266 fAfterV0(tracker.fAfterV0),
267 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
268 fCoefficients(tracker.fCoefficients),
270 fTrackingPhase(tracker.fTrackingPhase),
271 fUseTGeo(tracker.fUseTGeo),
272 fNtracks(tracker.fNtracks),
273 fxOverX0Pipe(tracker.fxOverX0Pipe),
274 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
276 fxTimesRhoPipeTrks(0),
277 fxOverX0ShieldTrks(0),
278 fxTimesRhoShieldTrks(0),
279 fxOverX0LayerTrks(0),
280 fxTimesRhoLayerTrks(0),
281 fDebugStreamer(tracker.fDebugStreamer),
282 fITSChannelStatus(tracker.fITSChannelStatus),
283 fkDetTypeRec(tracker.fkDetTypeRec),
284 fPlaneEff(tracker.fPlaneEff) {
286 fOriginal.SetOwner();
289 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
292 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
293 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
296 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
297 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
300 //------------------------------------------------------------------------
301 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
302 //Assignment operator
303 this->~AliITStrackerMI();
304 new(this) AliITStrackerMI(tracker);
307 //------------------------------------------------------------------------
308 AliITStrackerMI::~AliITStrackerMI()
313 if (fCoefficients) delete [] fCoefficients;
314 DeleteTrksMaterialLUT();
315 if (fDebugStreamer) {
316 //fDebugStreamer->Close();
317 delete fDebugStreamer;
319 if(fITSChannelStatus) delete fITSChannelStatus;
320 if(fPlaneEff) delete fPlaneEff;
322 //------------------------------------------------------------------------
323 void AliITStrackerMI::ReadBadFromDetTypeRec() {
324 //--------------------------------------------------------------------
325 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
327 //--------------------------------------------------------------------
329 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
331 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
333 if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
336 if(fITSChannelStatus) delete fITSChannelStatus;
337 fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
339 // ITS detectors and chips
340 Int_t i=0,j=0,k=0,ndet=0;
341 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
342 Int_t nBadDetsPerLayer=0;
343 ndet=AliITSgeomTGeo::GetNDetectors(i);
344 for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
345 for (k=1; k<ndet+1; k++) {
346 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
347 det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fkDetTypeRec);
348 if(det.IsBad()) {nBadDetsPerLayer++;}
349 } // end loop on detectors
350 } // end loop on ladders
351 Info("ReadBadFromDetTypeRec",Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
352 } // end loop on layers
356 //------------------------------------------------------------------------
357 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
358 //--------------------------------------------------------------------
359 //This function loads ITS clusters
360 //--------------------------------------------------------------------
362 TClonesArray *clusters = NULL;
363 AliITSRecPointContainer* rpcont=AliITSRecPointContainer::Instance();
364 clusters=rpcont->FetchClusters(0,cTree);
365 if(!(rpcont->IsSPDActive() || rpcont->IsSDDActive() || rpcont->IsSSDActive())){
366 AliError("ITS is not in a known running configuration: SPD, SDD and SSD are not active");
369 Int_t i=0,j=0,ndet=0;
371 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
372 ndet=fgLayers[i].GetNdetectors();
373 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
374 for (; j<jmax; j++) {
375 // if (!cTree->GetEvent(j)) continue;
376 clusters = rpcont->UncheckedGetClusters(j);
377 if(!clusters)continue;
378 Int_t ncl=clusters->GetEntriesFast();
379 SignDeltas(clusters,GetZ());
382 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
383 detector=c->GetDetectorIndex();
385 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
387 Int_t retval = fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
389 AliWarning(Form("Too many clusters on layer %d!",i));
394 // add dead zone "virtual" cluster in SPD, if there is a cluster within
395 // zwindow cm from the dead zone
396 // This method assumes that fSPDdetzcentre is ordered from -z to +z
397 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
398 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
399 Int_t lab[4] = {0,0,0,detector};
400 Int_t info[3] = {0,0,i};
401 Float_t q = 0.; // this identifies virtual clusters
402 Float_t hit[5] = {xdead,
404 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
405 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
407 Bool_t local = kTRUE;
408 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
409 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
410 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
411 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
412 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
413 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
414 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
415 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
416 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
417 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
418 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
419 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
420 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
421 hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
422 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
423 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
424 hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
425 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
426 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
428 } // "virtual" clusters in SPD
432 fgLayers[i].ResetRoad(); //road defined by the cluster density
433 fgLayers[i].SortClusters();
436 // check whether we have to skip some layers
437 SetForceSkippingOfLayer();
441 //------------------------------------------------------------------------
442 void AliITStrackerMI::UnloadClusters() {
443 //--------------------------------------------------------------------
444 //This function unloads ITS clusters
445 //--------------------------------------------------------------------
446 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
448 //------------------------------------------------------------------------
449 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
450 //--------------------------------------------------------------------
451 // Publishes all pointers to clusters known to the tracker into the
452 // passed object array.
453 // The ownership is not transfered - the caller is not expected to delete
455 //--------------------------------------------------------------------
457 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
458 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
459 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
466 //------------------------------------------------------------------------
467 Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
468 //--------------------------------------------------------------------
469 // Correction for the material between the TPC and the ITS
470 //--------------------------------------------------------------------
471 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
472 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
473 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
474 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
475 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
476 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
477 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
478 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
480 printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
486 //------------------------------------------------------------------------
487 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
488 //--------------------------------------------------------------------
489 // This functions reconstructs ITS tracks
490 // The clusters must be already loaded !
491 //--------------------------------------------------------------------
493 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
495 fTrackingPhase="Clusters2Tracks";
497 TObjArray itsTracks(15000);
499 fEsd = event; // store pointer to the esd
501 // temporary (for cosmics)
502 if(event->GetVertex()) {
503 TString title = event->GetVertex()->GetTitle();
504 if(title.Contains("cosmics")) {
505 Double_t xyz[3]={GetX(),GetY(),GetZ()};
506 Double_t exyz[3]={0.1,0.1,0.1};
512 {/* Read ESD tracks */
513 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
514 Int_t nentr=event->GetNumberOfTracks();
516 // Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
518 AliESDtrack *esd=event->GetTrack(nentr);
519 // ---- for debugging:
520 //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); }
522 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
523 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
524 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
525 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
528 t=new AliITStrackMI(*esd);
529 } catch (const Char_t *msg) {
530 //Warning("Clusters2Tracks",msg);
534 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
535 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
538 // look at the ESD mass hypothesys !
539 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
541 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
543 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
544 //track - can be V0 according to TPC
546 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
550 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
554 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
558 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
563 t->SetReconstructed(kFALSE);
564 itsTracks.AddLast(t);
565 fOriginal.AddLast(t);
567 } /* End Read ESD tracks */
571 Int_t nentr=itsTracks.GetEntriesFast();
572 fTrackHypothesys.Expand(nentr);
573 fBestHypothesys.Expand(nentr);
574 MakeCoefficients(nentr);
575 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
577 // THE TWO TRACKING PASSES
578 for (fPass=0; fPass<2; fPass++) {
579 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
580 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
581 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
582 if (t==0) continue; //this track has been already tracked
583 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
584 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
585 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
586 if (fConstraint[fPass]) {
587 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
588 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
591 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
592 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
594 ResetTrackToFollow(*t);
597 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
600 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
602 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
603 if (!besttrack) continue;
604 besttrack->SetLabel(tpcLabel);
605 // besttrack->CookdEdx();
607 besttrack->SetFakeRatio(1.);
608 CookLabel(besttrack,0.); //For comparison only
609 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
611 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
613 t->SetReconstructed(kTRUE);
615 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
617 GetBestHypothesysMIP(itsTracks);
618 } // end loop on the two tracking passes
620 if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
621 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
626 Int_t entries = fTrackHypothesys.GetEntriesFast();
627 for (Int_t ientry=0; ientry<entries; ientry++) {
628 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
629 if (array) array->Delete();
630 delete fTrackHypothesys.RemoveAt(ientry);
633 fTrackHypothesys.Delete();
634 entries = fBestHypothesys.GetEntriesFast();
635 for (Int_t ientry=0; ientry<entries; ientry++) {
636 TObjArray * array =(TObjArray*)fBestHypothesys.UncheckedAt(ientry);
637 if (array) array->Delete();
638 delete fBestHypothesys.RemoveAt(ientry);
640 fBestHypothesys.Delete();
642 delete [] fCoefficients;
644 DeleteTrksMaterialLUT();
646 AliInfo(Form("Number of prolonged tracks: %d out of %d ESD tracks",ntrk,noesd));
648 fTrackingPhase="Default";
652 //------------------------------------------------------------------------
653 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
654 //--------------------------------------------------------------------
655 // This functions propagates reconstructed ITS tracks back
656 // The clusters must be loaded !
657 //--------------------------------------------------------------------
658 fTrackingPhase="PropagateBack";
659 Int_t nentr=event->GetNumberOfTracks();
660 // Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
663 for (Int_t i=0; i<nentr; i++) {
664 AliESDtrack *esd=event->GetTrack(i);
666 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
667 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
671 t=new AliITStrackMI(*esd);
672 } catch (const Char_t *msg) {
673 //Warning("PropagateBack",msg);
677 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
679 ResetTrackToFollow(*t);
682 // propagate to vertex [SR, GSI 17.02.2003]
683 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
684 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
685 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
686 fTrackToFollow.StartTimeIntegral();
687 // from vertex to outside pipe
688 CorrectForPipeMaterial(&fTrackToFollow,"outward");
690 // Start time integral and add distance from current position to vertex
691 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
692 fTrackToFollow.GetXYZ(xyzTrk);
694 for (Int_t icoord=0; icoord<3; icoord++) {
695 Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
698 fTrackToFollow.StartTimeIntegral();
699 fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
701 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
702 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
703 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
707 fTrackToFollow.SetLabel(t->GetLabel());
708 //fTrackToFollow.CookdEdx();
709 CookLabel(&fTrackToFollow,0.); //For comparison only
710 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
711 //UseClusters(&fTrackToFollow);
717 AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
719 fTrackingPhase="Default";
723 //------------------------------------------------------------------------
724 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
725 //--------------------------------------------------------------------
726 // This functions refits ITS tracks using the
727 // "inward propagated" TPC tracks
728 // The clusters must be loaded !
729 //--------------------------------------------------------------------
730 fTrackingPhase="RefitInward";
732 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
734 Int_t nentr=event->GetNumberOfTracks();
735 // Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
738 for (Int_t i=0; i<nentr; i++) {
739 AliESDtrack *esd=event->GetTrack(i);
741 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
742 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
743 if (esd->GetStatus()&AliESDtrack::kTPCout)
744 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
748 t=new AliITStrackMI(*esd);
749 } catch (const Char_t *msg) {
750 //Warning("RefitInward",msg);
754 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
755 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
760 ResetTrackToFollow(*t);
761 fTrackToFollow.ResetClusters();
763 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
764 fTrackToFollow.ResetCovariance(10.);
767 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
768 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
770 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
771 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
772 AliDebug(2," refit OK");
773 fTrackToFollow.SetLabel(t->GetLabel());
774 // fTrackToFollow.CookdEdx();
775 CookdEdx(&fTrackToFollow);
777 CookLabel(&fTrackToFollow,0.0); //For comparison only
780 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
781 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
782 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
783 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
784 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
785 Double_t r[3]={0.,0.,0.};
787 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
794 AliInfo(Form("Number of refitted tracks: %d out of %d ESD tracks",ntrk,nentr));
796 fTrackingPhase="Default";
800 //------------------------------------------------------------------------
801 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
802 //--------------------------------------------------------------------
803 // Return pointer to a given cluster
804 //--------------------------------------------------------------------
805 Int_t l=(index & 0xf0000000) >> 28;
806 Int_t c=(index & 0x0fffffff) >> 00;
807 return fgLayers[l].GetCluster(c);
809 //------------------------------------------------------------------------
810 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
811 //--------------------------------------------------------------------
812 // Get track space point with index i
813 //--------------------------------------------------------------------
815 Int_t l=(index & 0xf0000000) >> 28;
816 Int_t c=(index & 0x0fffffff) >> 00;
817 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
818 Int_t idet = cl->GetDetectorIndex();
822 cl->GetGlobalXYZ(xyz);
823 cl->GetGlobalCov(cov);
825 p.SetCharge(cl->GetQ());
826 p.SetDriftTime(cl->GetDriftTime());
827 p.SetChargeRatio(cl->GetChargeRatio());
828 p.SetClusterType(cl->GetClusterType());
829 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
832 iLayer = AliGeomManager::kSPD1;
835 iLayer = AliGeomManager::kSPD2;
838 iLayer = AliGeomManager::kSDD1;
841 iLayer = AliGeomManager::kSDD2;
844 iLayer = AliGeomManager::kSSD1;
847 iLayer = AliGeomManager::kSSD2;
850 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
853 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
854 p.SetVolumeID((UShort_t)volid);
857 //------------------------------------------------------------------------
858 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
859 AliTrackPoint& p, const AliESDtrack *t) {
860 //--------------------------------------------------------------------
861 // Get track space point with index i
862 // (assign error estimated during the tracking)
863 //--------------------------------------------------------------------
865 Int_t l=(index & 0xf0000000) >> 28;
866 Int_t c=(index & 0x0fffffff) >> 00;
867 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
868 Int_t idet = cl->GetDetectorIndex();
870 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
872 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
874 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
875 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
876 Double_t alpha = t->GetAlpha();
877 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
878 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,GetBz()));
879 phi += alpha-det.GetPhi();
880 Float_t tgphi = TMath::Tan(phi);
882 Float_t tgl = t->GetTgl(); // tgl about const along track
883 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
885 Float_t errtrky,errtrkz,covyz;
886 Bool_t addMisalErr=kFALSE;
887 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
891 cl->GetGlobalXYZ(xyz);
892 // cl->GetGlobalCov(cov);
893 Float_t pos[3] = {0.,0.,0.};
894 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
895 tmpcl.GetGlobalCov(cov);
898 p.SetCharge(cl->GetQ());
899 p.SetDriftTime(cl->GetDriftTime());
900 p.SetChargeRatio(cl->GetChargeRatio());
901 p.SetClusterType(cl->GetClusterType());
903 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
906 iLayer = AliGeomManager::kSPD1;
909 iLayer = AliGeomManager::kSPD2;
912 iLayer = AliGeomManager::kSDD1;
915 iLayer = AliGeomManager::kSDD2;
918 iLayer = AliGeomManager::kSSD1;
921 iLayer = AliGeomManager::kSSD2;
924 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
927 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
929 p.SetVolumeID((UShort_t)volid);
932 //------------------------------------------------------------------------
933 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
935 //--------------------------------------------------------------------
936 // Follow prolongation tree
937 //--------------------------------------------------------------------
939 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
940 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
943 AliESDtrack * esd = otrack->GetESDtrack();
944 if (esd->GetV0Index(0)>0) {
945 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
946 // mapping of ESD track is different as ITS track in Containers
947 // Need something more stable
948 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
949 for (Int_t i=0;i<3;i++){
950 Int_t index = esd->GetV0Index(i);
952 AliESDv0 * vertex = fEsd->GetV0(index);
953 if (vertex->GetStatus()<0) continue; // rejected V0
955 if (esd->GetSign()>0) {
956 vertex->SetIndex(0,esdindex);
958 vertex->SetIndex(1,esdindex);
962 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
964 bestarray = new TObjArray(5);
965 bestarray->SetOwner();
966 fBestHypothesys.AddAt(bestarray,esdindex);
970 //setup tree of the prolongations
972 static AliITStrackMI tracks[7][100];
973 AliITStrackMI *currenttrack;
974 static AliITStrackMI currenttrack1;
975 static AliITStrackMI currenttrack2;
976 static AliITStrackMI backuptrack;
978 Int_t nindexes[7][100];
979 Float_t normalizedchi2[100];
980 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
981 otrack->SetNSkipped(0);
982 new (&(tracks[6][0])) AliITStrackMI(*otrack);
984 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
985 Int_t modstatus = 1; // found
989 // follow prolongations
990 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
991 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
994 AliITSlayer &layer=fgLayers[ilayer];
995 Double_t r = layer.GetR();
1001 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
1003 if (ntracks[ilayer]>=100) break;
1004 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
1005 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
1006 if (ntracks[ilayer]>15+ilayer){
1007 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
1008 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
1011 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
1013 // material between SSD and SDD, SDD and SPD
1015 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
1017 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
1021 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
1022 Int_t idet=layer.FindDetectorIndex(phi,z);
1024 Double_t trackGlobXYZ1[3];
1025 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1027 // Get the budget to the primary vertex for the current track being prolonged
1028 Double_t budgetToPrimVertex = GetEffectiveThickness();
1030 // check if we allow a prolongation without point
1031 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1033 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1034 // propagate to the layer radius
1035 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1036 if(!vtrack->Propagate(xToGo)) continue;
1037 // apply correction for material of the current layer
1038 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1039 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1040 vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1041 vtrack->SetClIndex(ilayer,-1);
1042 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1043 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1044 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1046 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1051 // track outside layer acceptance in z
1052 if (idet<0) continue;
1054 //propagate to the intersection with the detector plane
1055 const AliITSdetector &det=layer.GetDetector(idet);
1056 new(¤ttrack2) AliITStrackMI(currenttrack1);
1057 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1058 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1059 currenttrack1.SetDetectorIndex(idet);
1060 currenttrack2.SetDetectorIndex(idet);
1061 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1064 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1066 // road in global (rphi,z) [i.e. in tracking ref. system]
1067 Double_t zmin,zmax,ymin,ymax;
1068 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1070 // select clusters in road
1071 layer.SelectClusters(zmin,zmax,ymin,ymax);
1072 //********************
1074 // Define criteria for track-cluster association
1075 Double_t msz = currenttrack1.GetSigmaZ2() +
1076 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1077 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1078 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1079 Double_t msy = currenttrack1.GetSigmaY2() +
1080 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1081 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1082 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1084 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1085 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1087 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1088 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1090 msz = 1./msz; // 1/RoadZ^2
1091 msy = 1./msy; // 1/RoadY^2
1095 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1097 const AliITSRecPoint *cl=0;
1099 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1100 Bool_t deadzoneSPD=kFALSE;
1101 currenttrack = ¤ttrack1;
1103 // check if the road contains a dead zone
1104 Bool_t noClusters = kFALSE;
1105 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1106 if (noClusters) AliDebug(2,"no clusters in road");
1107 Double_t dz=0.5*(zmax-zmin);
1108 Double_t dy=0.5*(ymax-ymin);
1109 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1110 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1111 // create a prolongation without clusters (check also if there are no clusters in the road)
1114 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1115 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1116 updatetrack->SetClIndex(ilayer,-1);
1118 modstatus = 5; // no cls in road
1119 } else if (dead==1) {
1120 modstatus = 7; // holes in z in SPD
1121 } else if (dead==2 || dead==3 || dead==4) {
1122 modstatus = 2; // dead from OCDB
1124 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1125 // apply correction for material of the current layer
1126 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1127 if (constrain) { // apply vertex constrain
1128 updatetrack->SetConstrain(constrain);
1129 Bool_t isPrim = kTRUE;
1130 if (ilayer<4) { // check that it's close to the vertex
1131 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1132 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1133 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1134 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1135 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1137 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1139 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1141 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1142 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1144 } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1145 updatetrack->SetDeadZoneProbability(ilayer,1.);
1146 } else if (dead==4) { // at least a single dead channel from OCDB
1147 updatetrack->SetDeadZoneProbability(ilayer,0.);
1154 // loop over clusters in the road
1155 while ((cl=layer.GetNextCluster(clidx))!=0) {
1156 if (ntracks[ilayer]>95) break; //space for skipped clusters
1157 Bool_t changedet =kFALSE;
1158 if (TMath::Abs(cl->GetQ())<1.e-13 && deadzoneSPD==kTRUE) continue;
1159 Int_t idetc=cl->GetDetectorIndex();
1161 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1162 // take into account misalignment (bring track to real detector plane)
1163 Double_t xTrOrig = currenttrack->GetX();
1164 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1165 // a first cut on track-cluster distance
1166 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1167 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1168 { // cluster not associated to track
1169 AliDebug(2,"not associated");
1172 // bring track back to ideal detector plane
1173 if (!currenttrack->Propagate(xTrOrig)) continue;
1174 } else { // have to move track to cluster's detector
1175 const AliITSdetector &detc=layer.GetDetector(idetc);
1176 // a first cut on track-cluster distance
1178 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1179 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1180 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1181 continue; // cluster not associated to track
1183 new (&backuptrack) AliITStrackMI(currenttrack2);
1185 currenttrack =¤ttrack2;
1186 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1187 new (currenttrack) AliITStrackMI(backuptrack);
1191 currenttrack->SetDetectorIndex(idetc);
1192 // Get again the budget to the primary vertex
1193 // for the current track being prolonged, if had to change detector
1194 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1197 // calculate track-clusters chi2
1198 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1200 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1201 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1202 if (TMath::Abs(cl->GetQ())<1.e-13) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1203 if (ntracks[ilayer]>=100) continue;
1204 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1205 updatetrack->SetClIndex(ilayer,-1);
1206 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1208 if (TMath::Abs(cl->GetQ())>1.e-13) { // real cluster
1209 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1210 AliDebug(2,"update failed");
1213 updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1214 modstatus = 1; // found
1215 } else { // virtual cluster in dead zone
1216 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1217 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1218 modstatus = 7; // holes in z in SPD
1222 Float_t xlocnewdet,zlocnewdet;
1223 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1224 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1227 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1229 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1231 // apply correction for material of the current layer
1232 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1234 if (constrain) { // apply vertex constrain
1235 updatetrack->SetConstrain(constrain);
1236 Bool_t isPrim = kTRUE;
1237 if (ilayer<4) { // check that it's close to the vertex
1238 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1239 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1240 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1241 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1242 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1244 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1245 } //apply vertex constrain
1247 } // create new hypothesis
1249 AliDebug(2,"chi2 too large");
1252 } // loop over possible prolongations
1254 // allow one prolongation without clusters
1255 if (constrain && itrack<=1 && TMath::Abs(currenttrack1.GetNSkipped())<1.e-13 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1256 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1257 // apply correction for material of the current layer
1258 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1259 vtrack->SetClIndex(ilayer,-1);
1260 modstatus = 3; // skipped
1261 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1262 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1263 vtrack->IncrementNSkipped();
1268 } // loop over tracks in layer ilayer+1
1270 //loop over track candidates for the current layer
1276 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1277 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1278 if (normalizedchi2[itrack] <
1279 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1283 if (constrain) { // constrain
1284 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1286 } else { // !constrain
1287 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1292 // sort tracks by increasing normalized chi2
1293 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1294 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1295 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1296 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1297 } // end loop over layers
1301 // Now select tracks to be kept
1303 Int_t max = constrain ? 20 : 5;
1305 // tracks that reach layer 0 (SPD inner)
1306 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1307 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1308 if (track.GetNumberOfClusters()<2) continue;
1309 if (!constrain && track.GetNormChi2(0) >
1310 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1313 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1316 // tracks that reach layer 1 (SPD outer)
1317 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1318 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1319 if (track.GetNumberOfClusters()<4) continue;
1320 if (!constrain && track.GetNormChi2(1) >
1321 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1322 if (constrain) track.IncrementNSkipped();
1324 track.SetD(0,track.GetD(GetX(),GetY()));
1325 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1326 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1327 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1330 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1333 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1335 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1336 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1337 if (track.GetNumberOfClusters()<3) continue;
1338 if (!constrain && track.GetNormChi2(2) >
1339 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1340 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1342 track.SetD(0,track.GetD(GetX(),GetY()));
1343 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1344 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1345 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1348 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1354 // register best track of each layer - important for V0 finder
1356 for (Int_t ilayer=0;ilayer<5;ilayer++){
1357 if (ntracks[ilayer]==0) continue;
1358 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1359 if (track.GetNumberOfClusters()<1) continue;
1360 CookLabel(&track,0);
1361 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1365 // update TPC V0 information
1367 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1368 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1369 for (Int_t i=0;i<3;i++){
1370 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1371 if (index==0) break;
1372 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1373 if (vertex->GetStatus()<0) continue; // rejected V0
1375 if (otrack->GetSign()>0) {
1376 vertex->SetIndex(0,esdindex);
1379 vertex->SetIndex(1,esdindex);
1381 //find nearest layer with track info
1382 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1383 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1384 Int_t nearest = nearestold;
1385 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1386 if (ntracks[nearest]==0){
1391 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1392 if (nearestold<5&&nearest<5){
1393 Bool_t accept = track.GetNormChi2(nearest)<10;
1395 if (track.GetSign()>0) {
1396 vertex->SetParamP(track);
1397 vertex->Update(fprimvertex);
1398 //vertex->SetIndex(0,track.fESDtrack->GetID());
1399 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1401 vertex->SetParamN(track);
1402 vertex->Update(fprimvertex);
1403 //vertex->SetIndex(1,track.fESDtrack->GetID());
1404 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1406 vertex->SetStatus(vertex->GetStatus()+1);
1408 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1415 //------------------------------------------------------------------------
1416 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1418 //--------------------------------------------------------------------
1421 return fgLayers[layer];
1423 //------------------------------------------------------------------------
1424 AliITStrackerMI::AliITSlayer::AliITSlayer():
1454 //--------------------------------------------------------------------
1455 //default AliITSlayer constructor
1456 //--------------------------------------------------------------------
1457 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1458 fClusterWeight[i]=0;
1459 fClusterTracks[0][i]=-1;
1460 fClusterTracks[1][i]=-1;
1461 fClusterTracks[2][i]=-1;
1462 fClusterTracks[3][i]=-1;
1465 //------------------------------------------------------------------------
1466 AliITStrackerMI::AliITSlayer::
1467 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1496 //--------------------------------------------------------------------
1497 //main AliITSlayer constructor
1498 //--------------------------------------------------------------------
1499 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1500 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1502 //------------------------------------------------------------------------
1503 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1505 fPhiOffset(layer.fPhiOffset),
1506 fNladders(layer.fNladders),
1507 fZOffset(layer.fZOffset),
1508 fNdetectors(layer.fNdetectors),
1509 fDetectors(layer.fDetectors),
1514 fClustersCs(layer.fClustersCs),
1515 fClusterIndexCs(layer.fClusterIndexCs),
1519 fCurrentSlice(layer.fCurrentSlice),
1527 fAccepted(layer.fAccepted),
1529 fMaxSigmaClY(layer.fMaxSigmaClY),
1530 fMaxSigmaClZ(layer.fMaxSigmaClZ),
1531 fNMaxSigmaCl(layer.fNMaxSigmaCl)
1535 //------------------------------------------------------------------------
1536 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1537 //--------------------------------------------------------------------
1538 // AliITSlayer destructor
1539 //--------------------------------------------------------------------
1540 delete [] fDetectors;
1541 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1542 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1543 fClusterWeight[i]=0;
1544 fClusterTracks[0][i]=-1;
1545 fClusterTracks[1][i]=-1;
1546 fClusterTracks[2][i]=-1;
1547 fClusterTracks[3][i]=-1;
1550 //------------------------------------------------------------------------
1551 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1552 //--------------------------------------------------------------------
1553 // This function removes loaded clusters
1554 //--------------------------------------------------------------------
1555 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1556 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1557 fClusterWeight[i]=0;
1558 fClusterTracks[0][i]=-1;
1559 fClusterTracks[1][i]=-1;
1560 fClusterTracks[2][i]=-1;
1561 fClusterTracks[3][i]=-1;
1567 //------------------------------------------------------------------------
1568 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1569 //--------------------------------------------------------------------
1570 // This function reset weights of the clusters
1571 //--------------------------------------------------------------------
1572 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1573 fClusterWeight[i]=0;
1574 fClusterTracks[0][i]=-1;
1575 fClusterTracks[1][i]=-1;
1576 fClusterTracks[2][i]=-1;
1577 fClusterTracks[3][i]=-1;
1579 for (Int_t i=0; i<fN;i++) {
1580 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1581 if (cl&&cl->IsUsed()) cl->Use();
1585 //------------------------------------------------------------------------
1586 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1587 //--------------------------------------------------------------------
1588 // This function calculates the road defined by the cluster density
1589 //--------------------------------------------------------------------
1591 for (Int_t i=0; i<fN; i++) {
1592 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1594 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1596 //------------------------------------------------------------------------
1597 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1598 //--------------------------------------------------------------------
1599 //This function adds a cluster to this layer
1600 //--------------------------------------------------------------------
1601 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1607 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1609 Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
1610 Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2());
1611 if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
1612 if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
1613 if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
1614 if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
1617 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1618 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1619 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1620 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1624 //------------------------------------------------------------------------
1625 void AliITStrackerMI::AliITSlayer::SortClusters()
1630 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1631 Float_t *z = new Float_t[fN];
1632 Int_t * index = new Int_t[fN];
1634 fMaxSigmaClY=0.; //AD
1635 fMaxSigmaClZ=0.; //AD
1637 for (Int_t i=0;i<fN;i++){
1638 z[i] = fClusters[i]->GetZ();
1639 // save largest errors in y and z for this layer
1640 fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
1641 fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
1643 TMath::Sort(fN,z,index,kFALSE);
1644 for (Int_t i=0;i<fN;i++){
1645 clusters[i] = fClusters[index[i]];
1648 for (Int_t i=0;i<fN;i++){
1649 fClusters[i] = clusters[i];
1650 fZ[i] = fClusters[i]->GetZ();
1651 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1652 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1653 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1663 for (Int_t i=0;i<fN;i++){
1664 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1665 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1666 fClusterIndex[i] = i;
1670 fDy5 = (fYB[1]-fYB[0])/5.;
1671 fDy10 = (fYB[1]-fYB[0])/10.;
1672 fDy20 = (fYB[1]-fYB[0])/20.;
1673 for (Int_t i=0;i<6;i++) fN5[i] =0;
1674 for (Int_t i=0;i<11;i++) fN10[i]=0;
1675 for (Int_t i=0;i<21;i++) fN20[i]=0;
1677 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;}
1678 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;}
1679 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;}
1682 for (Int_t i=0;i<fN;i++)
1683 for (Int_t irot=-1;irot<=1;irot++){
1684 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1686 for (Int_t slice=0; slice<6;slice++){
1687 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1688 fClusters5[slice][fN5[slice]] = fClusters[i];
1689 fY5[slice][fN5[slice]] = curY;
1690 fZ5[slice][fN5[slice]] = fZ[i];
1691 fClusterIndex5[slice][fN5[slice]]=i;
1696 for (Int_t slice=0; slice<11;slice++){
1697 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1698 fClusters10[slice][fN10[slice]] = fClusters[i];
1699 fY10[slice][fN10[slice]] = curY;
1700 fZ10[slice][fN10[slice]] = fZ[i];
1701 fClusterIndex10[slice][fN10[slice]]=i;
1706 for (Int_t slice=0; slice<21;slice++){
1707 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1708 fClusters20[slice][fN20[slice]] = fClusters[i];
1709 fY20[slice][fN20[slice]] = curY;
1710 fZ20[slice][fN20[slice]] = fZ[i];
1711 fClusterIndex20[slice][fN20[slice]]=i;
1718 // consistency check
1720 for (Int_t i=0;i<fN-1;i++){
1726 for (Int_t slice=0;slice<21;slice++)
1727 for (Int_t i=0;i<fN20[slice]-1;i++){
1728 if (fZ20[slice][i]>fZ20[slice][i+1]){
1735 //------------------------------------------------------------------------
1736 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1737 //--------------------------------------------------------------------
1738 // This function returns the index of the nearest cluster
1739 //--------------------------------------------------------------------
1742 if (fCurrentSlice<0) {
1751 if (ncl==0) return 0;
1752 Int_t b=0, e=ncl-1, m=(b+e)/2;
1753 for (; b<e; m=(b+e)/2) {
1754 // if (z > fClusters[m]->GetZ()) b=m+1;
1755 if (z > zcl[m]) b=m+1;
1760 //------------------------------------------------------------------------
1761 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 {
1762 //--------------------------------------------------------------------
1763 // This function computes the rectangular road for this track
1764 //--------------------------------------------------------------------
1767 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1768 // take into account the misalignment: propagate track to misaligned detector plane
1769 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1771 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1772 TMath::Sqrt(track->GetSigmaZ2() +
1773 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1774 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1775 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1776 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1777 TMath::Sqrt(track->GetSigmaY2() +
1778 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1779 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1780 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1782 // track at boundary between detectors, enlarge road
1783 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1784 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1785 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1786 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1787 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1788 Float_t tgl = TMath::Abs(track->GetTgl());
1789 if (tgl > 1.) tgl=1.;
1790 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1791 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1792 Float_t snp = TMath::Abs(track->GetSnp());
1793 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1794 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1797 // add to the road a term (up to 2-3 mm) to deal with misalignments
1798 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1799 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1801 Double_t r = fgLayers[ilayer].GetR();
1802 zmin = track->GetZ() - dz;
1803 zmax = track->GetZ() + dz;
1804 ymin = track->GetY() + r*det.GetPhi() - dy;
1805 ymax = track->GetY() + r*det.GetPhi() + dy;
1807 // bring track back to idead detector plane
1808 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1812 //------------------------------------------------------------------------
1813 void AliITStrackerMI::AliITSlayer::
1814 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1815 //--------------------------------------------------------------------
1816 // This function sets the "window"
1817 //--------------------------------------------------------------------
1819 Double_t circle=2*TMath::Pi()*fR;
1825 // enlarge road in y by maximum cluster error on this layer (3 sigma)
1826 fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
1827 fYmax += fNMaxSigmaCl*fMaxSigmaClY;
1828 fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
1829 fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
1831 Float_t ymiddle = (fYmin+fYmax)*0.5;
1832 if (ymiddle<fYB[0]) {
1833 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1834 } else if (ymiddle>fYB[1]) {
1835 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1841 fClustersCs = fClusters;
1842 fClusterIndexCs = fClusterIndex;
1848 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1849 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1850 if (slice<0) slice=0;
1851 if (slice>20) slice=20;
1852 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1854 fCurrentSlice=slice;
1855 fClustersCs = fClusters20[fCurrentSlice];
1856 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1857 fYcs = fY20[fCurrentSlice];
1858 fZcs = fZ20[fCurrentSlice];
1859 fNcs = fN20[fCurrentSlice];
1864 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1865 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1866 if (slice<0) slice=0;
1867 if (slice>10) slice=10;
1868 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1870 fCurrentSlice=slice;
1871 fClustersCs = fClusters10[fCurrentSlice];
1872 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1873 fYcs = fY10[fCurrentSlice];
1874 fZcs = fZ10[fCurrentSlice];
1875 fNcs = fN10[fCurrentSlice];
1880 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1881 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1882 if (slice<0) slice=0;
1883 if (slice>5) slice=5;
1884 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1886 fCurrentSlice=slice;
1887 fClustersCs = fClusters5[fCurrentSlice];
1888 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1889 fYcs = fY5[fCurrentSlice];
1890 fZcs = fZ5[fCurrentSlice];
1891 fNcs = fN5[fCurrentSlice];
1895 fI = FindClusterIndex(fZmin);
1896 fImax = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
1902 //------------------------------------------------------------------------
1903 Int_t AliITStrackerMI::AliITSlayer::
1904 FindDetectorIndex(Double_t phi, Double_t z) const {
1905 //--------------------------------------------------------------------
1906 //This function finds the detector crossed by the track
1907 //--------------------------------------------------------------------
1909 if (fZOffset<0) // old geometry
1910 dphi = -(phi-fPhiOffset);
1911 else // new geometry
1912 dphi = phi-fPhiOffset;
1915 if (dphi < 0) dphi += 2*TMath::Pi();
1916 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1917 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1918 if (np>=fNladders) np-=fNladders;
1919 if (np<0) np+=fNladders;
1922 Double_t dz=fZOffset-z;
1923 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1924 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1925 if (nz>=fNdetectors || nz<0) {
1926 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1930 // ad hoc correction for 3rd ladder of SDD inner layer,
1931 // which is reversed (rotated by pi around local y)
1932 // this correction is OK only from AliITSv11Hybrid onwards
1933 if (GetR()>12. && GetR()<20.) { // SDD inner
1934 if(np==2) { // 3rd ladder
1935 Double_t posMod252[3];
1936 AliITSgeomTGeo::GetTranslation(252,posMod252);
1937 // check the Z coordinate of Mod 252: if negative
1938 // (old SDD geometry in AliITSv11Hybrid)
1939 // the swap of numeration whould be applied
1940 if(posMod252[2]<0.){
1941 nz = (fNdetectors-1) - nz;
1945 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1948 return np*fNdetectors + nz;
1950 //------------------------------------------------------------------------
1951 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1953 //--------------------------------------------------------------------
1954 // This function returns clusters within the "window"
1955 //--------------------------------------------------------------------
1957 if (fCurrentSlice<0) {
1958 Double_t rpi2 = 2.*fR*TMath::Pi();
1959 for (Int_t i=fI; i<fImax; i++) {
1962 if (fYmax<y) y -= rpi2;
1963 if (fYmin>y) y += rpi2;
1964 if (y<fYmin) continue;
1965 if (y>fYmax) continue;
1967 // skip clusters that are in "extended" road but they
1968 // 3sigma error does not touch the original road
1969 if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
1970 if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
1972 if (TMath::Abs(fClusters[i]->GetQ())<1.e-13 && fSkip==2) continue;
1975 return fClusters[i];
1978 for (Int_t i=fI; i<fImax; i++) {
1979 if (fYcs[i]<fYmin) continue;
1980 if (fYcs[i]>fYmax) continue;
1981 if (TMath::Abs(fClustersCs[i]->GetQ())<1.e-13 && fSkip==2) continue;
1982 ci=fClusterIndexCs[i];
1984 return fClustersCs[i];
1989 //------------------------------------------------------------------------
1990 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1992 //--------------------------------------------------------------------
1993 // This function returns the layer thickness at this point (units X0)
1994 //--------------------------------------------------------------------
1996 x0=AliITSRecoParam::GetX0Air();
1997 if (43<fR&&fR<45) { //SSD2
2000 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2001 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2002 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2003 for (Int_t i=0; i<12; i++) {
2004 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
2005 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2009 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
2010 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2014 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2015 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2018 if (37<fR&&fR<41) { //SSD1
2021 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2022 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
2023 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
2024 for (Int_t i=0; i<11; i++) {
2025 if (TMath::Abs(z-3.9*i)<0.15) {
2026 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2030 if (TMath::Abs(z+3.9*i)<0.15) {
2031 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2035 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2036 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2039 if (13<fR&&fR<26) { //SDD
2042 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2044 if (TMath::Abs(y-1.80)<0.55) {
2046 for (Int_t j=0; j<20; j++) {
2047 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2048 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2051 if (TMath::Abs(y+1.80)<0.55) {
2053 for (Int_t j=0; j<20; j++) {
2054 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2055 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2059 for (Int_t i=0; i<4; i++) {
2060 if (TMath::Abs(z-7.3*i)<0.60) {
2062 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2065 if (TMath::Abs(z+7.3*i)<0.60) {
2067 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2072 if (6<fR&&fR<8) { //SPD2
2073 Double_t dd=0.0063; x0=21.5;
2075 if (TMath::Abs(y-3.08)>0.5) d+=dd;
2076 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2078 if (3<fR&&fR<5) { //SPD1
2079 Double_t dd=0.0063; x0=21.5;
2081 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2082 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2087 //------------------------------------------------------------------------
2088 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2090 fRmisal(det.fRmisal),
2092 fSinPhi(det.fSinPhi),
2093 fCosPhi(det.fCosPhi),
2099 fNChips(det.fNChips),
2100 fChipIsBad(det.fChipIsBad)
2104 //------------------------------------------------------------------------
2105 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2106 const AliITSDetTypeRec *detTypeRec)
2108 //--------------------------------------------------------------------
2109 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2110 //--------------------------------------------------------------------
2112 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2113 // while in the tracker they start from 0 for each layer
2114 for(Int_t il=0; il<ilayer; il++)
2115 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2118 if (ilayer==0 || ilayer==1) { // ---------- SPD
2120 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2122 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2125 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2129 // Get calibration from AliITSDetTypeRec
2130 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2131 calib->SetModuleIndex(idet);
2132 AliITSCalibration *calibSPDdead = 0;
2133 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2134 if (calib->IsBad() ||
2135 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2138 // printf("lay %d bad %d\n",ilayer,idet);
2141 // Get segmentation from AliITSDetTypeRec
2142 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2144 // Read info about bad chips
2145 fNChips = segm->GetMaximumChipIndex()+1;
2146 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2147 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2148 fChipIsBad = new Bool_t[fNChips];
2149 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2150 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2151 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2152 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2157 //------------------------------------------------------------------------
2158 Double_t AliITStrackerMI::GetEffectiveThickness()
2160 //--------------------------------------------------------------------
2161 // Returns the thickness between the current layer and the vertex (units X0)
2162 //--------------------------------------------------------------------
2165 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2166 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2167 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2171 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2172 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2176 Double_t xn=fgLayers[fI].GetR();
2177 for (Int_t i=0; i<fI; i++) {
2178 Double_t xi=fgLayers[i].GetR();
2179 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2185 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2186 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2189 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2190 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2194 //------------------------------------------------------------------------
2195 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2196 //-------------------------------------------------------------------
2197 // This function returns number of clusters within the "window"
2198 //--------------------------------------------------------------------
2200 for (Int_t i=fI; i<fN; i++) {
2201 const AliITSRecPoint *c=fClusters[i];
2202 if (c->GetZ() > fZmax) break;
2203 if (c->IsUsed()) continue;
2204 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2205 Double_t y=fR*det.GetPhi() + c->GetY();
2207 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2208 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2210 if (y<fYmin) continue;
2211 if (y>fYmax) continue;
2216 //------------------------------------------------------------------------
2217 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2218 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2220 //--------------------------------------------------------------------
2221 // This function refits the track "track" at the position "x" using
2222 // the clusters from "clusters"
2223 // If "extra"==kTRUE,
2224 // the clusters from overlapped modules get attached to "track"
2225 // If "planeff"==kTRUE,
2226 // special approach for plane efficiency evaluation is applyed
2227 //--------------------------------------------------------------------
2229 Int_t index[AliITSgeomTGeo::kNLayers];
2231 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2232 Int_t nc=clusters->GetNumberOfClusters();
2233 for (k=0; k<nc; k++) {
2234 Int_t idx=clusters->GetClusterIndex(k);
2235 Int_t ilayer=(idx&0xf0000000)>>28;
2239 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2241 //------------------------------------------------------------------------
2242 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2243 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2245 //--------------------------------------------------------------------
2246 // This function refits the track "track" at the position "x" using
2247 // the clusters from array
2248 // If "extra"==kTRUE,
2249 // the clusters from overlapped modules get attached to "track"
2250 // If "planeff"==kTRUE,
2251 // special approach for plane efficiency evaluation is applyed
2252 //--------------------------------------------------------------------
2253 Int_t index[AliITSgeomTGeo::kNLayers];
2255 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2257 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2258 index[k]=clusters[k];
2261 // special for cosmics: check which the innermost layer crossed
2263 Int_t innermostlayer=5;
2264 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2265 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2266 if(drphi < fgLayers[innermostlayer].GetR()) break;
2268 AliDebug(2,Form(" drphi %f innermost %d",drphi,innermostlayer));
2270 Int_t modstatus=1; // found
2272 Int_t from, to, step;
2273 if (xx > track->GetX()) {
2274 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2277 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2280 TString dir = (step>0 ? "outward" : "inward");
2282 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2283 AliITSlayer &layer=fgLayers[ilayer];
2284 Double_t r=layer.GetR();
2286 if (step<0 && xx>r) break;
2288 // material between SSD and SDD, SDD and SPD
2289 Double_t hI=ilayer-0.5*step;
2290 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2291 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2292 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2293 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2296 Double_t oldGlobXYZ[3];
2297 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2299 // continue if we are already beyond this layer
2300 Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2301 if(step>0 && oldGlobR > r) continue; // going outward
2302 if(step<0 && oldGlobR < r) continue; // going inward
2305 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2307 Int_t idet=layer.FindDetectorIndex(phi,z);
2309 // check if we allow a prolongation without point for large-eta tracks
2310 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2312 modstatus = 4; // out in z
2313 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2314 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2317 // apply correction for material of the current layer
2318 // add time if going outward
2319 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2323 if (idet<0) return kFALSE;
2326 const AliITSdetector &det=layer.GetDetector(idet);
2327 // only for ITS-SA tracks refit
2328 if (ilayer>1 && fTrackingPhase.Contains("RefitInward") && !(track->GetStatus()&AliESDtrack::kTPCin)) track->SetCheckInvariant(kFALSE);
2330 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2332 track->SetDetectorIndex(idet);
2333 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2335 Double_t dz,zmin,zmax,dy,ymin,ymax;
2337 const AliITSRecPoint *clAcc=0;
2338 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2340 Int_t idx=index[ilayer];
2341 if (idx>=0) { // cluster in this layer
2342 modstatus = 6; // no refit
2343 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2345 if (idet != cl->GetDetectorIndex()) {
2346 idet=cl->GetDetectorIndex();
2347 const AliITSdetector &detc=layer.GetDetector(idet);
2348 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2349 track->SetDetectorIndex(idet);
2350 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2352 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2353 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2357 modstatus = 1; // found
2362 } else { // no cluster in this layer
2364 modstatus = 3; // skipped
2365 // Plane Eff determination:
2366 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2367 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2368 UseTrackForPlaneEff(track,ilayer);
2371 modstatus = 5; // no cls in road
2373 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2374 dz = 0.5*(zmax-zmin);
2375 dy = 0.5*(ymax-ymin);
2376 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2377 if (dead==1) modstatus = 7; // holes in z in SPD
2378 if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2383 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2384 track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2386 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2389 if (extra) { // search for extra clusters in overlapped modules
2390 AliITStrackV2 tmp(*track);
2391 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2392 layer.SelectClusters(zmin,zmax,ymin,ymax);
2394 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2396 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2397 Double_t tolerance=0.1;
2398 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2399 // only clusters in another module! (overlaps)
2400 idetExtra = clExtra->GetDetectorIndex();
2401 if (idet == idetExtra) continue;
2403 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2405 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2406 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2407 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2408 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2410 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2411 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2414 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2415 track->SetExtraModule(ilayer,idetExtra);
2417 } // end search for extra clusters in overlapped modules
2419 // Correct for material of the current layer
2421 // add time if going outward
2422 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2423 track->SetCheckInvariant(kTRUE);
2424 } // end loop on layers
2426 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2430 //------------------------------------------------------------------------
2431 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2434 // calculate normalized chi2
2435 // return NormalizedChi2(track,0);
2438 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2439 // track->fdEdxMismatch=0;
2440 Float_t dedxmismatch =0;
2441 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2443 for (Int_t i = 0;i<6;i++){
2444 if (track->GetClIndex(i)>=0){
2445 Float_t cerry, cerrz;
2446 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2448 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2451 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2452 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2453 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2455 cchi2+=(0.5-ratio)*10.;
2456 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2457 dedxmismatch+=(0.5-ratio)*10.;
2461 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2462 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2463 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2464 if (i<2) chi2+=2*cl->GetDeltaProbability();
2470 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2471 track->SetdEdxMismatch(dedxmismatch);
2475 for (Int_t i = 0;i<4;i++){
2476 if (track->GetClIndex(i)>=0){
2477 Float_t cerry, cerrz;
2478 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2479 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2482 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2483 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2487 for (Int_t i = 4;i<6;i++){
2488 if (track->GetClIndex(i)>=0){
2489 Float_t cerry, cerrz;
2490 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2491 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2494 Float_t cerryb, cerrzb;
2495 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2496 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2499 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2500 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2505 if (track->GetESDtrack()->GetTPCsignal()>85){
2506 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2508 chi2+=(0.5-ratio)*5.;
2511 chi2+=(ratio-2.0)*3;
2515 Double_t match = TMath::Sqrt(track->GetChi22());
2516 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2517 if (!track->GetConstrain()) {
2518 if (track->GetNumberOfClusters()>2) {
2519 match/=track->GetNumberOfClusters()-2.;
2524 if (match<0) match=0;
2526 // penalty factor for missing points (NDeadZone>0), but no penalty
2527 // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2528 // or there is a dead from OCDB)
2529 Float_t deadzonefactor = 0.;
2530 if (track->GetNDeadZone()>0.) {
2531 Int_t sumDeadZoneProbability=0;
2532 for(Int_t ilay=0;ilay<6;ilay++) {
2533 if(track->GetDeadZoneProbability(ilay)>0.) sumDeadZoneProbability++;
2535 Int_t nDeadZoneWithProbNot1=(Int_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2536 if(nDeadZoneWithProbNot1>0) {
2537 Float_t deadZoneProbability = track->GetNDeadZone()-(Float_t)sumDeadZoneProbability;
2538 AliDebug(2,Form("nDeadZone %f sumDZProbability %f nDZWithProbNot1 %f deadZoneProb %f\n",track->GetNDeadZone(),sumDeadZoneProbability,nDeadZoneWithProbNot1,deadZoneProbability));
2539 deadZoneProbability /= (Float_t)nDeadZoneWithProbNot1;
2541 deadZoneProbability = TMath::Min(deadZoneProbability,one);
2542 deadzonefactor = 3.*(1.1-deadZoneProbability);
2546 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2547 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2548 1./(1.+track->GetNSkipped()));
2549 AliDebug(2,Form("match %f deadzonefactor %f chi2 %f sum %f skipped\n",match,deadzonefactor,chi2,sum,track->GetNSkipped()));
2550 AliDebug(2,Form("NormChi2 %f cls %d\n",normchi2,track->GetNumberOfClusters()));
2553 //------------------------------------------------------------------------
2554 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2557 // return matching chi2 between two tracks
2558 Double_t largeChi2=1000.;
2560 AliITStrackMI track3(*track2);
2561 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2563 vec(0,0)=track1->GetY() - track3.GetY();
2564 vec(1,0)=track1->GetZ() - track3.GetZ();
2565 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2566 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2567 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2570 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2571 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2572 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2573 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2574 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2576 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2577 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2578 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2579 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2581 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2582 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2583 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2585 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2586 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2588 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2591 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2592 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2595 //------------------------------------------------------------------------
2596 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2599 // return probability that given point (characterized by z position and error)
2600 // is in SPD dead zone
2601 // This method assumes that fSPDdetzcentre is ordered from -z to +z
2603 Double_t probability = 0.;
2604 Double_t nearestz = 0.,distz=0.;
2605 Int_t nearestzone = -1;
2606 Double_t mindistz = 1000.;
2608 // find closest dead zone
2609 for (Int_t i=0; i<3; i++) {
2610 distz=TMath::Abs(zpos-0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]));
2611 if (distz<mindistz) {
2613 nearestz=0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]);
2618 // too far from dead zone
2619 if (TMath::Abs(zpos-nearestz)>0.25+3.*zerr) return probability;
2622 Double_t zmin, zmax;
2623 if (nearestzone==0) { // dead zone at z = -7
2624 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2625 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2626 } else if (nearestzone==1) { // dead zone at z = 0
2627 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2628 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2629 } else if (nearestzone==2) { // dead zone at z = +7
2630 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2631 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2636 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2638 probability = 0.5*( AliMathBase::ErfFast((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2639 AliMathBase::ErfFast((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2640 AliDebug(2,Form("zpos %f +- %f nearestzone %d zmin zmax %f %f prob %f\n",zpos,zerr,nearestzone,zmin,zmax,probability));
2643 //------------------------------------------------------------------------
2644 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2647 // calculate normalized chi2
2649 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2651 for (Int_t i = 0;i<6;i++){
2652 if (TMath::Abs(track->GetDy(i))>0){
2653 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2654 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2657 else{chi2[i]=10000;}
2660 TMath::Sort(6,chi2,index,kFALSE);
2661 Float_t max = float(ncl)*fac-1.;
2662 Float_t sumchi=0, sumweight=0;
2663 for (Int_t i=0;i<max+1;i++){
2664 Float_t weight = (i<max)?1.:(max+1.-i);
2665 sumchi+=weight*chi2[index[i]];
2668 Double_t normchi2 = sumchi/sumweight;
2671 //------------------------------------------------------------------------
2672 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2675 // calculate normalized chi2
2676 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2679 for (Int_t i=0;i<6;i++){
2680 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2681 Double_t sy1 = forwardtrack->GetSigmaY(i);
2682 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2683 Double_t sy2 = backtrack->GetSigmaY(i);
2684 Double_t sz2 = backtrack->GetSigmaZ(i);
2685 if (i<2){ sy2=1000.;sz2=1000;}
2687 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2688 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2690 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2691 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2693 res+= nz0*nz0+ny0*ny0;
2696 if (npoints>1) return
2697 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2698 //2*forwardtrack->fNUsed+
2699 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2700 1./(1.+forwardtrack->GetNSkipped()));
2703 //------------------------------------------------------------------------
2704 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2705 //--------------------------------------------------------------------
2706 // Return pointer to a given cluster
2707 //--------------------------------------------------------------------
2708 Int_t l=(index & 0xf0000000) >> 28;
2709 Int_t c=(index & 0x0fffffff) >> 00;
2710 return fgLayers[l].GetWeight(c);
2712 //------------------------------------------------------------------------
2713 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2715 //---------------------------------------------
2716 // register track to the list
2718 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2721 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2722 Int_t index = track->GetClusterIndex(icluster);
2723 Int_t l=(index & 0xf0000000) >> 28;
2724 Int_t c=(index & 0x0fffffff) >> 00;
2725 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2726 for (Int_t itrack=0;itrack<4;itrack++){
2727 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2728 fgLayers[l].SetClusterTracks(itrack,c,id);
2734 //------------------------------------------------------------------------
2735 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2737 //---------------------------------------------
2738 // unregister track from the list
2739 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2740 Int_t index = track->GetClusterIndex(icluster);
2741 Int_t l=(index & 0xf0000000) >> 28;
2742 Int_t c=(index & 0x0fffffff) >> 00;
2743 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2744 for (Int_t itrack=0;itrack<4;itrack++){
2745 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2746 fgLayers[l].SetClusterTracks(itrack,c,-1);
2751 //------------------------------------------------------------------------
2752 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2754 //-------------------------------------------------------------
2755 //get number of shared clusters
2756 //-------------------------------------------------------------
2758 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2759 // mean number of clusters
2760 Float_t *ny = GetNy(id), *nz = GetNz(id);
2763 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2764 Int_t index = track->GetClusterIndex(icluster);
2765 Int_t l=(index & 0xf0000000) >> 28;
2766 Int_t c=(index & 0x0fffffff) >> 00;
2767 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2769 printf("problem\n");
2771 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2775 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2776 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2777 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2779 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2782 deltan = (cl->GetNz()-nz[l]);
2784 if (deltan>2.0) continue; // extended - highly probable shared cluster
2785 weight = 2./TMath::Max(3.+deltan,2.);
2787 for (Int_t itrack=0;itrack<4;itrack++){
2788 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2790 clist[l] = (AliITSRecPoint*)GetCluster(index);
2796 track->SetNUsed(shared);
2799 //------------------------------------------------------------------------
2800 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2803 // find first shared track
2805 // mean number of clusters
2806 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2808 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2809 Int_t sharedtrack=100000;
2810 Int_t tracks[24],trackindex=0;
2811 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2813 for (Int_t icluster=0;icluster<6;icluster++){
2814 if (clusterlist[icluster]<0) continue;
2815 Int_t index = clusterlist[icluster];
2816 Int_t l=(index & 0xf0000000) >> 28;
2817 Int_t c=(index & 0x0fffffff) >> 00;
2819 printf("problem\n");
2821 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2822 //if (l>3) continue;
2823 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2826 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2827 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2828 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2830 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2833 deltan = (cl->GetNz()-nz[l]);
2835 if (deltan>2.0) continue; // extended - highly probable shared cluster
2837 for (Int_t itrack=3;itrack>=0;itrack--){
2838 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2839 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2840 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2845 if (trackindex==0) return -1;
2847 sharedtrack = tracks[0];
2849 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2852 Int_t tracks2[24], cluster[24];
2853 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2856 for (Int_t i=0;i<trackindex;i++){
2857 if (tracks[i]<0) continue;
2858 tracks2[index] = tracks[i];
2860 for (Int_t j=i+1;j<trackindex;j++){
2861 if (tracks[j]<0) continue;
2862 if (tracks[j]==tracks[i]){
2870 for (Int_t i=0;i<index;i++){
2871 if (cluster[index]>max) {
2872 sharedtrack=tracks2[index];
2879 if (sharedtrack>=100000) return -1;
2881 // make list of overlaps
2883 for (Int_t icluster=0;icluster<6;icluster++){
2884 if (clusterlist[icluster]<0) continue;
2885 Int_t index = clusterlist[icluster];
2886 Int_t l=(index & 0xf0000000) >> 28;
2887 Int_t c=(index & 0x0fffffff) >> 00;
2888 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2889 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2891 if (cl->GetNy()>2) continue;
2892 if (cl->GetNz()>2) continue;
2895 if (cl->GetNy()>3) continue;
2896 if (cl->GetNz()>3) continue;
2899 for (Int_t itrack=3;itrack>=0;itrack--){
2900 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2901 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2909 //------------------------------------------------------------------------
2910 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2912 // try to find track hypothesys without conflicts
2913 // with minimal chi2;
2914 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2915 Int_t entries1 = arr1->GetEntriesFast();
2916 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2917 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2918 Int_t entries2 = arr2->GetEntriesFast();
2919 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2921 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2922 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2923 if (track10->Pt()>0.5+track20->Pt()) return track10;
2925 for (Int_t itrack=0;itrack<entries1;itrack++){
2926 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2927 UnRegisterClusterTracks(track,trackID1);
2930 for (Int_t itrack=0;itrack<entries2;itrack++){
2931 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2932 UnRegisterClusterTracks(track,trackID2);
2936 Float_t maxconflicts=6;
2937 Double_t maxchi2 =1000.;
2939 // get weight of hypothesys - using best hypothesy
2942 Int_t list1[6],list2[6];
2943 AliITSRecPoint *clist1[6], *clist2[6] ;
2944 RegisterClusterTracks(track10,trackID1);
2945 RegisterClusterTracks(track20,trackID2);
2946 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2947 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2948 UnRegisterClusterTracks(track10,trackID1);
2949 UnRegisterClusterTracks(track20,trackID2);
2952 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2953 Float_t nerry[6],nerrz[6];
2954 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2955 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2956 for (Int_t i=0;i<6;i++){
2957 if ( (erry1[i]>0) && (erry2[i]>0)) {
2958 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2959 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2961 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2962 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2964 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2965 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2966 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2969 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2970 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2971 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2979 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2980 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2981 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2982 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2984 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2985 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2986 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2988 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2989 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2990 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2993 Double_t sumw = w1+w2;
2997 w1 = (d2+0.5)/(d1+d2+1.);
2998 w2 = (d1+0.5)/(d1+d2+1.);
3000 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
3001 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
3003 // get pair of "best" hypothesys
3005 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
3006 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
3008 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
3009 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
3010 //if (track1->fFakeRatio>0) continue;
3011 RegisterClusterTracks(track1,trackID1);
3012 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
3013 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
3015 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
3016 //if (track2->fFakeRatio>0) continue;
3018 RegisterClusterTracks(track2,trackID2);
3019 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
3020 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
3021 UnRegisterClusterTracks(track2,trackID2);
3023 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
3024 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
3025 if (nskipped>0.5) continue;
3027 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
3028 if (conflict1+1<cconflict1) continue;
3029 if (conflict2+1<cconflict2) continue;
3033 for (Int_t i=0;i<6;i++){
3035 Float_t c1 =0.; // conflict coeficients
3037 if (clist1[i]&&clist2[i]){
3040 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
3043 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
3045 c1 = 2./TMath::Max(3.+deltan,2.);
3046 c2 = 2./TMath::Max(3.+deltan,2.);
3052 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
3055 deltan = (clist1[i]->GetNz()-nz1[i]);
3057 c1 = 2./TMath::Max(3.+deltan,2.);
3064 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
3067 deltan = (clist2[i]->GetNz()-nz2[i]);
3069 c2 = 2./TMath::Max(3.+deltan,2.);
3075 if (TMath::Abs(track1->GetDy(i))>0.) {
3076 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
3077 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
3078 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
3079 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
3081 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
3084 if (TMath::Abs(track2->GetDy(i))>0.) {
3085 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
3086 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
3087 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
3088 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3091 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3093 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3094 if (chi21>0) sum+=w1;
3095 if (chi22>0) sum+=w2;
3098 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3099 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3100 Double_t normchi2 = 2*conflict+sumchi2/sum;
3101 if ( normchi2 <maxchi2 ){
3104 maxconflicts = conflict;
3108 UnRegisterClusterTracks(track1,trackID1);
3111 // if (maxconflicts<4 && maxchi2<th0){
3112 if (maxchi2<th0*2.){
3113 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3114 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3115 track1->SetChi2MIP(5,maxconflicts);
3116 track1->SetChi2MIP(6,maxchi2);
3117 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3118 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3119 track1->SetChi2MIP(8,index1);
3120 fBestTrackIndex[trackID1] =index1;
3121 UpdateESDtrack(track1, AliESDtrack::kITSin);
3123 else if (track10->GetChi2MIP(0)<th1){
3124 track10->SetChi2MIP(5,maxconflicts);
3125 track10->SetChi2MIP(6,maxchi2);
3126 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3127 UpdateESDtrack(track10,AliESDtrack::kITSin);
3130 for (Int_t itrack=0;itrack<entries1;itrack++){
3131 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3132 UnRegisterClusterTracks(track,trackID1);
3135 for (Int_t itrack=0;itrack<entries2;itrack++){
3136 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3137 UnRegisterClusterTracks(track,trackID2);
3140 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3141 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3142 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3143 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3144 RegisterClusterTracks(track10,trackID1);
3146 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3147 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3148 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3149 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3150 RegisterClusterTracks(track20,trackID2);
3155 //------------------------------------------------------------------------
3156 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3157 //--------------------------------------------------------------------
3158 // This function marks clusters assigned to the track
3159 //--------------------------------------------------------------------
3160 AliTracker::UseClusters(t,from);
3162 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3163 //if (c->GetQ()>2) c->Use();
3164 if (c->GetSigmaZ2()>0.1) c->Use();
3165 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3166 //if (c->GetQ()>2) c->Use();
3167 if (c->GetSigmaZ2()>0.1) c->Use();
3170 //------------------------------------------------------------------------
3171 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3173 //------------------------------------------------------------------
3174 // add track to the list of hypothesys
3175 //------------------------------------------------------------------
3177 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3178 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3180 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3182 array = new TObjArray(10);
3183 fTrackHypothesys.AddAt(array,esdindex);
3185 array->AddLast(track);
3187 //------------------------------------------------------------------------
3188 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3190 //-------------------------------------------------------------------
3191 // compress array of track hypothesys
3192 // keep only maxsize best hypothesys
3193 //-------------------------------------------------------------------
3194 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3195 if (! (fTrackHypothesys.At(esdindex)) ) return;
3196 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3197 Int_t entries = array->GetEntriesFast();
3199 //- find preliminary besttrack as a reference
3200 Float_t minchi2=10000;
3202 AliITStrackMI * besttrack=0;
3203 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3204 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3205 if (!track) continue;
3206 Float_t chi2 = NormalizedChi2(track,0);
3208 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3209 track->SetLabel(tpcLabel);
3211 track->SetFakeRatio(1.);
3212 CookLabel(track,0.); //For comparison only
3214 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3215 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3216 if (track->GetNumberOfClusters()<maxn) continue;
3217 maxn = track->GetNumberOfClusters();
3224 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3225 delete array->RemoveAt(itrack);
3229 if (!besttrack) return;
3232 //take errors of best track as a reference
3233 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3234 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3235 for (Int_t j=0;j<6;j++) {
3236 if (besttrack->GetClIndex(j)>=0){
3237 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3238 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3239 ny[j] = besttrack->GetNy(j);
3240 nz[j] = besttrack->GetNz(j);
3244 // calculate normalized chi2
3246 Float_t * chi2 = new Float_t[entries];
3247 Int_t * index = new Int_t[entries];
3248 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3249 for (Int_t itrack=0;itrack<entries;itrack++){
3250 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3252 AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3253 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3254 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3255 chi2[itrack] = track->GetChi2MIP(0);
3257 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3258 delete array->RemoveAt(itrack);
3264 TMath::Sort(entries,chi2,index,kFALSE);
3265 besttrack = (AliITStrackMI*)array->At(index[0]);
3266 if(besttrack) AliDebug(2,Form("ncls best track %d\n",besttrack->GetNumberOfClusters()));
3267 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3268 for (Int_t j=0;j<6;j++){
3269 if (besttrack->GetClIndex(j)>=0){
3270 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3271 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3272 ny[j] = besttrack->GetNy(j);
3273 nz[j] = besttrack->GetNz(j);
3278 // calculate one more time with updated normalized errors
3279 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3280 for (Int_t itrack=0;itrack<entries;itrack++){
3281 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3283 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3284 AliDebug(2,Form("track %d ncls %d\n",itrack,track->GetNumberOfClusters()));
3285 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3286 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3289 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3290 delete array->RemoveAt(itrack);
3295 entries = array->GetEntriesFast();
3299 TObjArray * newarray = new TObjArray();
3300 TMath::Sort(entries,chi2,index,kFALSE);
3301 besttrack = (AliITStrackMI*)array->At(index[0]);
3303 AliDebug(2,Form("ncls best track %d %f %f\n",besttrack->GetNumberOfClusters(),besttrack->GetChi2MIP(0),chi2[index[0]]));
3305 for (Int_t j=0;j<6;j++){
3306 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3307 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3308 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3309 ny[j] = besttrack->GetNy(j);
3310 nz[j] = besttrack->GetNz(j);
3313 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3314 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3315 Float_t minn = besttrack->GetNumberOfClusters()-3;
3317 for (Int_t i=0;i<entries;i++){
3318 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3319 if (!track) continue;
3320 if (accepted>maxcut) break;
3321 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3322 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3323 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3324 delete array->RemoveAt(index[i]);
3328 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3329 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3330 if (!shortbest) accepted++;
3332 newarray->AddLast(array->RemoveAt(index[i]));
3333 for (Int_t j=0;j<6;j++){
3335 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3336 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3337 ny[j] = track->GetNy(j);
3338 nz[j] = track->GetNz(j);
3343 delete array->RemoveAt(index[i]);
3347 delete fTrackHypothesys.RemoveAt(esdindex);
3348 fTrackHypothesys.AddAt(newarray,esdindex);
3352 delete fTrackHypothesys.RemoveAt(esdindex);
3358 //------------------------------------------------------------------------
3359 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3361 //-------------------------------------------------------------
3362 // try to find best hypothesy
3363 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3364 //-------------------------------------------------------------
3365 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3366 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3367 if (!array) return 0;
3368 Int_t entries = array->GetEntriesFast();
3369 if (!entries) return 0;
3370 Float_t minchi2 = 100000;
3371 AliITStrackMI * besttrack=0;
3373 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3374 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3375 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3376 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3378 for (Int_t i=0;i<entries;i++){
3379 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3380 if (!track) continue;
3381 Float_t sigmarfi,sigmaz;
3382 GetDCASigma(track,sigmarfi,sigmaz);
3383 track->SetDnorm(0,sigmarfi);
3384 track->SetDnorm(1,sigmaz);
3386 track->SetChi2MIP(1,1000000);
3387 track->SetChi2MIP(2,1000000);
3388 track->SetChi2MIP(3,1000000);
3391 backtrack = new(backtrack) AliITStrackMI(*track);
3392 if (track->GetConstrain()) {
3393 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3394 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3395 backtrack->ResetCovariance(10.);
3397 backtrack->ResetCovariance(10.);
3399 backtrack->ResetClusters();
3401 Double_t x = original->GetX();
3402 if (!RefitAt(x,backtrack,track)) continue;
3404 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3405 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3406 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3407 track->SetChi22(GetMatchingChi2(backtrack,original));
3409 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3410 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3411 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3414 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3416 //forward track - without constraint
3417 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3418 forwardtrack->ResetClusters();
3420 RefitAt(x,forwardtrack,track);
3421 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3422 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3423 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3425 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3426 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3427 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3428 forwardtrack->SetD(0,track->GetD(0));
3429 forwardtrack->SetD(1,track->GetD(1));
3432 AliITSRecPoint* clist[6];
3433 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3434 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3437 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3438 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3439 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3440 track->SetChi2MIP(3,1000);
3443 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3445 for (Int_t ichi=0;ichi<5;ichi++){
3446 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3448 if (chi2 < minchi2){
3449 //besttrack = new AliITStrackMI(*forwardtrack);
3451 besttrack->SetLabel(track->GetLabel());
3452 besttrack->SetFakeRatio(track->GetFakeRatio());
3454 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3455 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3456 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3460 delete forwardtrack;
3462 for (Int_t i=0;i<entries;i++){
3463 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3465 if (!track) continue;
3467 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3468 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3469 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3470 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3471 delete array->RemoveAt(i);
3481 SortTrackHypothesys(esdindex,checkmax,1);
3483 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3484 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3485 besttrack = (AliITStrackMI*)array->At(0);
3486 if (!besttrack) return 0;
3487 besttrack->SetChi2MIP(8,0);
3488 fBestTrackIndex[esdindex]=0;
3489 entries = array->GetEntriesFast();
3490 AliITStrackMI *longtrack =0;
3492 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3493 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3494 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3495 if (!track->GetConstrain()) continue;
3496 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3497 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3498 if (track->GetChi2MIP(0)>4.) continue;
3499 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3502 //if (longtrack) besttrack=longtrack;
3505 AliITSRecPoint * clist[6];
3506 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3507 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3508 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3509 RegisterClusterTracks(besttrack,esdindex);
3516 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3517 if (sharedtrack>=0){
3519 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3521 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3527 if (shared>2.5) return 0;
3528 if (shared>1.0) return besttrack;
3530 // Don't sign clusters if not gold track
3532 if (!besttrack->IsGoldPrimary()) return besttrack;
3533 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3535 if (fConstraint[fPass]){
3539 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3540 for (Int_t i=0;i<6;i++){
3541 Int_t index = besttrack->GetClIndex(i);
3542 if (index<0) continue;
3543 Int_t ilayer = (index & 0xf0000000) >> 28;
3544 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3545 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3547 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3548 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3549 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3550 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3551 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3552 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3554 Bool_t cansign = kTRUE;
3555 for (Int_t itrack=0;itrack<entries; itrack++){
3556 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3557 if (!track) continue;
3558 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3559 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3565 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3566 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3567 if (!c->IsUsed()) c->Use();
3573 //------------------------------------------------------------------------
3574 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3577 // get "best" hypothesys
3580 Int_t nentries = itsTracks.GetEntriesFast();
3581 for (Int_t i=0;i<nentries;i++){
3582 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3583 if (!track) continue;
3584 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3585 if (!array) continue;
3586 if (array->GetEntriesFast()<=0) continue;
3588 AliITStrackMI* longtrack=0;
3590 Float_t maxchi2=1000;
3591 for (Int_t j=0;j<array->GetEntriesFast();j++){
3592 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3593 if (!trackHyp) continue;
3594 if (trackHyp->GetGoldV0()) {
3595 longtrack = trackHyp; //gold V0 track taken
3598 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3599 Float_t chi2 = trackHyp->GetChi2MIP(0);
3601 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3603 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3605 if (chi2 > maxchi2) continue;
3606 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3613 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3614 if (!longtrack) {longtrack = besttrack;}
3615 else besttrack= longtrack;
3619 AliITSRecPoint * clist[6];
3620 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3622 track->SetNUsed(shared);
3623 track->SetNSkipped(besttrack->GetNSkipped());
3624 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3626 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3630 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3631 //if (sharedtrack==-1) sharedtrack=0;
3632 if (sharedtrack>=0) {
3633 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3636 if (besttrack&&fAfterV0) {
3637 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3639 if (besttrack&&fConstraint[fPass])
3640 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3641 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3642 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3643 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3649 //------------------------------------------------------------------------
3650 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3651 //--------------------------------------------------------------------
3652 //This function "cooks" a track label. If label<0, this track is fake.
3653 //--------------------------------------------------------------------
3656 if (track->GetESDtrack()){
3657 tpcLabel = track->GetESDtrack()->GetTPCLabel();
3658 ULong_t trStatus=track->GetESDtrack()->GetStatus();
3659 if(!(trStatus&AliESDtrack::kTPCin)) tpcLabel=track->GetLabel(); // for ITSsa tracks
3661 track->SetChi2MIP(9,0);
3663 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3664 Int_t cindex = track->GetClusterIndex(i);
3665 Int_t l=(cindex & 0xf0000000) >> 28;
3666 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3668 for (Int_t ind=0;ind<3;ind++){
3669 if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
3670 //AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3672 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3675 Int_t nclusters = track->GetNumberOfClusters();
3676 if (nclusters > 0) //PH Some tracks don't have any cluster
3677 track->SetFakeRatio(double(nwrong)/double(nclusters));
3678 if (tpcLabel>0 && track->GetFakeRatio()>wrong) {
3679 track->SetLabel(-tpcLabel);
3681 track->SetLabel(tpcLabel);
3683 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3686 //------------------------------------------------------------------------
3687 void AliITStrackerMI::CookdEdx(AliITStrackMI* track){
3689 // Fill the dE/dx in this track
3691 track->SetChi2MIP(9,0);
3692 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3693 Int_t cindex = track->GetClusterIndex(i);
3694 Int_t l=(cindex & 0xf0000000) >> 28;
3695 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3696 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3698 for (Int_t ind=0;ind<3;ind++){
3699 if (cl->GetLabel(ind)==lab) isWrong=0;
3701 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3705 track->CookdEdx(low,up);
3707 //------------------------------------------------------------------------
3708 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3710 // Create some arrays
3712 if (fCoefficients) delete []fCoefficients;
3713 fCoefficients = new Float_t[ntracks*48];
3714 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3716 //------------------------------------------------------------------------
3717 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3720 // Compute predicted chi2
3722 Float_t erry,errz,covyz;
3723 Float_t theta = track->GetTgl();
3724 Float_t phi = track->GetSnp();
3725 phi = TMath::Abs(phi)*TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3726 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
3727 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()));
3728 // Take into account the mis-alignment (bring track to cluster plane)
3729 Double_t xTrOrig=track->GetX();
3730 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3731 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()));
3732 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
3733 // Bring the track back to detector plane in ideal geometry
3734 // [mis-alignment will be accounted for in UpdateMI()]
3735 if (!track->Propagate(xTrOrig)) return 1000.;
3737 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3738 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3740 chi2+=0.5*TMath::Min(delta/2,2.);
3741 chi2+=2.*cluster->GetDeltaProbability();
3744 track->SetNy(layer,ny);
3745 track->SetNz(layer,nz);
3746 track->SetSigmaY(layer,erry);
3747 track->SetSigmaZ(layer, errz);
3748 track->SetSigmaYZ(layer,covyz);
3749 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3750 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3754 //------------------------------------------------------------------------
3755 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3760 Int_t layer = (index & 0xf0000000) >> 28;
3761 track->SetClIndex(layer, index);
3762 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3763 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3764 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3765 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3769 if (TMath::Abs(cl->GetQ())<1.e-13) return 0; // ingore the "virtual" clusters
3772 // Take into account the mis-alignment (bring track to cluster plane)
3773 Double_t xTrOrig=track->GetX();
3774 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3775 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3776 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3777 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3779 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3782 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3783 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3784 c.SetSigmaYZ(track->GetSigmaYZ(layer));
3787 Int_t updated = track->UpdateMI(&c,chi2,index);
3788 // Bring the track back to detector plane in ideal geometry
3789 if (!track->Propagate(xTrOrig)) return 0;
3791 if(!updated) AliDebug(2,"update failed");
3795 //------------------------------------------------------------------------
3796 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3799 //DCA sigmas parameterization
3800 //to be paramterized using external parameters in future
3803 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3804 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3806 //------------------------------------------------------------------------
3807 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3810 // Clusters from delta electrons?
3812 Int_t entries = clusterArray->GetEntriesFast();
3813 if (entries<4) return;
3814 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3815 Int_t layer = cluster->GetLayer();
3816 if (layer>1) return;
3818 Int_t ncandidates=0;
3819 Float_t r = (layer>0)? 7:4;
3821 for (Int_t i=0;i<entries;i++){
3822 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3823 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3824 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3825 index[ncandidates] = i; //candidate to belong to delta electron track
3827 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3828 cl0->SetDeltaProbability(1);
3834 for (Int_t i=0;i<ncandidates;i++){
3835 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3836 if (cl0->GetDeltaProbability()>0.8) continue;
3839 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3840 sumy=sumz=sumy2=sumyz=sumw=0.0;
3841 for (Int_t j=0;j<ncandidates;j++){
3843 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3845 Float_t dz = cl0->GetZ()-cl1->GetZ();
3846 Float_t dy = cl0->GetY()-cl1->GetY();
3847 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3848 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3849 y[ncl] = cl1->GetY();
3850 z[ncl] = cl1->GetZ();
3851 sumy+= y[ncl]*weight;
3852 sumz+= z[ncl]*weight;
3853 sumy2+=y[ncl]*y[ncl]*weight;
3854 sumyz+=y[ncl]*z[ncl]*weight;
3859 if (ncl<4) continue;
3860 Float_t det = sumw*sumy2 - sumy*sumy;
3862 if (TMath::Abs(det)>0.01){
3863 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3864 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3865 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3868 Float_t z0 = sumyz/sumy;
3869 delta = TMath::Abs(cl0->GetZ()-z0);
3872 cl0->SetDeltaProbability(1-20.*delta);
3876 //------------------------------------------------------------------------
3877 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3882 track->UpdateESDtrack(flags);
3883 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3884 if (oldtrack) delete oldtrack;
3885 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3886 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3887 printf("Problem\n");
3890 //------------------------------------------------------------------------
3891 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3893 // Get nearest upper layer close to the point xr.
3894 // rough approximation
3896 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3897 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3899 for (Int_t i=0;i<6;i++){
3900 if (radius<kRadiuses[i]){
3907 //------------------------------------------------------------------------
3908 void AliITStrackerMI::BuildMaterialLUT(TString material) {
3909 //--------------------------------------------------------------------
3910 // Fill a look-up table with mean material
3911 //--------------------------------------------------------------------
3915 Double_t point1[3],point2[3];
3916 Double_t phi,cosphi,sinphi,z;
3917 // 0-5 layers, 6 pipe, 7-8 shields
3918 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
3919 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
3921 Int_t ifirst=0,ilast=0;
3922 if(material.Contains("Pipe")) {
3924 } else if(material.Contains("Shields")) {
3926 } else if(material.Contains("Layers")) {
3929 Error("BuildMaterialLUT","Wrong layer name\n");
3932 for(Int_t imat=ifirst; imat<=ilast; imat++) {
3933 Double_t param[5]={0.,0.,0.,0.,0.};
3934 for (Int_t i=0; i<n; i++) {
3935 phi = 2.*TMath::Pi()*gRandom->Rndm();
3936 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
3937 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
3938 point1[0] = rmin[imat]*cosphi;
3939 point1[1] = rmin[imat]*sinphi;
3941 point2[0] = rmax[imat]*cosphi;
3942 point2[1] = rmax[imat]*sinphi;
3944 AliTracker::MeanMaterialBudget(point1,point2,mparam);
3945 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
3947 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
3949 fxOverX0Layer[imat] = param[1];
3950 fxTimesRhoLayer[imat] = param[0]*param[4];
3951 } else if(imat==6) {
3952 fxOverX0Pipe = param[1];
3953 fxTimesRhoPipe = param[0]*param[4];
3954 } else if(imat==7) {
3955 fxOverX0Shield[0] = param[1];
3956 fxTimesRhoShield[0] = param[0]*param[4];
3957 } else if(imat==8) {
3958 fxOverX0Shield[1] = param[1];
3959 fxTimesRhoShield[1] = param[0]*param[4];
3963 printf("%s\n",material.Data());
3964 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
3965 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
3966 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
3967 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
3968 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
3969 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
3970 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
3971 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
3972 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
3976 //------------------------------------------------------------------------
3977 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
3978 TString direction) {
3979 //-------------------------------------------------------------------
3980 // Propagate beyond beam pipe and correct for material
3981 // (material budget in different ways according to fUseTGeo value)
3982 // Add time if going outward (PropagateTo or PropagateToTGeo)
3983 //-------------------------------------------------------------------
3985 // Define budget mode:
3986 // 0: material from AliITSRecoParam (hard coded)
3987 // 1: material from TGeo in one step (on the fly)
3988 // 2: material from lut
3989 // 3: material from TGeo in one step (same for all hypotheses)
4002 if(fTrackingPhase.Contains("Clusters2Tracks"))
4003 { mode=3; } else { mode=1; }
4006 if(fTrackingPhase.Contains("Clusters2Tracks"))
4007 { mode=3; } else { mode=2; }
4013 if(fTrackingPhase.Contains("Default")) mode=0;
4015 Int_t index=fCurrentEsdTrack;
4017 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4018 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
4020 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4022 Double_t xOverX0,x0,lengthTimesMeanDensity;
4026 xOverX0 = AliITSRecoParam::GetdPipe();
4027 x0 = AliITSRecoParam::GetX0Be();
4028 lengthTimesMeanDensity = xOverX0*x0;
4029 lengthTimesMeanDensity *= dir;
4030 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4033 if (!t->PropagateToTGeo(xToGo,1)) return 0;
4036 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
4037 xOverX0 = fxOverX0Pipe;
4038 lengthTimesMeanDensity = fxTimesRhoPipe;
4039 lengthTimesMeanDensity *= dir;
4040 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4043 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
4044 if(fxOverX0PipeTrks[index]<0) {
4045 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4046 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4047 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4048 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
4049 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4052 xOverX0 = fxOverX0PipeTrks[index];
4053 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
4054 lengthTimesMeanDensity *= dir;
4055 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4061 //------------------------------------------------------------------------
4062 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4064 TString direction) {
4065 //-------------------------------------------------------------------
4066 // Propagate beyond SPD or SDD shield and correct for material
4067 // (material budget in different ways according to fUseTGeo value)
4068 // Add time if going outward (PropagateTo or PropagateToTGeo)
4069 //-------------------------------------------------------------------
4071 // Define budget mode:
4072 // 0: material from AliITSRecoParam (hard coded)
4073 // 1: material from TGeo in steps of X cm (on the fly)
4074 // X = AliITSRecoParam::GetStepSizeTGeo()
4075 // 2: material from lut
4076 // 3: material from TGeo in one step (same for all hypotheses)
4089 if(fTrackingPhase.Contains("Clusters2Tracks"))
4090 { mode=3; } else { mode=1; }
4093 if(fTrackingPhase.Contains("Clusters2Tracks"))
4094 { mode=3; } else { mode=2; }
4100 if(fTrackingPhase.Contains("Default")) mode=0;
4102 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4104 Int_t shieldindex=0;
4105 if (shield.Contains("SDD")) { // SDDouter
4106 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4108 } else if (shield.Contains("SPD")) { // SPDouter
4109 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4112 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4116 // do nothing if we are already beyond the shield
4117 Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4118 if(dir<0 && rTrack > rToGo) return 1; // going outward
4119 if(dir>0 && rTrack < rToGo) return 1; // going inward
4123 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4125 Int_t index=2*fCurrentEsdTrack+shieldindex;
4127 Double_t xOverX0,x0,lengthTimesMeanDensity;
4132 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4133 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4134 lengthTimesMeanDensity = xOverX0*x0;
4135 lengthTimesMeanDensity *= dir;
4136 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4139 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4140 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4143 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4144 xOverX0 = fxOverX0Shield[shieldindex];
4145 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4146 lengthTimesMeanDensity *= dir;
4147 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4150 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4151 if(fxOverX0ShieldTrks[index]<0) {
4152 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4153 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4154 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4155 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4156 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4159 xOverX0 = fxOverX0ShieldTrks[index];
4160 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4161 lengthTimesMeanDensity *= dir;
4162 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4168 //------------------------------------------------------------------------
4169 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4171 Double_t oldGlobXYZ[3],
4172 TString direction) {
4173 //-------------------------------------------------------------------
4174 // Propagate beyond layer and correct for material
4175 // (material budget in different ways according to fUseTGeo value)
4176 // Add time if going outward (PropagateTo or PropagateToTGeo)
4177 //-------------------------------------------------------------------
4179 // Define budget mode:
4180 // 0: material from AliITSRecoParam (hard coded)
4181 // 1: material from TGeo in stepsof X cm (on the fly)
4182 // X = AliITSRecoParam::GetStepSizeTGeo()
4183 // 2: material from lut
4184 // 3: material from TGeo in one step (same for all hypotheses)
4197 if(fTrackingPhase.Contains("Clusters2Tracks"))
4198 { mode=3; } else { mode=1; }
4201 if(fTrackingPhase.Contains("Clusters2Tracks"))
4202 { mode=3; } else { mode=2; }
4208 if(fTrackingPhase.Contains("Default")) mode=0;
4210 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4212 Double_t r=fgLayers[layerindex].GetR();
4213 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4215 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4217 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4219 Int_t index=6*fCurrentEsdTrack+layerindex;
4222 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4225 // back before material (no correction)
4227 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4228 if (!t->GetLocalXat(rOld,xOld)) return 0;
4229 if (!t->Propagate(xOld)) return 0;
4233 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4234 lengthTimesMeanDensity = xOverX0*x0;
4235 lengthTimesMeanDensity *= dir;
4236 // Bring the track beyond the material
4237 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4240 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4241 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4244 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4245 xOverX0 = fxOverX0Layer[layerindex];
4246 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4247 lengthTimesMeanDensity *= dir;
4248 // Bring the track beyond the material
4249 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4252 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4253 if(fxOverX0LayerTrks[index]<0) {
4254 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4255 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4256 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4257 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4258 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4259 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4262 xOverX0 = fxOverX0LayerTrks[index];
4263 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4264 lengthTimesMeanDensity *= dir;
4265 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4272 //------------------------------------------------------------------------
4273 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4274 //-----------------------------------------------------------------
4275 // Initialize LUT for storing material for each prolonged track
4276 //-----------------------------------------------------------------
4277 fxOverX0PipeTrks = new Float_t[ntracks];
4278 fxTimesRhoPipeTrks = new Float_t[ntracks];
4279 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4280 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4281 fxOverX0LayerTrks = new Float_t[ntracks*6];
4282 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4284 for(Int_t i=0; i<ntracks; i++) {
4285 fxOverX0PipeTrks[i] = -1.;
4286 fxTimesRhoPipeTrks[i] = -1.;
4288 for(Int_t j=0; j<ntracks*2; j++) {
4289 fxOverX0ShieldTrks[j] = -1.;
4290 fxTimesRhoShieldTrks[j] = -1.;
4292 for(Int_t k=0; k<ntracks*6; k++) {
4293 fxOverX0LayerTrks[k] = -1.;
4294 fxTimesRhoLayerTrks[k] = -1.;
4301 //------------------------------------------------------------------------
4302 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4303 //-----------------------------------------------------------------
4304 // Delete LUT for storing material for each prolonged track
4305 //-----------------------------------------------------------------
4306 if(fxOverX0PipeTrks) {
4307 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4309 if(fxOverX0ShieldTrks) {
4310 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4313 if(fxOverX0LayerTrks) {
4314 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4316 if(fxTimesRhoPipeTrks) {
4317 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4319 if(fxTimesRhoShieldTrks) {
4320 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4322 if(fxTimesRhoLayerTrks) {
4323 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4327 //------------------------------------------------------------------------
4328 void AliITStrackerMI::SetForceSkippingOfLayer() {
4329 //-----------------------------------------------------------------
4330 // Check if we are forced to skip layers
4331 // either we set to skip them in RecoParam
4332 // or they were off during data-taking
4333 //-----------------------------------------------------------------
4335 const AliEventInfo *eventInfo = GetEventInfo();
4337 for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
4338 fForceSkippingOfLayer[l] = 0;
4340 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
4344 AliITSReconstructor::GetRecoParam()->GetSkipSubdetsNotInTriggerCluster()) {
4345 AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
4347 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
4348 } else if(l==2 || l==3) {
4349 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1;
4351 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
4357 //------------------------------------------------------------------------
4358 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4359 Int_t ilayer,Int_t idet) const {
4360 //-----------------------------------------------------------------
4361 // This method is used to decide whether to allow a prolongation
4362 // without clusters, because we want to skip the layer.
4363 // In this case the return value is > 0:
4364 // return 1: the user requested to skip a layer
4365 // return 2: track outside z acceptance
4366 //-----------------------------------------------------------------
4368 if (ForceSkippingOfLayer(ilayer)) return 1;
4370 Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
4372 if (idet<0 && // out in z
4373 ilayer>innerLayCanSkip &&
4374 AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4375 // check if track will cross SPD outer layer
4376 Double_t phiAtSPD2,zAtSPD2;
4377 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4378 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4380 return 2; // always allow skipping, changed on 05.11.2009
4385 //------------------------------------------------------------------------
4386 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4387 Int_t ilayer,Int_t idet,
4388 Double_t dz,Double_t dy,
4389 Bool_t noClusters) const {
4390 //-----------------------------------------------------------------
4391 // This method is used to decide whether to allow a prolongation
4392 // without clusters, because there is a dead zone in the road.
4393 // In this case the return value is > 0:
4394 // return 1: dead zone at z=0,+-7cm in SPD
4395 // This method assumes that fSPDdetzcentre is ordered from -z to +z
4396 // return 2: all road is "bad" (dead or noisy) from the OCDB
4397 // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4398 // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4399 //-----------------------------------------------------------------
4401 // check dead zones at z=0,+-7cm in the SPD
4402 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4403 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4404 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4405 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4406 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4407 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4408 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4409 for (Int_t i=0; i<3; i++)
4410 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4411 AliDebug(2,Form("crack SPD %d track z %f %f %f %f\n",ilayer,track->GetZ(),dz,zmaxdead[i],zmindead[i]));
4412 if (GetSPDDeadZoneProbability(track->GetZ(),TMath::Sqrt(track->GetSigmaZ2()))>0.1) return 1;
4416 // check bad zones from OCDB
4417 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4419 if (idet<0) return 0;
4421 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4424 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4425 if (ilayer==0 || ilayer==1) { // ---------- SPD
4427 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4429 detSizeFactorX *= 2.;
4430 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4433 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4434 if (detType==2) segm->SetLayer(ilayer+1);
4435 Float_t detSizeX = detSizeFactorX*segm->Dx();
4436 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4438 // check if the road overlaps with bad chips
4440 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
4441 Float_t zlocmin = zloc-dz;
4442 Float_t zlocmax = zloc+dz;
4443 Float_t xlocmin = xloc-dy;
4444 Float_t xlocmax = xloc+dy;
4445 Int_t chipsInRoad[100];
4447 // check if road goes out of detector
4448 Bool_t touchNeighbourDet=kFALSE;
4449 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4450 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4451 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4452 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4453 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));
4455 // check if this detector is bad
4457 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4458 if(!touchNeighbourDet) {
4459 return 2; // all detectors in road are bad
4461 return 3; // at least one is bad
4465 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4466 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4467 if (!nChipsInRoad) return 0;
4469 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4470 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4471 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4472 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4473 if (det.IsChipBad(chipsInRoad[iCh])) {
4481 if(!touchNeighbourDet) {
4482 AliDebug(2,"all bad in road");
4483 return 2; // all chips in road are bad
4485 return 3; // at least a bad chip in road
4490 AliDebug(2,"at least a bad in road");
4491 return 3; // at least a bad chip in road
4495 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4496 || !noClusters) return 0;
4498 // There are no clusters in road: check if there is at least
4499 // a bad SPD pixel or SDD anode or SSD strips on both sides
4501 Int_t idetInITS=idet;
4502 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4504 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4505 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4508 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4512 //------------------------------------------------------------------------
4513 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4514 const AliITStrackMI *track,
4515 Float_t &xloc,Float_t &zloc) const {
4516 //-----------------------------------------------------------------
4517 // Gives position of track in local module ref. frame
4518 //-----------------------------------------------------------------
4523 if(idet<0) return kTRUE; // track out of z acceptance of layer
4525 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4527 Int_t lad = Int_t(idet/ndet) + 1;
4529 Int_t det = idet - (lad-1)*ndet + 1;
4531 Double_t xyzGlob[3],xyzLoc[3];
4533 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4534 // take into account the misalignment: xyz at real detector plane
4535 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4537 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4539 xloc = (Float_t)xyzLoc[0];
4540 zloc = (Float_t)xyzLoc[2];
4544 //------------------------------------------------------------------------
4545 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
4547 // Method to be optimized further:
4548 // Aim: decide whether a track can be used for PlaneEff evaluation
4549 // the decision is taken based on the track quality at the layer under study
4550 // no information on the clusters on this layer has to be used
4551 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4552 // the cut is done on number of sigmas from the boundaries
4554 // Input: Actual track, layer [0,5] under study
4556 // Return: kTRUE if this is a good track
4558 // it will apply a pre-selection to obtain good quality tracks.
4559 // Here also you will have the possibility to put a control on the
4560 // impact point of the track on the basic block, in order to exclude border regions
4561 // this will be done by calling a proper method of the AliITSPlaneEff class.
4563 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4564 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4566 Int_t index[AliITSgeomTGeo::kNLayers];
4568 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4570 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4571 index[k]=clusters[k];
4575 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4576 AliITSlayer &layer=fgLayers[ilayer];
4577 Double_t r=layer.GetR();
4578 AliITStrackMI tmp(*track);
4580 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4582 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) {
4583 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4584 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4585 if (tmp.GetClIndex(lay)>=0) ncl++;
4587 Bool_t nextout = kFALSE;
4588 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4589 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4590 Bool_t nextin = kFALSE;
4591 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4592 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4593 if(ncl<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
4595 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
4596 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
4597 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
4598 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
4602 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4603 Int_t idet=layer.FindDetectorIndex(phi,z);
4604 if(idet<0) { AliInfo(Form("cannot find detector"));
4607 // here check if it has good Chi Square.
4609 //propagate to the intersection with the detector plane
4610 const AliITSdetector &det=layer.GetDetector(idet);
4611 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4615 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
4616 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4617 if(key>fPlaneEff->Nblock()) return kFALSE;
4618 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4619 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4621 // DEFINITION OF SEARCH ROAD FOR accepting a track
4623 //For the time being they are hard-wired, later on from AliITSRecoParam
4624 // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
4625 // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
4628 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4629 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4630 // done for RecPoints
4632 // exclude tracks at boundary between detectors
4633 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
4634 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4635 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
4636 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
4637 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
4639 if ( (locx-dx < blockXmn+boundaryWidth) ||
4640 (locx+dx > blockXmx-boundaryWidth) ||
4641 (locz-dz < blockZmn+boundaryWidth) ||
4642 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
4645 //------------------------------------------------------------------------
4646 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
4648 // This Method has to be optimized! For the time-being it uses the same criteria
4649 // as those used in the search of extra clusters for overlapping modules.
4651 // Method Purpose: estabilish whether a track has produced a recpoint or not
4652 // in the layer under study (For Plane efficiency)
4654 // inputs: AliITStrackMI* track (pointer to a usable track)
4656 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
4657 // traversed by this very track. In details:
4658 // - if a cluster can be associated to the track then call
4659 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
4660 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
4663 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
4664 AliITSlayer &layer=fgLayers[ilayer];
4665 Double_t r=layer.GetR();
4666 AliITStrackMI tmp(*track);
4670 if (!tmp.GetPhiZat(r,phi,z)) return;
4671 Int_t idet=layer.FindDetectorIndex(phi,z);
4673 if(idet<0) { AliInfo(Form("cannot find detector"));
4677 //propagate to the intersection with the detector plane
4678 const AliITSdetector &det=layer.GetDetector(idet);
4679 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
4683 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
4685 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
4686 TMath::Sqrt(tmp.GetSigmaZ2() +
4687 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4688 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4689 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
4690 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
4691 TMath::Sqrt(tmp.GetSigmaY2() +
4692 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4693 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4694 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
4696 // road in global (rphi,z) [i.e. in tracking ref. system]
4697 Double_t zmin = tmp.GetZ() - dz;
4698 Double_t zmax = tmp.GetZ() + dz;
4699 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
4700 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
4702 // select clusters in road
4703 layer.SelectClusters(zmin,zmax,ymin,ymax);
4705 // Define criteria for track-cluster association
4706 Double_t msz = tmp.GetSigmaZ2() +
4707 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4708 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4709 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
4710 Double_t msy = tmp.GetSigmaY2() +
4711 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4712 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4713 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
4714 if (tmp.GetConstrain()) {
4715 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
4716 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
4718 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
4719 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
4721 msz = 1./msz; // 1/RoadZ^2
4722 msy = 1./msy; // 1/RoadY^2
4725 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
4727 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
4728 //Double_t tolerance=0.2;
4729 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
4730 idetc = cl->GetDetectorIndex();
4731 if(idet!=idetc) continue;
4732 //Int_t ilay = cl->GetLayer();
4734 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
4735 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
4737 Double_t chi2=tmp.GetPredictedChi2(cl);
4738 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
4742 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
4744 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
4745 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4746 if(key>fPlaneEff->Nblock()) return;
4747 Bool_t found=kFALSE;
4750 while ((cl=layer.GetNextCluster(clidx))!=0) {
4751 idetc = cl->GetDetectorIndex();
4752 if(idet!=idetc) continue;
4753 // here real control to see whether the cluster can be associated to the track.
4754 // cluster not associated to track
4755 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
4756 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
4757 // calculate track-clusters chi2
4758 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
4759 // in particular, the error associated to the cluster
4760 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
4762 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
4764 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
4765 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
4766 // track->SetExtraModule(ilayer,idetExtra);
4768 if(!fPlaneEff->UpDatePlaneEff(found,key))
4769 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
4770 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
4771 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
4772 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
4773 Int_t cltype[2]={-999,-999};
4777 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4778 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4781 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
4782 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
4783 cltype[0]=layer.GetCluster(ci)->GetNy();
4784 cltype[1]=layer.GetCluster(ci)->GetNz();
4786 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
4787 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
4788 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
4789 // It is computed properly by calling the method
4790 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4792 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
4793 //if (tmp.PropagateTo(x,0.,0.)) {
4794 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
4795 AliCluster c(*layer.GetCluster(ci));
4796 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
4797 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
4798 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
4799 clu[2]=TMath::Sqrt(c.GetSigmaY2());
4800 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
4803 fPlaneEff->FillHistos(key,found,tr,clu,cltype);